mem.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <bio.h>
  4. #include <mach.h>
  5. #define Extern extern
  6. #include "sparc.h"
  7. extern ulong textbase;
  8. ulong
  9. ifetch(ulong addr)
  10. {
  11. uchar *va;
  12. if(addr&3) {
  13. Bprint(bioout, "instruction_address_not_aligned [addr %.8lux]\n", addr);
  14. longjmp(errjmp, 0);
  15. }
  16. if(icache.on)
  17. updateicache(addr);
  18. va = vaddr(addr);
  19. iprof[(addr-textbase)/PROFGRAN]++;
  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, "mem_address_not_aligned [load addr %.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, "mem_address_not_aligned [load addr %.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, "mem_address_not_aligned [store addr %.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, "mem_address_not_aligned [store addr %.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. vaddr(ulong addr)
  157. {
  158. Segment *s, *es;
  159. int off, foff, l, n;
  160. uchar **p, *a;
  161. es = &memory.seg[Nseg];
  162. for(s = memory.seg; s < es; s++) {
  163. if(addr >= s->base && addr < s->end) {
  164. s->refs++;
  165. off = (addr-s->base)/BY2PG;
  166. p = &s->table[off];
  167. if(*p)
  168. return *p;
  169. s->rss++;
  170. switch(s->type) {
  171. default:
  172. fatal(0, "vaddr");
  173. case Text:
  174. *p = emalloc(BY2PG);
  175. if(seek(text, s->fileoff+(off*BY2PG), 0) < 0)
  176. fatal(1, "vaddr text seek");
  177. if(read(text, *p, BY2PG) < 0)
  178. fatal(1, "vaddr text read");
  179. return *p;
  180. case Data:
  181. *p = emalloc(BY2PG);
  182. foff = s->fileoff+(off*BY2PG);
  183. if(seek(text, foff, 0) < 0)
  184. fatal(1, "vaddr text seek");
  185. n = read(text, *p, BY2PG);
  186. if(n < 0)
  187. fatal(1, "vaddr text read");
  188. if(foff + n > s->fileend) {
  189. l = BY2PG - (s->fileend-foff);
  190. a = *p+(s->fileend-foff);
  191. memset(a, 0, l);
  192. }
  193. return *p;
  194. case Bss:
  195. case Stack:
  196. *p = emalloc(BY2PG);
  197. return *p;
  198. }
  199. }
  200. }
  201. Bprint(bioout, "data_access_MMU_miss [addr 0x%.8lux]\n", addr);
  202. longjmp(errjmp, 0);
  203. return 0; /*to stop compiler whining*/
  204. }