/* * operations on all memory data or unified caches, a no-op cache, * and an l1-only cache ops cache. * i-caches are not handled here. * * there are only three cache operations that we care about: * force cache contents to memory (before dma out or shutdown), * ignore cache contents in favour of memory (initialisation, after dma in), * both (update page tables and force cpu to read new contents). */ #include "u.h" #include "../port/lib.h" #include "mem.h" #include "dat.h" #include "fns.h" #include "io.h" #include "../port/error.h" static Cacheimpl allcaches, nullcaches, l1caches; void cachesinfo(Memcache *cp) { memset(cp, 0, sizeof *cp); cp->setsways = Cara | Cawa | Cawt | Cawb; cp->l1ip = 3<<14; /* PIPT */ cp->log2linelen = log2(CACHELINESZ); } void allcacheson(void) { l2pl310init(); allcache = &allcaches; nocache = &nullcaches; l1cache = &l1caches; } void cachesoff(void) { l2cache->off(); } void cachesinvse(void *va, int bytes) { int s; s = splhi(); l2cache->invse(va, bytes); cachedinvse(va, bytes); splx(s); } void cacheswbse(void *va, int bytes) { int s; s = splhi(); cachedwbse(va, bytes); l2cache->wbse(va, bytes); splx(s); } void cacheswbinvse(void *va, int bytes) { int s; s = splhi(); cachedwbse(va, bytes); l2cache->wbinvse(va, bytes); cachedwbinvse(va, bytes); splx(s); } void cachesinv(void) { int s; s = splhi(); l2cache->inv(); cachedinv(); splx(s); } void cacheswb(void) { int s; s = splhi(); cachedwb(); l2cache->wb(); splx(s); } void cacheswbinv(void) { int s; s = splhi(); cachedwb(); l2cache->wbinv(); cachedwbinv(); splx(s); } static Cacheimpl allcaches = { .info = cachesinfo, .on = allcacheson, .off = cachesoff, .inv = cachesinv, .wb = cacheswb, .wbinv = cacheswbinv, .invse = cachesinvse, .wbse = cacheswbse, .wbinvse= cacheswbinvse, }; /* * null cache ops */ void nullinfo(Memcache *cp) { memset(cp, 0, sizeof *cp); cp->log2linelen = 2; } void nullon(void) { nocache = &nullcaches; } void nullop(void) { } void nullse(void *, int) { } static Cacheimpl nullcaches = { .info = nullinfo, .on = nullon, .off = nullop, .inv = nullop, .wb = nullop, .wbinv = nullop, .invse = nullse, .wbse = nullse, .wbinvse= nullse, }; /* * l1-only ops */ void l1cachesinfo(Memcache *) { } void l1cacheson(void) { l1cache = &l1caches; } static Cacheimpl l1caches = { .info = l1cachesinfo, .on = l1cacheson, .off = nullop, .inv = cachedinv, .wb = cachedwb, .wbinv = cachedwbinv, .invse = cachedinvse, .wbse = cachedwbse, .wbinvse= cachedwbinvse, };