18e32b400SDavid du Colombier #include "u.h"
28e32b400SDavid du Colombier #include "../port/lib.h"
38e32b400SDavid du Colombier #include "mem.h"
48e32b400SDavid du Colombier #include "dat.h"
58e32b400SDavid du Colombier #include "fns.h"
68e32b400SDavid du Colombier #include "../port/error.h"
78e32b400SDavid du Colombier #include "io.h"
88e32b400SDavid du Colombier
98e32b400SDavid du Colombier #include "../ip/ip.h"
108e32b400SDavid du Colombier
118e32b400SDavid du Colombier enum {
128e32b400SDavid du Colombier Qdir = 0,
138e32b400SDavid du Colombier Qbase,
148e32b400SDavid du Colombier
158e32b400SDavid du Colombier Qmax = 16,
168e32b400SDavid du Colombier };
178e32b400SDavid du Colombier
188e32b400SDavid du Colombier typedef long Rdwrfn(Chan*, void*, long, vlong);
198e32b400SDavid du Colombier
208e32b400SDavid du Colombier static Rdwrfn *readfn[Qmax];
218e32b400SDavid du Colombier static Rdwrfn *writefn[Qmax];
228e32b400SDavid du Colombier
238e32b400SDavid du Colombier static Dirtab archdir[Qmax] = {
248e32b400SDavid du Colombier ".", { Qdir, 0, QTDIR }, 0, 0555,
258e32b400SDavid du Colombier };
268e32b400SDavid du Colombier
278e32b400SDavid du Colombier Lock archwlock; /* the lock is only for changing archdir */
288e32b400SDavid du Colombier int narchdir = Qbase;
298e32b400SDavid du Colombier
308e32b400SDavid du Colombier /*
318e32b400SDavid du Colombier * Add a file to the #P listing. Once added, you can't delete it.
328e32b400SDavid du Colombier * You can't add a file with the same name as one already there,
338e32b400SDavid du Colombier * and you get a pointer to the Dirtab entry so you can do things
348e32b400SDavid du Colombier * like change the Qid version. Changing the Qid path is disallowed.
358e32b400SDavid du Colombier */
368e32b400SDavid du Colombier Dirtab*
addarchfile(char * name,int perm,Rdwrfn * rdfn,Rdwrfn * wrfn)378e32b400SDavid du Colombier addarchfile(char *name, int perm, Rdwrfn *rdfn, Rdwrfn *wrfn)
388e32b400SDavid du Colombier {
398e32b400SDavid du Colombier int i;
408e32b400SDavid du Colombier Dirtab d;
418e32b400SDavid du Colombier Dirtab *dp;
428e32b400SDavid du Colombier
438e32b400SDavid du Colombier memset(&d, 0, sizeof d);
448e32b400SDavid du Colombier strcpy(d.name, name);
458e32b400SDavid du Colombier d.perm = perm;
468e32b400SDavid du Colombier
478e32b400SDavid du Colombier lock(&archwlock);
488e32b400SDavid du Colombier if(narchdir >= Qmax){
498e32b400SDavid du Colombier unlock(&archwlock);
508e32b400SDavid du Colombier return nil;
518e32b400SDavid du Colombier }
528e32b400SDavid du Colombier
538e32b400SDavid du Colombier for(i=0; i<narchdir; i++)
548e32b400SDavid du Colombier if(strcmp(archdir[i].name, name) == 0){
558e32b400SDavid du Colombier unlock(&archwlock);
568e32b400SDavid du Colombier return nil;
578e32b400SDavid du Colombier }
588e32b400SDavid du Colombier
598e32b400SDavid du Colombier d.qid.path = narchdir;
608e32b400SDavid du Colombier archdir[narchdir] = d;
618e32b400SDavid du Colombier readfn[narchdir] = rdfn;
628e32b400SDavid du Colombier writefn[narchdir] = wrfn;
638e32b400SDavid du Colombier dp = &archdir[narchdir++];
648e32b400SDavid du Colombier unlock(&archwlock);
658e32b400SDavid du Colombier
668e32b400SDavid du Colombier return dp;
678e32b400SDavid du Colombier }
688e32b400SDavid du Colombier
698e32b400SDavid du Colombier static Chan*
archattach(char * spec)708e32b400SDavid du Colombier archattach(char* spec)
718e32b400SDavid du Colombier {
728e32b400SDavid du Colombier return devattach('P', spec);
738e32b400SDavid du Colombier }
748e32b400SDavid du Colombier
758e32b400SDavid du Colombier Walkqid*
archwalk(Chan * c,Chan * nc,char ** name,int nname)768e32b400SDavid du Colombier archwalk(Chan* c, Chan *nc, char** name, int nname)
778e32b400SDavid du Colombier {
788e32b400SDavid du Colombier return devwalk(c, nc, name, nname, archdir, narchdir, devgen);
798e32b400SDavid du Colombier }
808e32b400SDavid du Colombier
818e32b400SDavid du Colombier static int
archstat(Chan * c,uchar * dp,int n)828e32b400SDavid du Colombier archstat(Chan* c, uchar* dp, int n)
838e32b400SDavid du Colombier {
848e32b400SDavid du Colombier return devstat(c, dp, n, archdir, narchdir, devgen);
858e32b400SDavid du Colombier }
868e32b400SDavid du Colombier
878e32b400SDavid du Colombier static Chan*
archopen(Chan * c,int omode)888e32b400SDavid du Colombier archopen(Chan* c, int omode)
898e32b400SDavid du Colombier {
908e32b400SDavid du Colombier return devopen(c, omode, archdir, narchdir, devgen);
918e32b400SDavid du Colombier }
928e32b400SDavid du Colombier
938e32b400SDavid du Colombier static void
archclose(Chan *)948e32b400SDavid du Colombier archclose(Chan*)
958e32b400SDavid du Colombier {
968e32b400SDavid du Colombier }
978e32b400SDavid du Colombier
988e32b400SDavid du Colombier static long
archread(Chan * c,void * a,long n,vlong offset)998e32b400SDavid du Colombier archread(Chan *c, void *a, long n, vlong offset)
1008e32b400SDavid du Colombier {
1018e32b400SDavid du Colombier Rdwrfn *fn;
1028e32b400SDavid du Colombier
1038e32b400SDavid du Colombier switch((ulong)c->qid.path){
1048e32b400SDavid du Colombier case Qdir:
1058e32b400SDavid du Colombier return devdirread(c, a, n, archdir, narchdir, devgen);
1068e32b400SDavid du Colombier
1078e32b400SDavid du Colombier default:
1088e32b400SDavid du Colombier if(c->qid.path < narchdir && (fn = readfn[c->qid.path]))
1098e32b400SDavid du Colombier return fn(c, a, n, offset);
1108e32b400SDavid du Colombier error(Eperm);
1118e32b400SDavid du Colombier break;
1128e32b400SDavid du Colombier }
1138e32b400SDavid du Colombier
1148e32b400SDavid du Colombier return 0;
1158e32b400SDavid du Colombier }
1168e32b400SDavid du Colombier
1178e32b400SDavid du Colombier static long
archwrite(Chan * c,void * a,long n,vlong offset)1188e32b400SDavid du Colombier archwrite(Chan *c, void *a, long n, vlong offset)
1198e32b400SDavid du Colombier {
1208e32b400SDavid du Colombier Rdwrfn *fn;
1218e32b400SDavid du Colombier
1228e32b400SDavid du Colombier if(c->qid.path < narchdir && (fn = writefn[c->qid.path]))
1238e32b400SDavid du Colombier return fn(c, a, n, offset);
1248e32b400SDavid du Colombier error(Eperm);
1258e32b400SDavid du Colombier
1268e32b400SDavid du Colombier return 0;
1278e32b400SDavid du Colombier }
1288e32b400SDavid du Colombier
1298e32b400SDavid du Colombier void archinit(void);
1308e32b400SDavid du Colombier
1318e32b400SDavid du Colombier Dev archdevtab = {
1328e32b400SDavid du Colombier 'P',
1338e32b400SDavid du Colombier "arch",
1348e32b400SDavid du Colombier
1358e32b400SDavid du Colombier devreset,
1368e32b400SDavid du Colombier archinit,
1378e32b400SDavid du Colombier devshutdown,
1388e32b400SDavid du Colombier archattach,
1398e32b400SDavid du Colombier archwalk,
1408e32b400SDavid du Colombier archstat,
1418e32b400SDavid du Colombier archopen,
1428e32b400SDavid du Colombier devcreate,
1438e32b400SDavid du Colombier archclose,
1448e32b400SDavid du Colombier archread,
1458e32b400SDavid du Colombier devbread,
1468e32b400SDavid du Colombier archwrite,
1478e32b400SDavid du Colombier devbwrite,
1488e32b400SDavid du Colombier devremove,
1498e32b400SDavid du Colombier devwstat,
1508e32b400SDavid du Colombier };
1518e32b400SDavid du Colombier
1528e32b400SDavid du Colombier /* convert AddrDevid register to a string in buf and return buf */
1538e32b400SDavid du Colombier char *
cputype2name(char * buf,int size)1548e32b400SDavid du Colombier cputype2name(char *buf, int size)
1558e32b400SDavid du Colombier {
1568e32b400SDavid du Colombier seprint(buf, buf + size, "Cortex-A8");
1578e32b400SDavid du Colombier return buf;
1588e32b400SDavid du Colombier }
1598e32b400SDavid du Colombier
1608e32b400SDavid du Colombier static long
cputyperead(Chan *,void * a,long n,vlong offset)1618e32b400SDavid du Colombier cputyperead(Chan*, void *a, long n, vlong offset)
1628e32b400SDavid du Colombier {
1638e32b400SDavid du Colombier char name[64], str[128];
1648e32b400SDavid du Colombier
1658e32b400SDavid du Colombier cputype2name(name, sizeof name);
166*df2dbabfSDavid du Colombier snprint(str, sizeof str, "ARM %s %llud\n", name, m->cpuhz / Mhz);
1678e32b400SDavid du Colombier return readstr(offset, a, n, str);
1688e32b400SDavid du Colombier }
1698e32b400SDavid du Colombier
1708e32b400SDavid du Colombier static long
tbread(Chan *,void * a,long n,vlong offset)1718e32b400SDavid du Colombier tbread(Chan*, void *a, long n, vlong offset)
1728e32b400SDavid du Colombier {
1738e32b400SDavid du Colombier char str[16];
1748e32b400SDavid du Colombier uvlong tb;
1758e32b400SDavid du Colombier
1768e32b400SDavid du Colombier cycles(&tb);
1778e32b400SDavid du Colombier
1788e32b400SDavid du Colombier snprint(str, sizeof(str), "%16.16llux", tb);
1798e32b400SDavid du Colombier return readstr(offset, a, n, str);
1808e32b400SDavid du Colombier }
1818e32b400SDavid du Colombier
1828e32b400SDavid du Colombier static long
nsread(Chan *,void * a,long n,vlong offset)1838e32b400SDavid du Colombier nsread(Chan*, void *a, long n, vlong offset)
1848e32b400SDavid du Colombier {
1858e32b400SDavid du Colombier char str[16];
1868e32b400SDavid du Colombier uvlong tb;
1878e32b400SDavid du Colombier
1888e32b400SDavid du Colombier cycles(&tb);
1898e32b400SDavid du Colombier
1908e32b400SDavid du Colombier snprint(str, sizeof(str), "%16.16llux", (tb/700)* 1000);
1918e32b400SDavid du Colombier return readstr(offset, a, n, str);
1928e32b400SDavid du Colombier }
1938e32b400SDavid du Colombier
1948e32b400SDavid du Colombier void
archinit(void)1958e32b400SDavid du Colombier archinit(void)
1968e32b400SDavid du Colombier {
1978e32b400SDavid du Colombier addarchfile("cputype", 0444, cputyperead, nil);
1988e32b400SDavid du Colombier addarchfile("timebase",0444, tbread, nil);
1998e32b400SDavid du Colombier // addarchfile("nsec", 0444, nsread, nil);
2008e32b400SDavid du Colombier }
201