xref: /plan9-contrib/sys/src/9/omap/devarch.c (revision b39189fd423aed869c5cf5189bc504918cff969b)
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 #ifdef TODO		/* identify the flavour of omap3530 SoC & cpu */
157 	char *soc;
158 
159 	m->cputype = *(ulong *)AddrDevid;
160 	switch(m->cputype & 3) {
161 	case 0:
162 //		soc = "88F6180";
163 		break;
164 	case 1:
165 //		soc = "88F619[02]";
166 		break;
167 	case 2:
168 //		soc = "88F6281";
169 		break;
170 	default:
171 		soc = "unknown";
172 		break;
173 	}
174 #endif
175 	seprint(buf, buf + size, "Cortex-A8");
176 	return buf;
177 }
178 
179 static long
180 cputyperead(Chan*, void *a, long n, vlong offset)
181 {
182 	char name[64], str[128];
183 
184 	cputype2name(name, sizeof name);
185 	snprint(str, sizeof str, "ARM %s %llud\n", name,
186 		m->cpuhz / (1000*1000));
187 	return readstr(offset, a, n, str);
188 }
189 
190 static long
191 tbread(Chan*, void *a, long n, vlong offset)
192 {
193 	char str[16];
194 	uvlong tb;
195 
196 	cycles(&tb);
197 
198 	snprint(str, sizeof(str), "%16.16llux", tb);
199 	return readstr(offset, a, n, str);
200 }
201 
202 static long
203 nsread(Chan*, void *a, long n, vlong offset)
204 {
205 	char str[16];
206 	uvlong tb;
207 
208 	cycles(&tb);
209 
210 	snprint(str, sizeof(str), "%16.16llux", (tb/700)* 1000);
211 	return readstr(offset, a, n, str);
212 }
213 
214 void
215 archinit(void)
216 {
217 	addarchfile("cputype", 0444, cputyperead, nil);
218 	addarchfile("timebase",0444, tbread, nil);
219 //	addarchfile("nsec", 0444, nsread, nil);
220 }
221