devarch.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  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 name[64], str[128];
  127. cputype2name(name, sizeof name);
  128. snprint(str, sizeof str, "ARM %s %llud\n", name, m->cpuhz / Mhz);
  129. return readstr(offset, a, n, str);
  130. }
  131. static long
  132. tbread(Chan*, void *a, long n, vlong offset)
  133. {
  134. char str[16];
  135. uvlong tb;
  136. cycles(&tb);
  137. snprint(str, sizeof(str), "%16.16llux", tb);
  138. return readstr(offset, a, n, str);
  139. }
  140. static long
  141. nsread(Chan*, void *a, long n, vlong offset)
  142. {
  143. char str[16];
  144. uvlong tb;
  145. cycles(&tb);
  146. snprint(str, sizeof(str), "%16.16llux", (tb/700)* 1000);
  147. return readstr(offset, a, n, str);
  148. }
  149. void
  150. archinit(void)
  151. {
  152. addarchfile("cputype", 0444, cputyperead, nil);
  153. addarchfile("timebase",0444, tbread, nil);
  154. // addarchfile("nsec", 0444, nsread, nil);
  155. }