xref: /plan9/sys/src/9/omap/devarch.c (revision add6b5c507a81def2a34db772d748c24f818bb5b)
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 	seprint(buf, buf + size, "Cortex-A8");
157 	return buf;
158 }
159 
160 static long
cputyperead(Chan *,void * a,long n,vlong offset)161 cputyperead(Chan*, void *a, long n, vlong offset)
162 {
163 	char name[64], str[128];
164 
165 	cputype2name(name, sizeof name);
166 	snprint(str, sizeof str, "ARM %s %llud\n", name, m->cpuhz / Mhz);
167 	return readstr(offset, a, n, str);
168 }
169 
170 static long
tbread(Chan *,void * a,long n,vlong offset)171 tbread(Chan*, void *a, long n, vlong offset)
172 {
173 	char str[16];
174 	uvlong tb;
175 
176 	cycles(&tb);
177 
178 	snprint(str, sizeof(str), "%16.16llux", tb);
179 	return readstr(offset, a, n, str);
180 }
181 
182 static long
nsread(Chan *,void * a,long n,vlong offset)183 nsread(Chan*, void *a, long n, vlong offset)
184 {
185 	char str[16];
186 	uvlong tb;
187 
188 	cycles(&tb);
189 
190 	snprint(str, sizeof(str), "%16.16llux", (tb/700)* 1000);
191 	return readstr(offset, a, n, str);
192 }
193 
194 void
archinit(void)195 archinit(void)
196 {
197 	addarchfile("cputype", 0444, cputyperead, nil);
198 	addarchfile("timebase",0444, tbread, nil);
199 //	addarchfile("nsec", 0444, nsread, nil);
200 }
201