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