xref: /plan9-contrib/sys/src/9/rb/devarch.c (revision f43f8ee646e2cb29aea7fd7bb5fc7318a3f4921f)
1*f43f8ee6SDavid du Colombier #include "u.h"
2*f43f8ee6SDavid du Colombier #include "../port/lib.h"
3*f43f8ee6SDavid du Colombier #include "mem.h"
4*f43f8ee6SDavid du Colombier #include "dat.h"
5*f43f8ee6SDavid du Colombier #include "fns.h"
6*f43f8ee6SDavid du Colombier #include "../port/error.h"
7*f43f8ee6SDavid du Colombier #include "io.h"
8*f43f8ee6SDavid du Colombier 
9*f43f8ee6SDavid du Colombier #include "../ip/ip.h"
10*f43f8ee6SDavid du Colombier 
11*f43f8ee6SDavid du Colombier enum {
12*f43f8ee6SDavid du Colombier 	Qdir = 0,
13*f43f8ee6SDavid du Colombier 	Qbase,
14*f43f8ee6SDavid du Colombier 
15*f43f8ee6SDavid du Colombier 	Qmax = 16,
16*f43f8ee6SDavid du Colombier };
17*f43f8ee6SDavid du Colombier 
18*f43f8ee6SDavid du Colombier typedef long Rdwrfn(Chan*, void*, long, vlong);
19*f43f8ee6SDavid du Colombier 
20*f43f8ee6SDavid du Colombier static Rdwrfn *readfn[Qmax];
21*f43f8ee6SDavid du Colombier static Rdwrfn *writefn[Qmax];
22*f43f8ee6SDavid du Colombier 
23*f43f8ee6SDavid du Colombier static Dirtab archdir[Qmax] = {
24*f43f8ee6SDavid du Colombier 	".",		{ Qdir, 0, QTDIR },	0,	0555,
25*f43f8ee6SDavid du Colombier };
26*f43f8ee6SDavid du Colombier 
27*f43f8ee6SDavid du Colombier Lock archwlock;	/* the lock is only for changing archdir */
28*f43f8ee6SDavid du Colombier int narchdir = Qbase;
29*f43f8ee6SDavid du Colombier 
30*f43f8ee6SDavid du Colombier /*
31*f43f8ee6SDavid du Colombier  * Add a file to the #P listing.  Once added, you can't delete it.
32*f43f8ee6SDavid du Colombier  * You can't add a file with the same name as one already there,
33*f43f8ee6SDavid du Colombier  * and you get a pointer to the Dirtab entry so you can do things
34*f43f8ee6SDavid du Colombier  * like change the Qid version.  Changing the Qid path is disallowed.
35*f43f8ee6SDavid du Colombier  */
36*f43f8ee6SDavid du Colombier Dirtab*
addarchfile(char * name,int perm,Rdwrfn * rdfn,Rdwrfn * wrfn)37*f43f8ee6SDavid du Colombier addarchfile(char *name, int perm, Rdwrfn *rdfn, Rdwrfn *wrfn)
38*f43f8ee6SDavid du Colombier {
39*f43f8ee6SDavid du Colombier 	int i;
40*f43f8ee6SDavid du Colombier 	Dirtab d;
41*f43f8ee6SDavid du Colombier 	Dirtab *dp;
42*f43f8ee6SDavid du Colombier 
43*f43f8ee6SDavid du Colombier 	memset(&d, 0, sizeof d);
44*f43f8ee6SDavid du Colombier 	strcpy(d.name, name);
45*f43f8ee6SDavid du Colombier 	d.perm = perm;
46*f43f8ee6SDavid du Colombier 
47*f43f8ee6SDavid du Colombier 	lock(&archwlock);
48*f43f8ee6SDavid du Colombier 	if(narchdir >= Qmax){
49*f43f8ee6SDavid du Colombier 		unlock(&archwlock);
50*f43f8ee6SDavid du Colombier 		return nil;
51*f43f8ee6SDavid du Colombier 	}
52*f43f8ee6SDavid du Colombier 
53*f43f8ee6SDavid du Colombier 	for(i=0; i<narchdir; i++)
54*f43f8ee6SDavid du Colombier 		if(strcmp(archdir[i].name, name) == 0){
55*f43f8ee6SDavid du Colombier 			unlock(&archwlock);
56*f43f8ee6SDavid du Colombier 			return nil;
57*f43f8ee6SDavid du Colombier 		}
58*f43f8ee6SDavid du Colombier 
59*f43f8ee6SDavid du Colombier 	d.qid.path = narchdir;
60*f43f8ee6SDavid du Colombier 	archdir[narchdir] = d;
61*f43f8ee6SDavid du Colombier 	readfn[narchdir] = rdfn;
62*f43f8ee6SDavid du Colombier 	writefn[narchdir] = wrfn;
63*f43f8ee6SDavid du Colombier 	dp = &archdir[narchdir++];
64*f43f8ee6SDavid du Colombier 	unlock(&archwlock);
65*f43f8ee6SDavid du Colombier 
66*f43f8ee6SDavid du Colombier 	return dp;
67*f43f8ee6SDavid du Colombier }
68*f43f8ee6SDavid du Colombier 
69*f43f8ee6SDavid du Colombier static Chan*
archattach(char * spec)70*f43f8ee6SDavid du Colombier archattach(char* spec)
71*f43f8ee6SDavid du Colombier {
72*f43f8ee6SDavid du Colombier 	return devattach('P', spec);
73*f43f8ee6SDavid du Colombier }
74*f43f8ee6SDavid du Colombier 
75*f43f8ee6SDavid du Colombier Walkqid*
archwalk(Chan * c,Chan * nc,char ** name,int nname)76*f43f8ee6SDavid du Colombier archwalk(Chan* c, Chan *nc, char** name, int nname)
77*f43f8ee6SDavid du Colombier {
78*f43f8ee6SDavid du Colombier 	return devwalk(c, nc, name, nname, archdir, narchdir, devgen);
79*f43f8ee6SDavid du Colombier }
80*f43f8ee6SDavid du Colombier 
81*f43f8ee6SDavid du Colombier static int
archstat(Chan * c,uchar * dp,int n)82*f43f8ee6SDavid du Colombier archstat(Chan* c, uchar* dp, int n)
83*f43f8ee6SDavid du Colombier {
84*f43f8ee6SDavid du Colombier 	return devstat(c, dp, n, archdir, narchdir, devgen);
85*f43f8ee6SDavid du Colombier }
86*f43f8ee6SDavid du Colombier 
87*f43f8ee6SDavid du Colombier static Chan*
archopen(Chan * c,int omode)88*f43f8ee6SDavid du Colombier archopen(Chan* c, int omode)
89*f43f8ee6SDavid du Colombier {
90*f43f8ee6SDavid du Colombier 	return devopen(c, omode, archdir, narchdir, devgen);
91*f43f8ee6SDavid du Colombier }
92*f43f8ee6SDavid du Colombier 
93*f43f8ee6SDavid du Colombier static void
archclose(Chan *)94*f43f8ee6SDavid du Colombier archclose(Chan*)
95*f43f8ee6SDavid du Colombier {
96*f43f8ee6SDavid du Colombier }
97*f43f8ee6SDavid du Colombier 
98*f43f8ee6SDavid du Colombier static long
archread(Chan * c,void * a,long n,vlong offset)99*f43f8ee6SDavid du Colombier archread(Chan *c, void *a, long n, vlong offset)
100*f43f8ee6SDavid du Colombier {
101*f43f8ee6SDavid du Colombier 	Rdwrfn *fn;
102*f43f8ee6SDavid du Colombier 
103*f43f8ee6SDavid du Colombier 	switch((ulong)c->qid.path){
104*f43f8ee6SDavid du Colombier 	case Qdir:
105*f43f8ee6SDavid du Colombier 		return devdirread(c, a, n, archdir, narchdir, devgen);
106*f43f8ee6SDavid du Colombier 
107*f43f8ee6SDavid du Colombier 	default:
108*f43f8ee6SDavid du Colombier 		if(c->qid.path < narchdir && (fn = readfn[c->qid.path]))
109*f43f8ee6SDavid du Colombier 			return fn(c, a, n, offset);
110*f43f8ee6SDavid du Colombier 		error(Eperm);
111*f43f8ee6SDavid du Colombier 		break;
112*f43f8ee6SDavid du Colombier 	}
113*f43f8ee6SDavid du Colombier 
114*f43f8ee6SDavid du Colombier 	return 0;
115*f43f8ee6SDavid du Colombier }
116*f43f8ee6SDavid du Colombier 
117*f43f8ee6SDavid du Colombier static long
archwrite(Chan * c,void * a,long n,vlong offset)118*f43f8ee6SDavid du Colombier archwrite(Chan *c, void *a, long n, vlong offset)
119*f43f8ee6SDavid du Colombier {
120*f43f8ee6SDavid du Colombier 	Rdwrfn *fn;
121*f43f8ee6SDavid du Colombier 
122*f43f8ee6SDavid du Colombier 	if(c->qid.path < narchdir && (fn = writefn[c->qid.path]))
123*f43f8ee6SDavid du Colombier 		return fn(c, a, n, offset);
124*f43f8ee6SDavid du Colombier 	error(Eperm);
125*f43f8ee6SDavid du Colombier 
126*f43f8ee6SDavid du Colombier 	return 0;
127*f43f8ee6SDavid du Colombier }
128*f43f8ee6SDavid du Colombier 
129*f43f8ee6SDavid du Colombier void archinit(void);
130*f43f8ee6SDavid du Colombier 
131*f43f8ee6SDavid du Colombier Dev archdevtab = {
132*f43f8ee6SDavid du Colombier 	'P',
133*f43f8ee6SDavid du Colombier 	"arch",
134*f43f8ee6SDavid du Colombier 
135*f43f8ee6SDavid du Colombier 	devreset,
136*f43f8ee6SDavid du Colombier 	archinit,
137*f43f8ee6SDavid du Colombier 	devshutdown,
138*f43f8ee6SDavid du Colombier 	archattach,
139*f43f8ee6SDavid du Colombier 	archwalk,
140*f43f8ee6SDavid du Colombier 	archstat,
141*f43f8ee6SDavid du Colombier 	archopen,
142*f43f8ee6SDavid du Colombier 	devcreate,
143*f43f8ee6SDavid du Colombier 	archclose,
144*f43f8ee6SDavid du Colombier 	archread,
145*f43f8ee6SDavid du Colombier 	devbread,
146*f43f8ee6SDavid du Colombier 	archwrite,
147*f43f8ee6SDavid du Colombier 	devbwrite,
148*f43f8ee6SDavid du Colombier 	devremove,
149*f43f8ee6SDavid du Colombier 	devwstat,
150*f43f8ee6SDavid du Colombier };
151*f43f8ee6SDavid du Colombier 
152*f43f8ee6SDavid du Colombier static long
cputyperead(Chan *,void * a,long n,vlong offset)153*f43f8ee6SDavid du Colombier cputyperead(Chan*, void *a, long n, vlong offset)
154*f43f8ee6SDavid du Colombier {
155*f43f8ee6SDavid du Colombier 	char str[128];
156*f43f8ee6SDavid du Colombier 
157*f43f8ee6SDavid du Colombier 	snprint(str, sizeof str, "MIPS 24k %lud\n", m->hz / Mhz);
158*f43f8ee6SDavid du Colombier 	return readstr(offset, a, n, str);
159*f43f8ee6SDavid du Colombier }
160*f43f8ee6SDavid du Colombier 
161*f43f8ee6SDavid du Colombier static long
tbread(Chan *,void * a,long n,vlong offset)162*f43f8ee6SDavid du Colombier tbread(Chan*, void *a, long n, vlong offset)
163*f43f8ee6SDavid du Colombier {
164*f43f8ee6SDavid du Colombier 	char str[16];
165*f43f8ee6SDavid du Colombier 	uvlong tb;
166*f43f8ee6SDavid du Colombier 
167*f43f8ee6SDavid du Colombier 	cycles(&tb);
168*f43f8ee6SDavid du Colombier 
169*f43f8ee6SDavid du Colombier 	snprint(str, sizeof(str), "%16.16llux", tb);
170*f43f8ee6SDavid du Colombier 	return readstr(offset, a, n, str);
171*f43f8ee6SDavid du Colombier }
172*f43f8ee6SDavid du Colombier 
173*f43f8ee6SDavid du Colombier static long
nsread(Chan *,void * a,long n,vlong offset)174*f43f8ee6SDavid du Colombier nsread(Chan*, void *a, long n, vlong offset)
175*f43f8ee6SDavid du Colombier {
176*f43f8ee6SDavid du Colombier 	char str[16];
177*f43f8ee6SDavid du Colombier 	uvlong tb;
178*f43f8ee6SDavid du Colombier 
179*f43f8ee6SDavid du Colombier 	cycles(&tb);
180*f43f8ee6SDavid du Colombier 
181*f43f8ee6SDavid du Colombier 	snprint(str, sizeof(str), "%16.16llux", (tb/700)* 1000);
182*f43f8ee6SDavid du Colombier 	return readstr(offset, a, n, str);
183*f43f8ee6SDavid du Colombier }
184*f43f8ee6SDavid du Colombier 
185*f43f8ee6SDavid du Colombier char *cputype = "mips";
186*f43f8ee6SDavid du Colombier 
187*f43f8ee6SDavid du Colombier char	*faultsprint(char *, char *);
188*f43f8ee6SDavid du Colombier char	*fpemuprint(char *, char *);
189*f43f8ee6SDavid du Colombier 
190*f43f8ee6SDavid du Colombier static long
archctlread(Chan *,void * a,long nn,vlong offset)191*f43f8ee6SDavid du Colombier archctlread(Chan*, void *a, long nn, vlong offset)
192*f43f8ee6SDavid du Colombier {
193*f43f8ee6SDavid du Colombier 	int n;
194*f43f8ee6SDavid du Colombier 	char *buf, *p, *ep;
195*f43f8ee6SDavid du Colombier 
196*f43f8ee6SDavid du Colombier 	p = buf = malloc(READSTR);
197*f43f8ee6SDavid du Colombier 	if(p == nil)
198*f43f8ee6SDavid du Colombier 		error(Enomem);
199*f43f8ee6SDavid du Colombier 	ep = p + READSTR;
200*f43f8ee6SDavid du Colombier 	p = seprint(p, ep, "cpu %s %lud\n", cputype,
201*f43f8ee6SDavid du Colombier 		(ulong)(m->hz+999999)/1000000);
202*f43f8ee6SDavid du Colombier 	p = seprint(p, ep, "stlb hash collisions");
203*f43f8ee6SDavid du Colombier 	for (n = 0; n < conf.nmach; n++)
204*f43f8ee6SDavid du Colombier 		p = seprint(p, ep, " %d", MACHP(n)->hashcoll);
205*f43f8ee6SDavid du Colombier 	p = seprint(p, ep, "\n");
206*f43f8ee6SDavid du Colombier 	p = seprint(p, ep, "NKTLB %d ktlb misses %ld utlb misses %ld\n",
207*f43f8ee6SDavid du Colombier 		NKTLB, m->ktlbfault, m->utlbfault);
208*f43f8ee6SDavid du Colombier 	p = fpemuprint(p, ep);
209*f43f8ee6SDavid du Colombier 	faultsprint(p, ep);
210*f43f8ee6SDavid du Colombier 	n = readstr(offset, a, nn, buf);
211*f43f8ee6SDavid du Colombier 	free(buf);
212*f43f8ee6SDavid du Colombier 	return n;
213*f43f8ee6SDavid du Colombier }
214*f43f8ee6SDavid du Colombier 
215*f43f8ee6SDavid du Colombier enum
216*f43f8ee6SDavid du Colombier {
217*f43f8ee6SDavid du Colombier 	CMfpemudebug,
218*f43f8ee6SDavid du Colombier };
219*f43f8ee6SDavid du Colombier 
220*f43f8ee6SDavid du Colombier static Cmdtab archctlmsg[] =
221*f43f8ee6SDavid du Colombier {
222*f43f8ee6SDavid du Colombier #ifdef FPEMUDEBUG
223*f43f8ee6SDavid du Colombier 	CMfpemudebug,	"fpemudebug",	2,
224*f43f8ee6SDavid du Colombier #else
225*f43f8ee6SDavid du Colombier 	CMfpemudebug,	"dummy",	1,
226*f43f8ee6SDavid du Colombier #endif
227*f43f8ee6SDavid du Colombier };
228*f43f8ee6SDavid du Colombier 
229*f43f8ee6SDavid du Colombier static long
archctlwrite(Chan *,void * a,long n,vlong)230*f43f8ee6SDavid du Colombier archctlwrite(Chan*, void *a, long n, vlong)
231*f43f8ee6SDavid du Colombier {
232*f43f8ee6SDavid du Colombier 	Cmdbuf *cb;
233*f43f8ee6SDavid du Colombier 	Cmdtab *ct;
234*f43f8ee6SDavid du Colombier 
235*f43f8ee6SDavid du Colombier 	cb = parsecmd(a, n);
236*f43f8ee6SDavid du Colombier 	if(waserror()){
237*f43f8ee6SDavid du Colombier 		free(cb);
238*f43f8ee6SDavid du Colombier 		nexterror();
239*f43f8ee6SDavid du Colombier 	}
240*f43f8ee6SDavid du Colombier 	ct = lookupcmd(cb, archctlmsg, nelem(archctlmsg));
241*f43f8ee6SDavid du Colombier 	switch(ct->index){
242*f43f8ee6SDavid du Colombier 	case CMfpemudebug:
243*f43f8ee6SDavid du Colombier 		fpemudebug = atoi(cb->f[1]);
244*f43f8ee6SDavid du Colombier 		break;
245*f43f8ee6SDavid du Colombier 	}
246*f43f8ee6SDavid du Colombier 	free(cb);
247*f43f8ee6SDavid du Colombier 	poperror();
248*f43f8ee6SDavid du Colombier 	return n;
249*f43f8ee6SDavid du Colombier }
250*f43f8ee6SDavid du Colombier 
251*f43f8ee6SDavid du Colombier void
archinit(void)252*f43f8ee6SDavid du Colombier archinit(void)
253*f43f8ee6SDavid du Colombier {
254*f43f8ee6SDavid du Colombier 	addarchfile("cputype", 0444, cputyperead, nil);
255*f43f8ee6SDavid du Colombier 	addarchfile("timebase",0444, tbread, nil);
256*f43f8ee6SDavid du Colombier 	addarchfile("archctl", 0664, archctlread, archctlwrite);
257*f43f8ee6SDavid du Colombier //	addarchfile("nsec", 0444, nsread, nil);
258*f43f8ee6SDavid du Colombier }
259