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