xref: /plan9-contrib/sys/src/9/bcm/devarch.c (revision 5c47fe09a0cc86dfb02c0ea4a2b6aec7eda2361f)
15d9de2d3SDavid du Colombier #include "u.h"
25d9de2d3SDavid du Colombier #include "../port/lib.h"
35d9de2d3SDavid du Colombier #include "mem.h"
45d9de2d3SDavid du Colombier #include "dat.h"
55d9de2d3SDavid du Colombier #include "fns.h"
65d9de2d3SDavid du Colombier #include "../port/error.h"
75d9de2d3SDavid du Colombier #include "io.h"
85d9de2d3SDavid du Colombier 
95d9de2d3SDavid du Colombier enum {
105d9de2d3SDavid du Colombier 	Qdir = 0,
115d9de2d3SDavid du Colombier 	Qbase,
125d9de2d3SDavid du Colombier 
135d9de2d3SDavid du Colombier 	Qmax = 16,
145d9de2d3SDavid du Colombier };
155d9de2d3SDavid du Colombier 
165d9de2d3SDavid du Colombier typedef long Rdwrfn(Chan*, void*, long, vlong);
175d9de2d3SDavid du Colombier 
185d9de2d3SDavid du Colombier static Rdwrfn *readfn[Qmax];
195d9de2d3SDavid du Colombier static Rdwrfn *writefn[Qmax];
205d9de2d3SDavid du Colombier 
215d9de2d3SDavid du Colombier static Dirtab archdir[Qmax] = {
225d9de2d3SDavid du Colombier 	".",		{ Qdir, 0, QTDIR },	0,	0555,
235d9de2d3SDavid du Colombier };
245d9de2d3SDavid du Colombier 
255d9de2d3SDavid du Colombier Lock archwlock;	/* the lock is only for changing archdir */
265d9de2d3SDavid du Colombier int narchdir = Qbase;
275d9de2d3SDavid du Colombier 
285d9de2d3SDavid du Colombier /*
295d9de2d3SDavid du Colombier  * Add a file to the #P listing.  Once added, you can't delete it.
305d9de2d3SDavid du Colombier  * You can't add a file with the same name as one already there,
315d9de2d3SDavid du Colombier  * and you get a pointer to the Dirtab entry so you can do things
325d9de2d3SDavid du Colombier  * like change the Qid version.  Changing the Qid path is disallowed.
335d9de2d3SDavid du Colombier  */
345d9de2d3SDavid du Colombier Dirtab*
addarchfile(char * name,int perm,Rdwrfn * rdfn,Rdwrfn * wrfn)355d9de2d3SDavid du Colombier addarchfile(char *name, int perm, Rdwrfn *rdfn, Rdwrfn *wrfn)
365d9de2d3SDavid du Colombier {
375d9de2d3SDavid du Colombier 	int i;
385d9de2d3SDavid du Colombier 	Dirtab d;
395d9de2d3SDavid du Colombier 	Dirtab *dp;
405d9de2d3SDavid du Colombier 
415d9de2d3SDavid du Colombier 	memset(&d, 0, sizeof d);
425d9de2d3SDavid du Colombier 	strcpy(d.name, name);
435d9de2d3SDavid du Colombier 	d.perm = perm;
445d9de2d3SDavid du Colombier 
455d9de2d3SDavid du Colombier 	lock(&archwlock);
465d9de2d3SDavid du Colombier 	if(narchdir >= Qmax){
475d9de2d3SDavid du Colombier 		unlock(&archwlock);
485d9de2d3SDavid du Colombier 		return nil;
495d9de2d3SDavid du Colombier 	}
505d9de2d3SDavid du Colombier 
515d9de2d3SDavid du Colombier 	for(i=0; i<narchdir; i++)
525d9de2d3SDavid du Colombier 		if(strcmp(archdir[i].name, name) == 0){
535d9de2d3SDavid du Colombier 			unlock(&archwlock);
545d9de2d3SDavid du Colombier 			return nil;
555d9de2d3SDavid du Colombier 		}
565d9de2d3SDavid du Colombier 
575d9de2d3SDavid du Colombier 	d.qid.path = narchdir;
585d9de2d3SDavid du Colombier 	archdir[narchdir] = d;
595d9de2d3SDavid du Colombier 	readfn[narchdir] = rdfn;
605d9de2d3SDavid du Colombier 	writefn[narchdir] = wrfn;
615d9de2d3SDavid du Colombier 	dp = &archdir[narchdir++];
625d9de2d3SDavid du Colombier 	unlock(&archwlock);
635d9de2d3SDavid du Colombier 
645d9de2d3SDavid du Colombier 	return dp;
655d9de2d3SDavid du Colombier }
665d9de2d3SDavid du Colombier 
675d9de2d3SDavid du Colombier static Chan*
archattach(char * spec)685d9de2d3SDavid du Colombier archattach(char* spec)
695d9de2d3SDavid du Colombier {
705d9de2d3SDavid du Colombier 	return devattach('P', spec);
715d9de2d3SDavid du Colombier }
725d9de2d3SDavid du Colombier 
735d9de2d3SDavid du Colombier Walkqid*
archwalk(Chan * c,Chan * nc,char ** name,int nname)745d9de2d3SDavid du Colombier archwalk(Chan* c, Chan *nc, char** name, int nname)
755d9de2d3SDavid du Colombier {
765d9de2d3SDavid du Colombier 	return devwalk(c, nc, name, nname, archdir, narchdir, devgen);
775d9de2d3SDavid du Colombier }
785d9de2d3SDavid du Colombier 
795d9de2d3SDavid du Colombier static int
archstat(Chan * c,uchar * dp,int n)805d9de2d3SDavid du Colombier archstat(Chan* c, uchar* dp, int n)
815d9de2d3SDavid du Colombier {
825d9de2d3SDavid du Colombier 	return devstat(c, dp, n, archdir, narchdir, devgen);
835d9de2d3SDavid du Colombier }
845d9de2d3SDavid du Colombier 
855d9de2d3SDavid du Colombier static Chan*
archopen(Chan * c,int omode)865d9de2d3SDavid du Colombier archopen(Chan* c, int omode)
875d9de2d3SDavid du Colombier {
885d9de2d3SDavid du Colombier 	return devopen(c, omode, archdir, narchdir, devgen);
895d9de2d3SDavid du Colombier }
905d9de2d3SDavid du Colombier 
915d9de2d3SDavid du Colombier static void
archclose(Chan *)925d9de2d3SDavid du Colombier archclose(Chan*)
935d9de2d3SDavid du Colombier {
945d9de2d3SDavid du Colombier }
955d9de2d3SDavid du Colombier 
965d9de2d3SDavid du Colombier static long
archread(Chan * c,void * a,long n,vlong offset)975d9de2d3SDavid du Colombier archread(Chan *c, void *a, long n, vlong offset)
985d9de2d3SDavid du Colombier {
995d9de2d3SDavid du Colombier 	Rdwrfn *fn;
1005d9de2d3SDavid du Colombier 
1015d9de2d3SDavid du Colombier 	switch((ulong)c->qid.path){
1025d9de2d3SDavid du Colombier 	case Qdir:
1035d9de2d3SDavid du Colombier 		return devdirread(c, a, n, archdir, narchdir, devgen);
1045d9de2d3SDavid du Colombier 
1055d9de2d3SDavid du Colombier 	default:
1065d9de2d3SDavid du Colombier 		if(c->qid.path < narchdir && (fn = readfn[c->qid.path]))
1075d9de2d3SDavid du Colombier 			return fn(c, a, n, offset);
1085d9de2d3SDavid du Colombier 		error(Eperm);
1095d9de2d3SDavid du Colombier 		break;
1105d9de2d3SDavid du Colombier 	}
1115d9de2d3SDavid du Colombier 
1125d9de2d3SDavid du Colombier 	return 0;
1135d9de2d3SDavid du Colombier }
1145d9de2d3SDavid du Colombier 
1155d9de2d3SDavid du Colombier static long
archwrite(Chan * c,void * a,long n,vlong offset)1165d9de2d3SDavid du Colombier archwrite(Chan *c, void *a, long n, vlong offset)
1175d9de2d3SDavid du Colombier {
1185d9de2d3SDavid du Colombier 	Rdwrfn *fn;
1195d9de2d3SDavid du Colombier 
1205d9de2d3SDavid du Colombier 	if(c->qid.path < narchdir && (fn = writefn[c->qid.path]))
1215d9de2d3SDavid du Colombier 		return fn(c, a, n, offset);
1225d9de2d3SDavid du Colombier 	error(Eperm);
1235d9de2d3SDavid du Colombier 
1245d9de2d3SDavid du Colombier 	return 0;
1255d9de2d3SDavid du Colombier }
1265d9de2d3SDavid du Colombier 
1275d9de2d3SDavid du Colombier void archinit(void);
1285d9de2d3SDavid du Colombier 
1295d9de2d3SDavid du Colombier Dev archdevtab = {
1305d9de2d3SDavid du Colombier 	'P',
1315d9de2d3SDavid du Colombier 	"arch",
1325d9de2d3SDavid du Colombier 
1335d9de2d3SDavid du Colombier 	devreset,
1345d9de2d3SDavid du Colombier 	archinit,
1355d9de2d3SDavid du Colombier 	devshutdown,
1365d9de2d3SDavid du Colombier 	archattach,
1375d9de2d3SDavid du Colombier 	archwalk,
1385d9de2d3SDavid du Colombier 	archstat,
1395d9de2d3SDavid du Colombier 	archopen,
1405d9de2d3SDavid du Colombier 	devcreate,
1415d9de2d3SDavid du Colombier 	archclose,
1425d9de2d3SDavid du Colombier 	archread,
1435d9de2d3SDavid du Colombier 	devbread,
1445d9de2d3SDavid du Colombier 	archwrite,
1455d9de2d3SDavid du Colombier 	devbwrite,
1465d9de2d3SDavid du Colombier 	devremove,
1475d9de2d3SDavid du Colombier 	devwstat,
1485d9de2d3SDavid du Colombier };
1495d9de2d3SDavid du Colombier 
1505d9de2d3SDavid du Colombier static long
cputyperead(Chan *,void * a,long n,vlong offset)1515d9de2d3SDavid du Colombier cputyperead(Chan*, void *a, long n, vlong offset)
1525d9de2d3SDavid du Colombier {
153*5c47fe09SDavid du Colombier 	char name[64], str[128];
1545d9de2d3SDavid du Colombier 
155*5c47fe09SDavid du Colombier 	cputype2name(name, sizeof name);
156*5c47fe09SDavid du Colombier 	snprint(str, sizeof str, "ARM %s %d\n", name, m->cpumhz);
157*5c47fe09SDavid du Colombier 	return readstr(offset, a, n, str);
158*5c47fe09SDavid du Colombier }
159*5c47fe09SDavid du Colombier 
160*5c47fe09SDavid du Colombier static long
cputempread(Chan *,void * a,long n,vlong offset)161*5c47fe09SDavid du Colombier cputempread(Chan*, void *a, long n, vlong offset)
162*5c47fe09SDavid du Colombier {
163*5c47fe09SDavid du Colombier 	char str[16];
164*5c47fe09SDavid du Colombier 
165*5c47fe09SDavid du Colombier 	snprint(str, sizeof str, "%ud\n", (getcputemp()+500)/1000);
166*5c47fe09SDavid du Colombier 	return readstr(offset, a, n, str);
167*5c47fe09SDavid du Colombier }
168*5c47fe09SDavid du Colombier 
169*5c47fe09SDavid du Colombier extern uvlong getserial(void);
170*5c47fe09SDavid du Colombier 
171*5c47fe09SDavid du Colombier static long
cpuserread(Chan *,void * a,long n,vlong offset)172*5c47fe09SDavid du Colombier cpuserread(Chan*, void *a, long n, vlong offset)
173*5c47fe09SDavid du Colombier {
174*5c47fe09SDavid du Colombier 	char str[16];
175*5c47fe09SDavid du Colombier 
176*5c47fe09SDavid du Colombier 	snprint(str, sizeof str, "%16.16llux", getserial());
1775d9de2d3SDavid du Colombier 	return readstr(offset, a, n, str);
1785d9de2d3SDavid du Colombier }
1795d9de2d3SDavid du Colombier 
1805d9de2d3SDavid du Colombier void
archinit(void)1815d9de2d3SDavid du Colombier archinit(void)
1825d9de2d3SDavid du Colombier {
1835d9de2d3SDavid du Colombier 	addarchfile("cputype", 0444, cputyperead, nil);
184*5c47fe09SDavid du Colombier 	addarchfile("cputemp", 0444, cputempread, nil);
185*5c47fe09SDavid du Colombier 	addarchfile("serial", 0444, cpuserread, nil)->length = 16;
1865d9de2d3SDavid du Colombier }
187