2 * PL310 level 2 cache (non-architectural bag on the side)
4 * guaranteed to work incorrectly with default settings; must set Sharovr.
6 * clean & invalidate (wbinv) is buggy, so we work around erratum 588369
7 * by disabling write-back and cache line-fill before, and restoring after.
10 #include "../port/lib.h"
15 #include "../port/error.h"
18 #define NWAYS(l2p) ((l2p)->auxctl & Assoc16way? 16: 8)
19 #define L2P ((L2pl310 *)soc.l2cache)
22 L2size = 1024 * 1024, /* according to the tegra 2 manual */
23 Wayszgran = 16 * KiB, /* granularity of way sizes */
26 typedef struct L2pl310 L2pl310;
27 typedef struct Pl310op Pl310op;
39 uchar _pad0[0x100 - 0x8];
43 uchar _pad1[0x730 - 0x108]; /* boring regs */
45 uchar _pad2[0x740 - 0x734];
46 ulong r3p0sync; /* workaround for r3p0 bug */
47 uchar _pad3[0x770 - 0x744];
48 Pl310op inv; /* inv.indexway doesn't exist */
49 uchar _pad4[0x7b0 - 0x780];
51 uchar _pad5[0x7f0 - 0x7c0];
53 uchar _pad6[0xc00 - 0x7d0];
56 uchar _pad6[0xf40 - 0xc08];
66 Ipref = 1<<29, /* prefetch enables */
69 Sharovr = 1<<22, /* shared attribute override (i.e., work right!) */
72 Waycfgmask = (1<<3) - 1,
75 * optim'n to 0 cache lines; must be enabled in a9(?!).
76 * set CpAClwr0line on all cpus 1st.
81 Wt = 1<<1, /* write-through, not write-back */
84 Basecfg = Wt | Nolinefill,
88 static int disallowed; /* by user: *l2off= in plan9.ini */
90 static int bg_op_running;
91 static ulong waysmask;
93 static Cacheimpl l2cacheimpl;
105 awaitbgop(); /* wait at normal PL first */
107 awaitbgop(); /* wait under lock */
117 /* call this first to set sets/ways configuration */
126 if (getconf("*l2off") != nil) {
127 // iprint("l2 cache (pl310) disabled\n");
131 if (l2ison || configed)
133 l2cache = &l2cacheimpl;
138 * l2: ext unified, 8 ways 512 sets 32 bytes/line => 128KB
139 * but the tegra 2 manual says there's 1MB available.
140 * ways or way-size may be fixed by hardware; the only way to tell
141 * is to try to change the setting and read it back.
146 /* figure out number of ways */
149 if (!(l2p->auxctl & Assoc16way)) {
150 l2p->auxctl |= Assoc16way;
154 // iprint("\nl2: was set for 8 ways, asked for 16, got %d\n", nways);
156 waysmask = MASK(nways);
158 /* figure out way size (and thus number of sets) */
159 waysz = L2size / nways;
160 new = l2p->auxctl & ~(Waycfgmask << Waycfgshift) |
161 (log2(waysz / Wayszgran) + 1) << Waycfgshift;
167 // iprint("\nl2: configed %d ways, %d sets (way size %d)\n", nways,
168 // waysz / CACHELINESZ, waysz);
169 if (l2p->auxctl != new)
170 iprint("l2 config %#8.8lux didn't stick; is now %#8.8lux\n",
176 l2pl310info(Memcache *cp)
182 memset(cp, 0, sizeof *cp);
187 assert((l2p->id >> 24) == 'A');
190 cp->external = Extcache;
191 cp->setsways = Cara | Cawa | Cawt | Cawb;
192 cp->l1ip = 3<<14; /* PIPT */
193 cp->setsh = cp->waysh = 0; /* bag on the side */
195 cp->linelen = CACHELINESZ;
196 cp->log2linelen = log2(CACHELINESZ);
198 cp->nways = NWAYS(l2p);
199 pow2 = ((l2p->auxctl >> Waycfgshift) & Waycfgmask) - 1;
202 waysz = (1 << pow2) * Wayszgran;
203 cp->nsets = waysz / CACHELINESZ;
212 if (getconf("*l2off") != nil) {
213 // iprint("l2 cache (pl310) disabled\n");
224 * drain l1. can't turn it off (which would make locks not work)
225 * because doing so makes references below to the l2 registers wedge
232 * this is only called once, on cpu0 at startup,
233 * so we don't need locks here.
234 * must do all configuration before enabling l2 cache.
238 l2p->filtstart = 0; /* no enable bit */
239 l2p->debug = 0; /* write-back, line fills allowed */
243 /* don't change number of sets & ways, but reset all else. */
244 ctl &= Waycfgmask << Waycfgshift | Assoc16way;
245 ctl |= Sharovr; /* actually work correctly for a change */
246 ctl |= Mbo | Ipref | Dpref | Parity | Fullline0;
250 l2p->ctl |= L2enable;
255 // iprint("l2 cache (pl310) now on\n");
265 L2P->ctl &= ~L2enable;
273 applyrange(ulong *reg, void *ava, int len)
277 if (disallowed || !l2ison)
280 panic("l2cache*se called with negative length");
281 endva = (uintptr)ava + len;
282 for (va = (uintptr)ava & ~(CACHELINESZ-1); va < endva;
289 l2pl310invse(void *va, int bytes)
295 * if start & end addresses are not on cache-line boundaries,
296 * flush first & last cachelines before invalidating.
301 if (start % CACHELINESZ != 0) {
302 // iprint("l2pl310invse: unaligned start %#p from %#p\n", start,
303 // getcallerpc(&va));
304 applyrange(&l2p->clean.pa, va, 1);
306 if (end % CACHELINESZ != 0) {
307 // iprint("l2pl310invse: unaligned end %#p from %#p\n", end,
308 // getcallerpc(&va));
309 applyrange(&l2p->clean.pa, (char *)va + bytes, 1);
312 applyrange(&l2p->inv.pa, va, bytes);
317 l2pl310wbse(void *va, int bytes)
320 applyrange(&L2P->clean.pa, va, bytes);
325 * assume that ldrex/strex (thus locks) won't work when Wt in is effect,
326 * so don't manipulate locks between setting and clearing Wt.
329 l2pl310wbinvse(void *va, int bytes)
337 applyrange(&l2p->clean.pa, va, bytes); /* paranoia */
340 l2p->debug |= Wt | Nolinefill; /* erratum workaround */
343 applyrange(&l2p->cleaninv.pa, va, bytes);
351 * we want to wait for completion at normal PL.
352 * if waiting is interrupted, interrupt code that calls
353 * these ops could deadlock on a uniprocessor, so we only
354 * give up l2lock before waiting on multiprocessors.
355 * in this port, only cpu 0 gets interrupts other than local timer ones.
368 l2p->inv.way = waysmask;
373 while (l2p->inv.way & waysmask)
384 * maximum time seen is 2542µs, typical is 625µs.
391 if (disallowed || !l2ison)
396 l2p->clean.way = waysmask;
401 while (l2p->clean.way & waysmask)
417 if (disallowed || !l2ison)
420 l2pl310wb(); /* paranoia */
425 l2p->debug |= Wt | Nolinefill; /* erratum workaround */
428 l2p->cleaninv.way = waysmask;
433 while (l2p->cleaninv.way & waysmask)
444 static Cacheimpl l2cacheimpl = {
451 .wbinv = l2pl310wbinv,
453 .invse = l2pl310invse,
455 .wbinvse= l2pl310wbinvse,