1*3de6a9c0SDavid du Colombier /*
2*3de6a9c0SDavid du Colombier * caches defined by arm v7 architecture
3*3de6a9c0SDavid du Colombier */
4*3de6a9c0SDavid du Colombier #include "u.h"
5*3de6a9c0SDavid du Colombier #include "../port/lib.h"
6*3de6a9c0SDavid du Colombier #include "mem.h"
7*3de6a9c0SDavid du Colombier #include "dat.h"
8*3de6a9c0SDavid du Colombier #include "fns.h"
9*3de6a9c0SDavid du Colombier #include "../port/error.h"
10*3de6a9c0SDavid du Colombier #include "io.h"
11*3de6a9c0SDavid du Colombier #include "arm.h"
12*3de6a9c0SDavid du Colombier
13*3de6a9c0SDavid du Colombier static char *
l1iptype(uint type)14*3de6a9c0SDavid du Colombier l1iptype(uint type)
15*3de6a9c0SDavid du Colombier {
16*3de6a9c0SDavid du Colombier static char *types[] = {
17*3de6a9c0SDavid du Colombier "reserved",
18*3de6a9c0SDavid du Colombier "asid-tagged VIVT",
19*3de6a9c0SDavid du Colombier "VIPT",
20*3de6a9c0SDavid du Colombier "PIPT",
21*3de6a9c0SDavid du Colombier };
22*3de6a9c0SDavid du Colombier
23*3de6a9c0SDavid du Colombier if (type >= nelem(types) || types[type] == nil)
24*3de6a9c0SDavid du Colombier return "GOK";
25*3de6a9c0SDavid du Colombier return types[type];
26*3de6a9c0SDavid du Colombier }
27*3de6a9c0SDavid du Colombier
28*3de6a9c0SDavid du Colombier static char *catype[] = {
29*3de6a9c0SDavid du Colombier "none,",
30*3de6a9c0SDavid du Colombier "i,",
31*3de6a9c0SDavid du Colombier "d,",
32*3de6a9c0SDavid du Colombier "split i&d,",
33*3de6a9c0SDavid du Colombier "unified,",
34*3de6a9c0SDavid du Colombier "gok,",
35*3de6a9c0SDavid du Colombier "gok,",
36*3de6a9c0SDavid du Colombier "gok,",
37*3de6a9c0SDavid du Colombier };
38*3de6a9c0SDavid du Colombier
39*3de6a9c0SDavid du Colombier void
cacheinfo(int level,Memcache * cp,int ext,int type)40*3de6a9c0SDavid du Colombier cacheinfo(int level, Memcache *cp, int ext, int type)
41*3de6a9c0SDavid du Colombier {
42*3de6a9c0SDavid du Colombier ulong setsways;
43*3de6a9c0SDavid du Colombier
44*3de6a9c0SDavid du Colombier memset(cp, 0, sizeof *cp);
45*3de6a9c0SDavid du Colombier if (type == Nocache)
46*3de6a9c0SDavid du Colombier return;
47*3de6a9c0SDavid du Colombier cp->level = level;
48*3de6a9c0SDavid du Colombier cp->type = type;
49*3de6a9c0SDavid du Colombier cp->external = ext;
50*3de6a9c0SDavid du Colombier if (level == 2) { /* external PL310 */
51*3de6a9c0SDavid du Colombier allcache->info(cp);
52*3de6a9c0SDavid du Colombier setsways = cp->setsways;
53*3de6a9c0SDavid du Colombier } else {
54*3de6a9c0SDavid du Colombier /* select internal cache level */
55*3de6a9c0SDavid du Colombier cpwrsc(CpIDcssel, CpID, CpIDid, 0, (level - 1) << 1);
56*3de6a9c0SDavid du Colombier
57*3de6a9c0SDavid du Colombier setsways = cprdsc(CpIDcsize, CpID, CpIDid, 0);
58*3de6a9c0SDavid du Colombier cp->l1ip = cpctget();
59*3de6a9c0SDavid du Colombier cp->nways = ((setsways >> 3) & MASK(10)) + 1;
60*3de6a9c0SDavid du Colombier cp->nsets = ((setsways >> 13) & MASK(15)) + 1;
61*3de6a9c0SDavid du Colombier cp->log2linelen = (setsways & MASK(2)) + 2 + 2;
62*3de6a9c0SDavid du Colombier }
63*3de6a9c0SDavid du Colombier cp->linelen = 1 << cp->log2linelen;
64*3de6a9c0SDavid du Colombier cp->setsways = setsways;
65*3de6a9c0SDavid du Colombier cp->setsh = cp->log2linelen;
66*3de6a9c0SDavid du Colombier cp->waysh = 32 - log2(cp->nways);
67*3de6a9c0SDavid du Colombier }
68*3de6a9c0SDavid du Colombier
69*3de6a9c0SDavid du Colombier void
allcacheinfo(Memcache * mc)70*3de6a9c0SDavid du Colombier allcacheinfo(Memcache *mc)
71*3de6a9c0SDavid du Colombier {
72*3de6a9c0SDavid du Colombier int n;
73*3de6a9c0SDavid du Colombier ulong lvl;
74*3de6a9c0SDavid du Colombier
75*3de6a9c0SDavid du Colombier lvl = cprdsc(CpIDcsize, CpID, CpIDidct, CpIDclvlid);
76*3de6a9c0SDavid du Colombier n = 1;
77*3de6a9c0SDavid du Colombier for (lvl &= MASK(21); lvl; lvl >>= 3)
78*3de6a9c0SDavid du Colombier cacheinfo(n, &mc[n], Intcache, lvl & MASK(3));
79*3de6a9c0SDavid du Colombier // cacheinfo(2, &mc[2], Extcache, Unified); /* PL310 */
80*3de6a9c0SDavid du Colombier }
81*3de6a9c0SDavid du Colombier
82*3de6a9c0SDavid du Colombier void
prcachecfg(void)83*3de6a9c0SDavid du Colombier prcachecfg(void)
84*3de6a9c0SDavid du Colombier {
85*3de6a9c0SDavid du Colombier int cache;
86*3de6a9c0SDavid du Colombier Memcache *mc;
87*3de6a9c0SDavid du Colombier
88*3de6a9c0SDavid du Colombier for (cache = 1; cache < 8 && cachel[cache].type; cache++) {
89*3de6a9c0SDavid du Colombier mc = &cachel[cache];
90*3de6a9c0SDavid du Colombier iprint("l%d: %s %-10s %2d ways %4d sets %d bytes/line; can W[",
91*3de6a9c0SDavid du Colombier mc->level, mc->external? "ext": "int", catype[mc->type],
92*3de6a9c0SDavid du Colombier mc->nways, mc->nsets, mc->linelen);
93*3de6a9c0SDavid du Colombier if (mc->linelen != CACHELINESZ)
94*3de6a9c0SDavid du Colombier iprint(" *should* be %d", CACHELINESZ);
95*3de6a9c0SDavid du Colombier if (mc->setsways & Cawt)
96*3de6a9c0SDavid du Colombier iprint("T");
97*3de6a9c0SDavid du Colombier if (mc->setsways & Cawb)
98*3de6a9c0SDavid du Colombier iprint("B");
99*3de6a9c0SDavid du Colombier if (mc->setsways & Cawa)
100*3de6a9c0SDavid du Colombier iprint("A");
101*3de6a9c0SDavid du Colombier iprint("]");
102*3de6a9c0SDavid du Colombier if (cache == 1)
103*3de6a9c0SDavid du Colombier iprint("; l1-i %s", l1iptype((mc->l1ip >> 14) & MASK(2)));
104*3de6a9c0SDavid du Colombier iprint("\n");
105*3de6a9c0SDavid du Colombier }
106*3de6a9c0SDavid du Colombier }
107