diff options
Diffstat (limited to 'target-mips')
-rw-r--r-- | target-mips/cpu.c | 8 | ||||
-rw-r--r-- | target-mips/op_helper.c | 33 | ||||
-rw-r--r-- | target-mips/translate.c | 17 |
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); |