1154abd99SDavid du Colombier #include "u.h"
2154abd99SDavid du Colombier #include "../port/lib.h"
3154abd99SDavid du Colombier #include "mem.h"
4154abd99SDavid du Colombier #include "dat.h"
5154abd99SDavid du Colombier #include "fns.h"
6154abd99SDavid du Colombier #include "../port/error.h"
7154abd99SDavid du Colombier #include "io.h"
8154abd99SDavid du Colombier
9154abd99SDavid du Colombier #include "../ip/ip.h"
10154abd99SDavid du Colombier
11154abd99SDavid du Colombier enum {
12154abd99SDavid du Colombier Qdir = 0,
13154abd99SDavid du Colombier Qbase,
14154abd99SDavid du Colombier
15154abd99SDavid du Colombier Qmax = 16,
16154abd99SDavid du Colombier };
17154abd99SDavid du Colombier
18154abd99SDavid du Colombier typedef long Rdwrfn(Chan*, void*, long, vlong);
19154abd99SDavid du Colombier
20154abd99SDavid du Colombier static Rdwrfn *readfn[Qmax];
21154abd99SDavid du Colombier static Rdwrfn *writefn[Qmax];
22154abd99SDavid du Colombier
23154abd99SDavid du Colombier static Dirtab archdir[Qmax] = {
24154abd99SDavid du Colombier ".", { Qdir, 0, QTDIR }, 0, 0555,
25154abd99SDavid du Colombier };
26154abd99SDavid du Colombier
27154abd99SDavid du Colombier Lock archwlock; /* the lock is only for changing archdir */
28154abd99SDavid du Colombier int narchdir = Qbase;
29154abd99SDavid du Colombier
30154abd99SDavid du Colombier /*
31154abd99SDavid du Colombier * Add a file to the #P listing. Once added, you can't delete it.
32154abd99SDavid du Colombier * You can't add a file with the same name as one already there,
33154abd99SDavid du Colombier * and you get a pointer to the Dirtab entry so you can do things
34154abd99SDavid du Colombier * like change the Qid version. Changing the Qid path is disallowed.
35154abd99SDavid du Colombier */
36154abd99SDavid du Colombier Dirtab*
addarchfile(char * name,int perm,Rdwrfn * rdfn,Rdwrfn * wrfn)37154abd99SDavid du Colombier addarchfile(char *name, int perm, Rdwrfn *rdfn, Rdwrfn *wrfn)
38154abd99SDavid du Colombier {
39154abd99SDavid du Colombier int i;
40154abd99SDavid du Colombier Dirtab d;
41154abd99SDavid du Colombier Dirtab *dp;
42154abd99SDavid du Colombier
43154abd99SDavid du Colombier memset(&d, 0, sizeof d);
44154abd99SDavid du Colombier strcpy(d.name, name);
45154abd99SDavid du Colombier d.perm = perm;
46154abd99SDavid du Colombier
47154abd99SDavid du Colombier lock(&archwlock);
48154abd99SDavid du Colombier if(narchdir >= Qmax){
49154abd99SDavid du Colombier unlock(&archwlock);
50154abd99SDavid du Colombier return nil;
51154abd99SDavid du Colombier }
52154abd99SDavid du Colombier
53154abd99SDavid du Colombier for(i=0; i<narchdir; i++)
54154abd99SDavid du Colombier if(strcmp(archdir[i].name, name) == 0){
55154abd99SDavid du Colombier unlock(&archwlock);
56154abd99SDavid du Colombier return nil;
57154abd99SDavid du Colombier }
58154abd99SDavid du Colombier
59154abd99SDavid du Colombier d.qid.path = narchdir;
60154abd99SDavid du Colombier archdir[narchdir] = d;
61154abd99SDavid du Colombier readfn[narchdir] = rdfn;
62154abd99SDavid du Colombier writefn[narchdir] = wrfn;
63154abd99SDavid du Colombier dp = &archdir[narchdir++];
64154abd99SDavid du Colombier unlock(&archwlock);
65154abd99SDavid du Colombier
66154abd99SDavid du Colombier return dp;
67154abd99SDavid du Colombier }
68154abd99SDavid du Colombier
69154abd99SDavid du Colombier static Chan*
archattach(char * spec)70154abd99SDavid du Colombier archattach(char* spec)
71154abd99SDavid du Colombier {
72154abd99SDavid du Colombier return devattach('P', spec);
73154abd99SDavid du Colombier }
74154abd99SDavid du Colombier
75154abd99SDavid du Colombier Walkqid*
archwalk(Chan * c,Chan * nc,char ** name,int nname)76154abd99SDavid du Colombier archwalk(Chan* c, Chan *nc, char** name, int nname)
77154abd99SDavid du Colombier {
78154abd99SDavid du Colombier return devwalk(c, nc, name, nname, archdir, narchdir, devgen);
79154abd99SDavid du Colombier }
80154abd99SDavid du Colombier
81154abd99SDavid du Colombier static int
archstat(Chan * c,uchar * dp,int n)82154abd99SDavid du Colombier archstat(Chan* c, uchar* dp, int n)
83154abd99SDavid du Colombier {
84154abd99SDavid du Colombier return devstat(c, dp, n, archdir, narchdir, devgen);
85154abd99SDavid du Colombier }
86154abd99SDavid du Colombier
87154abd99SDavid du Colombier static Chan*
archopen(Chan * c,int omode)88154abd99SDavid du Colombier archopen(Chan* c, int omode)
89154abd99SDavid du Colombier {
90154abd99SDavid du Colombier return devopen(c, omode, archdir, narchdir, devgen);
91154abd99SDavid du Colombier }
92154abd99SDavid du Colombier
93154abd99SDavid du Colombier static void
archclose(Chan *)94154abd99SDavid du Colombier archclose(Chan*)
95154abd99SDavid du Colombier {
96154abd99SDavid du Colombier }
97154abd99SDavid du Colombier
98154abd99SDavid du Colombier static long
archread(Chan * c,void * a,long n,vlong offset)99154abd99SDavid du Colombier archread(Chan *c, void *a, long n, vlong offset)
100154abd99SDavid du Colombier {
101154abd99SDavid du Colombier Rdwrfn *fn;
102154abd99SDavid du Colombier
103154abd99SDavid du Colombier switch((ulong)c->qid.path){
104154abd99SDavid du Colombier case Qdir:
105154abd99SDavid du Colombier return devdirread(c, a, n, archdir, narchdir, devgen);
106154abd99SDavid du Colombier
107154abd99SDavid du Colombier default:
108154abd99SDavid du Colombier if(c->qid.path < narchdir && (fn = readfn[c->qid.path]))
109154abd99SDavid du Colombier return fn(c, a, n, offset);
110154abd99SDavid du Colombier error(Eperm);
111154abd99SDavid du Colombier break;
112154abd99SDavid du Colombier }
113154abd99SDavid du Colombier
114154abd99SDavid du Colombier return 0;
115154abd99SDavid du Colombier }
116154abd99SDavid du Colombier
117154abd99SDavid du Colombier static long
archwrite(Chan * c,void * a,long n,vlong offset)118154abd99SDavid du Colombier archwrite(Chan *c, void *a, long n, vlong offset)
119154abd99SDavid du Colombier {
120154abd99SDavid du Colombier Rdwrfn *fn;
121154abd99SDavid du Colombier
122154abd99SDavid du Colombier if(c->qid.path < narchdir && (fn = writefn[c->qid.path]))
123154abd99SDavid du Colombier return fn(c, a, n, offset);
124154abd99SDavid du Colombier error(Eperm);
125154abd99SDavid du Colombier
126154abd99SDavid du Colombier return 0;
127154abd99SDavid du Colombier }
128154abd99SDavid du Colombier
129154abd99SDavid du Colombier void archinit(void);
130154abd99SDavid du Colombier
131154abd99SDavid du Colombier Dev archdevtab = {
132154abd99SDavid du Colombier 'P',
133154abd99SDavid du Colombier "arch",
134154abd99SDavid du Colombier
135154abd99SDavid du Colombier devreset,
136154abd99SDavid du Colombier archinit,
137154abd99SDavid du Colombier devshutdown,
138154abd99SDavid du Colombier archattach,
139154abd99SDavid du Colombier archwalk,
140154abd99SDavid du Colombier archstat,
141154abd99SDavid du Colombier archopen,
142154abd99SDavid du Colombier devcreate,
143154abd99SDavid du Colombier archclose,
144154abd99SDavid du Colombier archread,
145154abd99SDavid du Colombier devbread,
146154abd99SDavid du Colombier archwrite,
147154abd99SDavid du Colombier devbwrite,
148154abd99SDavid du Colombier devremove,
149154abd99SDavid du Colombier devwstat,
150154abd99SDavid du Colombier };
151154abd99SDavid du Colombier
152154abd99SDavid du Colombier /* convert AddrDevid register to a string in buf and return buf */
153154abd99SDavid du Colombier char *
cputype2name(char * buf,int size)154154abd99SDavid du Colombier cputype2name(char *buf, int size)
155154abd99SDavid du Colombier {
156ec4ca6beSDavid du Colombier ulong id, archid, rev;
157ec4ca6beSDavid du Colombier char *manu, *arch, *socrev;
158*7365b686SDavid du Colombier char unk[32], socnm[32], revname[32];
159ec4ca6beSDavid du Colombier Pciex *pci;
160154abd99SDavid du Colombier
161*7365b686SDavid du Colombier m->cputype = *(ulong *)soc.devid;
162ec4ca6beSDavid du Colombier #ifdef OLD
163154abd99SDavid du Colombier switch(m->cputype & 3) {
164154abd99SDavid du Colombier case 0:
165*7365b686SDavid du Colombier socnm = "88F6[12]80";
166154abd99SDavid du Colombier break;
167154abd99SDavid du Colombier case 1:
168*7365b686SDavid du Colombier socnm = "88F619[02]";
169154abd99SDavid du Colombier break;
170154abd99SDavid du Colombier case 2:
171*7365b686SDavid du Colombier socnm = "88F6281";
172154abd99SDavid du Colombier break;
173154abd99SDavid du Colombier default:
174*7365b686SDavid du Colombier socnm = "unknown";
175154abd99SDavid du Colombier break;
176154abd99SDavid du Colombier }
177ec4ca6beSDavid du Colombier #endif
178ec4ca6beSDavid du Colombier /* strange way to get this information, but it's what u-boot does */
179*7365b686SDavid du Colombier pci = (Pciex *)soc.pci;
180*7365b686SDavid du Colombier snprint(socnm, sizeof socnm, "88F%ux", pci->devid);
181a7a38e3eSDavid du Colombier /* stash rev for benefit of later usb initialisation */
182ab6ce076SDavid du Colombier m->socrev = rev = pci->revid & MASK(4);
183ec4ca6beSDavid du Colombier
184ec4ca6beSDavid du Colombier id = cpidget();
185ec4ca6beSDavid du Colombier if ((id >> 24) == 0x56 && pci->venid == 0x11ab)
186ec4ca6beSDavid du Colombier manu = "Marvell";
187ec4ca6beSDavid du Colombier else
188ec4ca6beSDavid du Colombier manu = "unknown";
189ab6ce076SDavid du Colombier archid = (id >> 16) & MASK(4);
190ec4ca6beSDavid du Colombier switch (archid) {
191ec4ca6beSDavid du Colombier case 5:
192ec4ca6beSDavid du Colombier arch = "v5te";
193ec4ca6beSDavid du Colombier break;
194ec4ca6beSDavid du Colombier default:
195ec4ca6beSDavid du Colombier snprint(unk, sizeof unk, "unknown (%ld)", archid);
196ec4ca6beSDavid du Colombier arch = unk;
197ec4ca6beSDavid du Colombier break;
198ec4ca6beSDavid du Colombier }
199ab6ce076SDavid du Colombier if (pci->devid != 0x6281)
200ab6ce076SDavid du Colombier socrev = "unknown";
201ab6ce076SDavid du Colombier else
202ec4ca6beSDavid du Colombier switch (rev) {
203897ae9c1SDavid du Colombier case Socrevz0:
204ab6ce076SDavid du Colombier socrev = "Z0";
205ab6ce076SDavid du Colombier break;
206897ae9c1SDavid du Colombier case Socreva0:
207ec4ca6beSDavid du Colombier socrev = "A0";
208ec4ca6beSDavid du Colombier break;
209897ae9c1SDavid du Colombier case Socreva1:
210ab6ce076SDavid du Colombier socrev = "A1";
211ec4ca6beSDavid du Colombier break;
212ec4ca6beSDavid du Colombier default:
213ab6ce076SDavid du Colombier snprint(revname, sizeof revname, "unknown rev (%ld)",
214ab6ce076SDavid du Colombier rev);
215ec4ca6beSDavid du Colombier socrev = revname;
216ec4ca6beSDavid du Colombier break;
217ec4ca6beSDavid du Colombier }
218ec4ca6beSDavid du Colombier seprint(buf, buf + size,
219ec4ca6beSDavid du Colombier "%s %s %s; arm926ej-s arch %s rev %ld.%ld part %lux",
220*7365b686SDavid du Colombier manu, socnm, socrev, arch, (id >> 20) & MASK(4),
221ab6ce076SDavid du Colombier id & MASK(4), (id >> 4) & MASK(12));
222154abd99SDavid du Colombier return buf;
223154abd99SDavid du Colombier }
224154abd99SDavid du Colombier
225154abd99SDavid du Colombier static long
cputyperead(Chan *,void * a,long n,vlong offset)226154abd99SDavid du Colombier cputyperead(Chan*, void *a, long n, vlong offset)
227154abd99SDavid du Colombier {
228154abd99SDavid du Colombier char name[64], str[128];
229154abd99SDavid du Colombier
230154abd99SDavid du Colombier cputype2name(name, sizeof name);
231154abd99SDavid du Colombier snprint(str, sizeof str, "ARM %s %llud\n", name, m->cpuhz / 1000000);
232154abd99SDavid du Colombier return readstr(offset, a, n, str);
233154abd99SDavid du Colombier }
234154abd99SDavid du Colombier
235154abd99SDavid du Colombier static long
tbread(Chan *,void * a,long n,vlong offset)236154abd99SDavid du Colombier tbread(Chan*, void *a, long n, vlong offset)
237154abd99SDavid du Colombier {
238154abd99SDavid du Colombier char str[16];
239154abd99SDavid du Colombier uvlong tb;
240154abd99SDavid du Colombier
241154abd99SDavid du Colombier cycles(&tb);
242154abd99SDavid du Colombier
243154abd99SDavid du Colombier snprint(str, sizeof(str), "%16.16llux", tb);
244154abd99SDavid du Colombier return readstr(offset, a, n, str);
245154abd99SDavid du Colombier }
246154abd99SDavid du Colombier
247154abd99SDavid du Colombier static long
nsread(Chan *,void * a,long n,vlong offset)248154abd99SDavid du Colombier nsread(Chan*, void *a, long n, vlong offset)
249154abd99SDavid du Colombier {
250154abd99SDavid du Colombier char str[16];
251154abd99SDavid du Colombier uvlong tb;
252154abd99SDavid du Colombier
253154abd99SDavid du Colombier cycles(&tb);
254154abd99SDavid du Colombier
255154abd99SDavid du Colombier snprint(str, sizeof(str), "%16.16llux", (tb/700)* 1000);
256154abd99SDavid du Colombier return readstr(offset, a, n, str);
257154abd99SDavid du Colombier }
258154abd99SDavid du Colombier
259154abd99SDavid du Colombier void
archinit(void)260154abd99SDavid du Colombier archinit(void)
261154abd99SDavid du Colombier {
262154abd99SDavid du Colombier addarchfile("cputype", 0444, cputyperead, nil);
263154abd99SDavid du Colombier addarchfile("timebase",0444, tbread, nil);
264154abd99SDavid du Colombier // addarchfile("nsec", 0444, nsread, nil);
265154abd99SDavid du Colombier }
266