Commit c4b89d18ba3b494545266970fe8714bc3d7f5917
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
Showing
7 changed files
with
172 additions
and
4 deletions
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 | ... | ... |