devarch.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  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. #include "../ip/ip.h"
  9. enum {
  10. Qdir = 0,
  11. Qbase,
  12. Qmax = 16,
  13. };
  14. typedef long Rdwrfn(Chan*, void*, long, vlong);
  15. static Rdwrfn *readfn[Qmax];
  16. static Rdwrfn *writefn[Qmax];
  17. static Dirtab archdir[Qmax] = {
  18. ".", { Qdir, 0, QTDIR }, 0, 0555,
  19. };
  20. Lock archwlock; /* the lock is only for changing archdir */
  21. int narchdir = Qbase;
  22. /*
  23. * Add a file to the #P listing. Once added, you can't delete it.
  24. * You can't add a file with the same name as one already there,
  25. * and you get a pointer to the Dirtab entry so you can do things
  26. * like change the Qid version. Changing the Qid path is disallowed.
  27. */
  28. Dirtab*
  29. addarchfile(char *name, int perm, Rdwrfn *rdfn, Rdwrfn *wrfn)
  30. {
  31. int i;
  32. Dirtab d;
  33. Dirtab *dp;
  34. memset(&d, 0, sizeof d);
  35. strcpy(d.name, name);
  36. d.perm = perm;
  37. lock(&archwlock);
  38. if(narchdir >= Qmax){
  39. unlock(&archwlock);
  40. return nil;
  41. }
  42. for(i=0; i<narchdir; i++)
  43. if(strcmp(archdir[i].name, name) == 0){
  44. unlock(&archwlock);
  45. return nil;
  46. }
  47. d.qid.path = narchdir;
  48. archdir[narchdir] = d;
  49. readfn[narchdir] = rdfn;
  50. writefn[narchdir] = wrfn;
  51. dp = &archdir[narchdir++];
  52. unlock(&archwlock);
  53. return dp;
  54. }
  55. static Chan*
  56. archattach(char* spec)
  57. {
  58. return devattach('P', spec);
  59. }
  60. Walkqid*
  61. archwalk(Chan* c, Chan *nc, char** name, int nname)
  62. {
  63. return devwalk(c, nc, name, nname, archdir, narchdir, devgen);
  64. }
  65. static int
  66. archstat(Chan* c, uchar* dp, int n)
  67. {
  68. return devstat(c, dp, n, archdir, narchdir, devgen);
  69. }
  70. static Chan*
  71. archopen(Chan* c, int omode)
  72. {
  73. return devopen(c, omode, archdir, narchdir, devgen);
  74. }
  75. static void
  76. archclose(Chan*)
  77. {
  78. }
  79. static long
  80. archread(Chan *c, void *a, long n, vlong offset)
  81. {
  82. Rdwrfn *fn;
  83. switch((ulong)c->qid.path){
  84. case Qdir:
  85. return devdirread(c, a, n, archdir, narchdir, devgen);
  86. default:
  87. if(c->qid.path < narchdir && (fn = readfn[c->qid.path]))
  88. return fn(c, a, n, offset);
  89. error(Eperm);
  90. break;
  91. }
  92. return 0;
  93. }
  94. static long
  95. archwrite(Chan *c, void *a, long n, vlong offset)
  96. {
  97. Rdwrfn *fn;
  98. if(c->qid.path < narchdir && (fn = writefn[c->qid.path]))
  99. return fn(c, a, n, offset);
  100. error(Eperm);
  101. return 0;
  102. }
  103. void archinit(void);
  104. Dev archdevtab = {
  105. 'P',
  106. "arch",
  107. devreset,
  108. archinit,
  109. devshutdown,
  110. archattach,
  111. archwalk,
  112. archstat,
  113. archopen,
  114. devcreate,
  115. archclose,
  116. archread,
  117. devbread,
  118. archwrite,
  119. devbwrite,
  120. devremove,
  121. devwstat,
  122. };
  123. /* convert AddrDevid register to a string in buf and return buf */
  124. char *
  125. cputype2name(char *buf, int size)
  126. {
  127. ulong id, archid, rev;
  128. char *manu, *arch, *socrev;
  129. char unk[32], socnm[32], revname[32];
  130. Pciex *pci;
  131. m->cputype = *(ulong *)soc.devid;
  132. #ifdef OLD
  133. switch(m->cputype & 3) {
  134. case 0:
  135. socnm = "88F6[12]80";
  136. break;
  137. case 1:
  138. socnm = "88F619[02]";
  139. break;
  140. case 2:
  141. socnm = "88F6281";
  142. break;
  143. default:
  144. socnm = "unknown";
  145. break;
  146. }
  147. #endif
  148. /* strange way to get this information, but it's what u-boot does */
  149. pci = (Pciex *)soc.pci;
  150. snprint(socnm, sizeof socnm, "88F%ux", pci->devid);
  151. /* stash rev for benefit of later usb initialisation */
  152. m->socrev = rev = pci->revid & MASK(4);
  153. id = cpidget();
  154. if ((id >> 24) == 0x56 && pci->venid == 0x11ab)
  155. manu = "Marvell";
  156. else
  157. manu = "unknown";
  158. archid = (id >> 16) & MASK(4);
  159. switch (archid) {
  160. case 5:
  161. arch = "v5te";
  162. break;
  163. default:
  164. snprint(unk, sizeof unk, "unknown (%ld)", archid);
  165. arch = unk;
  166. break;
  167. }
  168. if (pci->devid != 0x6281)
  169. socrev = "unknown";
  170. else
  171. switch (rev) {
  172. case Socrevz0:
  173. socrev = "Z0";
  174. break;
  175. case Socreva0:
  176. socrev = "A0";
  177. break;
  178. case Socreva1:
  179. socrev = "A1";
  180. break;
  181. default:
  182. snprint(revname, sizeof revname, "unknown rev (%ld)",
  183. rev);
  184. socrev = revname;
  185. break;
  186. }
  187. seprint(buf, buf + size,
  188. "%s %s %s; arm926ej-s arch %s rev %ld.%ld part %lux",
  189. manu, socnm, socrev, arch, (id >> 20) & MASK(4),
  190. id & MASK(4), (id >> 4) & MASK(12));
  191. return buf;
  192. }
  193. static long
  194. cputyperead(Chan*, void *a, long n, vlong offset)
  195. {
  196. char name[64], str[128];
  197. cputype2name(name, sizeof name);
  198. snprint(str, sizeof str, "ARM %s %llud\n", name, m->cpuhz / 1000000);
  199. return readstr(offset, a, n, str);
  200. }
  201. static long
  202. tbread(Chan*, void *a, long n, vlong offset)
  203. {
  204. char str[16];
  205. uvlong tb;
  206. cycles(&tb);
  207. snprint(str, sizeof(str), "%16.16llux", tb);
  208. return readstr(offset, a, n, str);
  209. }
  210. static long
  211. nsread(Chan*, void *a, long n, vlong offset)
  212. {
  213. char str[16];
  214. uvlong tb;
  215. cycles(&tb);
  216. snprint(str, sizeof(str), "%16.16llux", (tb/700)* 1000);
  217. return readstr(offset, a, n, str);
  218. }
  219. void
  220. archinit(void)
  221. {
  222. addarchfile("cputype", 0444, cputyperead, nil);
  223. addarchfile("timebase",0444, tbread, nil);
  224. // addarchfile("nsec", 0444, nsread, nil);
  225. }