svn commit: r208195 - in projects/ppc64/sys/powerpc: aim include

Nathan Whitehorn nwhitehorn at FreeBSD.org
Mon May 17 16:04:09 UTC 2010


Author: nwhitehorn
Date: Mon May 17 16:04:09 2010
New Revision: 208195
URL: http://svn.freebsd.org/changeset/base/208195

Log:
  Modify the way the virtual segment IDs for large-page mappings are set up
  to reduce the number of hash collisions with regular 4K pages. This allows
  systems with > 5 GB RAM to boot with the direct map enabled.

Modified:
  projects/ppc64/sys/powerpc/aim/mmu_oea64.c
  projects/ppc64/sys/powerpc/aim/ofw_machdep.c
  projects/ppc64/sys/powerpc/aim/slb.c
  projects/ppc64/sys/powerpc/include/slb.h

Modified: projects/ppc64/sys/powerpc/aim/mmu_oea64.c
==============================================================================
--- projects/ppc64/sys/powerpc/aim/mmu_oea64.c	Mon May 17 15:31:24 2010	(r208194)
+++ projects/ppc64/sys/powerpc/aim/mmu_oea64.c	Mon May 17 16:04:09 2010	(r208195)
@@ -838,7 +838,7 @@ moea64_bootstrap_slb_prefault(vm_offset_
 	}
 
 	entry.slbe = slbe;
-	entry.slbv = (esid | KERNEL_VSID_BIT) << SLBV_VSID_SHIFT;
+	entry.slbv = KERNEL_VSID(esid, large) << SLBV_VSID_SHIFT;
 	if (large)
 		entry.slbv |= SLBV_L;
 

Modified: projects/ppc64/sys/powerpc/aim/ofw_machdep.c
==============================================================================
--- projects/ppc64/sys/powerpc/aim/ofw_machdep.c	Mon May 17 15:31:24 2010	(r208194)
+++ projects/ppc64/sys/powerpc/aim/ofw_machdep.c	Mon May 17 16:04:09 2010	(r208195)
@@ -62,6 +62,7 @@ __FBSDID("$FreeBSD$");
 #define	OFMEM_REGIONS	32
 static struct mem_region OFmem[OFMEM_REGIONS + 1], OFavail[OFMEM_REGIONS + 3];
 static struct mem_region OFfree[OFMEM_REGIONS + 3];
+static int nOFmem;
 
 static struct mtx ofw_mutex;
 
@@ -270,10 +271,11 @@ ofw_mem_regions(struct mem_region **memp
 		phandle = OF_finddevice("/memory at 0");
 
 	msz = parse_ofw_memory(phandle, "reg", OFmem);
+	nOFmem = msz / sizeof(struct mem_region);
 	asz = parse_ofw_memory(phandle, "available", OFavail);
 
 	*memp = OFmem;
-	*memsz = msz / sizeof(struct mem_region);
+	*memsz = nOFmem;
 	
 	/*
 	 * OFavail may have overlapping regions - collapse these
@@ -640,7 +642,7 @@ mem_valid(vm_offset_t addr, int len)
 {
 	int i;
 
-	for (i = 0; i < OFMEM_REGIONS; i++)
+	for (i = 0; i < nOFmem; i++)
 		if ((addr >= OFmem[i].mr_start) 
 		    && (addr + len < OFmem[i].mr_start + OFmem[i].mr_size))
 			return (0);

Modified: projects/ppc64/sys/powerpc/aim/slb.c
==============================================================================
--- projects/ppc64/sys/powerpc/aim/slb.c	Mon May 17 15:31:24 2010	(r208194)
+++ projects/ppc64/sys/powerpc/aim/slb.c	Mon May 17 16:04:09 2010	(r208195)
@@ -70,8 +70,8 @@ va_to_slb_entry(pmap_t pm, vm_offset_t v
 	slb->slbe = (esid << SLBE_ESID_SHIFT) | SLBE_VALID;
 
 	if (pm == kernel_pmap) {
-		/* Set kernel VSID to ESID | KERNEL_VSID_BIT */
-		slb->slbv = (esid | KERNEL_VSID_BIT) << SLBV_VSID_SHIFT;
+		/* Set kernel VSID to deterministic value */
+		slb->slbv = va_to_vsid(kernel_pmap, va) << SLBV_VSID_SHIFT;
 
 		/* Figure out if this is a large-page mapping */
 		if (hw_direct_map && va < VM_MIN_KERNEL_ADDRESS) {
@@ -102,11 +102,18 @@ uint64_t
 va_to_vsid(pmap_t pm, vm_offset_t va)
 {
 	struct slb entry;
+	int large;
 
-	/* Shortcut kernel case: VSID = ESID | KERNEL_VSID_BIT */
+	/* Shortcut kernel case */
+	if (pm == kernel_pmap) {
+		large = 0;
+		if (hw_direct_map && va < VM_MIN_KERNEL_ADDRESS &&
+		    mem_valid(va, 0) == 0)
+			large = 1;
+
+		return (KERNEL_VSID((uintptr_t)va >> ADDR_SR_SHFT, large));
+	}
 
-	if (pm == kernel_pmap) 
-		return (((uintptr_t)va >> ADDR_SR_SHFT) | KERNEL_VSID_BIT);
 	/*
 	 * If there is no vsid for this VA, we need to add a new entry
 	 * to the PMAP's segment table.
@@ -128,7 +135,7 @@ allocate_vsid(pmap_t pm, uint64_t esid, 
 	prespill = NULL;
 
 	if (pm == kernel_pmap) {
-		vsid = esid | KERNEL_VSID_BIT;
+		vsid = va_to_vsid(pm, esid << ADDR_SR_SHFT);
 		slb_entry = &kern_entry;
 		prespill = PCPU_GET(slb);
 	} else {

Modified: projects/ppc64/sys/powerpc/include/slb.h
==============================================================================
--- projects/ppc64/sys/powerpc/include/slb.h	Mon May 17 15:31:24 2010	(r208194)
+++ projects/ppc64/sys/powerpc/include/slb.h	Mon May 17 16:04:09 2010	(r208195)
@@ -49,6 +49,13 @@
 
 #define	KERNEL_VSID_BIT	0x0000001000000000UL /* Bit set in all kernel VSIDs */
 
+/*
+ * Shift large-page VSIDs one place left. At present, they are only used in the
+ * kernel direct map, and we already assume in the placement of KVA that the
+ * CPU cannot address more than 63 bits of memory.
+ */
+#define KERNEL_VSID(esid, large) (((uint64_t)(esid) << (large ? 1 : 0)) | KERNEL_VSID_BIT)
+
 #define	SLBE_VALID	0x0000000008000000UL /* SLB entry valid */
 #define	SLBE_INDEX_MASK	0x0000000000000fffUL /* SLB index mask*/
 #define	SLBE_ESID_MASK	0xfffffffff0000000UL /* Effective segment ID mask */


More information about the svn-src-projects mailing list