diff options
Diffstat (limited to 'target-alpha')
-rw-r--r-- | target-alpha/cpu.h | 37 | ||||
-rw-r--r-- | target-alpha/translate.c | 7 |
2 files changed, 32 insertions, 12 deletions
diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h index 0daa5563ec..6b9deb394c 100644 --- a/target-alpha/cpu.h +++ b/target-alpha/cpu.h @@ -317,9 +317,34 @@ enum { IPR_LAST, }; -typedef struct CPUAlphaState CPUAlphaState; +/* MMU modes definitions */ + +/* Alpha has 5 MMU modes: PALcode, kernel, executive, supervisor, and user. + The Unix PALcode only exposes the kernel and user modes; presumably + executive and supervisor are used by VMS. + + PALcode itself uses physical mode for code and kernel mode for data; + there are PALmode instructions that can access data via physical mode + or via an os-installed "alternate mode", which is one of the 4 above. + + QEMU does not currently properly distinguish between code/data when + looking up addresses. To avoid having to address this issue, our + emulated PALcode will cheat and use the KSEG mapping for its code+data + rather than physical addresses. + + Moreover, we're only emulating Unix PALcode, and not attempting VMS. + + All of which allows us to drop all but kernel and user modes. + Elide the unused MMU modes to save space. */ -#define NB_MMU_MODES 4 +#define NB_MMU_MODES 2 + +#define MMU_MODE0_SUFFIX _kernel +#define MMU_MODE1_SUFFIX _user +#define MMU_KERNEL_IDX 0 +#define MMU_USER_IDX 1 + +typedef struct CPUAlphaState CPUAlphaState; struct CPUAlphaState { uint64_t ir[31]; @@ -370,15 +395,9 @@ struct CPUAlphaState { #define cpu_gen_code cpu_alpha_gen_code #define cpu_signal_handler cpu_alpha_signal_handler -/* MMU modes definitions */ -#define MMU_MODE0_SUFFIX _kernel -#define MMU_MODE1_SUFFIX _executive -#define MMU_MODE2_SUFFIX _supervisor -#define MMU_MODE3_SUFFIX _user -#define MMU_USER_IDX 3 static inline int cpu_mmu_index (CPUState *env) { - return (env->ps >> 3) & 3; + return (env->ps >> 3) & 1; } #include "cpu-all.h" diff --git a/target-alpha/translate.c b/target-alpha/translate.c index 851a045681..2c0b9c2e6f 100644 --- a/target-alpha/translate.c +++ b/target-alpha/translate.c @@ -1522,8 +1522,9 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) #ifndef CONFIG_USER_ONLY if (palcode < 0x40) { /* Privileged PAL code */ - if (ctx->mem_idx & 1) + if (ctx->mem_idx != MMU_KERNEL_IDX) { goto invalid_opc; + } ret = gen_excp(ctx, EXCP_CALL_PALP + ((palcode & 0x3F) << 6), 0); } #endif @@ -2651,11 +2652,11 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) goto invalid_opc; case 0xA: /* Longword virtual access with protection check (hw_ldl/w) */ - tcg_gen_qemu_ld32s(cpu_ir[ra], addr, 0); + tcg_gen_qemu_ld32s(cpu_ir[ra], addr, MMU_KERNEL_IDX); break; case 0xB: /* Quadword virtual access with protection check (hw_ldq/w) */ - tcg_gen_qemu_ld64(cpu_ir[ra], addr, 0); + tcg_gen_qemu_ld64(cpu_ir[ra], addr, MMU_KERNEL_IDX); break; case 0xC: /* Longword virtual access with alt access mode (hw_ldl/a)*/ |