mem.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <bio.h>
  4. #include <mach.h>
  5. #define Extern extern
  6. #include "mips.h"
  7. extern ulong textbase;
  8. ulong
  9. ifetch(ulong addr)
  10. {
  11. uchar *va;
  12. if(addr&3) {
  13. Bprint(bioout, "Address error (I-fetch) vaddr %.8lux\n", addr);
  14. longjmp(errjmp, 0);
  15. }
  16. if(icache.on)
  17. updateicache(addr);
  18. iprof[(addr-textbase)/PROFGRAN]++;
  19. va = vaddr(addr);
  20. va += addr&(BY2PG-1);
  21. return va[0]<<24 | va[1]<<16 | va[2]<<8 | va[3];
  22. }
  23. ulong
  24. getmem_4(ulong addr)
  25. {
  26. ulong val;
  27. int i;
  28. val = 0;
  29. for(i = 0; i < 4; i++)
  30. val = val<<8 | getmem_b(addr++);
  31. return val;
  32. }
  33. ulong
  34. getmem_2(ulong addr)
  35. {
  36. ulong val;
  37. val = getmem_b(addr);
  38. val = val<<8 | getmem_b(addr+1);
  39. return val;
  40. }
  41. ulong
  42. getmem_w(ulong addr)
  43. {
  44. uchar *va;
  45. if(addr&3) {
  46. Bprint(bioout, "Address error (Load) vaddr %.8lux\n", addr);
  47. longjmp(errjmp, 0);
  48. }
  49. if(membpt)
  50. brkchk(addr, Read);
  51. va = vaddr(addr);
  52. va += addr&(BY2PG-1);
  53. return va[0]<<24 | va[1]<<16 | va[2]<<8 | va[3];;
  54. }
  55. ushort
  56. getmem_h(ulong addr)
  57. {
  58. uchar *va;
  59. if(addr&1) {
  60. Bprint(bioout, "Address error (Load) vaddr %.8lux\n", addr);
  61. longjmp(errjmp, 0);
  62. }
  63. if(membpt)
  64. brkchk(addr, Read);
  65. va = vaddr(addr);
  66. va += addr&(BY2PG-1);
  67. return va[0]<<8 | va[1];
  68. }
  69. uchar
  70. getmem_b(ulong addr)
  71. {
  72. uchar *va;
  73. if(membpt)
  74. brkchk(addr, Read);
  75. va = vaddr(addr);
  76. va += addr&(BY2PG-1);
  77. return va[0];
  78. }
  79. void
  80. putmem_w(ulong addr, ulong data)
  81. {
  82. uchar *va;
  83. if(addr&3) {
  84. Bprint(bioout, "Address error (Store) vaddr %.8lux\n", addr);
  85. longjmp(errjmp, 0);
  86. }
  87. va = vaddr(addr);
  88. va += addr&(BY2PG-1);
  89. va[0] = data>>24;
  90. va[1] = data>>16;
  91. va[2] = data>>8;
  92. va[3] = data;
  93. if(membpt)
  94. brkchk(addr, Write);
  95. }
  96. void
  97. putmem_b(ulong addr, uchar data)
  98. {
  99. uchar *va;
  100. va = vaddr(addr);
  101. va += addr&(BY2PG-1);
  102. va[0] = data;
  103. if(membpt)
  104. brkchk(addr, Write);
  105. }
  106. void
  107. putmem_h(ulong addr, short data)
  108. {
  109. uchar *va;
  110. if(addr&1) {
  111. Bprint(bioout, "Address error (Store) vaddr %.8lux\n", addr);
  112. longjmp(errjmp, 0);
  113. }
  114. va = vaddr(addr);
  115. va += addr&(BY2PG-1);
  116. va[0] = data>>8;
  117. va[1] = data;
  118. if(membpt)
  119. brkchk(addr, Write);
  120. }
  121. char *
  122. memio(char *mb, ulong mem, int size, int dir)
  123. {
  124. int i;
  125. char *buf, c;
  126. if(mb == 0)
  127. mb = emalloc(size);
  128. buf = mb;
  129. switch(dir) {
  130. default:
  131. fatal(0, "memio");
  132. case MemRead:
  133. while(size--)
  134. *mb++ = getmem_b(mem++);
  135. break;
  136. case MemReadstring:
  137. for(;;) {
  138. if(size-- == 0) {
  139. Bprint(bioout, "memio: user/kernel copy too long for mipsim\n");
  140. longjmp(errjmp, 0);
  141. }
  142. c = getmem_b(mem++);
  143. *mb++ = c;
  144. if(c == '\0')
  145. break;
  146. }
  147. break;
  148. case MemWrite:
  149. for(i = 0; i < size; i++)
  150. putmem_b(mem++, *mb++);
  151. break;
  152. }
  153. return buf;
  154. }
  155. void
  156. dotlb(ulong vaddr)
  157. {
  158. ulong *l, *e;
  159. vaddr &= ~(BY2PG-1);
  160. e = &tlb.tlbent[tlb.tlbsize];
  161. for(l = tlb.tlbent; l < e; l++)
  162. if(*l == vaddr) {
  163. tlb.hit++;
  164. return;
  165. }
  166. tlb.miss++;
  167. tlb.tlbent[lnrand(tlb.tlbsize)] = vaddr;
  168. }
  169. void*
  170. vaddr1(ulong addr)
  171. {
  172. Segment *s, *es;
  173. int off, foff, l, n;
  174. uchar **p, *a;
  175. if(tlb.on)
  176. dotlb(addr);
  177. es = &memory.seg[Nseg];
  178. for(s = memory.seg; s < es; s++) {
  179. if(addr >= s->base && addr < s->end) {
  180. s->refs++;
  181. off = (addr-s->base)/BY2PG;
  182. p = &s->table[off];
  183. if(*p)
  184. return *p;
  185. s->rss++;
  186. switch(s->type) {
  187. default:
  188. fatal(0, "vaddr");
  189. case Text:
  190. *p = emalloc(BY2PG);
  191. if(seek(text, s->fileoff+(off*BY2PG), 0) < 0)
  192. fatal(1, "vaddr text seek");
  193. if(read(text, *p, BY2PG) < 0)
  194. fatal(1, "vaddr text read");
  195. return *p;
  196. case Data:
  197. *p = emalloc(BY2PG);
  198. foff = s->fileoff+(off*BY2PG);
  199. if(seek(text, foff, 0) < 0)
  200. fatal(1, "vaddr text seek");
  201. n = read(text, *p, BY2PG);
  202. if(n < 0)
  203. fatal(1, "vaddr text read");
  204. if(foff + n > s->fileend) {
  205. l = BY2PG - (s->fileend-foff);
  206. a = *p+(s->fileend-foff);
  207. memset(a, 0, l);
  208. }
  209. return *p;
  210. case Bss:
  211. case Stack:
  212. *p = emalloc(BY2PG);
  213. return *p;
  214. }
  215. }
  216. }
  217. return 0;
  218. }
  219. void*
  220. vaddr(ulong addr)
  221. {
  222. void *v;
  223. v = vaddr1(addr);
  224. if(v == 0) {
  225. Bprint(bioout, "User TLB miss vaddr 0x%.8lux\n", addr);
  226. longjmp(errjmp, 0);
  227. }
  228. return v;
  229. }
  230. int
  231. badvaddr(ulong addr, int n)
  232. {
  233. void *v;
  234. if(addr & (n-1))
  235. return 1;
  236. v = vaddr1(addr);
  237. if(v == 0)
  238. return 1;
  239. return 0;
  240. }