[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-ppc] [PATCH 24/32] mmu-hash64: Make find_pte64 do more of the job
From: |
David Gibson |
Subject: |
[Qemu-ppc] [PATCH 24/32] mmu-hash64: Make find_pte64 do more of the job of finding a pte |
Date: |
Fri, 15 Feb 2013 19:01:14 +1100 |
find_pte64() is not particularly well named. It only "finds" a PTE within
a given PTE group, and it also does permissions checking and other things.
This patch makes it somewhat close to matching the name, by folding the
search of both primary and secondary hash bucket into it, along with the
various address bit shuffling to determine the right hash buckets.
Signed-off-by: David Gibson <address@hidden>
---
target-ppc/mmu-hash64.c | 123 ++++++++++++++++++++++-------------------------
1 file changed, 57 insertions(+), 66 deletions(-)
diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c
index cb1fc02..2399b94 100644
--- a/target-ppc/mmu-hash64.c
+++ b/target-ppc/mmu-hash64.c
@@ -43,8 +43,6 @@
struct mmu_ctx_hash64 {
hwaddr raddr; /* Real address */
int prot; /* Protection bits */
- hwaddr hash[2]; /* Pagetable hash values */
- target_ulong ptem; /* Virtual segment ID | API */
int key; /* Access key */
};
@@ -378,15 +376,67 @@ static hwaddr ppc_hash64_pteg_search(CPUPPCState *env,
hwaddr pteg_off,
}
static int find_pte64(CPUPPCState *env, struct mmu_ctx_hash64 *ctx,
- target_ulong eaddr, int h, int rwx, int target_page_bits)
+ ppc_slb_t *slb, target_ulong eaddr, int rwx)
{
hwaddr pteg_off, pte_offset;
ppc_hash_pte64_t pte;
+ uint64_t vsid, pageaddr, ptem;
+ hwaddr hash;
+ int segment_bits, target_page_bits;
int ret;
ret = -1; /* No entry found */
- pteg_off = (ctx->hash[h] * HASH_PTEG_SIZE_64) & env->htab_mask;
- pte_offset = ppc_hash64_pteg_search(env, pteg_off, h, ctx->ptem, &pte);
+
+ if (slb->vsid & SLB_VSID_B) {
+ vsid = (slb->vsid & SLB_VSID_VSID) >> SLB_VSID_SHIFT_1T;
+ segment_bits = 40;
+ } else {
+ vsid = (slb->vsid & SLB_VSID_VSID) >> SLB_VSID_SHIFT;
+ segment_bits = 28;
+ }
+
+ target_page_bits = (slb->vsid & SLB_VSID_L)
+ ? TARGET_PAGE_BITS_16M : TARGET_PAGE_BITS;
+ ctx->key = !!(msr_pr ? (slb->vsid & SLB_VSID_KP)
+ : (slb->vsid & SLB_VSID_KS));
+
+ pageaddr = eaddr & ((1ULL << segment_bits)
+ - (1ULL << target_page_bits));
+ if (slb->vsid & SLB_VSID_B) {
+ hash = vsid ^ (vsid << 25) ^ (pageaddr >> target_page_bits);
+ } else {
+ hash = vsid ^ (pageaddr >> target_page_bits);
+ }
+ /* Only 5 bits of the page index are used in the AVPN */
+ ptem = (slb->vsid & SLB_VSID_PTEM) |
+ ((pageaddr >> 16) & ((1ULL << segment_bits) - 0x80));
+
+ ret = -1;
+
+ /* Page address translation */
+ LOG_MMU("htab_base " TARGET_FMT_plx " htab_mask " TARGET_FMT_plx
+ " hash " TARGET_FMT_plx "\n",
+ env->htab_base, env->htab_mask, hash);
+
+
+ /* Primary PTEG lookup */
+ LOG_MMU("0 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx
+ " vsid=" TARGET_FMT_lx " ptem=" TARGET_FMT_lx
+ " hash=" TARGET_FMT_plx "\n",
+ env->htab_base, env->htab_mask, vsid, ptem, hash);
+ pteg_off = (hash * HASH_PTEG_SIZE_64) & env->htab_mask;
+ pte_offset = ppc_hash64_pteg_search(env, pteg_off, 0, ptem, &pte);
+ if (pte_offset == -1) {
+ /* Secondary PTEG lookup */
+ LOG_MMU("1 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx
+ " vsid=" TARGET_FMT_lx " api=" TARGET_FMT_lx
+ " hash=" TARGET_FMT_plx "\n", env->htab_base,
+ env->htab_mask, vsid, ptem, ~hash);
+
+ pteg_off = (~hash * HASH_PTEG_SIZE_64) & env->htab_mask;
+ pte_offset = ppc_hash64_pteg_search(env, pteg_off, 1, ptem, &pte);
+ }
+
if (pte_offset != -1) {
ret = pte64_check(ctx, pte.pte0, pte.pte1, rwx);
LOG_MMU("found PTE at addr %08" HWADDR_PRIx " prot=%01x ret=%d\n",
@@ -409,13 +459,8 @@ static int find_pte64(CPUPPCState *env, struct
mmu_ctx_hash64 *ctx,
static int ppc_hash64_translate(CPUPPCState *env, struct mmu_ctx_hash64 *ctx,
target_ulong eaddr, int rwx)
{
- hwaddr hash;
- target_ulong vsid;
- int pr, target_page_bits;
- int ret, ret2;
+ int ret;
ppc_slb_t *slb;
- target_ulong pageaddr;
- int segment_bits;
/* 1. Handle real mode accesses */
if (((rwx == 2) && (msr_ir == 0)) || ((rwx != 2) && (msr_dr == 0))) {
@@ -438,61 +483,7 @@ static int ppc_hash64_translate(CPUPPCState *env, struct
mmu_ctx_hash64 *ctx,
return -3;
}
- pr = msr_pr;
-
- if (slb->vsid & SLB_VSID_B) {
- vsid = (slb->vsid & SLB_VSID_VSID) >> SLB_VSID_SHIFT_1T;
- segment_bits = 40;
- } else {
- vsid = (slb->vsid & SLB_VSID_VSID) >> SLB_VSID_SHIFT;
- segment_bits = 28;
- }
-
- target_page_bits = (slb->vsid & SLB_VSID_L)
- ? TARGET_PAGE_BITS_16M : TARGET_PAGE_BITS;
- ctx->key = !!(pr ? (slb->vsid & SLB_VSID_KP)
- : (slb->vsid & SLB_VSID_KS));
-
- pageaddr = eaddr & ((1ULL << segment_bits)
- - (1ULL << target_page_bits));
- if (slb->vsid & SLB_VSID_B) {
- hash = vsid ^ (vsid << 25) ^ (pageaddr >> target_page_bits);
- } else {
- hash = vsid ^ (pageaddr >> target_page_bits);
- }
- /* Only 5 bits of the page index are used in the AVPN */
- ctx->ptem = (slb->vsid & SLB_VSID_PTEM) |
- ((pageaddr >> 16) & ((1ULL << segment_bits) - 0x80));
-
- LOG_MMU("pte segment: key=%d nx %d vsid " TARGET_FMT_lx "\n",
- ctx->key, !!(slb->vsid & SLB_VSID_N), vsid);
- ret = -1;
-
- /* Page address translation */
- LOG_MMU("htab_base " TARGET_FMT_plx " htab_mask " TARGET_FMT_plx
- " hash " TARGET_FMT_plx "\n",
- env->htab_base, env->htab_mask, hash);
- ctx->hash[0] = hash;
- ctx->hash[1] = ~hash;
-
- LOG_MMU("0 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx
- " vsid=" TARGET_FMT_lx " ptem=" TARGET_FMT_lx
- " hash=" TARGET_FMT_plx "\n",
- env->htab_base, env->htab_mask, vsid, ctx->ptem,
- ctx->hash[0]);
- /* Primary table lookup */
- ret = find_pte64(env, ctx, eaddr, 0, rwx, target_page_bits);
- if (ret == -1) {
- /* Secondary table lookup */
- LOG_MMU("1 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx
- " vsid=" TARGET_FMT_lx " api=" TARGET_FMT_lx
- " hash=" TARGET_FMT_plx "\n", env->htab_base,
- env->htab_mask, vsid, ctx->ptem, ctx->hash[1]);
- ret2 = find_pte64(env, ctx, eaddr, 1, rwx, target_page_bits);
- if (ret2 != -1) {
- ret = ret2;
- }
- }
+ ret = find_pte64(env, ctx, slb, eaddr, rwx);
return ret;
}
--
1.7.10.4
- [Qemu-ppc] [PATCH 10/32] target-ppc: Disentangle 64-bit hash version of cpu_get_phys_page_debug(), (continued)
- [Qemu-ppc] [PATCH 10/32] target-ppc: Disentangle 64-bit hash version of cpu_get_phys_page_debug(), David Gibson, 2013/02/15
- [Qemu-ppc] [PATCH 19/32] mmu-hash64: Combine ppc_hash64_get_physical_address and get_segment64(), David Gibson, 2013/02/15
- [Qemu-ppc] [PATCH 20/32] mmu-hash64: Cleanup segment-level access checks, David Gibson, 2013/02/15
- [Qemu-ppc] [PATCH 09/32] target-ppc: Disentangle ppc64 hash mmu path for cpu_ppc_handle_mmu_fault, David Gibson, 2013/02/15
- [Qemu-ppc] [PATCH 07/32] target-ppc: Rework get_physical_address(), David Gibson, 2013/02/15
- [Qemu-ppc] [PATCH 05/32] target-ppc: Disentangle 64-bit version of find_pte(), David Gibson, 2013/02/15
- [Qemu-ppc] [PATCH 13/32] target-ppc: mmu_ctx_t should not be a global type, David Gibson, 2013/02/15
- [Qemu-ppc] [PATCH 06/32] target-ppc: Disentangle 64-bit version of get_segment(), David Gibson, 2013/02/15
- [Qemu-ppc] [PATCH 15/32] mmu-hash64: Add hash pte load/store helpers, David Gibson, 2013/02/15
- [Qemu-ppc] [PATCH 21/32] mmu-hash64: Don't keep looking for PTEs after we find a match, David Gibson, 2013/02/15
- [Qemu-ppc] [PATCH 24/32] mmu-hash64: Make find_pte64 do more of the job of finding a pte,
David Gibson <=
- [Qemu-ppc] [PATCH 27/32] mmu-hash64: Don't update PTE flags when permission is denied, David Gibson, 2013/02/15
- [Qemu-ppc] [PATCH 03/32] target-ppc: Move SLB handling into a mmu-hash64.c, David Gibson, 2013/02/15
- [Qemu-ppc] [PATCH 26/32] mmu-hash64: Clean up ppc_hash64_htab_lookup(), David Gibson, 2013/02/15
- [Qemu-ppc] [PATCH 23/32] mmu-hash64: Separate PTEG searching from permissions checking, David Gibson, 2013/02/15
- [Qemu-ppc] [PATCH 22/32] mmu-hash64: Separate VA matching from permission checking in pte64_check(), David Gibson, 2013/02/15
- [Qemu-ppc] [PATCH 30/32] mmu-hash64: Correctly mask RPN from hash PTE, David Gibson, 2013/02/15
- [Qemu-ppc] [PATCH 25/32] mmu-hash64: Remove permission checking from find_pte64(), David Gibson, 2013/02/15
- [Qemu-ppc] [PATCH 28/32] mmu-hash64: Clean up PTE permission checking, David Gibson, 2013/02/15
- [Qemu-ppc] [PATCH 29/32] mmu-hash64: Clean up PTE flags update, David Gibson, 2013/02/15
- [Qemu-ppc] [PATCH 31/32] mmu-hash64: Don't use full ppc_hash64_translate() path for get_phys_page_debug(), David Gibson, 2013/02/15