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