mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-05 00:33:55 -06:00
target/hppa: Replace MMU_PHYS_IDX with MMU_ABS_IDX, MMU_ABS_W_IDX
Align the language with pa2.0, separating absolute and physical. The translation from absolute to physical depends on PSW.W, and we prefer not to flush between changes, therefore use 2 mmu_idx. Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
17fe594c59
commit
451d993d58
3 changed files with 38 additions and 35 deletions
|
@ -31,24 +31,25 @@
|
||||||
basis. It's probably easier to fall back to a strong memory model. */
|
basis. It's probably easier to fall back to a strong memory model. */
|
||||||
#define TCG_GUEST_DEFAULT_MO TCG_MO_ALL
|
#define TCG_GUEST_DEFAULT_MO TCG_MO_ALL
|
||||||
|
|
||||||
#define MMU_KERNEL_IDX 7
|
#define MMU_ABS_W_IDX 6
|
||||||
#define MMU_KERNEL_P_IDX 8
|
#define MMU_ABS_IDX 7
|
||||||
#define MMU_PL1_IDX 9
|
#define MMU_KERNEL_IDX 8
|
||||||
#define MMU_PL1_P_IDX 10
|
#define MMU_KERNEL_P_IDX 9
|
||||||
#define MMU_PL2_IDX 11
|
#define MMU_PL1_IDX 10
|
||||||
#define MMU_PL2_P_IDX 12
|
#define MMU_PL1_P_IDX 11
|
||||||
#define MMU_USER_IDX 13
|
#define MMU_PL2_IDX 12
|
||||||
#define MMU_USER_P_IDX 14
|
#define MMU_PL2_P_IDX 13
|
||||||
#define MMU_PHYS_IDX 15
|
#define MMU_USER_IDX 14
|
||||||
|
#define MMU_USER_P_IDX 15
|
||||||
|
|
||||||
#define MMU_IDX_MMU_DISABLED(MIDX) ((MIDX) == MMU_PHYS_IDX)
|
#define MMU_IDX_MMU_DISABLED(MIDX) ((MIDX) < MMU_KERNEL_IDX)
|
||||||
#define MMU_IDX_TO_PRIV(MIDX) (((MIDX) - MMU_KERNEL_IDX) / 2)
|
#define MMU_IDX_TO_PRIV(MIDX) (((MIDX) - MMU_KERNEL_IDX) / 2)
|
||||||
#define MMU_IDX_TO_P(MIDX) (((MIDX) - MMU_KERNEL_IDX) & 1)
|
#define MMU_IDX_TO_P(MIDX) (((MIDX) - MMU_KERNEL_IDX) & 1)
|
||||||
#define PRIV_P_TO_MMU_IDX(PRIV, P) ((PRIV) * 2 + !!(P) + MMU_KERNEL_IDX)
|
#define PRIV_P_TO_MMU_IDX(PRIV, P) ((PRIV) * 2 + !!(P) + MMU_KERNEL_IDX)
|
||||||
|
|
||||||
#define TARGET_INSN_START_EXTRA_WORDS 2
|
#define TARGET_INSN_START_EXTRA_WORDS 2
|
||||||
|
|
||||||
/* No need to flush MMU_PHYS_IDX */
|
/* No need to flush MMU_ABS*_IDX */
|
||||||
#define HPPA_MMU_FLUSH_MASK \
|
#define HPPA_MMU_FLUSH_MASK \
|
||||||
(1 << MMU_KERNEL_IDX | 1 << MMU_KERNEL_P_IDX | \
|
(1 << MMU_KERNEL_IDX | 1 << MMU_KERNEL_P_IDX | \
|
||||||
1 << MMU_PL1_IDX | 1 << MMU_PL1_P_IDX | \
|
1 << MMU_PL1_IDX | 1 << MMU_PL1_P_IDX | \
|
||||||
|
@ -288,7 +289,8 @@ static inline int cpu_mmu_index(CPUHPPAState *env, bool ifetch)
|
||||||
if (env->psw & (ifetch ? PSW_C : PSW_D)) {
|
if (env->psw & (ifetch ? PSW_C : PSW_D)) {
|
||||||
return PRIV_P_TO_MMU_IDX(env->iaoq_f & 3, env->psw & PSW_P);
|
return PRIV_P_TO_MMU_IDX(env->iaoq_f & 3, env->psw & PSW_P);
|
||||||
}
|
}
|
||||||
return MMU_PHYS_IDX; /* mmu disabled */
|
/* mmu disabled */
|
||||||
|
return env->psw & PSW_W ? MMU_ABS_W_IDX : MMU_ABS_IDX;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,17 +53,6 @@ hwaddr hppa_abs_to_phys_pa2_w0(vaddr addr)
|
||||||
return (addr & MAKE_64BIT_MASK(0, 24)) | MAKE_64BIT_MASK(60, 4);
|
return (addr & MAKE_64BIT_MASK(0, 24)) | MAKE_64BIT_MASK(60, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
static hwaddr hppa_abs_to_phys(CPUHPPAState *env, vaddr addr)
|
|
||||||
{
|
|
||||||
if (!hppa_is_pa20(env)) {
|
|
||||||
return addr;
|
|
||||||
} else if (env->psw & PSW_W) {
|
|
||||||
return hppa_abs_to_phys_pa2_w1(addr);
|
|
||||||
} else {
|
|
||||||
return hppa_abs_to_phys_pa2_w0(addr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static HPPATLBEntry *hppa_find_tlb(CPUHPPAState *env, vaddr addr)
|
static HPPATLBEntry *hppa_find_tlb(CPUHPPAState *env, vaddr addr)
|
||||||
{
|
{
|
||||||
IntervalTreeNode *i = interval_tree_iter_first(&env->tlb_root, addr, addr);
|
IntervalTreeNode *i = interval_tree_iter_first(&env->tlb_root, addr, addr);
|
||||||
|
@ -161,9 +150,22 @@ int hppa_get_physical_address(CPUHPPAState *env, vaddr addr, int mmu_idx,
|
||||||
*tlb_entry = NULL;
|
*tlb_entry = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Virtual translation disabled. Direct map virtual to physical. */
|
/* Virtual translation disabled. Map absolute to physical. */
|
||||||
if (mmu_idx == MMU_PHYS_IDX) {
|
if (MMU_IDX_MMU_DISABLED(mmu_idx)) {
|
||||||
phys = addr;
|
switch (mmu_idx) {
|
||||||
|
case MMU_ABS_W_IDX:
|
||||||
|
phys = hppa_abs_to_phys_pa2_w1(addr);
|
||||||
|
break;
|
||||||
|
case MMU_ABS_IDX:
|
||||||
|
if (hppa_is_pa20(env)) {
|
||||||
|
phys = hppa_abs_to_phys_pa2_w0(addr);
|
||||||
|
} else {
|
||||||
|
phys = (uint32_t)addr;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_assert_not_reached();
|
||||||
|
}
|
||||||
prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
|
prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
|
||||||
goto egress;
|
goto egress;
|
||||||
}
|
}
|
||||||
|
@ -261,7 +263,7 @@ int hppa_get_physical_address(CPUHPPAState *env, vaddr addr, int mmu_idx,
|
||||||
}
|
}
|
||||||
|
|
||||||
egress:
|
egress:
|
||||||
*pphys = phys = hppa_abs_to_phys(env, phys);
|
*pphys = phys;
|
||||||
*pprot = prot;
|
*pprot = prot;
|
||||||
trace_hppa_tlb_get_physical_address(env, ret, prot, addr, phys);
|
trace_hppa_tlb_get_physical_address(env, ret, prot, addr, phys);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -271,16 +273,15 @@ hwaddr hppa_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
|
||||||
{
|
{
|
||||||
HPPACPU *cpu = HPPA_CPU(cs);
|
HPPACPU *cpu = HPPA_CPU(cs);
|
||||||
hwaddr phys;
|
hwaddr phys;
|
||||||
int prot, excp;
|
int prot, excp, mmu_idx;
|
||||||
|
|
||||||
/* If the (data) mmu is disabled, bypass translation. */
|
/* If the (data) mmu is disabled, bypass translation. */
|
||||||
/* ??? We really ought to know if the code mmu is disabled too,
|
/* ??? We really ought to know if the code mmu is disabled too,
|
||||||
in order to get the correct debugging dumps. */
|
in order to get the correct debugging dumps. */
|
||||||
if (!(cpu->env.psw & PSW_D)) {
|
mmu_idx = (cpu->env.psw & PSW_D ? MMU_KERNEL_IDX :
|
||||||
return hppa_abs_to_phys(&cpu->env, addr);
|
cpu->env.psw & PSW_W ? MMU_ABS_W_IDX : MMU_ABS_IDX);
|
||||||
}
|
|
||||||
|
|
||||||
excp = hppa_get_physical_address(&cpu->env, addr, MMU_KERNEL_IDX, 0,
|
excp = hppa_get_physical_address(&cpu->env, addr, mmu_idx, 0,
|
||||||
&phys, &prot, NULL);
|
&phys, &prot, NULL);
|
||||||
|
|
||||||
/* Since we're translating for debugging, the only error that is a
|
/* Since we're translating for debugging, the only error that is a
|
||||||
|
|
|
@ -3172,7 +3172,7 @@ static bool trans_lda(DisasContext *ctx, arg_ldst *a)
|
||||||
int hold_mmu_idx = ctx->mmu_idx;
|
int hold_mmu_idx = ctx->mmu_idx;
|
||||||
|
|
||||||
CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
|
CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
|
||||||
ctx->mmu_idx = MMU_PHYS_IDX;
|
ctx->mmu_idx = ctx->tb_flags & PSW_W ? MMU_ABS_W_IDX : MMU_ABS_IDX;
|
||||||
trans_ld(ctx, a);
|
trans_ld(ctx, a);
|
||||||
ctx->mmu_idx = hold_mmu_idx;
|
ctx->mmu_idx = hold_mmu_idx;
|
||||||
return true;
|
return true;
|
||||||
|
@ -3183,7 +3183,7 @@ static bool trans_sta(DisasContext *ctx, arg_ldst *a)
|
||||||
int hold_mmu_idx = ctx->mmu_idx;
|
int hold_mmu_idx = ctx->mmu_idx;
|
||||||
|
|
||||||
CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
|
CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
|
||||||
ctx->mmu_idx = MMU_PHYS_IDX;
|
ctx->mmu_idx = ctx->tb_flags & PSW_W ? MMU_ABS_W_IDX : MMU_ABS_IDX;
|
||||||
trans_st(ctx, a);
|
trans_st(ctx, a);
|
||||||
ctx->mmu_idx = hold_mmu_idx;
|
ctx->mmu_idx = hold_mmu_idx;
|
||||||
return true;
|
return true;
|
||||||
|
@ -4435,7 +4435,7 @@ static void hppa_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
|
||||||
ctx->privilege = (ctx->tb_flags >> TB_FLAG_PRIV_SHIFT) & 3;
|
ctx->privilege = (ctx->tb_flags >> TB_FLAG_PRIV_SHIFT) & 3;
|
||||||
ctx->mmu_idx = (ctx->tb_flags & PSW_D
|
ctx->mmu_idx = (ctx->tb_flags & PSW_D
|
||||||
? PRIV_P_TO_MMU_IDX(ctx->privilege, ctx->tb_flags & PSW_P)
|
? PRIV_P_TO_MMU_IDX(ctx->privilege, ctx->tb_flags & PSW_P)
|
||||||
: MMU_PHYS_IDX);
|
: ctx->tb_flags & PSW_W ? MMU_ABS_W_IDX : MMU_ABS_IDX);
|
||||||
|
|
||||||
/* Recover the IAOQ values from the GVA + PRIV. */
|
/* Recover the IAOQ values from the GVA + PRIV. */
|
||||||
uint64_t cs_base = ctx->base.tb->cs_base;
|
uint64_t cs_base = ctx->base.tb->cs_base;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue