[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v4 3/5] target/ppc: add hash MMU definitions for ISA
From: |
Cédric Le Goater |
Subject: |
[Qemu-devel] [PATCH v4 3/5] target/ppc: add hash MMU definitions for ISA v3.0 |
Date: |
Tue, 24 Apr 2018 13:30:43 +0200 |
The HPTE bits definitions are slightly modified in ISA v3.0. Let's add
some helpers to hide the differences in the hash MMU code.
Signed-off-by: Cédric Le Goater <address@hidden>
---
hw/ppc/spapr_hcall.c | 5 +++--
target/ppc/mmu-hash64.c | 30 ++++++++++++++++++++++--------
target/ppc/mmu-hash64.h | 30 ++++++++++++++++++++++++++++++
3 files changed, 55 insertions(+), 10 deletions(-)
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index 16bccdd5c012..929f4e05492d 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -94,7 +94,7 @@ static target_ulong h_enter(PowerPCCPU *cpu,
sPAPRMachineState *spapr,
return H_PARAMETER;
}
- raddr = (ptel & HPTE64_R_RPN) & ~((1ULL << apshift) - 1);
+ raddr = (ptel & ppc_hash64_hpte_r_rpn(cpu)) & ~((1ULL << apshift) - 1);
if (is_ram_address(spapr, raddr)) {
/* Regular RAM - should have WIMG=0010 */
@@ -586,7 +586,8 @@ static int rehash_hpte(PowerPCCPU *cpu,
base_pg_shift = ppc_hash64_hpte_page_shift_noslb(cpu, pte0, pte1);
assert(base_pg_shift); /* H_ENTER shouldn't allow a bad encoding */
- avpn = HPTE64_V_AVPN_VAL(pte0) & ~(((1ULL << base_pg_shift) - 1) >> 23);
+ avpn = ppc_hash64_hpte_v_avpn_val(cpu, pte0) &
+ ~(((1ULL << base_pg_shift) - 1) >> 23);
if (pte0 & HPTE64_V_SECONDARY) {
pteg = ~pteg;
diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c
index a1db20e3a8ed..ecea2ae04dd3 100644
--- a/target/ppc/mmu-hash64.c
+++ b/target/ppc/mmu-hash64.c
@@ -452,7 +452,8 @@ void ppc_hash64_unmap_hptes(PowerPCCPU *cpu, const
ppc_hash_pte64_t *hptes,
false, n * HASH_PTE_SIZE_64);
}
-static unsigned hpte_page_shift(const PPCHash64SegmentPageSizes *sps,
+static unsigned hpte_page_shift(PowerPCCPU *cpu,
+ const PPCHash64SegmentPageSizes *sps,
uint64_t pte0, uint64_t pte1)
{
int i;
@@ -479,7 +480,7 @@ static unsigned hpte_page_shift(const
PPCHash64SegmentPageSizes *sps,
continue;
}
- mask = ((1ULL << ps->page_shift) - 1) & HPTE64_R_RPN;
+ mask = ((1ULL << ps->page_shift) - 1) & ppc_hash64_hpte_r_rpn(cpu);
if ((pte1 & mask) == ((uint64_t)ps->pte_enc << HPTE64_R_RPN_SHIFT)) {
return ps->page_shift;
@@ -489,6 +490,18 @@ static unsigned hpte_page_shift(const
PPCHash64SegmentPageSizes *sps,
return 0; /* Bad page size encoding */
}
+static bool ppc_hash64_hpte_v_compare(PowerPCCPU *cpu, target_ulong pte0,
+ target_ulong ptem)
+{
+ CPUPPCState *env = &cpu->env;
+
+ if (env->mmu_model & POWERPC_MMU_3_00) {
+ return HPTE64_V_COMPARE_3_0(pte0, ptem);
+ } else {
+ return HPTE64_V_COMPARE(pte0, ptem);
+ }
+}
+
static hwaddr ppc_hash64_pteg_search(PowerPCCPU *cpu, hwaddr hash,
const PPCHash64SegmentPageSizes *sps,
target_ulong ptem,
@@ -509,8 +522,8 @@ static hwaddr ppc_hash64_pteg_search(PowerPCCPU *cpu,
hwaddr hash,
pte1 = ppc_hash64_hpte1(cpu, pteg, i);
/* This compares V, B, H (secondary) and the AVPN */
- if (HPTE64_V_COMPARE(pte0, ptem)) {
- *pshift = hpte_page_shift(sps, pte0, pte1);
+ if (ppc_hash64_hpte_v_compare(cpu, pte0, ptem)) {
+ *pshift = hpte_page_shift(cpu, sps, pte0, pte1);
/*
* If there is no match, ignore the PTE, it could simply
* be for a different segment size encoding and the
@@ -570,7 +583,8 @@ static hwaddr ppc_hash64_htab_lookup(PowerPCCPU *cpu,
epn = (eaddr & ~SEGMENT_MASK_256M) & epnmask;
hash = vsid ^ (epn >> sps->page_shift);
}
- ptem = (slb->vsid & SLB_VSID_PTEM) | ((epn >> 16) & HPTE64_V_AVPN);
+ ptem = (slb->vsid & SLB_VSID_PTEM) | ((epn >> 16) &
+ ppc_hash64_hpte_v_avpn(cpu));
ptem |= HPTE64_V_VALID;
/* Page address translation */
@@ -624,7 +638,7 @@ unsigned ppc_hash64_hpte_page_shift_noslb(PowerPCCPU *cpu,
break;
}
- shift = hpte_page_shift(sps, pte0, pte1);
+ shift = hpte_page_shift(cpu, sps, pte0, pte1);
if (shift) {
return shift;
}
@@ -860,7 +874,7 @@ skip_slb_search:
/* 7. Determine the real address from the PTE */
- raddr = deposit64(pte.pte1 & HPTE64_R_RPN, 0, apshift, eaddr);
+ raddr = deposit64(pte.pte1 & ppc_hash64_hpte_r_rpn(cpu), 0, apshift,
eaddr);
tlb_set_page(cs, eaddr & TARGET_PAGE_MASK, raddr & TARGET_PAGE_MASK,
prot, mmu_idx, 1ULL << apshift);
@@ -910,7 +924,7 @@ hwaddr ppc_hash64_get_phys_page_debug(PowerPCCPU *cpu,
target_ulong addr)
return -1;
}
- return deposit64(pte.pte1 & HPTE64_R_RPN, 0, apshift, addr)
+ return deposit64(pte.pte1 & ppc_hash64_hpte_r_rpn(cpu), 0, apshift, addr)
& TARGET_PAGE_MASK;
}
diff --git a/target/ppc/mmu-hash64.h b/target/ppc/mmu-hash64.h
index 53dcec5b9316..a3a0de452b94 100644
--- a/target/ppc/mmu-hash64.h
+++ b/target/ppc/mmu-hash64.h
@@ -70,8 +70,12 @@ void ppc_hash64_finalize(PowerPCCPU *cpu);
#define HPTE64_V_SSIZE_SHIFT 62
#define HPTE64_V_AVPN_SHIFT 7
#define HPTE64_V_AVPN 0x3fffffffffffff80ULL
+#define HPTE64_V_AVPN_3_0 0x000fffffffffff80ULL
#define HPTE64_V_AVPN_VAL(x) (((x) & HPTE64_V_AVPN) >> HPTE64_V_AVPN_SHIFT)
+#define HPTE64_V_AVPN_VAL_3_0(x) \
+ (((x) & HPTE64_V_AVPN_3_0) >> HPTE64_V_AVPN_SHIFT)
#define HPTE64_V_COMPARE(x, y) (!(((x) ^ (y)) & 0xffffffffffffff83ULL))
+#define HPTE64_V_COMPARE_3_0(x, y) (!(((x) ^ (y)) & 0x3fffffffffffff83ULL))
#define HPTE64_V_BOLTED 0x0000000000000010ULL
#define HPTE64_V_LARGE 0x0000000000000004ULL
#define HPTE64_V_SECONDARY 0x0000000000000002ULL
@@ -82,6 +86,7 @@ void ppc_hash64_finalize(PowerPCCPU *cpu);
#define HPTE64_R_KEY_HI 0x3000000000000000ULL
#define HPTE64_R_RPN_SHIFT 12
#define HPTE64_R_RPN 0x0ffffffffffff000ULL
+#define HPTE64_R_RPN_3_0 0x01fffffffffff000ULL
#define HPTE64_R_FLAGS 0x00000000000003ffULL
#define HPTE64_R_PP 0x0000000000000003ULL
#define HPTE64_R_N 0x0000000000000004ULL
@@ -99,6 +104,31 @@ void ppc_hash64_finalize(PowerPCCPU *cpu);
#define HPTE64_V_1TB_SEG 0x4000000000000000ULL
#define HPTE64_V_VRMA_MASK 0x4001ffffff000000ULL
+static inline target_ulong ppc_hash64_hpte_r_rpn(PowerPCCPU *cpu)
+{
+ CPUPPCState *env = &cpu->env;
+
+ return env->mmu_model & POWERPC_MMU_3_00 ?
+ HPTE64_R_RPN_3_0 : HPTE64_R_RPN;
+}
+
+static inline target_ulong ppc_hash64_hpte_v_avpn(PowerPCCPU *cpu)
+{
+ CPUPPCState *env = &cpu->env;
+
+ return env->mmu_model & POWERPC_MMU_3_00 ?
+ HPTE64_V_AVPN_3_0 : HPTE64_V_AVPN;
+}
+
+static inline target_ulong ppc_hash64_hpte_v_avpn_val(PowerPCCPU *cpu,
+ target_ulong pte0)
+{
+ CPUPPCState *env = &cpu->env;
+
+ return env->mmu_model & POWERPC_MMU_3_00 ?
+ HPTE64_V_AVPN_VAL_3_0(pte0) : HPTE64_V_AVPN_VAL(pte0);
+}
+
static inline hwaddr ppc_hash64_hpt_base(PowerPCCPU *cpu)
{
if (cpu->vhyp) {
--
2.13.6