1*74a4d8c2SCharles.Forsyth #include "u.h"
2*74a4d8c2SCharles.Forsyth #include "lib.h"
3*74a4d8c2SCharles.Forsyth #include "mem.h"
4*74a4d8c2SCharles.Forsyth #include "dat.h"
5*74a4d8c2SCharles.Forsyth #include "fns.h"
6*74a4d8c2SCharles.Forsyth
7*74a4d8c2SCharles.Forsyth char *premature = "premature EOF\n";
8*74a4d8c2SCharles.Forsyth
9*74a4d8c2SCharles.Forsyth /*
10*74a4d8c2SCharles.Forsyth * read in a segment
11*74a4d8c2SCharles.Forsyth */
12*74a4d8c2SCharles.Forsyth static long
readseg(int dev,long (* read)(int,void *,long),long len,long addr)13*74a4d8c2SCharles.Forsyth readseg(int dev, long (*read)(int, void*, long), long len, long addr)
14*74a4d8c2SCharles.Forsyth {
15*74a4d8c2SCharles.Forsyth char *a;
16*74a4d8c2SCharles.Forsyth long n, sofar;
17*74a4d8c2SCharles.Forsyth
18*74a4d8c2SCharles.Forsyth a = (char *)addr;
19*74a4d8c2SCharles.Forsyth for(sofar = 0; sofar < len; sofar += n){
20*74a4d8c2SCharles.Forsyth n = 8*1024;
21*74a4d8c2SCharles.Forsyth if(len - sofar < n)
22*74a4d8c2SCharles.Forsyth n = len - sofar;
23*74a4d8c2SCharles.Forsyth n = (*read)(dev, a + sofar, n);
24*74a4d8c2SCharles.Forsyth if(n <= 0)
25*74a4d8c2SCharles.Forsyth break;
26*74a4d8c2SCharles.Forsyth print(".");
27*74a4d8c2SCharles.Forsyth }
28*74a4d8c2SCharles.Forsyth return sofar;
29*74a4d8c2SCharles.Forsyth }
30*74a4d8c2SCharles.Forsyth
31*74a4d8c2SCharles.Forsyth /*
32*74a4d8c2SCharles.Forsyth * boot
33*74a4d8c2SCharles.Forsyth */
34*74a4d8c2SCharles.Forsyth int
plan9boot(int dev,long (* seek)(int,long),long (* read)(int,void *,long))35*74a4d8c2SCharles.Forsyth plan9boot(int dev, long (*seek)(int, long), long (*read)(int, void*, long))
36*74a4d8c2SCharles.Forsyth {
37*74a4d8c2SCharles.Forsyth long n;
38*74a4d8c2SCharles.Forsyth long addr;
39*74a4d8c2SCharles.Forsyth void (*b)(void);
40*74a4d8c2SCharles.Forsyth Exec *ep;
41*74a4d8c2SCharles.Forsyth
42*74a4d8c2SCharles.Forsyth if((*seek)(dev, 0) < 0)
43*74a4d8c2SCharles.Forsyth return -1;
44*74a4d8c2SCharles.Forsyth
45*74a4d8c2SCharles.Forsyth /*
46*74a4d8c2SCharles.Forsyth * read header
47*74a4d8c2SCharles.Forsyth */
48*74a4d8c2SCharles.Forsyth ep = (Exec *) ialloc(sizeof(Exec), 0);
49*74a4d8c2SCharles.Forsyth n = sizeof(Exec);
50*74a4d8c2SCharles.Forsyth if(readseg(dev, read, n, (long) ep) != n){
51*74a4d8c2SCharles.Forsyth print(premature);
52*74a4d8c2SCharles.Forsyth return -1;
53*74a4d8c2SCharles.Forsyth }
54*74a4d8c2SCharles.Forsyth if(GLLONG(ep->magic) != Q_MAGIC){
55*74a4d8c2SCharles.Forsyth print("bad magic 0x%lux not a plan 9 executable!\n", GLLONG(ep->magic));
56*74a4d8c2SCharles.Forsyth return -1;
57*74a4d8c2SCharles.Forsyth }
58*74a4d8c2SCharles.Forsyth
59*74a4d8c2SCharles.Forsyth /*
60*74a4d8c2SCharles.Forsyth * read text
61*74a4d8c2SCharles.Forsyth */
62*74a4d8c2SCharles.Forsyth addr = PADDR(GLLONG(ep->entry));
63*74a4d8c2SCharles.Forsyth n = GLLONG(ep->text);
64*74a4d8c2SCharles.Forsyth print("%d", n);
65*74a4d8c2SCharles.Forsyth if(readseg(dev, read, n, addr) != n){
66*74a4d8c2SCharles.Forsyth print(premature);
67*74a4d8c2SCharles.Forsyth return -1;
68*74a4d8c2SCharles.Forsyth }
69*74a4d8c2SCharles.Forsyth
70*74a4d8c2SCharles.Forsyth /*
71*74a4d8c2SCharles.Forsyth * read data (starts at first page after kernel)
72*74a4d8c2SCharles.Forsyth */
73*74a4d8c2SCharles.Forsyth addr = PGROUND(addr+n);
74*74a4d8c2SCharles.Forsyth n = GLLONG(ep->data);
75*74a4d8c2SCharles.Forsyth print("+%d@%8.8lux", n, addr);
76*74a4d8c2SCharles.Forsyth if(readseg(dev, read, n, addr) != n){
77*74a4d8c2SCharles.Forsyth print(premature);
78*74a4d8c2SCharles.Forsyth return -1;
79*74a4d8c2SCharles.Forsyth }
80*74a4d8c2SCharles.Forsyth
81*74a4d8c2SCharles.Forsyth /*
82*74a4d8c2SCharles.Forsyth * bss and entry point
83*74a4d8c2SCharles.Forsyth */
84*74a4d8c2SCharles.Forsyth print("+%d\nstart at 0x%lux\n", GLLONG(ep->bss), GLLONG(ep->entry));
85*74a4d8c2SCharles.Forsyth uartwait();
86*74a4d8c2SCharles.Forsyth scc2stop();
87*74a4d8c2SCharles.Forsyth splhi();
88*74a4d8c2SCharles.Forsyth
89*74a4d8c2SCharles.Forsyth /*
90*74a4d8c2SCharles.Forsyth * Go to new code. It's up to the program to get its PC relocated to
91*74a4d8c2SCharles.Forsyth * the right place.
92*74a4d8c2SCharles.Forsyth */
93*74a4d8c2SCharles.Forsyth b = (void (*)(void))(PADDR(GLLONG(ep->entry)));
94*74a4d8c2SCharles.Forsyth (*b)();
95*74a4d8c2SCharles.Forsyth return 0;
96*74a4d8c2SCharles.Forsyth }
97