From ccdf741c48db62319539a31bb5ae73a67316b295 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sun, 17 Sep 2023 14:54:16 -0700 Subject: [PATCH] target/hppa: Handle absolute addresses for pa2.0 With pa2.0, absolute addresses are not the same as physical addresses, and undergo a transformation based on PSW_W. Signed-off-by: Richard Henderson --- target/hppa/cpu.h | 3 +++ target/hppa/mem_helper.c | 43 +++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h index 301c82114a..2999df9ff9 100644 --- a/target/hppa/cpu.h +++ b/target/hppa/cpu.h @@ -313,6 +313,9 @@ static inline target_ulong hppa_form_gva(CPUHPPAState *env, uint64_t spc, return hppa_form_gva_psw(env->psw, spc, off); } +hwaddr hppa_abs_to_phys_pa2_w0(vaddr addr); +hwaddr hppa_abs_to_phys_pa2_w1(vaddr addr); + /* * Since PSW_{I,CB} will never need to be in tb->flags, reuse them. * TB_FLAG_SR_SAME indicates that SR4 through SR7 all contain the diff --git a/target/hppa/mem_helper.c b/target/hppa/mem_helper.c index 327fb20c17..420b43a0f6 100644 --- a/target/hppa/mem_helper.c +++ b/target/hppa/mem_helper.c @@ -25,6 +25,45 @@ #include "hw/core/cpu.h" #include "trace.h" +hwaddr hppa_abs_to_phys_pa2_w1(vaddr addr) +{ + if (likely(extract64(addr, 58, 4) != 0xf)) { + /* Memory address space */ + return addr & MAKE_64BIT_MASK(0, 62); + } + if (extract64(addr, 54, 4) != 0) { + /* I/O address space */ + return addr | MAKE_64BIT_MASK(62, 2); + } + /* PDC address space */ + return (addr & MAKE_64BIT_MASK(0, 54)) | MAKE_64BIT_MASK(60, 4); +} + +hwaddr hppa_abs_to_phys_pa2_w0(vaddr addr) +{ + if (likely(extract32(addr, 28, 4) != 0xf)) { + /* Memory address space */ + return addr & MAKE_64BIT_MASK(0, 32); + } + if (extract32(addr, 24, 4) != 0) { + /* I/O address space */ + return addr | MAKE_64BIT_MASK(32, 32); + } + /* PDC address space */ + 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) { IntervalTreeNode *i = interval_tree_iter_first(&env->tlb_root, addr, addr); @@ -222,7 +261,7 @@ int hppa_get_physical_address(CPUHPPAState *env, vaddr addr, int mmu_idx, } egress: - *pphys = phys; + *pphys = phys = hppa_abs_to_phys(env, phys); *pprot = prot; trace_hppa_tlb_get_physical_address(env, ret, prot, addr, phys); return ret; @@ -238,7 +277,7 @@ hwaddr hppa_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) /* ??? We really ought to know if the code mmu is disabled too, in order to get the correct debugging dumps. */ if (!(cpu->env.psw & PSW_D)) { - return addr; + return hppa_abs_to_phys(&cpu->env, addr); } excp = hppa_get_physical_address(&cpu->env, addr, MMU_KERNEL_IDX, 0, -- 2.11.0