xref: /plan9/sys/src/9/teg2/caches-v7.c (revision 3de6a9c0b3d5cf34fc4090d0bf1930d83799a7fd)
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