target-mips: get rid of tests on env->user_mode_only

Replace runtime checks on env->user_mode_only by compile time
checks on CONFIG_USER_ONLY.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6276 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
aurel32 2009-01-12 21:33:13 +00:00
parent ae1c1a3d68
commit 932e71cd57
3 changed files with 277 additions and 278 deletions

View File

@ -100,6 +100,7 @@ int r4k_map_address (CPUState *env, target_ulong *physical, int *prot,
return TLBRET_NOMATCH; return TLBRET_NOMATCH;
} }
#if !defined(CONFIG_USER_ONLY)
static int get_physical_address (CPUState *env, target_ulong *physical, static int get_physical_address (CPUState *env, target_ulong *physical,
int *prot, target_ulong address, int *prot, target_ulong address,
int rw, int access_type) int rw, int access_type)
@ -205,26 +206,29 @@ static int get_physical_address (CPUState *env, target_ulong *physical,
return ret; return ret;
} }
#endif
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr) target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
{ {
if (env->user_mode_only) #if defined(CONFIG_USER_ONLY)
return addr; return addr;
else { #else
target_ulong phys_addr; target_ulong phys_addr;
int prot; int prot;
if (get_physical_address(env, &phys_addr, &prot, addr, 0, ACCESS_INT) != 0) if (get_physical_address(env, &phys_addr, &prot, addr, 0, ACCESS_INT) != 0)
return -1; return -1;
return phys_addr; return phys_addr;
} #endif
} }
int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw, int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
int mmu_idx, int is_softmmu) int mmu_idx, int is_softmmu)
{ {
#if !defined(CONFIG_USER_ONLY)
target_ulong physical; target_ulong physical;
int prot; int prot;
#endif
int exception = 0, error_code = 0; int exception = 0, error_code = 0;
int access_type; int access_type;
int ret = 0; int ret = 0;
@ -243,11 +247,9 @@ int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
/* XXX: put correct access by using cpu_restore_state() /* XXX: put correct access by using cpu_restore_state()
correctly */ correctly */
access_type = ACCESS_INT; access_type = ACCESS_INT;
if (env->user_mode_only) { #if defined(CONFIG_USER_ONLY)
/* user mode only emulation */ ret = TLBRET_NOMATCH;
ret = TLBRET_NOMATCH; #else
goto do_fault;
}
ret = get_physical_address(env, &physical, &prot, ret = get_physical_address(env, &physical, &prot,
address, rw, access_type); address, rw, access_type);
if (logfile) { if (logfile) {
@ -258,8 +260,9 @@ int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
ret = tlb_set_page(env, address & TARGET_PAGE_MASK, ret = tlb_set_page(env, address & TARGET_PAGE_MASK,
physical & TARGET_PAGE_MASK, prot, physical & TARGET_PAGE_MASK, prot,
mmu_idx, is_softmmu); mmu_idx, is_softmmu);
} else if (ret < 0) { } else if (ret < 0)
do_fault: #endif
{
switch (ret) { switch (ret) {
default: default:
case TLBRET_BADADDR: case TLBRET_BADADDR:
@ -349,227 +352,227 @@ static const char * const excp_names[EXCP_LAST + 1] = {
void do_interrupt (CPUState *env) void do_interrupt (CPUState *env)
{ {
if (!env->user_mode_only) { #if !defined(CONFIG_USER_ONLY)
target_ulong offset; target_ulong offset;
int cause = -1; int cause = -1;
const char *name; const char *name;
if (logfile && env->exception_index != EXCP_EXT_INTERRUPT) { if (logfile && env->exception_index != EXCP_EXT_INTERRUPT) {
if (env->exception_index < 0 || env->exception_index > EXCP_LAST) if (env->exception_index < 0 || env->exception_index > EXCP_LAST)
name = "unknown"; name = "unknown";
else else
name = excp_names[env->exception_index]; name = excp_names[env->exception_index];
fprintf(logfile, "%s enter: PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx " %s exception\n", fprintf(logfile, "%s enter: PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx " %s exception\n",
__func__, env->active_tc.PC, env->CP0_EPC, name); __func__, env->active_tc.PC, env->CP0_EPC, name);
} }
if (env->exception_index == EXCP_EXT_INTERRUPT && if (env->exception_index == EXCP_EXT_INTERRUPT &&
(env->hflags & MIPS_HFLAG_DM)) (env->hflags & MIPS_HFLAG_DM))
env->exception_index = EXCP_DINT; env->exception_index = EXCP_DINT;
offset = 0x180; offset = 0x180;
switch (env->exception_index) { switch (env->exception_index) {
case EXCP_DSS: case EXCP_DSS:
env->CP0_Debug |= 1 << CP0DB_DSS; env->CP0_Debug |= 1 << CP0DB_DSS;
/* Debug single step cannot be raised inside a delay slot and /* Debug single step cannot be raised inside a delay slot and
resume will always occur on the next instruction resume will always occur on the next instruction
(but we assume the pc has always been updated during (but we assume the pc has always been updated during
code translation). */ code translation). */
env->CP0_DEPC = env->active_tc.PC;
goto enter_debug_mode;
case EXCP_DINT:
env->CP0_Debug |= 1 << CP0DB_DINT;
goto set_DEPC;
case EXCP_DIB:
env->CP0_Debug |= 1 << CP0DB_DIB;
goto set_DEPC;
case EXCP_DBp:
env->CP0_Debug |= 1 << CP0DB_DBp;
goto set_DEPC;
case EXCP_DDBS:
env->CP0_Debug |= 1 << CP0DB_DDBS;
goto set_DEPC;
case EXCP_DDBL:
env->CP0_Debug |= 1 << CP0DB_DDBL;
set_DEPC:
if (env->hflags & MIPS_HFLAG_BMASK) {
/* If the exception was raised from a delay slot,
come back to the jump. */
env->CP0_DEPC = env->active_tc.PC - 4;
env->hflags &= ~MIPS_HFLAG_BMASK;
} else {
env->CP0_DEPC = env->active_tc.PC; env->CP0_DEPC = env->active_tc.PC;
goto enter_debug_mode; }
case EXCP_DINT:
env->CP0_Debug |= 1 << CP0DB_DINT;
goto set_DEPC;
case EXCP_DIB:
env->CP0_Debug |= 1 << CP0DB_DIB;
goto set_DEPC;
case EXCP_DBp:
env->CP0_Debug |= 1 << CP0DB_DBp;
goto set_DEPC;
case EXCP_DDBS:
env->CP0_Debug |= 1 << CP0DB_DDBS;
goto set_DEPC;
case EXCP_DDBL:
env->CP0_Debug |= 1 << CP0DB_DDBL;
set_DEPC:
if (env->hflags & MIPS_HFLAG_BMASK) {
/* If the exception was raised from a delay slot,
come back to the jump. */
env->CP0_DEPC = env->active_tc.PC - 4;
env->hflags &= ~MIPS_HFLAG_BMASK;
} else {
env->CP0_DEPC = env->active_tc.PC;
}
enter_debug_mode: enter_debug_mode:
env->hflags |= MIPS_HFLAG_DM | MIPS_HFLAG_64 | MIPS_HFLAG_CP0; env->hflags |= MIPS_HFLAG_DM | MIPS_HFLAG_64 | MIPS_HFLAG_CP0;
env->hflags &= ~(MIPS_HFLAG_KSU); env->hflags &= ~(MIPS_HFLAG_KSU);
/* EJTAG probe trap enable is not implemented... */ /* EJTAG probe trap enable is not implemented... */
if (!(env->CP0_Status & (1 << CP0St_EXL))) if (!(env->CP0_Status & (1 << CP0St_EXL)))
env->CP0_Cause &= ~(1 << CP0Ca_BD); env->CP0_Cause &= ~(1 << CP0Ca_BD);
env->active_tc.PC = (int32_t)0xBFC00480; env->active_tc.PC = (int32_t)0xBFC00480;
break; break;
case EXCP_RESET: case EXCP_RESET:
cpu_reset(env); cpu_reset(env);
break; break;
case EXCP_SRESET: case EXCP_SRESET:
env->CP0_Status |= (1 << CP0St_SR); env->CP0_Status |= (1 << CP0St_SR);
memset(env->CP0_WatchLo, 0, sizeof(*env->CP0_WatchLo)); memset(env->CP0_WatchLo, 0, sizeof(*env->CP0_WatchLo));
goto set_error_EPC; goto set_error_EPC;
case EXCP_NMI: case EXCP_NMI:
env->CP0_Status |= (1 << CP0St_NMI); env->CP0_Status |= (1 << CP0St_NMI);
set_error_EPC: set_error_EPC:
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 - 4;
env->hflags &= ~MIPS_HFLAG_BMASK;
} else {
env->CP0_ErrorEPC = env->active_tc.PC;
}
env->CP0_Status |= (1 << CP0St_ERL) | (1 << CP0St_BEV);
env->hflags |= MIPS_HFLAG_64 | MIPS_HFLAG_CP0;
env->hflags &= ~(MIPS_HFLAG_KSU);
if (!(env->CP0_Status & (1 << CP0St_EXL)))
env->CP0_Cause &= ~(1 << CP0Ca_BD);
env->active_tc.PC = (int32_t)0xBFC00000;
break;
case EXCP_EXT_INTERRUPT:
cause = 0;
if (env->CP0_Cause & (1 << CP0Ca_IV))
offset = 0x200;
goto set_EPC;
case EXCP_LTLBL:
cause = 1;
goto set_EPC;
case EXCP_TLBL:
cause = 2;
if (env->error_code == 1 && !(env->CP0_Status & (1 << CP0St_EXL))) {
#if defined(TARGET_MIPS64)
int R = env->CP0_BadVAddr >> 62;
int UX = (env->CP0_Status & (1 << CP0St_UX)) != 0;
int SX = (env->CP0_Status & (1 << CP0St_SX)) != 0;
int KX = (env->CP0_Status & (1 << CP0St_KX)) != 0;
if ((R == 0 && UX) || (R == 1 && SX) || (R == 3 && KX))
offset = 0x080;
else
#endif
offset = 0x000;
}
goto set_EPC;
case EXCP_TLBS:
cause = 3;
if (env->error_code == 1 && !(env->CP0_Status & (1 << CP0St_EXL))) {
#if defined(TARGET_MIPS64)
int R = env->CP0_BadVAddr >> 62;
int UX = (env->CP0_Status & (1 << CP0St_UX)) != 0;
int SX = (env->CP0_Status & (1 << CP0St_SX)) != 0;
int KX = (env->CP0_Status & (1 << CP0St_KX)) != 0;
if ((R == 0 && UX) || (R == 1 && SX) || (R == 3 && KX))
offset = 0x080;
else
#endif
offset = 0x000;
}
goto set_EPC;
case EXCP_AdEL:
cause = 4;
goto set_EPC;
case EXCP_AdES:
cause = 5;
goto set_EPC;
case EXCP_IBE:
cause = 6;
goto set_EPC;
case EXCP_DBE:
cause = 7;
goto set_EPC;
case EXCP_SYSCALL:
cause = 8;
goto set_EPC;
case EXCP_BREAK:
cause = 9;
goto set_EPC;
case EXCP_RI:
cause = 10;
goto set_EPC;
case EXCP_CpU:
cause = 11;
env->CP0_Cause = (env->CP0_Cause & ~(0x3 << CP0Ca_CE)) |
(env->error_code << CP0Ca_CE);
goto set_EPC;
case EXCP_OVERFLOW:
cause = 12;
goto set_EPC;
case EXCP_TRAP:
cause = 13;
goto set_EPC;
case EXCP_FPE:
cause = 15;
goto set_EPC;
case EXCP_C2E:
cause = 18;
goto set_EPC;
case EXCP_MDMX:
cause = 22;
goto set_EPC;
case EXCP_DWATCH:
cause = 23;
/* XXX: TODO: manage defered watch exceptions */
goto set_EPC;
case EXCP_MCHECK:
cause = 24;
goto set_EPC;
case EXCP_THREAD:
cause = 25;
goto set_EPC;
case EXCP_CACHE:
cause = 30;
if (env->CP0_Status & (1 << CP0St_BEV)) {
offset = 0x100;
} else {
offset = 0x20000100;
}
set_EPC:
if (!(env->CP0_Status & (1 << CP0St_EXL))) {
if (env->hflags & MIPS_HFLAG_BMASK) { if (env->hflags & MIPS_HFLAG_BMASK) {
/* If the exception was raised from a delay slot, /* If the exception was raised from a delay slot,
come back to the jump. */ come back to the jump. */
env->CP0_ErrorEPC = env->active_tc.PC - 4; env->CP0_EPC = env->active_tc.PC - 4;
env->hflags &= ~MIPS_HFLAG_BMASK; env->CP0_Cause |= (1 << CP0Ca_BD);
} else { } else {
env->CP0_ErrorEPC = env->active_tc.PC; env->CP0_EPC = env->active_tc.PC;
env->CP0_Cause &= ~(1 << CP0Ca_BD);
} }
env->CP0_Status |= (1 << CP0St_ERL) | (1 << CP0St_BEV); env->CP0_Status |= (1 << CP0St_EXL);
env->hflags |= MIPS_HFLAG_64 | MIPS_HFLAG_CP0; env->hflags |= MIPS_HFLAG_64 | MIPS_HFLAG_CP0;
env->hflags &= ~(MIPS_HFLAG_KSU); env->hflags &= ~(MIPS_HFLAG_KSU);
if (!(env->CP0_Status & (1 << CP0St_EXL)))
env->CP0_Cause &= ~(1 << CP0Ca_BD);
env->active_tc.PC = (int32_t)0xBFC00000;
break;
case EXCP_EXT_INTERRUPT:
cause = 0;
if (env->CP0_Cause & (1 << CP0Ca_IV))
offset = 0x200;
goto set_EPC;
case EXCP_LTLBL:
cause = 1;
goto set_EPC;
case EXCP_TLBL:
cause = 2;
if (env->error_code == 1 && !(env->CP0_Status & (1 << CP0St_EXL))) {
#if defined(TARGET_MIPS64)
int R = env->CP0_BadVAddr >> 62;
int UX = (env->CP0_Status & (1 << CP0St_UX)) != 0;
int SX = (env->CP0_Status & (1 << CP0St_SX)) != 0;
int KX = (env->CP0_Status & (1 << CP0St_KX)) != 0;
if ((R == 0 && UX) || (R == 1 && SX) || (R == 3 && KX))
offset = 0x080;
else
#endif
offset = 0x000;
}
goto set_EPC;
case EXCP_TLBS:
cause = 3;
if (env->error_code == 1 && !(env->CP0_Status & (1 << CP0St_EXL))) {
#if defined(TARGET_MIPS64)
int R = env->CP0_BadVAddr >> 62;
int UX = (env->CP0_Status & (1 << CP0St_UX)) != 0;
int SX = (env->CP0_Status & (1 << CP0St_SX)) != 0;
int KX = (env->CP0_Status & (1 << CP0St_KX)) != 0;
if ((R == 0 && UX) || (R == 1 && SX) || (R == 3 && KX))
offset = 0x080;
else
#endif
offset = 0x000;
}
goto set_EPC;
case EXCP_AdEL:
cause = 4;
goto set_EPC;
case EXCP_AdES:
cause = 5;
goto set_EPC;
case EXCP_IBE:
cause = 6;
goto set_EPC;
case EXCP_DBE:
cause = 7;
goto set_EPC;
case EXCP_SYSCALL:
cause = 8;
goto set_EPC;
case EXCP_BREAK:
cause = 9;
goto set_EPC;
case EXCP_RI:
cause = 10;
goto set_EPC;
case EXCP_CpU:
cause = 11;
env->CP0_Cause = (env->CP0_Cause & ~(0x3 << CP0Ca_CE)) |
(env->error_code << CP0Ca_CE);
goto set_EPC;
case EXCP_OVERFLOW:
cause = 12;
goto set_EPC;
case EXCP_TRAP:
cause = 13;
goto set_EPC;
case EXCP_FPE:
cause = 15;
goto set_EPC;
case EXCP_C2E:
cause = 18;
goto set_EPC;
case EXCP_MDMX:
cause = 22;
goto set_EPC;
case EXCP_DWATCH:
cause = 23;
/* XXX: TODO: manage defered watch exceptions */
goto set_EPC;
case EXCP_MCHECK:
cause = 24;
goto set_EPC;
case EXCP_THREAD:
cause = 25;
goto set_EPC;
case EXCP_CACHE:
cause = 30;
if (env->CP0_Status & (1 << CP0St_BEV)) {
offset = 0x100;
} else {
offset = 0x20000100;
}
set_EPC:
if (!(env->CP0_Status & (1 << CP0St_EXL))) {
if (env->hflags & MIPS_HFLAG_BMASK) {
/* If the exception was raised from a delay slot,
come back to the jump. */
env->CP0_EPC = env->active_tc.PC - 4;
env->CP0_Cause |= (1 << CP0Ca_BD);
} else {
env->CP0_EPC = env->active_tc.PC;
env->CP0_Cause &= ~(1 << CP0Ca_BD);
}
env->CP0_Status |= (1 << CP0St_EXL);
env->hflags |= MIPS_HFLAG_64 | MIPS_HFLAG_CP0;
env->hflags &= ~(MIPS_HFLAG_KSU);
}
env->hflags &= ~MIPS_HFLAG_BMASK;
if (env->CP0_Status & (1 << CP0St_BEV)) {
env->active_tc.PC = (int32_t)0xBFC00200;
} else {
env->active_tc.PC = (int32_t)(env->CP0_EBase & ~0x3ff);
}
env->active_tc.PC += offset;
env->CP0_Cause = (env->CP0_Cause & ~(0x1f << CP0Ca_EC)) | (cause << CP0Ca_EC);
break;
default:
if (logfile) {
fprintf(logfile, "Invalid MIPS exception %d. Exiting\n",
env->exception_index);
}
printf("Invalid MIPS exception %d. Exiting\n", env->exception_index);
exit(1);
} }
if (logfile && env->exception_index != EXCP_EXT_INTERRUPT) { env->hflags &= ~MIPS_HFLAG_BMASK;
fprintf(logfile, "%s: PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx " cause %d\n" if (env->CP0_Status & (1 << CP0St_BEV)) {
" S %08x C %08x A " TARGET_FMT_lx " D " TARGET_FMT_lx "\n", env->active_tc.PC = (int32_t)0xBFC00200;
__func__, env->active_tc.PC, env->CP0_EPC, cause, } else {
env->CP0_Status, env->CP0_Cause, env->CP0_BadVAddr, env->active_tc.PC = (int32_t)(env->CP0_EBase & ~0x3ff);
env->CP0_DEPC);
} }
env->active_tc.PC += offset;
env->CP0_Cause = (env->CP0_Cause & ~(0x1f << CP0Ca_EC)) | (cause << CP0Ca_EC);
break;
default:
if (logfile) {
fprintf(logfile, "Invalid MIPS exception %d. Exiting\n",
env->exception_index);
}
printf("Invalid MIPS exception %d. Exiting\n", env->exception_index);
exit(1);
} }
if (logfile && env->exception_index != EXCP_EXT_INTERRUPT) {
fprintf(logfile, "%s: PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx " cause %d\n"
" S %08x C %08x A " TARGET_FMT_lx " D " TARGET_FMT_lx "\n",
__func__, env->active_tc.PC, env->CP0_EPC, cause,
env->CP0_Status, env->CP0_Cause, env->CP0_BadVAddr,
env->CP0_DEPC);
}
#endif
env->exception_index = EXCP_NONE; env->exception_index = EXCP_NONE;
} }

View File

@ -7859,13 +7859,13 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
gen_helper_rdhwr_ccres(t0); gen_helper_rdhwr_ccres(t0);
break; break;
case 29: case 29:
if (env->user_mode_only) { #if defined(CONFIG_USER_ONLY)
tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, tls_value)); tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, tls_value));
break; break;
} else { #else
/* XXX: Some CPUs implement this in hardware. /* XXX: Some CPUs implement this in hardware.
Not supported yet. */ Not supported yet. */
} #endif
default: /* Invalid */ default: /* Invalid */
MIPS_INVAL("rdhwr"); MIPS_INVAL("rdhwr");
generate_exception(ctx, EXCP_RI); generate_exception(ctx, EXCP_RI);
@ -7953,19 +7953,17 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
case OPC_DMTC0: case OPC_DMTC0:
#endif #endif
#ifndef CONFIG_USER_ONLY #ifndef CONFIG_USER_ONLY
if (!env->user_mode_only) gen_cp0(env, ctx, op1, rt, rd);
gen_cp0(env, ctx, op1, rt, rd);
#endif /* !CONFIG_USER_ONLY */ #endif /* !CONFIG_USER_ONLY */
break; break;
case OPC_C0_FIRST ... OPC_C0_LAST: case OPC_C0_FIRST ... OPC_C0_LAST:
#ifndef CONFIG_USER_ONLY #ifndef CONFIG_USER_ONLY
if (!env->user_mode_only) gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
#endif /* !CONFIG_USER_ONLY */ #endif /* !CONFIG_USER_ONLY */
break; break;
case OPC_MFMC0: case OPC_MFMC0:
#ifndef CONFIG_USER_ONLY #ifndef CONFIG_USER_ONLY
if (!env->user_mode_only) { {
TCGv t0 = tcg_temp_local_new(); TCGv t0 = tcg_temp_local_new();
op2 = MASK_MFMC0(ctx->opcode); op2 = MASK_MFMC0(ctx->opcode);
@ -8264,10 +8262,11 @@ gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
/* Restore delay slot state from the tb context. */ /* Restore delay slot state from the tb context. */
ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */ ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
restore_cpu_state(env, &ctx); restore_cpu_state(env, &ctx);
if (env->user_mode_only) #ifdef CONFIG_USER_ONLY
ctx.mem_idx = MIPS_HFLAG_UM; ctx.mem_idx = MIPS_HFLAG_UM;
else #else
ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU; ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
#endif
num_insns = 0; num_insns = 0;
max_insns = tb->cflags & CF_COUNT_MASK; max_insns = tb->cflags & CF_COUNT_MASK;
if (max_insns == 0) if (max_insns == 0)
@ -8583,40 +8582,37 @@ void cpu_reset (CPUMIPSState *env)
/* Minimal init */ /* Minimal init */
#if defined(CONFIG_USER_ONLY) #if defined(CONFIG_USER_ONLY)
env->user_mode_only = 1; env->hflags = MIPS_HFLAG_UM;
#endif #else
if (env->user_mode_only) { if (env->hflags & MIPS_HFLAG_BMASK) {
env->hflags = MIPS_HFLAG_UM; /* If the exception was raised from a delay slot,
come back to the jump. */
env->CP0_ErrorEPC = env->active_tc.PC - 4;
} else { } else {
if (env->hflags & MIPS_HFLAG_BMASK) { env->CP0_ErrorEPC = env->active_tc.PC;
/* If the exception was raised from a delay slot,
come back to the jump. */
env->CP0_ErrorEPC = env->active_tc.PC - 4;
} else {
env->CP0_ErrorEPC = env->active_tc.PC;
}
env->active_tc.PC = (int32_t)0xBFC00000;
env->CP0_Wired = 0;
/* SMP not implemented */
env->CP0_EBase = 0x80000000;
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);
env->hflags = MIPS_HFLAG_CP0;
} }
env->active_tc.PC = (int32_t)0xBFC00000;
env->CP0_Wired = 0;
/* SMP not implemented */
env->CP0_EBase = 0x80000000;
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);
env->hflags = MIPS_HFLAG_CP0;
#endif
env->exception_index = EXCP_NONE; env->exception_index = EXCP_NONE;
cpu_mips_register(env, env->cpu_model); cpu_mips_register(env, env->cpu_model);
} }

View File

@ -495,14 +495,14 @@ static void fpu_init (CPUMIPSState *env, const mips_def_t *def)
env->fpus[i].fcr0 = def->CP1_fcr0; env->fpus[i].fcr0 = def->CP1_fcr0;
memcpy(&env->active_fpu, &env->fpus[0], sizeof(env->active_fpu)); memcpy(&env->active_fpu, &env->fpus[0], sizeof(env->active_fpu));
if (env->user_mode_only) { #if defined(CONFIG_USER_ONLY)
if (env->CP0_Config1 & (1 << CP0C1_FP)) if (env->CP0_Config1 & (1 << CP0C1_FP))
env->hflags |= MIPS_HFLAG_FPU; env->hflags |= MIPS_HFLAG_FPU;
#ifdef TARGET_MIPS64 #ifdef TARGET_MIPS64
if (env->active_fpu.fcr0 & (1 << FCR0_F64)) if (env->active_fpu.fcr0 & (1 << FCR0_F64))
env->hflags |= MIPS_HFLAG_F64; env->hflags |= MIPS_HFLAG_F64;
#endif
#endif #endif
}
} }
static void mvp_init (CPUMIPSState *env, const mips_def_t *def) static void mvp_init (CPUMIPSState *env, const mips_def_t *def)
@ -520,9 +520,10 @@ static void mvp_init (CPUMIPSState *env, const mips_def_t *def)
// (0x04 << CP0MVPC0_PTC); // (0x04 << CP0MVPC0_PTC);
(1 << CP0MVPC0_TCA) | (0x0 << CP0MVPC0_PVPE) | (1 << CP0MVPC0_TCA) | (0x0 << CP0MVPC0_PVPE) |
(0x04 << CP0MVPC0_PTC); (0x04 << CP0MVPC0_PTC);
#if !defined(CONFIG_USER_ONLY)
/* Usermode has no TLB support */ /* Usermode has no TLB support */
if (!env->user_mode_only) env->mvp->CP0_MVPConf0 |= (env->tlb->nb_tlb << CP0MVPC0_PTLBE);
env->mvp->CP0_MVPConf0 |= (env->tlb->nb_tlb << CP0MVPC0_PTLBE); #endif
/* Allocatable CP1 have media extensions, allocatable CP1 have FP support, /* Allocatable CP1 have media extensions, allocatable CP1 have FP support,
no UDI implemented, no CP2 implemented, 1 CP1 implemented. */ no UDI implemented, no CP2 implemented, 1 CP1 implemented. */
@ -572,8 +573,7 @@ static int cpu_mips_register (CPUMIPSState *env, const mips_def_t *def)
env->insn_flags = def->insn_flags; env->insn_flags = def->insn_flags;
#ifndef CONFIG_USER_ONLY #ifndef CONFIG_USER_ONLY
if (!env->user_mode_only) mmu_init(env, def);
mmu_init(env, def);
#endif #endif
fpu_init(env, def); fpu_init(env, def);
mvp_init(env, def); mvp_init(env, def);