]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/kw/devarch.c
io.h: fis comment PciSID (alphapc, kw, mtx, teg2) (thanks qeed!)
[plan9front.git] / sys / src / 9 / kw / devarch.c
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*
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*
70 archattach(char* spec)
71 {
72         return devattach('P', spec);
73 }
74
75 Walkqid*
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
82 archstat(Chan* c, uchar* dp, int n)
83 {
84         return devstat(c, dp, n, archdir, narchdir, devgen);
85 }
86
87 static Chan*
88 archopen(Chan* c, int omode)
89 {
90         return devopen(c, omode, archdir, narchdir, devgen);
91 }
92
93 static void
94 archclose(Chan*)
95 {
96 }
97
98 static long
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
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 *
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
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
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
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
260 archinit(void)
261 {
262         addarchfile("cputype", 0444, cputyperead, nil);
263         addarchfile("timebase",0444, tbread, nil);
264 //      addarchfile("nsec", 0444, nsread, nil);
265 }