astarld.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include <u.h>
  10. #include <libc.h>
  11. #include <bio.h>
  12. enum
  13. {
  14. Doff= 4, /* offset into Cpline.bytes of data */
  15. Memsize= 1<<16, /* max size of 186 memory */
  16. };
  17. int dump, image, noload, nostart;
  18. typedef struct
  19. {
  20. int type;
  21. int dlen;
  22. uint32_t addr;
  23. uint8_t bytes[256+4];
  24. uint8_t csum;
  25. } Cpline;
  26. char* rdcpline(Biobuf*, Cpline*);
  27. void clearmem(int);
  28. void
  29. usage(void)
  30. {
  31. fprint(2, "usage: %s [-0123] file\n", argv0);
  32. exits("usage");
  33. }
  34. static void
  35. loadimage(char* file, int mfd)
  36. {
  37. uint8_t buf[256];
  38. int fd, n, r;
  39. if((fd = open(file, OREAD)) < 0)
  40. sysfatal("opening %s: %r", file);
  41. seek(mfd, 0, 0);
  42. do{
  43. n = read(fd, buf, sizeof(buf));
  44. if(n < 0)
  45. sysfatal("read %s: %r", file);
  46. if(n > 0)
  47. if((r = write(mfd, buf, n)) != n)
  48. sysfatal("write %s: %d != %d: %r", file, n, r);
  49. }while(n > 0);
  50. close(fd);
  51. }
  52. static void
  53. loadhex(char* file, int mfd)
  54. {
  55. int done;
  56. Cpline c;
  57. Biobuf *b;
  58. char *err;
  59. uint32_t addr, seg;
  60. int lineno;
  61. uint8_t buf[1024];
  62. b = Bopen(file, OREAD);
  63. if(b == 0)
  64. sysfatal("opening %s: %r", file);
  65. lineno = 1;
  66. seg = 0;
  67. for(done = 0; !done; lineno++){
  68. err = rdcpline(b, &c);
  69. if(err)
  70. sysfatal("%s line %d: %s", file, lineno, err);
  71. switch(c.type){
  72. case 0: /* data */
  73. addr = seg + c.addr;
  74. if(addr + c.dlen > Memsize)
  75. sysfatal("addr out of range: %lux-%lux", addr, addr+c.dlen);
  76. if(seek(mfd, addr, 0) < 0)
  77. sysfatal("seeking to %lud: %r", addr);
  78. if(write(mfd, c.bytes+Doff, c.dlen) != c.dlen)
  79. sysfatal("writing: %r");
  80. if(seek(mfd, addr, 0) < 0)
  81. sysfatal("seeking to %lud: %r", addr);
  82. if(read(mfd, buf, c.dlen) != c.dlen)
  83. sysfatal("reading: %r");
  84. if(memcmp(buf, c.bytes+Doff, c.dlen) != 0)
  85. print("readback error at %lux\n", addr);
  86. if(dump)
  87. print("%8.8lux: %d\n", addr, c.dlen);
  88. break;
  89. case 1: /* termination */
  90. done = 1;
  91. break;
  92. case 2: /* segment */
  93. seg = ((c.bytes[Doff]<<8) | c.bytes[Doff+1]) <<4;
  94. if(seg >= Memsize)
  95. sysfatal("seg out of range: %lux", seg);
  96. if(dump)
  97. print("seg %8.8lux\n", seg);
  98. break;
  99. default: /* ignore */
  100. if(dump)
  101. print("bad type %d\n", c.type);
  102. break;
  103. }
  104. }
  105. Bterm(b);
  106. }
  107. void
  108. main(int argc, char **argv)
  109. {
  110. int unit;
  111. int cfd, mfd;
  112. char file[128];
  113. unit = 0;
  114. ARGBEGIN{
  115. case 'd':
  116. dump = 1;
  117. break;
  118. case 'i':
  119. image = 1;
  120. break;
  121. case 'n':
  122. noload = 1;
  123. break;
  124. case 's':
  125. nostart = 1;
  126. break;
  127. case '0':
  128. unit = 0;
  129. break;
  130. case '1':
  131. unit = 1;
  132. break;
  133. case '2':
  134. unit = 2;
  135. break;
  136. case '3':
  137. unit = 3;
  138. break;
  139. }ARGEND;
  140. if(argc == 0)
  141. usage();
  142. if(noload == 0){
  143. sprint(file, "#G/astar%dctl", unit);
  144. cfd = open(file, ORDWR);
  145. if(cfd < 0)
  146. sysfatal("opening %s", file);
  147. sprint(file, "#G/astar%dmem", unit);
  148. mfd = open(file, ORDWR);
  149. if(mfd < 0)
  150. sysfatal("opening %s", file);
  151. if(write(cfd, "download", 8) != 8)
  152. sysfatal("requesting download: %r");
  153. } else {
  154. cfd = -1;
  155. mfd = create("/tmp/astarmem", ORDWR, 0664);
  156. if(mfd < 0)
  157. sysfatal("creating /tmp/astarmem: %r");
  158. }
  159. if(image)
  160. loadimage(argv[0], mfd);
  161. else{
  162. /* zero out the memory */
  163. clearmem(mfd);
  164. loadhex(argv[0], mfd);
  165. }
  166. close(mfd);
  167. if(noload == 0 && nostart == 0)
  168. if(write(cfd, "run", 3) != 3)
  169. sysfatal("requesting run: %r");
  170. close(cfd);
  171. exits(0);
  172. }
  173. void
  174. clearmem(int fd)
  175. {
  176. char buf[4096];
  177. char buf2[4096];
  178. int i, n;
  179. memset(buf, 0, sizeof buf);
  180. for(i = 0; i < Memsize; i += n){
  181. if(seek(fd, i, 0) < 0)
  182. sysfatal("seeking to %ux: %r", i);
  183. n = write(fd, buf, sizeof buf);
  184. if(n <= 0)
  185. break;
  186. if(seek(fd, i, 0) < 0)
  187. sysfatal("seeking to %ux: %r", i);
  188. n = read(fd, buf2, sizeof buf2);
  189. if(n <= 0)
  190. break;
  191. if(memcmp(buf, buf2, sizeof buf) != 0)
  192. print("error zeroing mem at %ux\n", i);
  193. }
  194. print("zero'd %d bytes\n", i);
  195. }
  196. int
  197. hex(char c)
  198. {
  199. if(c <= '9' && c >= '0')
  200. return c - '0';
  201. if(c <= 'f' && c >= 'a')
  202. return (c - 'a') + 10;
  203. if(c <= 'F' && c >= 'A')
  204. return (c - 'A') + 10;
  205. return -1;
  206. }
  207. char*
  208. rdcpline(Biobuf *b, Cpline *cpl)
  209. {
  210. char *cp, *ep, *p;
  211. uint8_t *up;
  212. uint8_t csum;
  213. int c;
  214. cp = Brdline(b, '\n');
  215. if(cp == 0)
  216. return "early eof";
  217. ep = cp + Blinelen(b);
  218. if(*cp++ != ':')
  219. return "bad load line";
  220. csum = 0;
  221. up = cpl->bytes;
  222. for(p = cp; p < ep;){
  223. c = hex(*p++)<<4;
  224. c |= hex(*p++);
  225. if(c < 0)
  226. break;
  227. csum += c;
  228. *up++ = c;
  229. }
  230. cpl->csum = csum;
  231. if(csum != 0){
  232. fprint(2, "checksum %ux\n", csum);
  233. return "bad checksum";
  234. }
  235. cpl->dlen = cpl->bytes[0];
  236. if(cpl->dlen + 5 != up - cpl->bytes){
  237. fprint(2, "%d %ld\n", cpl->dlen + 5, up - cpl->bytes);
  238. return "bad data length";
  239. }
  240. cpl->addr = (cpl->bytes[1]<<8) | cpl->bytes[2];
  241. cpl->type = cpl->bytes[3];
  242. return 0;
  243. }