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