xref: /inferno-os/os/boot/mpc/plan9boot.c (revision 74a4d8c26dd3c1e9febcb717cfd6cb6512991a7a)
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