]> git.lizzy.rs Git - plan9front.git/blob - sys/src/boot/pc/sub.c
remove 9bootfat print
[plan9front.git] / sys / src / boot / pc / sub.c
1 #include <u.h>
2 #include <a.out.h>
3 #include "fns.h"
4 #include "mem.h"
5
6 void
7 memset(void *p, int v, int n)
8 {
9         uchar *d = p;
10         while(n > 0){
11                 *d++ = v;
12                 n--;
13         }
14 }
15
16 void
17 memmove(void *dst, void *src, int n)
18 {
19         uchar *d = dst;
20         uchar *s = src;
21
22         if(d < s){
23                 while(n > 0){
24                         *d++ = *s++;
25                         n--;
26                 }
27         } if(d > s){
28                 s += n;
29                 d += n;
30                 while(n > 0){
31                         *--d = *--s;
32                         n--;
33                 }
34         }
35 }
36
37 int
38 memcmp(void *src, void *dst, int n)
39 {
40         uchar *d = dst;
41         uchar *s = src;
42         int r = 0;
43         while((n > 0) && (r = (*d++ - *s++)) == 0)
44                 n--;
45         return r;
46 }
47
48 int
49 strlen(char *s)
50 {
51         char *p = s;
52         while(*p)
53                 p++;
54         return p - s;
55 }
56
57 char*
58 strchr(char *s, int c)
59 {
60         for(; *s; s++)
61                 if(*s == c)
62                         return s;
63         return 0;
64 }
65
66 char*
67 strrchr(char *s, int c)
68 {
69         char *r;
70         r = 0;
71         while(s = strchr(s, c))
72                 r = s++;
73         return r;
74 }
75
76 void
77 print(char *s)
78 {
79         while(*s)
80                 putc(*s++);
81 }
82
83 int
84 readn(void *f, void *data, int len)
85 {
86         uchar *p, *e;
87
88         putc(' ');
89         p = data;
90         e = p + len;
91         while(p < e){
92                 if(((ulong)p & 0xF000) == 0){
93                         putc('\b');
94                         putc(hex[((ulong)p>>16)&0xF]);
95                 }
96                 if((len = read(f, p, e - p)) <= 0)
97                         break;
98                 p += len;
99         }
100         putc('\b');
101         return p - (uchar*)data;
102 }
103
104 static int
105 readline(void *f, char buf[64])
106 {
107         static char white[] = "\t ";
108         char *p;
109
110         p = buf;
111         do{
112                 if(!f)
113                         putc('>');
114                 while(p < buf + 64-1){
115                         if(!f){
116                                 putc(*p = getc());
117                                 if(*p == '\r')
118                                         putc('\n');
119                                 else if(*p == '\b' && p > buf){
120                                         p--;
121                                         continue;
122                                 }
123                         }else if(read(f, p, 1) <= 0)
124                                 return 0;
125                         if(p == buf && strchr(white, *p))
126                                 continue;
127                         if(strchr(crnl, *p))
128                                 break;
129                         p++;
130                 }
131                 while(p > buf && strchr(white, p[-1]))
132                         p--;
133         }while(p == buf);
134         *p = 0;
135         return p - buf;
136 }
137
138 static int
139 timeout(int ms)
140 {
141         while(ms > 0){
142                 if(gotc())
143                         return 1;
144                 usleep(100000);
145                 ms -= 100;
146         }
147         return 0;
148 }
149
150 #define BOOTLINE        ((char*)CONFADDR)
151 #define BOOTLINELEN     64
152 #define BOOTARGS        ((char*)(CONFADDR+BOOTLINELEN))
153 #define BOOTARGSLEN     (4096-0x200-BOOTLINELEN)
154
155 char *confend;
156
157 static void apmconf(int);
158 static void e820conf(void);
159
160 char*
161 configure(void *f, char *path)
162 {
163         char line[64], *kern, *p;
164         int inblock, n;
165 Clear:
166         kern = 0;
167         inblock = 0;
168
169         memset(BOOTLINE, 0, BOOTLINELEN);
170
171         confend = BOOTARGS;
172         memset(confend, 0, BOOTARGSLEN);
173
174         e820conf();
175 Loop:
176         while((n = readline(f, line)) > 0){
177                 if(*line == 0 || strchr("#;=", *line))
178                         continue;
179                 if(*line == '['){
180                         inblock = memcmp("[common]", line, 8);
181                         continue;
182                 }
183                 if(!memcmp("clear", line, 6)){
184                         print("ok\r\n");
185                         goto Clear;
186                 }
187                 if(!memcmp("boot", line, 5))
188                         break;
189                 if(inblock || !strrchr(line, '='))
190                         continue;
191                 if(!memcmp("bootfile=", line, 9))
192                         memmove(kern = path, line+9, 1 + n-9);
193                 if(!memcmp("apm", line, 3) && line[4]=='='){
194                         apmconf('0' - line[3]);
195                         continue;
196                 }
197                 memmove(confend, line, n); confend += n;
198                 *confend++ = '\n';
199                 print(line); print(crnl);
200         }
201         *confend = 0;
202
203         if(f){
204                 close(f);
205                 f = 0;
206
207                 if(kern && timeout(1000))
208                         goto Loop;
209         }
210
211         if(!kern){
212                 print("no bootfile\r\n");
213                 goto Loop;
214         }
215         if(p = strrchr(kern, '!'))
216                 kern = p+1;
217
218         return kern;
219 }
220
221
222 static void
223 hexfmt(char *s, int i, ulong a)
224 {
225         s += i;
226         while(i > 0){
227                 *--s = hex[a&15];
228                 a >>= 4;
229                 i--;
230         }
231 }
232
233 static void
234 addconfx(char *s, int w, ulong v)
235 {
236         int n;
237
238         n = strlen(s);
239         memmove(confend, s, n);
240         hexfmt(confend+n, w, v);
241         confend += n+w;
242         *confend = 0;
243 }
244
245 void apm(int id);
246
247 static void
248 apmconf(int id)
249 {
250         uchar *a;
251         char *s;
252
253         a = (uchar*)CONFADDR;
254         memset(a, 0, 20);
255
256         apm(id);
257         if(memcmp(a, "APM", 4))
258                 return;
259
260         s = confend;
261
262         addconfx("apm", 1, id);
263         addconfx("=ax=", 4, *((ushort*)(a+4)));
264         addconfx(" ebx=", 8, *((ulong*)(a+12)));
265         addconfx(" cx=", 4, *((ushort*)(a+6)));
266         addconfx(" dx=", 4, *((ushort*)(a+8)));
267         addconfx(" di=", 4, *((ushort*)(a+10)));
268         addconfx(" esi=", 8, *((ulong*)(a+16)));
269
270         print(s); print(crnl);
271
272         *confend++ = '\n';
273 }
274
275 ulong e820(ulong bx, void *p);
276
277 static void
278 e820conf(void)
279 {
280         struct {
281                 uvlong  base;
282                 uvlong  len;
283                 ulong   typ;
284                 ulong   ext;
285         } e;
286         uvlong v;
287         ulong bx;
288         char *s;
289
290         memset(&e, 0, sizeof(e));
291         if((bx = e820(0, &e)) == 0)
292                 return;
293
294         s = confend;
295         memmove(confend, "e820=", 5);
296         confend += 5;
297
298         do{
299                 if(e.typ == 1 && (e.ext & 1) == 0 && e.len){
300                         v = e.base;
301                         addconfx("", 8, v>>32);
302                         addconfx("", 8, v&0xffffffff);
303                         v = e.base + e.len;
304                         addconfx(" ", 8, v>>32);
305                         addconfx("", 8, v&0xffffffff);
306                         *confend++ = ' ';
307                 }
308
309                 memset(&e, 0, sizeof(e));
310         } while(bx = e820(bx, &e));
311
312         *confend = 0;
313         print(s); print(crnl);
314
315         *confend++ = '\n';
316 }
317
318 static ushort
319 beswab(ushort s)
320 {
321         uchar *p;
322
323         p = (uchar*)&s;
324         return (p[0]<<8) | p[1];
325 }
326
327 static ulong
328 beswal(ulong l)
329 {
330         uchar *p;
331
332         p = (uchar*)&l;
333         return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
334 }
335
336 void a20(void);
337
338 char*
339 bootkern(void *f)
340 {
341         uchar *e, *d, *t;
342         ulong n;
343         Exec ex;
344
345         a20();
346
347         if(readn(f, &ex, sizeof(ex)) != sizeof(ex))
348                 return "bad header";
349         if(beswal(ex.magic) != I_MAGIC)
350                 return "bad magic";
351
352         e = (uchar*)(beswal(ex.entry) & ~0xF0000000UL);
353         t = e;
354         n = beswal(ex.text);
355
356         if(readn(f, t, n) != n)
357                 goto Error;
358         d = (uchar*)PGROUND((ulong)t + n);
359         n = beswal(ex.data);
360
361         if(readn(f, d, n) != n)
362                 goto Error;
363         close(f);
364         unload();
365
366         print("boot");
367         print(crnl);
368
369         jump(e);
370
371 Error:          
372         return "i/o error";
373 }