aboutsummaryrefslogtreecommitdiff
path: root/target-mips
diff options
context:
space:
mode:
Diffstat (limited to 'target-mips')
-rw-r--r--target-mips/cpu.c8
-rw-r--r--target-mips/op_helper.c33
-rw-r--r--target-mips/translate.c17
3 files changed, 37 insertions, 21 deletions
diff --git a/target-mips/cpu.c b/target-mips/cpu.c
index 004406232b..10ff46d6a7 100644
--- a/target-mips/cpu.c
+++ b/target-mips/cpu.c
@@ -29,8 +29,16 @@ static void mips_cpu_reset(CPUState *s)
MIPSCPUClass *mcc = MIPS_CPU_GET_CLASS(cpu);
CPUMIPSState *env = &cpu->env;
+ if (qemu_loglevel_mask(CPU_LOG_RESET)) {
+ qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
+ log_cpu_state(env, 0);
+ }
+
mcc->parent_reset(s);
+ memset(env, 0, offsetof(CPUMIPSState, breakpoints));
+ tlb_flush(env, 1);
+
cpu_state_reset(env);
}
diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index d5c61e8a84..1bca4a159e 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -572,17 +572,23 @@ static inline void mips_tc_sleep(MIPSCPU *cpu, int tc)
}
}
-/* tc should point to an int with the value of the global TC index.
- This function will transform it into a local index within the
- returned CPUMIPSState.
-
- FIXME: This code assumes that all VPEs have the same number of TCs,
+/**
+ * mips_cpu_map_tc:
+ * @env: CPU from which mapping is performed.
+ * @tc: Should point to an int with the value of the global TC index.
+ *
+ * This function will transform @tc into a local index within the
+ * returned #CPUMIPSState.
+ */
+/* FIXME: This code assumes that all VPEs have the same number of TCs,
which depends on runtime setup. Can probably be fixed by
walking the list of CPUMIPSStates. */
static CPUMIPSState *mips_cpu_map_tc(CPUMIPSState *env, int *tc)
{
- CPUMIPSState *other;
- int vpe_idx, nr_threads = env->nr_threads;
+ MIPSCPU *cpu;
+ CPUState *cs;
+ CPUState *other_cs;
+ int vpe_idx;
int tc_idx = *tc;
if (!(env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP))) {
@@ -591,10 +597,15 @@ static CPUMIPSState *mips_cpu_map_tc(CPUMIPSState *env, int *tc)
return env;
}
- vpe_idx = tc_idx / nr_threads;
- *tc = tc_idx % nr_threads;
- other = qemu_get_cpu(vpe_idx);
- return other ? other : env;
+ cs = CPU(mips_env_get_cpu(env));
+ vpe_idx = tc_idx / cs->nr_threads;
+ *tc = tc_idx % cs->nr_threads;
+ other_cs = qemu_get_cpu(vpe_idx);
+ if (other_cs == NULL) {
+ return env;
+ }
+ cpu = MIPS_CPU(other_cs);
+ return &cpu->env;
}
/* The per VPE CP0_Status register shares some fields with the per TC
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 6281e70471..206ba83401 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -15878,13 +15878,10 @@ MIPSCPU *cpu_mips_init(const char *cpu_model)
void cpu_state_reset(CPUMIPSState *env)
{
- if (qemu_loglevel_mask(CPU_LOG_RESET)) {
- qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
- log_cpu_state(env, 0);
- }
-
- memset(env, 0, offsetof(CPUMIPSState, breakpoints));
- tlb_flush(env, 1);
+#ifndef CONFIG_USER_ONLY
+ MIPSCPU *cpu = mips_env_get_cpu(env);
+ CPUState *cs = CPU(cpu);
+#endif
/* Reset registers to their default values */
env->CP0_PRid = env->cpu_model->CP0_PRid;
@@ -15953,7 +15950,7 @@ void cpu_state_reset(CPUMIPSState *env)
env->CP0_Random = env->tlb->nb_tlb - 1;
env->tlb->tlb_in_use = env->tlb->nb_tlb;
env->CP0_Wired = 0;
- env->CP0_EBase = 0x80000000 | (env->cpu_index & 0x3FF);
+ env->CP0_EBase = 0x80000000 | (cs->cpu_index & 0x3FF);
env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
/* vectored interrupts not implemented, timer on int 7,
no performance counters. */
@@ -15976,13 +15973,13 @@ void cpu_state_reset(CPUMIPSState *env)
/* Only TC0 on VPE 0 starts as active. */
for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
- env->tcs[i].CP0_TCBind = env->cpu_index << CP0TCBd_CurVPE;
+ env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
env->tcs[i].CP0_TCHalt = 1;
}
env->active_tc.CP0_TCHalt = 1;
env->halted = 1;
- if (!env->cpu_index) {
+ if (cs->cpu_index == 0) {
/* VPE0 starts up enabled. */
env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);