summaryrefslogtreecommitdiff
path: root/target-lm32
diff options
context:
space:
mode:
Diffstat (limited to 'target-lm32')
-rw-r--r--target-lm32/cpu.c14
-rw-r--r--target-lm32/cpu.h13
-rw-r--r--target-lm32/helper.c64
-rw-r--r--target-lm32/op_helper.c23
-rw-r--r--target-lm32/translate.c5
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);