This is the maximum that was ever supported, in the PA-8700 thru
PA-8900. If we support a larger address space than expected, we
trip up software that did not fill in all of the page table bits,
expecting them to be ignored.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/hppa/cpu-param.h | 2 +-
target/hppa/mem_helper.c | 50 ++++++++++++++++++++++++++--------------
2 files changed, 34 insertions(+), 18 deletions(-)
diff --git a/target/hppa/cpu-param.h b/target/hppa/cpu-param.h
index 6746869a3b..7a8b216133 100644
--- a/target/hppa/cpu-param.h
+++ b/target/hppa/cpu-param.h
@@ -14,7 +14,7 @@
# define TARGET_PHYS_ADDR_SPACE_BITS 32
# define TARGET_VIRT_ADDR_SPACE_BITS 32
#else
-# define TARGET_PHYS_ADDR_SPACE_BITS 64
+# define TARGET_PHYS_ADDR_SPACE_BITS 44
# define TARGET_VIRT_ADDR_SPACE_BITS 64
#endif
diff --git a/target/hppa/mem_helper.c b/target/hppa/mem_helper.c
index 7bc456d4ee..08abd1a9f9 100644
--- a/target/hppa/mem_helper.c
+++ b/target/hppa/mem_helper.c
@@ -27,30 +27,39 @@
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);
+ /*
+ * Figure H-8 "62-bit Absolute Accesses when PSW W-bit is 1" describes
+ * an algorithm in which a 62-bit absolute address is transformed to
+ * a 64-bit physical address. This must then be combined with that
+ * pictured in Figure H-11 "Physical Address Space Mapping", in which
+ * the full physical address is truncated to the N-bit physical address
+ * supported by the implementation.
+ *
+ * Since the supported physical address space is below 54 bits, the
+ * H-8 algorithm is moot and all that is left is to truncate.
+ */
+ QEMU_BUILD_BUG_ON(TARGET_PHYS_ADDR_SPACE_BITS > 54);
+ return sextract64(addr, 0, TARGET_PHYS_ADDR_SPACE_BITS);
}
hwaddr hppa_abs_to_phys_pa2_w0(vaddr addr)
{
+ /*
+ * See Figure H-10, "Absolute Accesses when PSW W-bit is 0",
+ * combined with Figure H-11, as above.
+ */
if (likely(extract32(addr, 28, 4) != 0xf)) {
/* Memory address space */
- return addr & MAKE_64BIT_MASK(0, 32);
- }
- if (extract32(addr, 24, 4) != 0) {
+ addr = (uint32_t)addr;
+ } else if (extract32(addr, 24, 4) != 0) {
/* I/O address space */
- return addr | MAKE_64BIT_MASK(32, 32);
+ addr = (int32_t)addr;
+ } else {
+ /* PDC address space */
+ addr &= MAKE_64BIT_MASK(0, 24);
+ addr |= -1ull << (TARGET_PHYS_ADDR_SPACE_BITS - 4);
}
- /* PDC address space */
- return (addr & MAKE_64BIT_MASK(0, 24)) | MAKE_64BIT_MASK(60, 4);
+ return addr;
}
static HPPATLBEntry *hppa_find_tlb(CPUHPPAState *env, vaddr addr)
@@ -460,7 +469,14 @@ static void itlbt_pa20(CPUHPPAState *env, target_ulong r1,
ent->itree.start = va_b;
ent->itree.last = va_e;
- ent->pa = (r1 << 7) & (TARGET_PAGE_MASK << mask_shift);
+
+ /* Extract all 52 bits present in the page table entry. */
+ ent->pa = r1 << (TARGET_PAGE_BITS - 5);
+ /* Align per the page size. */
+ ent->pa &= TARGET_PAGE_MASK << mask_shift;
+ /* Ignore the bits beyond physical address space. */
+ ent->pa = sextract64(ent->pa, 0, TARGET_PHYS_ADDR_SPACE_BITS);
+
ent->t = extract64(r2, 61, 1);
ent->d = extract64(r2, 60, 1);
ent->b = extract64(r2, 59, 1);
--
2.34.1