Commit c4b89d18ba3b494545266970fe8714bc3d7f5917

Authored by ths
1 parent 26ea0918

Some bits of Linux/MIPS host support, still segfaulty.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2771 c046a42c-6fe2-441c-8c8c-71466251a162
Makefile.target
... ... @@ -181,6 +181,7 @@ BASE_LDFLAGS+=-Wl,-T,$(SRC_PATH)/$(ARCH).ld
181 181 endif
182 182  
183 183 ifeq ($(ARCH),mips)
  184 +OP_CFLAGS+=-G 0 -fomit-frame-pointer -fno-delayed-branch
184 185 ifeq ($(WORDS_BIGENDIAN),yes)
185 186 BASE_LDFLAGS+=-Wl,-T,$(SRC_PATH)/$(ARCH).ld
186 187 else
... ... @@ -189,6 +190,7 @@ endif
189 190 endif
190 191  
191 192 ifeq ($(ARCH),mips64)
  193 +OP_CFLAGS+=-G 0 -fomit-frame-pointer -fno-delayed-branch
192 194 ifeq ($(WORDS_BIGENDIAN),yes)
193 195 BASE_LDFLAGS+=-Wl,-T,$(SRC_PATH)/$(ARCH).ld
194 196 else
... ...
cpu-all.h
... ... @@ -20,7 +20,7 @@
20 20 #ifndef CPU_ALL_H
21 21 #define CPU_ALL_H
22 22  
23   -#if defined(__arm__) || defined(__sparc__)
  23 +#if defined(__arm__) || defined(__sparc__) || defined(__mips__)
24 24 #define WORDS_ALIGNED
25 25 #endif
26 26  
... ... @@ -1022,6 +1022,27 @@ static inline int64_t cpu_get_real_ticks (void)
1022 1022 return rval.i64;
1023 1023 #endif
1024 1024 }
  1025 +
  1026 +#elif defined(__mips__)
  1027 +
  1028 +static inline int64_t cpu_get_real_ticks(void)
  1029 +{
  1030 +#if __mips_isa_rev >= 2
  1031 + uint32_t count;
  1032 + static uint32_t cyc_per_count = 0;
  1033 +
  1034 + if (!cyc_per_count)
  1035 + __asm__ __volatile__("rdhwr %0, $3" : "=r" (cyc_per_count));
  1036 +
  1037 + __asm__ __volatile__("rdhwr %1, $2" : "=r" (count));
  1038 + return (int64_t)(count * cyc_per_count);
  1039 +#else
  1040 + /* FIXME */
  1041 + static int64_t ticks = 0;
  1042 + return ticks++;
  1043 +#endif
  1044 +}
  1045 +
1025 1046 #else
1026 1047 /* The host CPU doesn't have an easily accessible cycle counter.
1027 1048 Just return a monotonically increasing vlue. This will be totally wrong,
... ...
cpu-exec.c
... ... @@ -1540,8 +1540,22 @@ int cpu_signal_handler(int host_signum, void *pinfo,
1540 1540 /* XXX: compute is_write */
1541 1541 is_write = 0;
1542 1542 return handle_cpu_signal(pc, (unsigned long)info->si_addr,
1543   - is_write,
1544   - &uc->uc_sigmask, puc);
  1543 + is_write, &uc->uc_sigmask, puc);
  1544 +}
  1545 +
  1546 +#elif defined(__mips__)
  1547 +
  1548 +int cpu_signal_handler(int host_signum, struct siginfo *info,
  1549 + void *puc)
  1550 +{
  1551 + struct ucontext *uc = puc;
  1552 + greg_t pc = uc->uc_mcontext.pc;
  1553 + int is_write;
  1554 +
  1555 + /* XXX: compute is_write */
  1556 + is_write = 0;
  1557 + return handle_cpu_signal(pc, (unsigned long)info->si_addr,
  1558 + is_write, &uc->uc_sigmask, puc);
1545 1559 }
1546 1560  
1547 1561 #else
... ...
dyngen-exec.h
... ... @@ -129,10 +129,15 @@ extern int printf(const char *, ...);
129 129 #define AREG3 "r6"
130 130 #endif
131 131 #ifdef __mips__
132   -#define AREG0 "s3"
  132 +#define AREG0 "fp"
133 133 #define AREG1 "s0"
134 134 #define AREG2 "s1"
135 135 #define AREG3 "s2"
  136 +#define AREG4 "s3"
  137 +#define AREG5 "s4"
  138 +#define AREG6 "s5"
  139 +#define AREG7 "s6"
  140 +#define AREG8 "s7"
136 141 #endif
137 142 #ifdef __sparc__
138 143 #ifdef HOST_SOLARIS
... ... @@ -280,5 +285,9 @@ extern int __op_jmp0, __op_jmp1, __op_jmp2, __op_jmp3;
280 285 #ifdef __mc68000
281 286 #define EXIT_TB() asm volatile ("rts")
282 287 #endif
  288 +#ifdef __mips__
  289 +#define EXIT_TB() asm volatile ("jr $ra")
  290 +#define GOTO_LABEL_PARAM(n) asm volatile (".set noat; la $1, " ASM_NAME(__op_gen_label) #n "; jr $1; .set at")
  291 +#endif
283 292  
284 293 #endif /* !defined(__DYNGEN_EXEC_H__) */
... ...
dyngen.c
... ... @@ -117,6 +117,13 @@
117 117 #define elf_check_arch(x) ((x) == EM_68K)
118 118 #define ELF_USES_RELOCA
119 119  
  120 +#elif defined(HOST_MIPS)
  121 +
  122 +#define ELF_CLASS ELFCLASS32
  123 +#define ELF_ARCH EM_MIPS
  124 +#define elf_check_arch(x) ((x) == EM_MIPS)
  125 +#define ELF_USES_RELOC
  126 +
120 127 #else
121 128 #error unsupported CPU - please update the code
122 129 #endif
... ... @@ -1641,6 +1648,26 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
1641 1648 error("rts expected at the end of %s", name);
1642 1649 copy_size = p - p_start;
1643 1650 }
  1651 +#elif defined(HOST_MIPS)
  1652 + {
  1653 +#define INSN_RETURN 0x03e00008
  1654 +#define INSN_NOP 0x00000000
  1655 +
  1656 + uint8_t *p = p_end;
  1657 +
  1658 + if (p < (p_start + 0x8)) {
  1659 + error("empty code for %s", name);
  1660 + } else {
  1661 + uint32_t end_insn1, end_insn2;
  1662 +
  1663 + p -= 0x8;
  1664 + end_insn1 = get32((uint32_t *)(p + 0x0));
  1665 + end_insn2 = get32((uint32_t *)(p + 0x4));
  1666 + if (end_insn1 != INSN_RETURN && end_insn2 != INSN_NOP)
  1667 + error("jr ra not found at end of %s", name);
  1668 + }
  1669 + copy_size = p - p_start;
  1670 + }
1644 1671 #else
1645 1672 #error unsupported CPU
1646 1673 #endif
... ... @@ -2483,6 +2510,71 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
2483 2510 }
2484 2511 }
2485 2512 }
  2513 +#elif defined(HOST_MIPS)
  2514 + {
  2515 + for (i = 0, rel = relocs; i < nb_relocs; i++, rel++) {
  2516 + if (rel->r_offset >= start_offset && rel->r_offset < start_offset + copy_size) {
  2517 + char name[256];
  2518 + int type;
  2519 + int addend;
  2520 + int reloc_offset;
  2521 +
  2522 + sym_name = strtab + symtab[ELF32_R_SYM(rel->r_info)].st_name;
  2523 + /* the compiler leave some unnecessary references to the code */
  2524 + if (sym_name[0] == '\0')
  2525 + continue;
  2526 + get_reloc_expr(name, sizeof(name), sym_name);
  2527 + type = ELF32_R_TYPE(rel->r_info);
  2528 + addend = get32((uint32_t *)(text + rel->r_offset));
  2529 + reloc_offset = rel->r_offset - start_offset;
  2530 + switch (type) {
  2531 + case R_MIPS_HI16:
  2532 + fprintf(outfile, " /* R_MIPS_HI16 RELOC, offset 0x%x, name %s */\n",
  2533 + rel->r_offset, sym_name);
  2534 + fprintf(outfile,
  2535 + " *(uint32_t *)(gen_code_ptr + 0x%x) = "
  2536 + "((*(uint32_t *)(gen_code_ptr + 0x%x)) "
  2537 + " & ~0xffff) "
  2538 + " | (((%s - 0x8000) >> 16) & 0xffff);\n",
  2539 + reloc_offset, reloc_offset, name);
  2540 + break;
  2541 + case R_MIPS_LO16:
  2542 + fprintf(outfile, " /* R_MIPS_LO16 RELOC, offset 0x%x, name %s */\n",
  2543 + rel->r_offset, sym_name);
  2544 + fprintf(outfile,
  2545 + " *(uint32_t *)(gen_code_ptr + 0x%x) = "
  2546 + "((*(uint32_t *)(gen_code_ptr + 0x%x)) "
  2547 + " & ~0xffff) "
  2548 + " | (%s & 0xffff);\n",
  2549 + reloc_offset, reloc_offset, name);
  2550 + break;
  2551 + case R_MIPS_PC16:
  2552 + fprintf(outfile, " /* R_MIPS_PC16 RELOC, offset 0x%x, name %s */\n",
  2553 + rel->r_offset, sym_name);
  2554 + fprintf(outfile,
  2555 + " *(uint32_t *)(gen_code_ptr + 0x%x) = "
  2556 + "(0x%x & ~0xffff) "
  2557 + "| ((0x%x + ((%s - (*(uint32_t *)(gen_code_ptr + 0x%x))) >> 2)) "
  2558 + " & 0xffff);\n",
  2559 + reloc_offset, addend, addend, name, reloc_offset);
  2560 + break;
  2561 + case R_MIPS_GOT16:
  2562 + case R_MIPS_CALL16:
  2563 + fprintf(outfile, " /* R_MIPS_GOT16 RELOC, offset 0x%x, name %s */\n",
  2564 + rel->r_offset, sym_name);
  2565 + fprintf(outfile,
  2566 + " *(uint32_t *)(gen_code_ptr + 0x%x) = "
  2567 + "((*(uint32_t *)(gen_code_ptr + 0x%x)) "
  2568 + " & ~0xffff) "
  2569 + " | (((%s - 0x8000) >> 16) & 0xffff);\n",
  2570 + reloc_offset, reloc_offset, name);
  2571 + break;
  2572 + default:
  2573 + error("unsupported MIPS relocation (%d)", type);
  2574 + }
  2575 + }
  2576 + }
  2577 + }
2486 2578 #else
2487 2579 #error unsupported CPU
2488 2580 #endif
... ...
dyngen.h
... ... @@ -463,3 +463,11 @@ static inline void ia64_apply_fixes (uint8_t **gen_code_pp,
463 463 }
464 464  
465 465 #endif
  466 +
  467 +#ifdef __mips__
  468 +#include <sys/cachectl.h>
  469 +static inline void flush_icache_range(unsigned long start, unsigned long stop)
  470 +{
  471 + _flush_cache ((void *)start, stop - start, BCACHE);
  472 +}
  473 +#endif
... ...
exec-all.h
... ... @@ -481,6 +481,28 @@ static inline int testandset (int *p)
481 481 }
482 482 #endif
483 483  
  484 +#ifdef __mips__
  485 +static inline int testandset (int *p)
  486 +{
  487 + int ret;
  488 +
  489 + __asm__ __volatile__ (
  490 + " .set push \n"
  491 + " .set noat \n"
  492 + " .set mips2 \n"
  493 + "1: li $1, 1 \n"
  494 + " ll %0, %1 \n"
  495 + " sc $1, %1 \n"
  496 + " bnez $1, 1b \n"
  497 + " .set pop "
  498 + : "=r" (ret), "+R" (*p)
  499 + :
  500 + : "memory");
  501 +
  502 + return ret;
  503 +}
  504 +#endif
  505 +
484 506 typedef int spinlock_t;
485 507  
486 508 #define SPIN_LOCK_UNLOCKED 0
... ...