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