astarld.c 4.5 KB

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