/*
* caches defined by arm v7 architecture
*/
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "../port/error.h"
#include "io.h"
#include "arm.h"
static char *
l1iptype(uint type)
{
static char *types[] = {
"reserved",
"asid-tagged VIVT",
"VIPT",
"PIPT",
};
if (type >= nelem(types) || types[type] == nil)
return "GOK";
return types[type];
}
static char *catype[] = {
"none,",
"i,",
"d,",
"split i&d,",
"unified,",
"gok,",
"gok,",
"gok,",
};
void
cacheinfo(int level, Memcache *cp, int ext, int type)
{
ulong setsways;
memset(cp, 0, sizeof *cp);
if (type == Nocache)
return;
cp->level = level;
cp->type = type;
cp->external = ext;
if (level == 2) { /* external PL310 */
allcache->info(cp);
setsways = cp->setsways;
} else {
/* select internal cache level */
cpwrsc(CpIDcssel, CpID, CpIDid, 0, (level - 1) << 1);
setsways = cprdsc(CpIDcsize, CpID, CpIDid, 0);
cp->l1ip = cpctget();
cp->nways = ((setsways >> 3) & MASK(10)) + 1;
cp->nsets = ((setsways >> 13) & MASK(15)) + 1;
cp->log2linelen = (setsways & MASK(2)) + 2 + 2;
}
cp->linelen = 1 << cp->log2linelen;
cp->setsways = setsways;
cp->setsh = cp->log2linelen;
cp->waysh = 32 - log2(cp->nways);
}
void
allcacheinfo(Memcache *mc)
{
int n;
ulong lvl;
lvl = cprdsc(CpIDcsize, CpID, CpIDidct, CpIDclvlid);
n = 1;
for (lvl &= MASK(21); lvl; lvl >>= 3)
cacheinfo(n, &mc[n], Intcache, lvl & MASK(3));
// cacheinfo(2, &mc[2], Extcache, Unified); /* PL310 */
}
void
prcachecfg(void)
{
int cache;
Memcache *mc;
for (cache = 1; cache < 8 && cachel[cache].type; cache++) {
mc = &cachel[cache];
iprint("l%d: %s %-10s %2d ways %4d sets %d bytes/line; can W[",
mc->level, mc->external? "ext": "int", catype[mc->type],
mc->nways, mc->nsets, mc->linelen);
if (mc->linelen != CACHELINESZ)
iprint(" *should* be %d", CACHELINESZ);
if (mc->setsways & Cawt)
iprint("T");
if (mc->setsways & Cawb)
iprint("B");
if (mc->setsways & Cawa)
iprint("A");
iprint("]");
if (cache == 1)
iprint("; l1-i %s", l1iptype((mc->l1ip >> 14) & MASK(2)));
iprint("\n");
}
}
|