svn commit: r253788 - head/sys/arm/arm
Olivier Houchard
cognet at FreeBSD.org
Mon Jul 29 21:45:40 UTC 2013
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);
More information about the svn-src-head
mailing list