svn commit: r222620 - in head/sys/powerpc: aim include
Nathan Whitehorn
nwhitehorn at FreeBSD.org
Thu Jun 2 14:25:52 UTC 2011
Author: nwhitehorn
Date: Thu Jun 2 14:25:52 2011
New Revision: 222620
URL: http://svn.freebsd.org/changeset/base/222620
Log:
The POWER7 has only 32 SLB slots instead of 64, like other supported
64-bit PowerPC CPUs. Add infrastructure to support variable numbers of
SLB slots and move the user slot from 63 to 0, so that it is always
available.
Modified:
head/sys/powerpc/aim/machdep.c
head/sys/powerpc/aim/slb.c
head/sys/powerpc/aim/trap_subr64.S
head/sys/powerpc/include/slb.h
Modified: head/sys/powerpc/aim/machdep.c
==============================================================================
--- head/sys/powerpc/aim/machdep.c Thu Jun 2 14:25:27 2011 (r222619)
+++ head/sys/powerpc/aim/machdep.c Thu Jun 2 14:25:52 2011 (r222620)
@@ -132,6 +132,7 @@ extern vm_offset_t ksym_start, ksym_end;
int cold = 1;
#ifdef __powerpc64__
+extern int n_slbs;
int cacheline_size = 128;
#else
int cacheline_size = 32;
@@ -337,13 +338,13 @@ powerpc_init(vm_offset_t startkernel, vm
kdb_init();
- /*
- * PowerPC 970 CPUs have a misfeature requested by Apple that makes
- * them pretend they have a 32-byte cacheline. Turn this off
- * before we measure the cacheline size.
- */
-
+ /* Various very early CPU fix ups */
switch (mfpvr() >> 16) {
+ /*
+ * PowerPC 970 CPUs have a misfeature requested by Apple that
+ * makes them pretend they have a 32-byte cacheline. Turn this
+ * off before we measure the cacheline size.
+ */
case IBM970:
case IBM970FX:
case IBM970MP:
@@ -352,6 +353,12 @@ powerpc_init(vm_offset_t startkernel, vm
scratch &= ~HID5_970_DCBZ_SIZE_HI;
mtspr(SPR_HID5, scratch);
break;
+ #ifdef __powerpc64__
+ case IBMPOWER7:
+ /* XXX: get from ibm,slb-size in device tree */
+ n_slbs = 32;
+ break;
+ #endif
}
/*
@@ -367,7 +374,6 @@ powerpc_init(vm_offset_t startkernel, vm
msr = mfmsr();
mtmsr((msr & ~(PSL_IR | PSL_DR)) | PSL_RI);
- isync();
/*
* Measure the cacheline size using dcbz
@@ -502,7 +508,6 @@ powerpc_init(vm_offset_t startkernel, vm
* Restore MSR
*/
mtmsr(msr);
- isync();
/* Warn if cachline size was not determined */
if (cacheline_warn == 1) {
@@ -527,7 +532,6 @@ powerpc_init(vm_offset_t startkernel, vm
pmap_bootstrap(startkernel, endkernel);
mtmsr(PSL_KERNSET & ~PSL_EE);
- isync();
/*
* Initialize params/tunables that are derived from memsize
Modified: head/sys/powerpc/aim/slb.c
==============================================================================
--- head/sys/powerpc/aim/slb.c Thu Jun 2 14:25:27 2011 (r222619)
+++ head/sys/powerpc/aim/slb.c Thu Jun 2 14:25:52 2011 (r222620)
@@ -51,8 +51,9 @@ uintptr_t moea64_get_unique_vsid(void);
void moea64_release_vsid(uint64_t vsid);
static void slb_zone_init(void *);
-uma_zone_t slbt_zone;
-uma_zone_t slb_cache_zone;
+static uma_zone_t slbt_zone;
+static uma_zone_t slb_cache_zone;
+int n_slbs = 64;
SYSINIT(slb_zone_init, SI_SUB_KMEM, SI_ORDER_ANY, slb_zone_init, NULL);
@@ -426,16 +427,18 @@ slb_insert_kernel(uint64_t slbe, uint64_
/* Check for an unused slot, abusing the user slot as a full flag */
if (slbcache[USER_SLB_SLOT].slbe == 0) {
- for (i = 0; i < USER_SLB_SLOT; i++) {
+ for (i = 0; i < n_slbs; i++) {
+ if (i == USER_SLB_SLOT)
+ continue;
if (!(slbcache[i].slbe & SLBE_VALID))
goto fillkernslb;
}
- if (i == USER_SLB_SLOT)
+ if (i == n_slbs)
slbcache[USER_SLB_SLOT].slbe = 1;
}
- for (i = mftb() % 64, j = 0; j < 64; j++, i = (i+1) % 64) {
+ for (i = mftb() % n_slbs, j = 0; j < n_slbs; j++, i = (i+1) % n_slbs) {
if (i == USER_SLB_SLOT)
continue;
@@ -443,9 +446,11 @@ slb_insert_kernel(uint64_t slbe, uint64_
break;
}
- KASSERT(j < 64, ("All kernel SLB slots locked!"));
+ KASSERT(j < n_slbs, ("All kernel SLB slots locked!"));
fillkernslb:
+ KASSERT(i != USER_SLB_SLOT,
+ ("Filling user SLB slot with a kernel mapping"));
slbcache[i].slbv = slbv;
slbcache[i].slbe = slbe | (uint64_t)i;
@@ -466,11 +471,11 @@ slb_insert_user(pmap_t pm, struct slb *s
PMAP_LOCK_ASSERT(pm, MA_OWNED);
- if (pm->pm_slb_len < 64) {
+ if (pm->pm_slb_len < n_slbs) {
i = pm->pm_slb_len;
pm->pm_slb_len++;
} else {
- i = mftb() % 64;
+ i = mftb() % n_slbs;
}
/* Note that this replacement is atomic with respect to trap_subr */
@@ -521,8 +526,9 @@ slb_zone_init(void *dummy)
slbt_zone = uma_zcreate("SLB tree node", sizeof(struct slbtnode),
NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_VM);
- slb_cache_zone = uma_zcreate("SLB cache", 64*sizeof(struct slb *),
- NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_VM);
+ slb_cache_zone = uma_zcreate("SLB cache",
+ (n_slbs + 1)*sizeof(struct slb *), NULL, NULL, NULL, NULL,
+ UMA_ALIGN_PTR, UMA_ZONE_VM);
if (platform_real_maxaddr() != VM_MAX_ADDRESS) {
uma_zone_set_allocf(slb_cache_zone, slb_uma_real_alloc);
Modified: head/sys/powerpc/aim/trap_subr64.S
==============================================================================
--- head/sys/powerpc/aim/trap_subr64.S Thu Jun 2 14:25:27 2011 (r222619)
+++ head/sys/powerpc/aim/trap_subr64.S Thu Jun 2 14:25:52 2011 (r222620)
@@ -53,55 +53,53 @@
* User SRs are loaded through a pointer to the current pmap.
*/
restore_usersrs:
- GET_CPUINFO(%r28);
- ld %r28,PC_USERSLB(%r28);
+ GET_CPUINFO(%r28)
+ ld %r28,PC_USERSLB(%r28)
li %r29, 0 /* Set the counter to zero */
slbia
slbmfee %r31,%r29
clrrdi %r31,%r31,28
slbie %r31
-instuserslb:
- ld %r31, 0(%r28); /* Load SLB entry pointer */
- cmpli 0, %r31, 0; /* If NULL, stop */
- beqlr;
+1: ld %r31, 0(%r28) /* Load SLB entry pointer */
+ cmpli 0, %r31, 0 /* If NULL, stop */
+ beqlr
ld %r30, 0(%r31) /* Load SLBV */
ld %r31, 8(%r31) /* Load SLBE */
or %r31, %r31, %r29 /* Set SLBE slot */
- slbmte %r30, %r31; /* Install SLB entry */
+ slbmte %r30, %r31 /* Install SLB entry */
- addi %r28, %r28, 8; /* Advance pointer */
- addi %r29, %r29, 1;
- cmpli 0, %r29, 64; /* Repeat if we are not at the end */
- blt instuserslb;
- blr;
+ addi %r28, %r28, 8 /* Advance pointer */
+ addi %r29, %r29, 1
+ b 1b /* Repeat */
/*
* Kernel SRs are loaded directly from the PCPU fields
*/
restore_kernsrs:
- GET_CPUINFO(%r28);
- addi %r28,%r28,PC_KERNSLB;
+ GET_CPUINFO(%r28)
+ addi %r28,%r28,PC_KERNSLB
li %r29, 0 /* Set the counter to zero */
slbia
slbmfee %r31,%r29
clrrdi %r31,%r31,28
slbie %r31
-instkernslb:
- ld %r31, 8(%r28); /* Load SLBE */
+1: cmpli 0, %r29, USER_SLB_SLOT /* Skip the user slot */
+ beq- 2f
- cmpli 0, %r31, 0; /* If SLBE is not valid, stop */
- beqlr;
+ ld %r31, 8(%r28) /* Load SLBE */
+ cmpli 0, %r31, 0 /* If SLBE is not valid, stop */
+ beqlr
ld %r30, 0(%r28) /* Load SLBV */
- slbmte %r30, %r31; /* Install SLB entry */
+ slbmte %r30, %r31 /* Install SLB entry */
- addi %r28, %r28, 16; /* Advance pointer */
- addi %r29, %r29, 1;
- cmpli 0, %r29, USER_SLB_SLOT; /* Repeat if we are not at the end */
- blt instkernslb;
- blr;
+2: addi %r28, %r28, 16 /* Advance pointer */
+ addi %r29, %r29, 1
+ cmpli 0, %r29, 64 /* Repeat if we are not at the end */
+ blt 1b
+ blr
/*
* FRAME_SETUP assumes:
Modified: head/sys/powerpc/include/slb.h
==============================================================================
--- head/sys/powerpc/include/slb.h Thu Jun 2 14:25:27 2011 (r222619)
+++ head/sys/powerpc/include/slb.h Thu Jun 2 14:25:52 2011 (r222620)
@@ -65,7 +65,7 @@
/*
* User segment for copyin/out
*/
-#define USER_SLB_SLOT 63
+#define USER_SLB_SLOT 0
#define USER_SLB_SLBE (((USER_ADDR >> ADDR_SR_SHFT) << SLBE_ESID_SHIFT) | \
SLBE_VALID | USER_SLB_SLOT)
More information about the svn-src-head
mailing list