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