Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 5 Dec 2013 05:58:17 +0000 (UTC)
From:      Justin Hibbits <jhibbits@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r258957 - projects/pmac_pmu/sys/powerpc/powermac
Message-ID:  <201312050558.rB55wHD3074193@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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) {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201312050558.rB55wHD3074193>