svn commit: r258957 - projects/pmac_pmu/sys/powerpc/powermac
Justin Hibbits
jhibbits at FreeBSD.org
Thu Dec 5 05:58:18 UTC 2013
Author: jhibbits
Date: Thu Dec 5 05:58:17 2013
New Revision: 258957
URL: http://svnweb.freebsd.org/changeset/base/258957
Log:
Fix the cache flushing code, by flushing the L1 twice.
Linux and OS X do this very thing, possibly to work around bugs in the
silicon. Without this it doesn't flush completely, and results in
memory corruption down the road.
Modified:
projects/pmac_pmu/sys/powerpc/powermac/platform_powermac.c
Modified: projects/pmac_pmu/sys/powerpc/powermac/platform_powermac.c
==============================================================================
--- projects/pmac_pmu/sys/powerpc/powermac/platform_powermac.c Thu Dec 5 03:01:41 2013 (r258956)
+++ projects/pmac_pmu/sys/powerpc/powermac/platform_powermac.c Thu Dec 5 05:58:17 2013 (r258957)
@@ -332,7 +332,7 @@ flush_disable_caches(void)
register_t msr;
register_t msscr0;
register_t cache_reg;
- volatile uint32_t *romp;
+ volatile uint32_t *memp;
uint32_t temp;
int i;
int x;
@@ -359,17 +359,30 @@ flush_disable_caches(void)
mtspr(SPR_LDSTCR, 0);
- romp = (uint32_t *)0xfff00000;
+ /*
+ * Perform this in two stages: Flush the cache starting in RAM, then do it
+ * from ROM.
+ */
+ memp = (volatile uint32_t *)0x00000000;
+ for (i = 0; i < 128 * 1024; i++) {
+ temp = *memp;
+ __asm__ __volatile__("dcbf 0,%0" :: "r"(memp));
+ memp += 32/sizeof(*memp);
+ }
+
+ memp = (volatile uint32_t *)0xfff00000;
x = 0xfe;
for (; x != 0xff;) {
mtspr(SPR_LDSTCR, x);
for (i = 0; i < 128; i++) {
- temp = *romp;
- romp += 32/sizeof(*romp);
+ temp = *memp;
+ __asm__ __volatile__("dcbf 0,%0" :: "r"(memp));
+ memp += 32/sizeof(*memp);
}
x = ((x << 1) | 1) & 0xff;
}
+ mtspr(SPR_LDSTCR, 0);
cache_reg = mfspr(SPR_L2CR);
if (cache_reg & L2CR_L2E) {
More information about the svn-src-projects
mailing list