aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2023-09-17 14:54:16 -0700
committerRichard Henderson <richard.henderson@linaro.org>2023-11-06 18:49:33 -0800
commitccdf741c48db62319539a31bb5ae73a67316b295 (patch)
tree0b5a7770614d852d508b5109789f0c8b6d98587c
parent931adff3147826a27748c9cdc862cacfd0807a92 (diff)
downloadqemu-ccdf741c48db62319539a31bb5ae73a67316b295.zip
qemu-ccdf741c48db62319539a31bb5ae73a67316b295.tar.gz
qemu-ccdf741c48db62319539a31bb5ae73a67316b295.tar.bz2
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 <richard.henderson@linaro.org>
-rw-r--r--target/hppa/cpu.h3
-rw-r--r--target/hppa/mem_helper.c43
2 files changed, 44 insertions, 2 deletions
diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
index 301c821..2999df9 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 327fb20..420b43a 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,