1*da917039SDavid du Colombier #include "include.h"
2*da917039SDavid du Colombier #include "ip.h"
3*da917039SDavid du Colombier #include "/sys/src/libmach/elf.h"
4*da917039SDavid du Colombier
5*da917039SDavid du Colombier int tftpupload(char *name, void *p, int len);
6*da917039SDavid du Colombier
7*da917039SDavid du Colombier extern ulong cpuentry;
8*da917039SDavid du Colombier
9*da917039SDavid du Colombier static uchar elfident[7] = {
10*da917039SDavid du Colombier '\177', 'E', 'L', 'F', '\1', '\1', '\1'
11*da917039SDavid du Colombier };
12*da917039SDavid du Colombier static Ehdr ehdr, rehdr;
13*da917039SDavid du Colombier static Phdr *phdr;
14*da917039SDavid du Colombier static int curphdr;
15*da917039SDavid du Colombier static ulong curoff;
16*da917039SDavid du Colombier static ulong elftotal;
17*da917039SDavid du Colombier
18*da917039SDavid du Colombier static long (*swal)(long);
19*da917039SDavid du Colombier static ushort (*swab)(ushort);
20*da917039SDavid du Colombier
21*da917039SDavid du Colombier /*
22*da917039SDavid du Colombier * big-endian short
23*da917039SDavid du Colombier */
24*da917039SDavid du Colombier ushort
beswab(ushort s)25*da917039SDavid du Colombier beswab(ushort s)
26*da917039SDavid du Colombier {
27*da917039SDavid du Colombier uchar *p;
28*da917039SDavid du Colombier
29*da917039SDavid du Colombier p = (uchar*)&s;
30*da917039SDavid du Colombier return (p[0]<<8) | p[1];
31*da917039SDavid du Colombier }
32*da917039SDavid du Colombier
33*da917039SDavid du Colombier /*
34*da917039SDavid du Colombier * big-endian long
35*da917039SDavid du Colombier */
36*da917039SDavid du Colombier long
beswal(long l)37*da917039SDavid du Colombier beswal(long l)
38*da917039SDavid du Colombier {
39*da917039SDavid du Colombier uchar *p;
40*da917039SDavid du Colombier
41*da917039SDavid du Colombier p = (uchar*)&l;
42*da917039SDavid du Colombier return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
43*da917039SDavid du Colombier }
44*da917039SDavid du Colombier
45*da917039SDavid du Colombier /*
46*da917039SDavid du Colombier * little-endian short
47*da917039SDavid du Colombier */
48*da917039SDavid du Colombier ushort
leswab(ushort s)49*da917039SDavid du Colombier leswab(ushort s)
50*da917039SDavid du Colombier {
51*da917039SDavid du Colombier uchar *p;
52*da917039SDavid du Colombier
53*da917039SDavid du Colombier p = (uchar*)&s;
54*da917039SDavid du Colombier return (p[1]<<8) | p[0];
55*da917039SDavid du Colombier }
56*da917039SDavid du Colombier
57*da917039SDavid du Colombier /*
58*da917039SDavid du Colombier * little-endian long
59*da917039SDavid du Colombier */
60*da917039SDavid du Colombier long
leswal(long l)61*da917039SDavid du Colombier leswal(long l)
62*da917039SDavid du Colombier {
63*da917039SDavid du Colombier uchar *p;
64*da917039SDavid du Colombier
65*da917039SDavid du Colombier p = (uchar*)&l;
66*da917039SDavid du Colombier return (p[3]<<24) | (p[2]<<16) | (p[1]<<8) | p[0];
67*da917039SDavid du Colombier }
68*da917039SDavid du Colombier
69*da917039SDavid du Colombier /*
70*da917039SDavid du Colombier * Convert header to canonical form
71*da917039SDavid du Colombier */
72*da917039SDavid du Colombier static void
hswal(long * lp,int n,long (* swap)(long))73*da917039SDavid du Colombier hswal(long *lp, int n, long (*swap) (long))
74*da917039SDavid du Colombier {
75*da917039SDavid du Colombier while (n--) {
76*da917039SDavid du Colombier *lp = (*swap) (*lp);
77*da917039SDavid du Colombier lp++;
78*da917039SDavid du Colombier }
79*da917039SDavid du Colombier }
80*da917039SDavid du Colombier
81*da917039SDavid du Colombier static int
readehdr(Boot * b)82*da917039SDavid du Colombier readehdr(Boot *b)
83*da917039SDavid du Colombier {
84*da917039SDavid du Colombier int i;
85*da917039SDavid du Colombier
86*da917039SDavid du Colombier /* bitswap the header according to the DATA format */
87*da917039SDavid du Colombier if(ehdr.ident[CLASS] != ELFCLASS32) {
88*da917039SDavid du Colombier print("bad ELF class - not 32 bit\n");
89*da917039SDavid du Colombier return 0;
90*da917039SDavid du Colombier }
91*da917039SDavid du Colombier if(ehdr.ident[DATA] == ELFDATA2LSB) {
92*da917039SDavid du Colombier swab = leswab;
93*da917039SDavid du Colombier swal = leswal;
94*da917039SDavid du Colombier } else if(ehdr.ident[DATA] == ELFDATA2MSB) {
95*da917039SDavid du Colombier swab = beswab;
96*da917039SDavid du Colombier swal = beswal;
97*da917039SDavid du Colombier } else {
98*da917039SDavid du Colombier print("bad ELF encoding - not big or little endian\n");
99*da917039SDavid du Colombier return 0;
100*da917039SDavid du Colombier }
101*da917039SDavid du Colombier memmove(&rehdr, &ehdr, sizeof(Ehdr));
102*da917039SDavid du Colombier
103*da917039SDavid du Colombier ehdr.type = swab(ehdr.type);
104*da917039SDavid du Colombier ehdr.machine = swab(ehdr.machine);
105*da917039SDavid du Colombier ehdr.version = swal(ehdr.version);
106*da917039SDavid du Colombier ehdr.elfentry = swal(ehdr.elfentry);
107*da917039SDavid du Colombier ehdr.phoff = swal(ehdr.phoff);
108*da917039SDavid du Colombier ehdr.shoff = swal(ehdr.shoff);
109*da917039SDavid du Colombier ehdr.flags = swal(ehdr.flags);
110*da917039SDavid du Colombier ehdr.ehsize = swab(ehdr.ehsize);
111*da917039SDavid du Colombier ehdr.phentsize = swab(ehdr.phentsize);
112*da917039SDavid du Colombier ehdr.phnum = swab(ehdr.phnum);
113*da917039SDavid du Colombier ehdr.shentsize = swab(ehdr.shentsize);
114*da917039SDavid du Colombier ehdr.shnum = swab(ehdr.shnum);
115*da917039SDavid du Colombier ehdr.shstrndx = swab(ehdr.shstrndx);
116*da917039SDavid du Colombier if(ehdr.type != EXEC || ehdr.version != CURRENT)
117*da917039SDavid du Colombier return 0;
118*da917039SDavid du Colombier if(ehdr.phentsize != sizeof(Phdr))
119*da917039SDavid du Colombier return 0;
120*da917039SDavid du Colombier
121*da917039SDavid du Colombier if(debug)
122*da917039SDavid du Colombier print("readehdr OK entry 0x%lux\n", ehdr.elfentry);
123*da917039SDavid du Colombier
124*da917039SDavid du Colombier curoff = sizeof(Ehdr);
125*da917039SDavid du Colombier i = ehdr.phoff+ehdr.phentsize*ehdr.phnum - curoff;
126*da917039SDavid du Colombier b->state = READPHDR;
127*da917039SDavid du Colombier b->bp = (char*)malloc(i);
128*da917039SDavid du Colombier b->wp = b->bp;
129*da917039SDavid du Colombier b->ep = b->wp + i;
130*da917039SDavid du Colombier phdr = (Phdr*)(b->bp + ehdr.phoff-sizeof(Ehdr));
131*da917039SDavid du Colombier if(debug)
132*da917039SDavid du Colombier print("phdr...");
133*da917039SDavid du Colombier
134*da917039SDavid du Colombier return 1;
135*da917039SDavid du Colombier }
136*da917039SDavid du Colombier
137*da917039SDavid du Colombier static int
nextphdr(Boot * b)138*da917039SDavid du Colombier nextphdr(Boot *b)
139*da917039SDavid du Colombier {
140*da917039SDavid du Colombier Phdr *php;
141*da917039SDavid du Colombier ulong entry, offset;
142*da917039SDavid du Colombier char *paddr;
143*da917039SDavid du Colombier
144*da917039SDavid du Colombier if(debug)
145*da917039SDavid du Colombier print("readedata %d\n", curphdr);
146*da917039SDavid du Colombier
147*da917039SDavid du Colombier for(; curphdr < ehdr.phnum; curphdr++){
148*da917039SDavid du Colombier php = phdr+curphdr;
149*da917039SDavid du Colombier if(php->type != LOAD)
150*da917039SDavid du Colombier continue;
151*da917039SDavid du Colombier offset = php->offset;
152*da917039SDavid du Colombier paddr = (char*)PADDR(php->paddr);
153*da917039SDavid du Colombier if(offset < curoff){
154*da917039SDavid du Colombier /*
155*da917039SDavid du Colombier * Can't (be bothered to) rewind the
156*da917039SDavid du Colombier * input, it might be from tftp. If we
157*da917039SDavid du Colombier * did then we could boot FreeBSD kernels
158*da917039SDavid du Colombier * too maybe.
159*da917039SDavid du Colombier */
160*da917039SDavid du Colombier return 0;
161*da917039SDavid du Colombier }
162*da917039SDavid du Colombier if(php->offset > curoff){
163*da917039SDavid du Colombier b->state = READEPAD;
164*da917039SDavid du Colombier b->bp = (char*)malloc(offset - curoff);
165*da917039SDavid du Colombier b->wp = b->bp;
166*da917039SDavid du Colombier b->ep = b->wp + offset - curoff;
167*da917039SDavid du Colombier if(debug)
168*da917039SDavid du Colombier print("nextphdr %lud...\n", offset - curoff);
169*da917039SDavid du Colombier return 1;
170*da917039SDavid du Colombier }
171*da917039SDavid du Colombier b->state = READEDATA;
172*da917039SDavid du Colombier b->bp = paddr;
173*da917039SDavid du Colombier b->wp = b->bp;
174*da917039SDavid du Colombier b->ep = b->wp+php->filesz;
175*da917039SDavid du Colombier print("%ud+", php->filesz);
176*da917039SDavid du Colombier elftotal += php->filesz;
177*da917039SDavid du Colombier if(debug)
178*da917039SDavid du Colombier print("nextphdr %ud@0x%p\n", php->filesz, paddr);
179*da917039SDavid du Colombier
180*da917039SDavid du Colombier return 1;
181*da917039SDavid du Colombier }
182*da917039SDavid du Colombier
183*da917039SDavid du Colombier if(curphdr != 0){
184*da917039SDavid du Colombier print("=%lud\n", elftotal);
185*da917039SDavid du Colombier b->state = TRYBOOT;
186*da917039SDavid du Colombier entry = ehdr.elfentry & ~0xF0000000;
187*da917039SDavid du Colombier PLLONG(b->exec.entry, entry);
188*da917039SDavid du Colombier return 1;
189*da917039SDavid du Colombier }
190*da917039SDavid du Colombier
191*da917039SDavid du Colombier return 0;
192*da917039SDavid du Colombier }
193*da917039SDavid du Colombier
194*da917039SDavid du Colombier static int
readepad(Boot * b)195*da917039SDavid du Colombier readepad(Boot *b)
196*da917039SDavid du Colombier {
197*da917039SDavid du Colombier Phdr *php;
198*da917039SDavid du Colombier
199*da917039SDavid du Colombier php = phdr+curphdr;
200*da917039SDavid du Colombier if(debug)
201*da917039SDavid du Colombier print("readepad %d\n", curphdr);
202*da917039SDavid du Colombier curoff = php->offset;
203*da917039SDavid du Colombier
204*da917039SDavid du Colombier return nextphdr(b);
205*da917039SDavid du Colombier }
206*da917039SDavid du Colombier
207*da917039SDavid du Colombier static int
readedata(Boot * b)208*da917039SDavid du Colombier readedata(Boot *b)
209*da917039SDavid du Colombier {
210*da917039SDavid du Colombier Phdr *php;
211*da917039SDavid du Colombier
212*da917039SDavid du Colombier php = phdr+curphdr;
213*da917039SDavid du Colombier if(debug)
214*da917039SDavid du Colombier print("readedata %d\n", curphdr);
215*da917039SDavid du Colombier if(php->filesz < php->memsz){
216*da917039SDavid du Colombier print("%lud", php->memsz-php->filesz);
217*da917039SDavid du Colombier elftotal += php->memsz-php->filesz;
218*da917039SDavid du Colombier memset((char*)(PADDR(php->paddr)+php->filesz), 0, php->memsz-php->filesz);
219*da917039SDavid du Colombier }
220*da917039SDavid du Colombier curoff = php->offset+php->filesz;
221*da917039SDavid du Colombier curphdr++;
222*da917039SDavid du Colombier
223*da917039SDavid du Colombier return nextphdr(b);
224*da917039SDavid du Colombier }
225*da917039SDavid du Colombier
226*da917039SDavid du Colombier static int
readphdr(Boot * b)227*da917039SDavid du Colombier readphdr(Boot *b)
228*da917039SDavid du Colombier {
229*da917039SDavid du Colombier Phdr *php;
230*da917039SDavid du Colombier
231*da917039SDavid du Colombier php = phdr;
232*da917039SDavid du Colombier hswal((long*)php, ehdr.phentsize*ehdr.phnum/sizeof(long), swal);
233*da917039SDavid du Colombier if(debug)
234*da917039SDavid du Colombier print("phdr curoff %lud vaddr 0x%lux paddr 0x%lux\n",
235*da917039SDavid du Colombier curoff, php->vaddr, php->paddr);
236*da917039SDavid du Colombier
237*da917039SDavid du Colombier curoff = ehdr.phoff+ehdr.phentsize*ehdr.phnum;
238*da917039SDavid du Colombier curphdr = 0;
239*da917039SDavid du Colombier
240*da917039SDavid du Colombier return nextphdr(b);
241*da917039SDavid du Colombier }
242*da917039SDavid du Colombier
243*da917039SDavid du Colombier static ulong chksum, length;
244*da917039SDavid du Colombier
245*da917039SDavid du Colombier static void
sum(void * vp,int len)246*da917039SDavid du Colombier sum(void *vp, int len)
247*da917039SDavid du Colombier {
248*da917039SDavid du Colombier unsigned long *p;
249*da917039SDavid du Colombier
250*da917039SDavid du Colombier if (len % sizeof(int) != 0) {
251*da917039SDavid du Colombier print("sum: len %d not a multiple of word size\n",
252*da917039SDavid du Colombier len);
253*da917039SDavid du Colombier return;
254*da917039SDavid du Colombier }
255*da917039SDavid du Colombier p = vp;
256*da917039SDavid du Colombier len /= sizeof *p;
257*da917039SDavid du Colombier while (len-- > 0)
258*da917039SDavid du Colombier chksum += *p++;
259*da917039SDavid du Colombier }
260*da917039SDavid du Colombier
261*da917039SDavid du Colombier static int
addbytes(char ** dbuf,char * edbuf,char ** sbuf,char * esbuf)262*da917039SDavid du Colombier addbytes(char **dbuf, char *edbuf, char **sbuf, char *esbuf)
263*da917039SDavid du Colombier {
264*da917039SDavid du Colombier int n;
265*da917039SDavid du Colombier static ulong *start;
266*da917039SDavid du Colombier
267*da917039SDavid du Colombier n = edbuf - *dbuf;
268*da917039SDavid du Colombier if(n <= 0)
269*da917039SDavid du Colombier return 0;
270*da917039SDavid du Colombier if(n > esbuf - *sbuf)
271*da917039SDavid du Colombier n = esbuf - *sbuf;
272*da917039SDavid du Colombier if(n <= 0)
273*da917039SDavid du Colombier return -1;
274*da917039SDavid du Colombier
275*da917039SDavid du Colombier memmove(*dbuf, *sbuf, n);
276*da917039SDavid du Colombier coherence();
277*da917039SDavid du Colombier
278*da917039SDavid du Colombier /* verify that the copy worked */
279*da917039SDavid du Colombier if (memcmp(*dbuf, *sbuf, n) != 0)
280*da917039SDavid du Colombier panic("addbytes: memmove copied %d bytes wrong from %#p to %#p",
281*da917039SDavid du Colombier n, *sbuf, *dbuf);
282*da917039SDavid du Colombier *sbuf += n;
283*da917039SDavid du Colombier *dbuf += n;
284*da917039SDavid du Colombier return edbuf - *dbuf;
285*da917039SDavid du Colombier }
286*da917039SDavid du Colombier
287*da917039SDavid du Colombier int
bootpass(Boot * b,void * vbuf,int nbuf)288*da917039SDavid du Colombier bootpass(Boot *b, void *vbuf, int nbuf)
289*da917039SDavid du Colombier {
290*da917039SDavid du Colombier char *buf, *ebuf;
291*da917039SDavid du Colombier Exec *ep;
292*da917039SDavid du Colombier ulong entry, data, text, bss;
293*da917039SDavid du Colombier
294*da917039SDavid du Colombier SET(text, data);
295*da917039SDavid du Colombier USED(text, data);
296*da917039SDavid du Colombier if(b->state == FAILED)
297*da917039SDavid du Colombier return FAIL;
298*da917039SDavid du Colombier
299*da917039SDavid du Colombier if(nbuf == 0)
300*da917039SDavid du Colombier goto Endofinput;
301*da917039SDavid du Colombier
302*da917039SDavid du Colombier buf = vbuf;
303*da917039SDavid du Colombier ebuf = buf+nbuf;
304*da917039SDavid du Colombier while(addbytes(&b->wp, b->ep, &buf, ebuf) == 0) {
305*da917039SDavid du Colombier switch(b->state) {
306*da917039SDavid du Colombier case INITKERNEL:
307*da917039SDavid du Colombier b->state = READEXEC;
308*da917039SDavid du Colombier b->bp = (char*)&b->exec;
309*da917039SDavid du Colombier b->wp = b->bp;
310*da917039SDavid du Colombier b->ep = b->bp+sizeof(Exec);
311*da917039SDavid du Colombier break;
312*da917039SDavid du Colombier case READEXEC:
313*da917039SDavid du Colombier ep = &b->exec;
314*da917039SDavid du Colombier if(GLLONG(ep->magic) == Q_MAGIC) {
315*da917039SDavid du Colombier b->state = READ9TEXT;
316*da917039SDavid du Colombier b->bp = (char*)PADDR(GLLONG(ep->entry));
317*da917039SDavid du Colombier b->wp = b->bp;
318*da917039SDavid du Colombier b->ep = b->wp+GLLONG(ep->text);
319*da917039SDavid du Colombier print("%lud", GLLONG(ep->text));
320*da917039SDavid du Colombier break;
321*da917039SDavid du Colombier }
322*da917039SDavid du Colombier
323*da917039SDavid du Colombier /*
324*da917039SDavid du Colombier * Check for ELF.
325*da917039SDavid du Colombier */
326*da917039SDavid du Colombier if(memcmp(b->bp, elfident, 4) == 0){
327*da917039SDavid du Colombier b->state = READEHDR;
328*da917039SDavid du Colombier b->bp = (char*)&ehdr;
329*da917039SDavid du Colombier b->wp = b->bp;
330*da917039SDavid du Colombier b->ep = b->wp + sizeof(Ehdr);
331*da917039SDavid du Colombier memmove(b->bp, &b->exec, sizeof(Exec));
332*da917039SDavid du Colombier b->wp += sizeof(Exec);
333*da917039SDavid du Colombier print("elf...");
334*da917039SDavid du Colombier break;
335*da917039SDavid du Colombier }
336*da917039SDavid du Colombier
337*da917039SDavid du Colombier print("bad kernel format\n");
338*da917039SDavid du Colombier b->state = FAILED;
339*da917039SDavid du Colombier return FAIL;
340*da917039SDavid du Colombier
341*da917039SDavid du Colombier case READ9TEXT:
342*da917039SDavid du Colombier ep = &b->exec;
343*da917039SDavid du Colombier b->state = READ9DATA;
344*da917039SDavid du Colombier b->bp = (char*)UTROUND(PADDR(GLLONG(ep->entry)) +
345*da917039SDavid du Colombier GLLONG(ep->text));
346*da917039SDavid du Colombier b->wp = b->bp;
347*da917039SDavid du Colombier b->ep = b->wp + GLLONG(ep->data);
348*da917039SDavid du Colombier {
349*da917039SDavid du Colombier /*
350*da917039SDavid du Colombier * fill the gap between text and first page
351*da917039SDavid du Colombier * of data.
352*da917039SDavid du Colombier */
353*da917039SDavid du Colombier int wds;
354*da917039SDavid du Colombier ulong *dst = (ulong *)(PADDR(GLLONG(ep->entry))+
355*da917039SDavid du Colombier GLLONG(ep->text));
356*da917039SDavid du Colombier
357*da917039SDavid du Colombier for (wds = (ulong *)b->bp - dst; wds-- > 0;
358*da917039SDavid du Colombier dst++)
359*da917039SDavid du Colombier *dst = (uintptr)dst;
360*da917039SDavid du Colombier }
361*da917039SDavid du Colombier print("+%ld", GLLONG(ep->data));
362*da917039SDavid du Colombier length = b->ep - (char *)PADDR(GLLONG(ep->entry));
363*da917039SDavid du Colombier break;
364*da917039SDavid du Colombier
365*da917039SDavid du Colombier case READ9DATA:
366*da917039SDavid du Colombier ep = &b->exec;
367*da917039SDavid du Colombier bss = GLLONG(ep->bss);
368*da917039SDavid du Colombier print("+%ld=%ld\n",
369*da917039SDavid du Colombier bss, GLLONG(ep->text)+GLLONG(ep->data)+bss);
370*da917039SDavid du Colombier b->state = TRYBOOT;
371*da917039SDavid du Colombier return ENOUGH;
372*da917039SDavid du Colombier
373*da917039SDavid du Colombier case READEHDR:
374*da917039SDavid du Colombier if(!readehdr(b)){
375*da917039SDavid du Colombier print("readehdr failed\n");
376*da917039SDavid du Colombier b->state = FAILED;
377*da917039SDavid du Colombier return FAIL;
378*da917039SDavid du Colombier }
379*da917039SDavid du Colombier break;
380*da917039SDavid du Colombier
381*da917039SDavid du Colombier case READPHDR:
382*da917039SDavid du Colombier if(!readphdr(b)){
383*da917039SDavid du Colombier b->state = FAILED;
384*da917039SDavid du Colombier return FAIL;
385*da917039SDavid du Colombier }
386*da917039SDavid du Colombier break;
387*da917039SDavid du Colombier
388*da917039SDavid du Colombier case READEPAD:
389*da917039SDavid du Colombier if(!readepad(b)){
390*da917039SDavid du Colombier b->state = FAILED;
391*da917039SDavid du Colombier return FAIL;
392*da917039SDavid du Colombier }
393*da917039SDavid du Colombier break;
394*da917039SDavid du Colombier
395*da917039SDavid du Colombier case READEDATA:
396*da917039SDavid du Colombier if(!readedata(b)){
397*da917039SDavid du Colombier b->state = FAILED;
398*da917039SDavid du Colombier return FAIL;
399*da917039SDavid du Colombier }
400*da917039SDavid du Colombier if(b->state == TRYBOOT)
401*da917039SDavid du Colombier return ENOUGH;
402*da917039SDavid du Colombier break;
403*da917039SDavid du Colombier
404*da917039SDavid du Colombier case TRYBOOT:
405*da917039SDavid du Colombier case READGZIP:
406*da917039SDavid du Colombier return ENOUGH;
407*da917039SDavid du Colombier
408*da917039SDavid du Colombier case READ9LOAD:
409*da917039SDavid du Colombier case INIT9LOAD:
410*da917039SDavid du Colombier panic("9load");
411*da917039SDavid du Colombier
412*da917039SDavid du Colombier default:
413*da917039SDavid du Colombier panic("bootstate");
414*da917039SDavid du Colombier }
415*da917039SDavid du Colombier }
416*da917039SDavid du Colombier return MORE;
417*da917039SDavid du Colombier
418*da917039SDavid du Colombier
419*da917039SDavid du Colombier Endofinput:
420*da917039SDavid du Colombier /* end of input */
421*da917039SDavid du Colombier switch(b->state) {
422*da917039SDavid du Colombier case INITKERNEL:
423*da917039SDavid du Colombier case READEXEC:
424*da917039SDavid du Colombier case READ9TEXT:
425*da917039SDavid du Colombier case READ9DATA:
426*da917039SDavid du Colombier case READEHDR:
427*da917039SDavid du Colombier case READPHDR:
428*da917039SDavid du Colombier case READEPAD:
429*da917039SDavid du Colombier case READEDATA:
430*da917039SDavid du Colombier print("premature EOF\n");
431*da917039SDavid du Colombier b->state = FAILED;
432*da917039SDavid du Colombier return FAIL;
433*da917039SDavid du Colombier
434*da917039SDavid du Colombier case TRYBOOT:
435*da917039SDavid du Colombier delay(100);
436*da917039SDavid du Colombier syncall();
437*da917039SDavid du Colombier entry = GLLONG(b->exec.entry);
438*da917039SDavid du Colombier dcflush(PADDR(entry), 4*1024*1024); /* HACK */
439*da917039SDavid du Colombier
440*da917039SDavid du Colombier sum((void *)PADDR(entry), length);
441*da917039SDavid du Colombier print("checksum: %#luX (on length %lud)\n", chksum, length);
442*da917039SDavid du Colombier
443*da917039SDavid du Colombier print("entry: 0x%lux\n", entry);
444*da917039SDavid du Colombier delay(20);
445*da917039SDavid du Colombier
446*da917039SDavid du Colombier cpuentry = entry; /* for second cpu's use */
447*da917039SDavid du Colombier coherence();
448*da917039SDavid du Colombier dcflush((uintptr)&cpuentry, sizeof cpuentry);
449*da917039SDavid du Colombier
450*da917039SDavid du Colombier warp9(PADDR(entry));
451*da917039SDavid du Colombier
452*da917039SDavid du Colombier b->state = FAILED;
453*da917039SDavid du Colombier return FAIL;
454*da917039SDavid du Colombier
455*da917039SDavid du Colombier case INIT9LOAD:
456*da917039SDavid du Colombier case READ9LOAD:
457*da917039SDavid du Colombier panic("end 9load");
458*da917039SDavid du Colombier
459*da917039SDavid du Colombier default:
460*da917039SDavid du Colombier panic("bootdone");
461*da917039SDavid du Colombier }
462*da917039SDavid du Colombier b->state = FAILED;
463*da917039SDavid du Colombier return FAIL;
464*da917039SDavid du Colombier }
465