Revision 0eaef5aa target-mips/translate.c
b/target-mips/translate.c | ||
---|---|---|
2808 | 2808 |
tcg_temp_free(t1); |
2809 | 2809 |
} |
2810 | 2810 |
|
2811 |
/* CP0 (MMU and control) */ |
|
2812 | 2811 |
#ifndef CONFIG_USER_ONLY |
2812 |
/* CP0 (MMU and control) */ |
|
2813 | 2813 |
static inline void gen_mfc0_load32 (TCGv t, target_ulong off) |
2814 | 2814 |
{ |
2815 | 2815 |
TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32); |
... | ... | |
8052 | 8052 |
tcg_gen_helper_1_0(do_rdhwr_ccres, t0); |
8053 | 8053 |
break; |
8054 | 8054 |
case 29: |
8055 |
#if defined (CONFIG_USER_ONLY) |
|
8056 |
tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, tls_value)); |
|
8057 |
break; |
|
8058 |
#else |
|
8059 |
/* XXX: Some CPUs implement this in hardware. Not supported yet. */ |
|
8060 |
#endif |
|
8055 |
if (env->user_mode_only) { |
|
8056 |
tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, tls_value)); |
|
8057 |
break; |
|
8058 |
} else { |
|
8059 |
/* XXX: Some CPUs implement this in hardware. |
|
8060 |
Not supported yet. */ |
|
8061 |
} |
|
8061 | 8062 |
default: /* Invalid */ |
8062 | 8063 |
MIPS_INVAL("rdhwr"); |
8063 | 8064 |
generate_exception(ctx, EXCP_RI); |
... | ... | |
8166 | 8167 |
case OPC_DMTC0: |
8167 | 8168 |
#endif |
8168 | 8169 |
#ifndef CONFIG_USER_ONLY |
8169 |
gen_cp0(env, ctx, op1, rt, rd); |
|
8170 |
#endif |
|
8170 |
if (!env->user_mode_only) |
|
8171 |
gen_cp0(env, ctx, op1, rt, rd); |
|
8172 |
#endif /* !CONFIG_USER_ONLY */ |
|
8171 | 8173 |
break; |
8172 | 8174 |
case OPC_C0_FIRST ... OPC_C0_LAST: |
8173 | 8175 |
#ifndef CONFIG_USER_ONLY |
8174 |
gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd); |
|
8175 |
#endif |
|
8176 |
if (!env->user_mode_only) |
|
8177 |
gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd); |
|
8178 |
#endif /* !CONFIG_USER_ONLY */ |
|
8176 | 8179 |
break; |
8177 | 8180 |
case OPC_MFMC0: |
8178 | 8181 |
#ifndef CONFIG_USER_ONLY |
8179 |
op2 = MASK_MFMC0(ctx->opcode); |
|
8180 |
{ |
|
8182 |
if (!env->user_mode_only) { |
|
8181 | 8183 |
TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); |
8182 | 8184 |
|
8185 |
op2 = MASK_MFMC0(ctx->opcode); |
|
8183 | 8186 |
switch (op2) { |
8184 | 8187 |
case OPC_DMT: |
8185 | 8188 |
check_insn(env, ctx, ASE_MT); |
... | ... | |
8219 | 8222 |
gen_store_gpr(t0, rt); |
8220 | 8223 |
tcg_temp_free(t0); |
8221 | 8224 |
} |
8222 |
#endif |
|
8225 |
#endif /* !CONFIG_USER_ONLY */
|
|
8223 | 8226 |
break; |
8224 | 8227 |
case OPC_RDPGPR: |
8225 | 8228 |
check_insn(env, ctx, ISA_MIPS32R2); |
... | ... | |
8474 | 8477 |
/* Restore delay slot state from the tb context. */ |
8475 | 8478 |
ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */ |
8476 | 8479 |
restore_cpu_state(env, &ctx); |
8477 |
#if defined(CONFIG_USER_ONLY) |
|
8478 |
ctx.mem_idx = MIPS_HFLAG_UM; |
|
8479 |
#else |
|
8480 |
ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU; |
|
8481 |
#endif |
|
8480 |
if (env->user_mode_only) |
|
8481 |
ctx.mem_idx = MIPS_HFLAG_UM; |
|
8482 |
else |
|
8483 |
ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU; |
|
8482 | 8484 |
num_insns = 0; |
8483 | 8485 |
max_insns = tb->cflags & CF_COUNT_MASK; |
8484 | 8486 |
if (max_insns == 0) |
... | ... | |
8759 | 8761 |
tlb_flush(env, 1); |
8760 | 8762 |
|
8761 | 8763 |
/* Minimal init */ |
8762 |
#if !defined(CONFIG_USER_ONLY)
|
|
8763 |
if (env->hflags & MIPS_HFLAG_BMASK) {
|
|
8764 |
/* If the exception was raised from a delay slot,
|
|
8765 |
* come back to the jump. */
|
|
8766 |
env->CP0_ErrorEPC = env->active_tc.PC - 4;
|
|
8764 |
#if defined(CONFIG_USER_ONLY) |
|
8765 |
env->user_mode_only = 1;
|
|
8766 |
#endif
|
|
8767 |
if (env->user_mode_only) {
|
|
8768 |
env->hflags = MIPS_HFLAG_UM;
|
|
8767 | 8769 |
} else { |
8768 |
env->CP0_ErrorEPC = env->active_tc.PC; |
|
8769 |
} |
|
8770 |
env->active_tc.PC = (int32_t)0xBFC00000; |
|
8771 |
env->CP0_Wired = 0; |
|
8772 |
/* SMP not implemented */ |
|
8773 |
env->CP0_EBase = 0x80000000; |
|
8774 |
env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL); |
|
8775 |
/* vectored interrupts not implemented, timer on int 7, |
|
8776 |
no performance counters. */ |
|
8777 |
env->CP0_IntCtl = 0xe0000000; |
|
8778 |
{ |
|
8779 |
int i; |
|
8780 |
|
|
8781 |
for (i = 0; i < 7; i++) { |
|
8782 |
env->CP0_WatchLo[i] = 0; |
|
8783 |
env->CP0_WatchHi[i] = 0x80000000; |
|
8770 |
if (env->hflags & MIPS_HFLAG_BMASK) { |
|
8771 |
/* If the exception was raised from a delay slot, |
|
8772 |
come back to the jump. */ |
|
8773 |
env->CP0_ErrorEPC = env->active_tc.PC - 4; |
|
8774 |
} else { |
|
8775 |
env->CP0_ErrorEPC = env->active_tc.PC; |
|
8776 |
} |
|
8777 |
env->active_tc.PC = (int32_t)0xBFC00000; |
|
8778 |
env->CP0_Wired = 0; |
|
8779 |
/* SMP not implemented */ |
|
8780 |
env->CP0_EBase = 0x80000000; |
|
8781 |
env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL); |
|
8782 |
/* vectored interrupts not implemented, timer on int 7, |
|
8783 |
no performance counters. */ |
|
8784 |
env->CP0_IntCtl = 0xe0000000; |
|
8785 |
{ |
|
8786 |
int i; |
|
8787 |
|
|
8788 |
for (i = 0; i < 7; i++) { |
|
8789 |
env->CP0_WatchLo[i] = 0; |
|
8790 |
env->CP0_WatchHi[i] = 0x80000000; |
|
8791 |
} |
|
8792 |
env->CP0_WatchLo[7] = 0; |
|
8793 |
env->CP0_WatchHi[7] = 0; |
|
8784 | 8794 |
} |
8785 |
env->CP0_WatchLo[7] = 0; |
|
8786 |
env->CP0_WatchHi[7] = 0; |
|
8795 |
/* Count register increments in debug mode, EJTAG version 1 */ |
|
8796 |
env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER); |
|
8797 |
env->hflags = MIPS_HFLAG_CP0; |
|
8787 | 8798 |
} |
8788 |
/* Count register increments in debug mode, EJTAG version 1 */ |
|
8789 |
env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER); |
|
8790 |
#endif |
|
8791 | 8799 |
env->exception_index = EXCP_NONE; |
8792 |
#if defined(CONFIG_USER_ONLY) |
|
8793 |
env->hflags = MIPS_HFLAG_UM; |
|
8794 |
env->user_mode_only = 1; |
|
8795 |
#else |
|
8796 |
env->hflags = MIPS_HFLAG_CP0; |
|
8797 |
#endif |
|
8798 | 8800 |
cpu_mips_register(env, env->cpu_model); |
8799 | 8801 |
} |
8800 | 8802 |
|
Also available in: Unified diff