From: "Cédric Le Goater" <clg@kaod.org>
To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org,
David Gibson <david@gibson.dropbear.id.au>
Cc: "Suraj Jitindar Singh" <sjitindarsingh@gmail.com>,
"Cédric Le Goater" <clg@kaod.org>
Subject: [Qemu-devel] [PATCH 2/3] target/ppc: add hash MMU support on POWER9 for PowerNV only
Date: Wed, 31 Jan 2018 09:27:48 +0100 [thread overview]
Message-ID: <20180131082749.1803-3-clg@kaod.org> (raw)
In-Reply-To: <20180131082749.1803-1-clg@kaod.org>
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.
On a POWER9 processor, the Partition Table is composed of a pair of
doublewords per partition. The first doubleword indicates whether the
partition uses HPT or Radix Trees translation and contains the address
of the host's translation table structure and size.
The first doubleword of the PTCR holds the Hash Page Table base
address for the host when the hash MMU is in use. Also add an helper
to retrieve the HPT base address depending on the MMU revision.
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
hw/ppc/spapr_hcall.c | 5 +++--
target/ppc/mmu-hash64.c | 48 +++++++++++++++++++++++++++++++++++++++---------
target/ppc/mmu-hash64.h | 34 ++++++++++++++++++++++++++++++++--
3 files changed, 74 insertions(+), 13 deletions(-)
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index 3fda7fd39da1..30cfc1f450cc 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 14d34e512f42..54f052ad717c 100644
--- a/target/ppc/mmu-hash64.c
+++ b/target/ppc/mmu-hash64.c
@@ -290,6 +290,22 @@ target_ulong helper_load_slb_vsid(CPUPPCState *env, target_ulong rb)
return rt;
}
+hwaddr ppc_hash64_hpt_reg(PowerPCCPU *cpu)
+{
+ CPUPPCState *env = &cpu->env;
+
+ if (env->mmu_model & POWERPC_MMU_V3) {
+ if (msr_hv) {
+ return ldq_phys(CPU(cpu)->as, cpu->env.spr[SPR_PTCR] & PTCR_PTAB);
+ } else {
+ error_report("HPT Support Unimplemented");
+ exit(1);
+ }
+ } else {
+ return cpu->env.spr[SPR_SDR1];
+ }
+}
+
/* Check No-Execute or Guarded Storage */
static inline int ppc_hash64_pte_noexec_guard(PowerPCCPU *cpu,
ppc_hash_pte64_t pte)
@@ -452,8 +468,9 @@ 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 struct ppc_one_seg_page_size *sps,
- uint64_t pte0, uint64_t pte1)
+static unsigned hpte_page_shift(PowerPCCPU *cpu,
+ const struct ppc_one_seg_page_size *sps,
+ uint64_t pte0, uint64_t pte1)
{
int i;
@@ -479,7 +496,7 @@ static unsigned hpte_page_shift(const struct ppc_one_seg_page_size *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 +506,18 @@ static unsigned hpte_page_shift(const struct ppc_one_seg_page_size *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_V3) {
+ 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 struct ppc_one_seg_page_size *sps,
target_ulong ptem,
@@ -509,8 +538,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 +599,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 */
@@ -625,7 +655,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;
}
@@ -861,7 +891,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);
@@ -911,7 +941,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 4fb00ac17abb..4dc6b3968ec0 100644
--- a/target/ppc/mmu-hash64.h
+++ b/target/ppc/mmu-hash64.h
@@ -69,8 +69,12 @@ void ppc_hash64_update_rmls(CPUPPCState *env);
#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
@@ -81,6 +85,7 @@ void ppc_hash64_update_rmls(CPUPPCState *env);
#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
@@ -104,9 +109,34 @@ void ppc_hash64_update_rmls(CPUPPCState *env);
#define PTCR_PTAB 0x0FFFFFFFFFFFF000ULL /* Partition Table Base */
#define PTCR_PTAS 0x000000000000001FULL /* Partition Table Size */
+static inline target_ulong ppc_hash64_hpte_r_rpn(PowerPCCPU *cpu)
+{
+ CPUPPCState *env = &cpu->env;
+
+ return env->mmu_model & POWERPC_MMU_V3 ? 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_V3 ? 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_V3 ?
+ HPTE64_V_AVPN_VAL_3_0(pte0) : HPTE64_V_AVPN_VAL(pte0);
+}
+
+hwaddr ppc_hash64_hpt_reg(PowerPCCPU *cpu);
+
static inline hwaddr ppc_hash64_hpt_base(PowerPCCPU *cpu)
{
- return cpu->env.spr[SPR_SDR1] & SDR_64_HTABORG;
+ return ppc_hash64_hpt_reg(cpu) & SDR_64_HTABORG;
}
static inline hwaddr ppc_hash64_hpt_mask(PowerPCCPU *cpu)
@@ -116,7 +146,7 @@ static inline hwaddr ppc_hash64_hpt_mask(PowerPCCPU *cpu)
PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
return vhc->hpt_mask(cpu->vhyp);
}
- return (1ULL << ((cpu->env.spr[SPR_SDR1] & SDR_64_HTABSIZE) + 18 - 7)) - 1;
+ return (1ULL << ((ppc_hash64_hpt_reg(cpu) & SDR_64_HTABSIZE) + 18 - 7)) - 1;
}
struct ppc_hash_pte64 {
--
2.13.6
next prev parent reply other threads:[~2018-01-31 8:28 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-01-31 8:27 [Qemu-devel] [PATCH 0/3] target/ppc: add hash MMU support for the POWER9 PowerNV machine Cédric Le Goater
2018-01-31 8:27 ` [Qemu-devel] [PATCH 1/3] target/ppc: add basic support for PTCR on POWER9 Cédric Le Goater
2018-02-02 2:34 ` Suraj Jitindar Singh
2018-02-02 2:41 ` Suraj Jitindar Singh
2018-02-02 14:44 ` Cédric Le Goater
2018-02-02 14:43 ` Cédric Le Goater
2018-01-31 8:27 ` Cédric Le Goater [this message]
2018-01-31 8:27 ` [Qemu-devel] [PATCH 3/3] target/ppc: generalize check on radix when in HV mode Cédric Le Goater
2018-02-02 2:43 ` Suraj Jitindar Singh
2018-02-02 14:46 ` Cédric Le Goater
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180131082749.1803-3-clg@kaod.org \
--to=clg@kaod.org \
--cc=david@gibson.dropbear.id.au \
--cc=qemu-devel@nongnu.org \
--cc=qemu-ppc@nongnu.org \
--cc=sjitindarsingh@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).