xref: /plan9/sys/src/9/kw/devarch.c (revision 7365b686ae7154552580a79fd89a0ba5dc9297c4)
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 #include "../ip/ip.h"
10 
11 enum {
12 	Qdir = 0,
13 	Qbase,
14 
15 	Qmax = 16,
16 };
17 
18 typedef long Rdwrfn(Chan*, void*, long, vlong);
19 
20 static Rdwrfn *readfn[Qmax];
21 static Rdwrfn *writefn[Qmax];
22 
23 static Dirtab archdir[Qmax] = {
24 	".",		{ Qdir, 0, QTDIR },	0,	0555,
25 };
26 
27 Lock archwlock;	/* the lock is only for changing archdir */
28 int narchdir = Qbase;
29 
30 /*
31  * Add a file to the #P listing.  Once added, you can't delete it.
32  * You can't add a file with the same name as one already there,
33  * and you get a pointer to the Dirtab entry so you can do things
34  * like change the Qid version.  Changing the Qid path is disallowed.
35  */
36 Dirtab*
addarchfile(char * name,int perm,Rdwrfn * rdfn,Rdwrfn * wrfn)37 addarchfile(char *name, int perm, Rdwrfn *rdfn, Rdwrfn *wrfn)
38 {
39 	int i;
40 	Dirtab d;
41 	Dirtab *dp;
42 
43 	memset(&d, 0, sizeof d);
44 	strcpy(d.name, name);
45 	d.perm = perm;
46 
47 	lock(&archwlock);
48 	if(narchdir >= Qmax){
49 		unlock(&archwlock);
50 		return nil;
51 	}
52 
53 	for(i=0; i<narchdir; i++)
54 		if(strcmp(archdir[i].name, name) == 0){
55 			unlock(&archwlock);
56 			return nil;
57 		}
58 
59 	d.qid.path = narchdir;
60 	archdir[narchdir] = d;
61 	readfn[narchdir] = rdfn;
62 	writefn[narchdir] = wrfn;
63 	dp = &archdir[narchdir++];
64 	unlock(&archwlock);
65 
66 	return dp;
67 }
68 
69 static Chan*
archattach(char * spec)70 archattach(char* spec)
71 {
72 	return devattach('P', spec);
73 }
74 
75 Walkqid*
archwalk(Chan * c,Chan * nc,char ** name,int nname)76 archwalk(Chan* c, Chan *nc, char** name, int nname)
77 {
78 	return devwalk(c, nc, name, nname, archdir, narchdir, devgen);
79 }
80 
81 static int
archstat(Chan * c,uchar * dp,int n)82 archstat(Chan* c, uchar* dp, int n)
83 {
84 	return devstat(c, dp, n, archdir, narchdir, devgen);
85 }
86 
87 static Chan*
archopen(Chan * c,int omode)88 archopen(Chan* c, int omode)
89 {
90 	return devopen(c, omode, archdir, narchdir, devgen);
91 }
92 
93 static void
archclose(Chan *)94 archclose(Chan*)
95 {
96 }
97 
98 static long
archread(Chan * c,void * a,long n,vlong offset)99 archread(Chan *c, void *a, long n, vlong offset)
100 {
101 	Rdwrfn *fn;
102 
103 	switch((ulong)c->qid.path){
104 	case Qdir:
105 		return devdirread(c, a, n, archdir, narchdir, devgen);
106 
107 	default:
108 		if(c->qid.path < narchdir && (fn = readfn[c->qid.path]))
109 			return fn(c, a, n, offset);
110 		error(Eperm);
111 		break;
112 	}
113 
114 	return 0;
115 }
116 
117 static long
archwrite(Chan * c,void * a,long n,vlong offset)118 archwrite(Chan *c, void *a, long n, vlong offset)
119 {
120 	Rdwrfn *fn;
121 
122 	if(c->qid.path < narchdir && (fn = writefn[c->qid.path]))
123 		return fn(c, a, n, offset);
124 	error(Eperm);
125 
126 	return 0;
127 }
128 
129 void archinit(void);
130 
131 Dev archdevtab = {
132 	'P',
133 	"arch",
134 
135 	devreset,
136 	archinit,
137 	devshutdown,
138 	archattach,
139 	archwalk,
140 	archstat,
141 	archopen,
142 	devcreate,
143 	archclose,
144 	archread,
145 	devbread,
146 	archwrite,
147 	devbwrite,
148 	devremove,
149 	devwstat,
150 };
151 
152 /* convert AddrDevid register to a string in buf and return buf */
153 char *
cputype2name(char * buf,int size)154 cputype2name(char *buf, int size)
155 {
156 	ulong id, archid, rev;
157 	char *manu, *arch, *socrev;
158 	char unk[32], socnm[32], revname[32];
159 	Pciex *pci;
160 
161 	m->cputype = *(ulong *)soc.devid;
162 #ifdef OLD
163 	switch(m->cputype & 3) {
164 	case 0:
165 		socnm = "88F6[12]80";
166 		break;
167 	case 1:
168 		socnm = "88F619[02]";
169 		break;
170 	case 2:
171 		socnm = "88F6281";
172 		break;
173 	default:
174 		socnm = "unknown";
175 		break;
176 	}
177 #endif
178 	/* strange way to get this information, but it's what u-boot does */
179 	pci = (Pciex *)soc.pci;
180 	snprint(socnm, sizeof socnm, "88F%ux", pci->devid);
181 	/* stash rev for benefit of later usb initialisation */
182 	m->socrev = rev = pci->revid & MASK(4);
183 
184 	id = cpidget();
185 	if ((id >> 24) == 0x56 && pci->venid == 0x11ab)
186 		manu = "Marvell";
187 	else
188 		manu = "unknown";
189 	archid = (id >> 16) & MASK(4);
190 	switch (archid) {
191 	case 5:
192 		arch = "v5te";
193 		break;
194 	default:
195 		snprint(unk, sizeof unk, "unknown (%ld)", archid);
196 		arch = unk;
197 		break;
198 	}
199 	if (pci->devid != 0x6281)
200 		socrev = "unknown";
201 	else
202 		switch (rev) {
203 		case Socrevz0:
204 			socrev = "Z0";
205 			break;
206 		case Socreva0:
207 			socrev = "A0";
208 			break;
209 		case Socreva1:
210 			socrev = "A1";
211 			break;
212 		default:
213 			snprint(revname, sizeof revname, "unknown rev (%ld)",
214 				rev);
215 			socrev = revname;
216 			break;
217 		}
218 	seprint(buf, buf + size,
219 		"%s %s %s; arm926ej-s arch %s rev %ld.%ld part %lux",
220 		manu, socnm, socrev, arch, (id >> 20) & MASK(4),
221 		id & MASK(4), (id >> 4) & MASK(12));
222 	return buf;
223 }
224 
225 static long
cputyperead(Chan *,void * a,long n,vlong offset)226 cputyperead(Chan*, void *a, long n, vlong offset)
227 {
228 	char name[64], str[128];
229 
230 	cputype2name(name, sizeof name);
231 	snprint(str, sizeof str, "ARM %s %llud\n", name, m->cpuhz / 1000000);
232 	return readstr(offset, a, n, str);
233 }
234 
235 static long
tbread(Chan *,void * a,long n,vlong offset)236 tbread(Chan*, void *a, long n, vlong offset)
237 {
238 	char str[16];
239 	uvlong tb;
240 
241 	cycles(&tb);
242 
243 	snprint(str, sizeof(str), "%16.16llux", tb);
244 	return readstr(offset, a, n, str);
245 }
246 
247 static long
nsread(Chan *,void * a,long n,vlong offset)248 nsread(Chan*, void *a, long n, vlong offset)
249 {
250 	char str[16];
251 	uvlong tb;
252 
253 	cycles(&tb);
254 
255 	snprint(str, sizeof(str), "%16.16llux", (tb/700)* 1000);
256 	return readstr(offset, a, n, str);
257 }
258 
259 void
archinit(void)260 archinit(void)
261 {
262 	addarchfile("cputype", 0444, cputyperead, nil);
263 	addarchfile("timebase",0444, tbread, nil);
264 //	addarchfile("nsec", 0444, nsread, nil);
265 }
266