void cpu_state_reset(CPUMIPSState *env) { MIPSCPU *cpu = mips_env_get_cpu(env); CPUState *cs = CPU(cpu); /* Reset registers to their default values */ env->CP0_PRid = env->cpu_model->CP0_PRid; env->CP0_Config0 = env->cpu_model->CP0_Config0; #ifdef TARGET_WORDS_BIGENDIAN env->CP0_Config0 |= (1 << CP0C0_BE); #endif env->CP0_Config1 = env->cpu_model->CP0_Config1; env->CP0_Config2 = env->cpu_model->CP0_Config2; env->CP0_Config3 = env->cpu_model->CP0_Config3; env->CP0_Config4 = env->cpu_model->CP0_Config4; env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask; env->CP0_Config5 = env->cpu_model->CP0_Config5; env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask; env->CP0_Config6 = env->cpu_model->CP0_Config6; env->CP0_Config7 = env->cpu_model->CP0_Config7; env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask << env->cpu_model->CP0_LLAddr_shift; env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift; env->SYNCI_Step = env->cpu_model->SYNCI_Step; env->CCRes = env->cpu_model->CCRes; env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask; env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask; env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl; env->current_tc = 0; env->SEGBITS = env->cpu_model->SEGBITS; env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1); #if defined(TARGET_MIPS64) if (env->cpu_model->insn_flags & ISA_MIPS3) { env->SEGMask |= 3ULL << 62; } #endif env->PABITS = env->cpu_model->PABITS; env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask; env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0; env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask; env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1; env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask; env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2; env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask; env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3; env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask; env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4; env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask; env->CP0_PageGrain = env->cpu_model->CP0_PageGrain; env->CP0_EBaseWG_rw_bitmask = env->cpu_model->CP0_EBaseWG_rw_bitmask; env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0; env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask; env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31; env->msair = env->cpu_model->MSAIR; env->insn_flags = env->cpu_model->insn_flags; #if defined(CONFIG_USER_ONLY) env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU); # ifdef TARGET_MIPS64 /* Enable 64-bit register mode. */ env->CP0_Status |= (1 << CP0St_PX); # endif # ifdef TARGET_ABI_MIPSN64 /* Enable 64-bit address mode. */ env->CP0_Status |= (1 << CP0St_UX); # endif /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR hardware registers. */ env->CP0_HWREna |= 0x0000000F; if (env->CP0_Config1 & (1 << CP0C1_FP)) { env->CP0_Status |= (1 << CP0St_CU1); } if (env->CP0_Config3 & (1 << CP0C3_DSPP)) { env->CP0_Status |= (1 << CP0St_MX); } # if defined(TARGET_MIPS64) /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */ if ((env->CP0_Config1 & (1 << CP0C1_FP)) && (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) { env->CP0_Status |= (1 << CP0St_FR); } # endif #else if (env->hflags & MIPS_HFLAG_BMASK) { /* If the exception was raised from a delay slot, come back to the jump. */ env->CP0_ErrorEPC = (env->active_tc.PC - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4)); } else { env->CP0_ErrorEPC = env->active_tc.PC; } env->active_tc.PC = env->exception_base; env->CP0_Random = env->tlb->nb_tlb - 1; env->tlb->tlb_in_use = env->tlb->nb_tlb; env->CP0_Wired = 0; env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId; env->CP0_EBase = (cs->cpu_index & 0x3FF); if (kvm_enabled()) { env->CP0_EBase |= 0x40000000; } else { env->CP0_EBase |= (int32_t)0x80000000; } if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) { env->CP0_CMGCRBase = 0x1fbf8000 >> 4; } env->CP0_EntryHi_ASID_mask = (env->CP0_Config4 & (1 << CP0C4_AE)) ? 0x3ff : 0xff; env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL); /* vectored interrupts not implemented, timer on int 7, no performance counters. */ env->CP0_IntCtl = 0xe0000000; { int i; for (i = 0; i < 7; i++) { env->CP0_WatchLo[i] = 0; env->CP0_WatchHi[i] = 0x80000000; } env->CP0_WatchLo[7] = 0; env->CP0_WatchHi[7] = 0; } /* Count register increments in debug mode, EJTAG version 1 */ env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER); cpu_mips_store_count(env, 1); if (env->CP0_Config3 & (1 << CP0C3_MT)) { int i; /* Only TC0 on VPE 0 starts as active. */ for (i = 0; i < ARRAY_SIZE(env->tcs); i++) { env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE; env->tcs[i].CP0_TCHalt = 1; } env->active_tc.CP0_TCHalt = 1; cs->halted = 1; 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); /* TC0 starts up unhalted. */ cs->halted = 0; env->active_tc.CP0_TCHalt = 0; env->tcs[0].CP0_TCHalt = 0; /* With thread 0 active. */ env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A); env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A); } } #endif if ((env->insn_flags & ISA_MIPS32R6) && (env->active_fpu.fcr0 & (1 << FCR0_F64))) { /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */ env->CP0_Status |= (1 << CP0St_FR); } /* MSA */ if (env->CP0_Config3 & (1 << CP0C3_MSAP)) { msa_reset(env); } compute_hflags(env); restore_fp_status(env); restore_pamask(env); cs->exception_index = EXCP_NONE; if (semihosting_get_argc()) { /* UHI interface can be used to obtain argc and argv */ env->active_tc.gpr[4] = -1; } }