summaryrefslogtreecommitdiffstats
path: root/sys/powerpc/aim
diff options
context:
space:
mode:
authornwhitehorn <nwhitehorn@FreeBSD.org>2009-04-12 03:03:55 +0000
committernwhitehorn <nwhitehorn@FreeBSD.org>2009-04-12 03:03:55 +0000
commit32d233ecc5d49b564b71d9c7c48f3ad1980ab59f (patch)
tree79c849a2370af4a5db95ef5e30a993a3e85dcdd5 /sys/powerpc/aim
parent692f8aa2fac966ef1adc29843ad741d355db1ecd (diff)
downloadFreeBSD-src-32d233ecc5d49b564b71d9c7c48f3ad1980ab59f.zip
FreeBSD-src-32d233ecc5d49b564b71d9c7c48f3ad1980ab59f.tar.gz
Rework the way we get the cacheline size. Instead of having a table of
CPUs known to use 128 byte cache lines and defaulting to 32, use the dcbz instruction to measure it. Also make dcbz behave the way you would expect on PPC 970.
Diffstat (limited to 'sys/powerpc/aim')
-rw-r--r--sys/powerpc/aim/machdep.c51
1 files changed, 38 insertions, 13 deletions
diff --git a/sys/powerpc/aim/machdep.c b/sys/powerpc/aim/machdep.c
index e00268a..fb83e3a 100644
--- a/sys/powerpc/aim/machdep.c
+++ b/sys/powerpc/aim/machdep.c
@@ -117,6 +117,7 @@ __FBSDID("$FreeBSD$");
#include <machine/powerpc.h>
#include <machine/reg.h>
#include <machine/sigframe.h>
+#include <machine/spr.h>
#include <machine/trap.h>
#include <machine/vmparam.h>
@@ -254,8 +255,8 @@ powerpc_init(u_int startkernel, u_int endkernel, u_int basekernel, void *mdp)
size_t trap_offset;
void *kmdp;
char *env;
- int vers;
uint32_t msr, scratch;
+ uint8_t *cache_check;
end = 0;
kmdp = NULL;
@@ -326,37 +327,61 @@ powerpc_init(u_int startkernel, u_int endkernel, u_int basekernel, void *mdp)
}
/*
- * Set cacheline_size based on the CPU model.
+ * Init KDB
*/
- vers = mfpvr() >> 16;
- switch (vers) {
+ 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.
+ */
+
+ switch (mfpvr() >> 16) {
case IBM970:
case IBM970FX:
case IBM970MP:
case IBM970GX:
- cacheline_size = 128;
+ scratch = mfspr64upper(SPR_HID5,msr);
+ scratch &= ~HID5_970_DCBZ_SIZE_HI;
+ mtspr64(SPR_HID5, scratch, mfspr(SPR_HID5), msr);
break;
- default:
- cacheline_size = 32;
}
/*
- * Init KDB
+ * Initialize the interrupt tables and figure out our cache line
+ * size and whether or not we need the 64-bit bridge code.
*/
- kdb_init();
-
/*
- * XXX: Initialize the interrupt tables.
- * Disable translation in case the vector area
- * hasn't been mapped (G5)
+ * Disable translation in case the vector area hasn't been
+ * mapped (G5).
*/
+
msr = mfmsr();
mtmsr(msr & ~(PSL_IR | PSL_DR));
isync();
/*
+ * Measure the cacheline size using dcbz
+ *
+ * Use EXC_PGM as a playground. We are about to overwrite it
+ * anyway, we know it exists, and we know it is cache-aligned.
+ */
+
+ cache_check = (void *)EXC_PGM;
+
+ for (cacheline_size = 0; cacheline_size < 0x100; cacheline_size++)
+ cache_check[cacheline_size] = 0xff;
+
+ __asm __volatile("dcbz %0,0":: "r" (cache_check) : "memory");
+
+ /* Find the first byte dcbz did not zero to get the cache line size */
+ for (cacheline_size = 0; cacheline_size < 0x100 &&
+ cache_check[cacheline_size] == 0; cacheline_size++);
+
+ /*
* Figure out whether we need to use the 64 bit PMAP. This works by
* executing an instruction that is only legal on 64-bit PPC (mtmsrd),
* and setting ppc64 = 0 if that causes a trap.
OpenPOWER on IntegriCloud