xref: /inferno-os/os/boot/pc/bcom.c (revision 8a8c2d742b51525f66c2210e3c8a251de10022ff)
1*8a8c2d74SCharles.Forsyth /*
2*8a8c2d74SCharles.Forsyth  * ld - DOS boot loader of Plan 9
3*8a8c2d74SCharles.Forsyth  */
474a4d8c2SCharles.Forsyth #include "u.h"
574a4d8c2SCharles.Forsyth #include "lib.h"
674a4d8c2SCharles.Forsyth #include "mem.h"
774a4d8c2SCharles.Forsyth #include "dat.h"
874a4d8c2SCharles.Forsyth #include "fns.h"
974a4d8c2SCharles.Forsyth #include "io.h"
1074a4d8c2SCharles.Forsyth 
1174a4d8c2SCharles.Forsyth #include "fs.h"
1274a4d8c2SCharles.Forsyth 
1374a4d8c2SCharles.Forsyth Type types[] = {
1474a4d8c2SCharles.Forsyth 	{	Tfloppy,
1574a4d8c2SCharles.Forsyth 		Fini|Ffs,
1674a4d8c2SCharles.Forsyth 		floppyinit, floppyinitdev,
1774a4d8c2SCharles.Forsyth 		floppygetfspart, 0, floppyboot,
1874a4d8c2SCharles.Forsyth 	},
1974a4d8c2SCharles.Forsyth 	{	Tsd,
2074a4d8c2SCharles.Forsyth 		Fini|Ffs,
2174a4d8c2SCharles.Forsyth 		sdinit, sdinitdev,
2274a4d8c2SCharles.Forsyth 		sdgetfspart, sdaddconf, sdboot,
2374a4d8c2SCharles.Forsyth 	},
2474a4d8c2SCharles.Forsyth 	{	Tnil,
2574a4d8c2SCharles.Forsyth 		0,
2674a4d8c2SCharles.Forsyth 		0, 0,
2774a4d8c2SCharles.Forsyth 		0, 0, 0,
2874a4d8c2SCharles.Forsyth 	},
2974a4d8c2SCharles.Forsyth };
3074a4d8c2SCharles.Forsyth 
3174a4d8c2SCharles.Forsyth #include "sd.h"
3274a4d8c2SCharles.Forsyth 
3374a4d8c2SCharles.Forsyth extern SDifc sdataifc;
3474a4d8c2SCharles.Forsyth extern SDifc sdmylexifc;
3574a4d8c2SCharles.Forsyth extern SDifc sd53c8xxifc;
3674a4d8c2SCharles.Forsyth SDifc* sdifc[] = {
3774a4d8c2SCharles.Forsyth 	&sdataifc,
3874a4d8c2SCharles.Forsyth //	&sdmylexifc,
3974a4d8c2SCharles.Forsyth //	&sd53c8xxifc,
4074a4d8c2SCharles.Forsyth 	nil,
4174a4d8c2SCharles.Forsyth };
4274a4d8c2SCharles.Forsyth 
4374a4d8c2SCharles.Forsyth typedef struct Mode Mode;
4474a4d8c2SCharles.Forsyth 
4574a4d8c2SCharles.Forsyth enum {
4674a4d8c2SCharles.Forsyth 	Maxdev		= 7,
4774a4d8c2SCharles.Forsyth 	Dany		= -1,
4874a4d8c2SCharles.Forsyth 	Nmedia		= 16,
4974a4d8c2SCharles.Forsyth 	Nini		= 10,
5074a4d8c2SCharles.Forsyth };
5174a4d8c2SCharles.Forsyth 
5274a4d8c2SCharles.Forsyth enum {					/* mode */
5374a4d8c2SCharles.Forsyth 	Mauto		= 0x00,
5474a4d8c2SCharles.Forsyth 	Mlocal		= 0x01,
5574a4d8c2SCharles.Forsyth 	Manual		= 0x02,
5674a4d8c2SCharles.Forsyth 	NMode		= 0x03,
5774a4d8c2SCharles.Forsyth };
5874a4d8c2SCharles.Forsyth 
5974a4d8c2SCharles.Forsyth typedef struct Medium Medium;
6074a4d8c2SCharles.Forsyth struct Medium {
6174a4d8c2SCharles.Forsyth 	Type*	type;
6274a4d8c2SCharles.Forsyth 	int	flag;
6374a4d8c2SCharles.Forsyth 	int	dev;
6474a4d8c2SCharles.Forsyth 	char name[NAMELEN];
6574a4d8c2SCharles.Forsyth 	Fs*	inifs;
6674a4d8c2SCharles.Forsyth 
6774a4d8c2SCharles.Forsyth 	Medium*	next;
6874a4d8c2SCharles.Forsyth };
6974a4d8c2SCharles.Forsyth 
7074a4d8c2SCharles.Forsyth typedef struct Mode {
7174a4d8c2SCharles.Forsyth 	char*	name;
7274a4d8c2SCharles.Forsyth 	int	mode;
7374a4d8c2SCharles.Forsyth } Mode;
7474a4d8c2SCharles.Forsyth 
7574a4d8c2SCharles.Forsyth static Medium media[Nmedia];
7674a4d8c2SCharles.Forsyth static Medium *curmedium = media;
7774a4d8c2SCharles.Forsyth 
7874a4d8c2SCharles.Forsyth static Mode modes[NMode+1] = {
7974a4d8c2SCharles.Forsyth 	[Mauto]		{ "auto",   Mauto,  },
8074a4d8c2SCharles.Forsyth 	[Mlocal]	{ "local",  Mlocal, },
8174a4d8c2SCharles.Forsyth 	[Manual]	{ "manual", Manual, },
8274a4d8c2SCharles.Forsyth };
8374a4d8c2SCharles.Forsyth 
8474a4d8c2SCharles.Forsyth char *defaultpartition = "new";
8574a4d8c2SCharles.Forsyth 
8674a4d8c2SCharles.Forsyth static Medium*
parse(char * line,char ** file)8774a4d8c2SCharles.Forsyth parse(char *line, char **file)
8874a4d8c2SCharles.Forsyth {
8974a4d8c2SCharles.Forsyth 	char *p;
9074a4d8c2SCharles.Forsyth 	Type *tp;
9174a4d8c2SCharles.Forsyth 	Medium *mp;
9274a4d8c2SCharles.Forsyth 
9374a4d8c2SCharles.Forsyth 	if(p = strchr(line, '!')) {
9474a4d8c2SCharles.Forsyth 		*p++ = 0;
9574a4d8c2SCharles.Forsyth 		*file = p;
9674a4d8c2SCharles.Forsyth 	} else
9774a4d8c2SCharles.Forsyth 		*file = "";
9874a4d8c2SCharles.Forsyth 
9974a4d8c2SCharles.Forsyth 	for(tp = types; tp->type != Tnil; tp++)
10074a4d8c2SCharles.Forsyth 		for(mp = tp->media; mp; mp = mp->next)
10174a4d8c2SCharles.Forsyth 			if(strcmp(mp->name, line) == 0)
10274a4d8c2SCharles.Forsyth 				return mp;
10374a4d8c2SCharles.Forsyth 	return nil;
10474a4d8c2SCharles.Forsyth }
10574a4d8c2SCharles.Forsyth 
10674a4d8c2SCharles.Forsyth static int
boot(Medium * mp,char * file)10774a4d8c2SCharles.Forsyth boot(Medium *mp, char *file)
10874a4d8c2SCharles.Forsyth {
10974a4d8c2SCharles.Forsyth 	static Boot b;
11074a4d8c2SCharles.Forsyth 
11174a4d8c2SCharles.Forsyth 	memset(&b, 0, sizeof b);
11274a4d8c2SCharles.Forsyth 	b.state = INIT9LOAD;
11374a4d8c2SCharles.Forsyth 
11474a4d8c2SCharles.Forsyth //	sprint(BOOTLINE, "%s!%s", mp->name, file);
11574a4d8c2SCharles.Forsyth 	return (*mp->type->boot)(mp->dev, file, &b);
11674a4d8c2SCharles.Forsyth }
11774a4d8c2SCharles.Forsyth 
11874a4d8c2SCharles.Forsyth static Medium*
allocm(Type * tp)11974a4d8c2SCharles.Forsyth allocm(Type *tp)
12074a4d8c2SCharles.Forsyth {
12174a4d8c2SCharles.Forsyth 	Medium **l;
12274a4d8c2SCharles.Forsyth 
12374a4d8c2SCharles.Forsyth 	if(curmedium >= &media[Nmedia])
12474a4d8c2SCharles.Forsyth 		return 0;
12574a4d8c2SCharles.Forsyth 
12674a4d8c2SCharles.Forsyth 	for(l = &tp->media; *l; l = &(*l)->next)
12774a4d8c2SCharles.Forsyth 		;
12874a4d8c2SCharles.Forsyth 	*l = curmedium++;
12974a4d8c2SCharles.Forsyth 	return *l;
13074a4d8c2SCharles.Forsyth }
13174a4d8c2SCharles.Forsyth 
13274a4d8c2SCharles.Forsyth char *parts[] = { "dos", "9fat", "fs", 0 };
13374a4d8c2SCharles.Forsyth 
13474a4d8c2SCharles.Forsyth Medium*
probe(int type,int flag,int dev)13574a4d8c2SCharles.Forsyth probe(int type, int flag, int dev)
13674a4d8c2SCharles.Forsyth {
13774a4d8c2SCharles.Forsyth 	Type *tp;
13874a4d8c2SCharles.Forsyth 	int i;
13974a4d8c2SCharles.Forsyth 	Medium *mp;
14074a4d8c2SCharles.Forsyth 
14174a4d8c2SCharles.Forsyth 	for(tp = types; tp->type != Tnil; tp++){
14274a4d8c2SCharles.Forsyth 		if(type != Tany && type != tp->type)
14374a4d8c2SCharles.Forsyth 			continue;
14474a4d8c2SCharles.Forsyth 
14574a4d8c2SCharles.Forsyth 		if(flag != Fnone){
14674a4d8c2SCharles.Forsyth 			for(mp = tp->media; mp; mp = mp->next){
14774a4d8c2SCharles.Forsyth 				if((flag & mp->flag) && (dev == Dany || dev == mp->dev))
14874a4d8c2SCharles.Forsyth 					return mp;
14974a4d8c2SCharles.Forsyth 			}
15074a4d8c2SCharles.Forsyth 		}
15174a4d8c2SCharles.Forsyth 
15274a4d8c2SCharles.Forsyth 		if((tp->flag & Fprobe) == 0){
15374a4d8c2SCharles.Forsyth 			tp->flag |= Fprobe;
15474a4d8c2SCharles.Forsyth 			tp->mask = (*tp->init)();
15574a4d8c2SCharles.Forsyth 		}
15674a4d8c2SCharles.Forsyth 
15774a4d8c2SCharles.Forsyth 		for(i = 0; tp->mask; i++){
15874a4d8c2SCharles.Forsyth 			if((tp->mask & (1<<i)) == 0)
15974a4d8c2SCharles.Forsyth 				continue;
16074a4d8c2SCharles.Forsyth 			tp->mask &= ~(1<<i);
16174a4d8c2SCharles.Forsyth 
16274a4d8c2SCharles.Forsyth 			if((mp = allocm(tp)) == 0)
16374a4d8c2SCharles.Forsyth 				continue;
16474a4d8c2SCharles.Forsyth 
16574a4d8c2SCharles.Forsyth 			mp->dev = i;
16674a4d8c2SCharles.Forsyth 			mp->flag = tp->flag;
16774a4d8c2SCharles.Forsyth 			mp->type = tp;
16874a4d8c2SCharles.Forsyth 			(*tp->initdev)(i, mp->name);
16974a4d8c2SCharles.Forsyth 
17074a4d8c2SCharles.Forsyth 			if((flag & mp->flag) && (dev == Dany || dev == i))
17174a4d8c2SCharles.Forsyth 				return mp;
17274a4d8c2SCharles.Forsyth 		}
17374a4d8c2SCharles.Forsyth 	}
17474a4d8c2SCharles.Forsyth 
17574a4d8c2SCharles.Forsyth 	return 0;
17674a4d8c2SCharles.Forsyth }
17774a4d8c2SCharles.Forsyth 
17874a4d8c2SCharles.Forsyth extern int loopconst;
17974a4d8c2SCharles.Forsyth void
main(void)18074a4d8c2SCharles.Forsyth main(void)
18174a4d8c2SCharles.Forsyth {
18274a4d8c2SCharles.Forsyth 	Medium *mp;
18374a4d8c2SCharles.Forsyth 	int flag;
18474a4d8c2SCharles.Forsyth 	char def[2*NAMELEN], line[80], *p, *file;
18574a4d8c2SCharles.Forsyth 	Type *tp;
18674a4d8c2SCharles.Forsyth 
18774a4d8c2SCharles.Forsyth 	i8042a20();
18874a4d8c2SCharles.Forsyth 	memset(m, 0, sizeof(Mach));
18974a4d8c2SCharles.Forsyth 	trapinit();
19074a4d8c2SCharles.Forsyth 	clockinit();
19174a4d8c2SCharles.Forsyth 	alarminit();
19274a4d8c2SCharles.Forsyth 	spllo();
19374a4d8c2SCharles.Forsyth 
19474a4d8c2SCharles.Forsyth 	kbdinit();
19574a4d8c2SCharles.Forsyth 
19674a4d8c2SCharles.Forsyth 	if((ulong)&end > (KZERO|(640*1024)))
19774a4d8c2SCharles.Forsyth 		panic("i'm too big");
19874a4d8c2SCharles.Forsyth 
19974a4d8c2SCharles.Forsyth 	/*
20074a4d8c2SCharles.Forsyth 	 * If there were any arguments, MS-DOS leaves a character
20174a4d8c2SCharles.Forsyth 	 * count followed by the arguments in the runtime header.
20274a4d8c2SCharles.Forsyth 	 * Step over the leading space.
20374a4d8c2SCharles.Forsyth 	 */
20474a4d8c2SCharles.Forsyth 	p = (char*)0x80080080;
20574a4d8c2SCharles.Forsyth 	if(p[0]){
20674a4d8c2SCharles.Forsyth 		p[p[0]+1] = 0;
20774a4d8c2SCharles.Forsyth 		p += 2;
20874a4d8c2SCharles.Forsyth 	}
20974a4d8c2SCharles.Forsyth 	else
21074a4d8c2SCharles.Forsyth 		p = 0;
21174a4d8c2SCharles.Forsyth 
21274a4d8c2SCharles.Forsyth 	/*
21374a4d8c2SCharles.Forsyth 	 * Advance command line to first option, if any
21474a4d8c2SCharles.Forsyth 	 */
21574a4d8c2SCharles.Forsyth 	if(p) {
21674a4d8c2SCharles.Forsyth 		while(*p==' ' || *p=='\t')
21774a4d8c2SCharles.Forsyth 			p++;
21874a4d8c2SCharles.Forsyth 		if(*p == 0)
21974a4d8c2SCharles.Forsyth 			p = nil;
22074a4d8c2SCharles.Forsyth 	}
22174a4d8c2SCharles.Forsyth 
22274a4d8c2SCharles.Forsyth 	/*
22374a4d8c2SCharles.Forsyth  	 * Probe everything, to collect device names.
22474a4d8c2SCharles.Forsyth 	 */
22574a4d8c2SCharles.Forsyth 	probe(Tany, Fnone, Dany);
22674a4d8c2SCharles.Forsyth 
22774a4d8c2SCharles.Forsyth 	if(p != 0) {
22874a4d8c2SCharles.Forsyth 		if((mp = parse(p, &file)) == nil) {
22974a4d8c2SCharles.Forsyth 			print("bad loadfile syntax: %s\n", p);
23074a4d8c2SCharles.Forsyth 			goto done;
23174a4d8c2SCharles.Forsyth 		}
23274a4d8c2SCharles.Forsyth 		boot(mp, file);
23374a4d8c2SCharles.Forsyth 	}
23474a4d8c2SCharles.Forsyth 
23574a4d8c2SCharles.Forsyth done:
23674a4d8c2SCharles.Forsyth 	flag = 0;
23774a4d8c2SCharles.Forsyth 	for(tp = types; tp->type != Tnil; tp++){
23874a4d8c2SCharles.Forsyth 		for(mp = tp->media; mp; mp = mp->next){
23974a4d8c2SCharles.Forsyth 			if(flag == 0){
24074a4d8c2SCharles.Forsyth 				flag = 1;
24174a4d8c2SCharles.Forsyth 				print("Load devices:");
24274a4d8c2SCharles.Forsyth 			}
24374a4d8c2SCharles.Forsyth 			print(" %s", mp->name);
24474a4d8c2SCharles.Forsyth 		}
24574a4d8c2SCharles.Forsyth 	}
24674a4d8c2SCharles.Forsyth 	if(flag)
24774a4d8c2SCharles.Forsyth 		print("\n");
24874a4d8c2SCharles.Forsyth 
24974a4d8c2SCharles.Forsyth 	for(;;){
25074a4d8c2SCharles.Forsyth 		if(getstr("load from", line, sizeof(line), nil, 0) >= 0)
25174a4d8c2SCharles.Forsyth 			if(mp = parse(line, &file))
25274a4d8c2SCharles.Forsyth 				boot(mp, file);
25374a4d8c2SCharles.Forsyth 		def[0] = 0;
25474a4d8c2SCharles.Forsyth 	}
25574a4d8c2SCharles.Forsyth }
25674a4d8c2SCharles.Forsyth 
25774a4d8c2SCharles.Forsyth int
getfields(char * lp,char ** fields,int n,char sep)25874a4d8c2SCharles.Forsyth getfields(char *lp, char **fields, int n, char sep)
25974a4d8c2SCharles.Forsyth {
26074a4d8c2SCharles.Forsyth 	int i;
26174a4d8c2SCharles.Forsyth 
26274a4d8c2SCharles.Forsyth 	for(i = 0; lp && *lp && i < n; i++){
26374a4d8c2SCharles.Forsyth 		while(*lp == sep)
26474a4d8c2SCharles.Forsyth 			*lp++ = 0;
26574a4d8c2SCharles.Forsyth 		if(*lp == 0)
26674a4d8c2SCharles.Forsyth 			break;
26774a4d8c2SCharles.Forsyth 		fields[i] = lp;
26874a4d8c2SCharles.Forsyth 		while(*lp && *lp != sep){
26974a4d8c2SCharles.Forsyth 			if(*lp == '\\' && *(lp+1) == '\n')
27074a4d8c2SCharles.Forsyth 				*lp++ = ' ';
27174a4d8c2SCharles.Forsyth 			lp++;
27274a4d8c2SCharles.Forsyth 		}
27374a4d8c2SCharles.Forsyth 	}
27474a4d8c2SCharles.Forsyth 	return i;
27574a4d8c2SCharles.Forsyth }
27674a4d8c2SCharles.Forsyth 
27774a4d8c2SCharles.Forsyth int
cistrcmp(char * a,char * b)27874a4d8c2SCharles.Forsyth cistrcmp(char *a, char *b)
27974a4d8c2SCharles.Forsyth {
28074a4d8c2SCharles.Forsyth 	int ac, bc;
28174a4d8c2SCharles.Forsyth 
28274a4d8c2SCharles.Forsyth 	for(;;){
28374a4d8c2SCharles.Forsyth 		ac = *a++;
28474a4d8c2SCharles.Forsyth 		bc = *b++;
28574a4d8c2SCharles.Forsyth 
28674a4d8c2SCharles.Forsyth 		if(ac >= 'A' && ac <= 'Z')
28774a4d8c2SCharles.Forsyth 			ac = 'a' + (ac - 'A');
28874a4d8c2SCharles.Forsyth 		if(bc >= 'A' && bc <= 'Z')
28974a4d8c2SCharles.Forsyth 			bc = 'a' + (bc - 'A');
29074a4d8c2SCharles.Forsyth 		ac -= bc;
29174a4d8c2SCharles.Forsyth 		if(ac)
29274a4d8c2SCharles.Forsyth 			return ac;
29374a4d8c2SCharles.Forsyth 		if(bc == 0)
29474a4d8c2SCharles.Forsyth 			break;
29574a4d8c2SCharles.Forsyth 	}
29674a4d8c2SCharles.Forsyth 	return 0;
29774a4d8c2SCharles.Forsyth }
29874a4d8c2SCharles.Forsyth 
29974a4d8c2SCharles.Forsyth int
cistrncmp(char * a,char * b,int n)30074a4d8c2SCharles.Forsyth cistrncmp(char *a, char *b, int n)
30174a4d8c2SCharles.Forsyth {
30274a4d8c2SCharles.Forsyth 	unsigned ac, bc;
30374a4d8c2SCharles.Forsyth 
30474a4d8c2SCharles.Forsyth 	while(n > 0){
30574a4d8c2SCharles.Forsyth 		ac = *a++;
30674a4d8c2SCharles.Forsyth 		bc = *b++;
30774a4d8c2SCharles.Forsyth 		n--;
30874a4d8c2SCharles.Forsyth 
30974a4d8c2SCharles.Forsyth 		if(ac >= 'A' && ac <= 'Z')
31074a4d8c2SCharles.Forsyth 			ac = 'a' + (ac - 'A');
31174a4d8c2SCharles.Forsyth 		if(bc >= 'A' && bc <= 'Z')
31274a4d8c2SCharles.Forsyth 			bc = 'a' + (bc - 'A');
31374a4d8c2SCharles.Forsyth 
31474a4d8c2SCharles.Forsyth 		ac -= bc;
31574a4d8c2SCharles.Forsyth 		if(ac)
31674a4d8c2SCharles.Forsyth 			return ac;
31774a4d8c2SCharles.Forsyth 		if(bc == 0)
31874a4d8c2SCharles.Forsyth 			break;
31974a4d8c2SCharles.Forsyth 	}
32074a4d8c2SCharles.Forsyth 
32174a4d8c2SCharles.Forsyth 	return 0;
32274a4d8c2SCharles.Forsyth }
32374a4d8c2SCharles.Forsyth 
32474a4d8c2SCharles.Forsyth void*
ialloc(ulong n,int align)32574a4d8c2SCharles.Forsyth ialloc(ulong n, int align)
32674a4d8c2SCharles.Forsyth {
32774a4d8c2SCharles.Forsyth 
32874a4d8c2SCharles.Forsyth 	static ulong palloc;
32974a4d8c2SCharles.Forsyth 	ulong p;
33074a4d8c2SCharles.Forsyth 	int a;
33174a4d8c2SCharles.Forsyth 
33274a4d8c2SCharles.Forsyth 	if(palloc == 0)
33374a4d8c2SCharles.Forsyth 		palloc = 3*1024*1024;
33474a4d8c2SCharles.Forsyth 
33574a4d8c2SCharles.Forsyth 	p = palloc;
33674a4d8c2SCharles.Forsyth 	if(align <= 0)
33774a4d8c2SCharles.Forsyth 		align = 4;
33874a4d8c2SCharles.Forsyth 	if(a = n % align)
33974a4d8c2SCharles.Forsyth 		n += align - a;
34074a4d8c2SCharles.Forsyth 	if(a = p % align)
34174a4d8c2SCharles.Forsyth 		p += align - a;
34274a4d8c2SCharles.Forsyth 
34374a4d8c2SCharles.Forsyth 	palloc = p+n;
34474a4d8c2SCharles.Forsyth 
34574a4d8c2SCharles.Forsyth 	return memset((void*)(p|KZERO), 0, n);
34674a4d8c2SCharles.Forsyth }
34774a4d8c2SCharles.Forsyth 
34874a4d8c2SCharles.Forsyth void*
xspanalloc(ulong size,int align,ulong span)34974a4d8c2SCharles.Forsyth xspanalloc(ulong size, int align, ulong span)
35074a4d8c2SCharles.Forsyth {
35174a4d8c2SCharles.Forsyth 	ulong a, v;
35274a4d8c2SCharles.Forsyth 
35374a4d8c2SCharles.Forsyth 	a = (ulong)ialloc(size+align+span, 0);
35474a4d8c2SCharles.Forsyth 
35574a4d8c2SCharles.Forsyth 	if(span > 2)
35674a4d8c2SCharles.Forsyth 		v = (a + span) & ~(span-1);
35774a4d8c2SCharles.Forsyth 	else
35874a4d8c2SCharles.Forsyth 		v = a;
35974a4d8c2SCharles.Forsyth 
36074a4d8c2SCharles.Forsyth 	if(align > 1)
36174a4d8c2SCharles.Forsyth 		v = (v + align) & ~(align-1);
36274a4d8c2SCharles.Forsyth 
36374a4d8c2SCharles.Forsyth 	return (void*)v;
36474a4d8c2SCharles.Forsyth }
36574a4d8c2SCharles.Forsyth 
36674a4d8c2SCharles.Forsyth static Block *allocbp;
36774a4d8c2SCharles.Forsyth 
36874a4d8c2SCharles.Forsyth Block*
allocb(int size)36974a4d8c2SCharles.Forsyth allocb(int size)
37074a4d8c2SCharles.Forsyth {
37174a4d8c2SCharles.Forsyth 	Block *bp, **lbp;
37274a4d8c2SCharles.Forsyth 	ulong addr;
37374a4d8c2SCharles.Forsyth 
37474a4d8c2SCharles.Forsyth 	lbp = &allocbp;
37574a4d8c2SCharles.Forsyth 	for(bp = *lbp; bp; bp = bp->next){
37674a4d8c2SCharles.Forsyth 		if((bp->lim - bp->base) >= size){
37774a4d8c2SCharles.Forsyth 			*lbp = bp->next;
37874a4d8c2SCharles.Forsyth 			break;
37974a4d8c2SCharles.Forsyth 		}
38074a4d8c2SCharles.Forsyth 		lbp = &bp->next;
38174a4d8c2SCharles.Forsyth 	}
38274a4d8c2SCharles.Forsyth 	if(bp == 0){
38374a4d8c2SCharles.Forsyth 		bp = ialloc(sizeof(Block)+size+64, 0);
38474a4d8c2SCharles.Forsyth 		addr = (ulong)bp;
38574a4d8c2SCharles.Forsyth 		addr = ROUNDUP(addr + sizeof(Block), 8);
38674a4d8c2SCharles.Forsyth 		bp->base = (uchar*)addr;
38774a4d8c2SCharles.Forsyth 		bp->lim = ((uchar*)bp) + sizeof(Block)+size+64;
38874a4d8c2SCharles.Forsyth 	}
38974a4d8c2SCharles.Forsyth 
39074a4d8c2SCharles.Forsyth 	if(bp->flag)
39174a4d8c2SCharles.Forsyth 		panic("allocb reuse\n");
39274a4d8c2SCharles.Forsyth 
39374a4d8c2SCharles.Forsyth 	bp->rp = bp->base;
39474a4d8c2SCharles.Forsyth 	bp->wp = bp->rp;
39574a4d8c2SCharles.Forsyth 	bp->next = 0;
39674a4d8c2SCharles.Forsyth 	bp->flag = 1;
39774a4d8c2SCharles.Forsyth 
39874a4d8c2SCharles.Forsyth 	return bp;
39974a4d8c2SCharles.Forsyth }
40074a4d8c2SCharles.Forsyth 
40174a4d8c2SCharles.Forsyth void
freeb(Block * bp)40274a4d8c2SCharles.Forsyth freeb(Block* bp)
40374a4d8c2SCharles.Forsyth {
40474a4d8c2SCharles.Forsyth 	bp->next = allocbp;
40574a4d8c2SCharles.Forsyth 	allocbp = bp;
40674a4d8c2SCharles.Forsyth 
40774a4d8c2SCharles.Forsyth 	bp->flag = 0;
40874a4d8c2SCharles.Forsyth }
40974a4d8c2SCharles.Forsyth 
41074a4d8c2SCharles.Forsyth enum {
41174a4d8c2SCharles.Forsyth 	Paddr=		0x70,	/* address port */
41274a4d8c2SCharles.Forsyth 	Pdata=		0x71,	/* data port */
41374a4d8c2SCharles.Forsyth };
41474a4d8c2SCharles.Forsyth 
41574a4d8c2SCharles.Forsyth uchar
nvramread(int offset)41674a4d8c2SCharles.Forsyth nvramread(int offset)
41774a4d8c2SCharles.Forsyth {
41874a4d8c2SCharles.Forsyth 	outb(Paddr, offset);
41974a4d8c2SCharles.Forsyth 	return inb(Pdata);
42074a4d8c2SCharles.Forsyth }
42174a4d8c2SCharles.Forsyth 
42274a4d8c2SCharles.Forsyth void (*etherdetach)(void);
42374a4d8c2SCharles.Forsyth void (*floppydetach)(void);
42474a4d8c2SCharles.Forsyth void (*sddetach)(void);
42574a4d8c2SCharles.Forsyth 
42674a4d8c2SCharles.Forsyth void
warp9(ulong entry)42774a4d8c2SCharles.Forsyth warp9(ulong entry)
42874a4d8c2SCharles.Forsyth {
42974a4d8c2SCharles.Forsyth 	if(etherdetach)
43074a4d8c2SCharles.Forsyth 		etherdetach();
43174a4d8c2SCharles.Forsyth 	consdrain();
43274a4d8c2SCharles.Forsyth 	(*(void(*)(void))(PADDR(entry)))();
43374a4d8c2SCharles.Forsyth }
43474a4d8c2SCharles.Forsyth 
43574a4d8c2SCharles.Forsyth char*
getconf(char *)43674a4d8c2SCharles.Forsyth getconf(char*)
43774a4d8c2SCharles.Forsyth {
43874a4d8c2SCharles.Forsyth 	return nil;
43974a4d8c2SCharles.Forsyth }
44074a4d8c2SCharles.Forsyth 
44174a4d8c2SCharles.Forsyth void
addconf(char *,...)44274a4d8c2SCharles.Forsyth addconf(char*, ...)
44374a4d8c2SCharles.Forsyth {
44474a4d8c2SCharles.Forsyth }
44574a4d8c2SCharles.Forsyth 
44674a4d8c2SCharles.Forsyth void
uartspecial(int,void (*)(int),int (*)(void),int)44774a4d8c2SCharles.Forsyth uartspecial(int, void(*)(int), int(*)(void), int)
44874a4d8c2SCharles.Forsyth {
44974a4d8c2SCharles.Forsyth }
45074a4d8c2SCharles.Forsyth 
45174a4d8c2SCharles.Forsyth void
uartputs(IOQ *,char *,int)45274a4d8c2SCharles.Forsyth uartputs(IOQ*, char*, int)
45374a4d8c2SCharles.Forsyth {
45474a4d8c2SCharles.Forsyth }
45574a4d8c2SCharles.Forsyth 
45674a4d8c2SCharles.Forsyth void
uartputc(int)45774a4d8c2SCharles.Forsyth uartputc(int)
45874a4d8c2SCharles.Forsyth {}
45974a4d8c2SCharles.Forsyth 
46074a4d8c2SCharles.Forsyth void
uartdrain(void)46174a4d8c2SCharles.Forsyth uartdrain(void)
46274a4d8c2SCharles.Forsyth {
46374a4d8c2SCharles.Forsyth }
464