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 #include "io.h"
7*74a4d8c2SCharles.Forsyth
8*74a4d8c2SCharles.Forsyth #include "dosfs.h"
9*74a4d8c2SCharles.Forsyth
10*74a4d8c2SCharles.Forsyth typedef struct Type Type;
11*74a4d8c2SCharles.Forsyth typedef struct Medium Medium;
12*74a4d8c2SCharles.Forsyth typedef struct Mode Mode;
13*74a4d8c2SCharles.Forsyth
14*74a4d8c2SCharles.Forsyth enum {
15*74a4d8c2SCharles.Forsyth Dany = -1,
16*74a4d8c2SCharles.Forsyth Nmedia = 16,
17*74a4d8c2SCharles.Forsyth
18*74a4d8c2SCharles.Forsyth /* DS1 switch options */
19*74a4d8c2SCharles.Forsyth Sflashfs = 1<<0, /* take local fs from flash */
20*74a4d8c2SCharles.Forsyth Snotflash = 1<<1, /* don't boot from flash */
21*74a4d8c2SCharles.Forsyth };
22*74a4d8c2SCharles.Forsyth
23*74a4d8c2SCharles.Forsyth enum { /* type */
24*74a4d8c2SCharles.Forsyth Tflash,
25*74a4d8c2SCharles.Forsyth Tuart,
26*74a4d8c2SCharles.Forsyth Tether,
27*74a4d8c2SCharles.Forsyth Thard,
28*74a4d8c2SCharles.Forsyth
29*74a4d8c2SCharles.Forsyth Tany = -1,
30*74a4d8c2SCharles.Forsyth };
31*74a4d8c2SCharles.Forsyth
32*74a4d8c2SCharles.Forsyth enum { /* flag and name */
33*74a4d8c2SCharles.Forsyth Fnone = 0x00,
34*74a4d8c2SCharles.Forsyth
35*74a4d8c2SCharles.Forsyth Fdos = 0x01,
36*74a4d8c2SCharles.Forsyth Ndos = 0x00,
37*74a4d8c2SCharles.Forsyth Fboot = 0x02,
38*74a4d8c2SCharles.Forsyth Nboot = 0x01,
39*74a4d8c2SCharles.Forsyth Fbootp = 0x04,
40*74a4d8c2SCharles.Forsyth Nbootp = 0x02,
41*74a4d8c2SCharles.Forsyth Fflash = 0x08,
42*74a4d8c2SCharles.Forsyth Fuart = 0x10,
43*74a4d8c2SCharles.Forsyth NName = 0x03,
44*74a4d8c2SCharles.Forsyth
45*74a4d8c2SCharles.Forsyth Fany = Fbootp|Fboot|Fdos|Fflash|Fuart,
46*74a4d8c2SCharles.Forsyth
47*74a4d8c2SCharles.Forsyth Fini = 0x10,
48*74a4d8c2SCharles.Forsyth Fprobe = 0x80,
49*74a4d8c2SCharles.Forsyth };
50*74a4d8c2SCharles.Forsyth
51*74a4d8c2SCharles.Forsyth enum { /* mode */
52*74a4d8c2SCharles.Forsyth Mauto = 0x00,
53*74a4d8c2SCharles.Forsyth Mlocal = 0x01,
54*74a4d8c2SCharles.Forsyth Manual = 0x02,
55*74a4d8c2SCharles.Forsyth NMode = 0x03,
56*74a4d8c2SCharles.Forsyth };
57*74a4d8c2SCharles.Forsyth
58*74a4d8c2SCharles.Forsyth typedef struct Type {
59*74a4d8c2SCharles.Forsyth int type;
60*74a4d8c2SCharles.Forsyth char *cname;
61*74a4d8c2SCharles.Forsyth int flag;
62*74a4d8c2SCharles.Forsyth int (*init)(void);
63*74a4d8c2SCharles.Forsyth long (*read)(int, void*, long);
64*74a4d8c2SCharles.Forsyth long (*seek)(int, long);
65*74a4d8c2SCharles.Forsyth Partition* (*setpart)(int, char*);
66*74a4d8c2SCharles.Forsyth char* name[NName];
67*74a4d8c2SCharles.Forsyth
68*74a4d8c2SCharles.Forsyth int mask;
69*74a4d8c2SCharles.Forsyth Medium* media;
70*74a4d8c2SCharles.Forsyth } Type;
71*74a4d8c2SCharles.Forsyth
72*74a4d8c2SCharles.Forsyth typedef struct Medium {
73*74a4d8c2SCharles.Forsyth Type* type;
74*74a4d8c2SCharles.Forsyth int flag;
75*74a4d8c2SCharles.Forsyth Partition* partition;
76*74a4d8c2SCharles.Forsyth Dos;
77*74a4d8c2SCharles.Forsyth
78*74a4d8c2SCharles.Forsyth Medium* next;
79*74a4d8c2SCharles.Forsyth } Medium;
80*74a4d8c2SCharles.Forsyth
81*74a4d8c2SCharles.Forsyth typedef struct Mode {
82*74a4d8c2SCharles.Forsyth char* name;
83*74a4d8c2SCharles.Forsyth int mode;
84*74a4d8c2SCharles.Forsyth } Mode;
85*74a4d8c2SCharles.Forsyth
86*74a4d8c2SCharles.Forsyth static Type types[] = {
87*74a4d8c2SCharles.Forsyth { Tflash, "flash",
88*74a4d8c2SCharles.Forsyth Fflash,
89*74a4d8c2SCharles.Forsyth flashinit, 0, 0, 0,
90*74a4d8c2SCharles.Forsyth { 0, "F", 0, }
91*74a4d8c2SCharles.Forsyth },
92*74a4d8c2SCharles.Forsyth /*
93*74a4d8c2SCharles.Forsyth { Tuart, "uart",
94*74a4d8c2SCharles.Forsyth Fuart|Fboot,
95*74a4d8c2SCharles.Forsyth uartinit, uartread, uartseek, setuartpart,
96*74a4d8c2SCharles.Forsyth { 0, "u", 0, }
97*74a4d8c2SCharles.Forsyth },
98*74a4d8c2SCharles.Forsyth */
99*74a4d8c2SCharles.Forsyth { Tether, "ether",
100*74a4d8c2SCharles.Forsyth Fbootp,
101*74a4d8c2SCharles.Forsyth etherinit, 0, 0, 0,
102*74a4d8c2SCharles.Forsyth { 0, 0, "e", },
103*74a4d8c2SCharles.Forsyth },
104*74a4d8c2SCharles.Forsyth { Thard, "ata",
105*74a4d8c2SCharles.Forsyth Fini|Fboot|Fdos,
106*74a4d8c2SCharles.Forsyth 0, 0, 0, 0, /* not used now, will be later with PCMCIA */
107*74a4d8c2SCharles.Forsyth { "hd", "h", 0, },
108*74a4d8c2SCharles.Forsyth },
109*74a4d8c2SCharles.Forsyth {-1},
110*74a4d8c2SCharles.Forsyth };
111*74a4d8c2SCharles.Forsyth
112*74a4d8c2SCharles.Forsyth static Medium media[Nmedia];
113*74a4d8c2SCharles.Forsyth static Medium *curmedium = media;
114*74a4d8c2SCharles.Forsyth
115*74a4d8c2SCharles.Forsyth static Mode modes[NMode+1] = {
116*74a4d8c2SCharles.Forsyth [Mauto] { "auto", Mauto, },
117*74a4d8c2SCharles.Forsyth [Mlocal] { "local", Mlocal, },
118*74a4d8c2SCharles.Forsyth [Manual] { "manual", Manual, },
119*74a4d8c2SCharles.Forsyth };
120*74a4d8c2SCharles.Forsyth
121*74a4d8c2SCharles.Forsyth static char *inis[] = {
122*74a4d8c2SCharles.Forsyth "inferno/inferno.ini",
123*74a4d8c2SCharles.Forsyth "inferno.ini",
124*74a4d8c2SCharles.Forsyth "plan9/plan9.ini",
125*74a4d8c2SCharles.Forsyth "plan9.ini",
126*74a4d8c2SCharles.Forsyth 0,
127*74a4d8c2SCharles.Forsyth };
128*74a4d8c2SCharles.Forsyth char **ini;
129*74a4d8c2SCharles.Forsyth int predawn;
130*74a4d8c2SCharles.Forsyth
131*74a4d8c2SCharles.Forsyth static int
parse(char * line,int * type,int * flag,int * dev,char * file)132*74a4d8c2SCharles.Forsyth parse(char *line, int *type, int *flag, int *dev, char *file)
133*74a4d8c2SCharles.Forsyth {
134*74a4d8c2SCharles.Forsyth Type *tp;
135*74a4d8c2SCharles.Forsyth char buf[2*NAMELEN], *v[4], *p;
136*74a4d8c2SCharles.Forsyth int i;
137*74a4d8c2SCharles.Forsyth
138*74a4d8c2SCharles.Forsyth strcpy(buf, line);
139*74a4d8c2SCharles.Forsyth switch(getcfields(buf, v, 4, "!")){
140*74a4d8c2SCharles.Forsyth
141*74a4d8c2SCharles.Forsyth case 3:
142*74a4d8c2SCharles.Forsyth break;
143*74a4d8c2SCharles.Forsyth
144*74a4d8c2SCharles.Forsyth case 2:
145*74a4d8c2SCharles.Forsyth v[2] = "";
146*74a4d8c2SCharles.Forsyth break;
147*74a4d8c2SCharles.Forsyth
148*74a4d8c2SCharles.Forsyth default:
149*74a4d8c2SCharles.Forsyth return 0;
150*74a4d8c2SCharles.Forsyth }
151*74a4d8c2SCharles.Forsyth
152*74a4d8c2SCharles.Forsyth *flag = 0;
153*74a4d8c2SCharles.Forsyth for(tp = types; tp->cname; tp++){
154*74a4d8c2SCharles.Forsyth for(i = 0; i < NName; i++){
155*74a4d8c2SCharles.Forsyth
156*74a4d8c2SCharles.Forsyth if(tp->name[i] == 0 || strcmp(v[0], tp->name[i]))
157*74a4d8c2SCharles.Forsyth continue;
158*74a4d8c2SCharles.Forsyth *type = tp->type;
159*74a4d8c2SCharles.Forsyth *flag |= 1<<i;
160*74a4d8c2SCharles.Forsyth
161*74a4d8c2SCharles.Forsyth if((*dev = strtoul(v[1], &p, 0)) == 0 && p == v[1])
162*74a4d8c2SCharles.Forsyth return 0;
163*74a4d8c2SCharles.Forsyth
164*74a4d8c2SCharles.Forsyth strcpy(file, v[2]);
165*74a4d8c2SCharles.Forsyth
166*74a4d8c2SCharles.Forsyth return 1;
167*74a4d8c2SCharles.Forsyth }
168*74a4d8c2SCharles.Forsyth }
169*74a4d8c2SCharles.Forsyth
170*74a4d8c2SCharles.Forsyth return 0;
171*74a4d8c2SCharles.Forsyth
172*74a4d8c2SCharles.Forsyth }
173*74a4d8c2SCharles.Forsyth
174*74a4d8c2SCharles.Forsyth static int
boot(Medium * mp,int flag,char * file)175*74a4d8c2SCharles.Forsyth boot(Medium *mp, int flag, char *file)
176*74a4d8c2SCharles.Forsyth {
177*74a4d8c2SCharles.Forsyth Dosfile df;
178*74a4d8c2SCharles.Forsyth char ixdos[128], *p;
179*74a4d8c2SCharles.Forsyth int r;
180*74a4d8c2SCharles.Forsyth
181*74a4d8c2SCharles.Forsyth uartsetboot(0);
182*74a4d8c2SCharles.Forsyth if(flag & Fbootp){
183*74a4d8c2SCharles.Forsyth sprint(BOOTLINE, "%s!%d", mp->type->name[Nbootp], mp->dev);
184*74a4d8c2SCharles.Forsyth return bootp(mp->dev, file);
185*74a4d8c2SCharles.Forsyth }
186*74a4d8c2SCharles.Forsyth
187*74a4d8c2SCharles.Forsyth if(flag & Fflash){
188*74a4d8c2SCharles.Forsyth if(mp->flag & Fflash && flashbootable(0))
189*74a4d8c2SCharles.Forsyth flashboot(mp->dev);
190*74a4d8c2SCharles.Forsyth }
191*74a4d8c2SCharles.Forsyth
192*74a4d8c2SCharles.Forsyth if(flag & Fboot){
193*74a4d8c2SCharles.Forsyth
194*74a4d8c2SCharles.Forsyth if(mp->flag & Fini){
195*74a4d8c2SCharles.Forsyth (*mp->type->setpart)(mp->dev, "disk");
196*74a4d8c2SCharles.Forsyth plan9ini(mp, nil);
197*74a4d8c2SCharles.Forsyth }
198*74a4d8c2SCharles.Forsyth if(file == 0 || *file == 0)
199*74a4d8c2SCharles.Forsyth file = mp->partition->name;
200*74a4d8c2SCharles.Forsyth (*mp->type->setpart)(mp->dev, file);
201*74a4d8c2SCharles.Forsyth sprint(BOOTLINE, "%s!%d!%s", mp->type->name[Nboot], mp->dev, file);
202*74a4d8c2SCharles.Forsyth r = plan9boot(mp->dev, mp->seek, mp->read);
203*74a4d8c2SCharles.Forsyth uartsetboot(0);
204*74a4d8c2SCharles.Forsyth return r;
205*74a4d8c2SCharles.Forsyth }
206*74a4d8c2SCharles.Forsyth
207*74a4d8c2SCharles.Forsyth if(flag & Fdos){
208*74a4d8c2SCharles.Forsyth if(mp->type->setpart)
209*74a4d8c2SCharles.Forsyth (*mp->type->setpart)(mp->dev, "disk");
210*74a4d8c2SCharles.Forsyth if(mp->flag & Fini)
211*74a4d8c2SCharles.Forsyth plan9ini(mp, nil);
212*74a4d8c2SCharles.Forsyth if(file == 0 || *file == 0){
213*74a4d8c2SCharles.Forsyth strcpy(ixdos, *ini);
214*74a4d8c2SCharles.Forsyth if(p = strrchr(ixdos, '/'))
215*74a4d8c2SCharles.Forsyth p++;
216*74a4d8c2SCharles.Forsyth else
217*74a4d8c2SCharles.Forsyth p = ixdos;
218*74a4d8c2SCharles.Forsyth strcpy(p, "impc");
219*74a4d8c2SCharles.Forsyth if(dosstat(mp, ixdos, &df) <= 0)
220*74a4d8c2SCharles.Forsyth return -1;
221*74a4d8c2SCharles.Forsyth }
222*74a4d8c2SCharles.Forsyth else
223*74a4d8c2SCharles.Forsyth strcpy(ixdos, file);
224*74a4d8c2SCharles.Forsyth sprint(BOOTLINE, "%s!%d!%s", mp->type->name[Ndos], mp->dev, ixdos);
225*74a4d8c2SCharles.Forsyth return dosboot(mp, ixdos);
226*74a4d8c2SCharles.Forsyth }
227*74a4d8c2SCharles.Forsyth
228*74a4d8c2SCharles.Forsyth return -1;
229*74a4d8c2SCharles.Forsyth }
230*74a4d8c2SCharles.Forsyth
231*74a4d8c2SCharles.Forsyth static Medium*
allocm(Type * tp)232*74a4d8c2SCharles.Forsyth allocm(Type *tp)
233*74a4d8c2SCharles.Forsyth {
234*74a4d8c2SCharles.Forsyth Medium **l;
235*74a4d8c2SCharles.Forsyth
236*74a4d8c2SCharles.Forsyth if(curmedium >= &media[Nmedia])
237*74a4d8c2SCharles.Forsyth return 0;
238*74a4d8c2SCharles.Forsyth
239*74a4d8c2SCharles.Forsyth for(l = &tp->media; *l; l = &(*l)->next)
240*74a4d8c2SCharles.Forsyth ;
241*74a4d8c2SCharles.Forsyth *l = curmedium++;
242*74a4d8c2SCharles.Forsyth return *l;
243*74a4d8c2SCharles.Forsyth }
244*74a4d8c2SCharles.Forsyth
245*74a4d8c2SCharles.Forsyth Medium*
probe(int type,int flag,int dev)246*74a4d8c2SCharles.Forsyth probe(int type, int flag, int dev)
247*74a4d8c2SCharles.Forsyth {
248*74a4d8c2SCharles.Forsyth Type *tp;
249*74a4d8c2SCharles.Forsyth int dombr, i, start;
250*74a4d8c2SCharles.Forsyth Medium *mp;
251*74a4d8c2SCharles.Forsyth Dosfile df;
252*74a4d8c2SCharles.Forsyth Partition *pp;
253*74a4d8c2SCharles.Forsyth
254*74a4d8c2SCharles.Forsyth for(tp = types; tp->cname; tp++){
255*74a4d8c2SCharles.Forsyth if(type != Tany && type != tp->type || tp->init == 0)
256*74a4d8c2SCharles.Forsyth continue;
257*74a4d8c2SCharles.Forsyth
258*74a4d8c2SCharles.Forsyth if(flag != Fnone){
259*74a4d8c2SCharles.Forsyth for(mp = tp->media; mp; mp = mp->next){
260*74a4d8c2SCharles.Forsyth if((flag & mp->flag) && (dev == Dany || dev == mp->dev))
261*74a4d8c2SCharles.Forsyth return mp;
262*74a4d8c2SCharles.Forsyth }
263*74a4d8c2SCharles.Forsyth }
264*74a4d8c2SCharles.Forsyth if((tp->flag & Fprobe) == 0){
265*74a4d8c2SCharles.Forsyth tp->flag |= Fprobe;
266*74a4d8c2SCharles.Forsyth tp->mask = (*tp->init)();
267*74a4d8c2SCharles.Forsyth }
268*74a4d8c2SCharles.Forsyth
269*74a4d8c2SCharles.Forsyth for(i = 0; tp->mask; i++){
270*74a4d8c2SCharles.Forsyth if((tp->mask & (1<<i)) == 0)
271*74a4d8c2SCharles.Forsyth continue;
272*74a4d8c2SCharles.Forsyth tp->mask &= ~(1<<i);
273*74a4d8c2SCharles.Forsyth
274*74a4d8c2SCharles.Forsyth if((mp = allocm(tp)) == 0)
275*74a4d8c2SCharles.Forsyth continue;
276*74a4d8c2SCharles.Forsyth
277*74a4d8c2SCharles.Forsyth mp->dev = i;
278*74a4d8c2SCharles.Forsyth mp->flag = tp->flag;
279*74a4d8c2SCharles.Forsyth mp->seek = tp->seek;
280*74a4d8c2SCharles.Forsyth mp->read = tp->read;
281*74a4d8c2SCharles.Forsyth mp->type = tp;
282*74a4d8c2SCharles.Forsyth
283*74a4d8c2SCharles.Forsyth if(mp->flag & Fboot){
284*74a4d8c2SCharles.Forsyth if((mp->partition = (*tp->setpart)(i, "boot")) == 0)
285*74a4d8c2SCharles.Forsyth mp->flag &= ~Fboot;
286*74a4d8c2SCharles.Forsyth if((mp->flag & (Fflash|Fuart)) == 0)
287*74a4d8c2SCharles.Forsyth (*tp->setpart)(i, "disk");
288*74a4d8c2SCharles.Forsyth }
289*74a4d8c2SCharles.Forsyth
290*74a4d8c2SCharles.Forsyth if(mp->flag & Fdos){
291*74a4d8c2SCharles.Forsyth start = 0;
292*74a4d8c2SCharles.Forsyth dombr = 1;
293*74a4d8c2SCharles.Forsyth if(mp->type->setpart){
294*74a4d8c2SCharles.Forsyth if(pp = (*mp->type->setpart)(i, "dos")){
295*74a4d8c2SCharles.Forsyth if(start = pp->start)
296*74a4d8c2SCharles.Forsyth dombr = 0;
297*74a4d8c2SCharles.Forsyth }
298*74a4d8c2SCharles.Forsyth (*tp->setpart)(i, "disk");
299*74a4d8c2SCharles.Forsyth }
300*74a4d8c2SCharles.Forsyth if(dosinit(mp, start, dombr) < 0)
301*74a4d8c2SCharles.Forsyth mp->flag &= ~(Fini|Fdos);
302*74a4d8c2SCharles.Forsyth else
303*74a4d8c2SCharles.Forsyth print("dos init failed\n");
304*74a4d8c2SCharles.Forsyth }
305*74a4d8c2SCharles.Forsyth
306*74a4d8c2SCharles.Forsyth if(mp->flag & Fini){
307*74a4d8c2SCharles.Forsyth mp->flag &= ~Fini;
308*74a4d8c2SCharles.Forsyth for(ini = inis; *ini; ini++){
309*74a4d8c2SCharles.Forsyth if(dosstat(mp, *ini, &df) <= 0)
310*74a4d8c2SCharles.Forsyth continue;
311*74a4d8c2SCharles.Forsyth mp->flag |= Fini;
312*74a4d8c2SCharles.Forsyth break;
313*74a4d8c2SCharles.Forsyth }
314*74a4d8c2SCharles.Forsyth }
315*74a4d8c2SCharles.Forsyth
316*74a4d8c2SCharles.Forsyth if((flag & mp->flag) && (dev == Dany || dev == i))
317*74a4d8c2SCharles.Forsyth return mp;
318*74a4d8c2SCharles.Forsyth }
319*74a4d8c2SCharles.Forsyth }
320*74a4d8c2SCharles.Forsyth
321*74a4d8c2SCharles.Forsyth return 0;
322*74a4d8c2SCharles.Forsyth }
323*74a4d8c2SCharles.Forsyth
324*74a4d8c2SCharles.Forsyth void
main(void)325*74a4d8c2SCharles.Forsyth main(void)
326*74a4d8c2SCharles.Forsyth {
327*74a4d8c2SCharles.Forsyth Medium *mp;
328*74a4d8c2SCharles.Forsyth int dev, flag, i, mode, tried, type, options;
329*74a4d8c2SCharles.Forsyth char def[2*NAMELEN], file[2*NAMELEN], line[80], *p;
330*74a4d8c2SCharles.Forsyth Type *tp;
331*74a4d8c2SCharles.Forsyth
332*74a4d8c2SCharles.Forsyth machinit();
333*74a4d8c2SCharles.Forsyth archinit();
334*74a4d8c2SCharles.Forsyth meminit();
335*74a4d8c2SCharles.Forsyth cpminit();
336*74a4d8c2SCharles.Forsyth trapinit();
337*74a4d8c2SCharles.Forsyth consinit(); /* screen and keyboard initially */
338*74a4d8c2SCharles.Forsyth /* screeninit(); */
339*74a4d8c2SCharles.Forsyth cpuidprint();
340*74a4d8c2SCharles.Forsyth alarminit();
341*74a4d8c2SCharles.Forsyth clockinit();
342*74a4d8c2SCharles.Forsyth print("predawn\n");
343*74a4d8c2SCharles.Forsyth predawn = 0;
344*74a4d8c2SCharles.Forsyth spllo();
345*74a4d8c2SCharles.Forsyth print("dawn\n");
346*74a4d8c2SCharles.Forsyth options = archoptionsw();
347*74a4d8c2SCharles.Forsyth print("options=#%ux\n", options);
348*74a4d8c2SCharles.Forsyth
349*74a4d8c2SCharles.Forsyth mp = 0;
350*74a4d8c2SCharles.Forsyth for(tp = types; tp->cname; tp++){
351*74a4d8c2SCharles.Forsyth if(tp->type == Tether)
352*74a4d8c2SCharles.Forsyth continue;
353*74a4d8c2SCharles.Forsyth if((mp = probe(tp->type, Fini, Dany)) && (mp->flag & Fini)){
354*74a4d8c2SCharles.Forsyth plan9ini(mp, nil);
355*74a4d8c2SCharles.Forsyth break;
356*74a4d8c2SCharles.Forsyth }
357*74a4d8c2SCharles.Forsyth }
358*74a4d8c2SCharles.Forsyth
359*74a4d8c2SCharles.Forsyth if(mp == 0 || (mp->flag & Fini) == 0)
360*74a4d8c2SCharles.Forsyth plan9ini(nil, flashconfig(0));
361*74a4d8c2SCharles.Forsyth
362*74a4d8c2SCharles.Forsyth //consinit(); /* establish new console location */
363*74a4d8c2SCharles.Forsyth
364*74a4d8c2SCharles.Forsyth if((options & Snotflash) == 0 && flashbootable(0)){
365*74a4d8c2SCharles.Forsyth print("Flash boot\n");
366*74a4d8c2SCharles.Forsyth flashboot(0);
367*74a4d8c2SCharles.Forsyth }
368*74a4d8c2SCharles.Forsyth
369*74a4d8c2SCharles.Forsyth tried = 0;
370*74a4d8c2SCharles.Forsyth mode = Mauto;
371*74a4d8c2SCharles.Forsyth p = getconf("bootfile");
372*74a4d8c2SCharles.Forsyth flag = 0;
373*74a4d8c2SCharles.Forsyth
374*74a4d8c2SCharles.Forsyth if(p != 0) {
375*74a4d8c2SCharles.Forsyth mode = Manual;
376*74a4d8c2SCharles.Forsyth for(i = 0; i < NMode; i++){
377*74a4d8c2SCharles.Forsyth if(strcmp(p, modes[i].name) == 0){
378*74a4d8c2SCharles.Forsyth mode = modes[i].mode;
379*74a4d8c2SCharles.Forsyth goto done;
380*74a4d8c2SCharles.Forsyth }
381*74a4d8c2SCharles.Forsyth }
382*74a4d8c2SCharles.Forsyth if(parse(p, &type, &flag, &dev, file) == 0) {
383*74a4d8c2SCharles.Forsyth print("Bad bootfile syntax: %s\n", p);
384*74a4d8c2SCharles.Forsyth goto done;
385*74a4d8c2SCharles.Forsyth }
386*74a4d8c2SCharles.Forsyth mp = probe(type, flag, dev);
387*74a4d8c2SCharles.Forsyth if(mp == 0) {
388*74a4d8c2SCharles.Forsyth print("Cannot access device: %s\n", p);
389*74a4d8c2SCharles.Forsyth goto done;
390*74a4d8c2SCharles.Forsyth }
391*74a4d8c2SCharles.Forsyth tried = boot(mp, flag, file);
392*74a4d8c2SCharles.Forsyth }
393*74a4d8c2SCharles.Forsyth done:
394*74a4d8c2SCharles.Forsyth if(tried == 0 && mode != Manual){
395*74a4d8c2SCharles.Forsyth flag = Fany;
396*74a4d8c2SCharles.Forsyth if(mode == Mlocal)
397*74a4d8c2SCharles.Forsyth flag &= ~Fbootp;
398*74a4d8c2SCharles.Forsyth if(options & Snotflash)
399*74a4d8c2SCharles.Forsyth flag &= ~Fflash;
400*74a4d8c2SCharles.Forsyth if((mp = probe(Tany, flag, Dany)) != 0)
401*74a4d8c2SCharles.Forsyth boot(mp, flag & mp->flag, 0);
402*74a4d8c2SCharles.Forsyth }
403*74a4d8c2SCharles.Forsyth
404*74a4d8c2SCharles.Forsyth def[0] = 0;
405*74a4d8c2SCharles.Forsyth probe(Tany, Fnone, Dany);
406*74a4d8c2SCharles.Forsyth
407*74a4d8c2SCharles.Forsyth flag = 0;
408*74a4d8c2SCharles.Forsyth for(tp = types; tp->cname; tp++){
409*74a4d8c2SCharles.Forsyth for(mp = tp->media; mp; mp = mp->next){
410*74a4d8c2SCharles.Forsyth if(flag == 0){
411*74a4d8c2SCharles.Forsyth flag = 1;
412*74a4d8c2SCharles.Forsyth print("Boot devices:");
413*74a4d8c2SCharles.Forsyth }
414*74a4d8c2SCharles.Forsyth
415*74a4d8c2SCharles.Forsyth if(mp->flag & Fbootp)
416*74a4d8c2SCharles.Forsyth print(" %s!%d", mp->type->name[Nbootp], mp->dev);
417*74a4d8c2SCharles.Forsyth if(mp->flag & Fdos)
418*74a4d8c2SCharles.Forsyth print(" %s!%d", mp->type->name[Ndos], mp->dev);
419*74a4d8c2SCharles.Forsyth if(mp->flag & (Fflash|Fuart) || mp->flag & Fboot)
420*74a4d8c2SCharles.Forsyth print(" %s!%d", mp->type->name[Nboot], mp->dev);
421*74a4d8c2SCharles.Forsyth }
422*74a4d8c2SCharles.Forsyth }
423*74a4d8c2SCharles.Forsyth if(flag)
424*74a4d8c2SCharles.Forsyth print("\n");
425*74a4d8c2SCharles.Forsyth
426*74a4d8c2SCharles.Forsyth for(;;){
427*74a4d8c2SCharles.Forsyth if(getstr("boot from", line, sizeof(line), def) >= 0){
428*74a4d8c2SCharles.Forsyth if(parse(line, &type, &flag, &dev, file)){
429*74a4d8c2SCharles.Forsyth if(mp = probe(type, flag, dev))
430*74a4d8c2SCharles.Forsyth boot(mp, flag, file);
431*74a4d8c2SCharles.Forsyth }
432*74a4d8c2SCharles.Forsyth }
433*74a4d8c2SCharles.Forsyth def[0] = 0;
434*74a4d8c2SCharles.Forsyth }
435*74a4d8c2SCharles.Forsyth }
436*74a4d8c2SCharles.Forsyth
437*74a4d8c2SCharles.Forsyth void
machinit(void)438*74a4d8c2SCharles.Forsyth machinit(void)
439*74a4d8c2SCharles.Forsyth {
440*74a4d8c2SCharles.Forsyth memset(m, 0, sizeof(*m));
441*74a4d8c2SCharles.Forsyth m->delayloop = 20000;
442*74a4d8c2SCharles.Forsyth m->cpupvr = getpvr();
443*74a4d8c2SCharles.Forsyth m->iomem = KADDR(INTMEM);
444*74a4d8c2SCharles.Forsyth }
445*74a4d8c2SCharles.Forsyth
446*74a4d8c2SCharles.Forsyth int
getcfields(char * lp,char ** fields,int n,char * sep)447*74a4d8c2SCharles.Forsyth getcfields(char* lp, char** fields, int n, char* sep)
448*74a4d8c2SCharles.Forsyth {
449*74a4d8c2SCharles.Forsyth int i;
450*74a4d8c2SCharles.Forsyth
451*74a4d8c2SCharles.Forsyth for(i = 0; lp && *lp && i < n; i++){
452*74a4d8c2SCharles.Forsyth while(*lp && strchr(sep, *lp) != 0)
453*74a4d8c2SCharles.Forsyth *lp++ = 0;
454*74a4d8c2SCharles.Forsyth if(*lp == 0)
455*74a4d8c2SCharles.Forsyth break;
456*74a4d8c2SCharles.Forsyth fields[i] = lp;
457*74a4d8c2SCharles.Forsyth while(*lp && strchr(sep, *lp) == 0){
458*74a4d8c2SCharles.Forsyth if(*lp == '\\' && *(lp+1) == '\n')
459*74a4d8c2SCharles.Forsyth *lp++ = ' ';
460*74a4d8c2SCharles.Forsyth lp++;
461*74a4d8c2SCharles.Forsyth }
462*74a4d8c2SCharles.Forsyth }
463*74a4d8c2SCharles.Forsyth
464*74a4d8c2SCharles.Forsyth return i;
465*74a4d8c2SCharles.Forsyth }
466*74a4d8c2SCharles.Forsyth
467*74a4d8c2SCharles.Forsyth static Map memv[512];
468*74a4d8c2SCharles.Forsyth static RMap rammap = {"physical memory"};
469*74a4d8c2SCharles.Forsyth
470*74a4d8c2SCharles.Forsyth void
meminit(void)471*74a4d8c2SCharles.Forsyth meminit(void)
472*74a4d8c2SCharles.Forsyth {
473*74a4d8c2SCharles.Forsyth ulong e;
474*74a4d8c2SCharles.Forsyth
475*74a4d8c2SCharles.Forsyth mapinit(&rammap, memv, sizeof(memv));
476*74a4d8c2SCharles.Forsyth e = PADDR(&end);
477*74a4d8c2SCharles.Forsyth mapfree(&rammap, e, 4*1024*1024-e); /* fixed 4Mbytes is plenty for bootstrap */
478*74a4d8c2SCharles.Forsyth }
479*74a4d8c2SCharles.Forsyth
480*74a4d8c2SCharles.Forsyth void*
ialloc(ulong n,int align)481*74a4d8c2SCharles.Forsyth ialloc(ulong n, int align)
482*74a4d8c2SCharles.Forsyth {
483*74a4d8c2SCharles.Forsyth ulong a;
484*74a4d8c2SCharles.Forsyth int s;
485*74a4d8c2SCharles.Forsyth
486*74a4d8c2SCharles.Forsyth if(align <= 0)
487*74a4d8c2SCharles.Forsyth align = 4;
488*74a4d8c2SCharles.Forsyth s = splhi();
489*74a4d8c2SCharles.Forsyth a = mapalloc(&rammap, 0, n, align);
490*74a4d8c2SCharles.Forsyth splx(s);
491*74a4d8c2SCharles.Forsyth if(a == 0)
492*74a4d8c2SCharles.Forsyth panic("ialloc");
493*74a4d8c2SCharles.Forsyth return memset(KADDR(a), 0, n);
494*74a4d8c2SCharles.Forsyth }
495*74a4d8c2SCharles.Forsyth
496*74a4d8c2SCharles.Forsyth void*
malloc(ulong n)497*74a4d8c2SCharles.Forsyth malloc(ulong n)
498*74a4d8c2SCharles.Forsyth {
499*74a4d8c2SCharles.Forsyth ulong *p;
500*74a4d8c2SCharles.Forsyth
501*74a4d8c2SCharles.Forsyth n = ((n+sizeof(int)-1)&~(sizeof(int)-1))+2*sizeof(int);
502*74a4d8c2SCharles.Forsyth p = ialloc(n, sizeof(int));
503*74a4d8c2SCharles.Forsyth *p++ = 0xcafebeef;
504*74a4d8c2SCharles.Forsyth *p++ = n;
505*74a4d8c2SCharles.Forsyth return p;
506*74a4d8c2SCharles.Forsyth }
507*74a4d8c2SCharles.Forsyth
508*74a4d8c2SCharles.Forsyth void
free(void * ap)509*74a4d8c2SCharles.Forsyth free(void *ap)
510*74a4d8c2SCharles.Forsyth {
511*74a4d8c2SCharles.Forsyth int s;
512*74a4d8c2SCharles.Forsyth ulong *p;
513*74a4d8c2SCharles.Forsyth
514*74a4d8c2SCharles.Forsyth p = ap;
515*74a4d8c2SCharles.Forsyth if(p){
516*74a4d8c2SCharles.Forsyth if(*(p -= 2) != 0xcafebeef)
517*74a4d8c2SCharles.Forsyth panic("free");
518*74a4d8c2SCharles.Forsyth s = splhi();
519*74a4d8c2SCharles.Forsyth mapfree(&rammap, (ulong)p, p[1]);
520*74a4d8c2SCharles.Forsyth splx(s);
521*74a4d8c2SCharles.Forsyth }
522*74a4d8c2SCharles.Forsyth }
523*74a4d8c2SCharles.Forsyth
524*74a4d8c2SCharles.Forsyth void
sched(void)525*74a4d8c2SCharles.Forsyth sched(void)
526*74a4d8c2SCharles.Forsyth {
527*74a4d8c2SCharles.Forsyth }
528