qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: qemu@gibson.dropbear.id.au
To: qemu-devel@nongnu.org
Cc: paulus@samba.org, agraf@suse.de, anton@samba.org
Subject: [Qemu-devel] [PATCH 12/28] Support 1T segments on ppc
Date: Tue, 15 Feb 2011 15:56:23 +1100	[thread overview]
Message-ID: <1297745799-26148-13-git-send-email-qemu@gibson.dropbear.id.au> (raw)
In-Reply-To: <1297745799-26148-1-git-send-email-qemu@gibson.dropbear.id.au>

From: David Gibson <david@gibson.dropbear.id.au>

Traditionally, the "segments" used for the two-stage translation used on
powerpc MMUs were 256MB in size.  This was the only option on all hash
page table based 32-bit powerpc cpus, and on the earlier 64-bit hash page
table based cpus.  However, newer 64-bit cpus also permit 1TB segments

This patch adds support for 1TB segment translation to the qemu code.

Signed-off-by: David Gibson <dwg@au1.ibm.com>
---
 target-ppc/cpu.h    |    7 ++++++
 target-ppc/helper.c |   54 +++++++++++++++++++++++++++++++++++---------------
 2 files changed, 45 insertions(+), 16 deletions(-)

diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 71f8d72..9abf4a9 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -114,6 +114,7 @@ enum powerpc_mmu_t {
     POWERPC_MMU_601        = 0x0000000A,
 #if defined(TARGET_PPC64)
 #define POWERPC_MMU_64       0x00010000
+#define POWERPC_MMU_1TSEG    0x00020000
     /* 64 bits PowerPC MMU                                     */
     POWERPC_MMU_64B        = POWERPC_MMU_64 | 0x00000001,
     /* 620 variant (no segment exceptions)                     */
@@ -382,9 +383,11 @@ struct ppc_slb_t {
 
 /* Bits in the SLB VSID word */
 #define SLB_VSID_SHIFT          12
+#define SLB_VSID_SHIFT_1T       24
 #define SLB_VSID_SSIZE_SHIFT    62
 #define SLB_VSID_B              0xc000000000000000ULL
 #define SLB_VSID_B_256M         0x0000000000000000ULL
+#define SLB_VSID_B_1T           0x4000000000000000ULL
 #define SLB_VSID_VSID           0x3FFFFFFFFFFFF000ULL
 #define SLB_VSID_PTEM           (SLB_VSID_B | SLB_VSID_VSID)
 #define SLB_VSID_KS             0x0000000000000800ULL
@@ -398,6 +401,10 @@ struct ppc_slb_t {
 #define SEGMENT_SHIFT_256M      28
 #define SEGMENT_MASK_256M       ~((1ULL << SEGMENT_SHIFT_256M) - 1)
 
+#define SEGMENT_SHIFT_1T        40
+#define SEGMENT_MASK_1T         ~((1ULL << SEGMENT_SHIFT_1T) - 1)
+
+
 /*****************************************************************************/
 /* Machine state register bits definition                                    */
 #define MSR_SF   63 /* Sixty-four-bit mode                            hflags */
diff --git a/target-ppc/helper.c b/target-ppc/helper.c
index 111675d..3e3b5da 100644
--- a/target-ppc/helper.c
+++ b/target-ppc/helper.c
@@ -671,19 +671,26 @@ static inline int find_pte(CPUState *env, mmu_ctx_t *ctx, int h, int rw,
 #if defined(TARGET_PPC64)
 static inline ppc_slb_t *slb_lookup(CPUPPCState *env, target_ulong eaddr)
 {
-    uint64_t esid;
+    uint64_t esid_256M, esid_1T;
     int n;
 
     LOG_SLB("%s: eaddr " TARGET_FMT_lx "\n", __func__, eaddr);
 
-    esid = (eaddr & SEGMENT_MASK_256M) | SLB_ESID_V;
+    esid_256M = (eaddr & SEGMENT_MASK_256M) | SLB_ESID_V;
+    esid_1T = (eaddr & SEGMENT_MASK_1T) | SLB_ESID_V;
 
     for (n = 0; n < env->slb_nr; n++) {
         ppc_slb_t *slb = &env->slb[n];
 
         LOG_SLB("%s: slot %d %016" PRIx64 " %016"
                     PRIx64 "\n", __func__, n, slb->esid, slb->vsid);
-        if (slb->esid == esid) {
+        /* We check for 1T matches on all MMUs here - if the MMU
+         * doesn't have 1T segment support, we will have prevented 1T
+         * entries from being inserted in the slbmte code. */
+        if ( ((slb->esid == esid_256M) &&
+              ((slb->vsid & SLB_VSID_B) == SLB_VSID_B_256M))
+             || ((slb->esid == esid_1T) &&
+                 ((slb->vsid & SLB_VSID_B) == SLB_VSID_B_1T)) ) {
             return slb;
         }
     }
@@ -736,16 +743,19 @@ void ppc_slb_invalidate_one (CPUPPCState *env, uint64_t T0)
 int ppc_store_slb (CPUPPCState *env, target_ulong rb, target_ulong rs)
 {
     int slot = rb & 0xfff;
-    uint64_t esid = rb & ~0xfff;
     ppc_slb_t *slb = &env->slb[slot];
-
-    if (slot >= env->slb_nr) {
-        return -1;
-    }
-
-    slb->esid = esid;
+ 
+    if (rb & (0x1000 - env->slb_nr))
+	return -1; /* Reserved bits set or slot too high */
+    if (rs & (SLB_VSID_B & ~SLB_VSID_B_1T))
+	return -1; /* Bad segment size */
+    if ((rs & SLB_VSID_B) && !(env->mmu_model & POWERPC_MMU_1TSEG))
+ 	return -1; /* 1T segment on MMU that doesn't support it */
+
+    /* Mask out the slot number as we store the entry */
+    slb->esid = rb & (SLB_ESID_ESID | SLB_ESID_V);
     slb->vsid = rs;
-
+ 
     LOG_SLB("%s: %d " TARGET_FMT_lx " - " TARGET_FMT_lx " => %016" PRIx64
             " %016" PRIx64 "\n", __func__, slot, rb, rs,
             slb->esid, slb->vsid);
@@ -795,6 +805,7 @@ static inline int get_segment(CPUState *env, mmu_ctx_t *ctx,
     if (env->mmu_model & POWERPC_MMU_64) {
         ppc_slb_t *slb;
         target_ulong pageaddr;
+        int segment_bits;
 
         LOG_MMU("Check SLBs\n");
         slb = slb_lookup(env, eaddr);
@@ -802,7 +813,14 @@ static inline int get_segment(CPUState *env, mmu_ctx_t *ctx,
             return -5;
         }
 
-        vsid = (slb->vsid & SLB_VSID_VSID) >> SLB_VSID_SHIFT;
+	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)
@@ -810,11 +828,15 @@ static inline int get_segment(CPUState *env, mmu_ctx_t *ctx,
         ds = 0;
         ctx->nx = !!(slb->vsid & SLB_VSID_N);
 
-        pageaddr = eaddr & ((1ULL << 28) - (1ULL << target_page_bits));
-        /* XXX: this is false for 1 TB segments */
-        hash = vsid ^ (pageaddr >> target_page_bits);
+        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) & 0x0F80);
+        ctx->ptem = (slb->vsid & SLB_VSID_PTEM) | 
+            ((pageaddr >> 16) & ((1ULL << segment_bits) - 0x80));
     } else
 #endif /* defined(TARGET_PPC64) */
     {
-- 
1.7.1

  parent reply	other threads:[~2011-02-15  4:57 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-02-15  4:56 [Qemu-devel] RFC: Implement emulation of pSeries logical partitions (v2) qemu
2011-02-15  4:56 ` [Qemu-devel] [PATCH 01/28] Add TAGS and *~ to .gitignore qemu
2011-02-15  4:56 ` [Qemu-devel] [PATCH 02/28] Clean up PowerPC SLB handling code qemu
2011-02-15  4:56 ` [Qemu-devel] [PATCH 03/28] Allow qemu_devtree_setprop() to take arbitrary values qemu
2011-02-15  4:56 ` [Qemu-devel] [PATCH 04/28] Add a hook to allow hypercalls to be emulated on PowerPC qemu
2011-02-15  4:56 ` [Qemu-devel] [PATCH 05/28] Implement PowerPC slbmfee and slbmfev instructions qemu
2011-02-15  4:56 ` [Qemu-devel] [PATCH 06/28] Implement missing parts of the logic for the POWER PURR qemu
2011-02-15  4:56 ` [Qemu-devel] [PATCH 07/28] Correct ppc popcntb logic, implement popcntw and popcntd qemu
2011-02-15  4:56 ` [Qemu-devel] [PATCH 08/28] Clean up slb_lookup() function qemu
2011-02-15  4:56 ` [Qemu-devel] [PATCH 09/28] Parse SDR1 on mtspr instead of at translate time qemu
2011-02-15  4:56 ` [Qemu-devel] [PATCH 10/28] Use "hash" more consistently in ppc mmu code qemu
2011-02-15  4:56 ` [Qemu-devel] [PATCH 11/28] Better factor the ppc hash translation path qemu
2011-02-15  4:56 ` qemu [this message]
2011-02-15  4:56 ` [Qemu-devel] [PATCH 13/28] Add POWER7 support for ppc qemu
2011-02-15  4:56 ` [Qemu-devel] [PATCH 14/28] Start implementing pSeries logical partition machine qemu
2011-02-15  4:56 ` [Qemu-devel] [PATCH 15/28] Implement the bus structure for PAPR virtual IO qemu
2011-02-15  4:56 ` [Qemu-devel] [PATCH 16/28] Virtual hash page table handling on pSeries machine qemu
2011-02-15  4:56 ` [Qemu-devel] [PATCH 17/28] Implement hcall based RTAS for pSeries machines qemu
2011-02-15  4:56 ` [Qemu-devel] [PATCH 18/28] Implement assorted pSeries hcalls and RTAS methods qemu
2011-02-15  4:56 ` [Qemu-devel] [PATCH 19/28] Implement the PAPR (pSeries) virtualized interrupt controller (xics) qemu
2011-02-15  4:56 ` [Qemu-devel] [PATCH 20/28] Add PAPR H_VIO_SIGNAL hypercall and infrastructure for VIO interrupts qemu
2011-02-15  4:56 ` [Qemu-devel] [PATCH 21/28] Add (virtual)_interrupt to PAPR virtual tty device qemu
2011-02-15  4:56 ` [Qemu-devel] [PATCH 22/28] Implement TCE translation for sPAPR VIO qemu
2011-02-15  4:56 ` [Qemu-devel] [PATCH 23/28] Implement sPAPR Virtual LAN (ibmveth) qemu
2011-02-15  4:56 ` [Qemu-devel] [PATCH 24/28] Implement PAPR CRQ hypercalls qemu
2011-02-15  4:56 ` [Qemu-devel] [PATCH 25/28] Implement PAPR virtual SCSI interface (ibmvscsi) qemu
2011-02-15  4:56 ` [Qemu-devel] [PATCH 26/28] Add a PAPR TCE-bypass mechanism for the pSeries machine qemu
2011-02-15  4:56 ` [Qemu-devel] [PATCH 27/28] Add SLOF-based partition firmware for pSeries machine, allowing more boot options qemu
2011-02-15  4:56 ` [Qemu-devel] [PATCH 28/28] Implement PAPR VPA functions for pSeries shared processor partitions qemu

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=1297745799-26148-13-git-send-email-qemu@gibson.dropbear.id.au \
    --to=qemu@gibson.dropbear.id.au \
    --cc=agraf@suse.de \
    --cc=anton@samba.org \
    --cc=paulus@samba.org \
    --cc=qemu-devel@nongnu.org \
    /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).