1*3de6a9c0SDavid du Colombier #include "u.h"
2*3de6a9c0SDavid du Colombier #include "../port/lib.h"
3*3de6a9c0SDavid du Colombier #include "mem.h"
4*3de6a9c0SDavid du Colombier #include "dat.h"
5*3de6a9c0SDavid du Colombier #include "fns.h"
6*3de6a9c0SDavid du Colombier #include "../port/error.h"
7*3de6a9c0SDavid du Colombier #include "io.h"
8*3de6a9c0SDavid du Colombier
9*3de6a9c0SDavid du Colombier #include "../ip/ip.h"
10*3de6a9c0SDavid du Colombier
11*3de6a9c0SDavid du Colombier enum {
12*3de6a9c0SDavid du Colombier Qdir = 0,
13*3de6a9c0SDavid du Colombier Qbase,
14*3de6a9c0SDavid du Colombier
15*3de6a9c0SDavid du Colombier Qmax = 16,
16*3de6a9c0SDavid du Colombier };
17*3de6a9c0SDavid du Colombier
18*3de6a9c0SDavid du Colombier typedef long Rdwrfn(Chan*, void*, long, vlong);
19*3de6a9c0SDavid du Colombier
20*3de6a9c0SDavid du Colombier static Rdwrfn *readfn[Qmax];
21*3de6a9c0SDavid du Colombier static Rdwrfn *writefn[Qmax];
22*3de6a9c0SDavid du Colombier
23*3de6a9c0SDavid du Colombier static Dirtab archdir[Qmax] = {
24*3de6a9c0SDavid du Colombier ".", { Qdir, 0, QTDIR }, 0, 0555,
25*3de6a9c0SDavid du Colombier };
26*3de6a9c0SDavid du Colombier
27*3de6a9c0SDavid du Colombier Lock archwlock; /* the lock is only for changing archdir */
28*3de6a9c0SDavid du Colombier int narchdir = Qbase;
29*3de6a9c0SDavid du Colombier
30*3de6a9c0SDavid du Colombier /*
31*3de6a9c0SDavid du Colombier * Add a file to the #P listing. Once added, you can't delete it.
32*3de6a9c0SDavid du Colombier * You can't add a file with the same name as one already there,
33*3de6a9c0SDavid du Colombier * and you get a pointer to the Dirtab entry so you can do things
34*3de6a9c0SDavid du Colombier * like change the Qid version. Changing the Qid path is disallowed.
35*3de6a9c0SDavid du Colombier */
36*3de6a9c0SDavid du Colombier Dirtab*
addarchfile(char * name,int perm,Rdwrfn * rdfn,Rdwrfn * wrfn)37*3de6a9c0SDavid du Colombier addarchfile(char *name, int perm, Rdwrfn *rdfn, Rdwrfn *wrfn)
38*3de6a9c0SDavid du Colombier {
39*3de6a9c0SDavid du Colombier int i;
40*3de6a9c0SDavid du Colombier Dirtab d;
41*3de6a9c0SDavid du Colombier Dirtab *dp;
42*3de6a9c0SDavid du Colombier
43*3de6a9c0SDavid du Colombier memset(&d, 0, sizeof d);
44*3de6a9c0SDavid du Colombier strcpy(d.name, name);
45*3de6a9c0SDavid du Colombier d.perm = perm;
46*3de6a9c0SDavid du Colombier
47*3de6a9c0SDavid du Colombier lock(&archwlock);
48*3de6a9c0SDavid du Colombier if(narchdir >= Qmax){
49*3de6a9c0SDavid du Colombier unlock(&archwlock);
50*3de6a9c0SDavid du Colombier return nil;
51*3de6a9c0SDavid du Colombier }
52*3de6a9c0SDavid du Colombier
53*3de6a9c0SDavid du Colombier for(i=0; i<narchdir; i++)
54*3de6a9c0SDavid du Colombier if(strcmp(archdir[i].name, name) == 0){
55*3de6a9c0SDavid du Colombier unlock(&archwlock);
56*3de6a9c0SDavid du Colombier return nil;
57*3de6a9c0SDavid du Colombier }
58*3de6a9c0SDavid du Colombier
59*3de6a9c0SDavid du Colombier d.qid.path = narchdir;
60*3de6a9c0SDavid du Colombier archdir[narchdir] = d;
61*3de6a9c0SDavid du Colombier readfn[narchdir] = rdfn;
62*3de6a9c0SDavid du Colombier writefn[narchdir] = wrfn;
63*3de6a9c0SDavid du Colombier dp = &archdir[narchdir++];
64*3de6a9c0SDavid du Colombier unlock(&archwlock);
65*3de6a9c0SDavid du Colombier
66*3de6a9c0SDavid du Colombier return dp;
67*3de6a9c0SDavid du Colombier }
68*3de6a9c0SDavid du Colombier
69*3de6a9c0SDavid du Colombier static Chan*
archattach(char * spec)70*3de6a9c0SDavid du Colombier archattach(char* spec)
71*3de6a9c0SDavid du Colombier {
72*3de6a9c0SDavid du Colombier return devattach('P', spec);
73*3de6a9c0SDavid du Colombier }
74*3de6a9c0SDavid du Colombier
75*3de6a9c0SDavid du Colombier Walkqid*
archwalk(Chan * c,Chan * nc,char ** name,int nname)76*3de6a9c0SDavid du Colombier archwalk(Chan* c, Chan *nc, char** name, int nname)
77*3de6a9c0SDavid du Colombier {
78*3de6a9c0SDavid du Colombier return devwalk(c, nc, name, nname, archdir, narchdir, devgen);
79*3de6a9c0SDavid du Colombier }
80*3de6a9c0SDavid du Colombier
81*3de6a9c0SDavid du Colombier static int
archstat(Chan * c,uchar * dp,int n)82*3de6a9c0SDavid du Colombier archstat(Chan* c, uchar* dp, int n)
83*3de6a9c0SDavid du Colombier {
84*3de6a9c0SDavid du Colombier return devstat(c, dp, n, archdir, narchdir, devgen);
85*3de6a9c0SDavid du Colombier }
86*3de6a9c0SDavid du Colombier
87*3de6a9c0SDavid du Colombier static Chan*
archopen(Chan * c,int omode)88*3de6a9c0SDavid du Colombier archopen(Chan* c, int omode)
89*3de6a9c0SDavid du Colombier {
90*3de6a9c0SDavid du Colombier return devopen(c, omode, archdir, narchdir, devgen);
91*3de6a9c0SDavid du Colombier }
92*3de6a9c0SDavid du Colombier
93*3de6a9c0SDavid du Colombier static void
archclose(Chan *)94*3de6a9c0SDavid du Colombier archclose(Chan*)
95*3de6a9c0SDavid du Colombier {
96*3de6a9c0SDavid du Colombier }
97*3de6a9c0SDavid du Colombier
98*3de6a9c0SDavid du Colombier static long
archread(Chan * c,void * a,long n,vlong offset)99*3de6a9c0SDavid du Colombier archread(Chan *c, void *a, long n, vlong offset)
100*3de6a9c0SDavid du Colombier {
101*3de6a9c0SDavid du Colombier Rdwrfn *fn;
102*3de6a9c0SDavid du Colombier
103*3de6a9c0SDavid du Colombier switch((ulong)c->qid.path){
104*3de6a9c0SDavid du Colombier case Qdir:
105*3de6a9c0SDavid du Colombier return devdirread(c, a, n, archdir, narchdir, devgen);
106*3de6a9c0SDavid du Colombier
107*3de6a9c0SDavid du Colombier default:
108*3de6a9c0SDavid du Colombier if(c->qid.path < narchdir && (fn = readfn[c->qid.path]))
109*3de6a9c0SDavid du Colombier return fn(c, a, n, offset);
110*3de6a9c0SDavid du Colombier error(Eperm);
111*3de6a9c0SDavid du Colombier break;
112*3de6a9c0SDavid du Colombier }
113*3de6a9c0SDavid du Colombier
114*3de6a9c0SDavid du Colombier return 0;
115*3de6a9c0SDavid du Colombier }
116*3de6a9c0SDavid du Colombier
117*3de6a9c0SDavid du Colombier static long
archwrite(Chan * c,void * a,long n,vlong offset)118*3de6a9c0SDavid du Colombier archwrite(Chan *c, void *a, long n, vlong offset)
119*3de6a9c0SDavid du Colombier {
120*3de6a9c0SDavid du Colombier Rdwrfn *fn;
121*3de6a9c0SDavid du Colombier
122*3de6a9c0SDavid du Colombier if(c->qid.path < narchdir && (fn = writefn[c->qid.path]))
123*3de6a9c0SDavid du Colombier return fn(c, a, n, offset);
124*3de6a9c0SDavid du Colombier error(Eperm);
125*3de6a9c0SDavid du Colombier
126*3de6a9c0SDavid du Colombier return 0;
127*3de6a9c0SDavid du Colombier }
128*3de6a9c0SDavid du Colombier
129*3de6a9c0SDavid du Colombier void archinit(void);
130*3de6a9c0SDavid du Colombier
131*3de6a9c0SDavid du Colombier Dev archdevtab = {
132*3de6a9c0SDavid du Colombier 'P',
133*3de6a9c0SDavid du Colombier "arch",
134*3de6a9c0SDavid du Colombier
135*3de6a9c0SDavid du Colombier devreset,
136*3de6a9c0SDavid du Colombier archinit,
137*3de6a9c0SDavid du Colombier devshutdown,
138*3de6a9c0SDavid du Colombier archattach,
139*3de6a9c0SDavid du Colombier archwalk,
140*3de6a9c0SDavid du Colombier archstat,
141*3de6a9c0SDavid du Colombier archopen,
142*3de6a9c0SDavid du Colombier devcreate,
143*3de6a9c0SDavid du Colombier archclose,
144*3de6a9c0SDavid du Colombier archread,
145*3de6a9c0SDavid du Colombier devbread,
146*3de6a9c0SDavid du Colombier archwrite,
147*3de6a9c0SDavid du Colombier devbwrite,
148*3de6a9c0SDavid du Colombier devremove,
149*3de6a9c0SDavid du Colombier devwstat,
150*3de6a9c0SDavid du Colombier };
151*3de6a9c0SDavid du Colombier
152*3de6a9c0SDavid du Colombier static long
cputyperead(Chan *,void * a,long n,vlong offset)153*3de6a9c0SDavid du Colombier cputyperead(Chan*, void *a, long n, vlong offset)
154*3de6a9c0SDavid du Colombier {
155*3de6a9c0SDavid du Colombier char name[64], str[128];
156*3de6a9c0SDavid du Colombier
157*3de6a9c0SDavid du Colombier cputype2name(name, sizeof name);
158*3de6a9c0SDavid du Colombier snprint(str, sizeof str, "ARM %s %llud\n", name, m->cpuhz / Mhz);
159*3de6a9c0SDavid du Colombier return readstr(offset, a, n, str);
160*3de6a9c0SDavid du Colombier }
161*3de6a9c0SDavid du Colombier
162*3de6a9c0SDavid du Colombier static long
tbread(Chan *,void * a,long n,vlong offset)163*3de6a9c0SDavid du Colombier tbread(Chan*, void *a, long n, vlong offset)
164*3de6a9c0SDavid du Colombier {
165*3de6a9c0SDavid du Colombier char str[16];
166*3de6a9c0SDavid du Colombier uvlong tb;
167*3de6a9c0SDavid du Colombier
168*3de6a9c0SDavid du Colombier cycles(&tb);
169*3de6a9c0SDavid du Colombier
170*3de6a9c0SDavid du Colombier snprint(str, sizeof(str), "%16.16llux", tb);
171*3de6a9c0SDavid du Colombier return readstr(offset, a, n, str);
172*3de6a9c0SDavid du Colombier }
173*3de6a9c0SDavid du Colombier
174*3de6a9c0SDavid du Colombier static long
nsread(Chan *,void * a,long n,vlong offset)175*3de6a9c0SDavid du Colombier nsread(Chan*, void *a, long n, vlong offset)
176*3de6a9c0SDavid du Colombier {
177*3de6a9c0SDavid du Colombier char str[16];
178*3de6a9c0SDavid du Colombier uvlong tb;
179*3de6a9c0SDavid du Colombier
180*3de6a9c0SDavid du Colombier cycles(&tb);
181*3de6a9c0SDavid du Colombier
182*3de6a9c0SDavid du Colombier snprint(str, sizeof(str), "%16.16llux", (tb/700)* 1000);
183*3de6a9c0SDavid du Colombier return readstr(offset, a, n, str);
184*3de6a9c0SDavid du Colombier }
185*3de6a9c0SDavid du Colombier
186*3de6a9c0SDavid du Colombier void
archinit(void)187*3de6a9c0SDavid du Colombier archinit(void)
188*3de6a9c0SDavid du Colombier {
189*3de6a9c0SDavid du Colombier addarchfile("cputype", 0444, cputyperead, nil);
190*3de6a9c0SDavid du Colombier addarchfile("timebase",0444, tbread, nil);
191*3de6a9c0SDavid du Colombier // addarchfile("nsec", 0444, nsread, nil);
192*3de6a9c0SDavid du Colombier }
193