174a4d8c2SCharles.Forsyth #include "u.h"
274a4d8c2SCharles.Forsyth #include "lib.h"
374a4d8c2SCharles.Forsyth #include "mem.h"
474a4d8c2SCharles.Forsyth #include "dat.h"
574a4d8c2SCharles.Forsyth #include "fns.h"
674a4d8c2SCharles.Forsyth #include "io.h"
7*8a8c2d74SCharles.Forsyth #include "sd.h"
874a4d8c2SCharles.Forsyth #include "fs.h"
974a4d8c2SCharles.Forsyth
10*8a8c2d74SCharles.Forsyth #ifndef VERBOSE
11*8a8c2d74SCharles.Forsyth #define VERBOSE 0
12*8a8c2d74SCharles.Forsyth #endif
13*8a8c2d74SCharles.Forsyth
14*8a8c2d74SCharles.Forsyth /*
15*8a8c2d74SCharles.Forsyth * "cache" must be in this list so that 9load will pass the definition of
16*8a8c2d74SCharles.Forsyth * the cache partition into the kernel so that the disk named by the `cfs'
17*8a8c2d74SCharles.Forsyth * variable in plan9.ini can be seen in all circumstances before termrc
18*8a8c2d74SCharles.Forsyth * sets up all the disk partitions. In particular, if it's on an odd-ball
19*8a8c2d74SCharles.Forsyth * disk like sd10 rather than sdC0, this is needed.
20*8a8c2d74SCharles.Forsyth */
21*8a8c2d74SCharles.Forsyth static char *diskparts[] = {
22*8a8c2d74SCharles.Forsyth "dos", "9fat", "fs", "data", "cdboot", "cache", 0
23*8a8c2d74SCharles.Forsyth };
2474a4d8c2SCharles.Forsyth static char *etherparts[] = { "*", 0 };
2574a4d8c2SCharles.Forsyth
2674a4d8c2SCharles.Forsyth static char *diskinis[] = {
2774a4d8c2SCharles.Forsyth "plan9/plan9.ini",
2874a4d8c2SCharles.Forsyth "plan9.ini",
2974a4d8c2SCharles.Forsyth 0
3074a4d8c2SCharles.Forsyth };
3174a4d8c2SCharles.Forsyth static char *etherinis[] = {
3274a4d8c2SCharles.Forsyth "/cfg/pxe/%E",
3374a4d8c2SCharles.Forsyth 0
3474a4d8c2SCharles.Forsyth };
3574a4d8c2SCharles.Forsyth
36*8a8c2d74SCharles.Forsyth /* ordering: devbios must be called before devsd calls sdbios */
3774a4d8c2SCharles.Forsyth Type types[] = {
3874a4d8c2SCharles.Forsyth { Tfloppy,
3974a4d8c2SCharles.Forsyth Fini|Ffs,
4074a4d8c2SCharles.Forsyth floppyinit, floppyinitdev,
4174a4d8c2SCharles.Forsyth floppygetfspart, 0, floppyboot,
4274a4d8c2SCharles.Forsyth floppyprintdevs,
4374a4d8c2SCharles.Forsyth diskparts,
4474a4d8c2SCharles.Forsyth diskinis,
4574a4d8c2SCharles.Forsyth },
4674a4d8c2SCharles.Forsyth { Tether,
4774a4d8c2SCharles.Forsyth Fini|Fbootp,
4874a4d8c2SCharles.Forsyth etherinit, etherinitdev,
4974a4d8c2SCharles.Forsyth pxegetfspart, 0, bootpboot,
5074a4d8c2SCharles.Forsyth etherprintdevs,
5174a4d8c2SCharles.Forsyth etherparts,
5274a4d8c2SCharles.Forsyth etherinis,
5374a4d8c2SCharles.Forsyth },
54*8a8c2d74SCharles.Forsyth { Tbios,
55*8a8c2d74SCharles.Forsyth Fini|Ffs,
56*8a8c2d74SCharles.Forsyth biosinit, biosinitdev,
57*8a8c2d74SCharles.Forsyth biosgetfspart, nil, biosboot,
58*8a8c2d74SCharles.Forsyth biosprintdevs,
59*8a8c2d74SCharles.Forsyth diskparts,
60*8a8c2d74SCharles.Forsyth diskinis,
61*8a8c2d74SCharles.Forsyth },
62*8a8c2d74SCharles.Forsyth { Tcd,
63*8a8c2d74SCharles.Forsyth Fini|Ffs,
64*8a8c2d74SCharles.Forsyth cdinit, sdinitdev,
65*8a8c2d74SCharles.Forsyth sdgetfspart, sdaddconf, sdboot,
66*8a8c2d74SCharles.Forsyth sdprintdevs,
67*8a8c2d74SCharles.Forsyth diskparts,
68*8a8c2d74SCharles.Forsyth diskinis,
69*8a8c2d74SCharles.Forsyth },
7074a4d8c2SCharles.Forsyth { Tsd,
7174a4d8c2SCharles.Forsyth Fini|Ffs,
7274a4d8c2SCharles.Forsyth sdinit, sdinitdev,
7374a4d8c2SCharles.Forsyth sdgetfspart, sdaddconf, sdboot,
7474a4d8c2SCharles.Forsyth sdprintdevs,
7574a4d8c2SCharles.Forsyth diskparts,
7674a4d8c2SCharles.Forsyth diskinis,
7774a4d8c2SCharles.Forsyth },
7874a4d8c2SCharles.Forsyth { Tnil,
7974a4d8c2SCharles.Forsyth 0,
8074a4d8c2SCharles.Forsyth nil, nil, nil, nil, nil, nil,
8174a4d8c2SCharles.Forsyth nil,
8274a4d8c2SCharles.Forsyth nil,
8374a4d8c2SCharles.Forsyth 0,
8474a4d8c2SCharles.Forsyth nil,
8574a4d8c2SCharles.Forsyth },
8674a4d8c2SCharles.Forsyth };
8774a4d8c2SCharles.Forsyth
88*8a8c2d74SCharles.Forsyth static char *typenm[] = {
89*8a8c2d74SCharles.Forsyth [Tnil] "nil",
90*8a8c2d74SCharles.Forsyth [Tfloppy] "floppy",
91*8a8c2d74SCharles.Forsyth [Tsd] "sd",
92*8a8c2d74SCharles.Forsyth [Tether] "ether",
93*8a8c2d74SCharles.Forsyth [Tcd] "cd",
94*8a8c2d74SCharles.Forsyth [Tbios] "bios",
95*8a8c2d74SCharles.Forsyth };
96*8a8c2d74SCharles.Forsyth
97*8a8c2d74SCharles.Forsyth static char *
typename(int type)98*8a8c2d74SCharles.Forsyth typename(int type)
99*8a8c2d74SCharles.Forsyth {
100*8a8c2d74SCharles.Forsyth if (type < 0 || type >= nelem(typenm) || typenm[type] == nil)
101*8a8c2d74SCharles.Forsyth return "**gok**";
102*8a8c2d74SCharles.Forsyth return typenm[type];
103*8a8c2d74SCharles.Forsyth }
10474a4d8c2SCharles.Forsyth
10574a4d8c2SCharles.Forsyth extern SDifc sdataifc;
106*8a8c2d74SCharles.Forsyth extern SDifc sdiahciifc;
107*8a8c2d74SCharles.Forsyth extern SDifc sdaoeifc;
108*8a8c2d74SCharles.Forsyth extern SDifc sdbiosifc;
10974a4d8c2SCharles.Forsyth
11074a4d8c2SCharles.Forsyth #ifdef NOSCSI
11174a4d8c2SCharles.Forsyth
11274a4d8c2SCharles.Forsyth SDifc* sdifc[] = {
11374a4d8c2SCharles.Forsyth &sdataifc,
114*8a8c2d74SCharles.Forsyth &sdiahciifc,
115*8a8c2d74SCharles.Forsyth &sdbiosifc,
116*8a8c2d74SCharles.Forsyth &sdaoeifc,
11774a4d8c2SCharles.Forsyth nil,
11874a4d8c2SCharles.Forsyth };
11974a4d8c2SCharles.Forsyth
12074a4d8c2SCharles.Forsyth #else
12174a4d8c2SCharles.Forsyth
12274a4d8c2SCharles.Forsyth extern SDifc sdmylexifc;
12374a4d8c2SCharles.Forsyth extern SDifc sd53c8xxifc;
124*8a8c2d74SCharles.Forsyth
12574a4d8c2SCharles.Forsyth SDifc* sdifc[] = {
12674a4d8c2SCharles.Forsyth &sdataifc,
127*8a8c2d74SCharles.Forsyth &sdiahciifc,
12874a4d8c2SCharles.Forsyth &sdmylexifc,
12974a4d8c2SCharles.Forsyth &sd53c8xxifc,
130*8a8c2d74SCharles.Forsyth &sdbiosifc,
131*8a8c2d74SCharles.Forsyth &sdaoeifc,
13274a4d8c2SCharles.Forsyth nil,
13374a4d8c2SCharles.Forsyth };
13474a4d8c2SCharles.Forsyth
13574a4d8c2SCharles.Forsyth #endif NOSCSI
13674a4d8c2SCharles.Forsyth
13774a4d8c2SCharles.Forsyth typedef struct Mode Mode;
13874a4d8c2SCharles.Forsyth
13974a4d8c2SCharles.Forsyth enum {
14074a4d8c2SCharles.Forsyth Maxdev = 7,
14174a4d8c2SCharles.Forsyth Dany = -1,
14274a4d8c2SCharles.Forsyth Nmedia = 16,
14374a4d8c2SCharles.Forsyth Nini = 10,
14474a4d8c2SCharles.Forsyth };
14574a4d8c2SCharles.Forsyth
14674a4d8c2SCharles.Forsyth enum { /* mode */
14774a4d8c2SCharles.Forsyth Mauto = 0x00,
14874a4d8c2SCharles.Forsyth Mlocal = 0x01,
14974a4d8c2SCharles.Forsyth Manual = 0x02,
15074a4d8c2SCharles.Forsyth NMode = 0x03,
15174a4d8c2SCharles.Forsyth };
15274a4d8c2SCharles.Forsyth
15374a4d8c2SCharles.Forsyth typedef struct Medium Medium;
15474a4d8c2SCharles.Forsyth struct Medium {
15574a4d8c2SCharles.Forsyth Type* type;
15674a4d8c2SCharles.Forsyth int flag;
15774a4d8c2SCharles.Forsyth int dev;
15874a4d8c2SCharles.Forsyth char name[NAMELEN];
15974a4d8c2SCharles.Forsyth
16074a4d8c2SCharles.Forsyth Fs *inifs;
16174a4d8c2SCharles.Forsyth char *part;
16274a4d8c2SCharles.Forsyth char *ini;
16374a4d8c2SCharles.Forsyth
16474a4d8c2SCharles.Forsyth Medium* next;
16574a4d8c2SCharles.Forsyth };
16674a4d8c2SCharles.Forsyth
16774a4d8c2SCharles.Forsyth typedef struct Mode {
16874a4d8c2SCharles.Forsyth char* name;
16974a4d8c2SCharles.Forsyth int mode;
17074a4d8c2SCharles.Forsyth } Mode;
17174a4d8c2SCharles.Forsyth
17274a4d8c2SCharles.Forsyth static Medium media[Nmedia];
17374a4d8c2SCharles.Forsyth static Medium *curmedium = media;
17474a4d8c2SCharles.Forsyth
17574a4d8c2SCharles.Forsyth static Mode modes[NMode+1] = {
17674a4d8c2SCharles.Forsyth [Mauto] { "auto", Mauto, },
17774a4d8c2SCharles.Forsyth [Mlocal] { "local", Mlocal, },
17874a4d8c2SCharles.Forsyth [Manual] { "manual", Manual, },
17974a4d8c2SCharles.Forsyth };
18074a4d8c2SCharles.Forsyth
18174a4d8c2SCharles.Forsyth char **ini;
18274a4d8c2SCharles.Forsyth
18374a4d8c2SCharles.Forsyth int scsi0port;
18474a4d8c2SCharles.Forsyth char *defaultpartition;
18574a4d8c2SCharles.Forsyth int iniread;
18674a4d8c2SCharles.Forsyth
187*8a8c2d74SCharles.Forsyth int debugload;
188*8a8c2d74SCharles.Forsyth
18974a4d8c2SCharles.Forsyth static Medium*
parse(char * line,char ** file)19074a4d8c2SCharles.Forsyth parse(char *line, char **file)
19174a4d8c2SCharles.Forsyth {
19274a4d8c2SCharles.Forsyth char *p;
19374a4d8c2SCharles.Forsyth Type *tp;
19474a4d8c2SCharles.Forsyth Medium *mp;
19574a4d8c2SCharles.Forsyth
19674a4d8c2SCharles.Forsyth if(p = strchr(line, '!')) {
19774a4d8c2SCharles.Forsyth *p++ = 0;
19874a4d8c2SCharles.Forsyth *file = p;
19974a4d8c2SCharles.Forsyth } else
20074a4d8c2SCharles.Forsyth *file = "";
20174a4d8c2SCharles.Forsyth
20274a4d8c2SCharles.Forsyth for(tp = types; tp->type != Tnil; tp++)
20374a4d8c2SCharles.Forsyth for(mp = tp->media; mp; mp = mp->next)
20474a4d8c2SCharles.Forsyth if(strcmp(mp->name, line) == 0)
20574a4d8c2SCharles.Forsyth return mp;
20674a4d8c2SCharles.Forsyth if(p)
20774a4d8c2SCharles.Forsyth *--p = '!';
20874a4d8c2SCharles.Forsyth return nil;
20974a4d8c2SCharles.Forsyth }
21074a4d8c2SCharles.Forsyth
21174a4d8c2SCharles.Forsyth static int
boot(Medium * mp,char * file)21274a4d8c2SCharles.Forsyth boot(Medium *mp, char *file)
21374a4d8c2SCharles.Forsyth {
21474a4d8c2SCharles.Forsyth Type *tp;
21574a4d8c2SCharles.Forsyth Medium *xmp;
21674a4d8c2SCharles.Forsyth static int didaddconf;
21774a4d8c2SCharles.Forsyth Boot b;
21874a4d8c2SCharles.Forsyth
21974a4d8c2SCharles.Forsyth memset(&b, 0, sizeof b);
22074a4d8c2SCharles.Forsyth b.state = INITKERNEL;
22174a4d8c2SCharles.Forsyth
22274a4d8c2SCharles.Forsyth if(didaddconf == 0) {
22374a4d8c2SCharles.Forsyth didaddconf = 1;
22474a4d8c2SCharles.Forsyth for(tp = types; tp->type != Tnil; tp++)
22574a4d8c2SCharles.Forsyth if(tp->addconf)
22674a4d8c2SCharles.Forsyth for(xmp = tp->media; xmp; xmp = xmp->next)
22774a4d8c2SCharles.Forsyth (*tp->addconf)(xmp->dev);
22874a4d8c2SCharles.Forsyth }
22974a4d8c2SCharles.Forsyth
23074a4d8c2SCharles.Forsyth sprint(BOOTLINE, "%s!%s", mp->name, file);
231*8a8c2d74SCharles.Forsyth print("booting %s!%s\n", mp->name, file);
23274a4d8c2SCharles.Forsyth return (*mp->type->boot)(mp->dev, file, &b);
23374a4d8c2SCharles.Forsyth }
23474a4d8c2SCharles.Forsyth
23574a4d8c2SCharles.Forsyth static Medium*
allocm(Type * tp)23674a4d8c2SCharles.Forsyth allocm(Type *tp)
23774a4d8c2SCharles.Forsyth {
23874a4d8c2SCharles.Forsyth Medium **l;
23974a4d8c2SCharles.Forsyth
24074a4d8c2SCharles.Forsyth if(curmedium >= &media[Nmedia])
24174a4d8c2SCharles.Forsyth return 0;
24274a4d8c2SCharles.Forsyth
24374a4d8c2SCharles.Forsyth for(l = &tp->media; *l; l = &(*l)->next)
24474a4d8c2SCharles.Forsyth ;
24574a4d8c2SCharles.Forsyth *l = curmedium++;
24674a4d8c2SCharles.Forsyth return *l;
24774a4d8c2SCharles.Forsyth }
24874a4d8c2SCharles.Forsyth
24974a4d8c2SCharles.Forsyth Medium*
probe(int type,int flag,int dev)25074a4d8c2SCharles.Forsyth probe(int type, int flag, int dev)
25174a4d8c2SCharles.Forsyth {
25274a4d8c2SCharles.Forsyth Type *tp;
25374a4d8c2SCharles.Forsyth int i;
25474a4d8c2SCharles.Forsyth Medium *mp;
25574a4d8c2SCharles.Forsyth File f;
25674a4d8c2SCharles.Forsyth Fs *fs;
25774a4d8c2SCharles.Forsyth char **partp;
25874a4d8c2SCharles.Forsyth
25974a4d8c2SCharles.Forsyth for(tp = types; tp->type != Tnil; tp++){
26074a4d8c2SCharles.Forsyth if(type != Tany && type != tp->type)
26174a4d8c2SCharles.Forsyth continue;
26274a4d8c2SCharles.Forsyth
26374a4d8c2SCharles.Forsyth if(flag != Fnone){
26474a4d8c2SCharles.Forsyth for(mp = tp->media; mp; mp = mp->next){
26574a4d8c2SCharles.Forsyth if((flag & mp->flag) && (dev == Dany || dev == mp->dev))
26674a4d8c2SCharles.Forsyth return mp;
26774a4d8c2SCharles.Forsyth }
26874a4d8c2SCharles.Forsyth }
269*8a8c2d74SCharles.Forsyth if (debugload)
270*8a8c2d74SCharles.Forsyth print("probing %s...", typename(tp->type));
27174a4d8c2SCharles.Forsyth if((tp->flag & Fprobe) == 0){
27274a4d8c2SCharles.Forsyth tp->flag |= Fprobe;
27374a4d8c2SCharles.Forsyth tp->mask = (*tp->init)();
27474a4d8c2SCharles.Forsyth }
27574a4d8c2SCharles.Forsyth
27674a4d8c2SCharles.Forsyth for(i = 0; tp->mask; i++){
27774a4d8c2SCharles.Forsyth if((tp->mask & (1<<i)) == 0)
27874a4d8c2SCharles.Forsyth continue;
27974a4d8c2SCharles.Forsyth tp->mask &= ~(1<<i);
28074a4d8c2SCharles.Forsyth
28174a4d8c2SCharles.Forsyth if((mp = allocm(tp)) == 0)
28274a4d8c2SCharles.Forsyth continue;
28374a4d8c2SCharles.Forsyth
28474a4d8c2SCharles.Forsyth mp->dev = i;
28574a4d8c2SCharles.Forsyth mp->flag = tp->flag;
28674a4d8c2SCharles.Forsyth mp->type = tp;
28774a4d8c2SCharles.Forsyth (*tp->initdev)(i, mp->name);
28874a4d8c2SCharles.Forsyth
28974a4d8c2SCharles.Forsyth if(mp->flag & Fini){
29074a4d8c2SCharles.Forsyth mp->flag &= ~Fini;
29174a4d8c2SCharles.Forsyth for(partp = tp->parts; *partp; partp++){
29274a4d8c2SCharles.Forsyth if((fs = (*tp->getfspart)(i, *partp, 0)) == nil)
29374a4d8c2SCharles.Forsyth continue;
29474a4d8c2SCharles.Forsyth
29574a4d8c2SCharles.Forsyth for(ini = tp->inis; *ini; ini++){
29674a4d8c2SCharles.Forsyth if(fswalk(fs, *ini, &f) > 0){
29774a4d8c2SCharles.Forsyth mp->inifs = fs;
29874a4d8c2SCharles.Forsyth mp->part = *partp;
29974a4d8c2SCharles.Forsyth mp->ini = f.path;
30074a4d8c2SCharles.Forsyth mp->flag |= Fini;
30174a4d8c2SCharles.Forsyth goto Break2;
30274a4d8c2SCharles.Forsyth }
30374a4d8c2SCharles.Forsyth }
30474a4d8c2SCharles.Forsyth }
30574a4d8c2SCharles.Forsyth }
30674a4d8c2SCharles.Forsyth Break2:
30774a4d8c2SCharles.Forsyth if((flag & mp->flag) && (dev == Dany || dev == i))
30874a4d8c2SCharles.Forsyth return mp;
30974a4d8c2SCharles.Forsyth }
31074a4d8c2SCharles.Forsyth }
31174a4d8c2SCharles.Forsyth
31274a4d8c2SCharles.Forsyth return 0;
31374a4d8c2SCharles.Forsyth }
31474a4d8c2SCharles.Forsyth
31574a4d8c2SCharles.Forsyth void
main(void)31674a4d8c2SCharles.Forsyth main(void)
31774a4d8c2SCharles.Forsyth {
31874a4d8c2SCharles.Forsyth Medium *mp;
31974a4d8c2SCharles.Forsyth int flag, i, mode, tried;
32074a4d8c2SCharles.Forsyth char def[2*NAMELEN], line[80], *p, *file;
32174a4d8c2SCharles.Forsyth Type *tp;
32274a4d8c2SCharles.Forsyth
32374a4d8c2SCharles.Forsyth i8042a20();
32474a4d8c2SCharles.Forsyth memset(m, 0, sizeof(Mach));
32574a4d8c2SCharles.Forsyth trapinit();
32674a4d8c2SCharles.Forsyth clockinit();
32774a4d8c2SCharles.Forsyth alarminit();
32874a4d8c2SCharles.Forsyth meminit(0);
32974a4d8c2SCharles.Forsyth spllo();
330*8a8c2d74SCharles.Forsyth consinit("0", "9600");
33174a4d8c2SCharles.Forsyth kbdinit();
33274a4d8c2SCharles.Forsyth if((ulong)&end > (KZERO|(640*1024)))
33374a4d8c2SCharles.Forsyth panic("i'm too big\n");
33474a4d8c2SCharles.Forsyth
33574a4d8c2SCharles.Forsyth readlsconf();
336*8a8c2d74SCharles.Forsyth print("initial probe, to find plan9.ini...");
337*8a8c2d74SCharles.Forsyth /* find and read plan9.ini, setting configuration variables */
33874a4d8c2SCharles.Forsyth for(tp = types; tp->type != Tnil; tp++){
339*8a8c2d74SCharles.Forsyth /* skip bios until we have read plan9.ini */
340*8a8c2d74SCharles.Forsyth if(!pxe && tp->type == Tether || tp->type == Tbios)
341*8a8c2d74SCharles.Forsyth continue;
342*8a8c2d74SCharles.Forsyth if (VERBOSE)
343*8a8c2d74SCharles.Forsyth print("probing %s...", typename(tp->type));
34474a4d8c2SCharles.Forsyth if((mp = probe(tp->type, Fini, Dany)) && (mp->flag & Fini)){
34574a4d8c2SCharles.Forsyth print("using %s!%s!%s\n", mp->name, mp->part, mp->ini);
34674a4d8c2SCharles.Forsyth iniread = !dotini(mp->inifs);
34774a4d8c2SCharles.Forsyth break;
34874a4d8c2SCharles.Forsyth }
34974a4d8c2SCharles.Forsyth }
350*8a8c2d74SCharles.Forsyth print("\n");
35174a4d8c2SCharles.Forsyth apminit();
35274a4d8c2SCharles.Forsyth
353*8a8c2d74SCharles.Forsyth debugload = getconf("*debugload") != nil;
35474a4d8c2SCharles.Forsyth if((p = getconf("console")) != nil)
35574a4d8c2SCharles.Forsyth consinit(p, getconf("baud"));
356*8a8c2d74SCharles.Forsyth
35774a4d8c2SCharles.Forsyth devpccardlink();
35874a4d8c2SCharles.Forsyth devi82365link();
35974a4d8c2SCharles.Forsyth
36074a4d8c2SCharles.Forsyth /*
36174a4d8c2SCharles.Forsyth * Even after we find the ini file, we keep probing disks,
36274a4d8c2SCharles.Forsyth * because we have to collect the partition tables and
36374a4d8c2SCharles.Forsyth * have boot devices for parse.
36474a4d8c2SCharles.Forsyth */
36574a4d8c2SCharles.Forsyth probe(Tany, Fnone, Dany);
366*8a8c2d74SCharles.Forsyth if (debugload)
367*8a8c2d74SCharles.Forsyth print("end disk probe\n");
36874a4d8c2SCharles.Forsyth tried = 0;
36974a4d8c2SCharles.Forsyth mode = Mauto;
37074a4d8c2SCharles.Forsyth
37174a4d8c2SCharles.Forsyth p = getconf("bootfile");
37274a4d8c2SCharles.Forsyth
37374a4d8c2SCharles.Forsyth if(p != 0) {
37474a4d8c2SCharles.Forsyth mode = Manual;
37574a4d8c2SCharles.Forsyth for(i = 0; i < NMode; i++){
37674a4d8c2SCharles.Forsyth if(strcmp(p, modes[i].name) == 0){
37774a4d8c2SCharles.Forsyth mode = modes[i].mode;
37874a4d8c2SCharles.Forsyth goto done;
37974a4d8c2SCharles.Forsyth }
38074a4d8c2SCharles.Forsyth }
38174a4d8c2SCharles.Forsyth if((mp = parse(p, &file)) == nil) {
38274a4d8c2SCharles.Forsyth print("Unknown boot device: %s\n", p);
38374a4d8c2SCharles.Forsyth goto done;
38474a4d8c2SCharles.Forsyth }
38574a4d8c2SCharles.Forsyth tried = boot(mp, file);
38674a4d8c2SCharles.Forsyth }
38774a4d8c2SCharles.Forsyth done:
38874a4d8c2SCharles.Forsyth if(tried == 0 && mode != Manual){
38974a4d8c2SCharles.Forsyth flag = Fany;
39074a4d8c2SCharles.Forsyth if(mode == Mlocal)
39174a4d8c2SCharles.Forsyth flag &= ~Fbootp;
39274a4d8c2SCharles.Forsyth if((mp = probe(Tany, flag, Dany)) && mp->type->type != Tfloppy)
39374a4d8c2SCharles.Forsyth boot(mp, "");
394*8a8c2d74SCharles.Forsyth if (debugload)
395*8a8c2d74SCharles.Forsyth print("end auto probe\n");
39674a4d8c2SCharles.Forsyth }
39774a4d8c2SCharles.Forsyth
39874a4d8c2SCharles.Forsyth def[0] = 0;
39974a4d8c2SCharles.Forsyth probe(Tany, Fnone, Dany);
400*8a8c2d74SCharles.Forsyth if (debugload)
401*8a8c2d74SCharles.Forsyth print("end final probe\n");
40274a4d8c2SCharles.Forsyth if(p = getconf("bootdef"))
40374a4d8c2SCharles.Forsyth strcpy(def, p);
40474a4d8c2SCharles.Forsyth
40574a4d8c2SCharles.Forsyth flag = 0;
40674a4d8c2SCharles.Forsyth for(tp = types; tp->type != Tnil; tp++){
40774a4d8c2SCharles.Forsyth for(mp = tp->media; mp; mp = mp->next){
40874a4d8c2SCharles.Forsyth if(flag == 0){
40974a4d8c2SCharles.Forsyth flag = 1;
41074a4d8c2SCharles.Forsyth print("Boot devices:");
41174a4d8c2SCharles.Forsyth }
41274a4d8c2SCharles.Forsyth (*tp->printdevs)(mp->dev);
41374a4d8c2SCharles.Forsyth }
41474a4d8c2SCharles.Forsyth }
41574a4d8c2SCharles.Forsyth if(flag)
41674a4d8c2SCharles.Forsyth print("\n");
41774a4d8c2SCharles.Forsyth
41874a4d8c2SCharles.Forsyth for(;;){
41974a4d8c2SCharles.Forsyth if(getstr("boot from", line, sizeof(line), def, (mode != Manual)*15) >= 0)
42074a4d8c2SCharles.Forsyth if(mp = parse(line, &file))
42174a4d8c2SCharles.Forsyth boot(mp, file);
42274a4d8c2SCharles.Forsyth def[0] = 0;
42374a4d8c2SCharles.Forsyth }
42474a4d8c2SCharles.Forsyth }
42574a4d8c2SCharles.Forsyth
42674a4d8c2SCharles.Forsyth int
getfields(char * lp,char ** fields,int n,char sep)42774a4d8c2SCharles.Forsyth getfields(char *lp, char **fields, int n, char sep)
42874a4d8c2SCharles.Forsyth {
42974a4d8c2SCharles.Forsyth int i;
43074a4d8c2SCharles.Forsyth
43174a4d8c2SCharles.Forsyth for(i = 0; lp && *lp && i < n; i++){
43274a4d8c2SCharles.Forsyth while(*lp == sep)
43374a4d8c2SCharles.Forsyth *lp++ = 0;
43474a4d8c2SCharles.Forsyth if(*lp == 0)
43574a4d8c2SCharles.Forsyth break;
43674a4d8c2SCharles.Forsyth fields[i] = lp;
43774a4d8c2SCharles.Forsyth while(*lp && *lp != sep){
43874a4d8c2SCharles.Forsyth if(*lp == '\\' && *(lp+1) == '\n')
43974a4d8c2SCharles.Forsyth *lp++ = ' ';
44074a4d8c2SCharles.Forsyth lp++;
44174a4d8c2SCharles.Forsyth }
44274a4d8c2SCharles.Forsyth }
44374a4d8c2SCharles.Forsyth return i;
44474a4d8c2SCharles.Forsyth }
44574a4d8c2SCharles.Forsyth
44674a4d8c2SCharles.Forsyth int
cistrcmp(char * a,char * b)44774a4d8c2SCharles.Forsyth cistrcmp(char *a, char *b)
44874a4d8c2SCharles.Forsyth {
44974a4d8c2SCharles.Forsyth int ac, bc;
45074a4d8c2SCharles.Forsyth
45174a4d8c2SCharles.Forsyth for(;;){
45274a4d8c2SCharles.Forsyth ac = *a++;
45374a4d8c2SCharles.Forsyth bc = *b++;
45474a4d8c2SCharles.Forsyth
45574a4d8c2SCharles.Forsyth if(ac >= 'A' && ac <= 'Z')
45674a4d8c2SCharles.Forsyth ac = 'a' + (ac - 'A');
45774a4d8c2SCharles.Forsyth if(bc >= 'A' && bc <= 'Z')
45874a4d8c2SCharles.Forsyth bc = 'a' + (bc - 'A');
45974a4d8c2SCharles.Forsyth ac -= bc;
46074a4d8c2SCharles.Forsyth if(ac)
46174a4d8c2SCharles.Forsyth return ac;
46274a4d8c2SCharles.Forsyth if(bc == 0)
46374a4d8c2SCharles.Forsyth break;
46474a4d8c2SCharles.Forsyth }
46574a4d8c2SCharles.Forsyth return 0;
46674a4d8c2SCharles.Forsyth }
46774a4d8c2SCharles.Forsyth
46874a4d8c2SCharles.Forsyth int
cistrncmp(char * a,char * b,int n)46974a4d8c2SCharles.Forsyth cistrncmp(char *a, char *b, int n)
47074a4d8c2SCharles.Forsyth {
47174a4d8c2SCharles.Forsyth unsigned ac, bc;
47274a4d8c2SCharles.Forsyth
47374a4d8c2SCharles.Forsyth while(n > 0){
47474a4d8c2SCharles.Forsyth ac = *a++;
47574a4d8c2SCharles.Forsyth bc = *b++;
47674a4d8c2SCharles.Forsyth n--;
47774a4d8c2SCharles.Forsyth
47874a4d8c2SCharles.Forsyth if(ac >= 'A' && ac <= 'Z')
47974a4d8c2SCharles.Forsyth ac = 'a' + (ac - 'A');
48074a4d8c2SCharles.Forsyth if(bc >= 'A' && bc <= 'Z')
48174a4d8c2SCharles.Forsyth bc = 'a' + (bc - 'A');
48274a4d8c2SCharles.Forsyth
48374a4d8c2SCharles.Forsyth ac -= bc;
48474a4d8c2SCharles.Forsyth if(ac)
48574a4d8c2SCharles.Forsyth return ac;
48674a4d8c2SCharles.Forsyth if(bc == 0)
48774a4d8c2SCharles.Forsyth break;
48874a4d8c2SCharles.Forsyth }
48974a4d8c2SCharles.Forsyth
49074a4d8c2SCharles.Forsyth return 0;
49174a4d8c2SCharles.Forsyth }
49274a4d8c2SCharles.Forsyth
493*8a8c2d74SCharles.Forsyth #define PSTART ( 8*1024*1024)
49474a4d8c2SCharles.Forsyth #define PEND (16*1024*1024)
49574a4d8c2SCharles.Forsyth
49674a4d8c2SCharles.Forsyth ulong palloc = PSTART;
49774a4d8c2SCharles.Forsyth
49874a4d8c2SCharles.Forsyth void*
ialloc(ulong n,int align)49974a4d8c2SCharles.Forsyth ialloc(ulong n, int align)
50074a4d8c2SCharles.Forsyth {
50174a4d8c2SCharles.Forsyth ulong p;
50274a4d8c2SCharles.Forsyth int a;
50374a4d8c2SCharles.Forsyth
50474a4d8c2SCharles.Forsyth p = palloc;
50574a4d8c2SCharles.Forsyth if(align <= 0)
50674a4d8c2SCharles.Forsyth align = 4;
50774a4d8c2SCharles.Forsyth if(a = n % align)
50874a4d8c2SCharles.Forsyth n += align - a;
50974a4d8c2SCharles.Forsyth if(a = p % align)
51074a4d8c2SCharles.Forsyth p += align - a;
51174a4d8c2SCharles.Forsyth
51274a4d8c2SCharles.Forsyth
51374a4d8c2SCharles.Forsyth palloc = p+n;
51474a4d8c2SCharles.Forsyth if(palloc > PEND)
515*8a8c2d74SCharles.Forsyth panic("ialloc(%lud, %d) called from %#p\n",
51674a4d8c2SCharles.Forsyth n, align, getcallerpc(&n));
51774a4d8c2SCharles.Forsyth return memset((void*)(p|KZERO), 0, n);
51874a4d8c2SCharles.Forsyth }
51974a4d8c2SCharles.Forsyth
52074a4d8c2SCharles.Forsyth void*
xspanalloc(ulong size,int align,ulong span)52174a4d8c2SCharles.Forsyth xspanalloc(ulong size, int align, ulong span)
52274a4d8c2SCharles.Forsyth {
52374a4d8c2SCharles.Forsyth ulong a, v;
52474a4d8c2SCharles.Forsyth
52574a4d8c2SCharles.Forsyth if((palloc + (size+align+span)) > PEND)
526*8a8c2d74SCharles.Forsyth panic("xspanalloc(%lud, %d, 0x%lux) called from %#p\n",
52774a4d8c2SCharles.Forsyth size, align, span, getcallerpc(&size));
52874a4d8c2SCharles.Forsyth
52974a4d8c2SCharles.Forsyth a = (ulong)ialloc(size+align+span, 0);
53074a4d8c2SCharles.Forsyth
53174a4d8c2SCharles.Forsyth if(span > 2)
53274a4d8c2SCharles.Forsyth v = (a + span) & ~(span-1);
53374a4d8c2SCharles.Forsyth else
53474a4d8c2SCharles.Forsyth v = a;
53574a4d8c2SCharles.Forsyth
53674a4d8c2SCharles.Forsyth if(align > 1)
53774a4d8c2SCharles.Forsyth v = (v + align) & ~(align-1);
53874a4d8c2SCharles.Forsyth
53974a4d8c2SCharles.Forsyth return (void*)v;
54074a4d8c2SCharles.Forsyth }
54174a4d8c2SCharles.Forsyth
54274a4d8c2SCharles.Forsyth static Block *allocbp;
54374a4d8c2SCharles.Forsyth
54474a4d8c2SCharles.Forsyth Block*
allocb(int size)54574a4d8c2SCharles.Forsyth allocb(int size)
54674a4d8c2SCharles.Forsyth {
54774a4d8c2SCharles.Forsyth Block *bp, **lbp;
54874a4d8c2SCharles.Forsyth ulong addr;
54974a4d8c2SCharles.Forsyth
55074a4d8c2SCharles.Forsyth lbp = &allocbp;
55174a4d8c2SCharles.Forsyth for(bp = *lbp; bp; bp = bp->next){
55274a4d8c2SCharles.Forsyth if((bp->lim - bp->base) >= size){
55374a4d8c2SCharles.Forsyth *lbp = bp->next;
55474a4d8c2SCharles.Forsyth break;
55574a4d8c2SCharles.Forsyth }
55674a4d8c2SCharles.Forsyth lbp = &bp->next;
55774a4d8c2SCharles.Forsyth }
55874a4d8c2SCharles.Forsyth if(bp == 0){
55974a4d8c2SCharles.Forsyth if((palloc + (sizeof(Block)+size+64)) > PEND)
560*8a8c2d74SCharles.Forsyth panic("allocb(%d) called from %#p\n",
56174a4d8c2SCharles.Forsyth size, getcallerpc(&size));
56274a4d8c2SCharles.Forsyth bp = ialloc(sizeof(Block)+size+64, 0);
56374a4d8c2SCharles.Forsyth addr = (ulong)bp;
56474a4d8c2SCharles.Forsyth addr = ROUNDUP(addr + sizeof(Block), 8);
56574a4d8c2SCharles.Forsyth bp->base = (uchar*)addr;
56674a4d8c2SCharles.Forsyth bp->lim = ((uchar*)bp) + sizeof(Block)+size+64;
56774a4d8c2SCharles.Forsyth }
56874a4d8c2SCharles.Forsyth
56974a4d8c2SCharles.Forsyth if(bp->flag)
57074a4d8c2SCharles.Forsyth panic("allocb reuse\n");
57174a4d8c2SCharles.Forsyth
57274a4d8c2SCharles.Forsyth bp->rp = bp->base;
57374a4d8c2SCharles.Forsyth bp->wp = bp->rp;
57474a4d8c2SCharles.Forsyth bp->next = 0;
57574a4d8c2SCharles.Forsyth bp->flag = 1;
57674a4d8c2SCharles.Forsyth
57774a4d8c2SCharles.Forsyth return bp;
57874a4d8c2SCharles.Forsyth }
57974a4d8c2SCharles.Forsyth
58074a4d8c2SCharles.Forsyth void
freeb(Block * bp)58174a4d8c2SCharles.Forsyth freeb(Block* bp)
58274a4d8c2SCharles.Forsyth {
58374a4d8c2SCharles.Forsyth bp->next = allocbp;
58474a4d8c2SCharles.Forsyth allocbp = bp;
58574a4d8c2SCharles.Forsyth
58674a4d8c2SCharles.Forsyth bp->flag = 0;
58774a4d8c2SCharles.Forsyth }
58874a4d8c2SCharles.Forsyth
58974a4d8c2SCharles.Forsyth enum {
59074a4d8c2SCharles.Forsyth Paddr= 0x70, /* address port */
59174a4d8c2SCharles.Forsyth Pdata= 0x71, /* data port */
59274a4d8c2SCharles.Forsyth };
59374a4d8c2SCharles.Forsyth
59474a4d8c2SCharles.Forsyth uchar
nvramread(int offset)59574a4d8c2SCharles.Forsyth nvramread(int offset)
59674a4d8c2SCharles.Forsyth {
59774a4d8c2SCharles.Forsyth outb(Paddr, offset);
59874a4d8c2SCharles.Forsyth return inb(Pdata);
59974a4d8c2SCharles.Forsyth }
60074a4d8c2SCharles.Forsyth
60174a4d8c2SCharles.Forsyth void (*etherdetach)(void);
60274a4d8c2SCharles.Forsyth void (*floppydetach)(void);
60374a4d8c2SCharles.Forsyth void (*sddetach)(void);
60474a4d8c2SCharles.Forsyth
60574a4d8c2SCharles.Forsyth void
warp9(ulong entry)60674a4d8c2SCharles.Forsyth warp9(ulong entry)
60774a4d8c2SCharles.Forsyth {
60874a4d8c2SCharles.Forsyth if(etherdetach)
60974a4d8c2SCharles.Forsyth etherdetach();
61074a4d8c2SCharles.Forsyth if(floppydetach)
61174a4d8c2SCharles.Forsyth floppydetach();
61274a4d8c2SCharles.Forsyth if(sddetach)
61374a4d8c2SCharles.Forsyth sddetach();
61474a4d8c2SCharles.Forsyth consdrain();
61574a4d8c2SCharles.Forsyth
61674a4d8c2SCharles.Forsyth splhi();
61774a4d8c2SCharles.Forsyth trapdisable();
61874a4d8c2SCharles.Forsyth
61974a4d8c2SCharles.Forsyth /*
62074a4d8c2SCharles.Forsyth * This is where to push things on the stack to
62174a4d8c2SCharles.Forsyth * boot *BSD systems, e.g.
62274a4d8c2SCharles.Forsyth (*(void(*)(void*, void*, void*, void*, ulong, ulong))(PADDR(entry)))(0, 0, 0, 0, 8196, 640);
62374a4d8c2SCharles.Forsyth * will enable NetBSD boot (the real memory size needs to
62474a4d8c2SCharles.Forsyth * go in the 5th argument).
62574a4d8c2SCharles.Forsyth */
62674a4d8c2SCharles.Forsyth (*(void(*)(void))(PADDR(entry)))();
62774a4d8c2SCharles.Forsyth }
628