aboutsummaryrefslogtreecommitdiff
path: root/target-cris
diff options
context:
space:
mode:
authorAnthony Liguori <aliguori@us.ibm.com>2013-03-14 14:50:58 -0500
committerAnthony Liguori <aliguori@us.ibm.com>2013-03-14 14:50:58 -0500
commit3d34a4110c58bba120bc3d7c96c4b9571994c2a8 (patch)
tree7bbd137a5886c67352f77ee11a94009ad4af52cd /target-cris
parent0ec4a8e63ce5244cdb2aa8ef93427898e3f6631b (diff)
parent0ad6773f1151c9e172b0b714aada78655dda4cf4 (diff)
Merge remote-tracking branch 'afaerber/qom-cpu' into staging
# By Andreas Färber (16) and Igor Mammedov (1) # Via Andreas Färber * afaerber/qom-cpu: target-lm32: Update VMStateDescription to LM32CPU target-arm: Override do_interrupt for ARMv7-M profile cpu: Replace do_interrupt() by CPUClass::do_interrupt method cpu: Pass CPUState to cpu_interrupt() exec: Pass CPUState to cpu_reset_interrupt() cpu: Move halted and interrupt_request fields to CPUState target-cris/helper.c: Update Coding Style target-i386: Update VMStateDescription to X86CPU cpu: Introduce cpu_class_set_vmsd() cpu: Register VMStateDescription through CPUState stubs: Add a vmstate_dummy struct for CONFIG_USER_ONLY vmstate: Make vmstate_register() static inline target-sh4: Move PVR/PRR/CVR into SuperHCPUClass target-sh4: Introduce SuperHCPU subclasses cpus: Replace open-coded CPU loop in qmp_memsave() with qemu_get_cpu() monitor: Use qemu_get_cpu() in monitor_set_cpu() cpu: Fix qemu_get_cpu() to return NULL if CPU not found
Diffstat (limited to 'target-cris')
-rw-r--r--target-cris/cpu-qom.h2
-rw-r--r--target-cris/cpu.c1
-rw-r--r--target-cris/cpu.h5
-rw-r--r--target-cris/helper.c402
-rw-r--r--target-cris/translate.c3
5 files changed, 210 insertions, 203 deletions
diff --git a/target-cris/cpu-qom.h b/target-cris/cpu-qom.h
index 11e528661d..deea1d804b 100644
--- a/target-cris/cpu-qom.h
+++ b/target-cris/cpu-qom.h
@@ -73,4 +73,6 @@ static inline CRISCPU *cris_env_get_cpu(CPUCRISState *env)
#define ENV_OFFSET offsetof(CRISCPU, env)
+void cris_cpu_do_interrupt(CPUState *cpu);
+
#endif
diff --git a/target-cris/cpu.c b/target-cris/cpu.c
index 7974be33f2..95cbf399d9 100644
--- a/target-cris/cpu.c
+++ b/target-cris/cpu.c
@@ -243,6 +243,7 @@ static void cris_cpu_class_init(ObjectClass *oc, void *data)
cc->reset = cris_cpu_reset;
cc->class_by_name = cris_cpu_class_by_name;
+ cc->do_interrupt = cris_cpu_do_interrupt;
}
static const TypeInfo cris_cpu_type_info = {
diff --git a/target-cris/cpu.h b/target-cris/cpu.h
index ebf2d4027f..dbd7d36870 100644
--- a/target-cris/cpu.h
+++ b/target-cris/cpu.h
@@ -175,7 +175,6 @@ typedef struct CPUCRISState {
CRISCPU *cpu_cris_init(const char *cpu_model);
int cpu_cris_exec(CPUCRISState *s);
-void do_interrupt(CPUCRISState *env);
/* you can call this signal handler from your SIGBUS and SIGSEGV
signal handlers to inform the virtual CPU of exceptions. non zero
is returned if the signal was handled by the virtual CPU. */
@@ -289,9 +288,7 @@ void cris_cpu_list(FILE *f, fprintf_function cpu_fprintf);
static inline bool cpu_has_work(CPUState *cpu)
{
- CPUCRISState *env = &CRIS_CPU(cpu)->env;
-
- return env->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI);
+ return cpu->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI);
}
#include "exec/exec-all.h"
diff --git a/target-cris/helper.c b/target-cris/helper.c
index 6e75e9819e..e1ef7bcc0b 100644
--- a/target-cris/helper.c
+++ b/target-cris/helper.c
@@ -36,19 +36,22 @@
#if defined(CONFIG_USER_ONLY)
-void do_interrupt (CPUCRISState *env)
+void cris_cpu_do_interrupt(CPUState *cs)
{
- env->exception_index = -1;
- env->pregs[PR_ERP] = env->pc;
+ CRISCPU *cpu = CRIS_CPU(cs);
+ CPUCRISState *env = &cpu->env;
+
+ env->exception_index = -1;
+ env->pregs[PR_ERP] = env->pc;
}
int cpu_cris_handle_mmu_fault(CPUCRISState * env, target_ulong address, int rw,
int mmu_idx)
{
- env->exception_index = 0xaa;
- env->pregs[PR_EDA] = address;
- cpu_dump_state(env, stderr, fprintf, 0);
- return 1;
+ env->exception_index = 0xaa;
+ env->pregs[PR_EDA] = address;
+ cpu_dump_state(env, stderr, fprintf, 0);
+ return 1;
}
#else /* !CONFIG_USER_ONLY */
@@ -56,211 +59,214 @@ int cpu_cris_handle_mmu_fault(CPUCRISState * env, target_ulong address, int rw,
static void cris_shift_ccs(CPUCRISState *env)
{
- uint32_t ccs;
- /* Apply the ccs shift. */
- ccs = env->pregs[PR_CCS];
- ccs = ((ccs & 0xc0000000) | ((ccs << 12) >> 2)) & ~0x3ff;
- env->pregs[PR_CCS] = ccs;
+ uint32_t ccs;
+ /* Apply the ccs shift. */
+ ccs = env->pregs[PR_CCS];
+ ccs = ((ccs & 0xc0000000) | ((ccs << 12) >> 2)) & ~0x3ff;
+ env->pregs[PR_CCS] = ccs;
}
-int cpu_cris_handle_mmu_fault (CPUCRISState *env, target_ulong address, int rw,
- int mmu_idx)
+int cpu_cris_handle_mmu_fault(CPUCRISState *env, target_ulong address, int rw,
+ int mmu_idx)
{
- struct cris_mmu_result res;
- int prot, miss;
- int r = -1;
- target_ulong phy;
-
- D(printf ("%s addr=%x pc=%x rw=%x\n", __func__, address, env->pc, rw));
- miss = cris_mmu_translate(&res, env, address & TARGET_PAGE_MASK,
- rw, mmu_idx, 0);
- if (miss)
- {
- if (env->exception_index == EXCP_BUSFAULT)
- cpu_abort(env,
- "CRIS: Illegal recursive bus fault."
- "addr=%x rw=%d\n",
- address, rw);
-
- env->pregs[PR_EDA] = address;
- env->exception_index = EXCP_BUSFAULT;
- env->fault_vector = res.bf_vec;
- r = 1;
- }
- else
- {
- /*
- * Mask off the cache selection bit. The ETRAX busses do not
- * see the top bit.
- */
- phy = res.phy & ~0x80000000;
- prot = res.prot;
- tlb_set_page(env, address & TARGET_PAGE_MASK, phy,
- prot, mmu_idx, TARGET_PAGE_SIZE);
- r = 0;
- }
- if (r > 0)
- D_LOG("%s returns %d irqreq=%x addr=%x phy=%x vec=%x pc=%x\n",
- __func__, r, env->interrupt_request, address, res.phy,
- res.bf_vec, env->pc);
- return r;
+ D(CPUState *cpu = CPU(cris_env_get_cpu(env)));
+ struct cris_mmu_result res;
+ int prot, miss;
+ int r = -1;
+ target_ulong phy;
+
+ D(printf("%s addr=%x pc=%x rw=%x\n", __func__, address, env->pc, rw));
+ miss = cris_mmu_translate(&res, env, address & TARGET_PAGE_MASK,
+ rw, mmu_idx, 0);
+ if (miss) {
+ if (env->exception_index == EXCP_BUSFAULT) {
+ cpu_abort(env,
+ "CRIS: Illegal recursive bus fault."
+ "addr=%x rw=%d\n",
+ address, rw);
+ }
+
+ env->pregs[PR_EDA] = address;
+ env->exception_index = EXCP_BUSFAULT;
+ env->fault_vector = res.bf_vec;
+ r = 1;
+ } else {
+ /*
+ * Mask off the cache selection bit. The ETRAX busses do not
+ * see the top bit.
+ */
+ phy = res.phy & ~0x80000000;
+ prot = res.prot;
+ tlb_set_page(env, address & TARGET_PAGE_MASK, phy,
+ prot, mmu_idx, TARGET_PAGE_SIZE);
+ r = 0;
+ }
+ if (r > 0) {
+ D_LOG("%s returns %d irqreq=%x addr=%x phy=%x vec=%x pc=%x\n",
+ __func__, r, cpu->interrupt_request, address, res.phy,
+ res.bf_vec, env->pc);
+ }
+ return r;
}
static void do_interruptv10(CPUCRISState *env)
{
- int ex_vec = -1;
-
- D_LOG( "exception index=%d interrupt_req=%d\n",
- env->exception_index,
- env->interrupt_request);
-
- assert(!(env->pregs[PR_CCS] & PFIX_FLAG));
- switch (env->exception_index)
- {
- case EXCP_BREAK:
- /* These exceptions are genereated by the core itself.
- ERP should point to the insn following the brk. */
- ex_vec = env->trap_vector;
- env->pregs[PRV10_BRP] = env->pc;
- break;
-
- case EXCP_NMI:
- /* NMI is hardwired to vector zero. */
- ex_vec = 0;
- env->pregs[PR_CCS] &= ~M_FLAG_V10;
- env->pregs[PRV10_BRP] = env->pc;
- break;
-
- case EXCP_BUSFAULT:
- cpu_abort(env, "Unhandled busfault");
- break;
-
- default:
- /* The interrupt controller gives us the vector. */
- ex_vec = env->interrupt_vector;
- /* Normal interrupts are taken between
- TB's. env->pc is valid here. */
- env->pregs[PR_ERP] = env->pc;
- break;
- }
-
- if (env->pregs[PR_CCS] & U_FLAG) {
- /* Swap stack pointers. */
- env->pregs[PR_USP] = env->regs[R_SP];
- env->regs[R_SP] = env->ksp;
- }
-
- /* Now that we are in kernel mode, load the handlers address. */
- env->pc = cpu_ldl_code(env, env->pregs[PR_EBP] + ex_vec * 4);
- env->locked_irq = 1;
- env->pregs[PR_CCS] |= F_FLAG_V10; /* set F. */
-
- qemu_log_mask(CPU_LOG_INT, "%s isr=%x vec=%x ccs=%x pid=%d erp=%x\n",
- __func__, env->pc, ex_vec,
- env->pregs[PR_CCS],
- env->pregs[PR_PID],
- env->pregs[PR_ERP]);
+ D(CPUState *cs = CPU(cris_env_get_cpu(env)));
+ int ex_vec = -1;
+
+ D_LOG("exception index=%d interrupt_req=%d\n",
+ env->exception_index,
+ cs->interrupt_request);
+
+ assert(!(env->pregs[PR_CCS] & PFIX_FLAG));
+ switch (env->exception_index) {
+ case EXCP_BREAK:
+ /* These exceptions are genereated by the core itself.
+ ERP should point to the insn following the brk. */
+ ex_vec = env->trap_vector;
+ env->pregs[PRV10_BRP] = env->pc;
+ break;
+
+ case EXCP_NMI:
+ /* NMI is hardwired to vector zero. */
+ ex_vec = 0;
+ env->pregs[PR_CCS] &= ~M_FLAG_V10;
+ env->pregs[PRV10_BRP] = env->pc;
+ break;
+
+ case EXCP_BUSFAULT:
+ cpu_abort(env, "Unhandled busfault");
+ break;
+
+ default:
+ /* The interrupt controller gives us the vector. */
+ ex_vec = env->interrupt_vector;
+ /* Normal interrupts are taken between
+ TB's. env->pc is valid here. */
+ env->pregs[PR_ERP] = env->pc;
+ break;
+ }
+
+ if (env->pregs[PR_CCS] & U_FLAG) {
+ /* Swap stack pointers. */
+ env->pregs[PR_USP] = env->regs[R_SP];
+ env->regs[R_SP] = env->ksp;
+ }
+
+ /* Now that we are in kernel mode, load the handlers address. */
+ env->pc = cpu_ldl_code(env, env->pregs[PR_EBP] + ex_vec * 4);
+ env->locked_irq = 1;
+ env->pregs[PR_CCS] |= F_FLAG_V10; /* set F. */
+
+ qemu_log_mask(CPU_LOG_INT, "%s isr=%x vec=%x ccs=%x pid=%d erp=%x\n",
+ __func__, env->pc, ex_vec,
+ env->pregs[PR_CCS],
+ env->pregs[PR_PID],
+ env->pregs[PR_ERP]);
}
-void do_interrupt(CPUCRISState *env)
+void cris_cpu_do_interrupt(CPUState *cs)
{
- int ex_vec = -1;
-
- if (env->pregs[PR_VR] < 32)
- return do_interruptv10(env);
-
- D_LOG( "exception index=%d interrupt_req=%d\n",
- env->exception_index,
- env->interrupt_request);
-
- switch (env->exception_index)
- {
- case EXCP_BREAK:
- /* These exceptions are genereated by the core itself.
- ERP should point to the insn following the brk. */
- ex_vec = env->trap_vector;
- env->pregs[PR_ERP] = env->pc;
- break;
-
- case EXCP_NMI:
- /* NMI is hardwired to vector zero. */
- ex_vec = 0;
- env->pregs[PR_CCS] &= ~M_FLAG_V32;
- env->pregs[PR_NRP] = env->pc;
- break;
-
- case EXCP_BUSFAULT:
- ex_vec = env->fault_vector;
- env->pregs[PR_ERP] = env->pc;
- break;
-
- default:
- /* The interrupt controller gives us the vector. */
- ex_vec = env->interrupt_vector;
- /* Normal interrupts are taken between
- TB's. env->pc is valid here. */
- env->pregs[PR_ERP] = env->pc;
- break;
- }
-
- /* Fill in the IDX field. */
- env->pregs[PR_EXS] = (ex_vec & 0xff) << 8;
-
- if (env->dslot) {
- D_LOG("excp isr=%x PC=%x ds=%d SP=%x"
- " ERP=%x pid=%x ccs=%x cc=%d %x\n",
- ex_vec, env->pc, env->dslot,
- env->regs[R_SP],
- env->pregs[PR_ERP], env->pregs[PR_PID],
- env->pregs[PR_CCS],
- env->cc_op, env->cc_mask);
- /* We loose the btarget, btaken state here so rexec the
- branch. */
- env->pregs[PR_ERP] -= env->dslot;
- /* Exception starts with dslot cleared. */
- env->dslot = 0;
- }
+ CRISCPU *cpu = CRIS_CPU(cs);
+ CPUCRISState *env = &cpu->env;
+ int ex_vec = -1;
+
+ if (env->pregs[PR_VR] < 32) {
+ return do_interruptv10(env);
+ }
+
+ D_LOG("exception index=%d interrupt_req=%d\n",
+ env->exception_index,
+ cs->interrupt_request);
+
+ switch (env->exception_index) {
+ case EXCP_BREAK:
+ /* These exceptions are genereated by the core itself.
+ ERP should point to the insn following the brk. */
+ ex_vec = env->trap_vector;
+ env->pregs[PR_ERP] = env->pc;
+ break;
+
+ case EXCP_NMI:
+ /* NMI is hardwired to vector zero. */
+ ex_vec = 0;
+ env->pregs[PR_CCS] &= ~M_FLAG_V32;
+ env->pregs[PR_NRP] = env->pc;
+ break;
+
+ case EXCP_BUSFAULT:
+ ex_vec = env->fault_vector;
+ env->pregs[PR_ERP] = env->pc;
+ break;
+
+ default:
+ /* The interrupt controller gives us the vector. */
+ ex_vec = env->interrupt_vector;
+ /* Normal interrupts are taken between
+ TB's. env->pc is valid here. */
+ env->pregs[PR_ERP] = env->pc;
+ break;
+ }
+
+ /* Fill in the IDX field. */
+ env->pregs[PR_EXS] = (ex_vec & 0xff) << 8;
+
+ if (env->dslot) {
+ D_LOG("excp isr=%x PC=%x ds=%d SP=%x"
+ " ERP=%x pid=%x ccs=%x cc=%d %x\n",
+ ex_vec, env->pc, env->dslot,
+ env->regs[R_SP],
+ env->pregs[PR_ERP], env->pregs[PR_PID],
+ env->pregs[PR_CCS],
+ env->cc_op, env->cc_mask);
+ /* We loose the btarget, btaken state here so rexec the
+ branch. */
+ env->pregs[PR_ERP] -= env->dslot;
+ /* Exception starts with dslot cleared. */
+ env->dslot = 0;
+ }
- if (env->pregs[PR_CCS] & U_FLAG) {
- /* Swap stack pointers. */
- env->pregs[PR_USP] = env->regs[R_SP];
- env->regs[R_SP] = env->ksp;
- }
-
- /* Apply the CRIS CCS shift. Clears U if set. */
- cris_shift_ccs(env);
-
- /* Now that we are in kernel mode, load the handlers address.
- This load may not fault, real hw leaves that behaviour as
- undefined. */
- env->pc = cpu_ldl_code(env, env->pregs[PR_EBP] + ex_vec * 4);
-
- /* Clear the excption_index to avoid spurios hw_aborts for recursive
- bus faults. */
- env->exception_index = -1;
-
- D_LOG("%s isr=%x vec=%x ccs=%x pid=%d erp=%x\n",
- __func__, env->pc, ex_vec,
- env->pregs[PR_CCS],
- env->pregs[PR_PID],
- env->pregs[PR_ERP]);
+ if (env->pregs[PR_CCS] & U_FLAG) {
+ /* Swap stack pointers. */
+ env->pregs[PR_USP] = env->regs[R_SP];
+ env->regs[R_SP] = env->ksp;
+ }
+
+ /* Apply the CRIS CCS shift. Clears U if set. */
+ cris_shift_ccs(env);
+
+ /* Now that we are in kernel mode, load the handlers address.
+ This load may not fault, real hw leaves that behaviour as
+ undefined. */
+ env->pc = cpu_ldl_code(env, env->pregs[PR_EBP] + ex_vec * 4);
+
+ /* Clear the excption_index to avoid spurios hw_aborts for recursive
+ bus faults. */
+ env->exception_index = -1;
+
+ D_LOG("%s isr=%x vec=%x ccs=%x pid=%d erp=%x\n",
+ __func__, env->pc, ex_vec,
+ env->pregs[PR_CCS],
+ env->pregs[PR_PID],
+ env->pregs[PR_ERP]);
}
hwaddr cpu_get_phys_page_debug(CPUCRISState * env, target_ulong addr)
{
- uint32_t phy = addr;
- struct cris_mmu_result res;
- int miss;
-
- miss = cris_mmu_translate(&res, env, addr, 0, 0, 1);
- /* If D TLB misses, try I TLB. */
- if (miss) {
- miss = cris_mmu_translate(&res, env, addr, 2, 0, 1);
- }
-
- if (!miss)
- phy = res.phy;
- D(fprintf(stderr, "%s %x -> %x\n", __func__, addr, phy));
- return phy;
+ uint32_t phy = addr;
+ struct cris_mmu_result res;
+ int miss;
+
+ miss = cris_mmu_translate(&res, env, addr, 0, 0, 1);
+ /* If D TLB misses, try I TLB. */
+ if (miss) {
+ miss = cris_mmu_translate(&res, env, addr, 2, 0, 1);
+ }
+
+ if (!miss) {
+ phy = res.phy;
+ }
+ D(fprintf(stderr, "%s %x -> %x\n", __func__, addr, phy));
+ return phy;
}
#endif
diff --git a/target-cris/translate.c b/target-cris/translate.c
index ec71ef4721..dbcb811b7b 100644
--- a/target-cris/translate.c
+++ b/target-cris/translate.c
@@ -2888,7 +2888,8 @@ static int dec_rfe_etc(CPUCRISState *env, DisasContext *dc)
cris_cc_mask(dc, 0);
if (dc->op2 == 15) {
- t_gen_mov_env_TN(halted, tcg_const_tl(1));
+ tcg_gen_st_i32(tcg_const_i32(1), cpu_env,
+ -offsetof(CRISCPU, env) + offsetof(CPUState, halted));
tcg_gen_movi_tl(env_pc, dc->pc + 2);
t_gen_raise_exception(EXCP_HLT);
return 2;