Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 29 Jul 2013 21:45:39 +0000 (UTC)
From:      Olivier Houchard <cognet@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r253788 - head/sys/arm/arm
Message-ID:  <201307292145.r6TLjdQQ046475@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: cognet
Date: Mon Jul 29 21:45:39 2013
New Revision: 253788
URL: http://svnweb.freebsd.org/changeset/base/253788

Log:
  The errata 727915 requires a different workaround for r2p0, we have to
  explicitely clean/invalidate every cache line using way/set operations.

Modified:
  head/sys/arm/arm/pl310.c

Modified: head/sys/arm/arm/pl310.c
==============================================================================
--- head/sys/arm/arm/pl310.c	Mon Jul 29 21:32:57 2013	(r253787)
+++ head/sys/arm/arm/pl310.c	Mon Jul 29 21:45:39 2013	(r253788)
@@ -79,6 +79,8 @@ static const uint32_t g_l2cache_line_siz
 static const uint32_t g_l2cache_align_mask = (32 - 1);
 
 static uint32_t g_l2cache_size;
+static uint32_t g_way_size;
+static uint32_t g_ways_assoc;
 
 static struct pl310_softc *pl310_softc;
 
@@ -146,16 +148,29 @@ pl310_wbinv_all(void)
 
 	PL310_LOCK(pl310_softc);
 #ifdef PL310_ERRATA_727915
-	if (pl310_softc->sc_rtl_revision == CACHE_ID_RELEASE_r2p0 ||
-	    pl310_softc->sc_rtl_revision == CACHE_ID_RELEASE_r3p0)
+	if (pl310_softc->sc_rtl_revision == CACHE_ID_RELEASE_r2p0) {
+		int i, j;
+
+		for (i = 0; i < g_ways_assoc; i++) {
+			for (j = 0; j < g_way_size / g_l2cache_line_size; j++) {
+				pl310_write4(pl310_softc, 
+				    PL310_CLEAN_INV_LINE_IDX,
+				    (i << 28 | j << 5));
+			}
+		}
+		pl310_cache_sync();
+		PL310_UNLOCK(pl310_softc);
+		return;
+
+	}
+	if (pl310_softc->sc_rtl_revision == CACHE_ID_RELEASE_r3p0)
 		platform_pl310_write_debug(pl310_softc, 3);
 #endif
 	pl310_write4(pl310_softc, PL310_CLEAN_INV_WAY, g_l2cache_way_mask);
 	pl310_wait_background_op(PL310_CLEAN_INV_WAY, g_l2cache_way_mask);
 	pl310_cache_sync();
 #ifdef PL310_ERRATA_727915
-	if (pl310_softc->sc_rtl_revision == CACHE_ID_RELEASE_r2p0 ||
-	    pl310_softc->sc_rtl_revision == CACHE_ID_RELEASE_r3p0)
+	if (pl310_softc->sc_rtl_revision == CACHE_ID_RELEASE_r3p0)
 		platform_pl310_write_debug(pl310_softc, 0);
 #endif
 	PL310_UNLOCK(pl310_softc);
@@ -278,8 +293,6 @@ pl310_attach(device_t dev)
 	struct pl310_softc *sc = device_get_softc(dev);
 	int rid = 0;
 	uint32_t aux_value;
-	uint32_t way_size;
-	uint32_t ways_assoc;
 	uint32_t ctrl_value;
 	uint32_t cache_id;
 
@@ -312,18 +325,18 @@ pl310_attach(device_t dev)
 	    (cache_id >> CACHE_ID_PARTNUM_SHIFT) & CACHE_ID_PARTNUM_MASK,
 	    (cache_id >> CACHE_ID_RELEASE_SHIFT) & CACHE_ID_RELEASE_MASK);
 	aux_value = pl310_read4(sc, PL310_AUX_CTRL);
-	way_size = (aux_value & AUX_CTRL_WAY_SIZE_MASK) >>
+	g_way_size = (aux_value & AUX_CTRL_WAY_SIZE_MASK) >>
 	    AUX_CTRL_WAY_SIZE_SHIFT;
-	way_size = 1 << (way_size + 13);
+	g_way_size = 1 << (g_way_size + 13);
 	if (aux_value & (1 << AUX_CTRL_ASSOCIATIVITY_SHIFT))
-		ways_assoc = 16;
+		g_ways_assoc = 16;
 	else
-		ways_assoc = 8;
-	g_l2cache_way_mask = (1 << ways_assoc) - 1;
-	g_l2cache_size = way_size * ways_assoc;
+		g_ways_assoc = 8;
+	g_l2cache_way_mask = (1 << g_ways_assoc) - 1;
+	g_l2cache_size = g_way_size * g_ways_assoc;
 	/* Print the information */
 	device_printf(dev, "L2 Cache: %uKB/%dB %d ways\n", (g_l2cache_size / 1024),
-	       g_l2cache_line_size, ways_assoc);
+	       g_l2cache_line_size, g_ways_assoc);
 
 	ctrl_value = pl310_read4(sc, PL310_CTRL);
 



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