123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580 |
- #include "u.h"
- #include "lib.h"
- #include "mem.h"
- #include "dat.h"
- #include "fns.h"
- #include "io.h"
- #include "fs.h"
- /*
- * "cache" must be in this list so that 9load will pass the definition of
- * the cache partition into the kernel so that the disk named by the `cfs'
- * variable in plan9.ini can be seen in all circumstances before termrc
- * sets up all the disk partitions. In particular, if it's on an odd-ball
- * disk like sd10 rather than sdC0, this is needed.
- */
- static char *diskparts[] = {
- "dos", "9fat", "fs", "data", "cdboot", "cache", 0
- };
- static char *etherparts[] = { "*", 0 };
- static char *diskinis[] = {
- "plan9/plan9.ini",
- "plan9.ini",
- 0
- };
- static char *etherinis[] = {
- "/cfg/pxe/%E",
- 0
- };
- Type types[] = {
- { Tfloppy,
- Fini|Ffs,
- floppyinit, floppyinitdev,
- floppygetfspart, 0, floppyboot,
- floppyprintdevs,
- diskparts,
- diskinis,
- },
- { Tcd,
- Fini|Ffs,
- cdinit, sdinitdev,
- sdgetfspart, sdaddconf, sdboot,
- sdprintdevs,
- diskparts,
- diskinis,
- },
- { Tether,
- Fini|Fbootp,
- etherinit, etherinitdev,
- pxegetfspart, 0, bootpboot,
- etherprintdevs,
- etherparts,
- etherinis,
- },
- { Tsd,
- Fini|Ffs,
- sdinit, sdinitdev,
- sdgetfspart, sdaddconf, sdboot,
- sdprintdevs,
- diskparts,
- diskinis,
- },
- { Tnil,
- 0,
- nil, nil, nil, nil, nil, nil,
- nil,
- nil,
- 0,
- nil,
- },
- };
- #include "sd.h"
- extern SDifc sdataifc;
- #ifdef NOSCSI
- SDifc* sdifc[] = {
- &sdataifc,
- nil,
- };
- #else
- extern SDifc sdmylexifc;
- extern SDifc sd53c8xxifc;
- SDifc* sdifc[] = {
- &sdataifc,
- &sdmylexifc,
- &sd53c8xxifc,
- nil,
- };
- #endif NOSCSI
- typedef struct Mode Mode;
- enum {
- Maxdev = 7,
- Dany = -1,
- Nmedia = 16,
- Nini = 10,
- };
- enum { /* mode */
- Mauto = 0x00,
- Mlocal = 0x01,
- Manual = 0x02,
- NMode = 0x03,
- };
- typedef struct Medium Medium;
- struct Medium {
- Type* type;
- int flag;
- int dev;
- char name[NAMELEN];
- Fs *inifs;
- char *part;
- char *ini;
- Medium* next;
- };
- typedef struct Mode {
- char* name;
- int mode;
- } Mode;
- static Medium media[Nmedia];
- static Medium *curmedium = media;
- static Mode modes[NMode+1] = {
- [Mauto] { "auto", Mauto, },
- [Mlocal] { "local", Mlocal, },
- [Manual] { "manual", Manual, },
- };
- char **ini;
- int scsi0port;
- char *defaultpartition;
- int iniread;
- static Medium*
- parse(char *line, char **file)
- {
- char *p;
- Type *tp;
- Medium *mp;
- if(p = strchr(line, '!')) {
- *p++ = 0;
- *file = p;
- } else
- *file = "";
- for(tp = types; tp->type != Tnil; tp++)
- for(mp = tp->media; mp; mp = mp->next)
- if(strcmp(mp->name, line) == 0)
- return mp;
- if(p)
- *--p = '!';
- return nil;
- }
- static int
- boot(Medium *mp, char *file)
- {
- Type *tp;
- Medium *xmp;
- static int didaddconf;
- Boot b;
- memset(&b, 0, sizeof b);
- b.state = INITKERNEL;
- if(didaddconf == 0) {
- didaddconf = 1;
- for(tp = types; tp->type != Tnil; tp++)
- if(tp->addconf)
- for(xmp = tp->media; xmp; xmp = xmp->next)
- (*tp->addconf)(xmp->dev);
- }
- sprint(BOOTLINE, "%s!%s", mp->name, file);
- return (*mp->type->boot)(mp->dev, file, &b);
- }
- static Medium*
- allocm(Type *tp)
- {
- Medium **l;
- if(curmedium >= &media[Nmedia])
- return 0;
- for(l = &tp->media; *l; l = &(*l)->next)
- ;
- *l = curmedium++;
- return *l;
- }
- Medium*
- probe(int type, int flag, int dev)
- {
- Type *tp;
- int i;
- Medium *mp;
- File f;
- Fs *fs;
- char **partp;
- for(tp = types; tp->type != Tnil; tp++){
- if(type != Tany && type != tp->type)
- continue;
- if(flag != Fnone){
- for(mp = tp->media; mp; mp = mp->next){
- if((flag & mp->flag) && (dev == Dany || dev == mp->dev))
- return mp;
- }
- }
- if((tp->flag & Fprobe) == 0){
- tp->flag |= Fprobe;
- tp->mask = (*tp->init)();
- }
- for(i = 0; tp->mask; i++){
- if((tp->mask & (1<<i)) == 0)
- continue;
- tp->mask &= ~(1<<i);
- if((mp = allocm(tp)) == 0)
- continue;
- mp->dev = i;
- mp->flag = tp->flag;
- mp->type = tp;
- (*tp->initdev)(i, mp->name);
- if(mp->flag & Fini){
- mp->flag &= ~Fini;
- for(partp = tp->parts; *partp; partp++){
- if((fs = (*tp->getfspart)(i, *partp, 0)) == nil)
- continue;
- for(ini = tp->inis; *ini; ini++){
- if(fswalk(fs, *ini, &f) > 0){
- mp->inifs = fs;
- mp->part = *partp;
- mp->ini = f.path;
- mp->flag |= Fini;
- goto Break2;
- }
- }
- }
- }
- Break2:
- if((flag & mp->flag) && (dev == Dany || dev == i))
- return mp;
- }
- }
- return 0;
- }
- static char *typenm[] = {
- [Tnil] "nil",
- [Tfloppy] "Tfloppy",
- [Tsd] "Tsd",
- [Tether] "Tether",
- [Tcd] "Tcd",
- };
- void
- main(void)
- {
- Medium *mp;
- int flag, i, mode, tried;
- char def[2*NAMELEN], line[80], *p, *file;
- Type *tp;
- i8042a20();
- memset(m, 0, sizeof(Mach));
- trapinit();
- clockinit();
- alarminit();
- meminit(0);
- spllo();
- kbdinit();
- if((ulong)&end > (KZERO|(640*1024)))
- panic("i'm too big\n");
- readlsconf();
- for(tp = types; tp->type != Tnil; tp++){
- if(!pxe && tp->type == Tether)
- continue;
- if((mp = probe(tp->type, Fini, Dany)) && (mp->flag & Fini)){
- print("using %s!%s!%s\n", mp->name, mp->part, mp->ini);
- iniread = !dotini(mp->inifs);
- break;
- }
- }
- apminit();
- if((p = getconf("console")) != nil)
- consinit(p, getconf("baud"));
- devpccardlink();
- devi82365link();
- /*
- * Even after we find the ini file, we keep probing disks,
- * because we have to collect the partition tables and
- * have boot devices for parse.
- */
- probe(Tany, Fnone, Dany);
- tried = 0;
- mode = Mauto;
-
- p = getconf("bootfile");
- if(p != 0) {
- mode = Manual;
- for(i = 0; i < NMode; i++){
- if(strcmp(p, modes[i].name) == 0){
- mode = modes[i].mode;
- goto done;
- }
- }
- if((mp = parse(p, &file)) == nil) {
- print("Unknown boot device: %s\n", p);
- goto done;
- }
- tried = boot(mp, file);
- }
- done:
- if(tried == 0 && mode != Manual){
- flag = Fany;
- if(mode == Mlocal)
- flag &= ~Fbootp;
- if((mp = probe(Tany, flag, Dany)) && mp->type->type != Tfloppy)
- boot(mp, "");
- }
- def[0] = 0;
- probe(Tany, Fnone, Dany);
- if(p = getconf("bootdef"))
- strcpy(def, p);
- flag = 0;
- for(tp = types; tp->type != Tnil; tp++){
- for(mp = tp->media; mp; mp = mp->next){
- if(flag == 0){
- flag = 1;
- print("Boot devices:");
- }
- (*tp->printdevs)(mp->dev);
- }
- }
- if(flag)
- print("\n");
- for(;;){
- if(getstr("boot from", line, sizeof(line), def, (mode != Manual)*15) >= 0)
- if(mp = parse(line, &file))
- boot(mp, file);
- def[0] = 0;
- }
- }
- int
- getfields(char *lp, char **fields, int n, char sep)
- {
- int i;
- for(i = 0; lp && *lp && i < n; i++){
- while(*lp == sep)
- *lp++ = 0;
- if(*lp == 0)
- break;
- fields[i] = lp;
- while(*lp && *lp != sep){
- if(*lp == '\\' && *(lp+1) == '\n')
- *lp++ = ' ';
- lp++;
- }
- }
- return i;
- }
- int
- cistrcmp(char *a, char *b)
- {
- int ac, bc;
- for(;;){
- ac = *a++;
- bc = *b++;
-
- if(ac >= 'A' && ac <= 'Z')
- ac = 'a' + (ac - 'A');
- if(bc >= 'A' && bc <= 'Z')
- bc = 'a' + (bc - 'A');
- ac -= bc;
- if(ac)
- return ac;
- if(bc == 0)
- break;
- }
- return 0;
- }
- int
- cistrncmp(char *a, char *b, int n)
- {
- unsigned ac, bc;
- while(n > 0){
- ac = *a++;
- bc = *b++;
- n--;
- if(ac >= 'A' && ac <= 'Z')
- ac = 'a' + (ac - 'A');
- if(bc >= 'A' && bc <= 'Z')
- bc = 'a' + (bc - 'A');
- ac -= bc;
- if(ac)
- return ac;
- if(bc == 0)
- break;
- }
- return 0;
- }
- #define PSTART ( 8*1024*1024)
- #define PEND (16*1024*1024)
- ulong palloc = PSTART;
- void*
- ialloc(ulong n, int align)
- {
- ulong p;
- int a;
- p = palloc;
- if(align <= 0)
- align = 4;
- if(a = n % align)
- n += align - a;
- if(a = p % align)
- p += align - a;
- palloc = p+n;
- if(palloc > PEND)
- panic("ialloc(%lud, %d) called from %#p\n",
- n, align, getcallerpc(&n));
- return memset((void*)(p|KZERO), 0, n);
- }
- void*
- xspanalloc(ulong size, int align, ulong span)
- {
- ulong a, v;
- if((palloc + (size+align+span)) > PEND)
- panic("xspanalloc(%lud, %d, 0x%lux) called from %#p\n",
- size, align, span, getcallerpc(&size));
- a = (ulong)ialloc(size+align+span, 0);
- if(span > 2)
- v = (a + span) & ~(span-1);
- else
- v = a;
- if(align > 1)
- v = (v + align) & ~(align-1);
- return (void*)v;
- }
- static Block *allocbp;
- Block*
- allocb(int size)
- {
- Block *bp, **lbp;
- ulong addr;
- lbp = &allocbp;
- for(bp = *lbp; bp; bp = bp->next){
- if((bp->lim - bp->base) >= size){
- *lbp = bp->next;
- break;
- }
- lbp = &bp->next;
- }
- if(bp == 0){
- if((palloc + (sizeof(Block)+size+64)) > PEND)
- panic("allocb(%d) called from %#p\n",
- size, getcallerpc(&size));
- bp = ialloc(sizeof(Block)+size+64, 0);
- addr = (ulong)bp;
- addr = ROUNDUP(addr + sizeof(Block), 8);
- bp->base = (uchar*)addr;
- bp->lim = ((uchar*)bp) + sizeof(Block)+size+64;
- }
- if(bp->flag)
- panic("allocb reuse\n");
- bp->rp = bp->base;
- bp->wp = bp->rp;
- bp->next = 0;
- bp->flag = 1;
- return bp;
- }
- void
- freeb(Block* bp)
- {
- bp->next = allocbp;
- allocbp = bp;
- bp->flag = 0;
- }
- enum {
- Paddr= 0x70, /* address port */
- Pdata= 0x71, /* data port */
- };
- uchar
- nvramread(int offset)
- {
- outb(Paddr, offset);
- return inb(Pdata);
- }
- void (*etherdetach)(void);
- void (*floppydetach)(void);
- void (*sddetach)(void);
- void
- warp9(ulong entry)
- {
- if(etherdetach)
- etherdetach();
- if(floppydetach)
- floppydetach();
- if(sddetach)
- sddetach();
- consdrain();
-
- splhi();
- trapdisable();
- /*
- * This is where to push things on the stack to
- * boot *BSD systems, e.g.
- (*(void(*)(void*, void*, void*, void*, ulong, ulong))(PADDR(entry)))(0, 0, 0, 0, 8196, 640);
- * will enable NetBSD boot (the real memory size needs to
- * go in the 5th argument).
- */
- (*(void(*)(void))(PADDR(entry)))();
- }
|