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