diff options
Diffstat (limited to 'target-lm32')
-rw-r--r-- | target-lm32/cpu.c | 14 | ||||
-rw-r--r-- | target-lm32/cpu.h | 13 | ||||
-rw-r--r-- | target-lm32/helper.c | 64 | ||||
-rw-r--r-- | target-lm32/op_helper.c | 23 | ||||
-rw-r--r-- | target-lm32/translate.c | 5 |
5 files changed, 63 insertions, 56 deletions
diff --git a/target-lm32/cpu.c b/target-lm32/cpu.c index 7e716fb336..c5c20d74c4 100644 --- a/target-lm32/cpu.c +++ b/target-lm32/cpu.c @@ -110,6 +110,11 @@ static void lm32_cpu_init_cfg_reg(LM32CPU *cpu) env->cfg = cfg; } +static bool lm32_cpu_has_work(CPUState *cs) +{ + return cs->interrupt_request & CPU_INTERRUPT_HARD; +} + /* CPUClass::reset() */ static void lm32_cpu_reset(CPUState *s) { @@ -120,10 +125,10 @@ static void lm32_cpu_reset(CPUState *s) lcc->parent_reset(s); /* reset cpu state */ - memset(env, 0, offsetof(CPULM32State, breakpoints)); + memset(env, 0, offsetof(CPULM32State, eba)); lm32_cpu_init_cfg_reg(cpu); - tlb_flush(env, 1); + tlb_flush(s, 1); } static void lm32_cpu_realizefn(DeviceState *dev, Error **errp) @@ -255,12 +260,15 @@ static void lm32_cpu_class_init(ObjectClass *oc, void *data) cc->reset = lm32_cpu_reset; cc->class_by_name = lm32_cpu_class_by_name; + cc->has_work = lm32_cpu_has_work; cc->do_interrupt = lm32_cpu_do_interrupt; cc->dump_state = lm32_cpu_dump_state; cc->set_pc = lm32_cpu_set_pc; cc->gdb_read_register = lm32_cpu_gdb_read_register; cc->gdb_write_register = lm32_cpu_gdb_write_register; -#ifndef CONFIG_USER_ONLY +#ifdef CONFIG_USER_ONLY + cc->handle_mmu_fault = lm32_cpu_handle_mmu_fault; +#else cc->get_phys_page_debug = lm32_cpu_get_phys_page_debug; cc->vmsd = &vmstate_lm32_cpu; #endif diff --git a/target-lm32/cpu.h b/target-lm32/cpu.h index 18cf3488f7..24bde78502 100644 --- a/target-lm32/cpu.h +++ b/target-lm32/cpu.h @@ -166,11 +166,12 @@ struct CPULM32State { uint32_t bp[4]; /* breakpoints */ uint32_t wp[4]; /* watchpoints */ - CPUBreakpoint * cpu_breakpoint[4]; - CPUWatchpoint * cpu_watchpoint[4]; + struct CPUBreakpoint *cpu_breakpoint[4]; + struct CPUWatchpoint *cpu_watchpoint[4]; CPU_COMMON + /* Fields from here on are preserved across CPU reset. */ uint32_t eba; /* exception base address */ uint32_t deba; /* debug exception base address */ @@ -231,9 +232,8 @@ static inline CPULM32State *cpu_init(const char *cpu_model) #define cpu_gen_code cpu_lm32_gen_code #define cpu_signal_handler cpu_lm32_signal_handler -int cpu_lm32_handle_mmu_fault(CPULM32State *env, target_ulong address, int rw, +int lm32_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw, int mmu_idx); -#define cpu_handle_mmu_fault cpu_lm32_handle_mmu_fault #include "exec/cpu-all.h" @@ -245,11 +245,6 @@ static inline void cpu_get_tb_cpu_state(CPULM32State *env, target_ulong *pc, *flags = 0; } -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-lm32/helper.c b/target-lm32/helper.c index eecb9f612e..783aa16a45 100644 --- a/target-lm32/helper.c +++ b/target-lm32/helper.c @@ -20,18 +20,20 @@ #include "cpu.h" #include "qemu/host-utils.h" -int cpu_lm32_handle_mmu_fault(CPULM32State *env, target_ulong address, int rw, +int lm32_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw, int mmu_idx) { + LM32CPU *cpu = LM32_CPU(cs); + CPULM32State *env = &cpu->env; int prot; address &= TARGET_PAGE_MASK; prot = PAGE_BITS; if (env->flags & LM32_FLAG_IGNORE_MSB) { - tlb_set_page(env, address, address & 0x7fffffff, prot, mmu_idx, - TARGET_PAGE_SIZE); + tlb_set_page(cs, address, address & 0x7fffffff, prot, mmu_idx, + TARGET_PAGE_SIZE); } else { - 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; @@ -51,22 +53,28 @@ hwaddr lm32_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) void lm32_breakpoint_insert(CPULM32State *env, int idx, target_ulong address) { - cpu_breakpoint_insert(env, address, BP_CPU, &env->cpu_breakpoint[idx]); + LM32CPU *cpu = lm32_env_get_cpu(env); + + cpu_breakpoint_insert(CPU(cpu), address, BP_CPU, + &env->cpu_breakpoint[idx]); } void lm32_breakpoint_remove(CPULM32State *env, int idx) { + LM32CPU *cpu = lm32_env_get_cpu(env); + if (!env->cpu_breakpoint[idx]) { return; } - cpu_breakpoint_remove_by_ref(env, env->cpu_breakpoint[idx]); + cpu_breakpoint_remove_by_ref(CPU(cpu), env->cpu_breakpoint[idx]); env->cpu_breakpoint[idx] = NULL; } void lm32_watchpoint_insert(CPULM32State *env, int idx, target_ulong address, lm32_wp_t wp_type) { + LM32CPU *cpu = lm32_env_get_cpu(env); int flags = 0; switch (wp_type) { @@ -85,18 +93,20 @@ void lm32_watchpoint_insert(CPULM32State *env, int idx, target_ulong address, } if (flags != 0) { - cpu_watchpoint_insert(env, address, 1, flags, + cpu_watchpoint_insert(CPU(cpu), address, 1, flags, &env->cpu_watchpoint[idx]); } } void lm32_watchpoint_remove(CPULM32State *env, int idx) { + LM32CPU *cpu = lm32_env_get_cpu(env); + if (!env->cpu_watchpoint[idx]) { return; } - cpu_watchpoint_remove_by_ref(env, env->cpu_watchpoint[idx]); + cpu_watchpoint_remove_by_ref(CPU(cpu), env->cpu_watchpoint[idx]); env->cpu_watchpoint[idx] = NULL; } @@ -116,19 +126,20 @@ static bool check_watchpoints(CPULM32State *env) void lm32_debug_excp_handler(CPULM32State *env) { + CPUState *cs = CPU(lm32_env_get_cpu(env)); CPUBreakpoint *bp; - if (env->watchpoint_hit) { - if (env->watchpoint_hit->flags & BP_CPU) { - env->watchpoint_hit = NULL; + if (cs->watchpoint_hit) { + if (cs->watchpoint_hit->flags & BP_CPU) { + cs->watchpoint_hit = NULL; if (check_watchpoints(env)) { raise_exception(env, EXCP_WATCHPOINT); } else { - cpu_resume_from_signal(env, NULL); + cpu_resume_from_signal(cs, NULL); } } } else { - QTAILQ_FOREACH(bp, &env->breakpoints, entry) { + QTAILQ_FOREACH(bp, &cs->breakpoints, entry) { if (bp->pc == env->pc) { if (bp->flags & BP_CPU) { raise_exception(env, EXCP_BREAKPOINT); @@ -145,9 +156,9 @@ void lm32_cpu_do_interrupt(CPUState *cs) CPULM32State *env = &cpu->env; qemu_log_mask(CPU_LOG_INT, - "exception at pc=%x type=%x\n", env->pc, env->exception_index); + "exception at pc=%x type=%x\n", env->pc, cs->exception_index); - switch (env->exception_index) { + switch (cs->exception_index) { case EXCP_INSN_BUS_ERROR: case EXCP_DATA_BUS_ERROR: case EXCP_DIVIDE_BY_ZERO: @@ -158,9 +169,9 @@ void lm32_cpu_do_interrupt(CPUState *cs) env->ie |= (env->ie & IE_IE) ? IE_EIE : 0; env->ie &= ~IE_IE; if (env->dc & DC_RE) { - env->pc = env->deba + (env->exception_index * 32); + env->pc = env->deba + (cs->exception_index * 32); } else { - env->pc = env->eba + (env->exception_index * 32); + env->pc = env->eba + (cs->exception_index * 32); } log_cpu_state_mask(CPU_LOG_INT, cs, 0); break; @@ -170,30 +181,19 @@ void lm32_cpu_do_interrupt(CPUState *cs) env->regs[R_BA] = env->pc; env->ie |= (env->ie & IE_IE) ? IE_BIE : 0; env->ie &= ~IE_IE; - env->pc = env->deba + (env->exception_index * 32); + env->pc = env->deba + (cs->exception_index * 32); log_cpu_state_mask(CPU_LOG_INT, cs, 0); break; default: - cpu_abort(env, "unhandled exception type=%d\n", - env->exception_index); + cpu_abort(cs, "unhandled exception type=%d\n", + cs->exception_index); break; } } LM32CPU *cpu_lm32_init(const char *cpu_model) { - LM32CPU *cpu; - ObjectClass *oc; - - oc = cpu_class_by_name(TYPE_LM32_CPU, cpu_model); - if (oc == NULL) { - return NULL; - } - cpu = LM32_CPU(object_new(object_class_get_name(oc))); - - object_property_set_bool(OBJECT(cpu), true, "realized", NULL); - - return cpu; + return LM32_CPU(cpu_generic_init(TYPE_LM32_CPU, cpu_model)); } /* Some soc ignores the MSB on the address bus. Thus creating a shadow memory diff --git a/target-lm32/op_helper.c b/target-lm32/op_helper.c index 7189cb5cc4..2f36b7b053 100644 --- a/target-lm32/op_helper.c +++ b/target-lm32/op_helper.c @@ -25,8 +25,10 @@ void raise_exception(CPULM32State *env, int index) { - env->exception_index = index; - cpu_loop_exit(env); + CPUState *cs = CPU(lm32_env_get_cpu(env)); + + cs->exception_index = index; + cpu_loop_exit(cs); } void HELPER(raise_exception)(CPULM32State *env, uint32_t index) @@ -39,8 +41,8 @@ void HELPER(hlt)(CPULM32State *env) CPUState *cs = CPU(lm32_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); } void HELPER(ill)(CPULM32State *env) @@ -148,20 +150,21 @@ uint32_t HELPER(rcsr_jrx)(CPULM32State *env) } /* 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(CPULM32State *env, target_ulong addr, int is_write, int mmu_idx, + * NULL, it means that the function was called in C code (i.e. not + * from generated code or from helper.c) + */ +void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx, uintptr_t retaddr) { int ret; - ret = cpu_lm32_handle_mmu_fault(env, addr, is_write, mmu_idx); + ret = lm32_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); } } #endif diff --git a/target-lm32/translate.c b/target-lm32/translate.c index 80bffc7b27..c8abd1f27e 100644 --- a/target-lm32/translate.c +++ b/target-lm32/translate.c @@ -1037,10 +1037,11 @@ static inline void decode(DisasContext *dc, uint32_t ir) static void check_breakpoint(CPULM32State *env, DisasContext *dc) { + CPUState *cs = CPU(lm32_env_get_cpu(env)); CPUBreakpoint *bp; - 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) { tcg_gen_movi_tl(cpu_pc, dc->pc); t_gen_raise_exception(dc, EXCP_DEBUG); |