/*
* 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,
};
|