diff options
Diffstat (limited to 'target-m68k')
-rw-r--r-- | target-m68k/cpu.c | 14 | ||||
-rw-r--r-- | target-m68k/cpu.h | 9 | ||||
-rw-r--r-- | target-m68k/helper.c | 23 | ||||
-rw-r--r-- | target-m68k/m68k-semi.c | 5 | ||||
-rw-r--r-- | target-m68k/op_helper.c | 34 | ||||
-rw-r--r-- | target-m68k/qregs.def | 1 | ||||
-rw-r--r-- | target-m68k/translate.c | 47 |
7 files changed, 71 insertions, 62 deletions
diff --git a/target-m68k/cpu.c b/target-m68k/cpu.c index 008d8db2da..c9cff19efc 100644 --- a/target-m68k/cpu.c +++ b/target-m68k/cpu.c @@ -30,6 +30,11 @@ static void m68k_cpu_set_pc(CPUState *cs, vaddr value) cpu->env.pc = value; } +static bool m68k_cpu_has_work(CPUState *cs) +{ + return cs->interrupt_request & CPU_INTERRUPT_HARD; +} + static void m68k_set_feature(CPUM68KState *env, int feature) { env->features |= (1u << feature); @@ -44,7 +49,7 @@ static void m68k_cpu_reset(CPUState *s) mcc->parent_reset(s); - memset(env, 0, offsetof(CPUM68KState, breakpoints)); + memset(env, 0, offsetof(CPUM68KState, features)); #if !defined(CONFIG_USER_ONLY) env->sr = 0x2700; #endif @@ -53,7 +58,7 @@ static void m68k_cpu_reset(CPUState *s) env->cc_op = CC_OP_FLAGS; /* TODO: We should set PC from the interrupt vector. */ env->pc = 0; - tlb_flush(env, 1); + tlb_flush(s, 1); } /* CPU models */ @@ -189,12 +194,15 @@ static void m68k_cpu_class_init(ObjectClass *c, void *data) cc->reset = m68k_cpu_reset; cc->class_by_name = m68k_cpu_class_by_name; + cc->has_work = m68k_cpu_has_work; cc->do_interrupt = m68k_cpu_do_interrupt; cc->dump_state = m68k_cpu_dump_state; cc->set_pc = m68k_cpu_set_pc; cc->gdb_read_register = m68k_cpu_gdb_read_register; cc->gdb_write_register = m68k_cpu_gdb_write_register; -#ifndef CONFIG_USER_ONLY +#ifdef CONFIG_USER_ONLY + cc->handle_mmu_fault = m68k_cpu_handle_mmu_fault; +#else cc->get_phys_page_debug = m68k_cpu_get_phys_page_debug; #endif dc->vmsd = &vmstate_m68k_cpu; diff --git a/target-m68k/cpu.h b/target-m68k/cpu.h index cfd6846347..6e4001d523 100644 --- a/target-m68k/cpu.h +++ b/target-m68k/cpu.h @@ -110,6 +110,7 @@ typedef struct CPUM68KState { CPU_COMMON + /* Fields from here on are preserved across CPU reset. */ uint32_t features; } CPUM68KState; @@ -237,9 +238,8 @@ static inline int cpu_mmu_index (CPUM68KState *env) return (env->sr & SR_S) == 0 ? 1 : 0; } -int cpu_m68k_handle_mmu_fault(CPUM68KState *env, target_ulong address, int rw, +int m68k_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw, int mmu_idx); -#define cpu_handle_mmu_fault cpu_m68k_handle_mmu_fault #include "exec/cpu-all.h" @@ -253,11 +253,6 @@ static inline void cpu_get_tb_cpu_state(CPUM68KState *env, target_ulong *pc, | ((env->macsr >> 4) & 0xf); /* Bits 0-3 */ } -static inline bool cpu_has_work(CPUState *cpu) -{ - return cpu->interrupt_request & CPU_INTERRUPT_HARD; -} - #include "exec/exec-all.h" #endif diff --git a/target-m68k/helper.c b/target-m68k/helper.c index a364eb1e5c..077b653f24 100644 --- a/target-m68k/helper.c +++ b/target-m68k/helper.c @@ -132,6 +132,7 @@ void m68k_cpu_init_gdb(M68kCPU *cpu) void cpu_m68k_flush_flags(CPUM68KState *env, int cc_op) { + M68kCPU *cpu = m68k_env_get_cpu(env); int flags; uint32_t src; uint32_t dest; @@ -204,7 +205,7 @@ void cpu_m68k_flush_flags(CPUM68KState *env, int cc_op) flags |= CCF_C; break; default: - cpu_abort(env, "Bad CC_OP %d", cc_op); + cpu_abort(CPU(cpu), "Bad CC_OP %d", cc_op); } env->cc_op = CC_OP_FLAGS; env->cc_dest = flags; @@ -212,6 +213,8 @@ void cpu_m68k_flush_flags(CPUM68KState *env, int cc_op) void HELPER(movec)(CPUM68KState *env, uint32_t reg, uint32_t val) { + M68kCPU *cpu = m68k_env_get_cpu(env); + switch (reg) { case 0x02: /* CACR */ env->cacr = val; @@ -225,7 +228,7 @@ void HELPER(movec)(CPUM68KState *env, uint32_t reg, uint32_t val) break; /* TODO: Implement control registers. */ default: - cpu_abort(env, "Unimplemented control register write 0x%x = 0x%x\n", + cpu_abort(CPU(cpu), "Unimplemented control register write 0x%x = 0x%x\n", reg, val); } } @@ -277,11 +280,13 @@ void m68k_switch_sp(CPUM68KState *env) #if defined(CONFIG_USER_ONLY) -int cpu_m68k_handle_mmu_fault (CPUM68KState *env, target_ulong address, int rw, - int mmu_idx) +int m68k_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw, + int mmu_idx) { - env->exception_index = EXCP_ACCESS; - env->mmu.ar = address; + M68kCPU *cpu = M68K_CPU(cs); + + cs->exception_index = EXCP_ACCESS; + cpu->env.mmu.ar = address; return 1; } @@ -295,14 +300,14 @@ hwaddr m68k_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) return addr; } -int cpu_m68k_handle_mmu_fault (CPUM68KState *env, target_ulong address, int rw, - int mmu_idx) +int m68k_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw, + int mmu_idx) { int prot; address &= TARGET_PAGE_MASK; prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; - tlb_set_page(env, address, address, prot, mmu_idx, TARGET_PAGE_SIZE); + tlb_set_page(cs, address, address, prot, mmu_idx, TARGET_PAGE_SIZE); return 0; } diff --git a/target-m68k/m68k-semi.c b/target-m68k/m68k-semi.c index 94c4983813..9dffe8de60 100644 --- a/target-m68k/m68k-semi.c +++ b/target-m68k/m68k-semi.c @@ -428,7 +428,8 @@ void do_m68k_semihosting(CPUM68KState *env, int nr) case HOSTED_INIT_SIM: #if defined(CONFIG_USER_ONLY) { - TaskState *ts = env->opaque; + CPUState *cs = CPU(m68k_env_get_cpu(env)); + TaskState *ts = cs->opaque; /* Allocate the heap using sbrk. */ if (!ts->heap_limit) { abi_ulong ret; @@ -460,7 +461,7 @@ void do_m68k_semihosting(CPUM68KState *env, int nr) #endif return; default: - cpu_abort(env, "Unsupported semihosting syscall %d\n", nr); + cpu_abort(CPU(m68k_env_get_cpu(env)), "Unsupported semihosting syscall %d\n", nr); result = 0; } failed: diff --git a/target-m68k/op_helper.c b/target-m68k/op_helper.c index bbbfd7f130..06302b1071 100644 --- a/target-m68k/op_helper.c +++ b/target-m68k/op_helper.c @@ -23,10 +23,7 @@ void m68k_cpu_do_interrupt(CPUState *cs) { - M68kCPU *cpu = M68K_CPU(cs); - CPUM68KState *env = &cpu->env; - - env->exception_index = -1; + cs->exception_index = -1; } void do_interrupt_m68k_hardirq(CPUM68KState *env) @@ -56,18 +53,18 @@ extern int semihosting_enabled; /* Try to fill the TLB and return an exception if error. If retaddr is NULL, it means that the function was called in C code (i.e. not from generated code or from helper.c) */ -void tlb_fill(CPUM68KState *env, target_ulong addr, int is_write, int mmu_idx, +void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx, uintptr_t retaddr) { int ret; - ret = cpu_m68k_handle_mmu_fault(env, addr, is_write, mmu_idx); + ret = m68k_cpu_handle_mmu_fault(cs, addr, is_write, mmu_idx); if (unlikely(ret)) { if (retaddr) { /* now we have a real cpu fault */ - cpu_restore_state(env, retaddr); + cpu_restore_state(cs, retaddr); } - cpu_loop_exit(env); + cpu_loop_exit(cs); } } @@ -87,7 +84,7 @@ static void do_rte(CPUM68KState *env) static void do_interrupt_all(CPUM68KState *env, int is_hw) { - CPUState *cs; + CPUState *cs = CPU(m68k_env_get_cpu(env)); uint32_t sp; uint32_t fmt; uint32_t retaddr; @@ -97,7 +94,7 @@ static void do_interrupt_all(CPUM68KState *env, int is_hw) retaddr = env->pc; if (!is_hw) { - switch (env->exception_index) { + switch (cs->exception_index) { case EXCP_RTE: /* Return from an exception. */ do_rte(env); @@ -112,20 +109,19 @@ static void do_interrupt_all(CPUM68KState *env, int is_hw) do_m68k_semihosting(env, env->dregs[0]); return; } - cs = CPU(m68k_env_get_cpu(env)); cs->halted = 1; - env->exception_index = EXCP_HLT; - cpu_loop_exit(env); + cs->exception_index = EXCP_HLT; + cpu_loop_exit(cs); return; } - if (env->exception_index >= EXCP_TRAP0 - && env->exception_index <= EXCP_TRAP15) { + if (cs->exception_index >= EXCP_TRAP0 + && cs->exception_index <= EXCP_TRAP15) { /* Move the PC after the trap instruction. */ retaddr += 2; } } - vector = env->exception_index << 2; + vector = cs->exception_index << 2; sp = env->aregs[7]; @@ -168,8 +164,10 @@ void do_interrupt_m68k_hardirq(CPUM68KState *env) static void raise_exception(CPUM68KState *env, int tt) { - env->exception_index = tt; - cpu_loop_exit(env); + CPUState *cs = CPU(m68k_env_get_cpu(env)); + + cs->exception_index = tt; + cpu_loop_exit(cs); } void HELPER(raise_exception)(CPUM68KState *env, uint32_t tt) diff --git a/target-m68k/qregs.def b/target-m68k/qregs.def index 4235b02764..204663e1aa 100644 --- a/target-m68k/qregs.def +++ b/target-m68k/qregs.def @@ -7,6 +7,5 @@ DEFO32(CC_SRC, cc_src) DEFO32(CC_X, cc_x) DEFO32(DIV1, div1) DEFO32(DIV2, div2) -DEFO32(EXCEPTION, exception_index) DEFO32(MACSR, macsr) DEFO32(MAC_MASK, mac_mask) diff --git a/target-m68k/translate.c b/target-m68k/translate.c index f54b94a53f..cd662891c8 100644 --- a/target-m68k/translate.c +++ b/target-m68k/translate.c @@ -43,6 +43,7 @@ #undef DEFF64 static TCGv_i32 cpu_halted; +static TCGv_i32 cpu_exception_index; static TCGv_ptr cpu_env; @@ -81,6 +82,10 @@ void m68k_tcg_init(void) cpu_halted = tcg_global_mem_new_i32(TCG_AREG0, -offsetof(M68kCPU, env) + offsetof(CPUState, halted), "HALTED"); + cpu_exception_index = tcg_global_mem_new_i32(TCG_AREG0, + -offsetof(M68kCPU, env) + + offsetof(CPUState, exception_index), + "EXCEPTION"); cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env"); @@ -110,14 +115,6 @@ void m68k_tcg_init(void) store_dummy = tcg_global_mem_new(TCG_AREG0, -8, "NULL"); } -static inline void qemu_assert(int cond, const char *msg) -{ - if (!cond) { - fprintf (stderr, "badness: %s\n", msg); - abort(); - } -} - /* internal defines */ typedef struct DisasContext { CPUM68KState *env; @@ -199,7 +196,7 @@ static inline TCGv gen_load(DisasContext * s, int opsize, TCGv addr, int sign) tcg_gen_qemu_ld32u(tmp, addr, index); break; default: - qemu_assert(0, "bad load size"); + g_assert_not_reached(); } gen_throws_exception = gen_last_qop; return tmp; @@ -233,7 +230,7 @@ static inline void gen_store(DisasContext *s, int opsize, TCGv addr, TCGv val) tcg_gen_qemu_st32(val, addr, index); break; default: - qemu_assert(0, "bad store size"); + g_assert_not_reached(); } gen_throws_exception = gen_last_qop; } @@ -437,8 +434,7 @@ static inline int opsize_bytes(int opsize) case OS_SINGLE: return 4; case OS_DOUBLE: return 8; default: - qemu_assert(0, "bad operand size"); - return 0; + g_assert_not_reached(); } } @@ -465,8 +461,7 @@ static void gen_partset_reg(int opsize, TCGv reg, TCGv val) tcg_gen_mov_i32(reg, val); break; default: - qemu_assert(0, "Bad operand size"); - break; + g_assert_not_reached(); } } @@ -495,7 +490,7 @@ static inline TCGv gen_extend(TCGv val, int opsize, int sign) tmp = val; break; default: - qemu_assert(0, "Bad operand size"); + g_assert_not_reached(); } return tmp; } @@ -669,7 +664,7 @@ static TCGv gen_ea(CPUM68KState *env, DisasContext *s, uint16_t insn, offset = read_im32(env, s); break; default: - qemu_assert(0, "Bad immediate operand"); + g_assert_not_reached(); } return tcg_const_i32(offset); default: @@ -886,8 +881,10 @@ DISAS_INSN(undef_fpu) DISAS_INSN(undef) { + M68kCPU *cpu = m68k_env_get_cpu(env); + gen_exception(s, s->pc - 2, EXCP_UNSUPPORTED); - cpu_abort(env, "Illegal instruction: %04x @ %08x", insn, s->pc - 2); + cpu_abort(CPU(cpu), "Illegal instruction: %04x @ %08x", insn, s->pc - 2); } DISAS_INSN(mulw) @@ -2087,12 +2084,14 @@ DISAS_INSN(wddata) DISAS_INSN(wdebug) { + M68kCPU *cpu = m68k_env_get_cpu(env); + if (IS_USER(s)) { gen_exception(s, s->pc - 2, EXCP_PRIVILEGE); return; } /* TODO: Implement wdebug. */ - qemu_assert(0, "WDEBUG not implemented"); + cpu_abort(CPU(cpu), "WDEBUG not implemented"); } DISAS_INSN(trap) @@ -2466,14 +2465,18 @@ DISAS_INSN(fbcc) DISAS_INSN(frestore) { + M68kCPU *cpu = m68k_env_get_cpu(env); + /* TODO: Implement frestore. */ - qemu_assert(0, "FRESTORE not implemented"); + cpu_abort(CPU(cpu), "FRESTORE not implemented"); } DISAS_INSN(fsave) { + M68kCPU *cpu = m68k_env_get_cpu(env); + /* TODO: Implement fsave. */ - qemu_assert(0, "FSAVE not implemented"); + cpu_abort(CPU(cpu), "FSAVE not implemented"); } static inline TCGv gen_mac_extract_word(DisasContext *s, TCGv val, int upper) @@ -3008,8 +3011,8 @@ gen_intermediate_code_internal(M68kCPU *cpu, TranslationBlock *tb, do { pc_offset = dc->pc - pc_start; gen_throws_exception = NULL; - if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) { - QTAILQ_FOREACH(bp, &env->breakpoints, entry) { + if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) { + QTAILQ_FOREACH(bp, &cs->breakpoints, entry) { if (bp->pc == dc->pc) { gen_exception(dc, dc->pc, EXCP_DEBUG); dc->is_jmp = DISAS_JUMP; |