devarch.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  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. static long
  124. cputyperead(Chan*, void *a, long n, vlong offset)
  125. {
  126. char str[128];
  127. snprint(str, sizeof str, "MIPS 24k %lud\n", m->hz / Mhz);
  128. return readstr(offset, a, n, str);
  129. }
  130. static long
  131. tbread(Chan*, void *a, long n, vlong offset)
  132. {
  133. char str[16];
  134. uvlong tb;
  135. cycles(&tb);
  136. snprint(str, sizeof(str), "%16.16llux", tb);
  137. return readstr(offset, a, n, str);
  138. }
  139. static long
  140. nsread(Chan*, void *a, long n, vlong offset)
  141. {
  142. char str[16];
  143. uvlong tb;
  144. cycles(&tb);
  145. snprint(str, sizeof(str), "%16.16llux", (tb/700)* 1000);
  146. return readstr(offset, a, n, str);
  147. }
  148. char *cputype = "mips";
  149. char *faultsprint(char *, char *);
  150. char *fpemuprint(char *, char *);
  151. static long
  152. archctlread(Chan*, void *a, long nn, vlong offset)
  153. {
  154. int n;
  155. char *buf, *p, *ep;
  156. p = buf = malloc(READSTR);
  157. if(p == nil)
  158. error(Enomem);
  159. ep = p + READSTR;
  160. p = seprint(p, ep, "cpu %s %lud\n", cputype,
  161. (ulong)(m->hz+999999)/1000000);
  162. p = seprint(p, ep, "stlb hash collisions");
  163. for (n = 0; n < conf.nmach; n++)
  164. p = seprint(p, ep, " %d", MACHP(n)->hashcoll);
  165. p = seprint(p, ep, "\n");
  166. p = seprint(p, ep, "NKTLB %d ktlb misses %ld utlb misses %ld\n",
  167. NKTLB, m->ktlbfault, m->utlbfault);
  168. p = fpemuprint(p, ep);
  169. faultsprint(p, ep);
  170. n = readstr(offset, a, nn, buf);
  171. free(buf);
  172. return n;
  173. }
  174. enum
  175. {
  176. CMfpemudebug,
  177. };
  178. static Cmdtab archctlmsg[] =
  179. {
  180. #ifdef FPEMUDEBUG
  181. CMfpemudebug, "fpemudebug", 2,
  182. #else
  183. CMfpemudebug, "dummy", 1,
  184. #endif
  185. };
  186. static long
  187. archctlwrite(Chan*, void *a, long n, vlong)
  188. {
  189. Cmdbuf *cb;
  190. Cmdtab *ct;
  191. cb = parsecmd(a, n);
  192. if(waserror()){
  193. free(cb);
  194. nexterror();
  195. }
  196. ct = lookupcmd(cb, archctlmsg, nelem(archctlmsg));
  197. switch(ct->index){
  198. case CMfpemudebug:
  199. fpemudebug = atoi(cb->f[1]);
  200. break;
  201. }
  202. free(cb);
  203. poperror();
  204. return n;
  205. }
  206. void
  207. archinit(void)
  208. {
  209. addarchfile("cputype", 0444, cputyperead, nil);
  210. addarchfile("timebase",0444, tbread, nil);
  211. addarchfile("archctl", 0664, archctlread, archctlwrite);
  212. // addarchfile("nsec", 0444, nsread, nil);
  213. }