shithub: 9ferno

Download patch

ref: 5c30140aa4d842dbb700cd6c8b9d7296fd91da84
parent: 72db5b394c55a4fecc11f7af3faad04b5bc755ba
author: joe9 <joe9mail@gmail.com>
date: Sat Jul 17 02:27:44 EDT 2021

moving inferno os/boot away

diff: cannot open a/os/boot/arm1110//null: 'a/os/boot/arm1110//null' does not exist diff: cannot open a/os/boot/libflate//null: 'a/os/boot/libflate//null' does not exist diff: cannot open a/os/boot/mpc//null: 'a/os/boot/mpc//null' does not exist diff 8247188: suicide: sys: trap: fault write addr=0x0 pc=0x202952 diff 8247194: suicide: sys: trap: fault write addr=0x0 pc=0x202952 diff: cannot open a/os/boot/pc//null: 'a/os/boot/pc//null' does not exist diff: cannot open a/os/boot/puma//null: 'a/os/boot/puma//null' does not exist diff 8247505: suicide: sys: trap: fault write addr=0x0 pc=0x202952 diff 8247517: suicide: sys: trap: fault write addr=0x0 pc=0x202952 diff: cannot open a/os/boot/rpcg//null: 'a/os/boot/rpcg//null' does not exist diff: cannot open a/os/boot//null: 'a/os/boot//null' does not exist diff: cannot open b/os/boot.original/arm1110//null: 'b/os/boot.original/arm1110//null' does not exist diff: cannot open b/os/boot.original/libflate//null: 'b/os/boot.original/libflate//null' does not exist diff: cannot open b/os/boot.original/mpc//null: 'b/os/boot.original/mpc//null' does not exist diff 8248027: suicide: sys: trap: fault write addr=0x0 pc=0x202952 diff 8248033: suicide: sys: trap: fault write addr=0x0 pc=0x202952 diff: cannot open b/os/boot.original/pc//null: 'b/os/boot.original/pc//null' does not exist diff: cannot open b/os/boot.original/puma//null: 'b/os/boot.original/puma//null' does not exist diff 8248342: suicide: sys: trap: fault write addr=0x0 pc=0x202952 diff 8248359: suicide: sys: trap: fault write addr=0x0 pc=0x202952 diff: cannot open b/os/boot.original/rpcg//null: 'b/os/boot.original/rpcg//null' does not exist diff: cannot open b/os/boot.original//null: 'b/os/boot.original//null' does not exist
--- a/os/boot/README
+++ /dev/null
@@ -1,33 +1,0 @@
-Often the devices we use now come with some
-form of bootstrap (often annoyingly complicated,
-which gets in the way).  Older boards were sometimes
-bare, and we had to provide something (often annoyingly
-complicated...).  On the PC it's currently helpful to
-have something that can boot from disc or ether;
-since it's a thankless task to write such a thing, we
-use Plan 9's, and thank its authors.
-
-The current scheme on newer devices is to have a simple
-program that can put a stripped-down Inferno kernel into
-flash, and use that to boot from other devices (including over the net)
-as required during development.
-
-There are two distinct models for bootstrap in this directory.
-
-	Model I
-
-Each member of the first model is represented by a self-contained directory.
-They are derived from various ages of Plan 9's /sys/src/boot/pc.
-
-arm1110	arm	a prefix to a gzip'd kernel to decompress it (runs after basic bootloader)
-pc	386	pc-specific bootstrap essentially identical to current Plan 9
-		and covered by the Lucent Public License; it uses
-libflate	-	zlib-style inflate/deflate library
-mpc	power	PowerPC bootstrap for FADS board derived from an older version
-		of Plan 9 but covered by our Inferno licence (because it came with Inferno)
-puma	arm	SA110 bootstrap for Teralogics Puma, also covered by the Inferno licence
-
-	Model II
-omap	purpose-built bootstrap for the OMAP processor
-
-Not all of these are being distributed.
--- a/os/boot/arm1110/Mk
+++ /dev/null
@@ -1,8 +1,0 @@
-#!/bin/rc
-rfork ne
-ROOT=/usr/inferno
-fn cd
-NPROC=3
-path=(/usr/inferno/Plan9/$cputype/bin $path)
-#bind /usr/inferno/mkconfig.dist /usr/inferno/mkconfig
-exec mk $*
--- a/os/boot/arm1110/dat.h
+++ /dev/null
@@ -1,1 +1,0 @@
-/* deliberately empty */
--- a/os/boot/arm1110/donprint.c
+++ /dev/null
@@ -1,332 +1,0 @@
-#include	"u.h"
-#include	"lib.h"
-
-#define	PTR	sizeof(char*)
-#define	SHORT	sizeof(int)
-#define	INT	sizeof(int)
-#define	LONG	sizeof(long)
-#define	IDIGIT	30
-#define	MAXCON	30
-
-#define	FLONG	(1<<0)
-#define	FSHORT	(1<<1)
-#define	FUNSIGN	(1<<2)
-
-typedef struct Op	Op;
-struct Op
-{
-	char	*p;
-	char	*ep;
-	void	*argp;
-	int	f1;
-	int	f2;
-	int	f3;
-};
-
-static	int	noconv(Op*);
-static	int	cconv(Op*);
-static	int	dconv(Op*);
-static	int	hconv(Op*);
-static	int	lconv(Op*);
-static	int	oconv(Op*);
-static	int	sconv(Op*);
-static	int	uconv(Op*);
-static	int	xconv(Op*);
-static	int	Xconv(Op*);
-static	int	percent(Op*);
-
-static
-int	(*fmtconv[MAXCON])(Op*) =
-{
-	noconv,
-	cconv, dconv, hconv, lconv,
-	oconv, sconv, uconv, xconv,
-	Xconv, percent,
-};
-static
-char	fmtindex[128] =
-{
-	['c'] 1,
-	['d'] 2,
-	['h'] 3,
-	['l'] 4,
-	['o'] 5,
-	['s'] 6,
-	['u'] 7,
-	['x'] 8,
-	['X'] 9,
-	['%'] 10,
-};
-
-static	int	convcount  = { 11 };
-static	int	ucase;
-
-static void
-PUT(Op *o, int c)
-{
-	static int pos;
-	int opos;
-
-	if(c == '\t'){
-		opos = pos;
-		pos = (opos+8) & ~7;
-		while(opos++ < pos && o->p < o->ep)
-			*o->p++ = ' ';
-		return;
-	}
-	if(o->p < o->ep){
-		*o->p++ = c;
-		pos++;
-	}
-	if(c == '\n')
-		pos = 0;
-}
-
-int
-fmtinstall(char c, int (*f)(Op*))
-{
-
-	c &= 0177;
-	if(fmtindex[c] == 0) {
-		if(convcount >= MAXCON)
-			return 1;
-		fmtindex[c] = convcount++;
-	}
-	fmtconv[fmtindex[c]] = f;
-	return 0;
-}
-
-char*
-donprint(char *p, char *ep, char *fmt, void *argp)
-{
-	int sf1, c;
-	Op o;
-
-	o.p = p;
-	o.ep = ep;
-	o.argp = argp;
-
-loop:
-	c = *fmt++;
-	if(c != '%') {
-		if(c == 0) {
-			if(o.p < o.ep)
-				*o.p = 0;
-			return o.p;
-		}
-		PUT(&o, c);
-		goto loop;
-	}
-	o.f1 = 0;
-	o.f2 = -1;
-	o.f3 = 0;
-	c = *fmt++;
-	sf1 = 0;
-	if(c == '-') {
-		sf1 = 1;
-		c = *fmt++;
-	}
-	while(c >= '0' && c <= '9') {
-		o.f1 = o.f1*10 + c-'0';
-		c = *fmt++;
-	}
-	if(sf1)
-		o.f1 = -o.f1;
-	if(c != '.')
-		goto l1;
-	c = *fmt++;
-	while(c >= '0' && c <= '9') {
-		if(o.f2 < 0)
-			o.f2 = 0;
-		o.f2 = o.f2*10 + c-'0';
-		c = *fmt++;
-	}
-l1:
-	if(c == 0)
-		fmt--;
-	c = (*fmtconv[fmtindex[c&0177]])(&o);
-	if(c < 0) {
-		o.f3 |= -c;
-		c = *fmt++;
-		goto l1;
-	}
-	o.argp = (char*)o.argp + c;
-	goto loop;
-}
-
-void
-strconv(char *o, Op *op, int f1, int f2)
-{
-	int n, c;
-	char *p;
-
-	n = strlen(o);
-	if(f1 >= 0)
-		while(n < f1) {
-			PUT(op, ' ');
-			n++;
-		}
-	for(p=o; c = *p++;)
-		if(f2 != 0) {
-			PUT(op, c);
-			f2--;
-		}
-	if(f1 < 0) {
-		f1 = -f1;
-		while(n < f1) {
-			PUT(op, ' ');
-			n++;
-		}
-	}
-}
-
-int
-numbconv(Op *op, int base)
-{
-	char b[IDIGIT];
-	int i, f, n, r;
-	long v;
-	short h;
-
-	f = 0;
-	switch(op->f3 & (FLONG|FSHORT|FUNSIGN)) {
-	case FLONG:
-		v = *(long*)op->argp;
-		r = LONG;
-		break;
-
-	case FUNSIGN|FLONG:
-		v = *(ulong*)op->argp;
-		r = LONG;
-		break;
-
-	case FSHORT:
-		h = *(int*)op->argp;
-		v = h;
-		r = SHORT;
-		break;
-
-	case FUNSIGN|FSHORT:
-		h = *(int*)op->argp;
-		v = (ushort)h;
-		r = SHORT;
-		break;
-
-	default:
-		v = *(int*)op->argp;
-		r = INT;
-		break;
-
-	case FUNSIGN:
-		v = *(unsigned*)op->argp;
-		r = INT;
-		break;
-	}
-	if(!(op->f3 & FUNSIGN) && v < 0) {
-		v = -v;
-		f = 1;
-	}
-	b[IDIGIT-1] = 0;
-	for(i = IDIGIT-2;; i--) {
-		n = (ulong)v % base;
-		n += '0';
-		if(n > '9'){
-			n += 'a' - ('9'+1);
-			if(ucase)
-				n += 'A'-'a';
-		}
-		b[i] = n;
-		if(i < 2)
-			break;
-		v = (ulong)v / base;
-		if(op->f2 >= 0 && i >= IDIGIT-op->f2)
-			continue;
-		if(v <= 0)
-			break;
-	}
-	if(f)
-		b[--i] = '-';
-	strconv(b+i, op, op->f1, -1);
-	return r;
-}
-
-static	int
-noconv(Op *op)
-{
-
-	strconv("***", op, 0, -1);
-	return 0;
-}
-
-static	int
-cconv(Op *op)
-{
-	char b[2];
-
-	b[0] = *(int*)op->argp;
-	b[1] = 0;
-	strconv(b, op, op->f1, -1);
-	return INT;
-}
-
-static	int
-dconv(Op *op)
-{
-	return numbconv(op, 10);
-}
-
-static	int
-hconv(Op*)
-{
-	return -FSHORT;
-}
-
-static	int
-lconv(Op*)
-{
-	return -FLONG;
-}
-
-static	int
-oconv(Op *op)
-{
-	return numbconv(op, 8);
-}
-
-static	int
-sconv(Op *op)
-{
-	strconv(*(char**)op->argp, op, op->f1, op->f2);
-	return PTR;
-}
-
-static	int
-uconv(Op*)
-{
-	return -FUNSIGN;
-}
-
-static	int
-xconv(Op *op)
-{
-	return numbconv(op, 16);
-}
-
-static	int
-Xconv(Op *op)
-{
-	int r;
-
-	ucase = 1;
-	r = numbconv(op, 16);
-	ucase = 0;
-	return r;
-}
-
-static	int
-percent(Op *op)
-{
-
-	PUT(op, '%');
-	return 0;
-}
--- a/os/boot/arm1110/fns.h
+++ /dev/null
@@ -1,7 +1,0 @@
-/*
- *  functions defined locally
- */
-extern int	gunzip(uchar *out, int outn, uchar *in, int inn);
-extern void	delay(int ms);
-extern void	serialputs(char *str, int n);
-extern void	draincache(void);
--- a/os/boot/arm1110/il.s
+++ /dev/null
@@ -1,99 +1,0 @@
-#include "mem.h"
-/*
- *  Entered here from Compaq's bootldr.  First relocate to
- *  the location we're linked for and then copy back the
- *  decompressed kernel.
- *
- *  All 
- */
-TEXT _start(SB), $-4
-	MOVW	$setR12(SB), R12		/* load the SB */
-	MOVW	$1, R0		/* dance to make 5l think that the magic */
-	MOVW	$1, R1		/* numbers in WORDs below are being used */
-	CMP.S	R0, R1		/* and to align them to where bootldr wants */
-	BEQ	_start2
-	WORD	$0x016f2818	/* magic number to say we are a kernel */
-	WORD	$0xc0008000	/* entry point address */
-	WORD	$0		/* size?, or end of data? */
-
-_start2:
-
-	/* SVC mode, interrupts disabled */
-	MOVW	$(PsrDirq|PsrDfiq|PsrMsvc), R1
-	MOVW	R1, CPSR
-
-	/* disable the MMU */
-	MOVW	$0x130, R1
-	MCR     CpMMU, 0, R1, C(CpControl), C(0x0)
-
-	/* enable caches */
-	MRC	CpMMU, 0, R0, C(CpControl), C(0x0)
-	ORR	$(CpCdcache|CpCicache|CpCwb), R0
-	MCR     CpMMU, 0, R0, C(CpControl), C(0x0)
-
-	/* flush caches */
-	MCR	CpMMU, 0, R0, C(CpCacheFlush), C(0x7), 0
-	/* drain prefetch */
-	MOVW	R0,R0						
-	MOVW	R0,R0
-	MOVW	R0,R0
-	MOVW	R0,R0
-
-	/* drain write buffer */
-	MCR	CpMMU, 0, R0, C(CpCacheFlush), C(0xa), 4
-
-	/* relocate to where we expect to be */
-	MOVW	$(FLATESIZE),R3
-	MOVW	$0xC0008000,R1
-	MOVW	$0xC0200000,R2
-	ADD	R1,R3
-_relloop:
-	MOVW	(R1),R0
-	MOVW	R0,(R2)
-	ADD	$4,R1
-	ADD	$4,R2
-	CMP.S	R1,R3
-	BNE	_relloop
-
-	MOVW	$(MACHADDR+BY2PG), R13		/* stack */
-	SUB	$4, R13				/* link */
-
-	/* jump to where we've been relocated */
-	MOVW	$_relocated(SB),R15
-
-TEXT _relocated(SB),$-4
-	BL	main(SB)
-	BL	exit(SB)
-	/* we shouldn't get here */
-_mainloop:
-	B	_mainloop
-	BL	_div(SB)			/* hack to get _div etc loaded */
-
-TEXT mypc(SB),$-4
-	MOVW	R14,R0
-	RET
-
-TEXT draincache(SB),$-4
-	/* write back any dirty data */
-	MOVW	$0xe0000000,R0
-	ADD	$(8*1024),R0,R1
-_cfloop:
-	MOVW.P	32(R0),R2
-	CMP.S	R0,R1
-	BNE	_cfloop
-	
-	/* drain write buffer and invalidate i&d cache contents */
-	MCR	CpMMU, 0, R0, C(CpCacheFlush), C(0xa), 4
-	MCR	CpMMU, 0, R0, C(CpCacheFlush), C(0x7), 0
-
-	/* drain prefetch */
-	MOVW	R0,R0						
-	MOVW	R0,R0
-	MOVW	R0,R0
-	MOVW	R0,R0
-
-	/* disable caches */
-	MRC	CpMMU, 0, R0, C(CpControl), C(0x0)
-	BIC	$(CpCdcache|CpCicache|CpCwb), R0
-	MCR     CpMMU, 0, R0, C(CpControl), C(0x0)
-	RET
--- a/os/boot/arm1110/imain.c
+++ /dev/null
@@ -1,48 +1,0 @@
-#include "u.h"
-#include "lib.h"
-#include "fns.h"
-#include "dat.h"
-#include "mem.h"
-
-void
-main(void)
-{
-	void (*f)(void);
-	ulong *kernel;
-
-	print("inflating kernel\n");
-
-	kernel = (ulong*)(0xc0200000+20*1024);
-	if(gunzip((uchar*)0xc0008000, 2*1024*1024, (uchar*)kernel, FLATESIZE) > 0){
-		f = (void (*)(void))0xc0008010;
-		draincache();
-	} else {
-		print("inflation failed\n");
-		f = nil;
-	}
-	(*f)();
-}
-
-void
-exit(void)
-{
-
-	void (*f)(void);
-
-	delay(1000);
-
-	print("it's a wonderful day to die\n");
-	f = nil;
-	(*f)();
-}
-
-void
-delay(int ms)
-{
-	int i;
-
-	while(ms-- > 0){
-		for(i = 0; i < 1000; i++)
-			;
-	}
-}
--- a/os/boot/arm1110/inflate.c
+++ /dev/null
@@ -1,208 +1,0 @@
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include <flate.h>
-
-typedef struct Biobuf	Biobuf;
-
-struct Biobuf
-{
-	uchar *bp;
-	uchar *p;
-	uchar *ep;
-};
-
-static int	header(Biobuf*);
-static int	trailer(Biobuf*, Biobuf*);
-static int	getc(void*);
-static ulong	offset(Biobuf*);
-static int	crcwrite(void *out, void *buf, int n);
-static ulong	get4(Biobuf *b);
-static ulong	Boffset(Biobuf *bp);
-
-/* GZIP flags */
-enum {
-	Ftext=		(1<<0),
-	Fhcrc=		(1<<1),
-	Fextra=		(1<<2),
-	Fname=		(1<<3),
-	Fcomment=	(1<<4),
-
-	GZCRCPOLY	= 0xedb88320UL,
-};
-
-static ulong	*crctab;
-static ulong	crc;
-
-int
-gunzip(uchar *out, int outn, uchar *in, int inn)
-{
-	Biobuf bin, bout;
-	int err;
-
-	crc = 0;
-	crctab = mkcrctab(GZCRCPOLY);
-	err = inflateinit();
-	if(err != FlateOk)
-		print("inflateinit failed: %s\n", flateerr(err));
-
-	bin.bp = bin.p = in;
-	bin.ep = in+inn;
-	bout.bp = bout.p = out;
-	bout.ep = out+outn;
-
-	err = header(&bin);
-	if(err != FlateOk)
-		return err;
-
-	err = inflate(&bout, crcwrite, &bin, getc);
-	if(err != FlateOk)
-		print("inflate failed: %s\n", flateerr(err));
-
-	err = trailer(&bout, &bin);
-	if(err != FlateOk)
-		return err;
-
-	return Boffset(&bout);
-}
-
-static int
-header(Biobuf *bin)
-{
-	int i, flag;
-
-	if(getc(bin) != 0x1f || getc(bin) != 0x8b){
-		print("bad magic\n");
-		return FlateCorrupted;
-	}
-	if(getc(bin) != 8){
-		print("unknown compression type\n");
-		return FlateCorrupted;
-	}
-	
-	flag = getc(bin);
-	
-	/* mod time */
-	get4(bin);
-	
-	/* extra flags */
-	getc(bin);
-	
-	/* OS type */
-	getc(bin);
-
-	if(flag & Fextra)
-		for(i=getc(bin); i>0; i--)
-			getc(bin);
-	
-	/* name */
-	if(flag&Fname)
-		while(getc(bin) != 0)
-			;
-
-	/* comment */
-	if(flag&Fcomment)
-		while(getc(bin) != 0)
-			;
-
-	/* crc16 */
-	if(flag&Fhcrc) {
-		getc(bin);
-		getc(bin);
-	}
-		
-	return FlateOk;
-}
-
-static int
-trailer(Biobuf *bout, Biobuf *bin)
-{
-	/* crc32 */
-	ulong x;
-
-	x = get4(bin);
-	if(crc != x){
-		print("crc mismatch %lux %lux\n", crc, x);
-		return FlateCorrupted;
-	}
-
-	/* length */
-	if(get4(bin) != Boffset(bout)){
-		print("bad output len\n");
-		return FlateCorrupted;
-	}
-	return FlateOk;
-}
-
-static ulong
-get4(Biobuf *b)
-{
-	ulong v;
-	int i, c;
-
-	v = 0;
-	for(i = 0; i < 4; i++){
-		c = getc(b);
-		v |= c << (i * 8);
-	}
-	return v;
-}
-
-static int
-getc(void *in)
-{
-	Biobuf *bp = in;
-
-	if((bp->p - bp->bp) % 10000 == 0)
-		print(".");
-	if(bp->p >= bp->ep)
-		return -1;
-	return *bp->p++;
-}
-
-static ulong
-Boffset(Biobuf *bp)
-{
-	return bp->p - bp->bp;
-}
-
-static int
-crcwrite(void *out, void *buf, int n)
-{
-	Biobuf *bp;
-
-	crc = blockcrc(crctab, crc, buf, n);
-	bp = out;
-	if(n > bp->ep-bp->p)
-		n = bp->ep-bp->p;
-	memmove(bp->p, buf, n);
-	bp->p += n;
-	return n;
-}
-
-#undef malloc
-#undef free
-
-static ulong ibrkp = ~0;
-
-void *
-malloc(ulong n)
-{
-	ulong rv;
-
-	if(ibrkp == ~0)
-		ibrkp = ((ulong)end)+1024*1024;
-	n = (n+3)>>2;
-	n <<= 2;
-	rv = ibrkp;
-	ibrkp += n;
-	return (void*)rv;
-}
-
-void
-free(void *)
-{
-}
--- a/os/boot/arm1110/io.h
+++ /dev/null
@@ -1,261 +1,0 @@
-/*
- *  Definitions for IO devices.  Used only in C.
- */
-
-enum
-{
-	/* hardware counter frequency */
-	ClockFreq=	3686400,
-};
-
-/*
- *  IRQ's defined by SA1100
- */
-enum
-{
-	IRQgpio0=	0,
-	IRQgpio1=	1,
-	IRQgpio2=	2,
-	IRQgpio3=	3,
-	IRQgpio4=	4,
-	IRQgpio5=	5,
-	IRQgpio6=	6,
-	IRQgpio7=	7,
-	IRQgpio8=	8,
-	IRQgpio9=	9,
-	IRQgpio10=	10,
-	IRQgpiohi=	11,
-	IRQlcd=		12,
-	IRQudc=		13,
-	IRQuart1b=	15,
-	IRQuart2=	16,
-	IRQuart3=	17,
-	IRQmcp=		18,
-	IRQssp=		19,
-	IRQdma0=	20,
-	IRQdma1=	21,
-	IRQdma2=	22,
-	IRQdma3=	23,
-	IRQdma4=	24,
-	IRQdma5=	25,
-	IRQtimer0=	26,
-	IRQtimer1=	27,
-	IRQtimer2=	28,
-	IRQtimer3=	29,
-	IRQsecond=	30,
-	IRQrtc=		31,
-};
-
-/*
- *  GPIO lines (signal names from compaq document).  _i indicates input
- *  and _o output.
- */
-enum
-{
-	GPIO_PWR_ON_i=		1<<0,	/* power button */
-	GPIO_UP_IRQ_i=		1<<1,	/* microcontroller interrupts */
-	GPIO_LDD8_o=		1<<2,	/* LCD data 8-15 */
-	GPIO_LDD9_o=		1<<3,
-	GPIO_LDD10_o=		1<<4,
-	GPIO_LDD11_o=		1<<5,
-	GPIO_LDD12_o=		1<<6,
-	GPIO_LDD13_o=		1<<7,
-	GPIO_LDD14_o=		1<<8,
-	GPIO_LDD15_o=		1<<9,
-	GPIO_CARD_IND1_i=	1<<10,	/* card inserted in PCMCIA socket 1 */
-	GPIO_CARD_IRQ1_i=	1<<11,	/* PCMCIA socket 1 interrupt */
-	GPIO_CLK_SET0_o=	1<<12,	/* clock selects for audio codec */
-	GPIO_CLK_SET1_o=	1<<13,
-	GPIO_L3_SDA_io=		1<<14,	/* UDA1341 interface */
-	GPIO_L3_MODE_o=		1<<15,
-	GPIO_L3_SCLK_o=		1<<16,
-	GPIO_CARD_IND0_i=	1<<17,	/* card inserted in PCMCIA socket 0 */
-	GPIO_KEY_ACT_i=		1<<18,	/* hot key from cradle */
-	GPIO_SYS_CLK_i=		1<<19,	/* clock from codec */
-	GPIO_BAT_FAULT_i=	1<<20,	/* battery fault */
-	GPIO_CARD_IRQ0_i=	1<<21,	/* PCMCIA socket 0 interrupt */
-	GPIO_LOCK_i=		1<<22,	/* expansion pack lock/unlock */
-	GPIO_COM_DCD_i=		1<<23,	/* DCD from UART3 */
-	GPIO_OPT_IRQ_i=		1<<24,	/* expansion pack IRQ */
-	GPIO_COM_CTS_i=		1<<25,	/* CTS from UART3 */
-	GPIO_COM_RTS_o=		1<<26,	/* RTS to UART3 */
-	GPIO_OPT_IND_i=		1<<27,	/* expansion pack inserted */
-
-/* Peripheral Unit GPIO pin assignments: alternate functions */
-	GPIO_SSP_TXD_o=		1<<10,	/* SSP Transmit Data */
-	GPIO_SSP_RXD_i=		1<<11,	/* SSP Receive Data */
-	GPIO_SSP_SCLK_o=	1<<12,	/* SSP Sample CLocK */
-	GPIO_SSP_SFRM_o=	1<<13,	/* SSP Sample FRaMe */
-	/* ser. port 1: */
-	GPIO_UART_TXD_o=	1<<14,	/* UART Transmit Data */
-	GPIO_UART_RXD_i=	1<<15,	/* UART Receive Data */
-	GPIO_SDLC_SCLK_io=	1<<16,	/* SDLC Sample CLocK (I/O) */
-	GPIO_SDLC_AAF_o=	1<<17,	/* SDLC Abort After Frame */
-	GPIO_UART_SCLK1_i=	1<<18,	/* UART Sample CLocK 1 */
-	/* ser. port 4: */
-	GPIO_SSP_CLK_i=		1<<19,	/* SSP external CLocK */
-	/* ser. port 3: */
-	GPIO_UART_SCLK3_i=	1<<20,	/* UART Sample CLocK 3 */
-	/* ser. port 4: */
-	GPIO_MCP_CLK_i=		1<<21,	/* MCP CLocK */
-	/* test controller: */
-	GPIO_TIC_ACK_o=		1<<21,	/* TIC ACKnowledge */
-	GPIO_MBGNT_o=		1<<21,	/* Memory Bus GraNT */
-	GPIO_TREQA_i=		1<<22,	/* TIC REQuest A */
-	GPIO_MBREQ_i=		1<<22,	/* Memory Bus REQuest */
-	GPIO_TREQB_i=		1<<23,	/* TIC REQuest B */
-	GPIO_1Hz_o=			1<<25,	/* 1 Hz clock */
-	GPIO_RCLK_o=		1<<26,	/* internal (R) CLocK (O, fcpu/2) */
-	GPIO_32_768kHz_o=	1<<27,	/* 32.768 kHz clock (O, RTC) */
-};
-
-/*
- *  types of interrupts
- */
-enum
-{
-	GPIOrising,
-	GPIOfalling,
-	GPIOboth,
-	IRQ,
-};
-
-/* hardware registers */
-typedef struct Uartregs Uartregs;
-struct Uartregs
-{
-	ulong	ctl[4];
-	ulong	dummya;
-	ulong	data;
-	ulong	dummyb;
-	ulong	status[2];
-};
-Uartregs *uart3regs;
-
-/* general purpose I/O lines control registers */
-typedef struct GPIOregs GPIOregs;
-struct GPIOregs
-{
-	ulong	level;		/* 1 == high */
-	ulong	direction;	/* 1 == output */
-	ulong	set;		/* a 1 sets the bit, 0 leaves it alone */
-	ulong	clear;		/* a 1 clears the bit, 0 leaves it alone */
-	ulong	rising;		/* rising edge detect enable */
-	ulong	falling;	/* falling edge detect enable */
-	ulong	edgestatus;	/* writing a 1 bit clears */
-	ulong	altfunc;	/* turn on alternate function for any set bits */
-};
-
-extern GPIOregs *gpioregs;
-
-/* extra general purpose I/O bits, output only */
-enum
-{
-	EGPIO_prog_flash=	1<<0,
-	EGPIO_pcmcia_reset=	1<<1,
-	EGPIO_exppack_reset=	1<<2,
-	EGPIO_codec_reset=	1<<3,
-	EGPIO_exp_nvram_power=	1<<4,
-	EGPIO_exp_full_power=	1<<5,
-	EGPIO_lcd_3v=		1<<6,
-	EGPIO_rs232_power=	1<<7,
-	EGPIO_lcd_ic_power=	1<<8,
-	EGPIO_ir_power=		1<<9,
-	EGPIO_audio_power=	1<<10,
-	EGPIO_audio_ic_power=	1<<11,
-	EGPIO_audio_mute=	1<<12,
-	EGPIO_fir=		1<<13,	/* not set is sir */
-	EGPIO_lcd_5v=		1<<14,
-	EGPIO_lcd_9v=		1<<15,
-};
-extern ulong *egpioreg;
-
-/* Peripheral pin controller registers */
-typedef struct PPCregs PPCregs;
-struct PPCregs {
-	ulong	direction;
-	ulong	state;
-	ulong	assignment;
-	ulong	sleepdir;
-	ulong	flags;
-};
-extern PPCregs *ppcregs;
-
-/* Synchronous Serial Port controller registers */
-typedef struct SSPregs SSPregs;
-struct SSPregs {
-	ulong	control0;
-	ulong	control1;
-	ulong	dummy0;
-	ulong	data;
-	ulong	dummy1;
-	ulong	status;
-};
-extern SSPregs *sspregs;
-
-/* Multimedia Communications Port controller registers */
-typedef struct MCPregs MCPregs;
-struct MCPregs {
-	ulong	control0;
-	ulong	reserved0;
-	ulong	data0;
-	ulong	data1;
-	ulong	data2;
-	ulong	reserved1;
-	ulong	status;
-	ulong	reserved[11];
-	ulong	control1;
-};
-extern MCPregs *mcpregs;
-
-/*
- *  memory configuration
- */
-enum
-{
-	/* bit shifts for pcmcia access time counters */
-	MECR_io0=	0,
-	MECR_attr0=	5,
-	MECR_mem0=	10,
-	MECR_fast0=	11,
-	MECR_io1=	MECR_io0+16,
-	MECR_attr1=	MECR_attr0+16,
-	MECR_mem1=	MECR_mem0+16,
-	MECR_fast1=	MECR_fast0+16,
-};
-
-typedef struct MemConfRegs MemConfRegs;
-struct MemConfRegs
-{
-	ulong	mdcnfg;		/* dram */
-	ulong	mdcas00;	/* dram banks 0/1 */
-	ulong	mdcas01;
-	ulong	mdcas02;
-	ulong	msc0;		/* static */
-	ulong	msc1;
-	ulong	mecr;		/* pcmcia */
-	ulong	mdrefr;		/* dram refresh */
-	ulong	mdcas20;	/* dram banks 2/3 */
-	ulong	mdcas21;
-	ulong	mdcas22;
-	ulong	msc2;		/* static */
-	ulong	smcnfg;		/* SMROM config */
-};
-extern MemConfRegs *memconfregs;
-
-/*
- *  power management
- */
-typedef struct PowerRegs PowerRegs;
-struct PowerRegs
-{
-	ulong	pmcr;	/* Power manager control register */
-	ulong	pssr;	/* Power manager sleep status register */
-	ulong	pspr;	/* Power manager scratch pad register */
-	ulong	pwer;	/* Power manager wakeup enable register */
-	ulong	pcfr;	/* Power manager general configuration register */
-	ulong	ppcr;	/* Power manager PPL configuration register */
-	ulong	pgsr;	/* Power manager GPIO sleep state register */
-	ulong	posr;	/* Power manager oscillator status register */
-};
-extern PowerRegs *powerregs;
--- a/os/boot/arm1110/l.s
+++ /dev/null
@@ -1,454 +1,0 @@
-#include "mem.h"
-
-/*
- * Entered here from Compaq's bootldr with MMU disabled.
- */
-TEXT _start(SB), $-4
-	MOVW	$setR12(SB), R12		/* load the SB */
-_main:
-	/* SVC mode, interrupts disabled */
-	MOVW	$(PsrDirq|PsrDfiq|PsrMsvc), R1
-	MOVW	R1, CPSR
-
-	/* disable the MMU */
-	MOVW	$0x130, R1
-	MCR     CpMMU, 0, R1, C(CpControl), C(0x0)
-
-	/* flush caches */
-	MCR	CpMMU, 0, R0, C(CpCacheFlush), C(0x7), 0
-	/* drain prefetch */
-	MOVW	R0,R0						
-	MOVW	R0,R0
-	MOVW	R0,R0
-	MOVW	R0,R0
-
-	/* drain write buffer */
-	MCR	CpMMU, 0, R0, C(CpCacheFlush), C(0xa), 4
-
-	MOVW	$(MACHADDR+BY2PG), R13		/* stack */
-	SUB	$4, R13				/* link */
-	BL	main(SB)
-	BL	exit(SB)
-	/* we shouldn't get here */
-_mainloop:
-	B	_mainloop
-	BL	_div(SB)			/* hack to get _div etc loaded */
-
-/* flush tlb's */
-TEXT mmuinvalidate(SB), $-4
-	MCR	CpMMU, 0, R0, C(CpTLBFlush), C(0x7)
-	RET
-
-/* flush tlb's */
-TEXT mmuinvalidateaddr(SB), $-4
-	MCR	CpMMU, 0, R0, C(CpTLBFlush), C(0x6), 1
-	RET
-
-/* write back and invalidate i and d caches */
-TEXT cacheflush(SB), $-4
-	/* write back any dirty data */
-	MOVW	$0xe0000000,R0
-	ADD	$(8*1024),R0,R1
-_cfloop:
-	MOVW.P	32(R0),R2
-	CMP.S	R0,R1
-	BNE	_cfloop
-	
-	/* drain write buffer and invalidate i&d cache contents */
-	MCR	CpMMU, 0, R0, C(CpCacheFlush), C(0xa), 4
-	MCR	CpMMU, 0, R0, C(CpCacheFlush), C(0x7), 0
-
-	/* drain prefetch */
-	MOVW	R0,R0						
-	MOVW	R0,R0
-	MOVW	R0,R0
-	MOVW	R0,R0
-	RET
-
-/* write back d cache */
-TEXT cachewb(SB), $-4
-	/* write back any dirty data */
-_cachewb:
-	MOVW	$0xe0000000,R0
-	ADD	$(8*1024),R0,R1
-_cwbloop:
-	MOVW.P	32(R0),R2
-	CMP.S	R0,R1
-	BNE	_cwbloop
-	
-	/* drain write buffer */
-	MCR	CpMMU, 0, R0, C(CpCacheFlush), C(0xa), 4
-	RET
-
-/* write back a single cache line */
-TEXT cachewbaddr(SB), $-4
-	BIC	$31,R0
-	MCR	CpMMU, 0, R0, C(CpCacheFlush), C(0xa), 1
-	B	_wbflush
-
-/* write back a region of cache lines */
-TEXT cachewbregion(SB), $-4
-	MOVW	4(FP),R1
-	CMP.S	$(4*1024),R1
-	BGT	_cachewb
-	ADD	R0,R1
-	BIC	$31,R0
-_cwbrloop:
-	MCR	CpMMU, 0, R0, C(CpCacheFlush), C(0xa), 1
-	ADD	$32,R0
-	CMP.S	R0,R1
-	BGT	_cwbrloop
-	B	_wbflush
-
-/* invalidate the dcache */
-TEXT dcacheinvalidate(SB), $-4
-	MCR	CpMMU, 0, R0, C(CpCacheFlush), C(0x6)
-	RET
-
-/* invalidate the icache */
-TEXT icacheinvalidate(SB), $-4
-	MCR	CpMMU, 0, R0, C(CpCacheFlush), C(0x9)
-	RET
-
-/* drain write buffer */
-TEXT wbflush(SB), $-4
-_wbflush:
-	MCR	CpMMU, 0, R0, C(CpCacheFlush), C(0xa), 4
-	RET
-
-/* return cpu id */
-TEXT getcpuid(SB), $-4
-	MRC	CpMMU, 0, R0, C(CpCPUID), C(0x0)
-	RET
-
-/* return fault status */
-TEXT getfsr(SB), $-4
-	MRC	CpMMU, 0, R0, C(CpFSR), C(0x0)
-	RET
-
-/* return fault address */
-TEXT getfar(SB), $-4
-	MRC	CpMMU, 0, R0, C(CpFAR), C(0x0)
-	RET
-
-/* return fault address */
-TEXT putfar(SB), $-4
-	MRC	CpMMU, 0, R0, C(CpFAR), C(0x0)
-	RET
-
-/* set the translation table base */
-TEXT putttb(SB), $-4
-	MCR	CpMMU, 0, R0, C(CpTTB), C(0x0)
-	RET
-
-/*
- *  enable mmu, i and d caches
- */
-TEXT mmuenable(SB), $-4
-	MRC	CpMMU, 0, R0, C(CpControl), C(0x0)
-	ORR	$(CpCmmuena|CpCdcache|CpCicache|CpCwb), R0
-	MCR     CpMMU, 0, R0, C(CpControl), C(0x0)
-	RET
-
-TEXT mmudisable(SB), $-4
-	MRC	CpMMU, 0, R0, C(CpControl), C(0x0)
-	BIC	$(CpCmmuena|CpCdcache|CpCicache|CpCwb|CpCvivec), R0
-	MCR     CpMMU, 0, R0, C(CpControl), C(0x0)
-	RET
-
-/*
- *  use exception vectors at 0xffff0000
- */
-TEXT mappedIvecEnable(SB), $-4
-	MRC	CpMMU, 0, R0, C(CpControl), C(0x0)
-	ORR	$(CpCvivec), R0
-	MCR     CpMMU, 0, R0, C(CpControl), C(0x0)
-	RET
-TEXT mappedIvecDisable(SB), $-4
-	MRC	CpMMU, 0, R0, C(CpControl), C(0x0)
-	BIC	$(CpCvivec), R0
-	MCR     CpMMU, 0, R0, C(CpControl), C(0x0)
-	RET
-
-/* set the translation table base */
-TEXT putdac(SB), $-4
-	MCR	CpMMU, 0, R0, C(CpDAC), C(0x0)
-	RET
-
-/* set address translation pid */
-TEXT putpid(SB), $-4
-	MCR	CpMMU, 0, R0, C(CpPID), C(0x0)
-	RET
-
-/*
- *  set the stack value for the mode passed in R0
- */
-TEXT setr13(SB), $-4
-	MOVW	4(FP), R1
-
-	MOVW	CPSR, R2
-	BIC	$PsrMask, R2, R3
-	ORR	R0, R3
-	MOVW	R3, CPSR
-
-	MOVW	R13, R0
-	MOVW	R1, R13
-
-	MOVW	R2, CPSR
-	RET
-
-/*
- *  exception vectors, copied by trapinit() to somewhere useful
- */
-
-TEXT vectors(SB), $-4
-	MOVW	0x18(R15), R15			/* reset */
-	MOVW	0x18(R15), R15			/* undefined */
-	MOVW	0x18(R15), R15			/* SWI */
-	MOVW	0x18(R15), R15			/* prefetch abort */
-	MOVW	0x18(R15), R15			/* data abort */
-	MOVW	0x18(R15), R15			/* reserved */
-	MOVW	0x18(R15), R15			/* IRQ */
-	MOVW	0x18(R15), R15			/* FIQ */
-
-TEXT vtable(SB), $-4
-	WORD	$_vsvc(SB)			/* reset, in svc mode already */
-	WORD	$_vund(SB)			/* undefined, switch to svc mode */
-	WORD	$_vsvc(SB)			/* swi, in svc mode already */
-	WORD	$_vpabt(SB)			/* prefetch abort, switch to svc mode */
-	WORD	$_vdabt(SB)			/* data abort, switch to svc mode */
-	WORD	$_vsvc(SB)			/* reserved */
-	WORD	$_virq(SB)			/* IRQ, switch to svc mode */
-	WORD	$_vfiq(SB)			/* FIQ, switch to svc mode */
-
-TEXT _vrst(SB), $-4
-	BL	resettrap(SB)
-
-TEXT _vsvc(SB), $-4			/* SWI */
-	MOVW.W	R14, -4(R13)		/* ureg->pc = interupted PC */
-	MOVW	SPSR, R14		/* ureg->psr = SPSR */
-	MOVW.W	R14, -4(R13)		/* ... */
-	MOVW	$PsrMsvc, R14		/* ureg->type = PsrMsvc */
-	MOVW.W	R14, -4(R13)		/* ... */
-	MOVM.DB.W.S [R0-R14], (R13)	/* save user level registers, at end r13 points to ureg */
-	MOVW	$setR12(SB), R12	/* Make sure we've got the kernel's SB loaded */
-	MOVW	R13, R0			/* first arg is pointer to ureg */
-	SUB	$8, R13			/* space for argument+link */
-
-	BL	syscall(SB)
-
-	ADD	$(8+4*15), R13		/* make r13 point to ureg->type */
-	MOVW	8(R13), R14		/* restore link */
-	MOVW	4(R13), R0		/* restore SPSR */
-	MOVW	R0, SPSR		/* ... */
-	MOVM.DB.S (R13), [R0-R14]	/* restore registers */
-	ADD	$8, R13			/* pop past ureg->{type+psr} */
-	RFE				/* MOVM.IA.S.W (R13), [R15] */
-
-TEXT _vund(SB), $-4			/* undefined */
-	MOVM.IA	[R0-R4], (R13)		/* free some working space */
-	MOVW	$PsrMund, R0
-	B	_vswitch
-
-TEXT _vpabt(SB), $-4			/* prefetch abort */
-	MOVM.IA	[R0-R4], (R13)		/* free some working space */
-	MOVW	$PsrMabt, R0		/* r0 = type */
-	B	_vswitch
-
-TEXT _vdabt(SB), $-4			/* prefetch abort */
-	MOVM.IA	[R0-R4], (R13)		/* free some working space */
-	MOVW	$(PsrMabt+1), R0		/* r0 = type */
-	B	_vswitch
-
-TEXT _virq(SB), $-4			/* IRQ */
-	MOVM.IA	[R0-R4], (R13)		/* free some working space */
-	MOVW	$PsrMirq, R0		/* r0 = type */
-	B	_vswitch
-
-	/*
-	 *  come here with type in R0 and R13 pointing above saved [r0-r4]
-	 *  and type in r0.  we'll switch to SVC mode and then call trap.
-	 */
-_vswitch:
-	MOVW	SPSR, R1		/* save SPSR for ureg */
-	MOVW	R14, R2			/* save interrupted pc for ureg */
-	MOVW	R13, R3			/* save pointer to where the original [R0-R3] are */
-
-	/* switch to svc mode */
-	MOVW	CPSR, R14
-	BIC	$PsrMask, R14
-	ORR	$(PsrDirq|PsrDfiq|PsrMsvc), R14
-	MOVW	R14, CPSR
-
-	/* interupted code kernel or user? */
-	AND.S	$0xf, R1, R4
-	BEQ	_userexcep
-
-	/* here for trap from SVC mode */
-	MOVM.DB.W [R0-R2], (R13)	/* set ureg->{type, psr, pc}; r13 points to ureg->type  */
-	MOVM.IA	  (R3), [R0-R4]		/* restore [R0-R4] from previous mode's stack */
-	MOVM.DB.W [R0-R14], (R13)	/* save kernel level registers, at end r13 points to ureg */
-	MOVW	$setR12(SB), R12	/* Make sure we've got the kernel's SB loaded */
-	MOVW	R13, R0			/* first arg is pointer to ureg */
-	SUB	$8, R13			/* space for argument+link (for debugger) */
-	MOVW	$0xdeaddead,R11		/* marker */
-
-	BL	trap(SB)
-
-	ADD	$(8+4*15), R13		/* make r13 point to ureg->type */
-	MOVW	8(R13), R14		/* restore link */
-	MOVW	4(R13), R0		/* restore SPSR */
-	MOVW	R0, SPSR		/* ... */
-	MOVM.DB (R13), [R0-R14]	/* restore registers */
-	ADD	$8, R13			/* pop past ureg->{type+psr} */
-	RFE				/* MOVM.IA.S.W (R13), [R15] */
-
-	/* here for trap from USER mode */
-_userexcep:
-	MOVM.DB.W [R0-R2], (R13)	/* set ureg->{type, psr, pc}; r13 points to ureg->type  */
-	MOVM.IA	  (R3), [R0-R4]		/* restore [R0-R4] from previous mode's stack */
-	MOVM.DB.W.S [R0-R14], (R13)	/* save kernel level registers, at end r13 points to ureg */
-	MOVW	$setR12(SB), R12	/* Make sure we've got the kernel's SB loaded */
-	MOVW	R13, R0			/* first arg is pointer to ureg */
-	SUB	$8, R13			/* space for argument+link (for debugger) */
-
-	BL	trap(SB)
-
-	ADD	$(8+4*15), R13		/* make r13 point to ureg->type */
-	MOVW	8(R13), R14		/* restore link */
-	MOVW	4(R13), R0		/* restore SPSR */
-	MOVW	R0, SPSR		/* ... */
-	MOVM.DB.S (R13), [R0-R14]	/* restore registers */
-	ADD	$8, R13			/* pop past ureg->{type+psr} */
-	RFE				/* MOVM.IA.S.W (R13), [R15] */
-
-TEXT _vfiq(SB), $-4			/* FIQ */
-	RFE				/* FIQ is special, ignore it for now */
-
-/*
- *  This is the first jump from kernel to user mode.
- *  Fake a return from interrupt.
- *
- *  Enter with R0 containing the user stack pointer.
- *  UTZERO + 0x20 is always the entry point.
- *  
- */
-TEXT touser(SB),$-4
-	/* store the user stack pointer into the USR_r13 */
-	MOVM.DB.W [R0], (R13)
-	MOVM.S.IA.W (R13),[R13]
-
-	/* set up a PSR for user level */
-	MOVW	$(PsrMusr), R0
-	MOVW	R0,SPSR
-
-	/* save the PC on the stack */
-	MOVW	$(UTZERO+0x20), R0
-	MOVM.DB.W [R0],(R13)
-
-	/* return from interrupt */
-	RFE				/* MOVM.IA.S.W (R13), [R15] */
-	
-/*
- *  here to jump to a newly forked process
- */
-TEXT forkret(SB),$-4
-	ADD	$(4*15), R13		/* make r13 point to ureg->type */
-	MOVW	8(R13), R14		/* restore link */
-	MOVW	4(R13), R0		/* restore SPSR */
-	MOVW	R0, SPSR		/* ... */
-	MOVM.DB.S (R13), [R0-R14]	/* restore registers */
-	ADD	$8, R13			/* pop past ureg->{type+psr} */
-	RFE				/* MOVM.IA.S.W (R13), [R15] */
-
-TEXT splhi(SB), $-4
-	/* save caller pc in Mach */
-	MOVW	$(MACHADDR+0x04),R2
-	MOVW	R14,0(R2)
-	/* turn off interrupts */
-	MOVW	CPSR, R0
-	ORR	$(PsrDfiq|PsrDirq), R0, R1
-	MOVW	R1, CPSR
-	RET
-
-TEXT spllo(SB), $-4
-	MOVW	CPSR, R0
-	BIC	$(PsrDfiq|PsrDirq), R0, R1
-	MOVW	R1, CPSR
-	RET
-
-TEXT splx(SB), $-4
-	/* save caller pc in Mach */
-	MOVW	$(MACHADDR+0x04),R2
-	MOVW	R14,0(R2)
-	/* reset interrupt level */
-	MOVW	R0, R1
-	MOVW	CPSR, R0
-	MOVW	R1, CPSR
-	RET
-
-TEXT splxpc(SB), $-4				/* for iunlock */
-	MOVW	R0, R1
-	MOVW	CPSR, R0
-	MOVW	R1, CPSR
-	RET
-
-TEXT spldone(SB), $0
-	RET
-
-TEXT islo(SB), $-4
-	MOVW	CPSR, R0
-	AND	$(PsrDfiq|PsrDirq), R0
-	EOR	$(PsrDfiq|PsrDirq), R0
-	RET
-
-TEXT cpsrr(SB), $-4
-	MOVW	CPSR, R0
-	RET
-
-TEXT spsrr(SB), $-4
-	MOVW	SPSR, R0
-	RET
-
-TEXT getcallerpc(SB), $-4
-	MOVW	0(R13), R0
-	RET
-
-TEXT tas(SB), $-4
-	MOVW	R0, R1
-	MOVW	$0xDEADDEAD, R2
-	SWPW	R2, (R1), R0
-	RET
-
-TEXT setlabel(SB), $-4
-	MOVW	R13, 0(R0)			/* sp */
-	MOVW	R14, 4(R0)			/* pc */
-	MOVW	$0, R0
-	RET
-
-TEXT gotolabel(SB), $-4
-	MOVW	0(R0), R13			/* sp */
-	MOVW	4(R0), R14			/* pc */
-	MOVW	$1, R0
-	RET
-
-
-/* The first MCR instruction of this function needs to be on a cache-line
- * boundary; to make this happen, it will be copied (in trap.c).
- *
- * Doze puts the machine into idle mode.  Any interrupt will get it out
- * at the next instruction (the RET, to be precise).
- */
-TEXT _doze(SB), $-4
-	MOVW	$UCDRAMZERO, R1
-	MOVW	R0,R0
-	MOVW	R0,R0
-	MOVW	R0,R0
-	MOVW	R0,R0
-	MOVW	R0,R0
-	MOVW	R0,R0
-	MOVW	R0,R0
-	MCR     CpPWR, 0, R0, C(CpTest), C(0x2), 2
-	MOVW	(R1), R0
-	MCR     CpPWR, 0, R0, C(CpTest), C(0x8), 2
-	RET
--- a/os/boot/arm1110/lib.h
+++ /dev/null
@@ -1,143 +1,0 @@
-/*
- * functions (possibly) linked in, complete, from libc.
- */
-
-/*
- * mem routines
- */
-extern	void	*memccpy(void*, void*, int, long);
-extern	void	*memset(void*, int, long);
-extern	int	memcmp(void*, void*, long);
-extern	void	*memmove(void*, void*, long);
-extern	void	*memchr(void*, int, long);
-
-/*
- * string routines
- */
-extern	char	*strcat(char*, char*);
-extern	char	*strchr(char*, char);
-extern	char	*strrchr(char*, char);
-extern	int	strcmp(char*, char*);
-extern	char	*strcpy(char*, char*);
-extern	char	*strncat(char*, char*, long);
-extern	char	*strncpy(char*, char*, long);
-extern	int	strncmp(char*, char*, long);
-extern	long	strlen(char*);
-extern	char*	strstr(char*, char*);
-extern	int	atoi(char*);
-
-enum
-{
-	UTFmax		= 3,	/* maximum bytes per rune */
-	Runesync	= 0x80,	/* cannot represent part of a UTF sequence */
-	Runeself	= 0x80,	/* rune and UTF sequences are the same (<) */
-	Runeerror	= 0x80,	/* decoding error in UTF */
-};
-
-/*
- * rune routines
- */
-extern	int	runetochar(char*, Rune*);
-extern	int	chartorune(Rune*, char*);
-extern	char*	utfrune(char*, long);
-extern	int	utflen(char*);
-extern	int	runelen(long);
-
-extern	int	abs(int);
-
-/*
- * print routines
- */
-typedef struct Cconv Fconv;
-extern	char*	donprint(char*, char*, char*, void*);
-extern	int	sprint(char*, char*, ...);
-extern	char*	seprint(char*, char*, char*, ...);
-extern	int	snprint(char*, int, char*, ...);
-extern	int	print(char*, ...);
-
-/*
- * one-of-a-kind
- */
-extern	char*	cleanname(char*);
-extern	ulong	getcallerpc(void*);
-extern	long	strtol(char*, char**, int);
-extern	ulong	strtoul(char*, char**, int);
-extern	vlong	strtoll(char*, char**, int);
-extern	uvlong	strtoull(char*, char**, int);
-extern	char	etext[];
-extern	char	edata[];
-extern	char	end[];
-extern	int	getfields(char*, char**, int, int, char*);
-
-/*
- * Syscall data structures
- */
-#define	MORDER	0x0003	/* mask for bits defining order of mounting */
-#define	MREPL	0x0000	/* mount replaces object */
-#define	MBEFORE	0x0001	/* mount goes before others in union directory */
-#define	MAFTER	0x0002	/* mount goes after others in union directory */
-#define	MCREATE	0x0004	/* permit creation in mounted directory */
-#define	MCACHE	0x0010	/* cache some data */
-#define	MMASK	0x001F	/* all bits on */
-
-#define	OREAD	0	/* open for read */
-#define	OWRITE	1	/* write */
-#define	ORDWR	2	/* read and write */
-#define	OEXEC	3	/* execute, == read but check execute permission */
-#define	OTRUNC	16	/* or'ed in (except for exec), truncate file first */
-#define	OCEXEC	32	/* or'ed in, close on exec */
-#define	ORCLOSE	64	/* or'ed in, remove on close */
-
-#define	NCONT	0	/* continue after note */
-#define	NDFLT	1	/* terminate after note */
-#define	NSAVE	2	/* clear note but hold state */
-#define	NRSTR	3	/* restore saved state */
-
-typedef struct Qid	Qid;
-typedef struct Dir	Dir;
-typedef struct Waitmsg	Waitmsg;
-
-#define	ERRLEN		64
-#define	DIRLEN		116
-#define	NAMELEN		28
-
-struct Qid
-{
-	ulong	path;
-	ulong	vers;
-};
-
-struct Dir
-{
-	char	name[NAMELEN];
-	char	uid[NAMELEN];
-	char	gid[NAMELEN];
-	Qid	qid;
-	ulong	mode;
-	long	atime;
-	long	mtime;
-	vlong	length;
-	short	type;
-	short	dev;
-};
-
-struct Waitmsg
-{
-	char	pid[12];	/* of loved one */
-	char	time[3*12];	/* of loved one and descendants */
-	char	msg[ERRLEN];
-};
-
-/*
- *  locks
- */
-typedef
-struct Lock {
-	int	val;
-} Lock;
-
-extern int	_tas(int*);
-
-extern	void	lock(Lock*);
-extern	void	unlock(Lock*);
-extern	int	canlock(Lock*);
--- a/os/boot/arm1110/map
+++ /dev/null
@@ -1,10 +1,0 @@
-defn acidmap()
-{
-	local dfoffset;
-
-	dfoffset = map()[1][3];
-	map({"text", _start, etext, 0x20});
-	map({"data", etext+1, edata, dfoffset});
-	print("Set map for plan 9 kernel image\n");
-	print("btext ", _start, " etext ", etext, "\n");
-}
--- a/os/boot/arm1110/mem.h
+++ /dev/null
@@ -1,215 +1,0 @@
-/*
- * Memory and machine-specific definitions.  Used in C and assembler.
- */
-
-/*
- * Sizes
- */
-#define	BI2BY		8			/* bits per byte */
-#define BI2WD		32			/* bits per word */
-#define	BY2WD		4			/* bytes per word */
-#define	BY2V		8			/* bytes per double word */
-#define	BY2PG		4096			/* bytes per page */
-#define	WD2PG		(BY2PG/BY2WD)		/* words per page */
-#define	PGSHIFT		12			/* log(BY2PG) */
-#define ROUND(s, sz)	(((s)+(sz-1))&~(sz-1))
-#define PGROUND(s)	ROUND(s, BY2PG)
-#define	BLOCKALIGN	8
-
-#define	MAXMACH		1			/* max # cpus system can run */
-
-/*
- * Time
- */
-#define	HZ		(20)				/* clock frequency */
-#define	MS2HZ		(1000/HZ)			/* millisec per clock tick */
-#define	TK2SEC(t)	((t)/HZ)			/* ticks to seconds */
-#define	TK2MS(t)	((((ulong)(t))*1000)/HZ)	/* ticks to milliseconds */
-#define	MS2TK(t)	((((ulong)(t))*HZ)/1000)	/* milliseconds to ticks */
-
-/*
- *  Virtual addresses:
- *
- *  We direct map all discovered DRAM and the area twixt 0xe0000000 and
- *  0xe8000000 used to provide zeros for cache flushing.
- *
- *  Flash is mapped to 0xb0000000 and special registers are mapped
- *  on demand to areas starting at 0xa0000000.
- *
- *  The direct mapping is convenient but not necessary.  It means
- *  that we don't have to turn on the MMU till well into the
- *  kernel.  This can be changed by providing a mapping in l.s
- *  before calling main.
- */
-#define	UZERO		0			/* base of user address space */
-#define	UTZERO		(UZERO+BY2PG)		/* first address in user text */
-#define	KZERO		0xC0000000		/* base of kernel address space */
-#define	KTZERO		0xC0008000		/* first address in kernel text */
-#define	EMEMZERO	0x90000000		/* 256 meg for add on memory */
-#define	EMEMTOP		0xA0000000		/* ... */
-#define	REGZERO		0xA0000000		/* 128 meg for mapspecial regs */
-#define	REGTOP		0xA8000000		/* ... */
-#define	FLASHZERO	0xB0000000		/* 128 meg for flash */
-#define	FLASHTOP	0xB8000000		/* ... */
-#define	DRAMZERO	0xC0000000		/* 128 meg for dram */
-#define DRAMTOP		0xC8000000		/* ... */
-#define	UCDRAMZERO	0xC8000000		/* 128 meg for dram (uncached/unbuffered) */
-#define UCDRAMTOP	0xD0000000		/* ... */
-#define	NULLZERO	0xE0000000		/* 128 meg for cache flush zeroes */
-#define NULLTOP		0xE8000000		/* ... */
-#define	USTKTOP		0x2000000		/* byte just beyond user stack */
-#define	USTKSIZE	(8*1024*1024)		/* size of user stack */
-#define	TSTKTOP		(USTKTOP-USTKSIZE)	/* end of new stack in sysexec */
-#define TSTKSIZ 	100
-#define MACHADDR	(KZERO+0x00001000)
-#define	EVECTORS	0xFFFF0000		/* virt base of exception vectors */
-
-#define KSTACK		(16*1024)		/* Size of kernel stack */
-
-#define	FLATESIZE	(700*1024)		/* maximum size of compressed image */
-
-/*
- *  Offsets into flash
- */
-#define Flash_bootldr	(FLASHZERO+0x0)		/* boot loader */
-#define Flash_kernel	(FLASHZERO+0x10000)	/* boot kernel */
-#define	Flash_tar	(FLASHZERO+0x100000)	/* tar file containing fs.sac */
-
-/*
- *  virtual MMU
- */
-#define PTEMAPMEM	(1024*1024)	
-#define	PTEPERTAB	(PTEMAPMEM/BY2PG)
-#define SEGMAPSIZE	1984
-#define SSEGMAPSIZE	16
-#define PPN(x)		((x)&~(BY2PG-1))
-
-/*
- *  SA1110 definitions
- */
-
-/*
- *  memory physical addresses
- */
-#define PHYSFLASH0	0x00000000
-#define PHYSDRAM0	0xC0000000
-#define	PHYSNULL0	0xE0000000
-
-/*
- *  peripheral control module physical addresses
- */
-#define USBREGS		0x80000000	/* serial port 0 - USB */
-#define UART1REGS	0x80010000	/* serial port 1 - UART */
-#define GPCLKREGS	0x80020060	/* serial port 1 - general purpose clock */
-#define UART2REGS	0x80030000	/* serial port 2 - low speed IR */
-#define HSSPREGS	0x80040060	/* serial port 2 - high speed IR */
-#define UART3REGS	0x80050000	/* serial port 3 - RS232 UART */
-#define MCPREGS		0x80060000	/* serial port 4 - multimedia comm port */
-#define SSPREGS		0x80070060	/* serial port 4 - synchronous serial port */
-#define OSTIMERREGS	0x90000000	/* operating system timer registers */
-#define POWERREGS	0x90020000	/* power management */
-#define GPIOREGS	0x90040000	/* 28 general purpose IO pins */
-#define INTRREGS	0x90050000	/* interrupt registers */
-#define PPCREGS		0x90060000	/* peripheral pin controller */
-#define MEMCONFREGS	0xA0000000	/* memory configuration */
-#define LCDREGS		0xB0100000	/* display */
-
-/*
- *  PCMCIA addresses
- */
-#define PHYSPCM0REGS	0x20000000
-#define PYHSPCM0ATTR	0x28000000
-#define PYHSPCM0MEM	0x2C000000
-#define PHYSPCM1REGS	0x30000000
-#define PYHSPCM1ATTR	0x38000000
-#define PYHSPCM1MEM	0x3C000000
-
-/*
- *  Program Status Registers
- */
-#define PsrMusr		0x00000010	/* mode */
-#define PsrMfiq		0x00000011
-#define PsrMirq		0x00000012
-#define PsrMsvc		0x00000013
-#define PsrMabt		0x00000017
-#define PsrMund		0x0000001B
-#define PsrMask		0x0000001F
-
-#define PsrDfiq		0x00000040	/* disable FIQ interrupts */
-#define PsrDirq		0x00000080	/* disable IRQ interrupts */
-
-#define PsrV		0x10000000	/* overflow */
-#define PsrC		0x20000000	/* carry/borrow/extend */
-#define PsrZ		0x40000000	/* zero */
-#define PsrN		0x80000000	/* negative/less than */
-
-/*
- *  Coprocessors
- */
-#define CpMMU		15
-#define CpPWR		15
-
-/*
- *  Internal MMU coprocessor registers
- */
-#define CpCPUID		0		/* R: */
-#define CpControl	1		/* R: */
-#define CpTTB		2		/* RW: translation table base */
-#define CpDAC		3		/* RW: domain access control */
-#define CpFSR		5		/* RW: fault status */
-#define CpFAR		6		/* RW: fault address */
-#define CpCacheFlush	7		/* W: cache flushing, wb draining*/
-#define CpTLBFlush	8		/* W: TLB flushing */
-#define CpRBFlush	9		/* W: Read Buffer ops */
-#define CpPID		13		/* RW: PID for virtual mapping */
-#define	CpBpt		14		/* W: Breakpoint register */
-#define CpTest		15		/* W: Test, Clock and Idle Control */
-
-/*
- *  CpControl
- */
-#define CpCmmuena	0x00000001	/* M: MMU enable */
-#define CpCalign	0x00000002	/* A: alignment fault enable */
-#define CpCdcache	0x00000004	/* C: data cache on */
-#define CpCwb		0x00000008	/* W: write buffer turned on */
-#define CpCi32		0x00000010	/* P: 32-bit program space */
-#define CpCd32		0x00000020	/* D: 32-bit data space */
-#define CpCbe		0x00000080	/* B: big-endian operation */
-#define CpCsystem	0x00000100	/* S: system permission */
-#define CpCrom		0x00000200	/* R: ROM permission */
-#define CpCicache	0x00001000	/* I: instruction cache on */
-#define CpCvivec	0x00002000	/* X: virtual interrupt vector adjust */
-
-/*
- *  fault codes
- */
-#define	FCterm		0x2	/* terminal */
-#define	FCvec		0x0	/* vector */
-#define	FCalignf	0x1	/* unaligned full word data access */
-#define	FCalignh	0x3	/* unaligned half word data access */
-#define	FCl1abort	0xc	/* level 1 external abort on translation */
-#define	FCl2abort	0xe	/* level 2 external abort on translation */
-#define	FCtransSec	0x5	/* section translation */
-#define	FCtransPage	0x7	/* page translation */
-#define	FCdomainSec	0x9	/* section domain  */
-#define	FCdomainPage	0x11	/* page domain */
-#define	FCpermSec	0x9	/* section permissions  */
-#define	FCpermPage	0x11	/* page permissions */
-#define	FCabortLFSec	0x4	/* external abort on linefetch for section */
-#define	FCabortLFPage	0x6	/* external abort on linefetch for page */
-#define	FCabortNLFSec	0x8	/* external abort on non-linefetch for section */
-#define	FCabortNLFPage	0xa	/* external abort on non-linefetch for page */
-
-/*
- *  PTE bits used by fault.h.  mmu.c translates them to real values.
- */
-#define	PTEVALID	(1<<0)
-#define	PTERONLY	0	/* this is implied by the absence of PTEWRITE */
-#define	PTEWRITE	(1<<1)
-#define	PTEUNCACHED	(1<<2)
-#define PTEKERNEL	(1<<3)	/* no user access */
-
-/*
- *  H3650 specific definitions
- */
-#define EGPIOREGS	0x49000000	/* Additional GPIO register */
--- a/os/boot/arm1110/mkfile
+++ /dev/null
@@ -1,86 +1,0 @@
-<../../../mkconfig
-objtype=arm
-SYSTARG=$OSTARG
-OBJTYPE=arm
-BIN=$ROOT/Inferno/$OBJTYPE
-LIBDIR=$ROOT/Inferno/$OBJTYPE/lib
-LIBDIRS=../libflate $ROOT/libkern
-LIBS=\
-	libflate\
-	libkern\
-
-LIBFILES=${LIBS:%=$LIBDIR/%.a}
-<$ROOT/mkfiles/mkfile-$SYSTARG-$OBJTYPE
-
-BIN=$ROOT/Inferno/$OBJTYPE
-
-TARG=\
-	inflate\
-
-INFLATE=\
-	il.$O\
-	imain.$O\
-
-CORE=\
-	uart.$O\
-	inflate.$O\
-	donprint.$O\
-	print.$O\
-
-HFILES=\
-	mem.h\
-
-CFLAGS=-FVw -I.  -I$ROOT/Inferno/$OBJTYPE/include -I$ROOT/include
-
-all:V:	$TARG
-
-install:V:	$BIN/$TARG
-
-$BIN/%:	%
-	cp $stem $BIN/$stem
-
-inflate: $INFLATE $CORE $LIBFILES
-	$LD -o s$target -R4 -T0xC0200010 -l $prereq
-	$LD -o _$target -H5 -R4 -T0xC0200010 -l $prereq
-	dd -conv sync -ibs 20k -if _$target -of $target
-
-%.$O:	%.s
-	$AS $stem.s
-
-%.$O:	%.c
-	$CC $CFLAGS $stem.c
-
-%.$O:	$HFILES
-
-clean:
-	rm -f *.[$OS] [$OS].out y.tab.? y.debug y.output $TARG _$TARG s$TARG
-
-
-# added to cause libflate to be made automatically:
-
-$ROOT/Inferno/$OBJTYPE/lib/lib%.a:Q:	all-$SHELLTYPE
-	#
-
-rc-lib%.a nt-lib%.a:VQ:
-	echo '@{builtin cd ' $ROOT/lib$stem ';mk SHELLTYPE=$SHELLTYPE SYSTARG=$SYSTARG OBJTYPE=$OBJTYPE install}'
-	@{builtin cd  $ROOT/lib$stem ;mk 'SHELLTYPE='$SHELLTYPE 'SYSTARG='$SYSTARG 'OBJTYPE='$OBJTYPE install}
-
-sh-lib%.a:VQ:
-	echo "(cd $ROOT/lib$stem ; mk SHELLTYPE=$SHELLTYPE SYSTARG=$SYSTARG OBJTYPE=$OBJTYPE install)"
-	(cd $ROOT/lib$stem ; mk SHELLTYPE=$SHELLTYPE SYSTARG=$SYSTARG OBJTYPE=$OBJTYPE install)
-
-%-sh:QV:
-		for i in $LIBDIRS
-		do
-			echo "(cd $i ; mk SHELLTYPE=$SHELLTYPE SYSTARG=$SYSTARG OBJTYPE=$OBJTYPE $stem)"
-			(cd $i; mk 'SHELLTYPE='$SHELLTYPE 'SYSTARG='$SYSTARG 'OBJTYPE='$OBJTYPE $stem)
-		done
-
-%-rc %-nt:QV:
-		for (i in $LIBDIRS)
-		{
-			echo '@{cd $i ; mk SHELLTYPE=$SHELLTYPE SYSTARG=$SYSTARG OBJTYPE=$OBJTYPE $stem}'
-			@{cd $i; mk 'SHELLTYPE='$SHELLTYPE 'SYSTARG='$SYSTARG 'OBJTYPE='$OBJTYPE $stem}
-		}
-
-nuke:V:		clean nuke-$SHELLTYPE
--- a/os/boot/arm1110/print.c
+++ /dev/null
@@ -1,56 +1,0 @@
-#include "u.h"
-#include "lib.h"
-#include "fns.h"
-#include "dat.h"
-
-
-#define	SIZE	1024
-
-int
-print(char *fmt, ...)
-{
-	char buf[SIZE], *out;
-	va_list arg;
-
-	va_start(arg, fmt);
-	out = donprint(buf, buf+SIZE, fmt, arg);
-	va_end(arg);
-	serialputs(buf, out-buf);
-	return out-buf;
-}
-
-int
-sprint(char *buf, char *fmt, ...)
-{
-	char *out;
-	va_list arg;
-
-	va_start(arg, fmt);
-	out = donprint(buf, buf+SIZE, fmt, arg);
-	va_end(arg);
-	return out-buf;
-}
-
-int
-snprint(char *buf, int len, char *fmt, ...)
-{
-	char *out;
-	va_list arg;
-
-	va_start(arg, fmt);
-	out = donprint(buf, buf+len, fmt, arg);
-	va_end(arg);
-	return out-buf;
-}
-
-char*
-seprint(char *buf, char *e, char *fmt, ...)
-{
-	char *out;
-	va_list arg;
-
-	va_start(arg, fmt);
-	out = donprint(buf, e, fmt, arg);
-	va_end(arg);
-	return out;
-}
--- a/os/boot/arm1110/uart.c
+++ /dev/null
@@ -1,69 +1,0 @@
-#include	"u.h"
-#include	"lib.h"
-#include	"mem.h"
-#include	"dat.h"
-#include	"fns.h"
-#include	"io.h"
-
-enum
-{
-	/* ctl[0] bits */
-	Parity=		1<<0,
-	Even=		1<<1,
-	Stop2=		1<<2,
-	Bits8=		1<<3,
-	SCE=		1<<4,	/* synchronous clock enable */
-	RCE=		1<<5,	/* rx on falling edge of clock */
-	TCE=		1<<6,	/* tx on falling edge of clock */
-
-	/* ctl[3] bits */
-	Rena=		1<<0,	/* receiver enable */
-	Tena=		1<<1,	/* transmitter enable */
-	Break=		1<<2,	/* force TXD3 low */
-	Rintena=	1<<3,	/* enable receive interrupt */
-	Tintena=	1<<4,	/* enable transmitter interrupt */
-	Loopback=	1<<5,	/* loop back data */
-
-	/* data bits */
-	DEparity=	1<<8,	/* parity error */
-	DEframe=	1<<9,	/* framing error */
-	DEoverrun=	1<<10,	/* overrun error */
-
-	/* status[0] bits */
-	Tint=		1<<0,	/* transmit fifo half full interrupt */
-	Rint0=		1<<1,	/* receiver fifo 1/3-2/3 full */
-	Rint1=		1<<2,	/* receiver fifo not empty and receiver idle */
-	Breakstart=	1<<3,
-	Breakend=	1<<4,
-	Fifoerror=	1<<5,	/* fifo error */
-
-	/* status[1] bits */
-	Tbusy=		1<<0,	/* transmitting */
-	Rnotempty=	1<<1,	/* receive fifo not empty */
-	Tnotfull=	1<<2,	/* transmit fifo not full */
-	ParityError=	1<<3,
-	FrameError=	1<<4,
-	Overrun=	1<<5,
-};
-
-Uartregs *uart3regs = UART3REGS;
-
-
-/*
- *  for iprint, just write it
- */
-void
-serialputs(char *str, int n)
-{
-	Uartregs *ur;
-
-	ur = uart3regs;
-	while(n-- > 0){
-		/* wait for output ready */
-		while((ur->status[1] & Tnotfull) == 0)
-			;
-		ur->data = *str++;
-	}
-	while((ur->status[1] & Tbusy))
-		;
-}
--- a/os/boot/libflate/LICENCE
+++ /dev/null
@@ -1,237 +1,0 @@
-Lucent Public License Version 1.02
-
-THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS PUBLIC
-LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE
-PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
-
-1. DEFINITIONS
-
-"Contribution" means:
-
-  a. in the case of Lucent Technologies Inc. ("LUCENT"), the Original
-     Program, and
-  b. in the case of each Contributor,
-
-     i. changes to the Program, and
-    ii. additions to the Program;
-
-    where such changes and/or additions to the Program were added to the
-    Program by such Contributor itself or anyone acting on such
-    Contributor's behalf, and the Contributor explicitly consents, in
-    accordance with Section 3C, to characterization of the changes and/or
-    additions as Contributions.
-
-"Contributor" means LUCENT and any other entity that has Contributed a
-Contribution to the Program.
-
-"Distributor" means a Recipient that distributes the Program,
-modifications to the Program, or any part thereof.
-
-"Licensed Patents" mean patent claims licensable by a Contributor
-which are necessarily infringed by the use or sale of its Contribution
-alone or when combined with the Program.
-
-"Original Program" means the original version of the software
-accompanying this Agreement as released by LUCENT, including source
-code, object code and documentation, if any.
-
-"Program" means the Original Program and Contributions or any part
-thereof
-
-"Recipient" means anyone who receives the Program under this
-Agreement, including all Contributors.
-
-2. GRANT OF RIGHTS
-
- a. Subject to the terms of this Agreement, each Contributor hereby
-    grants Recipient a non-exclusive, worldwide, royalty-free copyright
-    license to reproduce, prepare derivative works of, publicly display,
-    publicly perform, distribute and sublicense the Contribution of such
-    Contributor, if any, and such derivative works, in source code and
-    object code form.
-    
- b. Subject to the terms of this Agreement, each Contributor hereby
-    grants Recipient a non-exclusive, worldwide, royalty-free patent
-    license under Licensed Patents to make, use, sell, offer to sell,
-    import and otherwise transfer the Contribution of such Contributor, if
-    any, in source code and object code form. The patent license granted
-    by a Contributor shall also apply to the combination of the
-    Contribution of that Contributor and the Program if, at the time the
-    Contribution is added by the Contributor, such addition of the
-    Contribution causes such combination to be covered by the Licensed
-    Patents. The patent license granted by a Contributor shall not apply
-    to (i) any other combinations which include the Contribution, nor to
-    (ii) Contributions of other Contributors. No hardware per se is
-    licensed hereunder.
-    
- c. Recipient understands that although each Contributor grants the
-    licenses to its Contributions set forth herein, no assurances are
-    provided by any Contributor that the Program does not infringe the
-    patent or other intellectual property rights of any other entity. Each
-    Contributor disclaims any liability to Recipient for claims brought by
-    any other entity based on infringement of intellectual property rights
-    or otherwise. As a condition to exercising the rights and licenses
-    granted hereunder, each Recipient hereby assumes sole responsibility
-    to secure any other intellectual property rights needed, if any. For
-    example, if a third party patent license is required to allow
-    Recipient to distribute the Program, it is Recipient's responsibility
-    to acquire that license before distributing the Program.
-
- d. Each Contributor represents that to its knowledge it has sufficient
-    copyright rights in its Contribution, if any, to grant the copyright
-    license set forth in this Agreement.
-
-3. REQUIREMENTS
-
-A. Distributor may choose to distribute the Program in any form under
-this Agreement or under its own license agreement, provided that:
-
- a. it complies with the terms and conditions of this Agreement;
-
- b. if the Program is distributed in source code or other tangible
-    form, a copy of this Agreement or Distributor's own license agreement
-    is included with each copy of the Program; and
-
- c. if distributed under Distributor's own license agreement, such
-    license agreement:
-
-      i. effectively disclaims on behalf of all Contributors all warranties
-         and conditions, express and implied, including warranties or
-         conditions of title and non-infringement, and implied warranties or
-         conditions of merchantability and fitness for a particular purpose;
-     ii. effectively excludes on behalf of all Contributors all liability
-         for damages, including direct, indirect, special, incidental and
-         consequential damages, such as lost profits; and
-    iii. states that any provisions which differ from this Agreement are
-         offered by that Contributor alone and not by any other party.
-
-B. Each Distributor must include the following in a conspicuous
-   location in the Program:
-
-   Copyright (C) 2003, Lucent Technologies Inc. and others. All Rights
-   Reserved.
-
-C. In addition, each Contributor must identify itself as the
-originator of its Contribution in a manner that reasonably allows
-subsequent Recipients to identify the originator of the Contribution.
-Also, each Contributor must agree that the additions and/or changes
-are intended to be a Contribution. Once a Contribution is contributed,
-it may not thereafter be revoked.
-
-4. COMMERCIAL DISTRIBUTION
-
-Commercial distributors of software may accept certain
-responsibilities with respect to end users, business partners and the
-like. While this license is intended to facilitate the commercial use
-of the Program, the Distributor who includes the Program in a
-commercial product offering should do so in a manner which does not
-create potential liability for Contributors. Therefore, if a
-Distributor includes the Program in a commercial product offering,
-such Distributor ("Commercial Distributor") hereby agrees to defend
-and indemnify every Contributor ("Indemnified Contributor") against
-any losses, damages and costs (collectively"Losses") arising from
-claims, lawsuits and other legal actions brought by a third party
-against the Indemnified Contributor to the extent caused by the acts
-or omissions of such Commercial Distributor in connection with its
-distribution of the Program in a commercial product offering. The
-obligations in this section do not apply to any claims or Losses
-relating to any actual or alleged intellectual property infringement.
-In order to qualify, an Indemnified Contributor must: a) promptly
-notify the Commercial Distributor in writing of such claim, and b)
-allow the Commercial Distributor to control, and cooperate with the
-Commercial Distributor in, the defense and any related settlement
-negotiations. The Indemnified Contributor may participate in any such
-claim at its own expense.
-
-For example, a Distributor might include the Program in a commercial
-product offering, Product X. That Distributor is then a Commercial
-Distributor. If that Commercial Distributor then makes performance
-claims, or offers warranties related to Product X, those performance
-claims and warranties are such Commercial Distributor's responsibility
-alone. Under this section, the Commercial Distributor would have to
-defend claims against the Contributors related to those performance
-claims and warranties, and if a court requires any Contributor to pay
-any damages as a result, the Commercial Distributor must pay those
-damages.
-
-5. NO WARRANTY
-
-EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS
-PROVIDED ON AN"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
-WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY
-OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely
-responsible for determining the appropriateness of using and
-distributing the Program and assumes all risks associated with its
-exercise of rights under this Agreement, including but not limited to
-the risks and costs of program errors, compliance with applicable
-laws, damage to or loss of data, programs or equipment, and
-unavailability or interruption of operations.
-
-6. DISCLAIMER OF LIABILITY
-
-EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR
-ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING
-WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR
-DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
-HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
-
-7. EXPORT CONTROL
-
-Recipient agrees that Recipient alone is responsible for compliance
-with the United States export administration regulations (and the
-export control laws and regulation of any other countries).
-
-8. GENERAL
-
-If any provision of this Agreement is invalid or unenforceable under
-applicable law, it shall not affect the validity or enforceability of
-the remainder of the terms of this Agreement, and without further
-action by the parties hereto, such provision shall be reformed to the
-minimum extent necessary to make such provision valid and enforceable.
-
-If Recipient institutes patent litigation against a Contributor with
-respect to a patent applicable to software (including a cross-claim or
-counterclaim in a lawsuit), then any patent licenses granted by that
-Contributor to such Recipient under this Agreement shall terminate as
-of the date such litigation is filed. In addition, if Recipient
-institutes patent litigation against any entity (including a
-cross-claim or counterclaim in a lawsuit) alleging that the Program
-itself (excluding combinations of the Program with other software or
-hardware) infringes such Recipient's patent(s), then such Recipient's
-rights granted under Section 2(b) shall terminate as of the date such
-litigation is filed.
-
-All Recipient's rights under this Agreement shall terminate if it
-fails to comply with any of the material terms or conditions of this
-Agreement and does not cure such failure in a reasonable period of
-time after becoming aware of such noncompliance. If all Recipient's
-rights under this Agreement terminate, Recipient agrees to cease use
-and distribution of the Program as soon as reasonably practicable.
-However, Recipient's obligations under this Agreement and any licenses
-granted by Recipient relating to the Program shall continue and
-survive.
-
-LUCENT may publish new versions (including revisions) of this
-Agreement from time to time. Each new version of the Agreement will be
-given a distinguishing version number. The Program (including
-Contributions) may always be distributed subject to the version of the
-Agreement under which it was received. In addition, after a new
-version of the Agreement is published, Contributor may elect to
-distribute the Program (including its Contributions) under the new
-version. No one other than LUCENT has the right to modify this
-Agreement. Except as expressly stated in Sections 2(a) and 2(b) above,
-Recipient receives no rights or licenses to the intellectual property
-of any Contributor under this Agreement, whether expressly, by
-implication, estoppel or otherwise. All rights in the Program not
-expressly granted under this Agreement are reserved.
-
-This Agreement is governed by the laws of the State of New York and
-the intellectual property laws of the United States of America. No
-party to this Agreement will bring a legal action under this Agreement
-more than one year after the cause of action arose. Each party waives
-its rights to a jury trial in any resulting litigation.
-
--- a/os/boot/libflate/NOTICE
+++ /dev/null
@@ -1,8 +1,0 @@
-Copyright © 2002 Lucent Technologies Inc.
-All Rights Reserved
-
-This software was originally developed for Plan 9.
-It is provided under the terms of the Lucent Public License, Version 1.02.
-
-Trivial modifications have been made to make it compile for Inferno.
-	Vita Nuova Holdings Limited.
--- a/os/boot/libflate/adler.c
+++ /dev/null
@@ -1,71 +1,0 @@
-#include "lib9.h"
-#include <flate.h>
-
-enum
-{
-	ADLERITERS	= 5552,	/* max iters before can overflow 32 bits */
-	ADLERBASE	= 65521 /* largest prime smaller than 65536 */
-};
-
-ulong
-adler32(ulong adler, void *vbuf, int n)
-{
-	ulong s1, s2;
-	uchar *buf, *ebuf;
-	int m;
-
-	buf = vbuf;
-	s1 = adler & 0xffff;
-	s2 = (adler >> 16) & 0xffff;
-	for(; n >= 16; n -= m){
-		m = n;
-		if(m > ADLERITERS)
-			m = ADLERITERS;
-		m &= ~15;
-		for(ebuf = buf + m; buf < ebuf; buf += 16){
-			s1 += buf[0];
-			s2 += s1;
-			s1 += buf[1];
-			s2 += s1;
-			s1 += buf[2];
-			s2 += s1;
-			s1 += buf[3];
-			s2 += s1;
-			s1 += buf[4];
-			s2 += s1;
-			s1 += buf[5];
-			s2 += s1;
-			s1 += buf[6];
-			s2 += s1;
-			s1 += buf[7];
-			s2 += s1;
-			s1 += buf[8];
-			s2 += s1;
-			s1 += buf[9];
-			s2 += s1;
-			s1 += buf[10];
-			s2 += s1;
-			s1 += buf[11];
-			s2 += s1;
-			s1 += buf[12];
-			s2 += s1;
-			s1 += buf[13];
-			s2 += s1;
-			s1 += buf[14];
-			s2 += s1;
-			s1 += buf[15];
-			s2 += s1;
-		}
-		s1 %= ADLERBASE;
-		s2 %= ADLERBASE;
-	}
-	if(n){
-		for(ebuf = buf + n; buf < ebuf; buf++){
-			s1 += buf[0];
-			s2 += s1;
-		}
-		s1 %= ADLERBASE;
-		s2 %= ADLERBASE;
-	}
-	return (s2 << 16) + s1;
-}
--- a/os/boot/libflate/crc.c
+++ /dev/null
@@ -1,39 +1,0 @@
-#include "lib9.h"
-#include <flate.h>
-
-ulong*
-mkcrctab(ulong poly)
-{
-	ulong *crctab;
-	ulong crc;
-	int i, j;
-
-	crctab = malloc(256 * sizeof(ulong));
-	if(crctab == nil)
-		return nil;
-
-	for(i = 0; i < 256; i++){
-		crc = i;
-		for(j = 0; j < 8; j++){
-			if(crc & 1)
-				crc = (crc >> 1) ^ poly;
-			else
-				crc >>= 1;
-		}
-		crctab[i] = crc;
-	}
-	return crctab;
-}
-
-ulong
-blockcrc(ulong *crctab, ulong crc, void *vbuf, int n)
-{
-	uchar *buf, *ebuf;
-
-	crc ^= 0xffffffff;
-	buf = vbuf;
-	ebuf = buf + n;
-	while(buf < ebuf)
-		crc = crctab[(crc & 0xff) ^ *buf++] ^ (crc >> 8);
-	return crc ^ 0xffffffff;
-}
--- a/os/boot/libflate/deflate.c
+++ /dev/null
@@ -1,1358 +1,0 @@
-#include "lib9.h"
-#include <flate.h>
-
-typedef struct Chain	Chain;
-typedef struct Chains	Chains;
-typedef struct Dyncode	Dyncode;
-typedef struct Huff	Huff;
-typedef struct LZblock	LZblock;
-typedef struct LZstate	LZstate;
-
-enum
-{
-	/*
-	 * deflate format paramaters
-	 */
-	DeflateUnc	= 0,			/* uncompressed block */
-	DeflateFix	= 1,			/* fixed huffman codes */
-	DeflateDyn	= 2,			/* dynamic huffman codes */
-
-	DeflateEob	= 256,			/* end of block code in lit/len book */
-	DeflateMaxBlock	= 64*1024-1,		/* maximum size of uncompressed block */
-
-	DeflateMaxExp	= 10,			/* maximum expansion for a block */
-
-	LenStart	= 257,			/* start of length codes in litlen */
-	Nlitlen		= 288,			/* number of litlen codes */
-	Noff		= 30,			/* number of offset codes */
-	Nclen		= 19,			/* number of codelen codes */
-
-	MaxOff		= 32*1024,
-	MinMatch	= 3,			/* shortest match possible */
-	MaxMatch	= 258,			/* longest match possible */
-
-	/*
-	 * huffman code paramaters
-	 */
-	MaxLeaf		= Nlitlen,
-	MaxHuffBits	= 16,			/* max bits in a huffman code */
-	ChainMem	= 2 * (MaxHuffBits - 1) * MaxHuffBits,
-
-	/*
-	 * coding of the lz parse
-	 */
-	LenFlag		= 1 << 3,
-	LenShift	= 4,			/* leaves enough space for MinMatchMaxOff */
-	MaxLitRun	= LenFlag - 1,
-
-	/*
-	 * internal lz paramaters
-	 */
-	DeflateOut	= 4096,			/* output buffer size */
-	BlockSize	= 8192,			/* attempted input read quanta */
-	DeflateBlock	= DeflateMaxBlock & ~(BlockSize - 1),
-	MinMatchMaxOff	= 4096,			/* max profitable offset for small match;
-						 * assumes 8 bits for len, 5+10 for offset
-						 * DONT CHANGE WITHOUT CHANGING LZPARSE CONSTANTS
-						 */
-	HistSlop	= 512,			/* must be at lead MaxMatch */
-	HistBlock	= 64*1024,
-	HistSize	= HistBlock + HistSlop,
-
-	HashLog		= 13,
-	HashSize	= 1<<HashLog,
-
-	MaxOffCode	= 256,			/* biggest offset looked up in direct table */
-
-	EstLitBits	= 8,
-	EstLenBits	= 4,
-	EstOffBits	= 5,
-};
-
-/*
- * knuth vol. 3 multiplicative hashing
- * each byte x chosen according to rules
- * 1/4 < x < 3/10, 1/3 x < < 3/7, 4/7 < x < 2/3, 7/10 < x < 3/4
- * with reasonable spread between the bytes & their complements
- *
- * the 3 byte value appears to be as almost good as the 4 byte value,
- * and might be faster on some machines
- */
-/*
-#define hashit(c)	(((ulong)(c) * 0x6b43a9) >> (24 - HashLog))
-*/
-#define hashit(c)	((((ulong)(c) & 0xffffff) * 0x6b43a9b5) >> (32 - HashLog))
-
-/*
- * lempel-ziv style compression state
- */
-struct LZstate
-{
-	uchar	hist[HistSize];
-	ulong	pos;				/* current location in history buffer */
-	ulong	avail;				/* data available after pos */
-	int	eof;
-	ushort	hash[HashSize];			/* hash chains */
-	ushort	nexts[MaxOff];
-	int	now;				/* pos in hash chains */
-	int	dot;				/* dawn of time in history */
-	int	prevlen;			/* lazy matching state */
-	int	prevoff;
-	int	maxcheck;			/* compressor tuning */
-
-	uchar	obuf[DeflateOut];
-	uchar	*out;				/* current position in the output buffer */
-	uchar	*eout;
-	ulong	bits;				/* bit shift register */
-	int	nbits;
-	int	rbad;				/* got an error reading the buffer */
-	int	wbad;				/* got an error writing the buffer */
-	int	(*w)(void*, void*, int);
-	void	*wr;
-
-	ulong	totr;				/* total input size */
-	ulong	totw;				/* total output size */
-	int	debug;
-};
-
-struct LZblock
-{
-	ushort	parse[DeflateMaxBlock / 2 + 1];
-	int	lastv;				/* value being constucted for parse */
-	ulong	litlencount[Nlitlen];
-	ulong	offcount[Noff];
-	ushort	*eparse;			/* limit for parse table */
-	int	bytes;				/* consumed from the input */
-	int	excost;				/* cost of encoding extra len & off bits */
-};
-
-/*
- * huffman code table
- */
-struct Huff
-{
-	short	bits;				/* length of the code */
-	ushort	encode;				/* the code */
-};
-
-/*
- * encoding of dynamic huffman trees
- */
-struct Dyncode
-{
-	int	nlit;
-	int	noff;
-	int	nclen;
-	int	ncode;
-	Huff	codetab[Nclen];
-	uchar	codes[Nlitlen+Noff];
-	uchar	codeaux[Nlitlen+Noff];
-};
-
-static	int	deflateb(LZstate *lz, LZblock *lzb, void *rr, int (*r)(void*, void*, int));
-static	int	lzcomp(LZstate*, LZblock*, uchar*, ushort*, int finish);
-static	void	wrblock(LZstate*, int, ushort*, ushort*, Huff*, Huff*);
-static	int	bitcost(Huff*, ulong*, int);
-static	int	huffcodes(Dyncode*, Huff*, Huff*);
-static	void	wrdyncode(LZstate*, Dyncode*);
-static	void	lzput(LZstate*, ulong bits, int nbits);
-static	void	lzflushbits(LZstate*);
-static	void	lzflush(LZstate *lz);
-static	void	lzwrite(LZstate *lz, void *buf, int n);
-
-static	int	hufftabinit(Huff*, int, ulong*, int);
-static	int	mkgzprecode(Huff*, ulong *, int, int);
-
-static	int	mkprecode(Huff*, ulong *, int, int, ulong*);
-static	void	nextchain(Chains*, int);
-static	void	leafsort(ulong*, ushort*, int, int);
-
-/* conversion from len to code word */
-static int lencode[MaxMatch];
-
-/*
- * conversion from off to code word
- * off <= MaxOffCode ? offcode[off] : bigoffcode[off >> 7]
-*/
-static int offcode[MaxOffCode];
-static int bigoffcode[256];
-
-/* litlen code words LenStart-285 extra bits */
-static int litlenbase[Nlitlen-LenStart];
-static int litlenextra[Nlitlen-LenStart] =
-{
-/* 257 */	0, 0, 0,
-/* 260 */	0, 0, 0, 0, 0, 1, 1, 1, 1, 2,
-/* 270 */	2, 2, 2, 3, 3, 3, 3, 4, 4, 4,
-/* 280 */	4, 5, 5, 5, 5, 0, 0, 0
-};
-
-/* offset code word extra bits */
-static int offbase[Noff];
-static int offextra[] =
-{
-	0,  0,  0,  0,  1,  1,  2,  2,  3,  3,
-	4,  4,  5,  5,  6,  6,  7,  7,  8,  8,
-	9,  9,  10, 10, 11, 11, 12, 12, 13, 13,
-	0,  0,
-};
-
-/* order code lengths */
-static int clenorder[Nclen] =
-{
-        16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
-};
-
-/* static huffman tables */
-static	Huff	litlentab[Nlitlen];
-static	Huff	offtab[Noff];
-static	Huff	hofftab[Noff];
-
-/* bit reversal for brain dead endian swap in huffman codes */
-static	uchar	revtab[256];
-static	ulong	nlits;
-static	ulong	nmatches;
-
-int
-deflateinit(void)
-{
-	ulong bitcount[MaxHuffBits];
-	int i, j, ci, n;
-
-	/* byte reverse table */
-	for(i=0; i<256; i++)
-		for(j=0; j<8; j++)
-			if(i & (1<<j))
-				revtab[i] |= 0x80 >> j;
-
-	/* static Litlen bit lengths */
-	for(i=0; i<144; i++)
-		litlentab[i].bits = 8;
-	for(i=144; i<256; i++)
-		litlentab[i].bits = 9;
-	for(i=256; i<280; i++)
-		litlentab[i].bits = 7;
-	for(i=280; i<Nlitlen; i++)
-		litlentab[i].bits = 8;
-
-	memset(bitcount, 0, sizeof(bitcount));
-	bitcount[8] += 144 - 0;
-	bitcount[9] += 256 - 144;
-	bitcount[7] += 280 - 256;
-	bitcount[8] += Nlitlen - 280;
-
-	if(!hufftabinit(litlentab, Nlitlen, bitcount, 9))
-		return FlateInternal;
-
-	/* static offset bit lengths */
-	for(i = 0; i < Noff; i++)
-		offtab[i].bits = 5;
-
-	memset(bitcount, 0, sizeof(bitcount));
-	bitcount[5] = Noff;
-
-	if(!hufftabinit(offtab, Noff, bitcount, 5))
-		return FlateInternal;
-
-	bitcount[0] = 0;
-	bitcount[1] = 0;
-	if(!mkgzprecode(hofftab, bitcount, 2, MaxHuffBits))
-		return FlateInternal;
-
-	/* conversion tables for lens & offs to codes */
-	ci = 0;
-	for(i = LenStart; i < 286; i++){
-		n = ci + (1 << litlenextra[i - LenStart]);
-		litlenbase[i - LenStart] = ci;
-		for(; ci < n; ci++)
-			lencode[ci] = i;
-	}
-	/* patch up special case for len MaxMatch */
-	lencode[MaxMatch-MinMatch] = 285;
-	litlenbase[285-LenStart] = MaxMatch-MinMatch;
-
-	ci = 0;
-	for(i = 0; i < 16; i++){
-		n = ci + (1 << offextra[i]);
-		offbase[i] = ci;
-		for(; ci < n; ci++)
-			offcode[ci] = i;
-	}
-
-	ci = ci >> 7;
-	for(; i < 30; i++){
-		n = ci + (1 << (offextra[i] - 7));
-		offbase[i] = ci << 7;
-		for(; ci < n; ci++)
-			bigoffcode[ci] = i;
-	}
-	return FlateOk;
-}
-
-static void
-deflatereset(LZstate *lz, int level, int debug)
-{
-	memset(lz->nexts, 0, sizeof lz->nexts);
-	memset(lz->hash, 0, sizeof lz->hash);
-	lz->totr = 0;
-	lz->totw = 0;
-	lz->pos = 0;
-	lz->avail = 0;
-	lz->out = lz->obuf;
-	lz->eout = &lz->obuf[DeflateOut];
-	lz->prevlen = MinMatch - 1;
-	lz->prevoff = 0;
-	lz->now = MaxOff + 1;
-	lz->dot = lz->now;
-	lz->bits = 0;
-	lz->nbits = 0;
-	lz->maxcheck = (1 << level);
-	lz->maxcheck -= lz->maxcheck >> 2;
-	if(lz->maxcheck < 2)
-		lz->maxcheck = 2;
-	else if(lz->maxcheck > 1024)
-		lz->maxcheck = 1024;
-
-	lz->debug = debug;
-}
-
-int
-deflate(void *wr, int (*w)(void*, void*, int), void *rr, int (*r)(void*, void*, int), int level, int debug)
-{
-	LZstate *lz;
-	LZblock *lzb;
-	int ok;
-
-	lz = malloc(sizeof *lz + sizeof *lzb);
-	if(lz == nil)
-		return FlateNoMem;
-	lzb = (LZblock*)&lz[1];
-
-	deflatereset(lz, level, debug);
-	lz->w = w;
-	lz->wr = wr;
-	lz->wbad = 0;
-	lz->rbad = 0;
-	lz->eof = 0;
-	ok = FlateOk;
-	while(!lz->eof || lz->avail){
-		ok = deflateb(lz, lzb, rr, r);
-		if(ok != FlateOk)
-			break;
-	}
-	if(ok == FlateOk && lz->rbad)
-		ok = FlateInputFail;
-	if(ok == FlateOk && lz->wbad)
-		ok = FlateOutputFail;
-	free(lz);
-	return ok;
-}
-
-static int
-deflateb(LZstate *lz, LZblock *lzb, void *rr, int (*r)(void*, void*, int))
-{
-	Dyncode dyncode, hdyncode;
-	Huff dlitlentab[Nlitlen], dofftab[Noff], hlitlentab[Nlitlen];
-	ulong litcount[Nlitlen];
-	long nunc, ndyn, nfix, nhuff;
-	uchar *slop, *hslop;
-	ulong ep;
-	int i, n, m, mm, nslop;
-
-	memset(lzb->litlencount, 0, sizeof lzb->litlencount);
-	memset(lzb->offcount, 0, sizeof lzb->offcount);
-	lzb->litlencount[DeflateEob]++;
-
-	lzb->bytes = 0;
-	lzb->eparse = lzb->parse;
-	lzb->lastv = 0;
-	lzb->excost = 0;
-
-	slop = &lz->hist[lz->pos];
-	n = lz->avail;
-	while(n < DeflateBlock && (!lz->eof || lz->avail)){
-		/*
-		 * fill the buffer as much as possible,
-		 * while leaving room for MaxOff history behind lz->pos,
-		 * and not reading more than we can handle.
-		 *
-		 * make sure we read at least HistSlop bytes.
-		 */
-		if(!lz->eof){
-			ep = lz->pos + lz->avail;
-			if(ep >= HistBlock)
-				ep -= HistBlock;
-			m = HistBlock - MaxOff - lz->avail;
-			if(m > HistBlock - n)
-				m = HistBlock - n;
-			if(m > (HistBlock + HistSlop) - ep)
-				m = (HistBlock + HistSlop) - ep;
-			if(m & ~(BlockSize - 1))
-				m &= ~(BlockSize - 1);
-
-			/*
-			 * be nice to the caller: stop reads that are too small.
-			 * can only get here when we've already filled the buffer some
-			 */
-			if(m < HistSlop){
-				if(!m || !lzb->bytes)
-					return FlateInternal;
-				break;
-			}
-
-			mm = (*r)(rr, &lz->hist[ep], m);
-			if(mm > 0){
-				/*
-				 * wrap data to end if we're read it from the beginning
-				 * this way, we don't have to wrap searches.
-				 *
-				 * wrap reads past the end to the beginning.
-				 * this way, we can guarantee minimum size reads.
-				 */
-				if(ep < HistSlop)
-					memmove(&lz->hist[ep + HistBlock], &lz->hist[ep], HistSlop - ep);
-				else if(ep + mm > HistBlock)
-					memmove(&lz->hist[0], &lz->hist[HistBlock], ep + mm - HistBlock);
-
-				lz->totr += mm;
-				n += mm;
-				lz->avail += mm;
-			}else{
-				if(mm < 0)
-					lz->rbad = 1;
-				lz->eof = 1;
-			}
-		}
-		ep = lz->pos + lz->avail;
-		if(ep > HistSize)
-			ep = HistSize;
-		if(lzb->bytes + ep - lz->pos > DeflateMaxBlock)
-			ep = lz->pos + DeflateMaxBlock - lzb->bytes;
-		m = lzcomp(lz, lzb, &lz->hist[ep], lzb->eparse, lz->eof);
-		lzb->bytes += m;
-		lz->pos = (lz->pos + m) & (HistBlock - 1);
-		lz->avail -= m;
-	}
-	if(lzb->lastv)
-		*lzb->eparse++ = lzb->lastv;
-	if(lzb->eparse > lzb->parse + nelem(lzb->parse))
-		return FlateInternal;
-	nunc = lzb->bytes;
-
-	if(!mkgzprecode(dlitlentab, lzb->litlencount, Nlitlen, MaxHuffBits)
-	|| !mkgzprecode(dofftab, lzb->offcount, Noff, MaxHuffBits))
-		return FlateInternal;
-
-	ndyn = huffcodes(&dyncode, dlitlentab, dofftab);
-	if(ndyn < 0)
-		return FlateInternal;
-	ndyn += bitcost(dlitlentab, lzb->litlencount, Nlitlen)
-		+ bitcost(dofftab, lzb->offcount, Noff)
-		+ lzb->excost;
-
-	memset(litcount, 0, sizeof litcount);
-
-	nslop = nunc;
-	if(nslop > &lz->hist[HistSize] - slop)
-		nslop = &lz->hist[HistSize] - slop;
-
-	for(i = 0; i < nslop; i++)
-		litcount[slop[i]]++;
-	hslop = &lz->hist[HistSlop - nslop];
-	for(; i < nunc; i++)
-		litcount[hslop[i]]++;
-	litcount[DeflateEob]++;
-
-	if(!mkgzprecode(hlitlentab, litcount, Nlitlen, MaxHuffBits))
-		return FlateInternal;
-	nhuff = huffcodes(&hdyncode, hlitlentab, hofftab);
-	if(nhuff < 0)
-		return FlateInternal;
-	nhuff += bitcost(hlitlentab, litcount, Nlitlen);
-
-	nfix = bitcost(litlentab, lzb->litlencount, Nlitlen)
-		+ bitcost(offtab, lzb->offcount, Noff)
-		+ lzb->excost;
-
-	lzput(lz, lz->eof && !lz->avail, 1);
-
-	if(lz->debug){
-		fprint(2, "block: bytes=%lud entries=%ld extra bits=%d\n\tuncompressed=%lud fixed=%lud dynamic=%lud huffman=%lud\n",
-			nunc, lzb->eparse - lzb->parse, lzb->excost, (nunc + 4) * 8, nfix, ndyn, nhuff);
-		fprint(2, "\tnlit=%lud matches=%lud eof=%d\n", nlits, nmatches, lz->eof && !lz->avail);
-	}
-
-	if((nunc + 4) * 8 < ndyn && (nunc + 4) * 8 < nfix && (nunc + 4) * 8 < nhuff){
-		lzput(lz, DeflateUnc, 2);
-		lzflushbits(lz);
-
-		lzput(lz, nunc & 0xff, 8);
-		lzput(lz, (nunc >> 8) & 0xff, 8);
-		lzput(lz, ~nunc & 0xff, 8);
-		lzput(lz, (~nunc >> 8) & 0xff, 8);
-		lzflush(lz);
-
-		lzwrite(lz, slop, nslop);
-		lzwrite(lz, &lz->hist[HistSlop], nunc - nslop);
-	}else if(ndyn < nfix && ndyn < nhuff){
-		lzput(lz, DeflateDyn, 2);
-
-		wrdyncode(lz, &dyncode);
-		wrblock(lz, slop - lz->hist, lzb->parse, lzb->eparse, dlitlentab, dofftab);
-		lzput(lz, dlitlentab[DeflateEob].encode, dlitlentab[DeflateEob].bits);
-	}else if(nhuff < nfix){
-		lzput(lz, DeflateDyn, 2);
-
-		wrdyncode(lz, &hdyncode);
-
-		m = 0;
-		for(i = nunc; i > MaxLitRun; i -= MaxLitRun)
-			lzb->parse[m++] = MaxLitRun;
-		lzb->parse[m++] = i;
-
-		wrblock(lz, slop - lz->hist, lzb->parse, lzb->parse + m, hlitlentab, hofftab);
-		lzput(lz, hlitlentab[DeflateEob].encode, hlitlentab[DeflateEob].bits);
-	}else{
-		lzput(lz, DeflateFix, 2);
-
-		wrblock(lz, slop - lz->hist, lzb->parse, lzb->eparse, litlentab, offtab);
-		lzput(lz, litlentab[DeflateEob].encode, litlentab[DeflateEob].bits);
-	}
-
-	if(lz->eof && !lz->avail){
-		lzflushbits(lz);
-		lzflush(lz);
-	}
-	return FlateOk;
-}
-
-static void
-lzwrite(LZstate *lz, void *buf, int n)
-{
-	int nw;
-
-	if(n && lz->w){
-		nw = (*lz->w)(lz->wr, buf, n);
-		if(nw != n){
-			lz->w = nil;
-			lz->wbad = 1;
-		}else
-			lz->totw += n;
-	}
-}
-
-static void
-lzflush(LZstate *lz)
-{
-	lzwrite(lz, lz->obuf, lz->out - lz->obuf);
-	lz->out = lz->obuf;
-}
-
-static void
-lzput(LZstate *lz, ulong bits, int nbits)
-{
-	bits = (bits << lz->nbits) | lz->bits;
-	for(nbits += lz->nbits; nbits >= 8; nbits -= 8){
-		*lz->out++ = bits;
-		if(lz->out == lz->eout)
-			lzflush(lz);
-		bits >>= 8;
-	}
-	lz->bits = bits;
-	lz->nbits = nbits;
-}
-
-static void
-lzflushbits(LZstate *lz)
-{
-	if(lz->nbits)
-		lzput(lz, 0, 8 - (lz->nbits & 7));
-}
-
-/*
- * write out a block of n samples,
- * given lz encoding and counts for huffman tables
- */
-static void
-wrblock(LZstate *out, int litoff, ushort *soff, ushort *eoff, Huff *litlentab, Huff *offtab)
-{
-	ushort *off;
-	int i, run, offset, lit, len, c;
-
-	if(out->debug > 2){
-		for(off = soff; off < eoff; ){
-			offset = *off++;
-			run = offset & MaxLitRun;
-			if(run){
-				for(i = 0; i < run; i++){
-					lit = out->hist[litoff & (HistBlock - 1)];
-					litoff++;
-					fprint(2, "\tlit %.2ux %c\n", lit, lit);
-				}
-				if(!(offset & LenFlag))
-					continue;
-				len = offset >> LenShift;
-				offset = *off++;
-			}else if(offset & LenFlag){
-				len = offset >> LenShift;
-				offset = *off++;
-			}else{
-				len = 0;
-				offset >>= LenShift;
-			}
-			litoff += len + MinMatch;
-			fprint(2, "\t<%d, %d>\n", offset + 1, len + MinMatch);
-		}
-	}
-
-	for(off = soff; off < eoff; ){
-		offset = *off++;
-		run = offset & MaxLitRun;
-		if(run){
-			for(i = 0; i < run; i++){
-				lit = out->hist[litoff & (HistBlock - 1)];
-				litoff++;
-				lzput(out, litlentab[lit].encode, litlentab[lit].bits);
-			}
-			if(!(offset & LenFlag))
-				continue;
-			len = offset >> LenShift;
-			offset = *off++;
-		}else if(offset & LenFlag){
-			len = offset >> LenShift;
-			offset = *off++;
-		}else{
-			len = 0;
-			offset >>= LenShift;
-		}
-		litoff += len + MinMatch;
-		c = lencode[len];
-		lzput(out, litlentab[c].encode, litlentab[c].bits);
-		c -= LenStart;
-		if(litlenextra[c])
-			lzput(out, len - litlenbase[c], litlenextra[c]);
-
-		if(offset < MaxOffCode)
-			c = offcode[offset];
-		else
-			c = bigoffcode[offset >> 7];
-		lzput(out, offtab[c].encode, offtab[c].bits);
-		if(offextra[c])
-			lzput(out, offset - offbase[c], offextra[c]);
-	}
-}
-
-/*
- * look for the longest, closest string which matches
- * the next prefix.  the clever part here is looking for
- * a string 1 longer than the previous best match.
- *
- * follows the recommendation of limiting number of chains
- * which are checked.  this appears to be the best heuristic.
- */
-static int
-lzmatch(int now, int then, uchar *p, uchar *es, ushort *nexts, uchar *hist, int runlen, int check, int *m)
-{
-	uchar *s, *t;
-	int ml, off, last;
-
-	ml = check;
-	if(runlen >= 8)
-		check >>= 2;
-	*m = 0;
-	if(p + runlen >= es)
-		return runlen;
-	last = 0;
-	for(; check-- > 0; then = nexts[then & (MaxOff-1)]){
-		off = (ushort)(now - then);
-		if(off <= last || off > MaxOff)
-			break;
-		s = p + runlen;
-		t = hist + (((p - hist) - off) & (HistBlock-1));
-		t += runlen;
-		for(; s >= p; s--){
-			if(*s != *t)
-				goto matchloop;
-			t--;
-		}
-
-		/*
-		 * we have a new best match.
-		 * extend it to it's maximum length
-		 */
-		t += runlen + 2;
-		s += runlen + 2;
-		for(; s < es; s++){
-			if(*s != *t)
-				break;
-			t++;
-		}
-		runlen = s - p;
-		*m = off - 1;
-		if(s == es || runlen > ml)
-			break;
-matchloop:;
-		last = off;
-	}
-	return runlen;
-}
-
-static int
-lzcomp(LZstate *lz, LZblock *lzb, uchar *ep, ushort *parse, int finish)
-{
-	ulong cont, excost, *litlencount, *offcount;
-	uchar *p, *q, *s, *es;
-	ushort *nexts, *hash;
-	int v, i, h, runlen, n, now, then, m, prevlen, prevoff, maxdefer;
-
-	litlencount = lzb->litlencount;
-	offcount = lzb->offcount;
-	nexts = lz->nexts;
-	hash = lz->hash;
-	now = lz->now;
-
-	p = &lz->hist[lz->pos];
-	if(lz->prevlen != MinMatch - 1)
-		p++;
-
-	/*
-	 * hash in the links for any hanging link positions,
-	 * and calculate the hash for the current position.
-	 */
-	n = MinMatch;
-	if(n > ep - p)
-		n = ep - p;
-	cont = 0;
-	for(i = 0; i < n - 1; i++){
-		m = now - ((MinMatch-1) - i);
-		if(m < lz->dot)
-			continue;
-		s = lz->hist + (((p - lz->hist) - (now - m)) & (HistBlock-1));
-
-		cont = (s[0] << 16) | (s[1] << 8) | s[2];
-		h = hashit(cont);
-		prevoff = 0;
-		for(then = hash[h]; ; then = nexts[then & (MaxOff-1)]){
-			v = (ushort)(now - then);
-			if(v <= prevoff || v >= (MinMatch-1) - i)
-				break;
-			prevoff = v;
-		}
-		if(then == (ushort)m)
-			continue;
-		nexts[m & (MaxOff-1)] = hash[h];
-		hash[h] = m;
-	}
-	for(i = 0; i < n; i++)
-		cont = (cont << 8) | p[i];
-
-	/*
-	 * now must point to the index in the nexts array
-	 * corresponding to p's position in the history
-	 */
-	prevlen = lz->prevlen;
-	prevoff = lz->prevoff;
-	maxdefer = lz->maxcheck >> 2;
-	excost = 0;
-	v = lzb->lastv;
-	for(;;){
-		es = p + MaxMatch;
-		if(es > ep){
-			if(!finish || p >= ep)
-				break;
-			es = ep;
-		}
-
-		h = hashit(cont);
-		runlen = lzmatch(now, hash[h], p, es, nexts, lz->hist, prevlen, lz->maxcheck, &m);
-
-		/*
-		 * back out of small matches too far in the past
-		 */
-		if(runlen == MinMatch && m >= MinMatchMaxOff){
-			runlen = MinMatch - 1;
-			m = 0;
-		}
-
-		/*
-		 * record the encoding and increment counts for huffman trees
-		 * if we get a match, defer selecting it until we check for
-		 * a longer match at the next position.
-		 */
-		if(prevlen >= runlen && prevlen != MinMatch - 1){
-			/*
-			 * old match at least as good; use that one
-			 */
-			n = prevlen - MinMatch;
-			if(v || n){
-				*parse++ = v | LenFlag | (n << LenShift);
-				*parse++ = prevoff;
-			}else
-				*parse++ = prevoff << LenShift;
-			v = 0;
-
-			n = lencode[n];
-			litlencount[n]++;
-			excost += litlenextra[n - LenStart];
-
-			if(prevoff < MaxOffCode)
-				n = offcode[prevoff];
-			else
-				n = bigoffcode[prevoff >> 7];
-			offcount[n]++;
-			excost += offextra[n];
-
-			runlen = prevlen - 1;
-			prevlen = MinMatch - 1;
-			nmatches++;
-		}else if(runlen == MinMatch - 1){
-			/*
-			 * no match; just put out the literal
-			 */
-			if(++v == MaxLitRun){
-				*parse++ = v;
-				v = 0;
-			}
-			litlencount[*p]++;
-			nlits++;
-			runlen = 1;
-		}else{
-			if(prevlen != MinMatch - 1){
-				/*
-				 * longer match now. output previous literal,
-				 * update current match, and try again
-				 */
-				if(++v == MaxLitRun){
-					*parse++ = v;
-					v = 0;
-				}
-				litlencount[p[-1]]++;
-				nlits++;
-			}
-
-			prevoff = m;
-
-			if(runlen < maxdefer){
-				prevlen = runlen;
-				runlen = 1;
-			}else{
-				n = runlen - MinMatch;
-				if(v || n){
-					*parse++ = v | LenFlag | (n << LenShift);
-					*parse++ = prevoff;
-				}else
-					*parse++ = prevoff << LenShift;
-				v = 0;
-
-				n = lencode[n];
-				litlencount[n]++;
-				excost += litlenextra[n - LenStart];
-
-				if(prevoff < MaxOffCode)
-					n = offcode[prevoff];
-				else
-					n = bigoffcode[prevoff >> 7];
-				offcount[n]++;
-				excost += offextra[n];
-
-				prevlen = MinMatch - 1;
-				nmatches++;
-			}
-		}
-
-		/*
-		 * update the hash for the newly matched data
-		 * this is constructed so the link for the old
-		 * match in this position must be at the end of a chain,
-		 * and will expire when this match is added, ie it will
-		 * never be examined by the match loop.
-		 * add to the hash chain only if we have the real hash data.
-		 */
-		for(q = p + runlen; p != q; p++){
-			if(p + MinMatch <= ep){
-				h = hashit(cont);
-				nexts[now & (MaxOff-1)] = hash[h];
-				hash[h] = now;
-				if(p + MinMatch < ep)
-					cont = (cont << 8) | p[MinMatch];
-			}
-			now++;
-		}
-	}
-
-	/*
-	 * we can just store away the lazy state and
-	 * pick it up next time.  the last block will have finish set
-	 * so we won't have any pending matches
-	 * however, we need to correct for how much we've encoded
-	 */
-	if(prevlen != MinMatch - 1)
-		p--;
-
-	lzb->excost += excost;
-	lzb->eparse = parse;
-	lzb->lastv = v;
-
-	lz->now = now;
-	lz->prevlen = prevlen;
-	lz->prevoff = prevoff;
-
-	return p - &lz->hist[lz->pos];
-}
-
-/*
- * make up the dynamic code tables, and return the number of bits
- * needed to transmit them.
- */
-static int
-huffcodes(Dyncode *dc, Huff *littab, Huff *offtab)
-{
-	Huff *codetab;
-	uchar *codes, *codeaux;
-	ulong codecount[Nclen], excost;
-	int i, n, m, v, c, nlit, noff, ncode, nclen;
-
-	codetab = dc->codetab;
-	codes = dc->codes;
-	codeaux = dc->codeaux;
-
-	/*
-	 * trim the sizes of the tables
-	 */
-	for(nlit = Nlitlen; nlit > 257 && littab[nlit-1].bits == 0; nlit--)
-		;
-	for(noff = Noff; noff > 1 && offtab[noff-1].bits == 0; noff--)
-		;
-
-	/*
-	 * make the code-length code
-	 */
-	for(i = 0; i < nlit; i++)
-		codes[i] = littab[i].bits;
-	for(i = 0; i < noff; i++)
-		codes[i + nlit] = offtab[i].bits;
-
-	/*
-	 * run-length compress the code-length code
-	 */
-	excost = 0;
-	c = 0;
-	ncode = nlit+noff;
-	for(i = 0; i < ncode; ){
-		n = i + 1;
-		v = codes[i];
-		while(n < ncode && v == codes[n])
-			n++;
-		n -= i;
-		i += n;
-		if(v == 0){
-			while(n >= 11){
-				m = n;
-				if(m > 138)
-					m = 138;
-				codes[c] = 18;
-				codeaux[c++] = m - 11;
-				n -= m;
-				excost += 7;
-			}
-			if(n >= 3){
-				codes[c] = 17;
-				codeaux[c++] = n - 3;
-				n = 0;
-				excost += 3;
-			}
-		}
-		while(n--){
-			codes[c++] = v;
-			while(n >= 3){
-				m = n;
-				if(m > 6)
-					m = 6;
-				codes[c] = 16;
-				codeaux[c++] = m - 3;
-				n -= m;
-				excost += 3;
-			}
-		}
-	}
-
-	memset(codecount, 0, sizeof codecount);
-	for(i = 0; i < c; i++)
-		codecount[codes[i]]++;
-	if(!mkgzprecode(codetab, codecount, Nclen, 8))
-		return -1;
-
-	for(nclen = Nclen; nclen > 4 && codetab[clenorder[nclen-1]].bits == 0; nclen--)
-		;
-
-	dc->nlit = nlit;
-	dc->noff = noff;
-	dc->nclen = nclen;
-	dc->ncode = c;
-
-	return 5 + 5 + 4 + nclen * 3 + bitcost(codetab, codecount, Nclen) + excost;
-}
-
-static void
-wrdyncode(LZstate *out, Dyncode *dc)
-{
-	Huff *codetab;
-	uchar *codes, *codeaux;
-	int i, v, c;
-
-	/*
-	 * write out header, then code length code lengths,
-	 * and code lengths
-	 */
-	lzput(out, dc->nlit-257, 5);
-	lzput(out, dc->noff-1, 5);
-	lzput(out, dc->nclen-4, 4);
-
-	codetab = dc->codetab;
-	for(i = 0; i < dc->nclen; i++)
-		lzput(out, codetab[clenorder[i]].bits, 3);
-
-	codes = dc->codes;
-	codeaux = dc->codeaux;
-	c = dc->ncode;
-	for(i = 0; i < c; i++){
-		v = codes[i];
-		lzput(out, codetab[v].encode, codetab[v].bits);
-		if(v >= 16){
-			if(v == 16)
-				lzput(out, codeaux[i], 2);
-			else if(v == 17)
-				lzput(out, codeaux[i], 3);
-			else /* v == 18 */
-				lzput(out, codeaux[i], 7);
-		}
-	}
-}
-
-static int
-bitcost(Huff *tab, ulong *count, int n)
-{
-	ulong tot;
-	int i;
-
-	tot = 0;
-	for(i = 0; i < n; i++)
-		tot += count[i] * tab[i].bits;
-	return tot;
-}
-
-static int
-mkgzprecode(Huff *tab, ulong *count, int n, int maxbits)
-{
-	ulong bitcount[MaxHuffBits];
-	int i, nbits;
-
-	nbits = mkprecode(tab, count, n, maxbits, bitcount);
-	for(i = 0; i < n; i++){
-		if(tab[i].bits == -1)
-			tab[i].bits = 0;
-		else if(tab[i].bits == 0){
-			if(nbits != 0 || bitcount[0] != 1)
-				return 0;
-			bitcount[1] = 1;
-			bitcount[0] = 0;
-			nbits = 1;
-			tab[i].bits = 1;
-		}
-	}
-	if(bitcount[0] != 0)
-		return 0;
-	return hufftabinit(tab, n, bitcount, nbits);
-}
-
-static int
-hufftabinit(Huff *tab, int n, ulong *bitcount, int nbits)
-{
-	ulong code, nc[MaxHuffBits];
-	int i, bits;
-
-	code = 0;
-	for(bits = 1; bits <= nbits; bits++){
-		code = (code + bitcount[bits-1]) << 1;
-		nc[bits] = code;
-	}
-
-	for(i = 0; i < n; i++){
-		bits = tab[i].bits;
-		if(bits){
-			code = nc[bits]++ << (16 - bits);
-			if(code & ~0xffff)
-				return 0;
-			tab[i].encode = revtab[code >> 8] | (revtab[code & 0xff] << 8);
-		}
-	}
-	return 1;
-}
-
-
-/*
- * this should be in a library
- */
-struct Chain
-{
-	ulong	count;				/* occurances of everything in the chain */
-	ushort	leaf;				/* leaves to the left of chain, or leaf value */
-	char	col;				/* ref count for collecting unused chains */
-	char	gen;				/* need to generate chains for next lower level */
-	Chain	*up;				/* Chain up in the lists */
-};
-
-struct Chains
-{
-	Chain	*lists[(MaxHuffBits - 1) * 2];
-	ulong	leafcount[MaxLeaf];		/* sorted list of leaf counts */
-	ushort	leafmap[MaxLeaf];		/* map to actual leaf number */
-	int	nleaf;				/* number of leaves */
-	Chain	chains[ChainMem];
-	Chain	*echains;
-	Chain	*free;
-	char	col;
-	int	nlists;
-};
-
-/*
- * fast, low space overhead algorithm for max depth huffman type codes
- *
- * J. Katajainen, A. Moffat and A. Turpin, "A fast and space-economical
- * algorithm for length-limited coding," Proc. Intl. Symp. on Algorithms
- * and Computation, Cairns, Australia, Dec. 1995, Lecture Notes in Computer
- * Science, Vol 1004, J. Staples, P. Eades, N. Katoh, and A. Moffat, eds.,
- * pp 12-21, Springer Verlag, New York, 1995.
- */
-static int
-mkprecode(Huff *tab, ulong *count, int n, int maxbits, ulong *bitcount)
-{
-	Chains cs;
-	Chain *c;
-	int i, m, em, bits;
-
-	/*
-	 * set up the sorted list of leaves
-	 */
-	m = 0;
-	for(i = 0; i < n; i++){
-		tab[i].bits = -1;
-		tab[i].encode = 0;
-		if(count[i] != 0){
-			cs.leafcount[m] = count[i];
-			cs.leafmap[m] = i;
-			m++;
-		}
-	}
-	if(m < 2){
-		if(m != 0){
-			tab[cs.leafmap[0]].bits = 0;
-			bitcount[0] = 1;
-		}else
-			bitcount[0] = 0;
-		return 0;
-	}
-	cs.nleaf = m;
-	leafsort(cs.leafcount, cs.leafmap, 0, m);
-
-	for(i = 0; i < m; i++)
-		cs.leafcount[i] = count[cs.leafmap[i]];
-
-	/*
-	 * set up free list
-	 */
-	cs.free = &cs.chains[2];
-	cs.echains = &cs.chains[ChainMem];
-	cs.col = 1;
-
-	/*
-	 * initialize chains for each list
-	 */
-	c = &cs.chains[0];
-	c->count = cs.leafcount[0];
-	c->leaf = 1;
-	c->col = cs.col;
-	c->up = nil;
-	c->gen = 0;
-	cs.chains[1] = cs.chains[0];
-	cs.chains[1].leaf = 2;
-	cs.chains[1].count = cs.leafcount[1];
-	for(i = 0; i < maxbits-1; i++){
-		cs.lists[i * 2] = &cs.chains[0];
-		cs.lists[i * 2 + 1] = &cs.chains[1];
-	}
-
-	cs.nlists = 2 * (maxbits - 1);
-	m = 2 * m - 2;
-	for(i = 2; i < m; i++)
-		nextchain(&cs, cs.nlists - 2);
-
-	bits = 0;
-	bitcount[0] = cs.nleaf;
-	for(c = cs.lists[cs.nlists - 1]; c != nil; c = c->up){
-		m = c->leaf;
-		bitcount[bits++] -= m;
-		bitcount[bits] = m;
-	}
-	m = 0;
-	for(i = bits; i >= 0; i--)
-		for(em = m + bitcount[i]; m < em; m++)
-			tab[cs.leafmap[m]].bits = i;
-
-	return bits;
-}
-
-/*
- * calculate the next chain on the list
- * we can always toss out the old chain
- */
-static void
-nextchain(Chains *cs, int list)
-{
-	Chain *c, *oc;
-	int i, nleaf, sumc;
-
-	oc = cs->lists[list + 1];
-	cs->lists[list] = oc;
-	if(oc == nil)
-		return;
-
-	/*
-	 * make sure we have all chains needed to make sumc
-	 * note it is possible to generate only one of these,
-	 * use twice that value for sumc, and then generate
-	 * the second if that preliminary sumc would be chosen.
-	 * however, this appears to be slower on current tests
-	 */
-	if(oc->gen){
-		nextchain(cs, list - 2);
-		nextchain(cs, list - 2);
-		oc->gen = 0;
-	}
-
-	/*
-	 * pick up the chain we're going to add;
-	 * collect unused chains no free ones are left
-	 */
-	for(c = cs->free; ; c++){
-		if(c >= cs->echains){
-			cs->col++;
-			for(i = 0; i < cs->nlists; i++)
-				for(c = cs->lists[i]; c != nil; c = c->up)
-					c->col = cs->col;
-			c = cs->chains;
-		}
-		if(c->col != cs->col)
-			break;
-	}
-
-	/*
-	 * pick the cheapest of
-	 * 1) the next package from the previous list
-	 * 2) the next leaf
-	 */
-	nleaf = oc->leaf;
-	sumc = 0;
-	if(list > 0 && cs->lists[list-1] != nil)
-		sumc = cs->lists[list-2]->count + cs->lists[list-1]->count;
-	if(sumc != 0 && (nleaf >= cs->nleaf || cs->leafcount[nleaf] > sumc)){
-		c->count = sumc;
-		c->leaf = oc->leaf;
-		c->up = cs->lists[list-1];
-		c->gen = 1;
-	}else if(nleaf >= cs->nleaf){
-		cs->lists[list + 1] = nil;
-		return;
-	}else{
-		c->leaf = nleaf + 1;
-		c->count = cs->leafcount[nleaf];
-		c->up = oc->up;
-		c->gen = 0;
-	}
-	cs->free = c + 1;
-
-	cs->lists[list + 1] = c;
-	c->col = cs->col;
-}
-
-static int
-pivot(ulong *c, int a, int n)
-{
-	int j, pi, pj, pk;
-
-	j = n/6;
-	pi = a + j;	/* 1/6 */
-	j += j;
-	pj = pi + j;	/* 1/2 */
-	pk = pj + j;	/* 5/6 */
-	if(c[pi] < c[pj]){
-		if(c[pi] < c[pk]){
-			if(c[pj] < c[pk])
-				return pj;
-			return pk;
-		}
-		return pi;
-	}
-	if(c[pj] < c[pk]){
-		if(c[pi] < c[pk])
-			return pi;
-		return pk;
-	}
-	return pj;
-}
-
-static	void
-leafsort(ulong *leafcount, ushort *leafmap, int a, int n)
-{
-	ulong t;
-	int j, pi, pj, pn;
-
-	while(n > 1){
-		if(n > 10){
-			pi = pivot(leafcount, a, n);
-		}else
-			pi = a + (n>>1);
-
-		t = leafcount[pi];
-		leafcount[pi] = leafcount[a];
-		leafcount[a] = t;
-		t = leafmap[pi];
-		leafmap[pi] = leafmap[a];
-		leafmap[a] = t;
-		pi = a;
-		pn = a + n;
-		pj = pn;
-		for(;;){
-			do
-				pi++;
-			while(pi < pn && (leafcount[pi] < leafcount[a] || leafcount[pi] == leafcount[a] && leafmap[pi] > leafmap[a]));
-			do
-				pj--;
-			while(pj > a && (leafcount[pj] > leafcount[a] || leafcount[pj] == leafcount[a] && leafmap[pj] < leafmap[a]));
-			if(pj < pi)
-				break;
-			t = leafcount[pi];
-			leafcount[pi] = leafcount[pj];
-			leafcount[pj] = t;
-			t = leafmap[pi];
-			leafmap[pi] = leafmap[pj];
-			leafmap[pj] = t;
-		}
-		t = leafcount[a];
-		leafcount[a] = leafcount[pj];
-		leafcount[pj] = t;
-		t = leafmap[a];
-		leafmap[a] = leafmap[pj];
-		leafmap[pj] = t;
-		j = pj - a;
-
-		n = n-j-1;
-		if(j >= n){
-			leafsort(leafcount, leafmap, a, j);
-			a += j+1;
-		}else{
-			leafsort(leafcount, leafmap, a + (j+1), n);
-			n = j;
-		}
-	}
-}
--- a/os/boot/libflate/deflateblock.c
+++ /dev/null
@@ -1,55 +1,0 @@
-#include "lib9.h"
-#include <flate.h>
-
-typedef struct Block	Block;
-
-struct Block
-{
-	uchar	*pos;
-	uchar	*limit;
-};
-
-static int
-blread(void *vb, void *buf, int n)
-{
-	Block *b;
-
-	b = vb;
-	if(n > b->limit - b->pos)
-		n = b->limit - b->pos;
-	memmove(buf, b->pos, n);
-	b->pos += n;
-	return n;
-}
-
-static int
-blwrite(void *vb, void *buf, int n)
-{
-	Block *b;
-
-	b = vb;
-
-	if(n > b->limit - b->pos)
-		n = b->limit - b->pos;
-	memmove(b->pos, buf, n);
-	b->pos += n;
-	return n;
-}
-
-int
-deflateblock(uchar *dst, int dsize, uchar *src, int ssize, int level, int debug)
-{
-	Block bd, bs;
-	int ok;
-
-	bs.pos = src;
-	bs.limit = src + ssize;
-
-	bd.pos = dst;
-	bd.limit = dst + dsize;
-
-	ok = deflate(&bd, blwrite, &bs, blread, level, debug);
-	if(ok != FlateOk)
-		return ok;
-	return bd.pos - dst;
-}
--- a/os/boot/libflate/deflatezlib.c
+++ /dev/null
@@ -1,59 +1,0 @@
-#include "lib9.h"
-#include <flate.h>
-#include "zlib.h"
-
-typedef struct ZRead	ZRead;
-
-struct ZRead
-{
-	ulong	adler;
-	void	*rr;
-	int	(*r)(void*, void*, int);
-};
-
-static int
-zlread(void *vzr, void *buf, int n)
-{
-	ZRead *zr;
-
-	zr = vzr;
-	n = (*zr->r)(zr->rr, buf, n);
-	if(n <= 0)
-		return n;
-	zr->adler = adler32(zr->adler, buf, n);
-	return n;
-}
-
-int
-deflatezlib(void *wr, int (*w)(void*, void*, int), void *rr, int (*r)(void*, void*, int), int level, int debug)
-{
-	ZRead zr;
-	uchar buf[4];
-	int ok;
-
-	buf[0] = ZlibDeflate | ZlibWin32k;
-
-	/* bogus zlib encoding of compression level */
-	buf[1] = ((level > 2) + (level > 5) + (level > 8)) << 6;
-
-	/* header check field */
-	buf[1] |= 31 - ((buf[0] << 8) | buf[1]) % 31;
-	if((*w)(wr, buf, 2) != 2)
-		return FlateOutputFail;
-
-	zr.rr = rr;
-	zr.r = r;
-	zr.adler = 1;
-	ok = deflate(wr, w, &zr, zlread, level, debug);
-	if(ok != FlateOk)
-		return ok;
-
-	buf[0] = zr.adler >> 24;
-	buf[1] = zr.adler >> 16;
-	buf[2] = zr.adler >> 8;
-	buf[3] = zr.adler;
-	if((*w)(wr, buf, 4) != 4)
-		return FlateOutputFail;
-
-	return FlateOk;
-}
--- a/os/boot/libflate/deflatezlibblock.c
+++ /dev/null
@@ -1,33 +1,0 @@
-#include "lib9.h"
-#include <flate.h>
-#include "zlib.h"
-
-int
-deflatezlibblock(uchar *dst, int dsize, uchar *src, int ssize, int level, int debug)
-{
-	ulong adler;
-	int n;
-
-	if(dsize < 6)
-		return FlateOutputFail;
-
-	n = deflateblock(dst + 2, dsize - 6, src, ssize, level, debug);
-	if(n < 0)
-		return n;
-
-	dst[0] = ZlibDeflate | ZlibWin32k;
-
-	/* bogus zlib encoding of compression level */
-	dst[1] = ((level > 2) + (level > 5) + (level > 8)) << 6;
-
-	/* header check field */
-	dst[1] |= 31 - ((dst[0] << 8) | dst[1]) % 31;
-
-	adler = adler32(1, src, ssize);
-	dst[n + 2] = adler >> 24;
-	dst[n + 3] = adler >> 16;
-	dst[n + 4] = adler >> 8;
-	dst[n + 5] = adler;
-
-	return n + 6;
-}
--- a/os/boot/libflate/flateerr.c
+++ /dev/null
@@ -1,22 +1,0 @@
-#include "lib9.h"
-#include <flate.h>
-
-char *
-flateerr(int err)
-{
-	switch(err){
-	case FlateOk:
-		return "no error";
-	case FlateNoMem:
-		return "out of memory";
-	case FlateInputFail:
-		return "input error";
-	case FlateOutputFail:
-		return "output error";
-	case FlateCorrupted:
-		return "corrupted data";
-	case FlateInternal:
-		return "internal error";
-	}
-	return "unknown error";
-}
--- a/os/boot/libflate/inflate.c
+++ /dev/null
@@ -1,692 +1,0 @@
-#include "lib9.h"
-#include <flate.h>
-
-enum {
-	HistorySize=	32*1024,
-	BufSize=	4*1024,
-	MaxHuffBits=	17,	/* maximum bits in a encoded code */
-	Nlitlen=	288,	/* number of litlen codes */
-	Noff=		32,	/* number of offset codes */
-	Nclen=		19,	/* number of codelen codes */
-	LenShift=	10,	/* code = len<<LenShift|code */
-	LitlenBits=	7,	/* number of bits in litlen decode table */
-	OffBits=	6,	/* number of bits in offset decode table */
-	ClenBits=	6,	/* number of bits in code len decode table */
-	MaxFlatBits=	LitlenBits,
-	MaxLeaf=	Nlitlen
-};
-
-typedef struct Input	Input;
-typedef struct History	History;
-typedef struct Huff	Huff;
-
-struct Input
-{
-	int	error;		/* first error encountered, or FlateOk */
-	void	*wr;
-	int	(*w)(void*, void*, int);
-	void	*getr;
-	int	(*get)(void*);
-	ulong	sreg;
-	int	nbits;
-};
-
-struct History
-{
-	uchar	his[HistorySize];
-	uchar	*cp;		/* current pointer in history */
-	int	full;		/* his has been filled up at least once */
-};
-
-struct Huff
-{
-	int	maxbits;	/* max bits for any code */
-	int	minbits;	/* min bits to get before looking in flat */
-	int	flatmask;	/* bits used in "flat" fast decoding table */
-	ulong	flat[1<<MaxFlatBits];
-	ulong	maxcode[MaxHuffBits];
-	ulong	last[MaxHuffBits];
-	ulong	decode[MaxLeaf];
-};
-
-/* litlen code words 257-285 extra bits */
-static int litlenextra[Nlitlen-257] =
-{
-/* 257 */	0, 0, 0,
-/* 260 */	0, 0, 0, 0, 0, 1, 1, 1, 1, 2,
-/* 270 */	2, 2, 2, 3, 3, 3, 3, 4, 4, 4,
-/* 280 */	4, 5, 5, 5, 5, 0, 0, 0
-};
-
-static int litlenbase[Nlitlen-257];
-
-/* offset code word extra bits */
-static int offextra[Noff] =
-{
-	0,  0,  0,  0,  1,  1,  2,  2,  3,  3,
-	4,  4,  5,  5,  6,  6,  7,  7,  8,  8,
-	9,  9,  10, 10, 11, 11, 12, 12, 13, 13,
-	0,  0,
-};
-static int offbase[Noff];
-
-/* order code lengths */
-static int clenorder[Nclen] =
-{
-        16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
-};
-
-/* for static huffman tables */
-static	Huff	litlentab;
-static	Huff	offtab;
-static	uchar	revtab[256];
-
-static int	uncblock(Input *in, History*);
-static int	fixedblock(Input *in, History*);
-static int	dynamicblock(Input *in, History*);
-static int	sregfill(Input *in, int n);
-static int	sregunget(Input *in);
-static int	decode(Input*, History*, Huff*, Huff*);
-static int	hufftab(Huff*, char*, int, int);
-static int	hdecsym(Input *in, Huff *h, int b);
-
-int
-inflateinit(void)
-{
-	char *len;
-	int i, j, base;
-
-	/* byte reverse table */
-	for(i=0; i<256; i++)
-		for(j=0; j<8; j++)
-			if(i & (1<<j))
-				revtab[i] |= 0x80 >> j;
-
-	for(i=257,base=3; i<Nlitlen; i++) {
-		litlenbase[i-257] = base;
-		base += 1<<litlenextra[i-257];
-	}
-	/* strange table entry in spec... */
-	litlenbase[285-257]--;
-
-	for(i=0,base=1; i<Noff; i++) {
-		offbase[i] = base;
-		base += 1<<offextra[i];
-	}
-
-	len = malloc(MaxLeaf);
-	if(len == nil)
-		return FlateNoMem;
-
-	/* static Litlen bit lengths */
-	for(i=0; i<144; i++)
-		len[i] = 8;
-	for(i=144; i<256; i++)
-		len[i] = 9;
-	for(i=256; i<280; i++)
-		len[i] = 7;
-	for(i=280; i<Nlitlen; i++)
-		len[i] = 8;
-
-	if(!hufftab(&litlentab, len, Nlitlen, MaxFlatBits))
-		return FlateInternal;
-
-	/* static Offset bit lengths */
-	for(i=0; i<Noff; i++)
-		len[i] = 5;
-
-	if(!hufftab(&offtab, len, Noff, MaxFlatBits))
-		return FlateInternal;
-	free(len);
-
-	return FlateOk;
-}
-
-int
-inflate(void *wr, int (*w)(void*, void*, int), void *getr, int (*get)(void*))
-{
-	History *his;
-	Input in;
-	int final, type;
-
-	his = malloc(sizeof(History));
-	if(his == nil)
-		return FlateNoMem;
-	his->cp = his->his;
-	his->full = 0;
-	in.getr = getr;
-	in.get = get;
-	in.wr = wr;
-	in.w = w;
-	in.nbits = 0;
-	in.sreg = 0;
-	in.error = FlateOk;
-
-	do {
-		if(!sregfill(&in, 3))
-			goto bad;
-		final = in.sreg & 0x1;
-		type = (in.sreg>>1) & 0x3;
-		in.sreg >>= 3;
-		in.nbits -= 3;
-		switch(type) {
-		default:
-			in.error = FlateCorrupted;
-			goto bad;
-		case 0:
-			/* uncompressed */
-			if(!uncblock(&in, his))
-				goto bad;
-			break;
-		case 1:
-			/* fixed huffman */
-			if(!fixedblock(&in, his))
-				goto bad;
-			break;
-		case 2:
-			/* dynamic huffman */
-			if(!dynamicblock(&in, his))
-				goto bad;
-			break;
-		}
-	} while(!final);
-
-	if(his->cp != his->his && (*w)(wr, his->his, his->cp - his->his) != his->cp - his->his) {
-		in.error = FlateOutputFail;
-		goto bad;
-	}
-
-	if(!sregunget(&in))
-		goto bad;
-
-	free(his);
-	if(in.error != FlateOk)
-		return FlateInternal;
-	return FlateOk;
-
-bad:
-	free(his);
-	if(in.error == FlateOk)
-		return FlateInternal;
-	return in.error;
-}
-
-static int
-uncblock(Input *in, History *his)
-{
-	int len, nlen, c;
-	uchar *hs, *hp, *he;
-
-	if(!sregunget(in))
-		return 0;
-	len = (*in->get)(in->getr);
-	len |= (*in->get)(in->getr)<<8;
-	nlen = (*in->get)(in->getr);
-	nlen |= (*in->get)(in->getr)<<8;
-	if(len != (~nlen&0xffff)) {
-		in->error = FlateCorrupted;
-		return 0;
-	}
-
-	hp = his->cp;
-	hs = his->his;
-	he = hs + HistorySize;
-
-	while(len > 0) {
-		c = (*in->get)(in->getr);
-		if(c < 0)
-			return 0;
-		*hp++ = c;
-		if(hp == he) {
-			his->full = 1;
-			if((*in->w)(in->wr, hs, HistorySize) != HistorySize) {
-				in->error = FlateOutputFail;
-				return 0;
-			}
-			hp = hs;
-		}
-		len--;
-	}
-
-	his->cp = hp;
-
-	return 1;
-}
-
-static int
-fixedblock(Input *in, History *his)
-{
-	return decode(in, his, &litlentab, &offtab);
-}
-
-static int
-dynamicblock(Input *in, History *his)
-{
-	Huff *lentab, *offtab;
-	char *len;
-	int i, j, n, c, nlit, ndist, nclen, res, nb;
-
-	if(!sregfill(in, 14))
-		return 0;
-	nlit = (in->sreg&0x1f) + 257;
-	ndist = ((in->sreg>>5) & 0x1f) + 1;
-	nclen = ((in->sreg>>10) & 0xf) + 4;
-	in->sreg >>= 14;
-	in->nbits -= 14;
-
-	if(nlit > Nlitlen || ndist > Noff || nlit < 257) {
-		in->error = FlateCorrupted;
-		return 0;
-	}
-
-	/* huff table header */
-	len = malloc(Nlitlen+Noff);
-	lentab = malloc(sizeof(Huff));
-	offtab = malloc(sizeof(Huff));
-	if(len == nil || lentab == nil || offtab == nil){
-		in->error = FlateNoMem;
-		goto bad;
-	}
-	for(i=0; i < Nclen; i++)
-		len[i] = 0;
-	for(i=0; i<nclen; i++) {
-		if(!sregfill(in, 3))
-			goto bad;
-		len[clenorder[i]] = in->sreg & 0x7;
-		in->sreg >>= 3;
-		in->nbits -= 3;
-	}
-
-	if(!hufftab(lentab, len, Nclen, ClenBits)){
-		in->error = FlateCorrupted;
-		goto bad;
-	}
-
-	n = nlit+ndist;
-	for(i=0; i<n;) {
-		nb = lentab->minbits;
-		for(;;){
-			if(in->nbits<nb && !sregfill(in, nb))
-				goto bad;
-			c = lentab->flat[in->sreg & lentab->flatmask];
-			nb = c & 0xff;
-			if(nb > in->nbits){
-				if(nb != 0xff)
-					continue;
-				c = hdecsym(in, lentab, c);
-				if(c < 0)
-					goto bad;
-			}else{
-				c >>= 8;
-				in->sreg >>= nb;
-				in->nbits -= nb;
-			}
-			break;
-		}
-
-		if(c < 16) {
-			j = 1;
-		} else if(c == 16) {
-			if(in->nbits<2 && !sregfill(in, 2))
-				goto bad;
-			j = (in->sreg&0x3)+3;
-			in->sreg >>= 2;
-			in->nbits -= 2;
-			if(i == 0) {
-				in->error = FlateCorrupted;
-				goto bad;
-			}
-			c = len[i-1];
-		} else if(c == 17) {
-			if(in->nbits<3 && !sregfill(in, 3))
-				goto bad;
-			j = (in->sreg&0x7)+3;
-			in->sreg >>= 3;
-			in->nbits -= 3;
-			c = 0;
-		} else if(c == 18) {
-			if(in->nbits<7 && !sregfill(in, 7))
-				goto bad;
-			j = (in->sreg&0x7f)+11;
-			in->sreg >>= 7;
-			in->nbits -= 7;
-			c = 0;
-		} else {
-			in->error = FlateCorrupted;
-			goto bad;
-		}
-
-		if(i+j > n) {
-			in->error = FlateCorrupted;
-			goto bad;
-		}
-
-		while(j) {
-			len[i] = c;
-			i++;
-			j--;
-		}
-	}
-
-	if(!hufftab(lentab, len, nlit, LitlenBits)
-	|| !hufftab(offtab, &len[nlit], ndist, OffBits)){
-		in->error = FlateCorrupted;
-		goto bad;
-	}
-
-	res = decode(in, his, lentab, offtab);
-
-	free(len);
-	free(lentab);
-	free(offtab);
-
-	return res;
-
-bad:
-	free(len);
-	free(lentab);
-	free(offtab);
-	return 0;
-}
-
-static int
-decode(Input *in, History *his, Huff *litlentab, Huff *offtab)
-{
-	int len, off;
-	uchar *hs, *hp, *hq, *he;
-	int c;
-	int nb;
-
-	hs = his->his;
-	he = hs + HistorySize;
-	hp = his->cp;
-
-	for(;;) {
-		nb = litlentab->minbits;
-		for(;;){
-			if(in->nbits<nb && !sregfill(in, nb))
-				return 0;
-			c = litlentab->flat[in->sreg & litlentab->flatmask];
-			nb = c & 0xff;
-			if(nb > in->nbits){
-				if(nb != 0xff)
-					continue;
-				c = hdecsym(in, litlentab, c);
-				if(c < 0)
-					return 0;
-			}else{
-				c >>= 8;
-				in->sreg >>= nb;
-				in->nbits -= nb;
-			}
-			break;
-		}
-
-		if(c < 256) {
-			/* literal */
-			*hp++ = c;
-			if(hp == he) {
-				his->full = 1;
-				if((*in->w)(in->wr, hs, HistorySize) != HistorySize) {
-					in->error = FlateOutputFail;
-					return 0;
-				}
-				hp = hs;
-			}
-			continue;
-		}
-
-		if(c == 256)
-			break;
-
-		if(c > 285) {
-			in->error = FlateCorrupted;
-			return 0;
-		}
-
-		c -= 257;
-		nb = litlenextra[c];
-		if(in->nbits < nb && !sregfill(in, nb))
-			return 0;
-		len = litlenbase[c] + (in->sreg & ((1<<nb)-1));
-		in->sreg >>= nb;
-		in->nbits -= nb;
-
-		/* get offset */
-		nb = offtab->minbits;
-		for(;;){
-			if(in->nbits<nb && !sregfill(in, nb))
-				return 0;
-			c = offtab->flat[in->sreg & offtab->flatmask];
-			nb = c & 0xff;
-			if(nb > in->nbits){
-				if(nb != 0xff)
-					continue;
-				c = hdecsym(in, offtab, c);
-				if(c < 0)
-					return 0;
-			}else{
-				c >>= 8;
-				in->sreg >>= nb;
-				in->nbits -= nb;
-			}
-			break;
-		}
-
-		if(c > 29) {
-			in->error = FlateCorrupted;
-			return 0;
-		}
-
-		nb = offextra[c];
-		if(in->nbits < nb && !sregfill(in, nb))
-			return 0;
-
-		off = offbase[c] + (in->sreg & ((1<<nb)-1));
-		in->sreg >>= nb;
-		in->nbits -= nb;
-
-		hq = hp - off;
-		if(hq < hs) {
-			if(!his->full) {
-				in->error = FlateCorrupted;
-				return 0;
-			}
-			hq += HistorySize;
-		}
-
-		/* slow but correct */
-		while(len) {
-			*hp = *hq;
-			hq++;
-			hp++;
-			if(hq >= he)
-				hq = hs;
-			if(hp == he) {
-				his->full = 1;
-				if((*in->w)(in->wr, hs, HistorySize) != HistorySize) {
-					in->error = FlateOutputFail;
-					return 0;
-				}
-				hp = hs;
-			}
-			len--;
-		}
-
-	}
-
-	his->cp = hp;
-
-	return 1;
-}
-
-static int
-revcode(int c, int b)
-{
-	/* shift encode up so it starts on bit 15 then reverse */
-	c <<= (16-b);
-	c = revtab[c>>8] | (revtab[c&0xff]<<8);
-	return c;
-}
-
-/*
- * construct the huffman decoding arrays and a fast lookup table.
- * the fast lookup is a table indexed by the next flatbits bits,
- * which returns the symbol matched and the number of bits consumed,
- * or the minimum number of bits needed and 0xff if more than flatbits
- * bits are needed.
- *
- * flatbits can be longer than the smallest huffman code,
- * because shorter codes are assigned smaller lexical prefixes.
- * this means assuming zeros for the next few bits will give a
- * conservative answer, in the sense that it will either give the
- * correct answer, or return the minimum number of bits which
- * are needed for an answer.
- */
-static int
-hufftab(Huff *h, char *hb, int maxleaf, int flatbits)
-{
-	ulong bitcount[MaxHuffBits];
-	ulong c, fc, ec, mincode, code, nc[MaxHuffBits];
-	int i, b, minbits, maxbits;
-
-	for(i = 0; i < MaxHuffBits; i++)
-		bitcount[i] = 0;
-	maxbits = -1;
-	minbits = MaxHuffBits + 1;
-	for(i=0; i < maxleaf; i++){
-		b = hb[i];
-		if(b){
-			bitcount[b]++;
-			if(b < minbits)
-				minbits = b;
-			if(b > maxbits)
-				maxbits = b;
-		}
-	}
-
-	h->maxbits = maxbits;
-	if(maxbits <= 0){
-		h->maxbits = 0;
-		h->minbits = 0;
-		h->flatmask = 0;
-		return 1;
-	}
-	code = 0;
-	c = 0;
-	for(b = 0; b <= maxbits; b++){
-		h->last[b] = c;
-		c += bitcount[b];
-		mincode = code << 1;
-		nc[b] = mincode;
-		code = mincode + bitcount[b];
-		if(code > (1 << b))
-			return 0;
-		h->maxcode[b] = code - 1;
-		h->last[b] += code - 1;
-	}
-
-	if(flatbits > maxbits)
-		flatbits = maxbits;
-	h->flatmask = (1 << flatbits) - 1;
-	if(minbits > flatbits)
-		minbits = flatbits;
-	h->minbits = minbits;
-
-	b = 1 << flatbits;
-	for(i = 0; i < b; i++)
-		h->flat[i] = ~0;
-
-	/*
-	 * initialize the flat table to include the minimum possible
-	 * bit length for each code prefix
-	 */
-	for(b = maxbits; b > flatbits; b--){
-		code = h->maxcode[b];
-		if(code == -1)
-			break;
-		mincode = code + 1 - bitcount[b];
-		mincode >>= b - flatbits;
-		code >>= b - flatbits;
-		for(; mincode <= code; mincode++)
-			h->flat[revcode(mincode, flatbits)] = (b << 8) | 0xff;
-	}
-
-	for(i = 0; i < maxleaf; i++){
-		b = hb[i];
-		if(b <= 0)
-			continue;
-		c = nc[b]++;
-		if(b <= flatbits){
-			code = (i << 8) | b;
-			ec = (c + 1) << (flatbits - b);
-			if(ec > (1<<flatbits))
-				return 0;	/* this is actually an internal error */
-			for(fc = c << (flatbits - b); fc < ec; fc++)
-				h->flat[revcode(fc, flatbits)] = code;
-		}
-		if(b > minbits){
-			c = h->last[b] - c;
-			if(c >= maxleaf)
-				return 0;
-			h->decode[c] = i;
-		}
-	}
-	return 1;
-}
-
-static int
-hdecsym(Input *in, Huff *h, int nb)
-{
-	long c;
-
-	if((nb & 0xff) == 0xff)
-		nb = nb >> 8;
-	else
-		nb = nb & 0xff;
-	for(; nb <= h->maxbits; nb++){
-		if(in->nbits<nb && !sregfill(in, nb))
-			return -1;
-		c = revtab[in->sreg&0xff]<<8;
-		c |= revtab[(in->sreg>>8)&0xff];
-		c >>= (16-nb);
-		if(c <= h->maxcode[nb]){
-			in->sreg >>= nb;
-			in->nbits -= nb;
-			return h->decode[h->last[nb] - c];
-		}
-	}
-	in->error = FlateCorrupted;
-	return -1;
-}
-
-static int
-sregfill(Input *in, int n)
-{
-	int c;
-
-	while(n > in->nbits) {
-		c = (*in->get)(in->getr);
-		if(c < 0){
-			in->error = FlateInputFail;
-			return 0;
-		}
-		in->sreg |= c<<in->nbits;
-		in->nbits += 8;
-	}
-	return 1;
-}
-
-static int
-sregunget(Input *in)
-{
-	if(in->nbits >= 8) {
-		in->error = FlateInternal;
-		return 0;
-	}
-
-	/* throw other bits on the floor */
-	in->nbits = 0;
-	in->sreg = 0;
-	return 1;
-}
--- a/os/boot/libflate/inflateblock.c
+++ /dev/null
@@ -1,53 +1,0 @@
-#include "lib9.h"
-#include <flate.h>
-
-typedef struct Block	Block;
-
-struct Block
-{
-	uchar	*pos;
-	uchar	*limit;
-};
-
-static int
-blgetc(void *vb)
-{
-	Block *b;
-
-	b = vb;
-	if(b->pos >= b->limit)
-		return -1;
-	return *b->pos++;
-}
-
-static int
-blwrite(void *vb, void *buf, int n)
-{
-	Block *b;
-
-	b = vb;
-
-	if(n > b->limit - b->pos)
-		n = b->limit - b->pos;
-	memmove(b->pos, buf, n);
-	b->pos += n;
-	return n;
-}
-
-int
-inflateblock(uchar *dst, int dsize, uchar *src, int ssize)
-{
-	Block bd, bs;
-	int ok;
-
-	bs.pos = src;
-	bs.limit = src + ssize;
-
-	bd.pos = dst;
-	bd.limit = dst + dsize;
-
-	ok = inflate(&bd, blwrite, &bs, blgetc);
-	if(ok != FlateOk)
-		return ok;
-	return bd.pos - dst;
-}
--- a/os/boot/libflate/inflatezlib.c
+++ /dev/null
@@ -1,65 +1,0 @@
-#include "lib9.h"
-#include <flate.h>
-#include "zlib.h"
-
-typedef struct ZWrite	ZWrite;
-
-struct ZWrite
-{
-	ulong	adler;
-	void	*wr;
-	int	(*w)(void*, void*, int);
-};
-
-static int
-zlwrite(void *vzw, void *buf, int n)
-{
-	ZWrite *zw;
-
-	zw = vzw;
-	zw->adler = adler32(zw->adler, buf, n);
-	n = (*zw->w)(zw->wr, buf, n);
-	if(n <= 0)
-		return n;
-	return n;
-}
-
-int
-inflatezlib(void *wr, int (*w)(void*, void*, int), void *getr, int (*get)(void*))
-{
-	ZWrite zw;
-	ulong v;
-	int c, i;
-
-	c = (*get)(getr);
-	if(c < 0)
-		return FlateInputFail;
-	i = (*get)(getr);
-	if(i < 0)
-		return FlateInputFail;
-
-	if(((c << 8) | i) % 31)
-		return FlateCorrupted;
-	if((c & ZlibMeth) != ZlibDeflate
-	|| (c & ZlibCInfo) > ZlibWin32k)
-		return FlateCorrupted;
-
-	zw.wr = wr;
-	zw.w = w;
-	zw.adler = 1;
-	i = inflate(&zw, zlwrite, getr, get);
-	if(i != FlateOk)
-		return i;
-
-	v = 0;
-	for(i = 0; i < 4; i++){
-		c = (*get)(getr);
-		if(c < 0)
-			return FlateInputFail;
-		v = (v << 8) | c;
-	}
-	if(zw.adler != v)
-		return FlateCorrupted;
-
-	return FlateOk;
-}
--- a/os/boot/libflate/inflatezlibblock.c
+++ /dev/null
@@ -1,67 +1,0 @@
-#include "lib9.h"
-#include <flate.h>
-#include "zlib.h"
-
-typedef struct Block	Block;
-
-struct Block
-{
-	uchar	*pos;
-	uchar	*limit;
-};
-
-static int
-blgetc(void *vb)
-{
-	Block *b;
-
-	b = vb;
-	if(b->pos >= b->limit)
-		return -1;
-	return *b->pos++;
-}
-
-static int
-blwrite(void *vb, void *buf, int n)
-{
-	Block *b;
-
-	b = vb;
-
-	if(n > b->limit - b->pos)
-		n = b->limit - b->pos;
-	memmove(b->pos, buf, n);
-	b->pos += n;
-	return n;
-}
-
-int
-inflatezlibblock(uchar *dst, int dsize, uchar *src, int ssize)
-{
-	Block bd, bs;
-	int ok;
-
-	if(ssize < 6)
-		return FlateInputFail;
-
-	if(((src[0] << 8) | src[1]) % 31)
-		return FlateCorrupted;
-	if((src[0] & ZlibMeth) != ZlibDeflate
-	|| (src[0] & ZlibCInfo) > ZlibWin32k)
-		return FlateCorrupted;
-
-	bs.pos = src + 2;
-	bs.limit = src + ssize - 6;
-
-	bd.pos = dst;
-	bd.limit = dst + dsize;
-
-	ok = inflate(&bd, blwrite, &bs, blgetc);
-	if(ok != FlateOk)
-		return ok;
-
-	if(adler32(1, dst, bs.pos - dst) != ((bs.pos[0] << 24) | (bs.pos[1] << 16) | (bs.pos[2] << 8) | bs.pos[3]))
-		return FlateCorrupted;
-
-	return bd.pos - dst;
-}
--- a/os/boot/libflate/mkfile
+++ /dev/null
@@ -1,21 +1,0 @@
-<../../../mkconfig
-
-LIB=libflate.a
-OFILES=\
-	deflate.$O\
-	deflatezlib.$O\
-	deflateblock.$O\
-	deflatezlibblock.$O\
-	inflate.$O\
-	inflatezlib.$O\
-	inflateblock.$O\
-	inflatezlibblock.$O\
-	flateerr.$O\
-	crc.$O\
-	adler.$O\
-
-HFILES=\
-	$ROOT/include/flate.h\
-	zlib.h\
-
-<$ROOT/mkfiles/mksyslib-$SHELLTYPE
--- a/os/boot/libflate/zlib.h
+++ /dev/null
@@ -1,11 +1,0 @@
-/*
- * zlib header fields
- */
-enum
-{
-	ZlibMeth	= 0x0f,			/* mask of compression methods */
-	ZlibDeflate	= 0x08,
-
-	ZlibCInfo	= 0xf0,			/* mask of compression aux. info */
-	ZlibWin32k	= 0x70,			/* 32k history window */
-};
--- a/os/boot/mpc/NOTICE
+++ /dev/null
@@ -1,3 +1,0 @@
-Inferno® Copyright © 1996-1999 Lucent Technologies Inc.  All rights reserved.
-PowerPC support Copyright © 1995-1997 C H Forsyth (forsyth@caldo.demon.co.uk).  All rights reserved.
-MPC8xx Inferno PowerPC port Copyright © 1998-2003 Vita Nuova Holdings Limited.  All rights reserved.
--- a/os/boot/mpc/alarm.c
+++ /dev/null
@@ -1,123 +1,0 @@
-#include	"u.h"
-#include	"lib.h"
-#include	"mem.h"
-#include	"dat.h"
-#include	"fns.h"
-#include	"io.h"
-#define	MAXALARM	10
-
-Alarm	alarmtab[MAXALARM];
-
-/*
- * Insert new into list after where
- */
-void
-insert(List **head, List *where, List *new)
-{
-	if(where == 0){
-		new->next = *head;
-		*head = new;
-	}else{
-		new->next = where->next;
-		where->next = new;
-	}
-		
-}
-
-/*
- * Delete old from list.  where->next is known to be old.
- */
-void
-delete(List **head, List *where, List *old)
-{
-	if(where == 0){
-		*head = old->next;
-		return;
-	}
-	where->next = old->next;
-}
-
-Alarm*
-newalarm(void)
-{
-	int i;
-	Alarm *a;
-
-	for(i=0,a=alarmtab; i < nelem(alarmtab); i++,a++)
-		if(a->busy==0 && a->f==0){
-			a->f = 0;
-			a->arg = 0;
-			a->busy = 1;
-			return a;
-		}
-	panic("newalarm");
-	return 0;	/* not reached */
-}
-
-Alarm*
-alarm(int ms, void (*f)(Alarm*), void *arg)
-{
-	Alarm *a, *w, *pw;
-	ulong s;
-
-	if(ms < 0)
-		ms = 0;
-	s = splhi();
-	a = newalarm();
-	a->dt = MS2TK(ms);
-	a->f = f;
-	a->arg = arg;
-	pw = 0;
-	for(w=m->alarm; w; pw=w, w=w->next){
-		if(w->dt <= a->dt){
-			a->dt -= w->dt;
-			continue;
-		}
-		w->dt -= a->dt;
-		break;
-	}
-	insert(&m->alarm, pw, a);
-	splx(s);
-	return a;
-}
-
-void
-cancel(Alarm *a)
-{
-	a->f = 0;
-}
-
-void
-alarminit(void)
-{
-}
-
-#define NA 10		/* alarms per clock tick */
-void
-checkalarms(void)
-{
-	int i, n, s;
-	Alarm *a;
-	void (*f)(Alarm*);
-	Alarm *alist[NA];
-
-	s = splhi();
-	a = m->alarm;
-	if(a){
-		for(n=0; a && a->dt<=0 && n<NA; n++){
-			alist[n] = a;
-			delete(&m->alarm, 0, a);
-			a = m->alarm;
-		}
-		if(a)
-			a->dt--;
-
-		for(i = 0; i < n; i++){
-			f = alist[i]->f;	/* avoid race with cancel */
-			if(f)
-				(*f)(alist[i]);
-			alist[i]->busy = 0;
-		}
-	}
-	splx(s);
-}
--- a/os/boot/mpc/all.h
+++ /dev/null
@@ -1,6 +1,0 @@
-#include	"u.h"
-#include	"lib.h"
-#include	"dat.h"
-#include	"fns.h"
-#include	"mem.h"
-#include	"io.h"
--- a/os/boot/mpc/archfads.c
+++ /dev/null
@@ -1,355 +1,0 @@
-#include	"u.h"
-#include	"lib.h"
-#include	"mem.h"
-#include	"dat.h"
-#include	"fns.h"
-#include	"io.h"
-#include	"archfads.h"
-
-/*
- * board-specific support for the 8xxFADS (including 860/21 development system)
- */
-
-enum {
-	USESDRAM = 0,	/* set to 1 if kernel is to use SDRAM as well as DRAM */
-
-	/* sccr */
-	RTSEL = IBIT(8),	/* =0, select main oscillator (OSCM); =1, select external crystal (EXTCLK) */
-	RTDIV = IBIT(7),	/* =0, divide by 4; =1, divide by 512 */
-	CRQEN = IBIT(9),	/* =1, switch to high frequency when CPM active */
-	PRQEN = IBIT(10),	/* =1, switch to high frequency when interrupt pending */
-
-	/* plprcr */
-	CSRC = IBIT(21),	/* =0, clock is DFNH; =1, clock is DFNL */
-};
-
-/*
- * called early in main.c, after machinit:
- * using board and architecture specific registers, initialise
- * 8xx registers that need it and complete initialisation of the Mach structure.
- */
-void
-archinit(void)
-{
-	IMM *io;
-	int mf, isfads, sysmhz, t;
-	ulong v;
-
-	v = getimmr() & 0xFFFF;
-	isfads = 0;		/* assume it's the 860/821 board */
-	sysmhz = 40;
-	switch(v>>8){
-	case 0x00:	t = 0x86000; break;
-	case 0x20:	t = 0x82300; isfads = 1; break;
-	case 0x21:	t = 0x823a0; isfads = 1; break;
-	default:	t = 0; break;
-	}
-	m->cputype = t;
-	m->bcsr = KADDR(BCSRMEM);
-	m->bcsr[1] |= DisableRS232a | DisableIR | DisableEther | DisablePCMCIA | DisableRS232b;
-	m->bcsr[1] &= ~(DisableDRAM|DisableFlash);
-	if(isfads){
-		sysmhz = 50;
-		m->bcsr[1] &= ~EnableSDRAM;
-		m->bcsr[4] &= ~(EnableVideoClock|EnableVideoPort);
-		m->bcsr[4] |= DisableVideoLamp;
-	}
-	io = m->iomem;
-	if(1 || io->sccr & IBIT(7)){	/* RTDIV=1 */
-		/* oscillator frequency can't be determined independently: check a switch */
-		if((m->bcsr[2]>>19)&(1<<2))
-			m->clockgen = 5*MHz;
-		else
-			m->clockgen = 4*MHz;
-	} else
-		m->clockgen = 32768;
-	mf = (sysmhz*MHz)/m->clockgen;
-	m->cpuhz = m->clockgen*mf;
-	io->plprcrk = KEEP_ALIVE_KEY;
-	io->plprcr &= ~IBIT(21);	/* general system clock is DFNH */
-	io->plprcr = (io->plprcr & ((1<<20)-1)) | ((mf-1)<<20);
-	io->mptpr = 0x0400;	/* memory prescaler = 16 for refresh */
-	io->plprcrk = ~KEEP_ALIVE_KEY;
-	if(isfads){
-		m->bcsr[1] |= EnableSDRAM;
-		sdraminit(SDRAMMEM);
-		if(!USESDRAM)
-			m->bcsr[1] &= ~EnableSDRAM;	/* tells kernel not to map it */
-	}
-}
-
-static void
-archidprint(void)
-{
-	int f, i;
-	ulong v;
-
-	/* 8xx and FADS specific */
-	print("IMMR: ");
-	v = getimmr() & 0xFFFF;
-	switch(v>>8){
-	case 0x00:	print("MPC860/821"); break;
-	case 0x20:	print("MPC823"); break;
-	case 0x21:	print("MPC823A"); break;
-	default:	print("Type #%lux", v>>8); break;
-	}
-	print(", mask #%lux\n", v&0xFF);
-	v = m->bcsr[3]>>16;
-	print("MPC8xxFADS rev %lud, DB: ", ((v>>4)&8)|((v>>1)&4)|(v&3));
-	f = (v>>8)&0x3F;
-	switch(f){
-	default:	print("ID#%x", f); break;
-	case 0x00:	print("MPC860/821"); break;
-	case 0x01:	print("MPC813"); break;
-	case 0x02:	print("MPC821"); break;
-	case 0x03:	print("MPC823"); break;
-	case 0x20:	print("MPC801"); break;
-	case 0x21:	print("MPC850"); break;
-	case 0x22:	print("MPC860"); break;
-	case 0x23:	print("MPC860SAR"); break;
-	case 0x24:	print("MPC860T"); break;
-	}
-	print("ADS, rev #%lux\n", (m->bcsr[2]>>16)&7);
-	for(i=0; i<=4; i++)
-		print("BCSR%d: %8.8lux\n", i, m->bcsr[i]);
-	v = m->bcsr[2];
-	f = (v>>28)&0xF;
-	switch(f){
-	default:	print("Unknown"); break;
-	case 4:	print("SM732A2000/SM73228 - 8M SIMM"); break;
-	case 5:	print("SM732A1000A/SM73218 - 4M SIMM"); break;
-	case 6:	print("MCM29080 - 8M SIMM"); break;
-	case 7:	print("MCM29040 - 4M SIMM"); break;
-	case 8:	print("MCM29020 - 2M SIMM"); break;
-	}
-	switch((m->bcsr[3]>>20)&7){
-	default:	i = 0; break;
-	case 1:	i = 150; break;
-	case 2:	i = 120; break;
-	case 3:	i = 90; break;
-	}
-	print(" flash, %dns\n", i);
-	f = (v>>23)&0xF;
-	switch(f&3){
-	case 0:	i = 4; break;
-	case 1:	i = 32; break;
-	case 2:	i = 16; break;
-	case 3:	i = 8; break;
-	}
-	print("%dM SIMM, ", i);
-	switch(f>>2){
-	default: 	i = 0; break;
-	case 2:	i = 70; break;
-	case 3:	i = 60; break;
-	}
-	print("%dns\n", i);
-	print("options: #%lux\n", (m->bcsr[2]>>19)&0xF);
-	print("plprcr=%8.8lux sccr=%8.8lux\n", m->iomem->plprcr, m->iomem->sccr);
-}
-
-void
-cpuidprint(void)
-{
-	int t;
-
-	print("PVR: ");
-	t = getpvr()>>16;
-	switch(t){
-	case 0x01:	print("MPC601"); break;
-	case 0x03:	print("MPC603"); break;
-	case 0x04:	print("MPC604"); break;
-	case 0x06:	print("MPC603e"); break;
-	case 0x07:	print("MPC603e-v7"); break;
-	case 0x50:	print("MPC8xx"); break;
-	default:	print("PowerPC version #%x", t); break;
-	}
-	print(", revision #%lux\n", getpvr()&0xffff);
-	archidprint();
-	print("%lud MHz system\n", m->cpuhz/MHz);
-	print("\n");
-}
-
-static	char*	defplan9ini[2] = {
-	/* 860/821 */
-	"ether0=type=SCC port=1 ea=00108bf12900\r\n"
-	"vgasize=640x480x8\r\n"
-	"kernelpercent=40\r\n"
-	"console=0 lcd\r\nbaud=9600\r\n",
-
-	/* 823 */
-	"ether0=type=SCC port=2 ea=00108bf12900\r\n"
-	"vgasize=640x480x8\r\n"
-	"kernelpercent=40\r\n"
-	"console=0 lcd\r\nbaud=9600\r\n",
-};
-
-char *
-archconfig(void)
-{
-	print("Using default configuration\n");
-	return defplan9ini[MPCMODEL(m->cputype) == 0x823];
-}
-
-/*
- * provide value for #r/switch (devrtc.c)
- */
-int
-archoptionsw(void)
-{
-	return (m->bcsr[2]>>19)&0xF;	/* value of switch DS1 */
-}
-
-/*
- * invoked by clock.c:/^clockintr
- */
-static void
-twinkle(void)
-{
-	if(m->ticks%MS2TK(1000) == 0)
-		m->bcsr[4] ^= DisableLamp;
-}
-
-void	(*archclocktick)(void) = twinkle;
-
-/*
- * for flash.c:/^flashreset
- * retrieve flash type, virtual base and length and return 0;
- * return -1 on error (no flash)
- */
-int
-archflashreset(char *type, void **addr, long *length)
-{
-	char *t;
-	int mbyte;
-
-	if((m->iomem->memc[0].base & 1) == 0)
-		return -1;		/* shouldn't happen */
-	switch((m->bcsr[2]>>28)&0xF){
-	default:	return -1;	/* unknown or not there */
-	case 4:	mbyte=8; t = "SM732x8"; break;
-	case 5:	mbyte=4; t = "SM732x8"; break;
-	case 6:	mbyte=8; t = "AMD29F0x0"; break;
-	case 7:	mbyte=4; t = "AMD29F0x0"; break;
-	case 8:	mbyte=2; t = "AMD29F0x0"; break;
-	}
-	strcpy(type, t);
-	*addr = KADDR(FLASHMEM);
-	*length = mbyte*1024*1024;
-	return 0;
-}
-
-/*
- * enable the clocks for the given SCC ether and reveal them to the caller.
- * do anything else required to prepare the transceiver (eg, set full-duplex, reset loopback).
- */
-int
-archetherenable(int cpmid, int *rcs, int *tcs)
-{
-	IMM *io;
-
-	switch(cpmid){
-	default:
-		/* no other SCCs are wired on the FADS board */
-		return -1;
-
-	case SCC2ID:	/* assume 8xxFADS board with 823DABS */
-		io = ioplock();
-		m->bcsr[1] |= DisableIR|DisableRS232b;
-		m->bcsr[1] &= ~DisableEther;
-		io->papar |= SIBIT(6)|SIBIT(5);	/* enable CLK2 and CLK3 */
-		io->padir &= ~(SIBIT(6)|SIBIT(5));
-
-		/* ETHLOOP etc set in BCSR elsewhere */
-		*rcs = CLK2;
-		*tcs = CLK3;
-		iopunlock();
-		break;
-
-	case SCC1ID:	/* assume 860/21 development board */
-		io = ioplock();
-		m->bcsr[1] |= DisableIR|DisableRS232b;	/* TO DO: might not be shared with RS232b */
-		m->bcsr[1] &= ~DisableEther;
-		io->papar |= SIBIT(6)|SIBIT(7);	/* enable CLK2 and CLK1 */
-		io->padir &= ~(SIBIT(6)|SIBIT(7));
-
-		/* settings peculiar to 860/821 development board */
-		io->pcpar &= ~(SIBIT(4)|SIBIT(5)|SIBIT(6));	/* ETHLOOP, TPFULDL~, TPSQEL~ */
-		io->pcdir |= SIBIT(4)|SIBIT(5)|SIBIT(6);
-		io->pcdat &= ~SIBIT(4);
-		io->pcdat |= SIBIT(5)|SIBIT(6);
-		*rcs = CLK2;
-		*tcs = CLK1;
-		iopunlock();
-		break;
-	}
-	return 0;
-}
-
-void
-archetherdisable(int id)
-{
-	USED(id);
-	m->bcsr[1] |= DisableEther|DisableIR|DisableRS232b;
-}
-
-/*
- * do anything extra required to enable the UART on the given CPM port
- */
-void
-archenableuart(int id, int irda)
-{
-	switch(id){
-	case SMC1ID:
-		m->bcsr[1] &= ~DisableRS232a;
-		break;
-	case SCC2ID:
-		m->bcsr[1] |= DisableEther|DisableIR|DisableRS232b;
-		if(irda)
-			m->bcsr[1] &= ~DisableIR;
-		else
-			m->bcsr[1] &= ~DisableRS232b;
-		break;
-	default:
-		/* nothing special */
-		break;
-	}
-}
-
-/*
- * do anything extra required to disable the UART on the given CPM port
- */
-void
-archdisableuart(int id)
-{
-	switch(id){
-	case SMC1ID:
-		m->bcsr[1] |= DisableRS232a;
-		break;
-	case SCC2ID:
-		m->bcsr[1] |= DisableIR|DisableRS232b;
-		break;
-	default:
-		/* nothing special */
-		break;
-	}
-}
-
-/*
- * enable/disable the LCD panel's backlight via
- * York touch panel interface (does no harm without it)
- */
-void
-archbacklight(int on)
-{
-	IMM *io;
-
-	delay(2);
-	io = ioplock();
-	io->papar &= ~SIBIT(4);
-	io->padir |= SIBIT(4);
-	if(on)
-		io->padat |= SIBIT(4);
-	else
-		io->padat &= ~SIBIT(4);
-	iopunlock();
-}
--- a/os/boot/mpc/archfads.h
+++ /dev/null
@@ -1,42 +1,0 @@
-
-enum {
-	/* BCSR1 bits */
-	DisableFlash=	IBIT(0),
-	DisableDRAM=	IBIT(1),
-	DisableEther=	IBIT(2),
-	DisableIR=	IBIT(3),
-	DisableRS232a=	IBIT(7),
-	DisablePCMCIA=	IBIT(8),
-	PCCVCCMask=	IBIT(9)|IBIT(15),
-	PCCVPPMask=	IBIT(10)|IBIT(11),
-	DisableRS232b=	IBIT(13),
-	EnableSDRAM=	IBIT(14),
-
-	PCCVCC0V=	IBIT(15)|IBIT(9),
-	PCCVCC5V=	IBIT(9),	/* active low */
-	PCCVCC3V=	IBIT(15),	/* active low */
-	PCCVPP0V=	IBIT(10)|IBIT(11),	/* active low */
-	PCCVPP5V=	IBIT(10),	/* active low */
-	PCCVPP12V=	IBIT(11),	/* active low */
-	PCCVPPHiZ=	IBIT(10)|IBIT(11),
-
-	/* BCSR4 bits */
-	DisableTPDuplex=	IBIT(1),
-	DisableLamp=	IBIT(3),
-	DisableUSB=	IBIT(4),
-	USBFullSpeed=	IBIT(5),
-	DisableUSBVcc=	IBIT(6),
-	DisableVideoLamp=	IBIT(8),
-	EnableVideoClock=	IBIT(9),
-	EnableVideoPort=	IBIT(10),
-	DisableModem=	IBIT(11),
-};
-
-enum {
-	/* memory controller CS assignment on FADS boards */
-	BOOTCS = 0,
-	BCSRCS = 1,
-	DRAM1 = 2,
-	DRAM2 = 3,
-	SDRAM = 4,
-};
--- a/os/boot/mpc/archpaq.c
+++ /dev/null
@@ -1,240 +1,0 @@
-#include	"u.h"
-#include	"lib.h"
-#include	"mem.h"
-#include	"dat.h"
-#include	"fns.h"
-#include	"io.h"
-
-#include	"archpaq.h"
-
-/*
- * board-specific support for the 82x PowerPAQ
- */
-
-enum {
-	SYSMHZ = 50,	/* desired system clock in MHz */
-
-	/* sccr */
-	RTSEL = IBIT(8),	/* =0, select main oscillator (OSCM); =1, select external crystal (EXTCLK) */
-	RTDIV = IBIT(7),	/* =0, divide by 4; =1, divide by 512 */
-	CRQEN = IBIT(9),	/* =1, switch to high frequency when CPM active */
-	PRQEN = IBIT(10),	/* =1, switch to high frequency when interrupt pending */
-
-	/* plprcr */
-	CSRC = IBIT(21),	/* =0, clock is DFNH; =1, clock is DFNL */
-};
-
-/*
- * called early in main.c, after machinit:
- * using board and architecture specific registers, initialise
- * 8xx registers that need it and complete initialisation of the Mach structure.
- */
-void
-archinit(void)
-{
-	IMM *io;
-	int mf, t;
-
-	switch((getimmr()>>8)&0xFF){
-	case 0x00:	t = 0x86000; break;	/* also 821 */
-	case 0x20:	t = 0x82300; break;
-	case 0x21:	t = 0x823a0; break;
-	default:	t = 0; break;
-	}
-	m->cputype = t;
-	m->bcsr = nil;	/* there isn't one */
-	m->clockgen = 32*1024;	/* crystal frequency */
-	io = m->iomem;
-	io->sccrk = KEEP_ALIVE_KEY;
-	io->sccr &= ~RTDIV;	/* divide 32k by 4 */
-	io->sccr |= RTSEL;
-	io->sccrk = ~KEEP_ALIVE_KEY;
-	mf = (SYSMHZ*MHz)/m->clockgen;
-	m->cpuhz = m->clockgen*mf;
-	io->plprcrk = KEEP_ALIVE_KEY;
-	io->plprcr &= ~IBIT(21);	/* general system clock is DFNH */
-	io->plprcr = (io->plprcr & ((1<<20)-1)) | ((mf-1)<<20);
-	io->mptpr = 0x0400;	/* memory prescaler = 16 for refresh */
-	io->plprcrk = ~KEEP_ALIVE_KEY;
-}
-
-void
-cpuidprint(void)
-{
-	int t, v;
-
-	print("PVR: ");
-	t = getpvr()>>16;
-	switch(t){
-	case 0x01:	print("MPC601"); break;
-	case 0x03:	print("MPC603"); break;
-	case 0x04:	print("MPC604"); break;
-	case 0x06:	print("MPC603e"); break;
-	case 0x07:	print("MPC603e-v7"); break;
-	case 0x50:	print("MPC8xx"); break;
-	default:	print("PowerPC version #%x", t); break;
-	}
-	print(", revision #%lux\n", getpvr()&0xffff);
-	print("IMMR: ");
-	v = getimmr() & 0xFFFF;
-	switch(v>>8){
-	case 0x00:	print("MPC860/821"); break;
-	case 0x20:	print("MPC823"); break;
-	case 0x21:	print("MPC823A"); break;
-	default:	print("Type #%lux", v>>8); break;
-	}
-	print(", mask #%lux\n", v&0xFF);
-	print("plprcr=%8.8lux sccr=%8.8lux\n", m->iomem->plprcr, m->iomem->sccr);
-	print("%lud MHz system\n", m->cpuhz/MHz);
-	print("\n");
-}
-
-static	char*	defplan9ini[2] = {
-	/* 860/821 */
-	"ether0=type=SCC port=1 ea=00108bf12900\r\n"
-	"vgasize=640x480x8\r\n"
-	"kernelpercent=40\r\n"
-	"console=0 lcd\r\nbaud=19200\r\n",
-
-	/* 823 */
-	"ether0=type=SCC port=2 ea=00108bf12900\r\n"
-	"vgasize=640x480x8\r\n"
-	"kernelpercent=40\r\n"
-	"console=0 lcd\r\nbaud=19200\r\n",
-};
-
-char *
-archconfig(void)
-{
-	print("Using default configuration\n");
-	return defplan9ini[MPCMODEL(m->cputype) == 0x823];
-}
-
-/*
- * provide value for #r/switch (devrtc.c)
- */
-int
-archoptionsw(void)
-{
-	return 0;
-}
-
-/*
- * invoked by clock.c:/^clockintr
- */
-static void
-twinkle(void)
-{
-	/* no easy-to-use LED on PAQ (they use i2c) */
-}
-
-void	(*archclocktick)(void) = twinkle;
-
-/*
- * for flash.c:/^flashinit
- * retrieve flash type, virtual base and length and return 0;
- * return -1 on error (no flash)
- */
-int
-archflashreset(char *type, void **addr, long *length)
-{
-	strcpy(type, "AMD29F0x0");
-	*addr = KADDR(FLASHMEM);
-	*length = 8*1024*1024;	/* 8mbytes on some models */
-	return 0;
-}
-
-/*
- * enable the clocks for the given SCC ether and reveal them to the caller.
- * do anything else required to prepare the transceiver (eg, set full-duplex, reset loopback).
- */
-int
-archetherenable(int cpmid, int *rcs, int *tcs)
-{
-	USED(cpmid, rcs, tcs);
-	return -1;	/* there isn't an ether on the PAQs */
-}
-
-void
-archetherdisable(int id)
-{
-	USED(id);
-}
-
-/*
- * do anything extra required to enable the UART on the given CPM port
- */
-void
-archenableuart(int id, int irda)
-{
-	IMM *io;
-
-	USED(irda);
-	switch(id){
-	case SMC1ID:
-		io = ioplock();
-		io->pbodr &= ~0xc0;
-		io->pbdat |= 0xc0;
-		io->pcdat |= 0x400;
-		io->pcpar &= ~0x400;
-		io->pcdir |= 0x400;
-		io->pcdat &= ~0x400;	/* enable SMC RS232 buffer */
-		iopunlock();
-		break;
-	case SCC2ID:
-		/* TO DO */
-		break;
-	default:
-		/* nothing special */
-		break;
-	}
-}
-
-/*
- * do anything extra required to disable the UART on the given CPM port
- */
-void
-archdisableuart(int id)
-{
-	switch(id){
-	case SMC1ID:
-		/* TO DO */
-		break;
-	case SCC2ID:
-		/* TO DO */
-		break;
-	default:
-		/* nothing special */
-		break;
-	}
-}
-
-/*
- * enable/disable the LCD panel's backlight via i2c
- */
-void
-archbacklight(int on)
-{
-	uchar msg;
-	IMM *io;
-
-	i2csetup();
-	msg = ~7;
-	i2csend(LEDRegI2C, &msg, 1);
-	io = ioplock();
-	io->pbpar &= ~EnableLCD;
-	io->pbodr &= ~EnableLCD;
-	io->pbdir |= EnableLCD;
-	if(on)
-		io->pbdat |= EnableLCD;
-	else
-		io->pbdat &= ~EnableLCD;
-	iopunlock();
-	if(on){
-		msg = ~(DisablePanelVCC5|DisableTFT);
-		i2csend(PanelI2C, &msg, 1);
-	}else{
-		msg = ~0;
-		i2csend(PanelI2C, &msg, 1);
-	}
-}
--- a/os/boot/mpc/archpaq.h
+++ /dev/null
@@ -1,29 +1,0 @@
-enum {
-	/* memory controller CS assignment on PowerPAQ */
-	BOOTCS = 0,
-	DRAM1 = 1,	/* UPMB */
-	DRAM2 = 2,	/* UPMB */
-	/* CS3 also connected to DRAM */
-	/* CS4 128mbyte 8-bit gpcm, trlx, 15 wait; it's DAC */
-	/* CS5 is external*/
-};
-
-enum {
-	/* I2C addresses */
-	PanelI2C = 0x21<<1,
-	  /* the control bits are active low enables, or high disables */
-	  DisableVGA = ~0xFD,	/* disable VGA signals */
-	  DisableTFT = ~0xFB,	/* disable TFT panel signals */
-	  DisableSPIBus = ~0xF7,	/* disable SPI/I2C to panel */
-	  DisablePanelVCC5 = ~0xEF,	/* disable +5V to panel(s) */
-	  DisablePanelVCC3 = ~0xDF,	/* disable +3.3V to panel(s) */
-	  DisableMonoPanel = ~0xBF,	/* disable mono panel signals */
-	  DisableSPISelect = ~0x7F,	/* disable SPI chip select to LVDS panel */
-	ContrastI2C = 0x2E<<1,
-	LEDRegI2C = 0x20<<1,
-	  DisableGreenLED = ~0xFE,
-	  DisableYellowLED = ~0xFD,
-	  DisableRedLED = ~0xFB,
-
-	EnableLCD = IBIT(23),	/* LCD enable bit in i/o port B */
-};
--- a/os/boot/mpc/boot.h
+++ /dev/null
@@ -1,8 +1,0 @@
-#include <u.h>
-#include "lib.h"
-
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "ureg.h"
--- a/os/boot/mpc/bootp.c
+++ /dev/null
@@ -1,507 +1,0 @@
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-
-#include "ip.h"
-
-enum {
-	CHECKSUM = 1,	/* set zero if trouble booting from Linux */
-};
-
-uchar broadcast[Eaddrlen] = {
-	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-};
-
-static ushort tftpport = 5000;
-static int Id = 1;
-static Netaddr myaddr;
-static Netaddr server;
-
-typedef struct {
-	uchar	header[4];
-	uchar	data[Segsize];
-} Tftp;
-static Tftp tftpb;
-
-static void
-hnputs(uchar *ptr, ushort val)
-{
-	ptr[0] = val>>8;
-	ptr[1] = val;
-}
-
-static void
-hnputl(uchar *ptr, ulong val)
-{
-	ptr[0] = val>>24;
-	ptr[1] = val>>16;
-	ptr[2] = val>>8;
-	ptr[3] = val;
-}
-
-static ulong
-nhgetl(uchar *ptr)
-{
-	return ((ptr[0]<<24) | (ptr[1]<<16) | (ptr[2]<<8) | ptr[3]);
-}
-
-static ushort
-nhgets(uchar *ptr)
-{
-	return ((ptr[0]<<8) | ptr[1]);
-}
-
-static	short	endian	= 1;
-static	char*	aendian	= (char*)&endian;
-#define	LITTLE	*aendian
-
-static ushort
-ptcl_csum(void *a, int len)
-{
-	uchar *addr;
-	ulong t1, t2;
-	ulong losum, hisum, mdsum, x;
-
-	addr = a;
-	losum = 0;
-	hisum = 0;
-	mdsum = 0;
-
-	x = 0;
-	if((ulong)addr & 1) {
-		if(len) {
-			hisum += addr[0];
-			len--;
-			addr++;
-		}
-		x = 1;
-	}
-	while(len >= 16) {
-		t1 = *(ushort*)(addr+0);
-		t2 = *(ushort*)(addr+2);	mdsum += t1;
-		t1 = *(ushort*)(addr+4);	mdsum += t2;
-		t2 = *(ushort*)(addr+6);	mdsum += t1;
-		t1 = *(ushort*)(addr+8);	mdsum += t2;
-		t2 = *(ushort*)(addr+10);	mdsum += t1;
-		t1 = *(ushort*)(addr+12);	mdsum += t2;
-		t2 = *(ushort*)(addr+14);	mdsum += t1;
-		mdsum += t2;
-		len -= 16;
-		addr += 16;
-	}
-	while(len >= 2) {
-		mdsum += *(ushort*)addr;
-		len -= 2;
-		addr += 2;
-	}
-	if(x) {
-		if(len)
-			losum += addr[0];
-		if(LITTLE)
-			losum += mdsum;
-		else
-			hisum += mdsum;
-	} else {
-		if(len)
-			hisum += addr[0];
-		if(LITTLE)
-			hisum += mdsum;
-		else
-			losum += mdsum;
-	}
-
-	losum += hisum >> 8;
-	losum += (hisum & 0xff) << 8;
-	while(hisum = losum>>16)
-		losum = hisum + (losum & 0xffff);
-
-	return ~losum;
-}
-
-static ushort
-ip_csum(uchar *addr)
-{
-	int len;
-	ulong sum = 0;
-
-	len = (addr[0]&0xf)<<2;
-
-	while(len > 0) {
-		sum += addr[0]<<8 | addr[1] ;
-		len -= 2;
-		addr += 2;
-	}
-
-	sum = (sum & 0xffff) + (sum >> 16);
-	sum = (sum & 0xffff) + (sum >> 16);
-	return (sum^0xffff);
-}
-
-static void
-udpsend(int ctlrno, Netaddr *a, void *data, int dlen)
-{
-	Udphdr *uh;
-	Etherhdr *ip;
-	static Etherpkt pkt;
-	int len, ptcllen;
-
-
-	uh = (Udphdr*)&pkt;
-
-	memset(uh, 0, sizeof(Etherpkt));
-	memmove(uh->udpcksum+sizeof(uh->udpcksum), data, dlen);
-
-	/*
-	 * UDP portion
-	 */
-	ptcllen = dlen + (UDP_HDRSIZE-UDP_PHDRSIZE);
-	uh->ttl = 0;
-	uh->udpproto = IP_UDPPROTO;
-	uh->frag[0] = 0;
-	uh->frag[1] = 0;
-	hnputs(uh->udpplen, ptcllen);
-	hnputl(uh->udpsrc, myaddr.ip);
-	hnputs(uh->udpsport, myaddr.port);
-	hnputl(uh->udpdst, a->ip);
-	hnputs(uh->udpdport, a->port);
-	hnputs(uh->udplen, ptcllen);
-	uh->udpcksum[0] = 0;
-	uh->udpcksum[1] = 0;
-	/*dlen = (dlen+1)&~1; */
-	hnputs(uh->udpcksum, ptcl_csum(&uh->ttl, dlen+UDP_HDRSIZE));
-
-	/*
-	 * IP portion
-	 */
-	ip = (Etherhdr*)&pkt;
-	len = sizeof(Udphdr)+dlen;
-	ip->vihl = IP_VER|IP_HLEN;
-	ip->tos = 0;
-	ip->ttl = 255;
-	hnputs(ip->length, len-ETHER_HDR);
-	hnputs(ip->id, Id++);
-	ip->frag[0] = 0;
-	ip->frag[1] = 0;
-	ip->cksum[0] = 0;
-	ip->cksum[1] = 0;
-	hnputs(ip->cksum, ip_csum(&ip->vihl));
-
-	/*
-	 * Ethernet MAC portion
-	 */
-	hnputs(ip->type, ET_IP);
-	memmove(ip->d, a->ea, sizeof(ip->d));
-
-	ethertxpkt(ctlrno, &pkt, len, Timeout);
-}
-
-static void
-nak(int ctlrno, Netaddr *a, int code, char *msg, int report)
-{
-	int n;
-	char buf[128];
-
-	buf[0] = 0;
-	buf[1] = Tftp_ERROR;
-	buf[2] = 0;
-	buf[3] = code;
-	strcpy(buf+4, msg);
-	n = strlen(msg) + 4 + 1;
-	udpsend(ctlrno, a, buf, n);
-	if(report)
-		print("\ntftp: error(%d): %s\n", code, msg);
-}
-
-static int
-udprecv(int ctlrno, Netaddr *a, void *data, int dlen)
-{
-	int n, len;
-	ushort csm;
-	Udphdr *h;
-	ulong addr, timo;
-	static Etherpkt pkt;
-	static int rxactive;
-
-	if(rxactive == 0)
-		timo = 1000;
-	else
-		timo = Timeout;
-	timo += TK2MS(m->ticks);
-	while(timo > TK2MS(m->ticks)){
-		n = etherrxpkt(ctlrno, &pkt, timo-TK2MS(m->ticks));
-		if(n <= 0)
-			continue;
-
-		h = (Udphdr*)&pkt;
-		if(nhgets(h->type) != ET_IP)
-			continue;
-
-		if(ip_csum(&h->vihl)) {
-			print("ip chksum error\n");
-			continue;
-		}
-		if(h->vihl != (IP_VER|IP_HLEN)) {
-			print("ip bad vers/hlen\n");
-			continue;
-		}
-
-		if(h->udpproto != IP_UDPPROTO)
-			continue;
-
-		h->ttl = 0;
-		len = nhgets(h->udplen);
-		hnputs(h->udpplen, len);
-
-		if(CHECKSUM && nhgets(h->udpcksum)) {
-			csm = ptcl_csum(&h->ttl, len+UDP_PHDRSIZE);
-			if(csm != 0) {
-				print("udp chksum error csum #%4lux len %d\n", csm, n);
-				break;
-			}
-		}
-
-		if(a->port != 0 && nhgets(h->udpsport) != a->port)
-			continue;
-
-		addr = nhgetl(h->udpsrc);
-		if(a->ip != Bcastip && addr != a->ip)
-			continue;
-
-		len -= UDP_HDRSIZE-UDP_PHDRSIZE;
-		if(len > dlen) {
-			print("udp: packet too big\n");
-			continue;
-		}
-
-		memmove(data, h->udpcksum+sizeof(h->udpcksum), len);
-		a->ip = addr;
-		a->port = nhgets(h->udpsport);
-		memmove(a->ea, pkt.s, sizeof(a->ea));
-
-		rxactive = 1;
-		return len;
-	}
-
-	return 0;
-}
-
-static int tftpblockno;
-
-static int
-tftpopen(int ctlrno, Netaddr *a, char *name, Tftp *tftp)
-{
-	int i, len, rlen, oport;
-	char buf[Segsize+2];
-
-	buf[0] = 0;
-	buf[1] = Tftp_READ;
-	len = sprint(buf+2, "%s", name) + 2;
-	len += sprint(buf+len+1, "octet") + 2;
-
-	oport = a->port;
-	for(i = 0; i < 5; i++){
-		a->port = oport;
-		udpsend(ctlrno, a, buf, len);
-		a->port = 0;
-		if((rlen = udprecv(ctlrno, a, tftp, sizeof(Tftp))) < sizeof(tftp->header))
-			continue;
-
-		switch((tftp->header[0]<<8)|tftp->header[1]){
-
-		case Tftp_ERROR:
-			print("tftpopen: error (%d): %s\n",
-				(tftp->header[2]<<8)|tftp->header[3], tftp->data);
-			return -1;
-
-		case Tftp_DATA:
-			tftpblockno = 1;
-			len = (tftp->header[2]<<8)|tftp->header[3];
-			if(len != tftpblockno){
-				print("tftpopen: block error: %d\n", len);
-				nak(ctlrno, a, 1, "block error", 0);
-				return -1;
-			}
-			return rlen-sizeof(tftp->header);
-		}
-	}
-
-	print("tftpopen: failed to connect to server\n");
-	return -1;
-}
-
-static int
-tftpread(int ctlrno, Netaddr *a, Tftp *tftp, int dlen)
-{
-	int blockno, len, retry;
-	uchar buf[4];
-
-	buf[0] = 0;
-	buf[1] = Tftp_ACK;
-	buf[2] = tftpblockno>>8;
-	buf[3] = tftpblockno;
-	tftpblockno++;
-
-	dlen += sizeof(tftp->header);
-
-	retry = 0;
-buggery:
-	udpsend(ctlrno, a, buf, sizeof(buf));
-
-	if((len = udprecv(ctlrno, a, tftp, dlen)) < dlen){
-		print("tftpread: %d != %d\n", len, dlen);
-		nak(ctlrno, a, 2, "short read", 0);
-		if(retry++ < 5)
-			goto buggery;
-		return -1;
-	}
-
-	blockno = (tftp->header[2]<<8)|tftp->header[3];
-	if(blockno != tftpblockno){
-		print("?");
-
-		if(blockno == tftpblockno-1 && retry++ < 8)
-			goto buggery;
-		print("tftpread: block error: %d, expected %d\n", blockno, tftpblockno);
-		nak(ctlrno, a, 1, "block error", 0);
-
-		return -1;
-	}
-
-	return len-sizeof(tftp->header);
-}
-
-int
-bootp(int ctlrno, char *file)
-{
-	Bootp req, rep;
-	int i, dlen, segsize, text, data, bss, total;
-	uchar *ea, *addr, *p;
-	ulong entry;
-	Exec *exec;
-	char name[128], *filename, *sysname;
-
-	if((ea = etheraddr(ctlrno)) == 0){
-		print("invalid ctlrno %d\n", ctlrno);
-		return -1;
-	}
-
-	filename = 0;
-	sysname = 0;
-	if(file && *file){
-		strcpy(name, file);
-		if(filename = strchr(name, ':')){
-			if(filename != name && *(filename-1) != '\\'){
-				sysname = name;
-				*filename++ = 0;
-			}
-		}
-		else
-			filename = name;
-	}
-		
-
-	memset(&req, 0, sizeof(req));
-	req.op = Bootrequest;
-	req.htype = 1;			/* ethernet */
-	req.hlen = Eaddrlen;		/* ethernet */
-	memmove(req.chaddr, ea, Eaddrlen);
-
-	myaddr.ip = 0;
-	myaddr.port = BPportsrc;
-	memmove(myaddr.ea, ea, Eaddrlen);
-
-	for(i = 0; i < 10; i++) {
-		server.ip = Bcastip;
-		server.port = BPportdst;
-		memmove(server.ea, broadcast, sizeof(server.ea));
-		udpsend(ctlrno, &server, &req, sizeof(req));
-		if(udprecv(ctlrno, &server, &rep, sizeof(rep)) <= 0)
-			continue;
-		if(memcmp(req.chaddr, rep.chaddr, Eaddrlen))
-			continue;
-		if(rep.htype != 1 || rep.hlen != Eaddrlen)
-			continue;
-		if(sysname == 0 || strcmp(sysname, rep.sname) == 0)
-			break;
-	}
-	if(i >= 10) {
-		print("bootp timed out\n");
-		return -1;
-	}
-
-	if(filename == 0 || *filename == 0)
-		filename = rep.file;
-
-	if(rep.sname[0] != '\0')
-		 print("%s ", rep.sname);
-	print("(%d.%d.%d.%d!%d): %s\n",
-		rep.siaddr[0],
-		rep.siaddr[1],
-		rep.siaddr[2],
-		rep.siaddr[3],
-		server.port,
-		filename);uartwait();
-
-	myaddr.ip = nhgetl(rep.yiaddr);
-	myaddr.port = tftpport++;
-	server.ip = nhgetl(rep.siaddr);
-	server.port = TFTPport;
-
-	if((dlen = tftpopen(ctlrno, &server, filename, &tftpb)) < 0)
-		return -1;
-	exec = (Exec*)(tftpb.data);
-	if(dlen < sizeof(Exec) || GLLONG(exec->magic) != Q_MAGIC){
-		nak(ctlrno, &server, 0, "bad magic number", 1);
-		return -1;
-	}
-	text = GLLONG(exec->text);
-	data = GLLONG(exec->data);
-	bss = GLLONG(exec->bss);
-	total = text+data+bss;
-	entry = GLLONG(exec->entry);
-print("load@%8.8lux: ", PADDR(entry));uartwait();
-	print("%d", text);
-
-	addr = (uchar*)PADDR(entry);
-	p = tftpb.data+sizeof(Exec);
-	dlen -= sizeof(Exec);
-	segsize = text;
-	for(;;){
-		if(dlen == 0){
-			if((dlen = tftpread(ctlrno, &server, &tftpb, sizeof(tftpb.data))) < 0)
-				return -1;
-			p = tftpb.data;
-		}
-		if(segsize <= dlen)
-			i = segsize;
-		else
-			i = dlen;
-		memmove(addr, p, i);
-
-		addr += i;
-		p += i;
-		segsize -= i;
-		dlen -= i;
-
-		if(segsize <= 0){
-			if(data == 0)
-				break;
-			print("+%d", data);
-			segsize = data;
-			data = 0;
-			addr = (uchar*)PGROUND((ulong)addr);
-		}
-	}
-	nak(ctlrno, &server, 3, "ok", 0);		/* tftpclose */
-	print("+%d=%d\n", bss, total);
-	print("entry: 0x%lux\n", entry);
-	uartwait();
-	scc2stop();
-	splhi();
-	(*(void(*)(void))(PADDR(entry)))();
-	
-	return 0;
-}
--- a/os/boot/mpc/clock.c
+++ /dev/null
@@ -1,71 +1,0 @@
-#include	"u.h"
-#include	"lib.h"
-#include	"mem.h"
-#include	"dat.h"
-#include	"fns.h"
-#include	"io.h"
-#include	"ureg.h"
-
-enum {
-	Timebase = 4,	/* system clock cycles per time base cycle */
-};
-
-void	(*archclocktick)(void);	/* set by arch*.c when desired */
-
-static	ulong	clkreload;
-
-void
-delay(int l)
-{
-	ulong i, j;
-
-	j = m->delayloop;
-	while(l-- > 0)
-		for(i=0; i < j; i++)
-			;
-}
-
-void
-microdelay(int l)
-{
-	ulong i;
-
-	l *= m->delayloop;
-	l /= 1000;
-	if(l <= 0)
-		l = 1;
-	for(i = 0; i < l; i++)
-		;
-}
-
-void
-clockintr(Ureg*, void*)
-{
-	putdec(clkreload);
-	m->ticks++;
-	checkalarms();
-	if(archclocktick != nil)
-		archclocktick();
-}
-
-void
-clockinit(void)
-{
-	long x;
-
-	m->delayloop = m->cpuhz/1000;	/* initial estimate */
-	do {
-		x = gettbl();
-		delay(10);
-		x = gettbl() - x;
-	} while(x < 0);
-
-	/*
-	 *  fix count
-	 */
-	m->delayloop = ((vlong)m->delayloop*(10*m->clockgen/1000))/(x*Timebase);
-	if(m->delayloop == 0)
-		m->delayloop = 1;
-	clkreload = (m->clockgen/Timebase)/HZ-1;
-	putdec(clkreload);
-}
--- a/os/boot/mpc/conf.c
+++ /dev/null
@@ -1,173 +1,0 @@
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-
-#include "dosfs.h"
-
-static char *confname[MAXCONF];
-static char *confval[MAXCONF];
-static int nconf;
-
-extern char **ini;
-
-char*
-getconf(char *name)
-{
-	int i;
-
-	for(i = 0; i < nconf; i++)
-		if(strcmp(confname[i], name) == 0)
-			return confval[i];
-	return 0;
-}
-
-/*
- *  read configuration file
- */
-int
-plan9ini(Dos *dos, char *val)
-{
-	Dosfile rc;
-	int i, n;
-	char *cp, *p, *q, *line[MAXCONF];
-
-	cp = BOOTARGS;
-	if(dos) {
-		if(dosstat(dos, *ini, &rc) <= 0)
-			return -1;
-
-		*cp = 0;
-		n = dosread(&rc, cp, BOOTARGSLEN-1);
-		if(n <= 0)
-			return -1;
-		cp[n] = 0;
-	} else if(val != nil){
-		if(memchr(val, 0, BOOTARGSLEN-1) == nil)
-			return -1;
-		print("Using flash configuration\n");
-		strcpy(cp, val);
-		n = strlen(cp);
-	}else{
-		strcpy(cp, archconfig());
-		n = strlen(cp);
-	}
-
-	/*
-	 * Make a working copy.
-	 * We could change this to pass the parsed strings
-	 * to the booted programme instead of the raw
-	 * string, then it only gets done once.
-	 */
-	memmove(cp+BOOTARGSLEN, cp, n+1);
-	cp += BOOTARGSLEN;
-
-	/*
-	 * Strip out '\r', change '\t' -> ' '.
-	 */
-	p = cp;
-	for(q = cp; *q; q++){
-		if(*q == '\r')
-			continue;
-		if(*q == '\t')
-			*q = ' ';
-		*p++ = *q;
-	}
-	*p = 0;
-	n = getcfields(cp, line, MAXCONF, "\n");
-	for(i = 0; i < n; i++){
-		cp = strchr(line[i], '=');
-		if(cp == 0)
-			continue;
-		*cp++ = 0;
-		if(cp - line[i] >= NAMELEN+1)
-			*(line[i]+NAMELEN-1) = 0;
-		confname[nconf] = line[i];
-		confval[nconf] = cp;
-		nconf++;
-	}
-	return 0;
-}
-
-int
-parseether(uchar *to, char *from)
-{
-	char nip[4];
-	char *p;
-	int i;
-
-	p = from;
-	while(*p == ' ')
-		++p;
-	for(i = 0; i < 6; i++){
-		if(*p == 0)
-			return -1;
-		nip[0] = *p++;
-		if(*p == 0)
-			return -1;
-		nip[1] = *p++;
-		nip[2] = 0;
-		to[i] = strtoul(nip, 0, 16);
-		if(*p == ':')
-			p++;
-	}
-	return 0;
-}
-
-int
-isaconfig(char *class, int ctlrno, ISAConf *isa)
-{
-	char cc[NAMELEN], *p, *q, *r;
-	int n;
-
-	sprint(cc, "%s%d", class, ctlrno);
-	for(n = 0; n < nconf; n++){
-		if(strncmp(confname[n], cc, NAMELEN))
-			continue;
-		isa->nopt = 0;
-		p = confval[n];
-		while(*p){
-			while(*p == ' ' || *p == '\t')
-				p++;
-			if(*p == '\0')
-				break;
-			if(strncmp(p, "type=", 5) == 0){
-				p += 5;
-				for(q = isa->type; q < &isa->type[NAMELEN-1]; q++){
-					if(*p == '\0' || *p == ' ' || *p == '\t')
-						break;
-					*q = *p++;
-				}
-				*q = '\0';
-			}
-			else if(strncmp(p, "port=", 5) == 0)
-				isa->port = strtoul(p+5, &p, 0);
-			else if(strncmp(p, "irq=", 4) == 0)
-				isa->irq = strtoul(p+4, &p, 0);
-			else if(strncmp(p, "mem=", 4) == 0)
-				isa->mem = strtoul(p+4, &p, 0);
-			else if(strncmp(p, "size=", 5) == 0)
-				isa->size = strtoul(p+5, &p, 0);
-			else if(strncmp(p, "ea=", 3) == 0){
-				if(parseether(isa->ea, p+3) == -1)
-					memset(isa->ea, 0, 6);
-			}
-			else if(isa->nopt < NISAOPT){
-				r = isa->opt[isa->nopt];
-				while(*p && *p != ' ' && *p != '\t'){
-					*r++ = *p++;
-					if(r-isa->opt[isa->nopt] >= ISAOPTLEN-1)
-						break;
-				}
-				*r = '\0';
-				isa->nopt++;
-			}
-			while(*p && *p != ' ' && *p != '\t')
-				p++;
-		}
-		return 1;
-	}
-	return 0;
-}
--- a/os/boot/mpc/console.c
+++ /dev/null
@@ -1,173 +1,0 @@
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-
-static Queue*	consiq;
-static Queue*	consoq;
-
-void
-bothputs(char *s, int n)
-{
-	uartputs(s, n);
-	screenputs(s, n);
-}
-
-static void (*consputs)(char*, int) = bothputs;	/* or screenputs */
-
-void
-consinit(void)
-{
-	char *p;
-	int baud, port;
-	static int cgadone;
-
-	p = getconf("console");
-	if(0)
-	if(p == 0 || strcmp(p, "lcd") == 0 || strcmp(p, "screen") == 0){
-		consiq = qopen(4*1024, 0, 0, 0);
-		consoq = qopen(8*1024, 0, 0, 0);
-		consputs = screenputs;
-		return;
-	}
-	if(p!=0 && strstr(p, "lcd") == 0)
-		consputs = bothputs;
-	else
-		consputs = uartputs;
-//consputs = screenputs;
-	port = 0;
-	if(p)
-		port = strtoul(p, 0, 0);
-	baud = 0;
-	if(p = getconf("baud"))
-		baud = strtoul(p, 0, 0);
-	if(baud == 0)
-		baud = 9600;
-	uartspecial(port, baud, &consiq, &consoq, kbdchar);
-}
-
-void
-kbdchar(Queue *q, int c)
-{
-	c &= 0x7F;
-	if(c == 0x10)
-		panic("^p");
-	qbputc(q, c);
-}
-
-static int
-getline(char *buf, int size, int dotimeout)
-{
-	int c, i=0;
-	ulong start;
-	char echo;
-
-	for (;;) {
-		start = m->ticks;
-		do{
-			if(dotimeout && ((m->ticks - start) > 5*HZ))
-				return -2;
-			c = qbgetc(consiq);
-		}while(c == -1);
-		if(c == '\r')
-			c = '\n'; 		/* turn carriage return into newline */
-		if(c == '\177')
-			c = '\010';		/* turn delete into backspace */
-		if(c == '\025')
-			echo = '\n';		/* echo ^U as a newline */
-		else
-			echo = c;
-		(*consputs)(&echo, 1);
-
-		if(c == '\010'){
-			if(i > 0)
-				i--; /* bs deletes last character */
-			continue;
-		}
-		/* a newline ends a line */
-		if (c == '\n')
-			break;
-		/* ^U wipes out the line */
-		if (c =='\025')
-			return -1;
-		if(i == size)
-			return size;
-		buf[i++] = c;
-	}
-	buf[i] = 0;
-	return i;
-}
-
-int
-getstr(char *prompt, char *buf, int size, char *def)
-{
-	int len, isdefault;
-
-	buf[0] = 0;
-	isdefault = (def && *def);
-	for (;;) {
-		if(isdefault)
-			print("%s[default==%s]: ", prompt, def);
-		else
-			print("%s: ", prompt);
-		len = getline(buf, size, isdefault);
-		switch(len){
-		case -1:
-			/* ^U typed */
-			continue;
-		case -2:
-			/* timeout, use default */
-			(*consputs)("\n", 1);
-			len = 0;
-			break;
-		default:
-			break;
-		}
-		if(len >= size){
-			print("line too long\n");
-			continue;
-		}
-		break;
-	}
-	if(len == 0 && isdefault)
-		strcpy(buf, def);
-	return 0;
-}
-
-int
-sprint(char *s, char *fmt, ...)
-{
-	return donprint(s, s+PRINTSIZE, fmt, (&fmt+1)) - s;
-}
-
-int
-print(char *fmt, ...)
-{
-	char buf[PRINTSIZE];
-	int n;
-
-	if(consputs == 0)
-		return 0;
-	n = donprint(buf, buf+sizeof(buf), fmt, (&fmt+1)) - buf;
-	(*consputs)(buf, n);
-	return n;
-}
-
-void
-panic(char *fmt, ...)
-{
-	char buf[PRINTSIZE];
-	int n;
-
-	if(consputs){
-		(*consputs)("panic: ", 7);
-		n = donprint(buf, buf+sizeof(buf), fmt, (&fmt+1)) - buf;
-		(*consputs)(buf, n);
-		(*consputs)("\n", 1);
-	}
-	spllo();
-	for(;;)
-		idle();
-}
--- a/os/boot/mpc/cpm.c
+++ /dev/null
@@ -1,162 +1,0 @@
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-
-enum {
-	BDSIZE=	1024,	/* TO DO: check this */
-};
-
-static	Map	bdmapv[BDSIZE/sizeof(BD)];
-static	RMap	bdmap = {"buffer descriptors"};
-
-void
-cpminit(void)
-{
-	IMM *io;
-
-	io = m->iomem;
-	io->sdcr = 1;
-	io->lccr &= ~1;	/* disable LCD */
-	io->pcint = 0;	/* disable all port C interrupts */
-	io->pcso = 0;
-	io->pcdir =0;
-	io->pcpar = 0;
-	io->pcdat = 0;
-	io->papar = 0;
-	io->padir = 0;
-	io->paodr = 0;
-	io->padat = 0;
-	io->pbpar = 0;
-	io->pbdir = 0;
-	io->pbodr = 0;
-	io->pbdat = 0;
-	eieio();
-
-	for(io->cpcr = 0x8001; io->cpcr & 1;)	/* reset all CPM channels */
-		eieio();
-
-	mapinit(&bdmap, bdmapv, sizeof(bdmapv));
-	mapfree(&bdmap, DPBASE, BDSIZE);
-}
-
-void
-cpmop(int op, int cno, int param)
-{
-	IMM *io;
-	int s;
-
-	s = splhi();
-	io = m->iomem;
-	eieio();
-	while(io->cpcr & 1)
-		eieio();
-	io->cpcr = (op<<8)|(cno<<4)|(param<<1)|1;
-	eieio();
-	while(io->cpcr & 1)
-		eieio();
-	splx(s);
-}
-
-/*
- * connect SCCx clocks in NSMI mode (x=1 for USB)
- */
-void
-sccnmsi(int x, int rcs, int tcs)
-{
-	IMM *io;
-	ulong v;
-	int sh;
-
-	sh = (x-1)*8;	/* each SCCx field in sicr is 8 bits */
-	v = (((rcs&7)<<3) | (tcs&7)) << sh;
-	io = ioplock();
-	io->sicr = (io->sicr & ~(0xFF<<sh)) | v;
-	iopunlock();
-}
-
-void
-scc2stop(void)
-{
-	SCC *scc;
-
-	scc = IOREGS(0xA20, SCC);
-	if(scc->gsmrl & (3<<4)){
-		cpmop(GracefulStopTx, SCC2ID, 0);
-		cpmop(CloseRxBD, SCC2ID, 0);
-		delay(1);
-		scc->gsmrl &= ~(3<<4);	/* disable current use */
-		archetherdisable(SCC2ID);
-	}
-}
-
-BD *
-bdalloc(int n)
-{
-	ulong a;
-
-	a = mapalloc(&bdmap, 0, n*sizeof(BD), 0);
-	if(a == 0)
-		panic("bdalloc");
-	return KADDR(a);
-}
-
-void
-bdfree(BD *b, int n)
-{
-	if(b){
-		eieio();
-		mapfree(&bdmap, PADDR(b), n*sizeof(BD));
-	}
-}
-
-/*
- * initialise receive and transmit buffer rings.
- */
-int
-ioringinit(Ring* r, int nrdre, int ntdre, int bufsize)
-{
-	int i, x;
-
-	/* the ring entries must be aligned on sizeof(BD) boundaries */
-	r->nrdre = nrdre;
-	if(r->rdr == nil)
-		r->rdr = bdalloc(nrdre);
-	/* the buffer size must align with cache lines since the cache doesn't snoop */
-	bufsize = (bufsize+CACHELINESZ-1)&~(CACHELINESZ-1);
-	if(r->rrb == nil)
-		r->rrb = malloc(nrdre*bufsize);
-	if(r->rdr == nil || r->rrb == nil)
-		return -1;
-	dcflush(r->rrb, nrdre*bufsize);
-	x = PADDR(r->rrb);
-	for(i = 0; i < nrdre; i++){
-		r->rdr[i].length = 0;
-		r->rdr[i].addr = x;
-		r->rdr[i].status = BDEmpty|BDInt;
-		x += bufsize;
-	}
-	r->rdr[i-1].status |= BDWrap;
-	r->rdrx = 0;
-
-	r->ntdre = ntdre;
-	if(r->tdr == nil)
-		r->tdr = bdalloc(ntdre);
-	if(r->txb == nil)
-		r->txb = malloc(ntdre*sizeof(Block*));
-	if(r->tdr == nil || r->txb == nil)
-		return -1;
-	for(i = 0; i < ntdre; i++){
-		r->txb[i] = nil;
-		r->tdr[i].addr = 0;
-		r->tdr[i].length = 0;
-		r->tdr[i].status = 0;
-	}
-	r->tdr[i-1].status |= BDWrap;
-	r->tdrh = 0;
-	r->tdri = 0;
-	r->ntq = 0;
-	return 0;
-}
--- a/os/boot/mpc/crc32.c
+++ /dev/null
@@ -1,42 +1,0 @@
-#include "boot.h"
-
-/*
- * from Rob Warnock
- */
-static	ulong	crc32tab[256];	/* initialised on first call to crc32 */
-
-enum {
-	CRC32POLY = 0x04c11db7     /* AUTODIN II, Ethernet, & FDDI */
-};
-
-/*
- * Build auxiliary table for parallel byte-at-a-time CRC-32.
- */
-static void
-initcrc32(void)
-{
-	int i, j;
-	ulong c;
-
-	for(i = 0; i < 256; i++) {
-		for(c = i << 24, j = 8; j > 0; j--)
-			if(c & (1<<31))
-				c = (c<<1) ^ CRC32POLY;
-			else
-				c <<= 1;
-		crc32tab[i] = c;
-	}
-}
-
-ulong
-crc32(void *buf, int n, ulong crc)
-{
-	uchar *p;
-
-	if(crc32tab[1] == 0)
-		initcrc32();
-	crc = ~crc;
-	for(p = buf; --n >= 0;)
-		crc = (crc << 8) ^ crc32tab[(crc >> 24) ^ *p++];
-	return ~crc;
-}
--- a/os/boot/mpc/dat.h
+++ /dev/null
@@ -1,217 +1,0 @@
-typedef struct Alarm Alarm;
-typedef struct Block Block;
-typedef struct IMM IMM;
-typedef struct Queue Queue;
-
-typedef struct List {
-	void	*next;
-} List;
-
-typedef struct {
-	int	fake;
-	int	pri;
-} Lock;
-#define	lock(x)
-#define	unlock(x)
-
-struct Alarm {
-	List;
-	int	busy;
-	long	dt;
-	void	(*f)(Alarm*);
-	void	*arg;
-};
-
-enum {
-	Eaddrlen	= 6,
-	ETHERMINTU	= 60,		/* minimum transmit size */
-	ETHERMAXTU	= 1514,		/* maximum transmit size */
-	ETHERHDRSIZE	= 14,		/* size of an ethernet header */
-
-	MaxEther	= 4,
-};
-
-typedef struct {
-	uchar	d[Eaddrlen];
-	uchar	s[Eaddrlen];
-	uchar	type[2];
-	uchar	data[1500];
-	uchar	crc[4];
-} Etherpkt;
-
-extern uchar broadcast[Eaddrlen];
-
-enum {
-	Npart		= 20+2,		/* 8 sub partitions, disk, and partition */
-	Maxxfer		= 16*1024,	/* maximum transfer size/cmd */
-};
-
-typedef struct {
-	ulong	start;
-	ulong	end;
-	char	name[NAMELEN+1];
-} Partition;
-
-typedef struct {
-	int	online;
-	int	npart;		/* number of real partitions */
-	Partition p[Npart];
-	ulong	offset;
-	Partition *current;	/* current partition */
-
-	ulong	cap;		/* total bytes */
-	int	bytes;		/* bytes/sector */
-	int	sectors;	/* sectors/track */
-	int	heads;		/* heads/cyl */
-	long	cyl;		/* cylinders/drive */
-
-	char	lba;		/* true if drive has logical block addressing */
-	char	multi;		/* non-zero if drive does multiple block xfers */
-} Disc;
-
-enum {
-	ScsiTestunit	= 0x00,
-	ScsiExtsens	= 0x03,
-	ScsiInquiry	= 0x12,
-	ScsiModesense	= 0x1a,
-	ScsiStartunit	= 0x1B,
-	ScsiStopunit	= 0x1B,
-	ScsiGetcap	= 0x25,
-	ScsiRead	= 0x08,
-	ScsiWrite	= 0x0a,
-	ScsiExtread	= 0x28,
-	ScsiExtwrite	= 0x2a,
-
-	/* data direction */
-	ScsiIn		= 1,
-	ScsiOut		= 0,
-};
-
-typedef struct Scsibuf Scsibuf;
-typedef struct Scsibuf {
-	void*		virt;
-	void*		phys;
-	Scsibuf*	next;
-};
-
-typedef struct Scsidata {
-	uchar*		base;
-	uchar*		lim;
-	uchar*		ptr;
-} Scsidata;
-
-typedef struct Ureg Ureg;
-
-typedef struct Scsi {
-	ulong		pid;
-	ushort		target;
-	ushort		lun;
-	ushort		rflag;
-	ushort		status;
-	Scsidata 	cmd;
-	Scsidata 	data;
-	Scsibuf*	b;
-	uchar*		save;
-	uchar		cmdblk[16];
-} Scsi;
-
-typedef struct Segdesc {
-	ulong	d0;
-	ulong	d1;
-} Segdesc;
-
-typedef struct Mach {
-	ulong	ticks;			/* of the clock since boot time */
-	ulong	delayloop;
-	long	cpuhz;	/* general system clock (cycles) */
-	long	clockgen;	/* clock generator frequency (cycles) */
-	ulong	cpupvr;	/* cpu type in processor version register */
-	ulong	cputype;	/* cpu variant in BCD (eg, 0x823xx) */
-	void*	alarm;			/* alarms bound to this clock */
-	ulong*	bcsr;
-	IMM*	iomem;
-} Mach;
-
-/* Mach.cputype */
-#define MPCREV(x)	((x) & 0xFF)
-#define MPCMODEL(x)	(((x)>>8) & 0xFFF)
-#define MPCFAMILY(x)	(((x)>>24) & 0x0F)
-
-
-extern Mach *m;
-
-#define Q_MAGIC		((((4*21)+0)*21)+7)
-
-typedef struct Exec Exec;
-struct	Exec
-{
-	uchar	magic[4];		/* magic number */
-	uchar	text[4];	 	/* size of text segment */
-	uchar	data[4];	 	/* size of initialized data */
-	uchar	bss[4];	  		/* size of uninitialized data */
-	uchar	syms[4];	 	/* size of symbol table */
-	uchar	entry[4];	 	/* entry point */
-	uchar	spsz[4];		/* size of sp/pc offset table */
-	uchar	pcsz[4];		/* size of pc/line number table */
-};
-
-/*
- *  bootline passed by boot program
- */
-#define BOOTLINE ((char *)0x200000-150)
-
-/*
- * Where we leave configuration info.
- */
-#define BOOTARGS	((char*)(0x200000))
-#define	BOOTARGSLEN	1024
-#define	MAXCONF		32
-
-/*
- *  a parsed plan9.ini line
- */
-#define ISAOPTLEN	16
-#define NISAOPT		8
-
-typedef struct  ISAConf {
-	char	type[NAMELEN];
-	ulong	port;
-	ulong	irq;
-	ulong	mem;
-	ulong	size;
-	uchar	ea[6];
-
-	int	nopt;
-	char	opt[NISAOPT][ISAOPTLEN];
-} ISAConf;
-
-typedef struct {
-	int	size;
-	ulong	addr;
-} Map;
-
-typedef struct {
-	char*	name;
-	Map*	map;
-	Map*	mapend;
-
-	Lock;
-} RMap;
-
-typedef struct PCIcfg PCIcfg;
-
-extern	uchar*	vgamem;
-
-struct Block {
-	uchar	*rp;
-	uchar	*wp;
-	uchar	*lim;
-	uchar	*data;
-	Block*	next;
-	ulong	magic;
-};
-#define	BLEN(b)	((b)->wp-(b)->rp)
-
-typedef struct QLock {
-	int	dummy;
-} QLock;
--- a/os/boot/mpc/defont0.c
+++ /dev/null
@@ -1,216 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include <libg.h>
-#include <gnot.h>
-
-
-
-static ulong bits0[] = {
- 0x907070f0,  0xf0f07000,  0xf0888888,  0xf8707070,  0xe0e0e0e0,  0xe09070f0,  0x70f870f0,  0xf870f088, 
- 0x00000000,  0x00000000,  0x00000000,  0x00000000,  0x00000000,  0x00000000,  0x00000000,  0x00000000, 
- 0x00000000,  0x00000000,  0x00000000,  0x00000000,  0x00000000,  0x00000000,  0x00000000,  0x00000000, 
- 0x00000000,  0x00000000,  0x00000000,  0x00000000,  0x00000000,  0x00000000,  0x00000000,  0x000000e0, 
- 0xd0808080,  0x80808800,  0x8888c888,  0x80888888,  0x90909090,  0x90d08080,  0x80808080,  0x80888888, 
- 0x00000000,  0x08000000,  0x0c300000,  0x00000006,  0x00000000,  0x00000000,  0x00000000,  0x00000000, 
- 0x00000000,  0x00000000,  0x00000000,  0x00000000,  0x00000000,  0x00000000,  0x0000003c,  0xc03c0000, 
- 0x00006000,  0x06001e00,  0x60181860,  0x78000000,  0x00000000,  0x00000000,  0x0000001c,  0x18380090, 
- 0xb06060e0,  0xe0e0f800,  0xf088a888,  0x80808080,  0x90909090,  0x90b060e0,  0x808060e0,  0x80808888, 
- 0x00182428,  0x3e707018,  0x18180000,  0x00000006,  0x3c183c3c,  0x1c3e3c7e,  0x3c3c0000,  0x0200403c, 
- 0x3c187c1e,  0x787e7e1e,  0x663c7c66,  0x6066623c,  0x7c3c7c3c,  0x7e6266c2,  0x66667e30,  0xc00c1000, 
- 0x08006000,  0x06003000,  0x60181860,  0x18000000,  0x00000000,  0x10000000,  0x00000030,  0x180c0090, 
- 0x90101080,  0x80808818,  0x88f8a888,  0xe0807070,  0xe0e0e0e0,  0xe0901080,  0x70e01080,  0xe098f088, 
- 0x00182428,  0x6adad818,  0x18181000,  0x0000000c,  0x66386666,  0x2c3e667e,  0x66660000,  0x06006066, 
- 0x42186632,  0x6c606032,  0x66181864,  0x60667224,  0x66246666,  0x186262da,  0x62620630,  0x600c3800, 
- 0x10006000,  0x06003000,  0x60000060,  0x18000000,  0x00000000,  0x30000000,  0x00000030,  0x180c00e0, 
- 0x00e0e0f0,  0xf0f00018,  0x88889850,  0x80880808,  0x201c1c1c,  0x1c00e0f0,  0x0080e0f0,  0x80888888, 
- 0x00182428,  0x68dad808,  0x300c5418,  0x0000000c,  0x66580606,  0x2c206002,  0x66661818,  0x0cfe3006, 
- 0x9e2c6660,  0x66606060,  0x6618186c,  0x60667266,  0x66666660,  0x186262da,  0x36660c30,  0x600c2800, 
- 0x103c6c3c,  0x3e3c7e3e,  0x6c787866,  0x18d46c3c,  0x6c3e763c,  0x7e6666c2,  0x66667e18,  0x18180000, 
- 0x44180000,  0x18241c24,  0xf0888820,  0x8070f0f0,  0x20202020,  0x201c243e,  0x1cf8241c,  0x80708870, 
- 0x0018247c,  0x78745008,  0x300c3818,  0x00000018,  0x66180606,  0x4c206006,  0x76661818,  0x18fe180c, 
- 0xb62c6660,  0x66606060,  0x66181868,  0x607e5a66,  0x66666470,  0x186266da,  0x34340c30,  0x300c6c00, 
- 0x18667666,  0x66663066,  0x76181864,  0x18fe7666,  0x76663666,  0x306662da,  0x62620608,  0x1810323c, 
- 0x44247c7c,  0x24342042,  0x00000000,  0x00000000,  0x20202020,  0x20222408,  0x22002420,  0x00000000, 
- 0x00180028,  0x3c287610,  0x300cee7e,  0x00fe0018,  0x66180c18,  0x4c3c7c0c,  0x3c3e0000,  0x30000c18, 
- 0xb62c7c60,  0x667c7c6e,  0x7e181878,  0x605a5a66,  0x6466783c,  0x186234da,  0x18341830,  0x300c4400, 
- 0x18066660,  0x66663066,  0x66181868,  0x18d66666,  0x66663860,  0x306662da,  0x34620c30,  0x180c5a20, 
- 0x44241010,  0x242c2042,  0x0e3e103e,  0x3e3c1c3e,  0x3c1c1c1c,  0x1c3e1c08,  0x3e222418,  0x0e0e0e0e, 
- 0x0008007c,  0x1e5cdc00,  0x300c387e,  0x00fe0030,  0x66181806,  0x7e066618,  0x6e060000,  0x18001818, 
- 0xb67e6660,  0x66606066,  0x6618186c,  0x605a4e66,  0x78666c0e,  0x1862346c,  0x2c183030,  0x180c4400, 
- 0x003e6660,  0x667e3066,  0x66181878,  0x18d66666,  0x6666303c,  0x306634da,  0x18341808,  0x18104c38, 
- 0x3c181010,  0x18241c42,  0x11081008,  0x20222208,  0x00000000,  0x00220408,  0x22361804,  0x11111111, 
- 0x00000028,  0x16b6cc00,  0x300c5418,  0x00000030,  0x66183006,  0x7e066618,  0x66060000,  0x0cfe3000, 
- 0x9a466660,  0x66606066,  0x6618186c,  0x605a4e66,  0x60666606,  0x1862346c,  0x6c183030,  0x180c0000, 
- 0x00666660,  0x66603066,  0x6618186c,  0x18d66666,  0x66663006,  0x3066346c,  0x2c343018,  0x18180020, 
- 0x00091010,  0x000e0942,  0x10081008,  0x20222208,  0x0f06060f,  0x0a09041e,  0x002a0e38,  0x10101010, 
- 0x00180028,  0x56b6cc00,  0x300c1018,  0x18001860,  0x66187e66,  0x0c666630,  0x66661818,  0x06fe6018, 
- 0x40466632,  0x6c606036,  0x66181866,  0x605a4624,  0x60246666,  0x1834186c,  0x46186030,  0x0c0c0000, 
- 0x006e6666,  0x6e66306e,  0x66181866,  0x18d66666,  0x666e3066,  0x306e186c,  0x46186030,  0x180c003c, 
- 0x08090909,  0x1f110aff,  0x0e081008,  0x382c2208,  0x08020901,  0x0a0a0911,  0x09220907,  0x0e0e0e0e, 
- 0x00180028,  0x7c1c7600,  0x18180000,  0x18001860,  0x3c7e7e3c,  0x0c3c3c30,  0x3c3c1818,  0x02004018, 
- 0x3e467c1e,  0x787e601e,  0x663c1866,  0x7e42463c,  0x603c663c,  0x1818186c,  0x66187e30,  0x0c0c0000, 
- 0x00367c3c,  0x363c7c36,  0x667e1866,  0x7ed6663c,  0x7c367c3c,  0x1e36186c,  0x66187e30,  0x180c0008, 
- 0x080f0606,  0x04110c18,  0x01081008,  0x20222208,  0x0e020203,  0x0a0c0d1e,  0x0d220e08,  0x01010101, 
- 0x00000000,  0x10000000,  0x18180000,  0x080000c0,  0x00000000,  0x00000000,  0x00000008,  0x00000000, 
- 0x00000000,  0x00000000,  0x00001800,  0x00000000,  0x000c0000,  0x00000000,  0x00000030,  0x060c00fe, 
- 0x00000000,  0x00000006,  0x00001800,  0x00000000,  0x60060000,  0x00000000,  0x0010001c,  0x18380008, 
- 0x08090606,  0x040e0a18,  0x11081f08,  0x20221c3e,  0x08020401,  0x0f0a0b11,  0x0b220908,  0x11111111, 
- 0x00000000,  0x00000000,  0x0c300000,  0x080000c0,  0x00000000,  0x00000000,  0x00000008,  0x00000000, 
- 0x00000000,  0x00000000,  0x00007000,  0x00000000,  0x00060000,  0x00000000,  0x0000003c,  0x063c0000, 
- 0x00000000,  0x00000066,  0x00001800,  0x00000000,  0x60060000,  0x00000000,  0x00300000,  0x00000008, 
- 0x0f090909,  0x04030900,  0x0e000000,  0x00000000,  0x0f0f0f0f,  0x0209091e,  0x09000f07,  0x0e0e0e0e, 
- 0x00000000,  0x00000000,  0x00000000,  0x10000000,  0x00000000,  0x00000000,  0x00000010,  0x00000000, 
- 0x00000000,  0x00000000,  0x00000000,  0x00000000,  0x00000000,  0x00000000,  0x00000000,  0x00000000, 
- 0x00000000,  0x0000003c,  0x00007000,  0x00000000,  0x60060000,  0x00000000,  0x00600000,  0x0000000f, 
-
-};
-
-static GBitmap strike0 = {
-	bits0,
-	0,
-	32,
-	0,
-	{0, 0, 1024, 14},
-	{0, 0, 1024, 14},
-};
-
-static Fontchar info0[] = {
-	{ 0, 0, 14, 0, 8 },
-	{ 8, 0, 14, 0, 8 },
-	{ 16, 0, 14, 0, 8 },
-	{ 24, 0, 14, 0, 8 },
-	{ 32, 0, 14, 0, 8 },
-	{ 40, 0, 14, 0, 8 },
-	{ 48, 0, 14, 0, 8 },
-	{ 56, 0, 14, 0, 8 },
-	{ 64, 0, 14, 0, 8 },
-	{ 72, 0, 14, 0, 8 },
-	{ 80, 0, 14, 0, 8 },
-	{ 88, 0, 14, 0, 8 },
-	{ 96, 0, 14, 0, 8 },
-	{ 104, 0, 14, 0, 8 },
-	{ 112, 0, 14, 0, 8 },
-	{ 120, 0, 14, 0, 8 },
-	{ 128, 0, 14, 0, 8 },
-	{ 136, 0, 14, 0, 8 },
-	{ 144, 0, 14, 0, 8 },
-	{ 152, 0, 14, 0, 8 },
-	{ 160, 0, 14, 0, 8 },
-	{ 168, 0, 14, 0, 8 },
-	{ 176, 0, 14, 0, 8 },
-	{ 184, 0, 14, 0, 8 },
-	{ 192, 0, 14, 0, 8 },
-	{ 200, 0, 14, 0, 8 },
-	{ 208, 0, 14, 0, 8 },
-	{ 216, 0, 14, 0, 8 },
-	{ 224, 0, 14, 0, 8 },
-	{ 232, 0, 14, 0, 8 },
-	{ 240, 0, 14, 0, 8 },
-	{ 248, 0, 14, 0, 8 },
-	{ 256, 0, 0, 0, 8 },
-	{ 264, 2, 11, 0, 8 },
-	{ 272, 2, 6, 0, 8 },
-	{ 280, 2, 11, 0, 8 },
-	{ 288, 1, 12, 0, 8 },
-	{ 296, 2, 11, 0, 8 },
-	{ 304, 2, 11, 0, 8 },
-	{ 312, 2, 7, 0, 8 },
-	{ 320, 1, 13, 0, 8 },
-	{ 328, 1, 13, 0, 8 },
-	{ 336, 3, 10, 0, 8 },
-	{ 344, 4, 10, 0, 8 },
-	{ 352, 9, 14, 0, 8 },
-	{ 360, 6, 8, 0, 8 },
-	{ 368, 9, 11, 0, 8 },
-	{ 376, 1, 13, 0, 8 },
-	{ 384, 2, 11, 0, 8 },
-	{ 392, 2, 11, 0, 8 },
-	{ 400, 2, 11, 0, 8 },
-	{ 408, 2, 11, 0, 8 },
-	{ 416, 2, 11, 0, 8 },
-	{ 424, 2, 11, 0, 8 },
-	{ 432, 2, 11, 0, 8 },
-	{ 440, 2, 11, 0, 8 },
-	{ 448, 2, 11, 0, 8 },
-	{ 456, 2, 11, 0, 8 },
-	{ 464, 4, 11, 0, 8 },
-	{ 472, 4, 14, 0, 8 },
-	{ 480, 2, 11, 0, 8 },
-	{ 488, 4, 10, 0, 8 },
-	{ 496, 2, 11, 0, 8 },
-	{ 504, 2, 11, 0, 8 },
-	{ 512, 2, 11, 0, 8 },
-	{ 520, 2, 11, 0, 8 },
-	{ 528, 2, 11, 0, 8 },
-	{ 536, 2, 11, 0, 8 },
-	{ 544, 2, 11, 0, 8 },
-	{ 552, 2, 11, 0, 8 },
-	{ 560, 2, 11, 0, 8 },
-	{ 568, 2, 11, 0, 8 },
-	{ 576, 2, 11, 0, 8 },
-	{ 584, 2, 11, 0, 8 },
-	{ 592, 2, 13, 0, 8 },
-	{ 600, 2, 11, 0, 8 },
-	{ 608, 2, 11, 0, 8 },
-	{ 616, 2, 11, 0, 8 },
-	{ 624, 2, 11, 0, 8 },
-	{ 632, 2, 11, 0, 8 },
-	{ 640, 2, 11, 0, 8 },
-	{ 648, 2, 13, 0, 8 },
-	{ 656, 2, 11, 0, 8 },
-	{ 664, 2, 11, 0, 8 },
-	{ 672, 2, 11, 0, 8 },
-	{ 680, 2, 11, 0, 8 },
-	{ 688, 2, 11, 0, 8 },
-	{ 696, 2, 11, 0, 8 },
-	{ 704, 2, 11, 0, 8 },
-	{ 712, 2, 11, 0, 8 },
-	{ 720, 2, 11, 0, 8 },
-	{ 728, 1, 13, 0, 8 },
-	{ 736, 1, 13, 0, 8 },
-	{ 744, 1, 13, 0, 8 },
-	{ 752, 2, 8, 0, 8 },
-	{ 760, 11, 12, 0, 8 },
-	{ 768, 2, 7, 0, 8 },
-	{ 776, 4, 11, 0, 8 },
-	{ 784, 1, 11, 0, 8 },
-	{ 792, 4, 11, 0, 8 },
-	{ 800, 1, 11, 0, 8 },
-	{ 808, 4, 11, 0, 8 },
-	{ 816, 1, 11, 0, 8 },
-	{ 824, 4, 14, 0, 8 },
-	{ 832, 1, 11, 0, 8 },
-	{ 840, 1, 11, 0, 8 },
-	{ 848, 1, 14, 0, 8 },
-	{ 856, 1, 11, 0, 8 },
-	{ 864, 1, 11, 0, 8 },
-	{ 872, 4, 11, 0, 8 },
-	{ 880, 4, 11, 0, 8 },
-	{ 888, 4, 11, 0, 8 },
-	{ 896, 4, 14, 0, 8 },
-	{ 904, 4, 14, 0, 8 },
-	{ 912, 4, 11, 0, 8 },
-	{ 920, 4, 11, 0, 8 },
-	{ 928, 2, 11, 0, 8 },
-	{ 936, 4, 11, 0, 8 },
-	{ 944, 4, 11, 0, 8 },
-	{ 952, 4, 11, 0, 8 },
-	{ 960, 4, 11, 0, 8 },
-	{ 968, 4, 14, 0, 8 },
-	{ 976, 4, 11, 0, 8 },
-	{ 984, 1, 12, 0, 8 },
-	{ 992, 1, 12, 0, 8 },
-	{ 1000, 1, 12, 0, 8 },
-	{ 1008, 5, 8, 0, 8 },
-	{ 1016, 0, 14, 0, 8 },
-	{ 1024, 0, 14, 0, 8 },
-	{ 0, 0, 0, 0, 0 }
-};
-
-GSubfont defont0 = {
-	129,
-	14,
-	2,
-	info0,
-	&strike0,
-};
--- a/os/boot/mpc/devether.c
+++ /dev/null
@@ -1,157 +1,0 @@
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-
-#include "etherif.h"
-
-static Ctlr ether[MaxEther];
-
-static struct {
-	char	*type;
-	int	(*reset)(Ctlr*);
-} cards[] = {
-	{ "SCC", sccethreset, },
-	{ "SCC2", sccethreset, },
-	{ 0, }
-};
-
-int
-etherinit(void)
-{
-	Ctlr *ctlr;
-	int ctlrno, i, mask, n;
-
-	mask = 0;
-	for(ctlrno = 0; ctlrno < MaxEther; ctlrno++){
-		ctlr = &ether[ctlrno];
-		memset(ctlr, 0, sizeof(Ctlr));
-		if(isaconfig("ether", ctlrno, &ctlr->card) == 0)
-			continue;
-		for(n = 0; cards[n].type; n++){
-			if(strcmp(cards[n].type, ctlr->card.type))
-				continue;
-			ctlr->ctlrno = ctlrno;
-			if((*cards[n].reset)(ctlr))
-				break;
-
-			ctlr->iq = qopen(16*1024, 1, 0, 0);
-			ctlr->oq = qopen(16*1024, 1, 0, 0);
-
-			ctlr->present = 1;
-			mask |= 1<<ctlrno;
-
-			print("ether%d: %s: port 0x%luX irq %d",
-				ctlr->ctlrno, ctlr->card.type, ctlr->card.port, ctlr->card.irq);
-			if(ctlr->card.mem)
-				print(" addr 0x%luX", PADDR(ctlr->card.mem));
-			if(ctlr->card.size)
-				print(" size 0x%luX", ctlr->card.size);
-			print(":");
-			for(i = 0; i < sizeof(ctlr->card.ea); i++)
-				print(" %2.2uX", ctlr->card.ea[i]);
-			print("\n"); uartwait();
-			setvec(VectorPIC + ctlr->card.irq, ctlr->card.intr, ctlr);
-			break;
-		}
-	}
-
-	return mask;
-}
-
-static Ctlr*
-attach(int ctlrno)
-{
-	Ctlr *ctlr;
-
-	if(ctlrno >= MaxEther || ether[ctlrno].present == 0)
-		return 0;
-
-	ctlr = &ether[ctlrno];
-	if(ctlr->present == 1){
-		ctlr->present = 2;
-		(*ctlr->card.attach)(ctlr);
-	}
-
-	return ctlr;
-}
-
-uchar*
-etheraddr(int ctlrno)
-{
-	Ctlr *ctlr;
-
-	if((ctlr = attach(ctlrno)) == 0)
-		return 0;
-
-	return ctlr->card.ea;
-}
-
-int
-etherrxpkt(int ctlrno, Etherpkt *pkt, int timo)
-{
-	int n;
-	Ctlr *ctlr;
-	Block *b;
-	ulong start;
-
-	if((ctlr = attach(ctlrno)) == 0)
-		return 0;
-
-	start = m->ticks;
-	while((b = qget(ctlr->iq)) == 0){
-		if(TK2MS(m->ticks - start) >= timo){
-			/*
-			print("ether%d: rx timeout\n", ctlrno);
-			 */
-			return 0;
-		}
-	}
-
-	n = BLEN(b);
-	memmove(pkt, b->rp, n);
-	freeb(b);
-
-	return n;
-}
-
-int
-etheriq(Ctlr *ctlr, Block *b, int freebp)
-{
-	if(memcmp(((Etherpkt*)b->rp)->d, ctlr->card.ea, Eaddrlen) != 0 &&
-	   memcmp(((Etherpkt*)b->rp)->d, broadcast, Eaddrlen) != 0){
-		if(freebp)
-			freeb(b);
-		return 0;
-	}
-	qbwrite(ctlr->iq, b);
-	return 1;
-}
-
-int
-ethertxpkt(int ctlrno, Etherpkt *pkt, int len, int)
-{
-	Ctlr *ctlr;
-	Block *b;
-	int s;
-
-	if((ctlr = attach(ctlrno)) == 0)
-		return 0;
-
-	if(qlen(ctlr->oq) > 16*1024){
-		print("ether%d: tx queue full\n", ctlrno);
-		return 0;
-	}
-	b = iallocb(sizeof(Etherpkt));
-	memmove(b->wp, pkt, len);
-	memmove(((Etherpkt*)b->wp)->s, ctlr->card.ea, Eaddrlen);
-	b->wp += len;
-	qbwrite(ctlr->oq, b);
-	s = splhi();
-	(*ctlr->card.transmit)(ctlr);
-	splx(s);
-
-	return 1;
-}
--- a/os/boot/mpc/devuart.c
+++ /dev/null
@@ -1,230 +1,0 @@
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-
-/*
- *  SMC1 in UART mode
- */
-
-typedef struct Uartsmc Uartsmc;
-struct Uartsmc {
-	IOCparam;
-	ushort	maxidl;
-	ushort	idlc;
-	ushort	brkln;
-	ushort	brkec;
-	ushort	brkcr;
-	ushort	rmask;
-};
-
-typedef struct Uart	Uart;
-struct Uart
-{
-	int	port;
-	int	setup;
-	uchar	txbusy;
-
-	Queue*	iq;
-	Queue*	oq;
-	void	(*rx)(Queue*, int);
-	void	(*boot)(uchar*, int);
-
-	ulong	frame;
-	ulong	overrun;
-	uchar	rxbuf[128];
-	char	txbuf[16];
-	BD*	rxb;
-	BD*	txb;
-};
-
-Uart	uart[1];
-int	predawn = 1;
-
-static	void	uartintr(Ureg*, void*);
-static	void	uartkick(void*);
-
-static int
-baudgen(int baud)
-{
-	int d;
-
-	d = ((m->cpuhz/baud)+8)>>4;
-	if(d >= (1<<12))
-		return ((d+15)>>3)|1;
-	return d<<1;
-}
-
-static void
-smcsetup(Uart *up, int baud)
-{
-	IMM *io;
-	Uartsmc *p;
-	BD *bd;
-	SMC *smc;
-
-	archenableuart(SMC1ID, 0);
-	io = m->iomem;
-	io->pbpar |= IBIT(24)|IBIT(25);	/* enable SMC1 TX/RX */
-	io->pbdir &= ~(IBIT(24)|IBIT(25));
-	io->brgc1 = baudgen(baud) | BaudEnable;
-	io->simode &= ~0xF000;	/* SMC1 to NMSI mode, Tx/Rx clocks are BRG1 */
-
-	bd = bdalloc(1);
-	p = (Uartsmc*)KADDR(SMC1P);
-	p->rbase = (ushort)bd;
-	up->rxb = bd;
-	bd->status = BDEmpty|BDWrap|BDInt;
-	bd->length = 0;
-	bd->addr = PADDR(up->rxbuf);
-	bd = bdalloc(1);
-	p->tbase = (ushort)bd;
-	up->txb = bd;
-	bd->status = BDWrap|BDInt;
-	bd->length = 0;
-	bd->addr = PADDR(up->txbuf);
-
-	cpmop(InitRxTx, SMC1ID, 0);
-
-	/* protocol parameters */
-	p->rfcr = 0x18;
-	p->tfcr = 0x18;
-	p->mrblr = 1;
-	p->maxidl = 1;
-	p->brkln = 0;
-	p->brkec = 0;
-	p->brkcr = 1;
-	smc = IOREGS(0xA80, SMC);
-	smc->smce = 0xff;	/* clear events */
-	smc->smcm = 0x17;	/* enable all possible interrupts */
-	setvec(VectorCPIC+4, uartintr, up);
-	smc->smcmr = 0x4820;	/* 8-bit mode, no parity, 1 stop bit, UART mode, ... */
-	smc->smcmr |= 3;	/* enable rx/tx */
-}
-
-static void
-uartintr(Ureg*, void *arg)
-{
-	Uart *up;
-	int ch, i;
-	BD *bd;
-	SMC *smc;
-	Block *b;
-
-	up = arg;
-	smc = IOREGS(0xA80, SMC);
-	smc->smce = 0xff;	/* clear all events */
-	if((bd = up->rxb) != nil && (bd->status & BDEmpty) == 0){
-		if(up->iq != nil && bd->length > 0){
-			if(up->boot != nil){
-				up->boot(up->rxbuf, bd->length);
-			}else if(up->rx != nil){
-				for(i=0; i<bd->length; i++){
-					ch = up->rxbuf[i];
-					up->rx(up->iq, ch);
-				}
-			}else{
-				b = iallocb(bd->length);
-				memmove(b->wp, up->rxbuf, bd->length);
-				b->wp += bd->length;
-				qbwrite(up->iq, b);
-			}
-		}
-		bd->status |= BDEmpty|BDInt;
-	} else if((bd = up->txb) != nil && (bd->status & BDReady) == 0){
-		ch = -1;
-		if(up->oq)
-			ch = qbgetc(up->oq);
-		if(ch != -1){
-			up->txbuf[0] = ch;
-			bd->length = 1;
-			bd->status |= BDReady;
-		}else
-			up->txbusy = 0;
-	}
-	/* TO DO: modem status, errors, etc */
-}
-
-static void
-uartkick(void *arg)
-{
-	Uart *up = arg;
-	int s, c, i;
-
-	s = splhi();
-	while(up->txbusy == 0 && (c = qbgetc(up->oq)) != -1){
-		if(predawn){
-			while(up->txb->status & BDReady)
-				;
-		} else {
-			for(i = 0; i < 100; i++){
-				if((up->txb->status & BDReady) == 0)
-					break;
-				delay(1);
-			}
-		}
-		up->txbuf[0] = c;
-		up->txb->length = 1;
-		up->txb->status |= BDReady;
-		up->txbusy = !predawn;
-	}
-	splx(s);
-}
-
-void
-uartspecial(int port, int baud, Queue **iq, Queue **oq, void (*rx)(Queue*,int))
-{
-	Uart *up = &uart[0];
-
-	if(up->setup)
-		return;
-	up->setup = 1;
-
-	*iq = up->iq = qopen(4*1024, 0, 0, 0);
-	*oq = up->oq = qopen(16*1024, 0, uartkick, up);
-	up->rx = rx;
-	USED(port);
-	up->port = SMC1ID;
-	if(baud == 0)
-		baud = 9600;
-	smcsetup(up, baud);
-	/* if using SCCn's UART, would also set DTR and RTS, but SMC doesn't use them */
-}
-
-void
-uartsetboot(void (*f)(uchar*, int))
-{
-	uart[0].boot = f;
-}
-
-void
-uartputs(char *s, int n)
-{
-	Uart *up = &uart[0];
-	Block *b;
-	int nl;
-	char *p;
-
-	nl = 0;
-	for(p = s; p < s+n; p++)
-		if(*p == '\n')
-			nl++;
-	b = iallocb(n+nl);
-	while(n--){
-		if(*s == '\n')
-			*b->wp++ = '\r';
-		*b->wp++ = *s++;
-	}
-	qbwrite(up->oq, b);
-}
-
-void
-uartwait(void)
-{
-	Uart *up = &uart[0];
-
-	while(up->txbusy)
-		;
-}
--- a/os/boot/mpc/dload.c
+++ /dev/null
@@ -1,103 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include <bio.h>
-#include <mach.h>
-
-static	char	*kernelfile = "/power/ipaq";
-ulong	crc32(void *buf, int n, ulong crc);
-
-void
-main(int argc, char **argv)
-{
-	int ifd, n;
-	char buf[64], reply[1];
-	int i, execsize;
-	Fhdr f;
-	ulong csum;
-
-	ARGBEGIN{
-	}ARGEND
-	ifd = open(kernelfile, OREAD);
-	if(ifd < 0){
-		fprint(2, "dload: can't open %s: %r\n", kernelfile);
-		exits("open");
-	}
-	i = 0;
-	if(crackhdr(ifd, &f) == 0){
-		fprint(2, "dload: not an executable file: %r\n");
-		exits("format");
-	}
-	if(f.magic != Q_MAGIC){
-		fprint(2, "dload: not a powerpc executable\n");
-		exits("format");
-	}
-	execsize = f.txtsz + f.datsz + f.txtoff;
-	seek(ifd, 0, 0);
-	csum = ~0;
-	while(execsize > 0 && (n = read(ifd, buf, sizeof(buf))) > 0){
-		if(n > execsize)
-			n = execsize;
-		for(;;){
-			if(write(1, buf, sizeof(buf)) != sizeof(buf)){	/* always writes full buffer */
-				fprint(2, "dload: write error: %r\n");
-				exits("write");
-			}
-			if(read(0, reply, 1) != 1){
-				fprint(2, "dload: bad reply\n");
-				exits("read");
-			}
-			if(reply[0] != 'n')
-				break;
-			fprint(2, "!");
-		}
-		if(reply[0] != 'y'){
-			fprint(2, "dload: bad ack: %c\n", reply[0]);
-			exits("reply");
-		}
-		if(++i%10 == 0)
-			fprint(2, ".");
-		execsize -= n;
-	}
-	exits(0);
-}
-
-/*
- * from Rob Warnock
- */
-static	ulong	crc32tab[256];	/* initialised on first call to crc32 */
-
-enum {
-	CRC32POLY = 0x04c11db7     /* AUTODIN II, Ethernet, & FDDI */
-};
-
-/*
- * Build auxiliary table for parallel byte-at-a-time CRC-32.
- */
-static void
-initcrc32(void)
-{
-	int i, j;
-	ulong c;
-
-	for(i = 0; i < 256; i++) {
-		for(c = i << 24, j = 8; j > 0; j--)
-			if(c & (1<<31))
-				c = (c<<1) ^ CRC32POLY;
-			else
-				c <<= 1;
-		crc32tab[i] = c;
-	}
-}
-
-ulong
-crc32(void *buf, int n, ulong crc)
-{
-	uchar *p;
-
-	if(crc32tab[1] == 0)
-		initcrc32();
-	crc = ~crc;
-	for(p = buf; --n >= 0;)
-		crc = (crc << 8) ^ crc32tab[(crc >> 24) ^ *p++];
-	return ~crc;
-}
--- a/os/boot/mpc/donprint.c
+++ /dev/null
@@ -1,332 +1,0 @@
-#include	"u.h"
-#include	"lib.h"
-
-#define	PTR	sizeof(char*)
-#define	SHORT	sizeof(int)
-#define	INT	sizeof(int)
-#define	LONG	sizeof(long)
-#define	IDIGIT	30
-#define	MAXCON	30
-
-#define	FLONG	(1<<0)
-#define	FSHORT	(1<<1)
-#define	FUNSIGN	(1<<2)
-
-typedef struct Op	Op;
-struct Op
-{
-	char	*p;
-	char	*ep;
-	void	*argp;
-	int	f1;
-	int	f2;
-	int	f3;
-};
-
-static	int	noconv(Op*);
-static	int	cconv(Op*);
-static	int	dconv(Op*);
-static	int	hconv(Op*);
-static	int	lconv(Op*);
-static	int	oconv(Op*);
-static	int	sconv(Op*);
-static	int	uconv(Op*);
-static	int	xconv(Op*);
-static	int	Xconv(Op*);
-static	int	percent(Op*);
-
-static
-int	(*fmtconv[MAXCON])(Op*) =
-{
-	noconv,
-	cconv, dconv, hconv, lconv,
-	oconv, sconv, uconv, xconv,
-	Xconv, percent,
-};
-static
-char	fmtindex[128] =
-{
-	['c'] 1,
-	['d'] 2,
-	['h'] 3,
-	['l'] 4,
-	['o'] 5,
-	['s'] 6,
-	['u'] 7,
-	['x'] 8,
-	['X'] 9,
-	['%'] 10,
-};
-
-static	int	convcount  = { 11 };
-static	int	ucase;
-
-static void
-PUT(Op *o, int c)
-{
-	static int pos;
-	int opos;
-
-	if(c == '\t'){
-		opos = pos;
-		pos = (opos+8) & ~7;
-		while(opos++ < pos && o->p < o->ep)
-			*o->p++ = ' ';
-		return;
-	}
-	if(o->p < o->ep){
-		*o->p++ = c;
-		pos++;
-	}
-	if(c == '\n')
-		pos = 0;
-}
-
-int
-fmtinstall(char c, int (*f)(Op*))
-{
-
-	c &= 0177;
-	if(fmtindex[c] == 0) {
-		if(convcount >= MAXCON)
-			return 1;
-		fmtindex[c] = convcount++;
-	}
-	fmtconv[fmtindex[c]] = f;
-	return 0;
-}
-
-char*
-donprint(char *p, char *ep, char *fmt, void *argp)
-{
-	int sf1, c;
-	Op o;
-
-	o.p = p;
-	o.ep = ep;
-	o.argp = argp;
-
-loop:
-	c = *fmt++;
-	if(c != '%') {
-		if(c == 0) {
-			if(o.p < o.ep)
-				*o.p = 0;
-			return o.p;
-		}
-		PUT(&o, c);
-		goto loop;
-	}
-	o.f1 = 0;
-	o.f2 = -1;
-	o.f3 = 0;
-	c = *fmt++;
-	sf1 = 0;
-	if(c == '-') {
-		sf1 = 1;
-		c = *fmt++;
-	}
-	while(c >= '0' && c <= '9') {
-		o.f1 = o.f1*10 + c-'0';
-		c = *fmt++;
-	}
-	if(sf1)
-		o.f1 = -o.f1;
-	if(c != '.')
-		goto l1;
-	c = *fmt++;
-	while(c >= '0' && c <= '9') {
-		if(o.f2 < 0)
-			o.f2 = 0;
-		o.f2 = o.f2*10 + c-'0';
-		c = *fmt++;
-	}
-l1:
-	if(c == 0)
-		fmt--;
-	c = (*fmtconv[fmtindex[c&0177]])(&o);
-	if(c < 0) {
-		o.f3 |= -c;
-		c = *fmt++;
-		goto l1;
-	}
-	o.argp = (char*)o.argp + c;
-	goto loop;
-}
-
-void
-strconv(char *o, Op *op, int f1, int f2)
-{
-	int n, c;
-	char *p;
-
-	n = strlen(o);
-	if(f1 >= 0)
-		while(n < f1) {
-			PUT(op, ' ');
-			n++;
-		}
-	for(p=o; c = *p++;)
-		if(f2 != 0) {
-			PUT(op, c);
-			f2--;
-		}
-	if(f1 < 0) {
-		f1 = -f1;
-		while(n < f1) {
-			PUT(op, ' ');
-			n++;
-		}
-	}
-}
-
-int
-numbconv(Op *op, int base)
-{
-	char b[IDIGIT];
-	int i, f, n, r;
-	long v;
-	short h;
-
-	f = 0;
-	switch(op->f3 & (FLONG|FSHORT|FUNSIGN)) {
-	case FLONG:
-		v = *(long*)op->argp;
-		r = LONG;
-		break;
-
-	case FUNSIGN|FLONG:
-		v = *(ulong*)op->argp;
-		r = LONG;
-		break;
-
-	case FSHORT:
-		h = *(int*)op->argp;
-		v = h;
-		r = SHORT;
-		break;
-
-	case FUNSIGN|FSHORT:
-		h = *(int*)op->argp;
-		v = (ushort)h;
-		r = SHORT;
-		break;
-
-	default:
-		v = *(int*)op->argp;
-		r = INT;
-		break;
-
-	case FUNSIGN:
-		v = *(unsigned*)op->argp;
-		r = INT;
-		break;
-	}
-	if(!(op->f3 & FUNSIGN) && v < 0) {
-		v = -v;
-		f = 1;
-	}
-	b[IDIGIT-1] = 0;
-	for(i = IDIGIT-2;; i--) {
-		n = (ulong)v % base;
-		n += '0';
-		if(n > '9'){
-			n += 'a' - ('9'+1);
-			if(ucase)
-				n += 'A'-'a';
-		}
-		b[i] = n;
-		if(i < 2)
-			break;
-		v = (ulong)v / base;
-		if(op->f2 >= 0 && i >= IDIGIT-op->f2)
-			continue;
-		if(v <= 0)
-			break;
-	}
-	if(f)
-		b[--i] = '-';
-	strconv(b+i, op, op->f1, -1);
-	return r;
-}
-
-static	int
-noconv(Op *op)
-{
-
-	strconv("***", op, 0, -1);
-	return 0;
-}
-
-static	int
-cconv(Op *op)
-{
-	char b[2];
-
-	b[0] = *(int*)op->argp;
-	b[1] = 0;
-	strconv(b, op, op->f1, -1);
-	return INT;
-}
-
-static	int
-dconv(Op *op)
-{
-	return numbconv(op, 10);
-}
-
-static	int
-hconv(Op*)
-{
-	return -FSHORT;
-}
-
-static	int
-lconv(Op*)
-{
-	return -FLONG;
-}
-
-static	int
-oconv(Op *op)
-{
-	return numbconv(op, 8);
-}
-
-static	int
-sconv(Op *op)
-{
-	strconv(*(char**)op->argp, op, op->f1, op->f2);
-	return PTR;
-}
-
-static	int
-uconv(Op*)
-{
-	return -FUNSIGN;
-}
-
-static	int
-xconv(Op *op)
-{
-	return numbconv(op, 16);
-}
-
-static	int
-Xconv(Op *op)
-{
-	int r;
-
-	ucase = 1;
-	r = numbconv(op, 16);
-	ucase = 0;
-	return r;
-}
-
-static	int
-percent(Op *op)
-{
-
-	PUT(op, '%');
-	return 0;
-}
--- a/os/boot/mpc/dosboot.c
+++ /dev/null
@@ -1,614 +1,0 @@
-#include	"u.h"
-#include	"lib.h"
-#include	"mem.h"
-#include	"dat.h"
-#include	"fns.h"
-#include	"dosfs.h"
-
-extern char *premature;
-
-/*
- *  predeclared
- */
-static void	bootdump(Dosboot*);
-static void	setname(Dosfile*, char*);
-long		dosreadseg(Dosfile*, long, long);
-
-/*
- *  debugging
- */
-#define chatty	1
-#define chat	if(chatty)print
-
-/*
- *  block io buffers
- */
-enum
-{
-	Nbio=	16,
-};
-typedef struct	Clustbuf	Clustbuf;
-struct Clustbuf
-{
-	int	age;
-	long	sector;
-	uchar	*iobuf;
-	Dos	*dos;
-	int	size;
-};
-Clustbuf	bio[Nbio];
-
-/*
- *  get an io block from an io buffer
- */
-Clustbuf*
-getclust(Dos *dos, long sector)
-{
-	Clustbuf *p, *oldest;
-	int size;
-
-	chat("getclust @ %d\n", sector);
-
-	/*
-	 *  if we have it, just return it
-	 */
-	for(p = bio; p < &bio[Nbio]; p++){
-		if(sector == p->sector && dos == p->dos){
-			p->age = m->ticks;
-			chat("getclust %d in cache\n", sector);
-			return p;
-		}
-	}
-
-	/*
-	 *  otherwise, reuse the oldest entry
-	 */
-	oldest = bio;
-	for(p = &bio[1]; p < &bio[Nbio]; p++){
-		if(p->age <= oldest->age)
-			oldest = p;
-	}
-	p = oldest;
-
-	/*
-	 *  make sure the buffer is big enough
-	 */
-	size = dos->clustsize*dos->sectsize;
-	if(p->iobuf==0 || p->size < size)
-		p->iobuf = ialloc(size, 0);
-	p->size = size;
-
-	/*
-	 *  read in the cluster
-	 */
-	chat("getclust addr %d\n", (sector+dos->start)*dos->sectsize);
-	if((*dos->seek)(dos->dev, (sector+dos->start)*dos->sectsize) < 0){
-		chat("can't seek block\n");
-		return 0;
-	}
-	if((*dos->read)(dos->dev, p->iobuf, size) != size){
-		chat("can't read block\n");
-		return 0;
-	}
-
-	p->age = m->ticks;
-	p->dos = dos;
-	p->sector = sector;
-	chat("getclust %d read\n", sector);
-	return p;
-}
-
-/*
- *  walk the fat one level ( n is a current cluster number ).
- *  return the new cluster number or -1 if no more.
- */
-static long
-fatwalk(Dos *dos, int n)
-{
-	ulong k, sect;
-	Clustbuf *p;
-	int o;
-
-	chat("fatwalk %d\n", n);
-
-	if(n < 2 || n >= dos->fatclusters)
-		return -1;
-
-	switch(dos->fatbits){
-	case 12:
-		k = (3*n)/2; break;
-	case 16:
-		k = 2*n; break;
-	default:
-		return -1;
-	}
-	if(k >= dos->fatsize*dos->sectsize)
-		panic("getfat");
-
-	sect = (k/(dos->sectsize*dos->clustsize))*dos->clustsize + dos->fataddr;
-	o = k%(dos->sectsize*dos->clustsize);
-	p = getclust(dos, sect);
-	k = p->iobuf[o++];
-	if(o >= dos->sectsize*dos->clustsize){
-		p = getclust(dos, sect+dos->clustsize);
-		o = 0;
-	}
-	k |= p->iobuf[o]<<8;
-	if(dos->fatbits == 12){
-		if(n&1)
-			k >>= 4;
-		else
-			k &= 0xfff;
-		if(k >= 0xff8)
-			k |= 0xf000;
-	}
-	k = k < 0xfff8 ? k : -1;
-	chat("fatwalk %d -> %d\n", n, k);
-	return k;
-}
-
-/*
- *  map a file's logical cluster address to a physical sector address
- */
-static long
-fileaddr(Dosfile *fp, long ltarget)
-{
-	Dos *dos = fp->dos;
-	long l;
-	long p;
-
-	chat("fileaddr %8.8s %d\n", fp->name, ltarget);
-	/*
-	 *  root directory is contiguous and easy
-	 */
-	if(fp->pstart == 0){
-		if(ltarget*dos->sectsize*dos->clustsize >= dos->rootsize*sizeof(Dosdir))
-			return -1;
-		l = dos->rootaddr + ltarget*dos->clustsize;
-		chat("fileaddr %d -> %d\n", ltarget, l);
-		return l;
-	}
-
-	/*
-	 *  anything else requires a walk through the fat
-	 */
-	if(ltarget >= fp->lcurrent && fp->pcurrent){
-		/* start at the currrent point */
-		l = fp->lcurrent;
-		p = fp->pcurrent;
-	} else {
-		/* go back to the beginning */
-		l = 0;
-		p = fp->pstart;
-	}
-	while(l != ltarget){
-		/* walk the fat */
-		p = fatwalk(dos, p);
-		if(p < 0)
-			return -1;
-		l++;
-	}
-	fp->lcurrent = l;
-	fp->pcurrent = p;
-
-	/*
-	 *  clusters start at 2 instead of 0 (why? - presotto)
-	 */
-	l =  dos->dataaddr + (p-2)*dos->clustsize;
-	chat("fileaddr %d -> %d\n", ltarget, l);
-	return l;
-}
-
-/*
- *  read from a dos file
- */
-long
-dosread(Dosfile *fp, void *a, long n)
-{
-	long addr;
-	long rv;
-	int i;
-	int off;
-	Clustbuf *p;
-	uchar *from, *to;
-
-	if((fp->attr & DDIR) == 0){
-		if(fp->offset >= fp->length)
-			return 0;
-		if(fp->offset+n > fp->length)
-			n = fp->length - fp->offset;
-	}
-
-	to = a;
-	for(rv = 0; rv < n; rv+=i){
-		/*
-		 *  read the cluster
-		 */
-		addr = fileaddr(fp, fp->offset/fp->dos->clustbytes);
-		if(addr < 0)
-			return -1;
-		p = getclust(fp->dos, addr);
-		if(p == 0)
-			return -1;
-
-		/*
-		 *  copy the bytes we need
-		 */
-		off = fp->offset % fp->dos->clustbytes;
-		from = &p->iobuf[off];
-		i = n - rv;
-		if(i > fp->dos->clustbytes - off)
-			i = fp->dos->clustbytes - off;
-		memmove(to, from, i);
-		to += i;
-		fp->offset += i;
-	}
-
-	return rv;
-}
-
-/*
- *  walk a directory returns
- * 	-1 if something went wrong
- *	 0 if not found
- *	 1 if found
- */
-int
-doswalk(Dosfile *file, char *name)
-{
-	Dosdir d;
-	long n;
-
-	if((file->attr & DDIR) == 0){
-		chat("walking non-directory!\n");
-		return -1;
-	}
-
-	setname(file, name);
-
-	file->offset = 0;	/* start at the beginning */
-	while((n = dosread(file, &d, sizeof(d))) == sizeof(d)){
-		chat("comparing to %8.8s.%3.3s\n", d.name, d.ext);
-		if(memcmp(file->name, d.name, sizeof(d.name)) != 0)
-			continue;
-		if(memcmp(file->ext, d.ext, sizeof(d.ext)) != 0)
-			continue;
-		if(d.attr & DVLABEL){
-			chat("%8.8s.%3.3s is a LABEL\n", d.name, d.ext);
-			continue;
-		}
-		file->attr = d.attr;
-		file->pstart = GSHORT(d.start);
-		file->length = GLONG(d.length);
-		file->pcurrent = 0;
-		file->lcurrent = 0;
-		file->offset = 0;
-		return 1;
-	}
-	return n >= 0 ? 0 : -1;
-}
-
-
-/*
- *  instructions that boot blocks can start with
- */
-#define	JMPSHORT	0xeb
-#define JMPNEAR		0xe9
-
-/*
- *  read dos file system properties
- */
-int
-dosinit(Dos *dos, int start, int ishard)
-{
-	Dosboot *b;
-	int i;
-	Clustbuf *p;
-	Dospart *dp;
-	ulong mbroffset, offset;
-
-	/* defaults till we know better */
-	dos->start = start;
-	dos->sectsize = 512;
-	dos->clustsize = 1;
-	mbroffset = 0;
-
-dmddo:
-	/* get first sector */
-	p = getclust(dos, mbroffset);
-	if(p == 0){
-		chat("can't read boot block\n");
-		return -1;
-	}
-
-	/*
-	 * If it's a hard disc then look for an MBR and pick either an
-	 * active partition or the FAT with the lowest starting LBA.
-	 * Things are tricky because we could be pointing to, amongst others:
-	 *	1) a floppy BPB;
-	 *	2) a hard disc MBR;
-	 *	3) a hard disc extended partition table;
-	 *	4) a logical drive on a hard disc;
-	 *	5) a disc-manager boot block.
-	 * They all have the same magic at the end of the block.
-	 */
-	if(p->iobuf[0x1FE] != 0x55 || p->iobuf[0x1FF] != 0xAA) {
-		chat("not DOS\n");
-		return -1;
-	}
-	p->dos = 0;
-	b = (Dosboot *)p->iobuf;
-	if(ishard && b->mediadesc != 0xF8){
-		dp = (Dospart*)&p->iobuf[0x1BE];
-		offset = 0xFFFFFFFF;
-		for(i = 0; i < 4; i++, dp++){
-			if(dp->type == DMDDO){
-				mbroffset = 63;
-				goto dmddo;
-			}
-			if(dp->type != FAT12 && dp->type != FAT16 && dp->type != FATHUGE)
-				continue;
-			if(dp->flag & 0x80){
-				offset = GLONG(dp->start);
-				break;
-			}
-			if(GLONG(dp->start) < offset)
-				offset = GLONG(dp->start);
-		}
-		if(i != 4 || offset != 0xFFFFFFFF){
-			dos->start = mbroffset+offset;
-			p = getclust(dos, 0);
-			if(p == 0 || p->iobuf[0x1FE] != 0x55 || p->iobuf[0x1FF] != 0xAA)
-				return -1;
-		}
-		p->dos = 0;
-	}
-
-	b = (Dosboot *)p->iobuf;
-	if(b->magic[0] != JMPNEAR && (b->magic[0] != JMPSHORT || b->magic[2] != 0x90)){
-		chat("no dos file system\n");
-		return -1;
-	}
-
-	if(chatty)
-		bootdump(b);
-
-	/*
-	 *  determine the systems' wondersous properties
-	 */
-	dos->sectsize = GSHORT(b->sectsize);
-	dos->clustsize = b->clustsize;
-	dos->clustbytes = dos->sectsize*dos->clustsize;
-	dos->nresrv = GSHORT(b->nresrv);
-	dos->nfats = b->nfats;
-	dos->rootsize = GSHORT(b->rootsize);
-	dos->volsize = GSHORT(b->volsize);
-	if(dos->volsize == 0)
-		dos->volsize = GLONG(b->bigvolsize);
-	dos->mediadesc = b->mediadesc;
-	dos->fatsize = GSHORT(b->fatsize);
-	dos->fataddr = dos->nresrv;
-	dos->rootaddr = dos->fataddr + dos->nfats*dos->fatsize;
-	i = dos->rootsize*sizeof(Dosdir) + dos->sectsize - 1;
-	i = i/dos->sectsize;
-	dos->dataaddr = dos->rootaddr + i;
-	dos->fatclusters = 2+(dos->volsize - dos->dataaddr)/dos->clustsize;
-	if(dos->fatclusters < 4087)
-		dos->fatbits = 12;
-	else
-		dos->fatbits = 16;
-	dos->freeptr = 2;
-
-	/*
-	 *  set up the root
-	 */
-	dos->root.dos = dos;
-	dos->root.pstart = 0;
-	dos->root.pcurrent = dos->root.lcurrent = 0;
-	dos->root.offset = 0;
-	dos->root.attr = DDIR;
-	dos->root.length = dos->rootsize*sizeof(Dosdir);
-
-	return 0;
-}
-
-static void
-bootdump(Dosboot *b)
-{
-	if(chatty == 0)
-		return;
-	print("magic: 0x%2.2x 0x%2.2x 0x%2.2x\n",
-		b->magic[0], b->magic[1], b->magic[2]);
-	print("version: \"%8.8s\"\n", b->version);
-	print("sectsize: %d\n", GSHORT(b->sectsize));
-	print("allocsize: %d\n", b->clustsize);
-	print("nresrv: %d\n", GSHORT(b->nresrv));
-	print("nfats: %d\n", b->nfats);
-	print("rootsize: %d\n", GSHORT(b->rootsize));
-	print("volsize: %d\n", GSHORT(b->volsize));
-	print("mediadesc: 0x%2.2x\n", b->mediadesc);
-	print("fatsize: %d\n", GSHORT(b->fatsize));
-	print("trksize: %d\n", GSHORT(b->trksize));
-	print("nheads: %d\n", GSHORT(b->nheads));
-	print("nhidden: %d\n", GLONG(b->nhidden));
-	print("bigvolsize: %d\n", GLONG(b->bigvolsize));
-	print("driveno: %d\n", b->driveno);
-	print("reserved0: 0x%2.2x\n", b->reserved0);
-	print("bootsig: 0x%2.2x\n", b->bootsig);
-	print("volid: 0x%8.8x\n", GLONG(b->volid));
-	print("label: \"%11.11s\"\n", b->label);
-}
-
-/*
- *  grab next element from a path, return the pointer to unprocessed portion of
- *  path.
- */
-static char *
-nextelem(char *path, char *elem)
-{
-	int i;
-
-	while(*path == '/')
-		path++;
-	if(*path==0 || *path==' ')
-		return 0;
-	for(i=0; *path!='\0' && *path!='/' && *path!=' '; i++){
-		if(i==28){
-			print("name component too long\n");
-			return 0;
-		}
-		*elem++ = *path++;
-	}
-	*elem = '\0';
-	return path;
-}
-
-int
-dosstat(Dos *dos, char *path, Dosfile *f)
-{
-	char element[NAMELEN];
-
-	*f = dos->root;
-	while(path = nextelem(path, element)){
-		switch(doswalk(f, element)){
-		case -1:
-			return -1;
-		case 0:
-			return 0;
-		}
-	}
-	return 1;
-}
-
-/*
- *  boot
- */
-int
-dosboot(Dos *dos, char *path)
-{
-	Dosfile file;
-	long n;
-	long addr;
-	Exec *ep;
-	void (*b)(void);
-
-	switch(dosstat(dos, path, &file)){
-
-	case -1:
-		print("error walking to %s\n", path);
-		return -1;
-	case 0:
-		print("%s not found\n", path);
-		return -1;
-	case 1:
-		print("found %8.8s.%3.3s attr 0x%ux start 0x%lux len %d\n", file.name,
-			file.ext, file.attr, file.pstart, file.length);
-		break;
-	}
-
-	/*
-	 *  read header
-	 */
-	ep = (Exec*)ialloc(sizeof(Exec), 0);
-	n = sizeof(Exec);
-	if(dosreadseg(&file, n, (ulong) ep) != n){
-		print(premature);
-		return -1;
-	}
-	if(GLLONG(ep->magic) != Q_MAGIC){
-		print("bad magic 0x%lux not a plan 9 executable!\n", GLLONG(ep->magic));
-		return -1;
-	}
-
-	/*
-	 *  read text
-	 */
-	addr = PADDR(GLLONG(ep->entry));
-	n = GLLONG(ep->text);
-	print("+%d", n);
-	if(dosreadseg(&file, n, addr) != n){
-		print(premature);
-		return -1;
-	}
-
-	/*
-	 *  read data (starts at first page after kernel)
-	 */
-	addr = PGROUND(addr+n);
-	n = GLLONG(ep->data);
-	print("+%d", n);
-	if(dosreadseg(&file, n, addr) != n){
-		print(premature);
-		return -1;
-	}
-
-	/*
-	 *  bss and entry point
-	 */
-	print("+%d\nstart at 0x%lux\n", GLLONG(ep->bss), GLLONG(ep->entry));
-
-	/*
-	 *  Go to new code. It's up to the program to get its PC relocated to
-	 *  the right place.
-	 */
-	b = (void (*)(void))(PADDR(GLLONG(ep->entry)));
-	(*b)();
-	return 0;
-}
-
-/*
- *  read in a segment
- */
-long
-dosreadseg(Dosfile *fp, long len, long addr)
-{
-	char *a;
-	long n, sofar;
-
-	a = (char *)addr;
-	for(sofar = 0; sofar < len; sofar += n){
-		n = 8*1024;
-		if(len - sofar < n)
-			n = len - sofar;
-		n = dosread(fp, a + sofar, n);
-		if(n <= 0)
-			break;
-		print(".");
-	}
-	return sofar;
-}
-
-/*
- *  set up a dos file name
- */
-static void
-setname(Dosfile *fp, char *from)
-{
-	char *to;
-
-	to = fp->name;
-	for(; *from && to-fp->name < 8; from++, to++){
-		if(*from == '.'){
-			from++;
-			break;
-		}
-		if(*from >= 'a' && *from <= 'z')
-			*to = *from + 'A' - 'a';
-		else
-			*to = *from;
-	}
-	while(to - fp->name < 8)
-		*to++ = ' ';
-	
-	to = fp->ext;
-	for(; *from && to-fp->ext < 3; from++, to++){
-		if(*from >= 'a' && *from <= 'z')
-			*to = *from + 'A' - 'a';
-		else
-			*to = *from;
-	}
-	while(to-fp->ext < 3)
-		*to++ = ' ';
-
-	chat("name is %8.8s %3.3s\n", fp->name, fp->ext);
-}
--- a/os/boot/mpc/dosfs.h
+++ /dev/null
@@ -1,110 +1,0 @@
-typedef struct Dosboot	Dosboot;
-typedef struct Dos	Dos;
-typedef struct Dosdir	Dosdir;
-typedef struct Dosfile	Dosfile;
-typedef struct Dospart	Dospart;
-
-struct Dospart
-{
-	uchar flag;		/* active flag */
-	uchar shead;		/* starting head */
-	uchar scs[2];		/* starting cylinder/sector */
-	uchar type;		/* partition type */
-	uchar ehead;		/* ending head */
-	uchar ecs[2];		/* ending cylinder/sector */
-	uchar start[4];		/* starting sector */
-	uchar len[4];		/* length in sectors */
-};
-
-#define FAT12	0x01
-#define FAT16	0x04
-#define FATHUGE	0x06
-#define DMDDO	0x54
-
-struct Dosboot{
-	uchar	magic[3];
-	uchar	version[8];
-	uchar	sectsize[2];
-	uchar	clustsize;
-	uchar	nresrv[2];
-	uchar	nfats;
-	uchar	rootsize[2];
-	uchar	volsize[2];
-	uchar	mediadesc;
-	uchar	fatsize[2];
-	uchar	trksize[2];
-	uchar	nheads[2];
-	uchar	nhidden[4];
-	uchar	bigvolsize[4];
-	uchar	driveno;
-	uchar	reserved0;
-	uchar	bootsig;
-	uchar	volid[4];
-	uchar	label[11];
-	uchar	reserved1[8];
-};
-
-struct Dosfile{
-	Dos	*dos;		/* owning dos file system */
-	char	name[8];
-	char	ext[3];
-	uchar	attr;
-	long	length;
-	long	pstart;		/* physical start cluster address */
-	long	pcurrent;	/* physical current cluster address */
-	long	lcurrent;	/* logical current cluster address */
-	long	offset;
-};
-
-struct Dos{
-	int	dev;				/* device id */
-	long	(*read)(int, void*, long);	/* read routine */
-	long	(*seek)(int, long);		/* seek routine */
-
-	int	start;		/* start of file system */
-	int	sectsize;	/* in bytes */
-	int	clustsize;	/* in sectors */
-	int	clustbytes;	/* in bytes */
-	int	nresrv;		/* sectors */
-	int	nfats;		/* usually 2 */
-	int	rootsize;	/* number of entries */
-	int	volsize;	/* in sectors */
-	int	mediadesc;
-	int	fatsize;	/* in sectors */
-	int	fatclusters;
-	int	fatbits;	/* 12 or 16 */
-	long	fataddr;	/* sector number */
-	long	rootaddr;
-	long	dataaddr;
-	long	freeptr;
-
-	Dosfile	root;
-};
-
-struct Dosdir{
-	uchar	name[8];
-	uchar	ext[3];
-	uchar	attr;
-	uchar	reserved[10];
-	uchar	time[2];
-	uchar	date[2];
-	uchar	start[2];
-	uchar	length[4];
-};
-
-#define	DRONLY	0x01
-#define	DHIDDEN	0x02
-#define	DSYSTEM	0x04
-#define	DVLABEL	0x08
-#define	DDIR	0x10
-#define	DARCH	0x20
-
-extern int chatty;
-
-extern int dosboot(Dos*, char*);
-extern int dosinit(Dos*, int, int);
-extern long dosread(Dosfile*, void*, long);
-extern int dosstat(Dos*, char*, Dosfile*);
-extern int doswalk(Dosfile*, char*);
-
-extern int plan9ini(Dos*, char*);
--- a/os/boot/mpc/etherif.h
+++ /dev/null
@@ -1,59 +1,0 @@
-/*
- * All the goo for PC ethernet cards.
- */
-typedef struct Card Card;
-typedef struct Type Type;
-typedef struct Ctlr Ctlr;
-
-/*
- * Hardware interface.
- */
-struct Card {
-	ISAConf;
-
-	int	(*reset)(Ctlr*);
-	void	(*attach)(Ctlr*);
-
-	void	*(*read)(Ctlr*, void*, ulong, ulong);
-	void	*(*write)(Ctlr*, ulong, void*, ulong);
-
-	void	(*receive)(Ctlr*);
-	void	(*transmit)(Ctlr*);
-	void	(*intr)(Ureg*, void*);
-	void	(*overflow)(Ctlr*);
-
-	uchar	bit16;			/* true if a 16 bit interface */
-	uchar	ram;			/* true if card has shared memory */
-
-	ulong	dp8390;			/* I/O address of 8390 (if any) */
-	ulong	data;			/* I/O data port if no shared memory */
-	uchar	nxtpkt;			/* software bndry */
-	uchar	tstart;			/* 8390 ring addresses */
-	uchar	pstart;
-	uchar	pstop;
-
-	uchar	dummyrr;		/* do dummy remote read */
-};
-
-/*
- * Software controller.
- */
-struct Ctlr {
-	Card	card;			/* hardware info */
-	int	ctlrno;
-	int	present;
-
-	Queue*	iq;
-	Queue*	oq;
-
-	int	inpackets;
-	int	outpackets;
-	int	crcs;			/* input crc errors */
-	int	oerrs;			/* output errors */
-	int	frames;			/* framing errors */
-	int	overflows;		/* packet overflows */
-	int	buffs;			/* buffering errors */
-};
-
-extern int sccethreset(Ctlr*);
-extern int	etheriq(Ctlr*, Block*, int);
--- a/os/boot/mpc/etherscc.c
+++ /dev/null
@@ -1,411 +1,0 @@
-/*
- * SCCn ethernet
- */
-
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-
-#include "etherif.h"
-
-enum {
-	Nrdre		= 32,	/* receive descriptor ring entries */
-	Ntdre		= 4,	/* transmit descriptor ring entries */
-
-	Rbsize		= ETHERMAXTU+4,		/* ring buffer size (+4 for CRC) */
-	Bufsize		= (Rbsize+7)&~7,	/* aligned */
-};
-
-enum {
-	/* ether-specific Rx BD bits */
-	RxMiss=		1<<8,
-	RxeLG=		1<<5,
-	RxeNO=		1<<4,
-	RxeSH=		1<<3,
-	RxeCR=		1<<2,
-	RxeOV=		1<<1,
-	RxeCL=		1<<0,
-	RxError=		(RxeLG|RxeNO|RxeSH|RxeCR|RxeOV|RxeCL),	/* various error flags */
-
-	/* ether-specific Tx BD bits */
-	TxPad=		1<<14,	/* pad short frames */
-	TxTC=		1<<10,	/* transmit CRC */
-	TxeDEF=		1<<9,
-	TxeHB=		1<<8,
-	TxeLC=		1<<7,
-	TxeRL=		1<<6,
-	TxeUN=		1<<1,
-	TxeCSL=		1<<0,
-
-	/* scce */
-	RXB=	1<<0,
-	TXB=	1<<1,
-	BSY=		1<<2,
-	RXF=		1<<3,
-	TXE=		1<<4,
-
-	/* gsmrl */
-	ENR=	1<<5,
-	ENT=	1<<4,
-
-	/* port A */
-	RXD1=	SIBIT(15),
-	TXD1=	SIBIT(14),
-
-	/* port B */
-	RTS1=	IBIT(19),
-
-	/* port C */
-	CTS1=	SIBIT(11),
-	CD1=	SIBIT(10),
-};
-
-typedef struct Etherparam Etherparam;
-struct Etherparam {
-	SCCparam;
-	ulong	c_pres;		/* preset CRC */
-	ulong	c_mask;		/* constant mask for CRC */
-	ulong	crcec;		/* CRC error counter */
-	ulong	alec;		/* alighnment error counter */
-	ulong	disfc;		/* discard frame counter */
-	ushort	pads;		/* short frame PAD characters */
-	ushort	ret_lim;	/* retry limit threshold */
-	ushort	ret_cnt;	/* retry limit counter */
-	ushort	mflr;		/* maximum frame length reg */
-	ushort	minflr;		/* minimum frame length reg */
-	ushort	maxd1;		/* maximum DMA1 length reg */
-	ushort	maxd2;		/* maximum DMA2 length reg */
-	ushort	maxd;		/* rx max DMA */
-	ushort	dma_cnt;	/* rx dma counter */
-	ushort	max_b;		/* max bd byte count */
-	ushort	gaddr[4];		/* group address filter */
-	ulong	tbuf0_data0;	/* save area 0 - current frm */
-	ulong	tbuf0_data1;	/* save area 1 - current frm */
-	ulong	tbuf0_rba0;
-	ulong	tbuf0_crc;
-	ushort	tbuf0_bcnt;
-	ushort	paddr[3];	/* physical address LSB to MSB increasing */
-	ushort	p_per;		/* persistence */
-	ushort	rfbd_ptr;	/* rx first bd pointer */
-	ushort	tfbd_ptr;	/* tx first bd pointer */
-	ushort	tlbd_ptr;	/* tx last bd pointer */
-	ulong	tbuf1_data0;	/* save area 0 - next frame */
-	ulong	tbuf1_data1;	/* save area 1 - next frame */
-	ulong	tbuf1_rba0;
-	ulong	tbuf1_crc;
-	ushort	tbuf1_bcnt;
-	ushort	tx_len;		/* tx frame length counter */
-	ushort	iaddr[4];		/* individual address filter*/
-	ushort	boff_cnt;	/* back-off counter */
-	ushort	taddr[3];	/* temp address */
-};
-
-typedef struct {
-	SCC*	scc;
-	int	port;
-	int	cpm;
-
-	BD*	rdr;				/* receive descriptor ring */
-	void*	rrb;				/* receive ring buffers */
-	int	rdrx;				/* index into rdr */
-
-	BD*	tdr;				/* transmit descriptor ring */
-	void*	trb;				/* transmit ring buffers */
-	int	tdrx;				/* index into tdr */
-} Mot;
-static Mot mot[MaxEther];
-
-static	int	sccid[] = {-1, SCC1ID, SCC2ID, SCC3ID, SCC4ID};
-static	int	sccparam[] = {-1, SCC1P, SCC2P, SCC3P, SCC4P};
-static	int	sccreg[] = {-1, 0xA00, 0xA20, 0xA40, 0xA60};
-static	int	sccirq[] = {-1, 0x1E, 0x1D, 0x1C, 0x1B};
-
-static void
-attach(Ctlr *ctlr)
-{
-	mot[ctlr->ctlrno].scc->gsmrl |= ENR|ENT;
-	eieio();
-}
-
-static void
-transmit(Ctlr *ctlr)
-{
-	int len;
-	Mot *motp;
-	Block *b;
-	BD *tdre;
-
-	motp = &mot[ctlr->ctlrno];
-	while(((tdre = &motp->tdr[motp->tdrx])->status & BDReady) == 0){
-		b = qget(ctlr->oq);
-		if(b == 0)
-			break;
-
-		/*
-		 * Copy the packet to the transmit buffer.
-		 */
-		len = BLEN(b);
-		memmove(KADDR(tdre->addr), b->rp, len);
-	
-		/*
-		 * Give ownership of the descriptor to the chip, increment the
-		 * software ring descriptor pointer and tell the chip to poll.
-		 */
-		tdre->length = len;
-		eieio();
-		tdre->status = (tdre->status & BDWrap) | BDReady|TxPad|BDInt|BDLast|TxTC;
-		eieio();
-		motp->scc->todr = 1<<15;	/* transmit now */
-		eieio();
-		motp->tdrx = NEXT(motp->tdrx, Ntdre);
-
-		freeb(b);
-	
-	}
-}
-
-static void
-interrupt(Ureg*, void *ap)
-{
-	int len, events, status;
-	Mot *motp;
-	BD *rdre;
-	Block *b;
-	Ctlr *ctlr;
-
-	ctlr = ap;
-	motp = &mot[ctlr->ctlrno];
-
-	/*
-	 * Acknowledge all interrupts and whine about those that shouldn't
-	 * happen.
-	 */
-	events = motp->scc->scce;
-	eieio();
-	motp->scc->scce = events;
-	eieio();
-	if(events & (TXE|BSY|RXB))
-		print("ETHER.SCC#%d: scce = 0x%uX\n", ctlr->ctlrno, events);
-	//print(" %ux|", events);
-	/*
-	 * Receiver interrupt: run round the descriptor ring logging
-	 * errors and passing valid receive data up to the higher levels
-	 * until we encounter a descriptor still owned by the chip.
-	 */
-	if(events & (RXF|RXB) || 1){
-		rdre = &motp->rdr[motp->rdrx];
-		while(((status = rdre->status) & BDEmpty) == 0){
-			if(status & RxError || (status & (BDFirst|BDLast)) != (BDFirst|BDLast)){
-				//if(status & RxBuff)
-				//	ctlr->buffs++;
-				if(status & (1<<2))
-					ctlr->crcs++;
-				if(status & (1<<1))
-					ctlr->overflows++;
-				//print("eth rx: %ux\n", status);
-				if(status & RxError)
-					print("~");
-				else if((status & BDLast) == 0)
-					print("@");
-			}
-			else{
-				/*
-				 * We have a packet. Read it into the next
-				 * free ring buffer, if any.
-				 */
-				len = rdre->length-4;
-				if((b = iallocb(len)) != 0){
-					memmove(b->wp, KADDR(rdre->addr), len);
-					b->wp += len;
-					etheriq(ctlr, b, 1);
-				}
-			}
-
-			/*
-			 * Finished with this descriptor, reinitialise it,
-			 * give it back to the chip, then on to the next...
-			 */
-			rdre->length = 0;
-			rdre->status = (rdre->status & BDWrap) | BDEmpty | BDInt;
-			eieio();
-
-			motp->rdrx = NEXT(motp->rdrx, Nrdre);
-			rdre = &motp->rdr[motp->rdrx];
-		}
-	}
-
-	/*
-	 * Transmitter interrupt: handle anything queued for a free descriptor.
-	 */
-	if(events & TXB)
-		transmit(ctlr);
-	if(events & TXE)
-		cpmop(RestartTx, motp->cpm, 0);
-}
-
-static void
-ringinit(Mot* motp)
-{
-	int i, x;
-
-	/*
-	 * Initialise the receive and transmit buffer rings. The ring
-	 * entries must be aligned on 16-byte boundaries.
-	 */
-	if(motp->rdr == 0)
-		motp->rdr = bdalloc(Nrdre);
-	if(motp->rrb == 0)
-		motp->rrb = ialloc(Nrdre*Bufsize, 0);
-	x = PADDR(motp->rrb);
-	for(i = 0; i < Nrdre; i++){
-		motp->rdr[i].length = 0;
-		motp->rdr[i].addr = x;
-		motp->rdr[i].status = BDEmpty|BDInt;
-		x += Bufsize;
-	}
-	motp->rdr[i-1].status |= BDWrap;
-	motp->rdrx = 0;
-
-	if(motp->tdr == 0)
-		motp->tdr = bdalloc(Ntdre);
-	if(motp->trb == 0)
-		motp->trb = ialloc(Ntdre*Bufsize, 0);
-	x = PADDR(motp->trb);
-	for(i = 0; i < Ntdre; i++){
-		motp->tdr[i].addr = x;
-		motp->tdr[i].length = 0;
-		motp->tdr[i].status = TxPad|BDInt|BDLast|TxTC;
-		x += Bufsize;
-	}
-	motp->tdr[i-1].status |= BDWrap;
-	motp->tdrx = 0;
-}
-
-/*
- * This follows the MPC823 user guide: section16.9.23.7's initialisation sequence,
- * except that it sets the right bits for the MPC823ADS board when SCC2 is used,
- * and those for the 860/821 development board for SCC1.
- */
-static void
-sccsetup(Mot *ctlr, SCC *scc, uchar *ea)
-{
-	int i, rcs, tcs, w;
-	Etherparam *p;
-	IMM *io;
-
-
-	i = 2*(ctlr->port-1);
-	io = ioplock();
-	w = (TXD1|RXD1)<<i;	/* TXDn and RXDn in port A */
-	io->papar |= w;	/* enable TXDn and RXDn pins */
-	io->padir &= ~w;
-	io->paodr &= ~w;	/* not open drain */
-
-	w = (CD1|CTS1)<<i;	/* CLSN and RENA: CDn and CTSn in port C */
-	io->pcpar &= ~w;	/* enable CLSN (CTSn) and RENA (CDn) */
-	io->pcdir &= ~w;
-	io->pcso |= w;
-	iopunlock();
-
-	/* clocks and transceiver control: details depend on the board's wiring */
-	archetherenable(ctlr->cpm, &rcs, &tcs);
-
-	sccnmsi(ctlr->port, rcs, tcs);	/* connect the clocks */
-
-	p = (Etherparam*)KADDR(sccparam[ctlr->port]);
-	memset(p, 0, sizeof(*p));
-	p->rfcr = 0x18;
-	p->tfcr = 0x18;
-	p->mrblr = Bufsize;
-	p->rbase = PADDR(ctlr->rdr);
-	p->tbase = PADDR(ctlr->tdr);
-
-	cpmop(InitRxTx, ctlr->cpm, 0);
-
-	p->c_pres = ~0;
-	p->c_mask = 0xDEBB20E3;
-	p->crcec = 0;
-	p->alec = 0;
-	p->disfc = 0;
-	p->pads = 0x8888;
-	p->ret_lim = 0xF;
-	p->mflr = Rbsize;
-	p->minflr = ETHERMINTU+4;
-	p->maxd1 = Bufsize;
-	p->maxd2 = Bufsize;
-	p->p_per = 0;	/* only moderate aggression */
-
-	for(i=0; i<Eaddrlen; i+=2)
-		p->paddr[2-i/2] = (ea[i+1]<<8)|ea[i];	/* it's not the obvious byte order */
-
-	scc->psmr = (2<<10)|(5<<1);	/* 32-bit CRC, ignore 22 bits before SFD */
-	scc->dsr = 0xd555;
-	scc->gsmrh = 0;	/* normal operation */
-	scc->gsmrl = (1<<28)|(4<<21)|(1<<19)|0xC;	/* transmit clock invert, 48 bit preamble, repetitive 10 preamble, ethernet */
-	eieio();
-	scc->scce = ~0;	/* clear all events */
-	eieio();
-	scc->sccm = TXE | RXF | TXB;	/* enable interrupts */
-	eieio();
-
-	io = ioplock();
-	w = RTS1<<(ctlr->port-1);	/* enable TENA pin (RTSn) */
-	io->pbpar |= w;
-	io->pbdir |= w;
-	iopunlock();
-
-	/* gsmrl enable is deferred until attach */
-}
-
-/*
- * Prepare the SCCx ethernet for booting.
- */
-int
-sccethreset(Ctlr* ctlr)
-{
-	uchar ea[Eaddrlen];
-	Mot *motp;
-	SCC *scc;
-	char line[50], def[50];
-
-	/*
-	 * Since there's no EPROM, insist that the configuration entry
-	 * (see conf.c and flash.c) holds the Ethernet address.
-	 */
-	memset(ea, 0, Eaddrlen);
-	if(memcmp(ea, ctlr->card.ea, Eaddrlen) == 0){
-		print("no preset Ether address\n");
-		for(;;){
-			strcpy(def, "00108bf12900");	/* valid MAC address to be used only for initial configuration */
-			if(getstr("ether MAC address", line, sizeof(line), def) < 0)
-				return -1;
-			if(parseether(ctlr->card.ea, line) >= 0 || ctlr->card.ea[0] == 0xFF)
-				break;
-			print("invalid MAC address\n");
-		}
-	}
-
-	scc = IOREGS(sccreg[ctlr->card.port], SCC);
-	ctlr->card.irq = VectorCPIC+sccirq[ctlr->card.port];
-
-	motp = &mot[ctlr->ctlrno];
-	motp->scc = scc;
-	motp->port = ctlr->card.port;
-	motp->cpm = sccid[ctlr->card.port];
-
-	ringinit(motp);
-
-	sccsetup(motp, scc, ctlr->card.ea);
-
-	/* enable is deferred until attach */
-
-	ctlr->card.reset = sccethreset;
-	ctlr->card.attach = attach;
-	ctlr->card.transmit = transmit;
-	ctlr->card.intr = interrupt;
-
-	return 0;
-}
--- a/os/boot/mpc/fblt.c
+++ /dev/null
@@ -1,531 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include <libg.h>
-#include <gnot.h>
-
-/*
- * bitblt operates a 'word' at a time.
- * WBITS is the number of bits in a word
- * LWBITS=log2(WBITS),
- * W2L is the number of words in a long
- * WMASK has bits set for the low order word of a long
- * WType is a pointer to a word
- */
-#ifndef WBITS
-#define WBITS	32
-#define LWBITS	5
-#define	W2L	1
-#define WMASK	~0UL
-typedef ulong	*WType;
-#endif
-
-#define DEBUG 
-
-#ifdef TEST
-/*
- * globals used for testing
- */
-int	FORCEFORW;
-int	FORCEBAKW;
-GBitmap	*curdm, *cursm;
-Point	curpt;
-Rectangle curr;
-Fcode	curf;
-void	*mem;
-#endif
-
-static void
-gbitexplode(ulong sw, ulong *buf, int sdep, int x)
-{
-	int j, o, q, n, nw, inc, qinc;
-	ulong s, dw, pix;
-
-	inc = 1 << sdep;
-	pix = (1 << inc) - 1;
-	nw = 1 << x;
-	n = 32 >> x;
-	qinc = (nw << sdep) - inc;
-	for(o = 32 - n; o >= 0; o -= n){
-		dw = 0;
-		s = sw >> o;
-		q = 0;
-		for(j = 0; j < n; j += inc){
-			dw |= (s & (pix << j)) << q;
-			q += qinc;
-		}
-		for(j = 0; j < x; j++)
-			dw |= dw << (inc << j);
-		*buf++ = dw;
-	}
-}
-
-/*
-void
-main(void)
-{
-	ulong buf[128];
-
-	gbitexplode(0x7777, buf, 0, 3);
-	exits(0);
-}
-*/
-
-void
-gbitblt(GBitmap *dm, Point pt, GBitmap *sm, Rectangle r, Fcode fcode)
-{
-	int	width;		/* width in bits of dst */
-	int	wwidth;		/* floor width in words */
-	int	height;		/* height in pixels minus 1 */
-	int	sdep;		/* src ldepth */
-	int 	ddep;		/* dst ldepth */
-	int	deltadep;	/* diff between ldepths */
-	int	sspan;		/* words between scanlines in src */
-	int	dspan;		/* words between scanlines in dst */
-	int	soff;		/* bit offset of src start point */
-	int	sdest;		/* bit offset of src start point that matches doff when expanded */
-	int	doff;		/* bit offset of dst start point */
-	int	delta;		/* amount to shift src by */
-	int	sign;		/* of delta */
-	ulong	*saddr;
-	ulong	*daddr;
-	ulong	*s;
-	ulong	*d;
-	ulong	mask;
-	ulong	tmp;		/* temp storage source word */
-	ulong	sw;		/* source word constructed */
-	ulong	dw;		/* dest word fetched */
-	ulong	lmask;		/* affected pixels in leftmost dst word */
-	ulong	rmask;		/* affected pixels in rightmost dst word */
-	int	i;
-	int	j;
-	ulong	buf[32];	/* for expanding a source */
-	ulong	*p;		/* pointer into buf */
-	int	spare;		/* number of words already converted */
-
-
-#ifdef TEST
-	curdm = dm;
-	cursm = sm;
-	curpt = pt;
-	curr = r;
-	curf = fcode;
-#endif
-
-	gbitbltclip(&dm);
-
-	width = r.max.x - r.min.x;
-	if(width <= 0)
-		return;
-	height = r.max.y - r.min.y - 1;
-	if(height < 0)
-		return;
-
-	ddep = dm->ldepth;
-	pt.x <<= ddep;
-	width <<= ddep;
-
-	sdep = sm->ldepth;
-	r.min.x <<= sdep;
-	r.max.x <<= sdep;
-
-	dspan = dm->width * W2L;
-	sspan = sm->width * W2L;
-
-	daddr = (ulong*)((WType)dm->base
-			+ dm->zero*W2L + pt.y*dspan
-			+ (pt.x >> LWBITS));
-	saddr = (ulong*)((WType)sm->base
-			+ sm->zero*W2L + r.min.y*sspan
-			+ (r.min.x >> LWBITS));
-
-	doff = pt.x & (WBITS - 1);
-	lmask = WMASK >> doff;
-	rmask = (WMASK << (WBITS - ((doff+width) & (WBITS-1))))&WMASK;
-	if(!rmask)
-		rmask = WMASK;
-	soff = r.min.x & (WBITS-1);
-	wwidth = ((pt.x+width-1)>>LWBITS) - (pt.x>>LWBITS);
-
-	if(sm == dm){
-#ifdef TEST
-		if(!FORCEBAKW &&
-		   (FORCEFORW || sm != dm || saddr > daddr ||
-		    (saddr == daddr && soff > doff)))
-			;
-		else{
-			daddr += height * dspan;
-			saddr += height * sspan;
-			sspan -= 2 * W2L * sm->width;
-			dspan -= 2 * W2L * dm->width;
-		}
-#else
-		if(r.min.y < pt.y){	/* bottom to top */
-			daddr += height * dspan;
-			saddr += height * sspan;
-			sspan -= 2 * W2L * sm->width;
-			dspan -= 2 * W2L * dm->width;
-		}else if(r.min.y == pt.y && r.min.x < pt.x)
-			abort()/*goto right*/;
-#endif
-	}
-	if(wwidth == 0)		/* collapse masks for narrow cases */
-		lmask &= rmask;
-	fcode &= F;
-
-	deltadep = ddep - sdep;
-	sdest = doff >> deltadep;
-	delta = soff - sdest;
-	sign = 0;
-	if(delta < 0){
-		sign = 1;
-		delta = -delta;
-	}
-
-	p = 0;
-	for(j = 0; j <= height; j++){
-		d = daddr;
-		s = saddr;
-		mask = lmask;
-		tmp = 0;
-		if(!sign)
-			tmp = *s++;
-		spare = 0;
-		for(i = wwidth; i >= 0; i--){
-			if(spare)
-				sw = *p++;
-			else{
-				if(sign){
-					sw = tmp << (WBITS-delta);
-					tmp = *s++;
-					sw |= tmp >> delta;
-				}else{
-					sw = tmp << delta;
-					tmp = *s++;
-					if(delta)
-						sw |= tmp >> (WBITS-delta);
-				}
-				spare = 1 << deltadep;
-				if(deltadep >= 1){
-					gbitexplode(sw, buf, sdep, deltadep);
-					p = buf;
-					sw = *p++;
-				}
-			}
-
-			dw = *d;
-			switch(fcode){		/* ltor bit aligned */
-			case Zero:	*d = dw & ~mask;		break;
-			case DnorS:	*d = dw ^ ((~sw | dw) & mask);	break;
-			case DandnotS:	*d = dw ^ ((sw & dw) & mask);	break;
-			case notS:	*d = dw ^ ((~sw ^ dw) & mask);	break;
-			case notDandS:	*d = dw ^ ((sw | dw) & mask);	break;
-			case notD:	*d = dw ^ mask;			break;
-			case DxorS:	*d = dw ^ (sw & mask);		break;
-			case DnandS:	*d = dw ^ ((sw | ~dw) & mask);	break;
-			case DandS:	*d = dw ^ ((~sw & dw) & mask);	break;
-			case DxnorS:	*d = dw ^ (~sw & mask);		break;
-			case D:						break;
-			case DornotS:	*d = dw | (~sw & mask);		break;
-			case S:		*d = dw ^ ((sw ^ dw) & mask);	break;
-			case notDorS:	*d = dw ^ (~(sw & dw) & mask);	break;
-			case DorS:	*d = dw | (sw & mask);		break;
-			case F:		*d = dw | mask;			break;
-			}
-			d++;
-
-			mask = WMASK;
-			if(i == 1)
-				mask = rmask;
-			spare--;
-		}
-		saddr += sspan;
-		daddr += dspan;
-	}
-}
-
-#ifdef TEST
-void	prprog(void);
-GBitmap *bb1, *bb2;
-ulong	*src, *dst, *xdst, *xans;
-int	swds, dwds;
-long	ticks;
-int	timeit;
-
-long
-func(int f, long s, int sld, long d, int dld)
-{
-	long a;
-	int sh, i, db, sb;
-
-	db = 1 << dld;
-	sb = 1 << sld;
-	sh = db - sb;
-	if(sh > 0) {
-		a = s;
-		for(i = sb; i<db; i += sb){
-			a <<= sb;
-			s |= a;
-		}
-	} else if(sh < 0)
-		s >>= -sh;
-
-	switch(f){
-	case Zero:	d = 0;			break;
-	case DnorS:	d = ~(d|s);		break;
-	case DandnotS:	d = d & ~s;		break;
-	case notS:	d = ~s;			break;
-	case notDandS:	d = ~d & s;		break;
-	case notD:	d = ~d;			break;
-	case DxorS:	d = d ^ s;		break;
-	case DnandS:	d = ~(d&s);		break;
-	case DandS:	d = d & s;		break;
-	case DxnorS:	d = ~(d^s);		break;
-	case S:		d = s;			break;
-	case DornotS:	d = d | ~s;		break;
-	case D:		d = d;			break;
-	case notDorS:	d = ~d | s;		break;
-	case DorS:	d = d | s;		break;
-	case F:		d = ~0;			break;
-	}
-
-	d &= ((1<<db)-1);
-	return d;
-}
-
-void
-run(int fr, int to, int w, int op)
-{
-	int i, j, f, t, fy, ty;
-	extern long *_clock;
-
-	fr += bb2->r.min.x;
-	to += bb1->r.min.x;
-	fy = bb2->r.min.y + 1;
-	ty = bb1->r.min.y + 1;
-	if(timeit) {
-		memcpy(dst, xdst, dwds * sizeof(long));
-		ticks -= *_clock;
-		gbitblt(bb1, Pt(to,ty), bb2, Rect(fr,fy,fr+w,fy+2), op);
-		ticks += *_clock;
-		return;
-	}
-	f = fr;
-	t = to;
-	memcpy(dst, xdst, dwds * sizeof(long));
-	for(i=0; i<w; i++) {
-		gbitblt(bb1, Pt(t,ty), bb2, Rect(f,fy,f+1,fy+1), op);
-		gbitblt(bb1, Pt(t,ty+1), bb2, Rect(f,fy+1,f+1,fy+2), op);
-		f++;
-		t++;
-	}
-	memcpy(xans, dst, dwds * sizeof(long));
-
-	memcpy(dst, xdst, dwds * sizeof(long));
-	gbitblt(bb1, Pt(to,ty), bb2, Rect(fr,fy,fr+w,fy+2), op);
-
-	if(memcmp(xans, dst, dwds * sizeof(long))) {
-		/*
-		 * print src and dst row offset, width in bits, and forw/back
-		 * then print for each of the four rows: the source (s),
-		 * the dest (d), the good value of the answer (g),
-		 * and the actual bad value of the answer (b)
-		 */
-		print("fr=%d to=%d w=%d fb=%d%d\n",
-			fr, to, w, FORCEFORW, FORCEBAKW);
-		print("dst bitmap b %#lux, z %d, w %d, ld %d, r [%d,%d][%d,%d]\n",
-			bb1->base, bb1->zero, bb1->width, bb1->ldepth,
-			bb1->r.min.x, bb1->r.min.y, bb1->r.max.x, bb1->r.max.y);
-		print("src bitmap b %#lux, z %d, w %d, ld %d, r [%d,%d][%d,%d]\n",
-			bb2->base, bb2->zero, bb2->width, bb2->ldepth,
-			bb2->r.min.x, bb2->r.min.y, bb2->r.max.x, bb2->r.max.y);
-		for(j=0; 7*j < dwds; j++) {
-			print("\ns");
-			for(i=0; i<7 && 7*j+i < dwds; i++)
-				print(" %.8lux", src[7*j + i]);
-			print("\nd");
-			for(i=0; i<7 && 7*j+i < dwds; i++)
-				print(" %.8lux", xdst[7*j + i]);
-			print("\ng");
-			for(i=0; i<7 && 7*j+i < dwds; i++)
-				print(" %.8lux", xans[7*j + i]);
-			print("\nb");
-			for(i=0; i<7 && 7*j+i < dwds; i++)
-				print(" %.8lux", dst[7*j + i]);
-			print("\n");
-		}
-		prprog();
-	}
-}
-
-void
-prprog(void)
-{
-	exits(0);
-}
-
-int
-main(int argc, char *argv[])
-{
-	int f, t, w, i, sld, dld, op, iters, simple;
-	ulong s, d, spix, dpix, apix, fpix, m, *ps, *pd;
-	Point sorg, dorg;
-	GBitmap *bs, *bd;
-	long seed;
-	char *ct;
-
-	sld = 0;
-	dld = 0;
-	timeit = 0;
-	iters = 200;
-	simple = 0;
-	ARGBEGIN {
-	case 'i':
-		iters = atoi(ARGF());
-		break;
-	case 's':
-		simple = 1;
-		break;
-	case 't':
-		timeit = 1;
-		ct = ARGF();
-		if(ct)
-			iters = atoi(ct);
-		break;
-	} ARGEND
-	if(argc > 0)
-		sld = atoi(argv[0]);
-	if(argc > 1)
-		dld = atoi(argv[1]);
-	if(!timeit && !simple) {
-		seed = time(0);
-		print("seed %lux\n", seed); srand(seed);	/**/
-	}
-
-	print("sld %d dld %d\n", sld, dld);
-	op = 1;
-
-	/* bitmaps for 1-bit tests */
-	bd = gballoc(Rect(0,0,32,1), dld);
-	bs = gballoc(Rect(0,0,32,1), sld);
-	for(i=0; i<bs->width; i++)
-		bs->base[i] = lrand();
-
-	/* bitmaps for rect tests */
-	if(simple) {
-		dorg = Pt(0,0);
-		sorg = Pt(0,0);
-	} else {
-		dorg = Pt(nrand(63)-31,nrand(63)-31);
-		sorg = Pt(nrand(63)-31,nrand(63)-31);
-	}
-	bb1 = gballoc(Rpt(dorg,add(dorg,Pt(200,4))), dld);
-	bb2 = gballoc(Rpt(sorg,add(sorg,Pt(200,4))), sld);
-	dwds = bb1->width * Dy(bb1->r);
-	swds = bb2->width * Dy(bb2->r);
-	dst = bb1->base;
-	src = bb2->base;
-	xdst = malloc(dwds * sizeof(long));
-	xans =  malloc(dwds * sizeof(long));
-	for(i=0; i<swds; i++)
-		src[i] = lrand();
-	for(i=0; i<dwds; i++)
-		xdst[i] = lrand();
-
-loop:
-	print("Op %d\n", op);
-	if(!timeit) {
-		print("one pixel\n");
-		ps = bs->base;
-		pd = bd->base;
-		FORCEFORW = 1;
-		FORCEBAKW = 0;
-		for(i=0; i<1000; i++, FORCEFORW = !FORCEFORW, FORCEBAKW = !FORCEBAKW) {
-			f = nrand(32 >> sld);
-			t = nrand(32 >> dld);
-			s = lrand();
-			d = lrand();
-			ps[0] = s;
-			pd[0] = d;
-#ifdef T386
-			spix = (byterev(s) >> (32 - ((f+1)<<sld))) & ((1 << (1<<sld)) - 1);
-			dpix = (byterev(d) >> (32 - ((t+1)<<dld))) & ((1 << (1<<dld)) - 1);
-#else
-			spix = (s >> (32 - ((f+1)<<sld))) & ((1 << (1<<sld)) - 1);
-			dpix = (d >> (32 - ((t+1)<<dld))) & ((1 << (1<<dld)) - 1);
-#endif
-#ifdef T386
-			apix = byterev(func(op, spix, sld, dpix, dld) << (32 - ((t+1)<<dld)));
-#else
-			apix = func(op, spix, sld, dpix, dld) << (32 - ((t+1)<<dld));
-#endif
-			gbitblt(bd, Pt(t,0), bs, Rect(f,0,f+1,1), op);
-			if(ps[0] != s) {
-				print("bb src %.8lux %.8lux %d %d\n", ps[0], s, f, t);
-				exits("error");
-			}
-			m = ((1 << (1<<dld)) - 1) << (32 - ((t+1)<<dld));
-#ifdef T386
-			m = byterev(m);
-#endif
-			if((pd[0] & ~m) != (d & ~m)) {
-					print("bb dst1 %.8lux %.8lux\n",
-						s, d);
-					print("bb      %.8lux %.8lux %d %d\n",
-						ps[0], pd[0], f, t);
-					prprog();
-					exits("error");
-			}
-			if((pd[0] & m) != apix) {
-				spix <<= 32 - ((f+1)<<sld);
-				dpix <<= 32 - ((t+1)<<dld);
-#ifdef T386
-				spix = byterev(spix);
-				dpix = byterev(dpix);
-#endif
-				print("bb dst2 %.8lux %.8lux\n",
-					s, d);
-				print("bb      %.8lux %.8lux %d %d\n",
-					ps[0], pd[0], f, t);
-				print("bb      %.8lux %.8lux %.8lux %.8lux\n",
-					spix, dpix, apix, pd[0] & m);
-				prprog();
-				exits("error");
-			}
-		}
-	}
-
-	print("for\n");
-	FORCEFORW = 1;
-	FORCEBAKW = 0;
-
-	for(i=0; i<iters; i++) {
-		f = nrand(64);
-		t = nrand(64);
-		w = nrand(130);
-		run(f, t, w, op);
-	}
-
-	if(sld == dld) {
-		print("bak\n");
-		FORCEFORW = 0;
-		FORCEBAKW = 1;
-	
-		for(i=0; i<iters; i++) {
-			f = nrand(64);
-			t = nrand(64);
-			w = nrand(130);
-			run(f, t, w, op);
-		}
-	}
-
-	if(op < F) {
-		op++;
-		goto loop;
-	}
-	if(timeit)
-		print("time: %d ticks\n", ticks);
-	exits(0);
-}
-
-
-#endif
--- a/os/boot/mpc/flash.c
+++ /dev/null
@@ -1,212 +1,0 @@
-#include "boot.h"
-
-typedef struct Flashdev Flashdev;
-struct Flashdev {
-	uchar*	base;
-	int	size;
-	uchar*	exec;
-	char*	config;
-	int	conflen;
-};
-
-enum {
-	FLASHSEG = 256*1024,
-	CONFIGLIM = FLASHSEG,
-	BOOTOFF = FLASHSEG,
-	BOOTLEN = 3*FLASHSEG,	/* third segment might be filsys */
-	/* rest of flash is free */
-};
-
-static Flashdev flash;
-
-/*
- * configuration data is written between the bootstrap and
- * the end of region 0. the region ends with allocation descriptors
- * of the following form:
- *
- * byte order is big endian
- *
- * the last valid region found that starts with the string "#plan9.ini\n" is plan9.ini
- */
-typedef struct Flalloc Flalloc;
-struct Flalloc {
-	ulong	check;	/* checksum of data, or ~0 */
-	ulong	base;	/* base of region; ~0 if unallocated, 0 if deleted */
-	uchar	len[3];
-	uchar	tag;		/* see below */
-	uchar	sig[4];
-};
-
-enum {
-	/* tags */
-	Tdead=	0,
-	Tboot=	0x01,	/* space reserved for boot */
-	Tconf=	0x02,	/* configuration data */
-	Tnone=	0xFF,
-
-	Noval=	~0,
-};
-
-static char flashsig[] = {0xF1, 0xA5, 0x5A, 0x1F};
-static char conftag[] = "#plan9.ini\n";
-
-static ulong
-checksum(uchar* p, int n)
-{
-	ulong s;
-
-	for(s=0; --n >= 0;)
-		s += *p++;
-	return s;
-}
-
-static int
-validptr(Flalloc *ap, uchar *p)
-{
-	return p > (uchar*)&end && p < (uchar*)ap;
-}
-
-static int
-flashcheck(Flalloc *ap, char **val, int *len)
-{
-	uchar *base;
-	int n;
-
-	if(ap->base == Noval || ap->base >= FLASHSEG || ap->tag == Tnone)
-		return 0;
-	base = flash.base+ap->base;
-	if(!validptr(ap, base))
-		return 0;
-	n = (((ap->len[0]<<8)|ap->len[1])<<8)|ap->len[2];
-	if(n == 0xFFFFFF)
-		n = 0;
-	if(n < 0)
-		return 0;
-	if(n > 0 && !validptr(ap, base+n-1))
-		return 0;
-	if(ap->check != Noval && checksum(base, n) != ap->check){
-		print("flash: bad checksum\n");
-		return 0;
-	}
-	*val = (char*)base;
-	*len = n;
-	return 1;
-}
-
-int
-flashinit(void)
-{
-	int len;
-	char *val;
-	Flalloc *ap;
-	void *addr;
-	long mbytes;
-	char type[20];
-
-	flash.base = 0;
-	flash.exec = 0;
-	flash.size = 0;
-	if(archflashreset(type, &addr, &mbytes) < 0){
-		print("flash: flash not present or not enabled\n");	/* shouldn't happen */
-		return 0;
-	}
-	flash.size = mbytes;
-	flash.base = addr;
-	flash.exec = flash.base + BOOTOFF;
-	flash.config = nil;
-	flash.conflen = 0;
-
-	for(ap = (Flalloc*)(flash.base+CONFIGLIM)-1; memcmp(ap->sig, flashsig, 4) == 0; ap--){
-		if(0)
-			print("conf #%8.8lux: #%x #%6.6lux\n", ap, ap->tag, ap->base);
-		if(ap->tag == Tconf &&
-		   flashcheck(ap, &val, &len) &&
-		   len >= sizeof(conftag)-1 &&
-		   memcmp(val, conftag, sizeof(conftag)-1) == 0){
-			flash.config = val;
-			flash.conflen = len;
-			if(0)
-				print("flash: found config %8.8lux(%d):\n%s\n", val, len, val);
-		}
-	}
-	if(flash.config == nil)
-		print("flash: no config\n");
-	else
-		print("flash config %8.8lux(%d):\n%s\n", flash.config, flash.conflen, flash.config);
-	if(issqueezed(flash.exec) == Q_MAGIC){
-		print("flash: squeezed powerpc kernel installed\n");
-		return 1<<0;
-	}
-	if(GLLONG(flash.exec) == Q_MAGIC){
-		print("flash: unsqueezed powerpc kernel installed\n");
-		return 1<<0;
-	}
-	flash.exec = 0;
-	print("flash: no powerpc kernel in Flash\n");
-	return 0;
-}
-
-char*
-flashconfig(int)
-{
-	return flash.config;
-}
-
-int
-flashbootable(int)
-{
-	return flash.exec != nil && (issqueezed(flash.exec) || GLLONG(flash.exec) == Q_MAGIC);
-}
-
-int
-flashboot(int)
-{
-	ulong entry, addr;
-	void (*b)(void);
-	Exec *ep;
-	Block in;
-	long n;
-	uchar *p;
-
-	if(flash.exec == 0)
-		return -1;
-	p = flash.exec;
-	if(GLLONG(p) == Q_MAGIC){
-		/* unsqueezed: copy data and perhaps text, then jump to it */
-		ep = (Exec*)p;
-		entry = PADDR(GLLONG(ep->entry));
-		p += sizeof(Exec);
-		addr = entry;
-		n = GLLONG(ep->text);
-		if(addr != (ulong)p){
-			memmove((void*)addr, p, n);
-			print("text: %8.8lux <- %8.8lux [%ld]\n", addr, p, n);
-		}
-		p += n;
-		if(entry >= FLASHMEM)
-			addr = 3*BY2PG;	/* kernel text is in Flash, data in RAM */
-		else
-			addr = PGROUND(addr+n);
-		n = GLLONG(ep->data);
-		memmove((void*)addr, p, n);
-		print("data: %8.8lux <- %8.8lux [%ld]\n", addr, p, n);
-	}else{
-		in.data = p;
-		in.rp = in.data;
-		in.lim = p+BOOTLEN;
-		in.wp = in.lim;
-		n = unsqueezef(&in, &entry);
-		if(n < 0)
-			return -1;
-	}
-	print("entry=0x%lux\n", entry);
-	uartwait();
-	scc2stop();
-	/*
-	 *  Go to new code. It's up to the program to get its PC relocated to
-	 *  the right place.
-	 */
-	b = (void (*)(void))KADDR(PADDR(entry));
-	(*b)();
-	return -1;
-}
--- a/os/boot/mpc/fns.h
+++ /dev/null
@@ -1,117 +1,0 @@
-Alarm*	alarm(int, void (*)(Alarm*), void*);
-void	alarminit(void);
-void	archbacklight(int);
-char*	archconfig(void);
-void	archdisableuart(int);
-void	archenableuart(int, int);
-void	archenableusb(int);
-void	archetherdisable(int);
-int	archetherenable(int, int*, int*);
-int	archflashreset(char*, void**, long*);
-void	archinit(void);
-int	archoptionsw(void);
-int	bootp(int, char*);
-void	cancel(Alarm*);
-void	checkalarms(void);
-void	clockinit(void);
-void	clockintr(Ureg*, void*);
-void	consinit(void);
-void	cpminit(void);
-void	cpuidprint(void);
-#define	dcflush(a,b)
-void	delay(int);
-void	eieio(void);
-uchar*	etheraddr(int);
-int	etherinit(void);
-int	etherrxpkt(int, Etherpkt*, int);
-int	ethertxpkt(int, Etherpkt*, int, int);
-void	exception(void);
-int	flashboot(int);
-int	flashbootable(int);
-char*	flashconfig(int);
-int	flashinit(void);
-void	free(void*);
-void	freeb(Block*);
-int	getcfields(char*, char**, int, char*);
-char*	getconf(char*);
-ulong	getdec(void);
-ulong	gethid0(void);
-ulong	getimmr(void);
-ulong	getmsr(void);
-ulong	getpvr(void);
-int	getstr(char*, char*, int, char*);
-ulong	gettbl(void);
-ulong	gettbu(void);
-int	hardinit(void);
-long	hardread(int, void*, long);
-long	hardseek(int, long);
-long	hardwrite(int, void*, long);
-long	i2csend(int, void*, long);
-void	i2csetup(void);
-void*	ialloc(ulong, int);
-Block*	iallocb(int);
-void	idle(void);
-int	isaconfig(char*, int, ISAConf*);
-int	issqueezed(uchar*);
-void	kbdchar(Queue*, int);
-void	kbdinit(void);
-void	kbdreset(void);
-void	machinit(void);
-void*	malloc(ulong);
-ulong	mapalloc(RMap*, ulong, int, int);
-void	mapfree(RMap*, ulong, int);
-void	mapinit(RMap*, Map*, int);
-void	meminit(void);
-void	microdelay(int);
-void	mmuinit(void);
-int	optionsw(void);
-void	panic(char*, ...);
-int	parseether(uchar*, char*);
-int	plan9boot(int, long (*)(int, long), long (*)(int, void*, long));
-void	putdec(ulong);
-void	puthid0(ulong);
-void	putmsr(ulong);
-int	qbgetc(Queue*);
-void	qbputc(Queue*, int);
-void	qbwrite(Queue*, Block*);
-Block*	qget(Queue*);
-long	qlen(Queue*);
-Queue*	qopen(int, int, void (*)(void*), void*);
-#define	qpass	qbwrite
-void	scc2stop(void);
-void	sccnmsi(int, int, int);
-void	sched(void);
-void	screeninit(void);
-void	screenputs(char*, int);
-void	sdraminit(ulong);
-Partition*	sethardpart(int, char*);
-Partition*	setscsipart(int, char*);
-void	setvec(int, void (*)(Ureg*, void*), void*);
-int	splhi(void);
-int	spllo(void);
-void	splx(int);
-void	trapinit(void);
-void	uartputs(char*, int);
-void	uartsetboot(void (*f)(uchar*, int));
-void	uartspecial(int, int, Queue**, Queue**, void(*)(Queue*,int));
-void	uartwait(void);
-long	unsqueezef(Block*, ulong*);
-
-#define	GSHORT(p)	(((p)[1]<<8)|(p)[0])
-#define	GLONG(p)	((GSHORT(p+2)<<16)|GSHORT(p))
-#define	GLSHORT(p)	(((p)[0]<<8)|(p)[1])
-#define	GLLONG(p)	((GLSHORT(p)<<16)|GLSHORT(p+2))
-
-#define KADDR(a)	((void*)((ulong)(a)|KZERO))
-#define PADDR(a)	((ulong)(a)&~KSEGM)
-
-/* IBM bit field order */
-#define	IBIT(b)	((ulong)1<<(31-(b)))
-#define	SIBIT(n)	((ushort)1<<(15-(n)))
-
-#define IOREGS(x, T)	((T*)((char*)m->iomem+(x)))
-
-int	uartinit(void);
-Partition*	setuartpart(int, char*);
-long	uartread(int, void*, long);
-long	uartseek(int, long);
--- a/os/boot/mpc/gbitbltclip.c
+++ /dev/null
@@ -1,52 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include <libg.h>
-#include <gnot.h>
-
-void
-gbitbltclip(void *vp)
-{
-	int dx, dy;
-	int i;
-	struct{
-		GBitmap *dm;
-		Point p;
-		GBitmap *sm;
-		Rectangle r;
-		Fcode f;
-	}*bp;
-
-	bp = vp;
-	dx = Dx(bp->r);
-	dy = Dy(bp->r);
-	if(bp->p.x < bp->dm->clipr.min.x){
-		i = bp->dm->clipr.min.x-bp->p.x;
-		bp->r.min.x += i;
-		bp->p.x += i;
-		dx -= i;
-	}
-	if(bp->p.y < bp->dm->clipr.min.y){
-		i = bp->dm->clipr.min.y-bp->p.y;
-		bp->r.min.y += i;
-		bp->p.y += i;
-		dy -= i;
-	}
-	if(bp->p.x+dx > bp->dm->clipr.max.x)
-		bp->r.max.x -= bp->p.x+dx-bp->dm->clipr.max.x;
-	if(bp->p.y+dy > bp->dm->clipr.max.y)
-		bp->r.max.y -= bp->p.y+dy-bp->dm->clipr.max.y;
-	if(bp->r.min.x < bp->sm->clipr.min.x){
-		i = bp->sm->clipr.min.x-bp->r.min.x;
-		bp->p.x += i;
-		bp->r.min.x += i;
-	}
-	if(bp->r.min.y < bp->sm->clipr.min.y){
-		i = bp->sm->clipr.min.y-bp->r.min.y;
-		bp->p.y += i;
-		bp->r.min.y += i;
-	}
-	if(bp->r.max.x > bp->sm->clipr.max.x)
-		bp->r.max.x = bp->sm->clipr.max.x;
-	if(bp->r.max.y > bp->sm->clipr.max.y)
-		bp->r.max.y = bp->sm->clipr.max.y;
-}
--- a/os/boot/mpc/gnot.h
+++ /dev/null
@@ -1,71 +1,0 @@
-
-extern void	*bbmalloc(int);
-extern void	bbfree(void *, int);
-extern int	bbonstack(void);
-extern void	bbexec(void(*)(void), int, int);
-
-/*
- * Graphics types
- */
-
-typedef	struct	GBitmap		GBitmap;
-typedef struct	GFont		GFont;
-typedef struct	GSubfont	GSubfont;
-typedef struct	GCacheinfo	GCacheinfo;
-
-struct	GBitmap
-{
-	ulong	*base;		/* pointer to start of data */
-	long	zero;		/* base+zero=&word containing (0,0) */
-	ulong	width;		/* width in 32 bit words of total data area */
-	int	ldepth;		/* log base 2 of number of bits per pixel */
-	Rectangle r;		/* rectangle in data area, local coords */
-	Rectangle clipr;	/* clipping region */
-	GBitmap	*cache;		/* zero; distinguishes bitmap from layer */
-};
-
-
-/*
- * GFont etc. are not used in the library, only in devbit.c.
- * GSubfont is only barely used.
- */
-struct	GSubfont
-{
-	short	n;		/* number of chars in font */
-	char	height;		/* height of bitmap */
-	char	ascent;		/* top of bitmap to baseline */
-	Fontchar *info;		/* n+1 character descriptors */
-	GBitmap	*bits;		/* where the characters are */
-};
-struct GCacheinfo
-{
-	ulong		xright;	/* right edge of bits */
-	Fontchar;
-};
-
-struct GFont
-{
-	uchar		height;	/* max height of bitmap, interline spacing */
-	char		ascent;	/* top of bitmap to baseline */
-	char		width;	/* widest so far; used in caching only */	
-	char		ldepth;	/* of images */
-	short		id;	/* of font */
-	int		ncache;	/* number of entries in cache */
-	GCacheinfo	*cache;	/* cached characters */
-	GBitmap		*b;	/* cached images */
-};
-
-extern ulong	 *gaddr(GBitmap*, Point);
-extern uchar	 *gbaddr(GBitmap*, Point);
-extern void	 gbitblt(GBitmap*, Point, GBitmap*, Rectangle, Fcode);
-extern void	 gbitbltclip(void*);
-extern void	 gtexture(GBitmap*, Rectangle, GBitmap*, Fcode);
-extern Point	 gsubfstrsize(GSubfont*, char*);
-extern int	 gsubfstrwidth(GSubfont*, char*);
-extern Point	 gsubfstring(GBitmap*, Point, GSubfont*, char*, Fcode);
-extern Point	 gbitbltstring(GBitmap*, Point, GSubfont*, char*, Fcode);
-extern void	 gsegment(GBitmap*, Point, Point, int, Fcode);
-extern void	 gpoint(GBitmap*, Point, int, Fcode);
-extern void	 gflushcpucache(void);
-extern GBitmap*	 gballoc(Rectangle, int);
-extern void	 gbfree(GBitmap*);
--- a/os/boot/mpc/i2c.c
+++ /dev/null
@@ -1,351 +1,0 @@
-#include "boot.h"
-
-/*
- * basic read/write interface to mpc8xx I2C bus (master mode)
- */
-
-typedef struct I2C I2C;
-
-struct I2C {
-	uchar	i2mod;
-	uchar	rsv12a[3];
-	uchar	i2add;
-	uchar	rsv12b[3];
-	uchar	i2brg;
-	uchar	rsv12c[3];
-	uchar	i2com;
-	uchar	rsv12d[3];
-	uchar	i2cer;
-	uchar	rsv12e[3];
-	uchar	i2cmr;
-};
-
-enum {
-	/* i2c-specific BD flags */
-	RxeOV=		1<<1,	/* overrun */
-	TxS=			1<<10,	/* transmit start condition */
-	TxeNAK=		1<<2,	/* last transmitted byte not acknowledged */
-	TxeUN=		1<<1,	/* underflow */
-	TxeCL=		1<<0,	/* collision */
-	TxERR=		(TxeNAK|TxeUN|TxeCL),
-
-	/* i2cmod */
-	REVD=	1<<5,	/* =1, LSB first */
-	GCD=	1<<4,	/* =1, general call address disabled */
-	FLT=		1<<3,	/* =0, not filtered; =1, filtered */
-	PDIV=	3<<1,	/* predivisor field */
-	EN=		1<<0,	/* enable */
-
-	/* i2com */
-	STR=		1<<7,	/* start transmit */
-	I2CM=	1<<0,	/* master */
-	I2CS=	0<<0,	/* slave */
-
-	/* i2cer */
-	TXE =	1<<4,
-	BSY =	1<<2,
-	TXB =	1<<1,
-	RXB =	1<<0,
-
-	/* port B bits */
-	I2CSDA =	IBIT(27),
-	I2CSCL = IBIT(26),
-
-	Rbit =	1<<0,	/* bit in address byte denoting read */
-
-	/* maximum I2C I/O (can change) */
-	Bufsize =	64,
-	Tbuflen=	Bufsize+4,	/* extra address bytes and alignment */
-	Freq =	100000,
-	I2CTimeout = 250,	/* msec */
-};
-
-/* data cache needn't be flushed if buffers allocated in uncached INTMEM */
-#define	DCFLUSH(a,n)
-
-/*
- * I2C software structures
- */
-
-struct Ctlr {
-	Lock;
-	QLock	io;
-	int	init;
-	I2C*	i2c;
-	IOCparam*	sp;
-
-	BD*	rd;
-	BD*	td;
-	int	phase;
-	char*	addr;
-	char*	txbuf;
-	char*	rxbuf;
-};
-typedef struct Ctlr Ctlr;
-
-static	Ctlr	i2ctlr[1];
-extern	int	predawn;
-
-static	void	interrupt(Ureg*, void*);
-
-static void
-enable(void)
-{
-	I2C *i2c;
-
-	i2c = i2ctlr->i2c;
-	i2c->i2cer = ~0;	/* clear events */
-	eieio();
-	i2c->i2mod |= EN;
-	eieio();
-	i2c->i2cmr = TXE|BSY|TXB|RXB;	/* enable all interrupts */
-	eieio();
-}
-
-static void
-disable(void)
-{
-	I2C *i2c;
-
-	i2c = i2ctlr->i2c;
-	i2c->i2cmr = 0;	/* mask all interrupts */
-	i2c->i2mod &= ~EN;
-}
-
-/*
- * called by the reset routine of any driver using the I2C
- */
-void
-i2csetup(void)
-{
-	IMM *io;
-	I2C *i2c;
-	IOCparam *sp;
-	Ctlr *ctlr;
-	long f, e, emin;
-	int p, d, dmax;
-
-	ctlr = i2ctlr;
-	if(ctlr->init)
-		return;
-	print("i2c setup...\n");
-	ctlr->init = 1;
-	i2c = KADDR(INTMEM+0x860);
-	ctlr->i2c = i2c;
-	sp = KADDR(INTMEM+0x3c80);
-	ctlr->sp = sp;
-	disable();
-
-	if(ctlr->txbuf == nil){
-		ctlr->txbuf = ialloc(Tbuflen, 2);
-		ctlr->addr = ctlr->txbuf+Bufsize;
-	}
-	if(ctlr->rxbuf == nil)
-		ctlr->rxbuf = ialloc(Bufsize, 2);
-	if(ctlr->rd == nil){
-		ctlr->rd = bdalloc(1);
-		ctlr->rd->addr = PADDR(ctlr->rxbuf);
-		ctlr->rd->length = 0;
-		ctlr->rd->status = BDWrap;
-	}
-	if(ctlr->td == nil){
-		ctlr->td = bdalloc(2);
-		ctlr->td->addr = PADDR(ctlr->txbuf);
-		ctlr->td->length = 0;
-		ctlr->td->status = BDWrap|BDLast;
-	}
-
-	/* select port pins */
-	io = ioplock();
-	io->pbdir |= I2CSDA | I2CSCL;
-	io->pbodr |= I2CSDA | I2CSCL;
-	io->pbpar |= I2CSDA | I2CSCL;
-	iopunlock();
-
-	/* explicitly initialise parameters, because InitRxTx can't be used (see i2c/spi relocation errata) */
-	sp = ctlr->sp;
-	sp->rbase = PADDR(ctlr->rd);
-	sp->tbase = PADDR(ctlr->td);
-	sp->rfcr = 0x18;
-	sp->tfcr = 0x18;
-	sp->mrblr = Bufsize;
-	sp->rstate = 0;
-	sp->rptr = 0;
-	sp->rbptr = sp->rbase;
-	sp->rcnt = 0;
-	sp->tstate = 0;
-	sp->tbptr = sp->tbase;
-	sp->tptr = 0;
-	sp->tcnt = 0;
-	eieio();
-
-	i2c->i2com = I2CM;
-	i2c->i2mod = 0;	/* normal mode */
-	i2c->i2add = 0;
-
-	emin = Freq;
-	dmax = (m->cpuhz/Freq)/2-3;
-	for(d=0; d < dmax; d++){
-		for(p=3; p>=0; p--){
-			f = (m->cpuhz>>(p+2))/(2*(d+3));
-			e = Freq - f;
-			if(e < 0)
-				e = -e;
-			if(e < emin){
-				emin = e;
-				i2c->i2brg = d;
-				i2c->i2mod = (i2c->i2mod&~PDIV)|((3-p)<<1); /* set PDIV */
-			}
-		}
-	}
-	//print("i2brg=%d i2mod=#%2.2ux\n", i2c->i2brg, i2c->i2mod);
-	setvec(VectorCPIC+0x10, interrupt, i2ctlr);
-}
-
-enum {
-	Idling,
-	Done,
-	Busy,
-		Sending,
-		Recving,
-};
-
-static void
-interrupt(Ureg*, void *arg)
-{
-	int events;
-	Ctlr *ctlr;
-	I2C *i2c;
-
-	ctlr = arg;
-	i2c = ctlr->i2c;
-	events = i2c->i2cer;
-	eieio();
-	i2c->i2cer = events;
-	if(events & (BSY|TXE)){
-		//print("I2C#%x\n", events);
-		if(ctlr->phase != Idling){
-			ctlr->phase = Idling;
-		}
-	}else{
-		if(events & TXB){
-			//print("i2c: xmt %d %4.4ux %4.4ux\n", ctlr->phase, ctlr->td->status, ctlr->td[1].status);
-			if(ctlr->phase == Sending){
-				ctlr->phase = Done;
-			}
-		}
-		if(events & RXB){
-			//print("i2c: rcv %d %4.4ux %d\n", ctlr->phase, ctlr->rd->status, ctlr->rd->length);
-			if(ctlr->phase == Recving){
-				ctlr->phase = Done;
-			}
-		}
-	}
-}
-
-static int
-done(void *a)
-{
-	return ((Ctlr*)a)->phase < Busy;
-}
-
-static void
-i2cwait(Ctlr *ctlr)
-{
-	/* TO DO: timeout */
-	while(!done(ctlr)){
-		if(predawn)
-			interrupt(nil, ctlr);
-	}
-}
-
-long
-i2csend(int addr, void *buf, long n)
-{
-	Ctlr *ctlr;
-	int i, p, s;
-
-	ctlr = i2ctlr;
-	if(n > Bufsize)
-		return -1;
-	i = 1;
-	ctlr->txbuf[0] = addr & ~1;
-	if(addr & 1){
-		ctlr->txbuf[1] = addr>>8;
-		i++;
-	}
-	memmove(ctlr->txbuf+i, buf, n);
-	DCFLUSH(ctlr->txbuf, Tbuflen);
-	ctlr->phase = Sending;
-	ctlr->rd->status = BDEmpty|BDWrap|BDInt;
-	ctlr->td->addr = PADDR(ctlr->txbuf);
-	ctlr->td->length = n+i;
-	ctlr->td->status = BDReady|BDWrap|BDLast|BDInt;
-	enable();
-	ctlr->i2c->i2com = STR|I2CM;
-	eieio();
-	i2cwait(ctlr);
-	disable();
-	p = ctlr->phase;
-	s = ctlr->td->status;
-	if(s & BDReady || s & TxERR || p != Done)
-		return -1;
-	return n;
-}
-
-long
-i2crecv(int addr, void *buf, long n)
-{
-	Ctlr *ctlr;
-	int p, s, flag;
-	BD *td;
-	long nr;
-
-	ctlr = i2ctlr;
-	if(n > Bufsize)
-		return -1;
-	ctlr->txbuf[0] = addr|Rbit;
-	if(addr & 1){	/* special select sequence */
-		ctlr->addr[0] = addr &~ 1;
-		ctlr->addr[1] = addr>>8;
-	}
-	DCFLUSH(ctlr->txbuf, Tbuflen);
-	DCFLUSH(ctlr->rxbuf, Bufsize);
-	ctlr->phase = Recving;
-	ctlr->rd->addr = PADDR(ctlr->rxbuf);
-	ctlr->rd->status = BDEmpty|BDWrap|BDInt;
-	flag = 0;
-	td = ctlr->td;
-	td[1].status = 0;
-	if(addr & 1){
-		/* special select sequence */
-		td->addr = PADDR(ctlr->addr);
-		td->length = 2;
-		/* td->status made BDReady below */
-		td++;
-		flag = TxS;
-	}
-	td->addr = PADDR(ctlr->txbuf);
-	td->length = n+1;
-	td->status = BDReady|BDWrap|BDLast | flag;	/* not BDInt: leave that to receive */
-	if(flag)
-		ctlr->td->status = BDReady;
-	enable();
-	ctlr->i2c->i2com = STR|I2CM;
-	eieio();
-	i2cwait(ctlr);
-	disable();
-	p = ctlr->phase;
-	s = ctlr->td->status;
-	if(flag)
-		s |= ctlr->td[1].status;
-	nr = ctlr->rd->length;
-	if(nr > n)
-		nr = n;	/* shouldn't happen */
-	if(s & TxERR || s & BDReady || ctlr->rd->status & BDEmpty)
-		return -1;
-	if(p != Done)
-		return -1;
-	memmove(buf, ctlr->rxbuf, nr);
-	return nr;
-}
--- a/os/boot/mpc/initfads.c
+++ /dev/null
@@ -1,187 +1,0 @@
-/*
- * Called from l.s in EPROM to set up a minimal working environment.
- * Since there is no DRAM yet, and therefore no stack, no function
- * calls may be made from sysinit0, and values can't be stored,
- * except to INTMEM.  Global values are accessed by offset from SB,
- * which has been set by l.s to point into EPROM.
- *
- * This is FADS-specific in CS assignment and access of the FADS BCSR
- * to discover memory size and speed.
- */
-
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-
-#include "archfads.h"
-
-#define	MB	(1024*1024)
-
-enum {
-	UPMSIZE = 64,	/* memory controller instruction RAM */
-	SPEED = 50,	/* maximum memory clock in MHz */
-	SDRAMSIZE = 4*MB,
-
-	/* mcr */
-	WriteRAM = 0<<30,
-	ReadRAM = 1<<30,
-	ExecRAM = 2<<30,
-
-	SelUPMA = 0<<23,
-	SelUPMB = 1<<23,
-
-	Once = 1<<8,
-};
-
-/*
- * mpc8bug uses the following for 60ns EDO DRAMs 32-50MHz
- */
-static ulong upma50[UPMSIZE] = {
-	0x8FFFEC24,	0xFFFEC04,	0xCFFEC04,	0xFFEC04,       
-	0xFFEC00,	0x37FFEC47,	0xFFFFFFFF,	0xFFFFFFFF,
-	0x8FFFEC24,	0xFFFEC04,	0x8FFEC04,	0xFFEC0C,
-	0x3FFEC00,	0xFFEC44,	0xFFCC08,	0xCFFCC44,
-	0xFFEC0C,	0x3FFEC00,	0xFFEC44,	0xFFCC00,
-	0x3FFFC847,	0x3FFFEC47,	0xFFFFFFFF,	0xFFFFFFFF,
-	0x8FAFCC24,	0xFAFCC04,	0xCAFCC00,	0x11BFCC47,
-	0xC0FFCC84,	0xFFFFFFFF,	0xFFFFFFFF,	0xFFFFFFFF,
-	0x8FAFCC24,	0xFAFCC04,	0xCAFCC00,	0x3AFCC4C,
-	0xCAFCC00,	0x3AFCC4C,	0xCAFCC00,	0x3AFCC4C,
-	0xCAFCC00,	0x33BFCC4F,	0xFFFFFFFF,	0xFFFFFFFF,
-	0xFFFFFFFF,	0xFFFFFFFF,	0xFFFFFFFF,	0xFFFFFFFF,
-	0xC0FFCC84,	0xFFCC04,	0x7FFCC04,	0x3FFFCC06,
-	0xFFFFCC85,	0xFFFFCC05,	0xFFFFCC05,	0xFFFFFFFF,
-	0xFFFFFFFF,	0xFFFFFFFF,	0xFFFFFFFF,	0xFFFFFFFF,
-	0x33FFCC07,	0xFFFFFFFF,	0xFFFFFFFF,	0xFFFFFFFF,
-};
-
-/*
- * the FADS manual table 3-7 suggests the following for 60ns EDO DRAMs at 20MHz
- */
-static ulong upma20[UPMSIZE] = {
-	0x8FFFCC04, 0x08FFCC00, 0x33FFCC47, ~0, ~0, ~0, ~0, ~0,
-	[0x08]	0x8FFFCC04, 0x08FFCC08, 0x08FFCC08, 0x08FFCC08, 0x08FFCC00, 0x3FFFCC47, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0,
-	[0x18]	0x8FEFCC00, 0x39BFCC47, ~0, ~0, ~0, ~0, ~0, ~0,
-	[0x20]	0x8FEFCC00, 0x09AFCC48, 0x09AFCC48, 0x08AFCC48, 0x39BFCC47, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0,
-	[0x30]	0x80FFCC84, 0x17FFCC04, 0xFFFFCC86, 0xFFFFCC05, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0,
-	[0x3C]	0x33FFCC07, ~0, ~0, ~0,
-};
-
-void
-sysinit0(int inrom)
-{
-	ulong *upm, *bcsr;
-	IMM *io;
-	int i, mb;
-
-	io = (IMM*)INTMEM;		/* running before maps, no KADDR */
-
-	/* system interface unit initialisation, FADS manual table 3-2, except as noted */
-	io->siumcr = 0x01012440;
-	io->sypcr = 0xFFFFFF88;
-	io->tbscrk = KEEP_ALIVE_KEY;
-	io->tbscr = 0xC3;	/* time base enabled */
-	io->rtcsck = KEEP_ALIVE_KEY;
-	io->rtcsc = 0xC1;	/* don't FRZ, real-time clock enabled */
-	io->rtcsck = ~KEEP_ALIVE_KEY;
-	io->piscrk = KEEP_ALIVE_KEY;
-	io->piscr = 0x82;
-
-	io->memc[BCSRCS].option = 0xFFFF8110;	/* 32k block, all types access, CS early negate, 1 ws */
-	io->memc[BCSRCS].base = BCSRMEM | 1;	/* base, 32-bit port, no parity, GPCM */
-
-	io->memc[BOOTCS].base = FLASHMEM | 1;
-	io->memc[BOOTCS].option = 0xFF800D54;
-
-	if(!inrom)
-		return;	/* can't initialise DRAM controller from DRAM */
-
-	bcsr = (ulong*)BCSRMEM;
-//	bcsr[1] &= ~DisableDRAM;
-	/* could check DRAM speed here; assume 60ns */
-	switch((bcsr[2]>>23)&3){
-	default:	return;	/* can't happen; for the compiler */
-	case 0:	mb = 4; break;
-	case 1:	mb = 32; break;
-	case 2:	mb = 16; break;
-	case 3:	mb = 8; break;
-	}
-
-	upm = upma50;
-	for(i=0; i<UPMSIZE; i++){
-		io->mdr = upm[i];
-		io->mcr = WriteRAM | SelUPMA | i;
-	}
-	io->mptpr = 0x0400;
-	if(SPEED >= 32)
-		io->mamr = (0x9C<<24) | 0xA21114;	/* 50MHz BRGCLK; FADS manual says 0xC0, mpc8bug sets 0x9C */
-	else if(SPEED >= 20)
-		io->mamr = (0x60<<24) | 0xA21114;	/* 25MHz BRGCLK */
-	else
-		io->mamr = (0x40<<24) | 0xA21114;	/* 16.67MHz BRGCLK */
-	io->memc[DRAM1].option = ~((mb<<20)-1)|0x0800;	/* address mask, SAM=1 */
-	io->memc[DRAM1].base = 0 | 0x81;	/* base at 0, 32-bit port size, no parity, UPMA */
-}
-
-/*
- * the FADS manual table 3-9's suggestion for MB811171622A-100 32+MHz-50MHz
- */
-static ulong upmb50[UPMSIZE] = {
-	[0x00]	0x1F07FC04, 0xEEAEFC04, 0x11ADFC04, 0xEFBBBC00, 0x1FF77C47,
-	[0x05]	0x1FF77C34, 0xEFEABC34, 0x1FB57C35,
-	[0x08]	0x1F07FC04, 0xEEAEFC04, 0x10ADFC04, 0xF0AFFC00, 0xF0AFFC00, 0xF1AFFC00, 0xEFBBBC00, 0x1FF77C47, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0,
-	[0x18]	0x1F27FC04, 0xEEAEBC00, 0x01B93C04, 0x1FF77C47, ~0, ~0, ~0, ~0,
-	[0x20]	0x1F07FC04, 0xEEAEBC00, 0x10AD7C00, 0xF0AFFC00, 0xF0AFFC00, 0xE1BBBC04, 0x1FF77C47, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0,
-	[0x30] 	0x1FF5FC84, 0xFFFFFC04, 0xFFFFFC04, 0xFFFFFC04, 0xFFFFFC84, 0xFFFFFC07, ~0, ~0, ~0, ~0, ~0, ~0,
-	[0x3C]	0x7FFFFC07, ~0, ~0, ~0,
-};
-
-/*
- * the FADS manual table 3-8's suggestion for MB811171622A-100 up to 32MHz
- */
-static	ulong	upmb32[UPMSIZE] = {
-	[0x00]	0x126CC04, 0xFB98C00, 0x1FF74C45, ~0, ~0,
-	[0x05]	0x1FE77C34, 0xEFAABC34, 0x1FA57C35,
-	[0x08]	0x0026FC04, 0x10ADFC00, 0xF0AFFC00, 0xF1AFFC00, 0xEFBBBC00, 0x1FF77C45, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0,
-	[0x18]	0x0E26BC04, 0x01B93C00, 0x1FF77C45, ~0, ~0, ~0, ~0, ~0,
-	[0x20]	0x0E26BC00, 0x10AD7C00, 0xF0AFFC00, 0xF0AFFC00, 0xE1BBBC04, 0x1FF77C45, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0,
-	[0x30]	0x1FF5FC84, 0xFFFFFC04, 0xFFFFFC84, 0xFFFFFC05, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0,
-	[0x3C]	0x7FFFFC07, ~0, ~0, ~0,
-};
-
-/*
- * optionally called by archfads.c:/^archinit to initialise access to SDRAM
- */
-void
-sdraminit(ulong base)
-{
-	ulong *upm;
-	IMM *io;
-	int i;
-
-	io = (IMM*)INTMEM;		/* running before maps, no KADDR */
-	if(SPEED > 32)
-		upm = upmb50;
-	else
-		upm = upmb32;
-	for(i=0; i<UPMSIZE; i++){
-		io->mdr = upm[i];
-		io->mcr = WriteRAM | SelUPMB | i;
-	}
-	io->memc[SDRAM].option = ~(SDRAMSIZE-1)|0x0A00;	/* address mask, SAM=1, G5LS=1 */
-	io->memc[SDRAM].base = base | 0xC1;
-	if(SPEED > 32){
-		io->mbmr = 0xD0802114;	/* 50MHz BRGCLK */
-		io->mar = 0x88;
-	}else{
-		io->mbmr = 0x80802114;	/* 32MHz BRGCLK */
-		io->mar = 0x48;
-	}
-	io->mcr = ExecRAM | SelUPMB | (SDRAM<<13) | Once | 5;	/* run MRS command in locations 5-8 of UPMB */
-	io->mbmr = (io->mbmr & ~0xF) | 8;
-	io->mcr = ExecRAM | SelUPMB | (SDRAM<<13) | Once | 0x30;	/* run refresh sequence */
-	io->mbmr = (io->mbmr & ~0xF) | 4;	/* 4-beat refresh bursts */
-}
--- a/os/boot/mpc/initpaq.c
+++ /dev/null
@@ -1,101 +1,0 @@
-/*
- * Called from l.s in EPROM to set up a minimal working environment.
- * Since there is no DRAM yet, and therefore no stack, no function
- * calls may be made from sysinit0, and values can't be stored,
- * except to INTMEM.  Global values are accessed by offset from SB,
- * which has been set by l.s to point into EPROM.
- *
- * This is PowerPAQ-specific:
- *	- assumes 8mbytes
- *	- powerpaq CS assignment
- */
-
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-
-#include "archpaq.h"
-
-#define	MB	(1024*1024)
-
-enum {
-	DRAMSIZE = 8*MB,
-	FLASHSIZE = 8*MB,
-
-	UPMSIZE = 64,	/* memory controller instruction RAM */
-	SPEED = 50,	/* maximum memory clock in MHz */
-
-	/* mcr */
-	WriteRAM = 0<<30,
-	ReadRAM = 1<<30,
-	ExecRAM = 2<<30,
-
-	SelUPMA = 0<<23,
-	SelUPMB = 1<<23,
-
-	Once = 1<<8,
-};
-
-/*
- * mpc8bug uses the following for 60ns EDO DRAMs 32-50MHz
- */
-static ulong upmb50[UPMSIZE] = {
-	0x8FFFEC24,	0xFFFEC04,	0xCFFEC04,	0xFFEC04,       
-	0xFFEC00,	0x37FFEC47,	0xFFFFFFFF,	0xFFFFFFFF,
-	0x8FFFEC24,	0xFFFEC04,	0x8FFEC04,	0xFFEC0C,
-	0x3FFEC00,	0xFFEC44,	0xFFCC08,	0xCFFCC44,
-	0xFFEC0C,	0x3FFEC00,	0xFFEC44,	0xFFCC00,
-	0x3FFFC847,	0x3FFFEC47,	0xFFFFFFFF,	0xFFFFFFFF,
-	0x8FAFCC24,	0xFAFCC04,	0xCAFCC00,	0x11BFCC47,
-	0xC0FFCC84,	0xFFFFFFFF,	0xFFFFFFFF,	0xFFFFFFFF,
-	0x8FAFCC24,	0xFAFCC04,	0xCAFCC00,	0x3AFCC4C,
-	0xCAFCC00,	0x3AFCC4C,	0xCAFCC00,	0x3AFCC4C,
-	0xCAFCC00,	0x33BFCC4F,	0xFFFFFFFF,	0xFFFFFFFF,
-	0xFFFFFFFF,	0xFFFFFFFF,	0xFFFFFFFF,	0xFFFFFFFF,
-	0xC0FFCC84,	0xFFCC04,	0x7FFCC04,	0x3FFFCC06,
-	0xFFFFCC85,	0xFFFFCC05,	0xFFFFCC05,	0xFFFFFFFF,
-	0xFFFFFFFF,	0xFFFFFFFF,	0xFFFFFFFF,	0xFFFFFFFF,
-	0x33FFCC07,	0xFFFFFFFF,	0xFFFFFFFF,	0xFFFFFFFF,
-};
-
-void
-sysinit0(int inrom)
-{
-	ulong *upm;
-	IMM *io;
-	int i;
-
-	io = (IMM*)INTMEM;		/* running before maps, no KADDR */
-
-	/* system interface unit initialisation, FADS manual table 3-2, except as noted */
-	io->siumcr = 0x01012440;
-	io->sypcr = 0xFFFFFF88;
-	io->tbscrk = KEEP_ALIVE_KEY;
-	io->tbscr = 0xC3;	/* time base enabled */
-	io->rtcsck = KEEP_ALIVE_KEY;
-	io->rtcsc = 0xC1;	/* don't FRZ, real-time clock enabled */
-	io->rtcsck = ~KEEP_ALIVE_KEY;
-	io->piscrk = KEEP_ALIVE_KEY;
-	io->piscr = 0x82;
-
-	io->memc[BOOTCS].base = FLASHMEM | 1;
-	io->memc[BOOTCS].option = ~(FLASHSIZE-1)|(1<<8)|(2<<4);	/* mask, BIH, 2 wait states */
-
-	if(!inrom)
-		return;	/* can't initialise DRAM controller from DRAM */
-
-	/* could check DRAM speed here; assume 60ns */
-	/* could probe DRAM for size here; assume DRAMSIZE */
-	io->mptpr = 0x400;	/* powerpaq flash has 0x1000 */
-	io->mbmr = (0xC0<<24) | 0xA21114;	/* 50MHz BRGCLK */
-	upm = upmb50;
-	for(i=0; i<UPMSIZE; i++){
-		io->mdr = upm[i];
-		io->mcr = WriteRAM | SelUPMB | i;
-	}
-	io->memc[DRAM1].option = ~(DRAMSIZE-1)|0x0800;	/* address mask, SAM=1 */
-	io->memc[DRAM1].base = 0 | 0xC1;	/* base at 0, 32-bit port size, no parity, UPMB */
-}
--- a/os/boot/mpc/initrpcg.c
+++ /dev/null
@@ -1,91 +1,0 @@
-
-/*
- * Called from l.s in EPROM to set up a minimal working environment.
- * Since there is no DRAM yet, and therefore no stack, no function
- * calls may be made from sysinit, and values can't be stored,
- * except to INTMEM.  Global values are accessed by offset from SB,
- * which has been set by l.s to point into EPROM.
- */
-
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-
-#include	"archrpcg.h"
-
-#define	MB	(1024*1024)
-
-enum {
-	UPMSIZE = 64,	/* memory controller instruction RAM */
-	DRAMSIZE = 16*MB,
-	FLASHSIZE = 4*MB,
-
-	WriteRAM = 0<<30,
-	ReadRAM = 1<<30,
-	ExecRAM = 2<<30,
-
-	SelUPMA = 0<<23,
-	SelUPMB = 1<<23,
-};
-/* RPCG values for RPXLite AW */
-static	ulong	upma50[UPMSIZE] = {
-	0xCFFFCC24,	0x0FFFCC04,	0x0CAFCC04,	0x03AFCC08,       
-	0x3FBFCC27,	0xFFFFCC25,	0xFFFFCC25,	0xFFFFCC25,
-	0xCFFFCC24,	0x0FFFCC04,	0x0CAFCC84,	0x03AFCC88,
-	0x3FBFCC27,	0xFFFFCC25,	0xFFFFCC25,	0xFFFFCC25,
-	0xFFFFCC25,	0xFFFFCC25,	0xFFFFCC25,	0xFFFFCC25,
-	0xFFFFCC25,	0xFFFFCC25,	0xFFFFCC25,	0xFFFFCC25,
-	0xCFFFCC24,	0x0FFFCC04,	0x0CFFCC04,	0x03FFCC00,
-	0x3FFFCC27,	0xFFFFCC25,	0xFFFFCC25,	0xFFFFCC25,
-	0xCFFFCC24,	0x0FFFCC04,	0x0CFFCC84,	0x03FFCC84,
-	0x0CFFCC00,	0x33FFCC27,	0xFFFFCC25,	0xFFFFCC25,
-	0xFFFFCC25,	0xFFFFCC25,	0xFFFFCC25,	0xFFFFCC25,
-	0xFFFFCC25,	0xFFFFCC25,	0xFFFFCC25,	0xFFFFCC25,
-	0xC0FFCC24,	0x03FFCC24,	0x0FFFCC24,	0x0FFFCC24,
-	0x3FFFCC27,	0xFFFFCC25,	0xFFFFCC25,	0xFFFFCC25,
-	0xFFFFCC25,	0xFFFFCC25,	0xFFFFCC25,	0xFFFFCC25,
-	0xFFFFCC25,	0xFFFFCC25,	0xFFFFCC25,	0xFFFFCC25,
-};
-
-void
-sysinit0(int inrom)
-{
-	ulong *upm;
-	IMM *io;
-	int i;
-
-	io = (IMM*)INTMEM;		/* running before maps, no KADDR */
-	io->siumcr = 0x01012440;
-	io->sypcr = 0xFFFFFF88;
-	io->tbscrk = KEEP_ALIVE_KEY;
-	io->tbscr = 0xC3;
-	io->rtcsck = KEEP_ALIVE_KEY;
-	io->rtcsc = 0xC1;
-	io->rtcsck = ~KEEP_ALIVE_KEY;
-	io->piscrk = KEEP_ALIVE_KEY;
-	io->piscr = 0x82;
-return;
-	io->memc[BCSRCS].option = 0xFFFF8910;	/* 32k block, all types access, CSNT, CS early negate, burst inhibit, 1 ws */
-	io->memc[BCSRCS].base = BCSRMEM | 1;	/* base, 32-bit port, no parity, GPCM */
-
-	io->memc[BOOTCS].base = FLASHMEM | 0x801; /* base, 16 bit port */
-	io->memc[BOOTCS].option = ~(FLASHSIZE-1)|(1<<8)|(4<<4);	/* mask, BIH, 4 wait states */
-
-	if(1||!inrom)
-		return;	/* can't initialise DRAM controller from DRAM */
-
-	/* TO DO: could check DRAM size and speed now */
-
-	upm = upma50;
-	for(i=0; i<nelem(upma50); i++){
-		io->mdr = upm[i];
-		io->mcr = WriteRAM | SelUPMA | i;
-	}
-	io->mptpr = 0x0800;	/* divide by 8 */
-	io->mamr = (0x58<<24) | 0xA01430;	/* 40MHz BRGCLK */
-	io->memc[DRAM1].option = ~(DRAMSIZE-1)|0x0E00;	/* address mask, SAM=1, G5LA/S=3 */
-	io->memc[DRAM1].base = 0 | 0x81;	/* base at 0, 32-bit port size, no parity, UPMA */
-}
--- a/os/boot/mpc/io.h
+++ /dev/null
@@ -1,463 +1,0 @@
-enum
-{
-	/* software interrupt vectors (SIU and CPM) */
-	VectorPIC= 0,	/* level 0 to level 7, assigned by software */
-		CPIClevel=	4,
-	VectorIRQ=	VectorPIC+8,	/* IRQ0 to IRQ7 */
-	VectorCPIC=	VectorIRQ+8,	/* 32 CPM interrupts: 0 (error) to 0x1F (PC15) */
-};
-
-enum
-{
-	BUSUNKNOWN = 0,
-};
-
-/*
- * Buffer Descriptors and IO Rings
- */
-
-typedef struct BD BD;
-struct BD {
-	ushort	status;
-	ushort	length;
-	ulong	addr;
-};
-
-BD*	bdalloc(int);
-void	bdfree(BD*, int);
-
-enum {
-	/* Rx BDs, bits common to all protocols */
-	BDEmpty=	1<<15,
-	BDWrap=		1<<13,
-	BDInt=		1<<12,
-	BDLast=		1<<11,
-	BDFirst=		1<<10,
-
-	/* Tx BDs */
-	BDReady=		1<<15,
-	/* BDWrap, BDInt, BDLast */
-};
-
-typedef struct Ring Ring;
-struct Ring {
-	BD*	rdr;				/* receive descriptor ring */
-	void*	rrb;				/* receive ring buffers */
-	int	rdrx;				/* index into rdr */
-	int	nrdre;			/* length of rdr */
-
-	BD*	tdr;				/* transmit descriptor ring */
-	Block**	txb;				/* corresponding transmit ring buffers */
-	int	tdrh;				/* host index into tdr */
-	int	tdri;				/* interface index into tdr */
-	int	ntdre;			/* length of tdr */
-	int	ntq;				/* pending transmit requests */
-};
-
-#define NEXT(x, l)	(((x)+1)%(l))
-#define PREV(x, l)	(((x) == 0) ? (l)-1: (x)-1)
-#define	HOWMANY(x, y)	(((x)+((y)-1))/(y))
-#define ROUNDUP(x, y)	(HOWMANY((x), (y))*(y))
-
-int	ioringinit(Ring*, int, int, int);
-
-/*
- * CPM
- */
-enum {
-	/* commands */
-	InitRxTx =	0,
-	InitRx =		1,
-	InitTx =		2,
-	EnterHunt=	3,
-	StopTx=		4,
-	GracefulStopTx = 5,
-	InitIDMA =	5,
-	RestartTx =	6,
-	CloseRxBD =	7,
-	SetGroupAddr = 8,
-	SetTimer =	8,
-	GCITimeout =	9,
-	GCIAbort =	10,
-	StopIDMA =	11,
-	StartDSP = 	12,
-	ArmIDMA =	13,
-	InitDSP =		13,
-	USBCmd =	15,
-
-	/* channel IDs */
-	SCC1ID=	0,
-	USBID=	0,
-	I2CID=	1,
-	IDMA1ID= 1,
-	SCC2ID=	4,
-	SPIID=	5,
-	IDMA2ID= 5,
-	TIMERID=	5,
-	SCC3ID=	8,
-	SMC1ID=	9,
-	DSP1ID=9,
-	SCC4ID=	12,
-	SMC2ID=	13,
-	DSP2ID=	13,
-
-	BaudEnable = 1<<16,
-
-	/* sicr */
-	CLK1 = 4,		/* SCC1,2 */
-	CLK2 = 5,
-	CLK3 = 6,
-	CLK4 = 7,
-	CLK5 = CLK1,	/* SCC3,4 */
-	CLK6 = CLK2,
-	CLK7 = CLK3,
-	CLK8 = CLK4,
-};
-
-void	cpmop(int, int, int);
-#define	ioplock()	(m->iomem)
-#define	iopunlock()
-
-/*
- * the structures below follow hardware/firmware layouts in the 8xx manuals:
- * mind the data types, offsets and alignment
- */
-
-/*
- * basic IO controller parameters (SMC and SCC)
- */
-typedef struct IOCparam IOCparam;
-struct IOCparam {
-	ushort	rbase;
-	ushort	tbase;
-	uchar	rfcr;
-	uchar	tfcr;
-	ushort	mrblr;
-	ulong	rstate;
-	ulong	rptr;
-	ushort	rbptr;
-	ushort	rcnt;
-	ulong	rtmp;
-	ulong	tstate;
-	ulong	tptr;
-	ushort	tbptr;
-	ushort	tcnt;
-	ulong	ttmp;
-};
-
-typedef struct SCCparam SCCparam;
-struct SCCparam {
-	IOCparam;
-	ulong	rcrc;
-	ulong	tcrc;
-};
-
-typedef struct SCC SCC;
-struct SCC {
-	ulong	gsmrl;
-	ulong	gsmrh;
-	ushort	psmr;
-	uchar	rsvscc0[2];
-	ushort	todr;
-	ushort	dsr;
-	ushort	scce;
-	uchar	rsvscc1[2];
-	ushort	sccm;
-	uchar	rsvscc3;
-	uchar	sccs;
-	ushort	irmode;
-	ushort	irsip;
-};
-
-typedef struct SMC SMC;
-struct SMC {
-	uchar	pad1[2];
-	ushort	smcmr;
-	uchar	pad2[2];
-	uchar	smce;
-	uchar	pad3[3];
-	uchar	smcm;
-	uchar	pad4[5];
-};
-
-typedef struct SPI SPI;
-struct SPI {
-	ushort	spmode;
-	uchar	res1[4];
-	uchar	spie;
-	uchar	res2[3];
-	uchar	spim;
-	uchar	res3[2];
-	uchar	spcom;
-	uchar	res4[10];
-};
-
-typedef struct USB USB;
-struct USB {	/* 823 only */
-	uchar	usmod;
-	uchar	usadr;
-	uchar	uscom;
-	uchar	rsvu1;
-	ushort	usep[4];
-	uchar	rsvu2[4];
-	ushort	usber;
-	uchar	rsvu3[2];
-	ushort	usbmr;
-	uchar	rsvu4;
-	uchar	usbs;
-	uchar	rsvu5[8];
-};
-
-typedef struct IMM IMM;
-struct IMM {
-	struct {	/* general SIU */
-		ulong	siumcr;
-		ulong	sypcr;
-		uchar	rsv0[0xE-0x8];
-		ushort	swsr;
-		ulong	sipend;
-		ulong	simask;
-		ulong	siel;
-		uchar	sivec;
-		uchar	padv[3];
-		ulong	tesr;
-		uchar	rsv1[0x30-0x24];
-		ulong	sdcr;
-		uchar	rsv2[0x80-0x34];
-	};
-	struct {	/* PCMCIA */
-		struct {
-			ulong	base;
-			ulong	option;
-		} pcmr[8];
-		uchar	rsv3[0xe0-0xc0];
-		ulong	pgcra;
-		ulong	pgcrb;
-		ulong	pscr;
-		uchar	rsv4[0xf0-0xec];
-		ulong	pipr;
-		uchar	rsv5[4];
-		ulong	per;
-		uchar	rsv6[4];
-	};
-	struct {	/* MEMC */
-		struct {
-			ulong	base;
-			ulong	option;
-		} memc[8];
-		uchar	rsv7a[0x24];
-		ulong	mar;
-		ulong	mcr;
-		uchar	rsv7b[4];
-		ulong	mamr;
-		ulong	mbmr;
-		ushort	mstat;
-		ushort	mptpr;
-		ulong	mdr;
-		uchar	rsv7c[0x80];
-	};
-	struct {	/* system integration timers */
-		ushort	tbscr;
-		uchar	rsv8a[2];
-		ulong	tbrefu;
-		ulong	tbrefl;
-		uchar	rsv8b[0x14];
-		ushort	rtcsc;
-		uchar	rsv8c[2];
-		ulong	rtc;
-		ulong	rtsec;
-		ulong	rtcal;
-		uchar	rsv8d[0x10];
-		ushort	piscr;
-		ushort	rsv8e;
-		ulong	pitc;
-		ulong	pitr;
-		uchar	rsv8f[0x34];
-	};
-	struct {	/* 280: clocks and resets */
-		ulong	sccr;
-		ulong	plprcr;
-		ulong	rsr;
-		uchar	rsv9[0x300-0x28c];
-	};
-	struct {	/* 300: system integration timers keys */
-		ulong	tbscrk;
-		ulong	tbrefuk;
-		ulong	tbreflk;
-		ulong	tbk;
-		uchar	rsv10a[0x10];
-		ulong	rtcsck;
-		ulong	rtck;
-		ulong	rtseck;
-		ulong	rtcalk;
-		uchar	rsv10b[0x10];
-		ulong	piscrk;
-		ulong	pitck;
-		uchar	rsv10c[0x38];
-	};
-	struct {	/* 380: clocks and resets keys */
-		ulong	sccrk;
-		ulong	plprcrk;
-		ulong	rsrk;
-		uchar	rsv11[0x800-0x38C];
-	};
-	struct {	/* 800: video controller */
-		ushort	vccr;
-		ushort	pad11a;
-		uchar	vsr;
-		uchar	pad11b;
-		uchar	vcmr;
-		uchar	pad11c;
-		ulong	vbcb;
-		ulong	pad11d;
-		ulong	vfcr0;
-		ulong	vfaa0;
-		ulong	vfba0;
-		ulong	vfcr1;
-		ulong	vfaa1;
-		ulong	vfba1;
-		uchar	rsv11a[0x840-0x828];
-	};
-	struct {	/* 840: LCD */
-		ulong	lccr;
-		ulong	lchcr;
-		ulong	lcvcr;
-		ulong	rsv11b;
-		ulong	lcfaa;
-		ulong	lcfba;
-		uchar	lcsr;
-		uchar	rsv11c[0x860-0x859];
-	};
-	struct {	/* 860: I2C */
-		uchar	i2mod;
-		uchar	rsv12a[3];
-		uchar	i2add;
-		uchar	rsv12b[3];
-		uchar	i2brg;
-		uchar	rsv12c[3];
-		uchar	i2com;
-		uchar	rsv12d[3];
-		uchar	i2cer;
-		uchar	rsv12e[3];
-		uchar	i2cmr;
-		uchar	rsv12[0x900-0x875];
-	};
-	struct {	/* 900: DMA */
-		uchar	rsv13[4];
-		ulong	sdar;
-		uchar	sdsr;
-		uchar	pad1[3];
-		uchar	sdmr;
-		uchar	pad2[3];
-		uchar	idsr1;
-		uchar	pad3[3];
-		uchar	idmr1;
-		uchar	pad4[3];
-		uchar	idsr2;
-		uchar	pad5[3];
-		uchar	idmr2;
-		uchar	pad6[0x930-0x91D];
-	};
-	struct {	/* CPM interrupt control */
-		ushort	civr;
-		uchar	pad7[0x940-0x932];
-		ulong	cicr;
-		ulong	cipr;
-		ulong	cimr;
-		ulong	cisr;
-	};
-	struct {	/* input/output port */
-		ushort	padir;
-		ushort	papar;
-		ushort	paodr;
-		ushort	padat;
-		uchar	pad8[8];
-		ushort	pcdir;
-		ushort	pcpar;
-		ushort	pcso;
-		ushort	pcdat;
-		ushort	pcint;
-		uchar	pad9[6];
-		ushort	pddir;
-		ushort	pdpar;
-		ushort	rsv14a;
-		ushort	pddat;
-		uchar	rsv14[0x980-0x978];
-	};
-	struct {	/* CPM timers */
-		ushort	tgcr;
-		uchar	rsv15a[0x990-0x982];
-		ushort	tmr1;
-		ushort	tmr2;
-		ushort	trr1;
-		ushort	trr2;
-		ushort	tcr1;
-		ushort	tcr2;
-		ushort	tcn1;
-		ushort	tcn2;
-		ushort	tmr3;
-		ushort	tmr4;
-		ushort	trr3;
-		ushort	trr4;
-		ushort	tcr3;
-		ushort	tcr4;
-		ushort	tcn3;
-		ushort	tcn4;
-		ushort	ter1;
-		ushort	ter2;
-		ushort	ter3;
-		ushort	ter4;
-		uchar	rsv15[0x9C0-0x9B8];
-	};
-	struct {	/* CPM */
-		ushort	cpcr;
-		uchar	res0[2];
-		ushort	rccr;
-		uchar	res1;
-		uchar	rmds;
-		uchar	res2a[4];
-		ushort	rctr1;
-		ushort	rctr2;
-		ushort	rctr3;
-		ushort	rctr4;
-		uchar	res2[2];
-		ushort	rter;
-		uchar	res3[2];
-		ushort	rtmr;
-		uchar	rsv16[0x9F0-0x9DC];
-	};
-	union {	/* BRG */
-		struct {
-			ulong	brgc1;
-			ulong	brgc2;
-			ulong	brgc3;
-			ulong	brgc4;
-		};
-		ulong	brgc[4];
-	};
-	uchar	skip0[0xAB2-0xA00];	/* USB, SCC, SMC, SPI: address using cpmdev(CP...)->regs */
-	struct {	/* PIP */
-		ushort	pipc;		/* not 823 */
-		ushort	ptpr;		/* not 823 */
-		ulong	pbdir;
-		ulong	pbpar;
-		uchar	pad10[2];
-		ushort	pbodr;
-		ulong	pbdat;
-		uchar	pad11[0xAE0-0xAC8];
-	};
-	struct {	/* SI */
-		ulong	simode;
-		uchar	sigmr;
-		uchar	pad12;
-		uchar	sistr;
-		uchar	sicmr;
-		uchar	pad13[4];
-		ulong	sicr;
-		ulong	sirp;
-		uchar	pad14[0xB00-0xAF4];
-	};
-	ulong	vcram[64];
-	ushort	siram[256];
-	ushort	lcdmap[256];
-};
--- a/os/boot/mpc/ip.h
+++ /dev/null
@@ -1,98 +1,0 @@
-typedef struct Udphdr Udphdr;
-struct Udphdr
-{
-	uchar	d[6];		/* Ethernet destination */
-	uchar	s[6];		/* Ethernet source */
-	uchar	type[2];	/* Ethernet packet type */
-
-	uchar	vihl;		/* Version and header length */
-	uchar	tos;		/* Type of service */
-	uchar	length[2];	/* packet length */
-	uchar	id[2];		/* Identification */
-	uchar	frag[2];	/* Fragment information */
-
-	/* Udp pseudo ip really starts here */
-	uchar	ttl;	
-	uchar	udpproto;	/* Protocol */
-	uchar	udpplen[2];	/* Header plus data length */
-	uchar	udpsrc[4];	/* Ip source */
-	uchar	udpdst[4];	/* Ip destination */
-	uchar	udpsport[2];	/* Source port */
-	uchar	udpdport[2];	/* Destination port */
-	uchar	udplen[2];	/* data length */
-	uchar	udpcksum[2];	/* Checksum */
-};
-
-typedef struct Etherhdr Etherhdr;
-struct Etherhdr
-{
-	uchar	d[6];
-	uchar	s[6];
-	uchar	type[2];
-
-	/* Now we have the ip fields */
-	uchar	vihl;		/* Version and header length */
-	uchar	tos;		/* Type of service */
-	uchar	length[2];	/* packet length */
-	uchar	id[2];		/* Identification */
-	uchar	frag[2];	/* Fragment information */
-	uchar	ttl;		/* Time to live */
-	uchar	proto;		/* Protocol */
-	uchar	cksum[2];	/* Header checksum */
-	uchar	src[4];		/* Ip source */
-	uchar	dst[4];		/* Ip destination */
-};
-
-enum
-{
-	IP_VER		= 0x40,
-	IP_HLEN		= 0x05,			
- 	UDP_EHSIZE	= 22,
-	UDP_PHDRSIZE	= 12,
-	UDP_HDRSIZE	= 20,
-	ETHER_HDR	= 14,
-	IP_UDPPROTO	= 17,
-	ET_IP		= 0x800,
-	Bcastip		= 0xffffffff,
-	BPportsrc	= 68,
-	BPportdst	= 67,
-	TFTPport	= 69,
-	Timeout		= 5000,	/* milliseconds */
-	Bootrequest 	= 1,
-	Bootreply   	= 2,
-	Tftp_READ	= 1,
-	Tftp_WRITE	= 2,
-	Tftp_DATA	= 3,
-	Tftp_ACK	= 4,
-	Tftp_ERROR	= 5,
-	Segsize		= 512,
-	TFTPSZ		= Segsize+10,
-};
-
-typedef struct Bootp Bootp;
-struct Bootp
-{
-	uchar	op;		/* opcode */
-	uchar	htype;		/* hardware type */
-	uchar	hlen;		/* hardware address len */
-	uchar	hops;		/* hops */
-	uchar	xid[4];		/* a random number */
-	uchar	secs[2];	/* elapsed snce client started booting */
-	uchar	pad[2];
-	uchar	ciaddr[4];	/* client IP address (client tells server) */
-	uchar	yiaddr[4];	/* client IP address (server tells client) */
-	uchar	siaddr[4];	/* server IP address */
-	uchar	giaddr[4];	/* gateway IP address */
-	uchar	chaddr[16];	/* client hardware address */
-	char	sname[64];	/* server host name (optional) */
-	char	file[128];	/* boot file name */
-	char	vend[128];	/* vendor-specific goo */
-};
-
-typedef struct Netaddr Netaddr;
-struct Netaddr
-{
-	ulong	ip;
-	ushort	port;
-	char	ea[Eaddrlen];
-};
--- a/os/boot/mpc/l.s
+++ /dev/null
@@ -1,370 +1,0 @@
-#include "mem.h"
-
-/* special instruction definitions */
-#define	BDNE	BC	0,2,
-#define	BDNZ	BC	16,0,
-#define	NOOP	OR	R0,R0,R0
-
-/*
- * common ppc special purpose registers
- */
-#define DSISR	18
-#define DAR	19	/* Data Address Register */
-#define DEC	22	/* Decrementer */
-#define SRR0	26	/* Saved Registers (exception) */
-#define SRR1	27
-#define SPRG0	272	/* Supervisor Private Registers */
-#define SPRG1	273
-#define SPRG2	274
-#define SPRG3	275
-#define TBRU	269	/* Time base Upper/Lower (Reading) */
-#define TBRL	268
-#define TBWU	285	/* Time base Upper/Lower (Writing) */
-#define TBWL	284
-#define PVR	287	/* Processor Version */
-
-/*
- * mpc82x-specific special purpose registers of interest here
- */
-#define EIE	80
-#define EID	81
-#define NRI	82
-#define IMMR	638
-#define IC_CST	560
-#define IC_ADR	561
-#define IC_DAT	562
-#define DC_CST	568
-#define DC_ADR	569
-#define DC_DAT	570
-#define MI_CTR	784
-#define MI_AP	786
-#define MI_EPN	787
-#define MI_TWC	789
-#define MI_RPN	790
-#define MI_DBCAM	816
-#define MI_DBRAM0	817
-#define MI_DBRAM1	818
-#define MD_CTR	792
-#define M_CASID	793
-#define MD_AP	794
-#define MD_EPN	795
-#define M_TWB	796
-#define MD_TWC	797
-#define MD_RPN	798
-#define	M_TW	799
-#define	MD_DBCAM	824
-#define	MD_DBRAM0	825
-#define	MD_DBRAM1	826
-
-/* as on 603e, apparently mtmsr needs help in some chip revisions */
-#define	WAITMSR	SYNC; ISYNC
-
-/* use of SPRG registers in save/restore */
-#define	SAVER0	SPRG0
-#define	SAVER1	SPRG1
-#define	SAVELR	SPRG2
-#define	SAVECR	SPRG3
-
-#define	UREGSIZE	((8+32)*4)
-#define	UREGSPACE	(UREGSIZE+8)	/* allow for arg to trap, and align */
-
-/*
- * This code is loaded by the ROM loader at location 0x3000,
- * or lives in flash memory at 0x2800100.
- * Move it to high memory so that it can load the kernel at 0x0000.
- */
-
-#define LOADCODEBASE	0x3000	/* when downloaded in S records */
-#define FLASHCODEBASE	(FLASHMEM+0x100)	/* when in flash */
-
-	TEXT	start(SB), $-4
-	MOVW	MSR, R3
-	MOVW	$(EE|IP|RI), R4
-	ANDN	R4, R3
-	OR	$ME, R3
-	SYNC
-	MOVW	R3, MSR	/* turn off interrupts but enable traps */
-	WAITMSR
-
-/*
- * reset the caches and disable them for now
- */
-	MOVW	SPR(IC_CST), R4	/* read and clear */
-	MOVW	$(5<<25), R4
-	MOVW	R4, SPR(IC_CST)	/* unlock all */
-	ISYNC
-	MOVW	$(6<<25), R4
-	MOVW	R4, SPR(IC_CST)	/* invalidate all */
-	ISYNC
-	MOVW	$(2<<25), R4
-	MOVW	R4, SPR(IC_CST)	/* disable i-cache */
-	ISYNC
-
-	SYNC
-	MOVW	SPR(DC_CST), R4	/* read and clear */
-	MOVW	$(10<<24), R4
-	MOVW	R4, SPR(DC_CST)	/* unlock all */
-	ISYNC
-	MOVW	$(12<<24), R4
-	MOVW	R4, SPR(DC_CST)	/* invalidate all */
-	ISYNC
-	MOVW	$(4<<24), R4
-	MOVW	R4, SPR(DC_CST)	/* disable i-cache */
-	ISYNC
-
-	MOVW	$7, R4
-ANDN R4, R4, R4
-	MOVW	R4, SPR(158)		/* cancel `show cycle' for normal instruction execution */
-
-/*
- * set other system configuration values
- */
-	MOVW	SPR(IMMR), R5		/* save initial space pointer */
-	MOVW	$INTMEM, R4
-	MOVW	R4, SPR(IMMR)		/* set internal memory base */
-	MOVW	$0xFFFFFF88, R3
-	MOVW	R3, 4(R4)	/* disable watchdog in sypcr */
-	MOVW	$0x01012440, R3
-	MOVW	R3, 0(R4)	/* siumcr */
-
-/*
- * system initialisation (init and map DRAM)
- */
-	MOVW	$0, R0
-	MOVW	$setSB(SB), R2
-	MOVW	$(0xF000<<16), R3
-/*MOVW R0, R3*/
-	ANDCC	R5, R3	/* initial space is high? */
-	BEQ	notrom
-	MOVW	$FLASHCODEBASE, R5	/* where $start(SB) actually is now */
-	MOVW	$start(SB), R4	/* logical start address */
-	SUB	R4, R5, R6	/* text relocation value */
-	MOVW	$etext(SB), R7
-	SUB	R4, R7
-	ADD	R5, R7	/* data address in ROM */
-	MOVW	$bdata(SB), R8
-	SUB	R8, R2
-	ADD	R7, R2	/* relocate SB: SB' = romdata+(SB-bdata) */
-	MOVW	$sysinit0(SB), R4
-	ADD	R6, R4	/* relocate sysinit0's address */
-	MOVW	R4, CTR
-	MOVW	$inmem(SB), R4
-	ADD	R6, R4
-	MOVW	R4, LR	/* and the return address */
-	BR	(CTR)	/* call sysinit0 */
-	TEXT	inmem(SB), $-4
-	MOVW	$FLASHCODEBASE, R3
-	BR	cpu0
-notrom:
-	MOVW	$start(SB), R6
-	SUB	R6, R2
-	ADD	$LOADCODEBASE, R2
-	BL	sysinit0(SB)
-	MOVW	$LOADCODEBASE, R3
-
-/*
- * cpu 0
- *	relocate bootstrap to our link addresses for text and data
- *	set new PC
- */
-cpu0:
-	MOVW	$setSB(SB), R2	/* set correct static base register */
-	MOVW	$start(SB), R4
-	MOVW	$etext(SB), R5
-	SUB	R4, R5
-	CMP	R4, R3	/* already there? */
-	BNE	copytext
-	ADD	R5, R3	/* start of data image */
-	BR	copydata
-
-copytext:
-	ADD	$3, R5
-	SRAW	$2, R5
-	MOVW	R5, CTR
-	SUB	$4, R4
-	SUB	$4, R3
-copyt:			/* copy text */
-	MOVWU	4(R3), R5
-	MOVWU	R5, 4(R4)
-	BDNZ	copyt
-	ADD	$4, R3
-
-copydata:
-	/* copy data */
-	MOVW	$bdata(SB), R4
-	CMP	R4, R3	/* already there? */
-	BEQ	loadkpc
-	MOVW	$edata(SB), R5
-	SUB	R4, R5
-	ADD	$3, R5
-	SRAW	$2, R5
-	MOVW	R5, CTR
-	SUB	$4, R4
-	SUB	$4, R3
-copyd:
-	MOVWU	4(R3), R5
-	MOVWU	R5, 4(R4)
-	BDNZ	copyd
-
-	/* load correct PC */
-loadkpc:
-	MOVW	$start1(SB), R3
-	MOVW	R3, LR
-	BR	(LR)
-TEXT start1(SB), $-4
-	MOVW	$edata(SB), R3
-	MOVW	$end(SB), R4
-	SUBCC	R3, R4
-	BLE	skipz
-	SRAW	$2, R4
-	MOVW	R4, CTR
-	SUB	$4, R3
-	MOVW	$0, R0
-zero:
-	MOVWU	R0, 4(R3)
-	BDNZ	zero
-skipz:
-	MOVW	$mach0(SB), R1
-	MOVW	R1, m(SB)
-	ADD	$(MACHSIZE-8), R1
-	MOVW	$0, R0
-	BL	main(SB)
-	BR	0(PC)
-
-TEXT	getmsr(SB), $0
-	MOVW	MSR, R3
-	RETURN
-
-TEXT	putmsr(SB), $0
-	SYNC
-	MOVW	R3, MSR
-	WAITMSR
-	RETURN
-
-TEXT	eieio(SB), $0
-	EIEIO
-	RETURN
-
-TEXT	idle(SB), $0
-	RETURN
-
-TEXT	spllo(SB), $0
-	MOVW	MSR, R3
-	OR	$EE, R3, R4
-	SYNC
-	MOVW	R4, MSR
-	WAITMSR
-	RETURN
-
-TEXT	splhi(SB), $0
-	MOVW	MSR, R3
-	RLWNM	$0, R3, $~EE, R4
-	SYNC
-	MOVW	R4, MSR
-	WAITMSR
-	RETURN
-
-TEXT	splx(SB), $0
-	MOVW	MSR, R4
-	RLWMI	$0, R3, $EE, R4
-	SYNC
-	MOVW	R4, MSR
-	WAITMSR
-	RETURN
-
-TEXT	gettbl(SB), $0
-/*	MOVW	SPR(TBRL), R3	*/
-	WORD	$0x7c6c42e6	/* mftbl on 8xx series */
-	RETURN
-
-TEXT	getpvr(SB), $0
-	MOVW	SPR(PVR), R3
-	RETURN
-
-TEXT	getimmr(SB), $0
-	MOVW	SPR(IMMR), R3
-	RETURN
-
-TEXT	getdec(SB), $0
-	MOVW	SPR(DEC), R3
-	RETURN
-
-TEXT	putdec(SB), $0
-	MOVW	R3, SPR(DEC)
-	RETURN
-
-/*
- * save state in Ureg on kernel stack.
- * enter with R0 giving the PC from the call to `exception' from the vector.
- * on return, SB (R2) has been set, and R3 has the Ureg*
- */
-TEXT saveureg(SB), $-4
-	SUB	$UREGSPACE, R1
-	MOVMW	R2, 48(R1)	/* r2:r31 */
-	MOVW	$setSB(SB), R2
-	MOVW	SPR(SAVER1), R4
-	MOVW	R4, 44(R1)
-	MOVW	SPR(SAVER0), R5
-	MOVW	R5, 40(R1)
-	MOVW	CTR, R6
-	MOVW	R6, 36(R1)
-	MOVW	XER, R4
-	MOVW	R4, 32(R1)
-	MOVW	SPR(SAVECR), R5	/* CR */
-	MOVW	R5, 28(R1)
-	MOVW	SPR(SAVELR), R6	/* LR */
-	MOVW	R6, 24(R1)
-	/* pad at 20(R1) */
-	MOVW	SPR(SRR0), R4
-	MOVW	R4, 16(R1)	/* old PC */
-	MOVW	SPR(SRR1), R5
-	MOVW	R5, 12(R1)
-	MOVW	R0, 8(R1)	/* cause/vector, encoded in LR from vector */
-	ADD	$8, R1, R3	/* Ureg* */
-	STWCCC	R3, (R1)	/* break any pending reservations */
-	MOVW	$0, R0	/* R0ISZERO */
-	BR	(LR)
-
-/*
- * restore state from Ureg
- * SB (R2) is unusable on return
- */
-TEXT restoreureg(SB), $-4
-	MOVMW	48(R1), R2	/* r2:r31 */
-	/* defer R1 */
-	MOVW	40(R1), R0
-	MOVW	R0, SPR(SAVER0)
-	MOVW	36(R1), R0
-	MOVW	R0, CTR
-	MOVW	32(R1), R0
-	MOVW	R0, XER
-	MOVW	28(R1), R0
-	MOVW	R0, CR	/* CR */
-	MOVW	24(R1), R0
-	MOVW	R0, SPR(SAVELR)	/* LR */
-	/* pad, skip */
-	MOVW	16(R1), R0
-	MOVW	R0, SPR(SRR0)	/* old PC */
-	MOVW	12(R1), R0
-	MOVW	R0, SPR(SRR1)	/* old MSR */
-	/* cause, skip */
-	MOVW	44(R1), R1	/* old SP */
-	BR	(LR)
-
-TEXT	exception(SB), $-4
-	MOVW	R1, SPR(SAVER1)
-	MOVW	CR, R0
-	MOVW	R0, SPR(SAVECR)
-	MOVW	LR, R0
-	BL	saveureg(SB)
-	MOVW	$0, R0
-	BL	trap(SB)
-	BL	restoreureg(SB)
-	MOVW	SPR(SAVELR), R0
-	MOVW	R0, LR
-	MOVW	SPR(SAVER0), R0
-	ISYNC
-	RFI
-
-GLOBL	mach0+0(SB), $MACHSIZE
-GLOBL	m(SB), $4
--- a/os/boot/mpc/lib.h
+++ /dev/null
@@ -1,106 +1,0 @@
-/*
- * functions (possibly) linked in, complete, from libc.
- */
-
-/*
- * mem routines
- */
-extern	void*	memccpy(void*, void*, int, long);
-extern	void*	memset(void*, int, long);
-extern	int	memcmp(void*, void*, long);
-extern	void*	memmove(void*, void*, long);
-extern	void*	memchr(void*, int, long);
-
-/*
- * string routines
- */
-extern	char*	strcat(char*, char*);
-extern	char*	strchr(char*, char);
-extern	int	strcmp(char*, char*);
-extern	char*	strcpy(char*, char*);
-extern	char*	strncat(char*, char*, long);
-extern	char*	strncpy(char*, char*, long);
-extern	int	strncmp(char*, char*, long);
-extern	long	strlen(char*);
-extern	char*	strrchr(char*, char);
-extern	char*	strstr(char*, char*);
-
-/*
- * print routines
- * 	Fconv isn't used but is defined to satisfy prototypes in libg.h
- *	that are never called.
- */
-typedef	struct Fconv Fconv;
-
-extern	char*	donprint(char*, char*, char*, void*);
-extern	int	sprint(char*, char*, ...);
-extern	int	print(char*, ...);
-
-#define	PRINTSIZE	256
-
-/*
- * one-of-a-kind
- */
-extern	int	atoi(char*);
-extern	long	strtol(char*, char**, int);
-extern	ulong	strtoul(char*, char**, int);
-extern	long	end;
-
-/*
- * Syscall data structures
- */
-
-#define	MORDER	0x0003	/* mask for bits defining order of mounting */
-#define	MREPL	0x0000	/* mount replaces object */
-#define	MBEFORE	0x0001	/* mount goes before others in union directory */
-#define	MAFTER	0x0002	/* mount goes after others in union directory */
-#define	MCREATE	0x0004	/* permit creation in mounted directory */
-#define	MMASK	0x0007	/* all bits on */
-
-#define	OREAD	0	/* open for read */
-#define	OWRITE	1	/* write */
-#define	ORDWR	2	/* read and write */
-#define	OEXEC	3	/* execute, == read but check execute permission */
-#define	OTRUNC	16	/* or'ed in (except for exec), truncate file first */
-#define	OCEXEC	32	/* or'ed in, close on exec */
-#define	ORCLOSE	64	/* or'ed in, remove on close */
-
-#define	NCONT	0	/* continue after note */
-#define	NDFLT	1	/* terminate after note */
-
-typedef struct Qid	Qid;
-typedef struct Dir	Dir;
-typedef struct Waitmsg	Waitmsg;
-
-#define	ERRLEN	64
-#define	DIRLEN	116
-#define	NAMELEN	28
-
-struct Qid
-{
-	ulong	path;
-	ulong	vers;
-};
-
-struct Dir
-{
-	char	name[NAMELEN];
-	char	uid[NAMELEN];
-	char	gid[NAMELEN];
-	Qid	qid;
-	ulong	mode;
-	long	atime;
-	long	mtime;
-	vlong	length;
-	short	type;
-	short	dev;
-};
-
-struct Waitmsg
-{
-	int	pid;		/* of loved one */
-	int	status;		/* unused; a placeholder */
-	ulong	time[3];	/* of loved one */
-	char	msg[ERRLEN];
-};
-#define	nelem(x)	(sizeof(x)/sizeof((x)[0]))
--- a/os/boot/mpc/main.c
+++ /dev/null
@@ -1,524 +1,0 @@
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-
-#include "dosfs.h"
-
-typedef struct Type Type;
-typedef struct Medium Medium;
-typedef struct Mode Mode;
-
-enum {
-	Dany		= -1,
-	Nmedia		= 16,
-
-	/* DS1 switch options */
-	Sflashfs		= 1<<0,	/* take local fs from flash */
-	Snotflash		= 1<<1,	/* don't boot from flash */
-};
-
-enum {					/* type */
-	Tflash,
-	Tuart,
-	Tether,
-	Thard,
-
-	Tany		= -1,
-};
-
-enum {					/* flag and name */
-	Fnone		= 0x00,
-
-	Fdos		= 0x01,
-	Ndos		= 0x00,
-	Fboot		= 0x02,
-	Nboot		= 0x01,
-	Fbootp		= 0x04,
-	Nbootp		= 0x02,
-	Fflash		= 0x08,
-	Fuart		= 0x10,
-	NName		= 0x03,
-
-	Fany		= Fbootp|Fboot|Fdos|Fflash|Fuart,
-
-	Fini		= 0x10,
-	Fprobe		= 0x80,
-};
-
-enum {					/* mode */
-	Mauto		= 0x00,
-	Mlocal		= 0x01,
-	Manual		= 0x02,
-	NMode		= 0x03,
-};
-
-typedef struct Type {
-	int	type;
-	char	*cname;
-	int	flag;
-	int	(*init)(void);
-	long	(*read)(int, void*, long);
-	long	(*seek)(int, long);
-	Partition* (*setpart)(int, char*);
-	char*	name[NName];
-
-	int	mask;
-	Medium*	media;
-} Type;
-
-typedef struct Medium {
-	Type*	type;
-	int	flag;
-	Partition* partition;
-	Dos;
-
-	Medium*	next;
-} Medium;
-
-typedef struct Mode {
-	char*	name;
-	int	mode;
-} Mode;
-
-static Type types[] = {
-	{	Tflash, "flash",
-		Fflash,
-		flashinit, 0, 0, 0,
-		{ 0, "F", 0, }
-	},
-/*
-	{	Tuart, "uart",
-		Fuart|Fboot,
-		uartinit, uartread, uartseek, setuartpart,
-		{ 0, "u", 0, }
-	},
-*/
-	{	Tether, "ether",
-		Fbootp,
-		etherinit, 0, 0, 0,
-		{ 0, 0, "e", },
-	},
-	{	Thard, "ata",
-		Fini|Fboot|Fdos,
-		0, 0, 0, 0,		/* not used now, will be later with PCMCIA */
-		{ "hd", "h", 0, },
-	},
-	{-1},
-};
-
-static Medium media[Nmedia];
-static Medium *curmedium = media;
-
-static Mode modes[NMode+1] = {
-	[Mauto]		{ "auto",   Mauto,  },
-	[Mlocal]	{ "local",  Mlocal, },
-	[Manual]	{ "manual", Manual, },
-};
-
-static char *inis[] = {
-	"inferno/inferno.ini",
-	"inferno.ini",
-	"plan9/plan9.ini",
-	"plan9.ini",
-	0,
-};
-char **ini;
-int	predawn;
-
-static int
-parse(char *line, int *type, int *flag, int *dev, char *file)
-{
-	Type *tp;
-	char buf[2*NAMELEN], *v[4], *p;
-	int i;
-
-	strcpy(buf, line);
-	switch(getcfields(buf, v, 4, "!")){
-
-	case 3:
-		break;
-
-	case 2:
-		v[2] = "";
-		break;
-
-	default:
-		return 0;
-	}
-
-	*flag = 0;
-	for(tp = types; tp->cname; tp++){
-		for(i = 0; i < NName; i++){
-
-			if(tp->name[i] == 0 || strcmp(v[0], tp->name[i]))
-				continue;
-			*type = tp->type;
-			*flag |= 1<<i;
-
-			if((*dev = strtoul(v[1], &p, 0)) == 0 && p == v[1])
-				return 0;
-		
-			strcpy(file, v[2]);
-		
-			return 1;
-		}
-	}
-
-	return 0;
-
-}
-
-static int
-boot(Medium *mp, int flag, char *file)
-{
-	Dosfile df;
-	char ixdos[128], *p;
-	int r;
-
-	uartsetboot(0);
-	if(flag & Fbootp){
-		sprint(BOOTLINE, "%s!%d", mp->type->name[Nbootp], mp->dev);
-		return bootp(mp->dev, file);
-	}
-
-	if(flag & Fflash){
-		if(mp->flag & Fflash && flashbootable(0))
-			flashboot(mp->dev);
-	}
-
-	if(flag & Fboot){
-
-		if(mp->flag & Fini){
-			(*mp->type->setpart)(mp->dev, "disk");
-			plan9ini(mp, nil);
-		}
-		if(file == 0 || *file == 0)
-			file = mp->partition->name;
-		(*mp->type->setpart)(mp->dev, file);
-		sprint(BOOTLINE, "%s!%d!%s", mp->type->name[Nboot], mp->dev, file);
-		r = plan9boot(mp->dev, mp->seek, mp->read);
-		uartsetboot(0);
-		return r;
-	}
-
-	if(flag & Fdos){
-		if(mp->type->setpart)
-			(*mp->type->setpart)(mp->dev, "disk");
-		if(mp->flag & Fini)
-			plan9ini(mp, nil);
-		if(file == 0 || *file == 0){
-			strcpy(ixdos, *ini);
-			if(p = strrchr(ixdos, '/'))
-				p++;
-			else
-				p = ixdos;
-			strcpy(p, "impc");
-			if(dosstat(mp, ixdos, &df) <= 0)
-				return -1;
-		}
-		else
-			strcpy(ixdos, file);
-		sprint(BOOTLINE, "%s!%d!%s", mp->type->name[Ndos], mp->dev, ixdos);
-		return dosboot(mp, ixdos);
-	}
-
-	return -1;
-}
-
-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 dombr, i, start;
-	Medium *mp;
-	Dosfile df;
-	Partition *pp;
-
-	for(tp = types; tp->cname; tp++){
-		if(type != Tany && type != tp->type || tp->init == 0)
-			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->seek = tp->seek;
-			mp->read = tp->read;
-			mp->type = tp;
-
-			if(mp->flag & Fboot){
-				if((mp->partition = (*tp->setpart)(i, "boot")) == 0)
-					mp->flag &= ~Fboot;
-				if((mp->flag & (Fflash|Fuart)) == 0)
-					(*tp->setpart)(i, "disk");
-			}
-
-			if(mp->flag & Fdos){
-				start = 0;
-				dombr = 1;
-				if(mp->type->setpart){
-					if(pp = (*mp->type->setpart)(i, "dos")){
-						if(start = pp->start)
-							dombr = 0;
-					}
-					(*tp->setpart)(i, "disk");
-				}
-				if(dosinit(mp, start, dombr) < 0)
-					mp->flag &= ~(Fini|Fdos);
-				else
-					print("dos init failed\n");
-			}
-
-			if(mp->flag & Fini){
-				mp->flag &= ~Fini;
-				for(ini = inis; *ini; ini++){
-					if(dosstat(mp, *ini, &df) <= 0)
-						continue;
-					mp->flag |= Fini;
-					break;
-				}
-			}
-
-			if((flag & mp->flag) && (dev == Dany || dev == i))
-				return mp;
-		}
-	}
-
-	return 0;
-}
-
-void
-main(void)
-{
-	Medium *mp;
-	int dev, flag, i, mode, tried, type, options;
-	char def[2*NAMELEN], file[2*NAMELEN], line[80], *p;
-	Type *tp;
-
-	machinit();
-	archinit();
-	meminit();
-	cpminit();
-	trapinit();
-	consinit();	/* screen and keyboard initially */
-	screeninit();
-	cpuidprint();
-	alarminit();
-	clockinit();
-	predawn = 0;
-	spllo();
-	options = archoptionsw();
-
-	mp = 0;
-	for(tp = types; tp->cname; tp++){
-		if(tp->type == Tether)
-			continue;
-		if((mp = probe(tp->type, Fini, Dany)) && (mp->flag & Fini)){
-			plan9ini(mp, nil);
-			break;
-		}
-	}
-
-	if(mp == 0 || (mp->flag & Fini) == 0)
-		plan9ini(nil, flashconfig(0));
-
-	//consinit();	/* establish new console location */
-
-	if((options & Snotflash) == 0 && flashbootable(0)){
-		print("Flash boot\n");
-		flashboot(0);
-	}
-
-	tried = 0;
-	mode = Mauto;
-	p = getconf("bootfile");
-	flag = 0;
-
-	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(parse(p, &type, &flag, &dev, file) == 0) {
-			print("Bad bootfile syntax: %s\n", p);
-			goto done;
-		}
-		mp = probe(type, flag, dev);
-		if(mp == 0) {
-			print("Cannot access device: %s\n", p);
-			goto done;
-		}
-		tried = boot(mp, flag, file);
-	}
-done:
-	if(tried == 0 && mode != Manual){
-		flag = Fany;
-		if(mode == Mlocal)
-			flag &= ~Fbootp;
-		if(options & Snotflash)
-			flag &= ~Fflash;
-		if((mp = probe(Tany, flag, Dany)) != 0)
-			boot(mp, flag & mp->flag, 0);
-	}
-
-	def[0] = 0;
-	probe(Tany, Fnone, Dany);
-
-	flag = 0;
-	for(tp = types; tp->cname; tp++){
-		for(mp = tp->media; mp; mp = mp->next){
-			if(flag == 0){
-				flag = 1;
-				print("Boot devices:");
-			}
-
-			if(mp->flag & Fbootp)
-				print(" %s!%d", mp->type->name[Nbootp], mp->dev);
-			if(mp->flag & Fdos)
-				print(" %s!%d", mp->type->name[Ndos], mp->dev);
-			if(mp->flag & (Fflash|Fuart) || mp->flag & Fboot)
-				print(" %s!%d", mp->type->name[Nboot], mp->dev);
-		}
-	}
-	if(flag)
-		print("\n");
-
-	for(;;){
-		if(getstr("boot from", line, sizeof(line), def) >= 0){
-			if(parse(line, &type, &flag, &dev, file)){
-				if(mp = probe(type, flag, dev))
-					boot(mp, flag, file);
-			}
-		}
-		def[0] = 0;
-	}
-}
-
-void
-machinit(void)
-{
-	memset(m, 0, sizeof(*m));
-	m->delayloop = 20000;
-	m->cpupvr = getpvr();
-	m->iomem = KADDR(INTMEM);
-}
-
-int
-getcfields(char* lp, char** fields, int n, char* sep)
-{
-	int i;
-
-	for(i = 0; lp && *lp && i < n; i++){
-		while(*lp && strchr(sep, *lp) != 0)
-			*lp++ = 0;
-		if(*lp == 0)
-			break;
-		fields[i] = lp;
-		while(*lp && strchr(sep, *lp) == 0){
-			if(*lp == '\\' && *(lp+1) == '\n')
-				*lp++ = ' ';
-			lp++;
-		}
-	}
-
-	return i;
-}
-
-static	Map	memv[512];
-static	RMap	rammap = {"physical memory"};
-
-void
-meminit(void)
-{
-	ulong e;
-
-	mapinit(&rammap, memv, sizeof(memv));
-	e = PADDR(&end);
-	mapfree(&rammap, e, 4*1024*1024-e);	/* fixed 4Mbytes is plenty for bootstrap */
-}
-
-void*
-ialloc(ulong n, int align)
-{
-	ulong a;
-	int s;
-
-	if(align <= 0)
-		align = 4;
-	s = splhi();
-	a = mapalloc(&rammap, 0, n, align);
-	splx(s);
-	if(a == 0)
-		panic("ialloc");
-	return memset(KADDR(a), 0, n);
-}
-
-void*
-malloc(ulong n)
-{
-	ulong *p;
-
-	n = ((n+sizeof(int)-1)&~(sizeof(int)-1))+2*sizeof(int);
-	p = ialloc(n, sizeof(int));
-	*p++ = 0xcafebeef;
-	*p++ = n;
-	return p;
-}
-
-void
-free(void *ap)
-{
-	int s;
-	ulong *p;
-
-	p = ap;
-	if(p){
-		if(*(p -= 2) != 0xcafebeef)
-			panic("free");
-		s = splhi();
-		mapfree(&rammap, (ulong)p, p[1]);
-		splx(s);
-	}
-}
-
-void
-sched(void)
-{
-}
--- a/os/boot/mpc/mem.h
+++ /dev/null
@@ -1,95 +1,0 @@
-/*
- * Memory and machine-specific definitions.  Used in C and assembler.
- */
-
-/*
- * Sizes
- */
-#define	BI2BY		8			/* bits per byte */
-#define BI2WD		32			/* bits per word */
-#define	BY2WD		4			/* bytes per word */
-#define	BY2PG		4096			/* bytes per page */
-#define	WD2PG		(BY2PG/BY2WD)		/* words per page */
-#define	PGSHIFT		12			/* log(BY2PG) */
-#define PGROUND(s)	(((s)+(BY2PG-1))&~(BY2PG-1))
-
-#define	MAXMACH		1			/* max # cpus system can run */
-#define	CACHELINELOG	4
-#define CACHELINESZ	(1<<CACHELINELOG)
-
-/*
- * Time
- */
-#define	HZ		(50)				/* clock frequency */
-#define	MS2HZ		(1000/HZ)			/* millisec per clock tick */
-#define	TK2SEC(t)	((t)/HZ)			/* ticks to seconds */
-#define	TK2MS(t)	((((ulong)(t))*1000)/HZ)	/* ticks to milliseconds */
-#define	MS2TK(t)	((((ulong)(t))*HZ)/1000)	/* milliseconds to ticks */
-#define	MHz	1000000
-
-/*
- * Fundamental values
- */
-
-#define	KZERO	0	/* bootstrap runs in real mode */
-#define	MACHSIZE	4096
-
-/*
- *  physical MMU
- */
-#define KSEG0	0x20000000
-#define	KSEGM	0xE0000000	/* mask to check which seg */
-
-/*
- * MSR bits
- */
-
-#define	POW	0x40000	/* enable power mgmt */
-#define	TGPR	0x20000	/* GPR0-3 remapped; 603/603e specific */
-#define	ILE	0x10000	/* interrupts little endian */
-#define	EE	0x08000	/* enable external/decrementer interrupts */
-#define	PR	0x04000	/* =1, user mode */
-#define	FPE	0x02000	/* enable floating point */
-#define	ME	0x01000	/* enable machine check exceptions */
-#define	FE0	0x00800
-#define	SE	0x00400	/* single-step trace */
-#define	BE	0x00200	/* branch trace */
-#define	FE1	0x00100
-#define	IP	0x00040	/* =0, vector to nnnnn; =1, vector to FFFnnnnn */
-#define	IR	0x00020	/* enable instruction address translation */
-#define	DR	0x00010	/* enable data address translation */
-#define	RI	0x00002	/* exception is recoverable */
-#define	LE	0x00001	/* little endian mode */
-
-#define	KMSR	(ME|FE0|FE1|FPE)
-#define	UMSR	(KMSR|PR|EE|IR|DR)
-
-/*
- * MPC82x addresses; mpc8bug is happy with these
- */
-#define	BCSRMEM	0x02100000
-#define	INTMEM	0x02200000
-#define	FLASHMEM	0x02800000
-#define	SDRAMMEM	0x03000000
-
-#define	DPRAM	(INTMEM+0x2000)
-#define	DPLEN1	0x400
-#define	DPLEN2	0x200
-#define	DPLEN3	0x100
-#define	DPBASE	(DPRAM+DPLEN1)
-
-#define	SCC1P	(INTMEM+0x3C00)
-#define	I2CP	(INTMEM+0x3C80)
-#define	MISCP	(INTMEM+0x3CB0)
-#define	IDMA1P	(INTMEM+0x3CC0)
-#define	SCC2P	(INTMEM+0x3D00)
-#define	SCC3P	(INTMEM+0x3E00)
-#define	SCC4P	(INTMEM+0x3F00)
-#define	SPIP	(INTMEM+0x3D80)
-#define	TIMERP	(INTMEM+0x3DB0)
-#define	SMC1P	(INTMEM+0x3E80)
-#define	DSP1P	(INTMEM+0x3EC0)
-#define	SMC2P	(INTMEM+0x3F80)
-#define	DSP2P	(INTMEM+0x3FC0)
-
-#define KEEP_ALIVE_KEY 0x55ccaa33	/* clock and rtc register key */
--- a/os/boot/mpc/mkfile
+++ /dev/null
@@ -1,116 +1,0 @@
-objtype=power
-OBJTYPE=power	# always
-<../../../mkconfig
-SYSTARG=$OSTARG	# always
-<$ROOT/mkfiles/mkfile-$SYSTARG-$OBJTYPE
-INSTALLDIR=$ROOT/Inferno/$OBJTYPE/bin	#path of directory where kernel is installed
-ARCH=fads	# selects board dependent code
-TARG=qb$ARCH
-OFILES=\
-	l.$O\
-	arch$ARCH.$O\
-	devuart.$O\
-	uartboot.$O\
-	alarm.$O\
-	bootp.$O\
-	clock.$O\
-	conf.$O\
-	console.$O\
-	cpm.$O\
-	defont0.$O\
-	donprint.$O\
-	dosboot.$O\
-	devether.$O\
-	etherscc.$O\
-	fblt.$O\
-	gbitbltclip.$O\
-	flash.$O\
-	main.$O\
-	plan9boot.$O\
-	qio.$O\
-	rmap.$O\
-	screen.$O\
-	init$ARCH.$O\
-	trap.$O\
-	zqs.$O\
-
-HFILES=\
-	boot.h\
-	dat.h\
-	fns.h\
-	io.h\
-	lib.h\
-	mem.h\
-	squeeze.h\
-	gnot.h\
-	arch$ARCH.h\
-
-LIBS=\
-	kern\
-
-LIBDIRS=$LIBS
-LIBNAMES=${LIBS:%=lib%.a}
-LIBFILES=${LIBS:%=$ROOT/$TARGMODEL/$OBJTYPE/lib/lib%.a}
-
-#all:NV:	$TARG k.mx f.mx
-all:NV:	$TARG
-install:V: 	$INSTALLDIR/$TARG
-installall:V: 	$INSTALLDIR/$TARG
-
-$INSTALLDIR/%: %
-	rm -f $INSTALLDIR/$stem && cp $stem $INSTALLDIR/$stem
-
-$TARG: $OFILES $LIBNAMES
-	$LD -o $target -l  -T0x140000 -R4 $OFILES $LIBFILES
-	ls -l $target
-
-qbrom$ARCH:	$OFILES $LIBNAMES
-	$LD -o $target -l -T0x02800100 -R0 -D0x140000 $OFILES $LIBFILES
-
-k.mx:	$TARG
-	ms2 -S 0x100 -a 0x100 -p 4 $TARG >k.mx
-
-f.mx:	qbrom$ARCH
-	ms2 -S 0x100 -a 0x2800100 -p 4 $prereq >f.mx
-
-%.$O:	%.s
-	$AS $stem.s
-
-%.$O:	%.c
-	$CC $CFLAGS $stem.c
-
-%.$O:	$HFILES
-
-lib%.a:V:	$SHELLTYPE-lib%.a
-
-rc-lib%.a nt-lib%.a:VQ:
-	echo '@{builtin cd ' $ROOT/lib$stem ';mk SHELLTYPE=$SHELLTYPE SYSTARG=$SYSTARG OBJTYPE=$OBJTYPE install}'
-	@{builtin cd  $ROOT/lib$stem ;mk 'SHELLTYPE='$SHELLTYPE 'SYSTARG='$SYSTARG 'OBJTYPE='$OBJTYPE install}
-
-sh-lib%.a:VQ:
-	echo "(cd $ROOT/lib$stem ; mk SHELLTYPE=$SHELLTYPE SYSTARG=$SYSTARG OBJTYPE=$OBJTYPE install)"
-	(cd $ROOT/lib$stem ; mk SHELLTYPE=$SHELLTYPE SYSTARG=$SYSTARG OBJTYPE=$OBJTYPE install)
-
-clock.$O floppy.$O trap.$O:	ureg.h
-conf.$O dosboot.$O main.$O:	dosfs.h
-ether.$O etherscc.$O:	etherif.h
-bootp.$O:	ip.h
-
-clean:V:
-	rm -f *.[$OS] [$OS].out y.tab.? y.debug y.output $TARG qboot k.mx f.mx romboot
-
-nuke-sh:QV:
-		for i in $LIBDIRS
-		do
-			echo "(cd $ROOT/lib$i ; mk SHELLTYPE=$SHELLTYPE SYSTARG=$SYSTARG OBJTYPE=$OBJTYPE nuke)"
-			(cd $ROOT/lib$i; mk 'SHELLTYPE='$SHELLTYPE 'SYSTARG='$SYSTARG 'OBJTYPE='$OBJTYPE nuke)
-		done
-
-nuke-rc nuke-nt:QV:
-		for (i in $LIBDIRS)
-		{
-			echo '@{cd $ROOT/lib$i ; mk SHELLTYPE=$SHELLTYPE SYSTARG=$SYSTARG OBJTYPE=$OBJTYPE nuke}'
-			@{cd $ROOT/lib$i; mk 'SHELLTYPE='$SHELLTYPE 'SYSTARG='$SYSTARG 'OBJTYPE='$OBJTYPE nuke}
-		}
-
-nuke:V:		clean nuke-$SHELLTYPE
--- a/os/boot/mpc/ms2.c
+++ /dev/null
@@ -1,179 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include <bio.h>
-#include <mach.h>
-
-void	record(uchar*, int);
-void	usage(void);
-void	dosegment(long, int);
-void trailer(ulong);
-
-enum
-{
-	Recordsize = 32,
-};
-
-int	dsegonly;
-int	supressend;
-int	binary;
-int	addr4;
-ulong	addr;
-ulong 	psize = 4096;
-ulong	startaddr = 0x030000;
-Biobuf 	stdout;
-Biobuf	bio;
-
-void
-main(int argc, char **argv)
-{
-	Dir dir;
-	Fhdr f;
-	int fd;
-
-	ARGBEGIN{
-	case 'd':
-		dsegonly++;
-		break;
-	case 's':
-		supressend++;
-		break;
-	case 'a':
-		addr = strtoul(ARGF(), 0, 0);
-		break;
-	case 'p':
-		psize = strtoul(ARGF(), 0, 0);
-		break;
-	case 'b':
-		binary++;
-		break;
-	case 'S':
-		startaddr = strtoul(ARGF(), 0, 0);
-		break;
-	case '4':
-		addr4++;
-		break;
-	default:
-		usage();
-	}ARGEND
-
-	if(argc != 1)
-		usage();
-
-	Binit(&stdout, 1, OWRITE);
-
-	fd = open(argv[0], OREAD);
-	if(fd < 0) {
-		fprint(2, "ms2: open %s: %r\n", argv[0]);
-		exits("open");
-	}
-
-	if(binary) {
-		if(dirfstat(fd, &dir) < 0) {
-			fprint(2, "ms2: stat failed %r");
-			exits("dirfstat");
-		}
-		Binit(&bio, fd, OREAD);
-		dosegment(0, dir.length);
-		if(supressend == 0)
-			trailer(startaddr);
-		Bterm(&stdout);
-		Bterm(&bio);
-		exits(0);
-	}
-
-	if(crackhdr(fd, &f) == 0){
-		fprint(2, "ms2: bad magic: %r\n");
-		exits("magic");
-	}
-	seek(fd, 0, 0);
-
-	Binit(&bio, fd, OREAD);
-
-	if(dsegonly)
-		dosegment(f.datoff, f.datsz);
-	else {
-		dosegment(f.txtoff, f.txtsz);
-		addr = (addr+(psize-1))&~(psize-1);
-		dosegment(f.datoff, f.datsz);
-	}
-
-	if(supressend == 0)
-		trailer(startaddr);
-
-	Bterm(&stdout);
-	Bterm(&bio);
-	exits(0);
-}
-
-void
-dosegment(long foff, int len)
-{
-	int l, n;
-	uchar buf[2*Recordsize];
-
-	Bseek(&bio, foff, 0);
-	for(;;) {
-		l = len;
-		if(l > Recordsize)
-			l = Recordsize;
-		n = Bread(&bio, buf, l);
-		if(n == 0)
-			break;
-		if(n < 0) {
-			fprint(2, "ms2: read error: %r\n");
-			exits("read");
-		}
-		record(buf, l);
-		len -= l;
-	}
-}
-
-void
-record(uchar *s, int l)
-{
-	int i;
-	ulong cksum;
-
-	if(addr4 || addr & (0xFF<<24)){
-		Bprint(&stdout, "S3%.2X%.8luX", l+5, addr);
-		cksum = l+5;
-		cksum += (addr>>24)&0xff;
-	}else{
-		Bprint(&stdout, "S2%.2X%.6X", l+4, addr);
-		cksum = l+4;
-	}
-	cksum += addr&0xff;
-	cksum += (addr>>8)&0xff;
-	cksum += (addr>>16)&0xff;
-
-	for(i = 0; i < l; i++) {
-		cksum += *s;
-		Bprint(&stdout, "%.2X", *s++);
-	}
-	Bprint(&stdout, "%.2X\n", (~cksum)&0xff);
-	addr += l;
-}
-
-void
-trailer(ulong a)
-{
-	ulong cksum;
-
-	cksum = 0;
-	if(addr4 || a & (0xFF<<24)){
-		Bprint(&stdout, "S7%.8luX", a);
-		cksum += (a>>24)&0xff;
-	}else
-		Bprint(&stdout, "S9%.6X", a);
-	cksum += a&0xff;
-	cksum += (a>>8)&0xff;
-	cksum += (a>>16)&0xff;
-	Bprint(&stdout, "%.2X\n", (~cksum)&0xff);
-}
-
-void
-usage(void)
-{
-	fprint(2, "usage: ms2 [-ds] [-a address] [-p pagesize] ?.out\n");
-	exits("usage");
-}
--- a/os/boot/mpc/plan9boot.c
+++ /dev/null
@@ -1,96 +1,0 @@
-#include	"u.h"
-#include	"lib.h"
-#include	"mem.h"
-#include	"dat.h"
-#include	"fns.h"
-
-char *premature = "premature EOF\n";
-
-/*
- *  read in a segment
- */
-static long
-readseg(int dev, long (*read)(int, void*, long), long len, long addr)
-{
-	char *a;
-	long n, sofar;
-
-	a = (char *)addr;
-	for(sofar = 0; sofar < len; sofar += n){
-		n = 8*1024;
-		if(len - sofar < n)
-			n = len - sofar;
-		n = (*read)(dev, a + sofar, n);
-		if(n <= 0)
-			break;
-		print(".");
-	}
-	return sofar;
-}
-
-/*
- *  boot
- */
-int
-plan9boot(int dev, long (*seek)(int, long), long (*read)(int, void*, long))
-{
-	long n;
-	long addr;
-	void (*b)(void);
-	Exec *ep;
-
-	if((*seek)(dev, 0) < 0)
-		return -1;
-
-	/*
-	 *  read header
-	 */
-	ep = (Exec *) ialloc(sizeof(Exec), 0);
-	n = sizeof(Exec);
-	if(readseg(dev, read, n, (long) ep) != n){
-		print(premature);
-		return -1;
-	}
-	if(GLLONG(ep->magic) != Q_MAGIC){
-		print("bad magic 0x%lux not a plan 9 executable!\n", GLLONG(ep->magic));
-		return -1;
-	}
-
-	/*
-	 *  read text
-	 */
-	addr = PADDR(GLLONG(ep->entry));
-	n = GLLONG(ep->text);
-	print("%d", n);
-	if(readseg(dev, read, n, addr) != n){
-		print(premature);
-		return -1;
-	}
-
-	/*
-	 *  read data (starts at first page after kernel)
-	 */
-	addr = PGROUND(addr+n);
-	n = GLLONG(ep->data);
-	print("+%d@%8.8lux", n, addr);
-	if(readseg(dev, read, n, addr) != n){
-		print(premature);
-		return -1;
-	}
-
-	/*
-	 *  bss and entry point
-	 */
-	print("+%d\nstart at 0x%lux\n", GLLONG(ep->bss), GLLONG(ep->entry));
-	uartwait();
-	scc2stop();
-	splhi();
-
-	/*
-	 *  Go to new code. It's up to the program to get its PC relocated to
-	 *  the right place.
-	 */
-	b = (void (*)(void))(PADDR(GLLONG(ep->entry)));
-	(*b)();
-	return 0;
-}
--- a/os/boot/mpc/qio.c
+++ /dev/null
@@ -1,128 +1,0 @@
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-
-struct Queue {
-	Block*	first;
-	Block*	last;
-	void	(*kick)(void*);
-	void*	arg;
-	long	len;
-};
-
-Block *
-iallocb(int n)
-{
-	Block *b;
-
-	b = (Block*)malloc(sizeof(Block)+n);
-	b->data = (uchar*)b + sizeof(Block);
-	b->rp = b->wp = b->data;
-	b->lim = b->data + n;
-	b->next = 0;
-	b->magic = 0xcafebee0;
-	return b;
-}
-
-void
-freeb(Block *b)
-{
-	if(b){
-		if(b->magic != 0xcafebee0)
-			panic("freeb");
-		b->magic = 0;
-		b->next = (Block*)0xdeadbabe;
-		free(b);
-	}
-}
-
-Queue *
-qopen(int limit, int msg, void (*kick)(void*), void *arg)
-{
-	Queue *q;
-
-	USED(limit, msg);
-	q = (Queue*)malloc(sizeof(Queue));
-	q->first = q->last = 0;
-	q->kick = kick;
-	q->arg = arg;
-	q->len = 0;
-	return q;
-}
-
-Block *
-qget(Queue *q)
-{
-	int s;
-	Block *b;
-
-	s = splhi();
-	if((b = q->first) != 0){
-		q->first = b->next;
-		b->next = 0;
-		q->len -= BLEN(b);
-		if(q->len < 0)
-			panic("qget");
-	}
-	splx(s);
-	return b;
-}
-
-void
-qbwrite(Queue *q, Block *b)
-{
-	int s;
-
-	s = splhi();
-	b->next = 0;
-	if(q->first == 0)
-		q->first = b;
-	else
-		q->last->next = b;
-	q->last = b;
-	q->len += BLEN(b);
-	splx(s);
-	if(q->kick)
-		q->kick(q->arg);
-}
-
-long
-qlen(Queue *q)
-{
-	return q->len;
-}
-
-int
-qbgetc(Queue *q)
-{
-	Block *b;
-	int s, c;
-
-	c = -1;
-	s = splhi();
-	while(c < 0 && (b = q->first) != nil){
-		if(b->rp < b->wp){
-			c = *b->rp++;
-			q->len--;
-		}
-		if(b->rp >= b->wp){
-			q->first = b->next;
-			b->next = nil;
-		}
-	}
-	splx(s);
-	return c;
-}
-
-void
-qbputc(Queue *q, int c)
-{
-	Block *b;
-
-	b = iallocb(1);
-	*b->wp++ = c;
-	qbwrite(q, b);
-}
--- a/os/boot/mpc/rmap.c
+++ /dev/null
@@ -1,104 +1,0 @@
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-
-void
-mapinit(RMap *rmap, Map *map, int size)
-{
-	lock(rmap);
-	rmap->map = map;
-	rmap->mapend = map+(size/sizeof(Map));
-	unlock(rmap);
-}
-
-void
-mapfree(RMap* rmap, ulong addr, int size)
-{
-	Map *mp;
-	ulong t;
-
-	if(size <= 0)
-		return;
-
-	lock(rmap);
-	for(mp = rmap->map; mp->addr <= addr && mp->size; mp++)
-		;
-
-	if(mp > rmap->map && (mp-1)->addr+(mp-1)->size == addr){
-		(mp-1)->size += size;
-		if(addr+size == mp->addr){
-			(mp-1)->size += mp->size;
-			while(mp->size){
-				mp++;
-				(mp-1)->addr = mp->addr;
-				(mp-1)->size = mp->size;
-			}
-		}
-	}
-	else{
-		if(addr+size == mp->addr && mp->size){
-			mp->addr -= size;
-			mp->size += size;
-		}
-		else do{
-			if(mp >= rmap->mapend){
-				print("mapfree: %s: losing 0x%uX, %d\n",
-					rmap->name, addr, size);
-				break;
-			}
-			t = mp->addr;
-			mp->addr = addr;
-			addr = t;
-			t = mp->size;
-			mp->size = size;
-			mp++;
-		}while(size = t);
-	}
-	unlock(rmap);
-}
-
-ulong
-mapalloc(RMap* rmap, ulong addr, int size, int align)
-{
-	Map *mp;
-	ulong maddr, oaddr;
-
-	lock(rmap);
-	for(mp = rmap->map; mp->size; mp++){
-		maddr = mp->addr;
-
-		if(addr){
-			if(maddr > addr)
-				continue;
-			if(addr+size > maddr+mp->size)
-				break;
-			maddr = addr;
-		}
-
-		if(align > 0)
-			maddr = ((maddr+align-1)/align)*align;
-		if(mp->addr+mp->size-maddr < size)
-			continue;
-
-		oaddr = mp->addr;
-		mp->addr = maddr+size;
-		mp->size -= maddr-oaddr+size;
-		if(mp->size == 0){
-			do{
-				mp++;
-				(mp-1)->addr = mp->addr;
-			}while((mp-1)->size = mp->size);
-		}
-
-		unlock(rmap);
-		if(oaddr != maddr)
-			mapfree(rmap, oaddr, maddr-oaddr);
-
-		return maddr;
-	}
-	unlock(rmap);
-
-	return 0;
-}
--- a/os/boot/mpc/screen.c
+++ /dev/null
@@ -1,242 +1,0 @@
-#include	"all.h"
-#include	<libg.h>
-#include	<gnot.h>
-
-enum {
-	Colldepth		= 3,
-	Colmaxx		= 640,
-	Colmaxxvis	= 640,
-	Colmaxy		= 480,
-};
-
-#define	MINX	8
-
-extern	GSubfont	defont0;
-
-struct{
-	Point	pos;
-	int	bwid;
-}out;
-
-typedef struct Mode Mode;
-struct Mode {
-	int	x;
-	int	y;
-	int	d;
-	char*	aperture;
-	int	apsize;
-};
-
-GBitmap	gscreen;
-Point	gchar(GBitmap*, Point, GFont*, int, Fcode);
-int	setcolor(ulong, ulong, ulong, ulong);
-static	void	lcdinit(Mode*);
-
-void
-screeninit(void)
-{
-	Mode m;
-
-	m.x = Colmaxx;
-	m.y = Colmaxy;
-	m.d = Colldepth;
-	m.aperture = 0;
-	lcdinit(&m);
-	if(m.aperture == 0)
-		return;
-	gscreen.ldepth = 3;
-	gscreen.base = (ulong*)m.aperture;
-	gscreen.width = Colmaxx/BY2WD;
-	gscreen.r = Rect(0, 0, Colmaxxvis, Colmaxy);
-	gscreen.clipr = gscreen.r;
-	/*
-	 * For now, just use a fixed colormap:
-	 * 0 == white and 255 == black
-	 */
-	setcolor(0, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
-	setcolor(255, 0x00000000, 0x00000000, 0x00000000);
-
-	gbitblt(&gscreen, Pt(0, 0), &gscreen, gscreen.r, Zero);
-	out.pos.x = MINX;
-	out.pos.y = 0;
-	out.bwid = defont0.info[' '].width;
-}
-
-void
-screenputc(int c)
-{
-	Fontchar *i;
-	Point p;
-
-	if(gscreen.base == nil)
-		return;
-	switch(c){
-	case '\n':
-		out.pos.x = MINX;
-		out.pos.y += defont0.height;
-		if(out.pos.y > gscreen.r.max.y-defont0.height)
-			out.pos.y = gscreen.r.min.y;
-		gbitblt(&gscreen, Pt(0, out.pos.y), &gscreen,
-		  Rect(0, out.pos.y, gscreen.r.max.x, out.pos.y+2*defont0.height),
-		  Zero);
-		break;
-	case '\t':
-		out.pos.x += (8-((out.pos.x-MINX)/out.bwid&7))*out.bwid;
-		if(out.pos.x >= gscreen.r.max.x)
-			screenputc('\n');
-		break;
-	case '\b':
-		if(out.pos.x >= out.bwid+MINX){
-			out.pos.x -= out.bwid;
-			screenputc(' ');
-			out.pos.x -= out.bwid;
-		}
-		break;
-	default:
-		if(out.pos.x >= gscreen.r.max.x-out.bwid)
-			screenputc('\n');
-		c &= 0x7f;
-		if(c <= 0 || c >= defont0.n)
-			break;
-		i = defont0.info + c;
-		p = out.pos;
-		gbitblt(&gscreen, Pt(p.x+i->left, p.y), defont0.bits,
-			Rect(i[0].x, 0, i[1].x, defont0.height),
-			S);
-		out.pos.x = p.x + i->width;
-		break;
-	}
-}
-
-void
-screenputs(char *s, int n)
-{
-	while(n-- > 0)
-		screenputc(*s++);
-}
-
-/*
- * See section 5.2.1 (page 5-6) of the MPC823 manual
- */
-static uchar lcdclock[17] = {	/* (a<<2)|b => divisor of (1<<a)*((b<<1)+1) */
-	0, 0, (1<<2), 1,
-	(2<<2), 2, (1<<2)|1, 3,
-	(3<<2), (1<<2)|2, (1<<2)|2, (2<<2)|1,
-	(2<<2)|1, (1<<2)|3, (1<<2)|3, (4<<2),
-	(4<<2)
-};
-	
-/*
- * support for the Sharp LQ64D341 TFT colour display
- */
-
-enum {
-	COLS = 640,
-	ROWS = 480,
-	LDEPTH = 3,	/* screen depth */
-	LCDFREQ = 25000000,
-
-	/* lccr */
-	ClockLow = 1<<11,
-	OELow = 1<<10,
-	HsyncLow = 1<<9,
-	VsyncLow = 1<<8,
-	DataLow = 1<<7,
-	Passive8 = 1<<4,
-	DualScan = 1<<3,
-	IsColour = 1<<2,
-	IsTFT = 1<<1,
-	Enable = 1<<0,
-
-	/* lchcr */
-	BigEndian = 1<<24,
-	AT7 = 7<<21,	/* access type */
-
-	/* sdcr */
-	LAM = 1<<6,	/* ``LCD aggressive mode'' */
-};
-
-/*
- * TO DO: most of the data could come from a table
- */
-static void
-lcdinit(Mode *mode)
-{
-	IMM *io;
-	int i, d;
-	long hz;
-
-	io = m->iomem;
-	mode->y = ROWS;
-	mode->x = COLS;
-	mode->d = LDEPTH;
-	mode->aperture = ialloc(mode->x*mode->y, 16);
-	mode->apsize = mode->x*mode->y;
-
-	io->sdcr &= ~LAM;	/* MPC823 errata: turn off LAM before disabling controller */
-	io->lcfaa = PADDR(mode->aperture);
-	io->lccr = (((mode->x*mode->y*(1<<LDEPTH)+127)/128) << 17) | (LDEPTH << 5) | IsColour | IsTFT | OELow | VsyncLow | ClockLow;
-
-	switch(LDEPTH){
-	default:
-	case 0:
-		/* monochrome/greyscale identity map */
-		for(i=0; i<16; i++)
-			io->lcdmap[i] = i;
-		break;
-	case 2:
-		/* 4-bit grey scale map */
-		for(i=0; i<16; i++)
-			io->lcdmap[0] = (i<<8)|(i<<4)|i;
-		break;
-	case 3:
-		/* 8-bit linear map */
-		for(i=0; i<256; i++)
-			io->lcdmap[i] = (i<<8)|(i<<4)|i;
-		break;
-	}
-
-	io->lcvcr = (mode->y << 11) | (1<<28) | 33;	/* 2 line vsync pulse, 34 line wait between frames */
-	io->lchcr = (mode->x<<10) | BigEndian | 228;	/* clock cycles between lines */
-
-	hz = m->cpuhz;
-	d = hz/LCDFREQ;
-	if(hz/d > LCDFREQ)
-		d++;
-	if(d >= 16)
-		d = 16;
-
-	/*
-	 * enable LCD outputs
-	 */
-	io->pddat = 0;
-	io->pdpar = 0x1fff;
-io->pdpar &= ~SIBIT(6);	/* 823 bug fix? */
-	io->pddir = 0x1fff;
-	io->pbpar |= IBIT(31) | IBIT(19) | IBIT(17);
-	io->pbdir |= IBIT(31) | IBIT(19) | IBIT(17);
-	io->pbodr &= ~(IBIT(31) | IBIT(19) | IBIT(17));
-
-	eieio();
-	io->sccrk = KEEP_ALIVE_KEY;
-	eieio();
-	io->sccr  = (io->sccr & ~0x1F) | lcdclock[d];
-	eieio();
-	io->sccrk = ~KEEP_ALIVE_KEY;
-	eieio();
-	gscreen.width = gscreen.width;	/* access external memory before enabling (mpc823 errata) */
-	io->lcsr = 7;	/* clear status */
-	eieio();
-	io->lccr |= Enable;
-	archbacklight(1);
-}
-
-int
-setcolor(ulong p, ulong r, ulong g, ulong b)
-{
-	r >>= 28;
-	g >>= 28;
-	b >>= 28;
-	m->iomem->lcdmap[~p&0xFF] = (r<<8) | (g<<4) | b;	/* TO DO: it's a function of the ldepth */
-	return 1;
-}
--- a/os/boot/mpc/sload.c
+++ /dev/null
@@ -1,71 +1,0 @@
-/*
- * send S records to rpcg
- */
-
-#include <u.h>
-#include <libc.h>
-#include <bio.h>
-
-static	int	dbg;
-static	char	buf[2048];
-static	int	run=1;
-static	void	stuffbym(char*, int, int);
-static	void	getdot(void);
-
-void
-main(int argc, char **argv)
-{
-	int n;
-	char *l;
-	Biobuf *f;
-	static int p;
-
-	ARGBEGIN{
-	case 'd': dbg++; break;
-	case 'n': run=0; break;
-	}ARGEND
-
-	f = Bopen(*argv? *argv: "k.mx", OREAD);
-	if(f == 0) {
-		fprint(2, "sload: cannot open k.mx: %r\n");
-		exits("sload");
-	}
-	getdot();
-	while((l = Brdline(f, '\n')) != 0) {
-		l[Blinelen(f)-1] = '\r';
-		stuffbym(l, Blinelen(f), 16);
-		getdot();
-		if(++p % 25 == 0)
-			write(2, ".", 1);
-	}
-	exits(0);
-}
-
-static void
-stuffbym(char *l, int n, int m)
-{
-	int nr, ns;
-
-	while(n > 0) {
-		ns = n;
-		if(ns > m)
-			ns = m;
-		write(1, l, ns);
-		l += ns;
-		n -= ns;
-	}
-}
-
-static void
-getdot(void)
-{
-	char c;
-
-	for(;;){
-		if(read(0, &c, 1) != 1)
-			exits("bang");
-		write(2, &c, 1);
-		if(c == '.')
-			break;
-	}
-}
--- a/os/boot/mpc/squeeze.h
+++ /dev/null
@@ -1,34 +1,0 @@
-
-/*
- * squeezed file format:
- *	Sqhdr
- *	original Exec header
- *	two Squeeze tables
- *	squeezed segment
- *	unsqueezed segment, if any
- */
-#define	SQMAGIC	(ulong)0xFEEF0F1E
-
-typedef struct Sqhdr Sqhdr;
-struct Sqhdr {
-	uchar	magic[4];	/* SQMAGIC */
-	uchar	text[4];	/* squeezed length of text (excluding tables) */
-	uchar	data[4];	/* squeezed length of data (excluding tables) */
-	uchar	asis[4];	/* length of unsqueezed segment */
-	uchar	toptxt[4];	/* value for 0 encoding in text */
-	uchar	topdat[4];	/* value for 0 encoding in data */
-	uchar	sum[4];	/* simple checksum of unsqueezed data */
-	uchar	flags[4];
-};
-#define	SQHDRLEN	(8*4)
-
-/*
- * certain power instruction types are rearranged by sqz
- * so as to move the variable part of the instruction word to the
- * low order bits.  note that the mapping is its own inverse.
- */
-#define	QREMAP(X)\
-	switch((X)>>26){\
-	case 19: case 31: case 59: case 63:\
-		(X) = (((X) & 0xFC00F801) | (((X)>>15)&0x7FE) | (((X)&0x7FE)<<15));\
-	}
--- a/os/boot/mpc/trap.c
+++ /dev/null
@@ -1,233 +1,0 @@
-#include "boot.h"
-
-enum 
-{
-	Maxhandler=	32+16,		/* max number of interrupt handlers */
-};
-
-typedef struct Handler	Handler;
-struct Handler
-{
-	void	(*r)(Ureg*, void*);
-	void	*arg;
-	Handler	*next;
-	int	edge;
-};
-
-struct
-{
-	Handler	*ivec[128];
-	Handler	h[Maxhandler];
-	int	free;
-} halloc;
-
-char	*excname[] = {
-	"reserved 0",
-	"system reset",
-	"machine check",
-	"data access",
-	"instruction access",
-	"external interrupt",
-	"alignment",
-	"program exception",
-	"floating-point unavailable",
-	"decrementer",
-	"reserved A",
-	"reserved B",
-	"system call",
-	"trace trap",
-	"floating point assist",
-	"reserved F",
-	"software emulation",
-	"ITLB miss",
-	"DTLB miss",
-	"ITLB error",
-	"DTLB error",
-};
-
-char *regname[]={
-	"CAUSE",	"SRR1",
-	"PC",		"GOK",
-	"LR",		"CR",
-	"XER",	"CTR",
-	"R0",		"R1",
-	"R2",		"R3",
-	"R4",		"R5",
-	"R6",		"R7",
-	"R8",		"R9",
-	"R10",	"R11",
-	"R12",	"R13",
-	"R14",	"R15",
-	"R16",	"R17",
-	"R18",	"R19",
-	"R20",	"R21",
-	"R22",	"R23",
-	"R24",	"R25",
-	"R26",	"R27",
-	"R28",	"R29",
-	"R30",	"R31",
-};
-
-static	void	intr(Ureg*);
-
-void
-sethvec(int v, void (*r)(void))
-{
-	ulong *vp, pa, o;
-
-	if((ulong)r & 3)
-		panic("sethvec");
-	vp = (ulong*)KADDR(v);
-	vp[0] = 0x7c1043a6;	/* MOVW R0, SPR(SPRG0) */
-	vp[1] = 0x7c0802a6;	/* MOVW LR, R0 */
-	vp[2] = 0x7c1243a6;	/* MOVW R0, SPR(SPRG2) */
-	pa = PADDR(r);
-	o = pa >> 25;
-	if(o != 0 && o != 0x7F){
-		/* a branch too far: running from ROM */
-		vp[3] = (15<<26)|(pa>>16);	/* MOVW $r&~0xFFFF, R0 */
-		vp[4] = (24<<26)|(pa&0xFFFF);	/* OR $r&0xFFFF, R0 */
-		vp[5] = 0x7c0803a6;	/* MOVW	R0, LR */
-		vp[6] = 0x4e800021;	/* BL (LR) */
-	}else
-		vp[3] = (18<<26)|(pa&0x3FFFFFC)|3;	/* bla */
-}
-
-#define	LEV(n)	(((n)<<1)|1)
-#define	IRQ(n)	(((n)<<1)|0)
-
-void
-setvec(int v, void (*r)(Ureg*, void*), void *arg)
-{
-	Handler *h;
-	IMM *io;
-
-	if(halloc.free >= Maxhandler)
-		panic("out of interrupt handlers");
-	v -= VectorPIC;
-	h = &halloc.h[halloc.free++];
-	h->next = halloc.ivec[v];
-	h->r = r;
-	h->arg = arg;
-	halloc.ivec[v] = h;
-
-	/*
-	 * enable corresponding interrupt in SIU/CPM
-	 */
-
-	io = m->iomem;
-	if(v >= VectorCPIC){
-		v -= VectorCPIC;
-		io->cimr |= 1<<(v&0x1F);
-	}
-	else if(v >= VectorIRQ)
-		io->simask |= 1<<(31-IRQ(v&7));
-	else
-		io->simask |= 1<<(31-LEV(v));
-}
-
-void
-trapinit(void)
-{
-	int i;
-	IMM *io;
-
-	io = m->iomem;
-	io->sypcr &= ~(3<<2);	/* disable watchdog (821/823) */
-	io->simask = 0;	/* mask all */
-	io->siel = ~0;	/* edge sensitive, wake on all */
-	io->cicr = 0;	/* disable CPM interrupts */
-	io->cipr = ~0;	/* clear all interrupts */
-	io->cimr = 0;	/* mask all events */
-	io->cicr = (0xE1<<16)|(CPIClevel<<13)|(0x1F<<8);
-	io->cicr |= 1 << 7;	/* enable */
-	io->tbscrk = KEEP_ALIVE_KEY;
-	io->tbscr = 1;	/* TBE */
-	io->simask |= 1<<(31-LEV(CPIClevel));	/* CPM's level */
-	io->tbk = KEEP_ALIVE_KEY;
-	eieio();
-	putdec(~0);
-
-	/*
-	 * set all exceptions to trap
-	 */
-	for(i = 0x0; i < 0x3000; i += 0x100)
-		sethvec(i, exception);
-}
-
-void
-dumpregs(Ureg *ur)
-{
-	int i;
-	ulong *l;
-	l = &ur->cause;
-	for(i=0; i<sizeof regname/sizeof(char*); i+=2, l+=2)
-		print("%s\t%.8lux\t%s\t%.8lux\n", regname[i], l[0], regname[i+1], l[1]);
-}
-
-void
-trap(Ureg *ur)
-{
-	int c;
-
-	c = ur->cause >> 8;
-	switch(c){
-	default:
-		{extern int predawn; predawn = 1;}
-		if(c < 0 || c >= nelem(excname))
-			print("exception/interrupt #%x\n", c);
-		else
-			print("exception %s\n", excname[c]);
-		dumpregs(ur);
-		/* spllo(); */
-		print("^P to reset\n");
-		for(;;)
-			;
-
-	case 0x09:	/* decrementer */
-		clockintr(ur, 0);
-		return;
-
-	case 0x05:	/* external interrupt */
-		intr(ur);
-		break;
-	}
-}
-
-static void
-intr(Ureg *ur)
-{
-	int b, v;
-	Handler *h;
-	IMM *io;
-
-	io = m->iomem;
-	b = io->sivec>>2;
-	v = b>>1;
-	if(b & 1) {
-		if(v == CPIClevel){
-			io->civr = 1;
-			eieio();
-			v = VectorCPIC+(io->civr>>11);
-		}
-	}else
-		v += VectorIRQ;
-	h = halloc.ivec[v];
-	if(h == nil){
-		for(;;)
-			;
-		//print("unknown interrupt %d pc=0x%lux\n", v, ur->pc);
-		return;
-	}
-	if(h->edge)
-		io->sipend |= 1<<(31-b);
-	/*
-	 *  call the interrupt handlers
-	 */
-	do {
-		(*h->r)(ur, h->arg);
-		h = h->next;
-	} while(h != nil);
-	if(v >= VectorCPIC)
-		io->cisr |= 1<<(v-VectorCPIC);
-}
--- a/os/boot/mpc/uartboot.c
+++ /dev/null
@@ -1,189 +1,0 @@
-#include "boot.h"
-
-/*
- * this doesn't yet use the crc
- */
-
-typedef struct Uboot Uboot;
-struct Uboot {
-	Queue*	iq;
-	Block*	partial;
-	ulong	csum;
-	long	bno;
-	uchar	buf[64];
-	int	nleft;
-	int	ntimeout;
-};
-
-static	Uboot	uboot;
-ulong	crc32(void *buf, int n, ulong crc);
-
-static void
-uartbrecv(uchar *p, int n)
-{
-	Uboot *ub;
-	Block *b;
-
-	ub = &uboot;
-	if(n > 0 && ub->iq != nil){
-		b = iallocb(n);
-		memmove(b->wp, p, n);
-		b->wp += n;
-		qbwrite(ub->iq, b);
-	}
-}
-
-int
-uartinit(void)
-{
-	return 1<<0;
-}
-
-Partition*
-setuartpart(int, char *s)
-{
-	static Partition pp[1];
-
-	if(strcmp(s, "boot") != 0 && strcmp(s, "disk") != 0)
-		return 0;
-	pp[0].start = 0;
-	pp[0].end = 2*1024*1024;
-	strcpy(pp[0].name, "boot");
-	return pp;
-}
-
-long
-uartseek(int, long)
-{
-	/* start the boot */
-	if(uboot.iq == nil)
-		uboot.iq = qopen(64*1024, 0, 0, 0);
-	if(uboot.partial){
-		freeb(uboot.partial);
-		uboot.partial = 0;
-	}
-	print("uart: start transmission\n");
-	uartsetboot(uartbrecv);
-	uboot.csum = ~0;
-	uboot.bno = 0;
-	uboot.nleft = 0;
-	uboot.ntimeout = 0;
-	return 0;
-}
-
-static long
-uartreadn(void *buf, int nb)
-{
-	ulong start;
-	Uboot *ub;
-	int l;
-	Block *b;
-	uchar *p;
-
-	p = buf;
-	ub = &uboot;
-	start = m->ticks;
-	while(nb > 0){
-		b = ub->partial;
-		ub->partial = nil;
-		if(b == nil){
-			ub->ntimeout = 0;
-			while((b = qget(ub->iq)) == 0){
-				if(TK2MS(m->ticks - start) >= 15*1000){
-					if(++ub->ntimeout >= 3){
-						print("uart: timeout\n");
-						return 0;
-					}
-					uartputs("n", 1);
-				}
-			}
-		}
-		l = BLEN(b);
-		if(l > nb)
-			l = nb;
-		memmove(p, b->rp, l);
-		b->rp += l;
-		if(b->rp >= b->wp)
-			freeb(b);
-		else
-			ub->partial = b;
-		nb -= l;
-		p += l;
-	}
-	return p-(uchar*)buf;
-}
-
-long
-uartread(int, void *buf, long n)
-{
-	uchar *p;
-	int l;
-	static uchar lbuf[64];
-
-	p = buf;
-	if((l = uboot.nleft) > 0){
-		if(l > n)
-			l = n;
-		uboot.nleft -= l;
-		memmove(p, uboot.buf, l);
-		p += l;
-		n -= l;
-	}
-	while(n > 0){
-		l = uartreadn(lbuf, sizeof(lbuf));
-		if(l < sizeof(lbuf))
-			return 0;
-		if(l > n){
-			uboot.nleft = l-n;
-			memmove(uboot.buf, lbuf+n, uboot.nleft);
-			l = n;
-		}
-		memmove(p, lbuf, l);
-		n -= l;
-		p += l;
-		uboot.bno++;
-		uartputs("y", 1);
-	}
-	return p-(uchar*)buf;
-}
-
-/*
- * from Rob Warnock
- */
-static	ulong	crc32tab[256];	/* initialised on first call to crc32 */
-
-enum {
-	CRC32POLY = 0x04c11db7     /* AUTODIN II, Ethernet, & FDDI */
-};
-
-/*
- * Build auxiliary table for parallel byte-at-a-time CRC-32.
- */
-static void
-initcrc32(void)
-{
-	int i, j;
-	ulong c;
-
-	for(i = 0; i < 256; i++) {
-		for(c = i << 24, j = 8; j > 0; j--)
-			if(c & (1<<31))
-				c = (c<<1) ^ CRC32POLY;
-			else
-				c <<= 1;
-		crc32tab[i] = c;
-	}
-}
-
-ulong
-crc32(void *buf, int n, ulong crc)
-{
-	uchar *p;
-
-	if(crc32tab[1] == 0)
-		initcrc32();
-	crc = ~crc;
-	for(p = buf; --n >= 0;)
-		crc = (crc << 8) ^ crc32tab[(crc >> 24) ^ *p++];
-	return ~crc;
-}
--- a/os/boot/mpc/ureg.h
+++ /dev/null
@@ -1,43 +1,0 @@
-struct Ureg
-{
-	ulong	cause;
-	union { ulong	srr1; ulong status;};
-	ulong	pc;	/* SRR0 */
-	ulong	pad;
-	ulong	lr;
-	ulong	cr;
-	ulong	xer;
-	ulong	ctr;
-	ulong	r0;
-	union{ ulong r1;	ulong	sp;	ulong	usp; };
-	ulong	r2;
-	ulong	r3;
-	ulong	r4;
-	ulong	r5;
-	ulong	r6;
-	ulong	r7;
-	ulong	r8;
-	ulong	r9;
-	ulong	r10;
-	ulong	r11;
-	ulong	r12;
-	ulong	r13;
-	ulong	r14;
-	ulong	r15;
-	ulong	r16;
-	ulong	r17;
-	ulong	r18;
-	ulong	r19;
-	ulong	r20;
-	ulong	r21;
-	ulong	r22;
-	ulong	r23;
-	ulong	r24;
-	ulong	r25;
-	ulong	r26;
-	ulong	r27;
-	ulong	r28;
-	ulong	r29;
-	ulong	r30;
-	ulong	r31;
-};
--- a/os/boot/mpc/zqs.c
+++ /dev/null
@@ -1,234 +1,0 @@
-#include "boot.h"
-#include "squeeze.h"
-
-/*
- * for details of `unsqueeze' see:
- *
- * %A Mark Taunton
- * %T Compressed Executables: An Exercise in Thinking Small
- * %P 385-404
- * %I USENIX
- * %B USENIX Conference Proceedings
- * %D Summer 1991
- * %C Nashville, TN
- *
- * several of the unimplemented improvements described in the paper
- * have been implemented here
- *
- * there is a further transformation on the powerpc (QFLAG!=0) to shuffle bits
- * in certain instructions so as to push the fixed bits to the top of the word.
- */
-
-#define	EXECHDRLEN	(8*4)
-
-typedef struct Squeeze Squeeze;
-struct Squeeze {
-	int	n;
-	ulong	tab[7*256];
-};
-
-#define	GET4(p)	(((((((p)[0]<<8)|(p)[1])<<8)|(p)[2])<<8)|(p)[3])
-
-/*
- * for speed of unsqueezing from Flash, certain checks are
- * not done inside the loop (as they would be in the unsqueeze program zqs),
- * but instead the checksum is expected to catch corrupted files.
- * in fact the Squeeze array bounds can't be exceeded in practice
- * because the tables are always full for a squeezed kernel.
- */
-enum {
-	QFLAG = 1,	/* invert powerpc-specific code transformation */
-	CHECK = 0,	/* check precise bounds in Squeeze array (otherwise checksum detects error) */
-};
-
-static	ulong	chksum;
-static	int	rdtab(Block*, Squeeze*, int);
-static	ulong*	unsqueeze(ulong*, uchar*, uchar*, Squeeze*, Squeeze*, ulong);
-static	uchar*	unsqzseg(uchar*, Block*, long, long, char*);
-static	Alarm*	unsqzal;
-
-int
-issqueezed(uchar *b)
-{
-	return GET4(b) == SQMAGIC? GET4(b+SQHDRLEN): 0;
-}
-
-static void
-unsqzdot(Alarm*)
-{
-	unsqzal = alarm(500, unsqzdot, nil);
-	print(".");
-}
-
-long
-unsqueezef(Block *b, ulong *entryp)
-{
-	uchar *loada, *wp;
-	ulong toptxt, topdat, oldsum;
-	long asis, nst, nsd;
-	Sqhdr *sqh;
-	Exec *ex;
-
-	if(BLEN(b) < SQHDRLEN+EXECHDRLEN)
-		return -1;
-	sqh = (Sqhdr*)b->rp;
-	if(GET4(sqh->magic) != SQMAGIC)
-		return -1;
-	chksum = 0;
-	toptxt = GET4(sqh->toptxt);
-	topdat = GET4(sqh->topdat);
-	oldsum = GET4(sqh->sum);
-	asis = GET4(sqh->asis);
-	nst = GET4(sqh->text);
-	nsd = GET4(sqh->data);
-	b->rp += SQHDRLEN;
-	ex = (Exec*)b->rp;
-	if(GET4(ex->magic) != Q_MAGIC){
-		print("zqs: not powerPC executable\n");
-		return -1;
-	}
-	*entryp = GET4(ex->entry);
-	b->rp += EXECHDRLEN;
-	loada = KADDR(PADDR(*entryp));
-	wp = unsqzseg(loada, b, nst, toptxt, "text");
-	if(wp == nil){
-		print("zqs: format error\n");
-		return -1;
-	}
-	if(nsd){
-		wp = (uchar*)PGROUND((ulong)wp);
-		wp = unsqzseg(wp, b, nsd, topdat, "data");
-		if(wp == nil){
-			print("zqs: format error\n");
-			return -1;
-		}
-	}
-	if(asis){
-		memmove(wp, b->rp, asis);
-		wp += asis;
-		b->rp += asis;
-	}
-	if(chksum != oldsum){
-		print("\nsqueezed kernel: checksum error: %8.8lux need %8.8lux\n", chksum, oldsum);
-		return -1;
-	}
-	return wp-loada;
-}
-
-static uchar *
-unsqzseg(uchar *wp, Block *b, long ns, long top, char *what)
-{
-	static Squeeze sq3, sq4;
-
-	print("unpack %s %8.8lux %lud:", what, wp, ns);
-	if(ns == 0)
-		return wp;
-	if(rdtab(b, &sq3, 0) < 0)
-		return nil;
-	if(rdtab(b, &sq4, 8) < 0)
-		return nil;
-	if(BLEN(b) < ns){
-		print(" **size error\n");
-		return nil;
-	}
-	unsqzal = alarm(500, unsqzdot, nil);
-	wp = (uchar*)unsqueeze((ulong*)wp, b->rp, b->rp+ns, &sq3, &sq4, top);
-	cancel(unsqzal);
-	unsqzal = nil;
-	print("\n");
-	if(wp == nil){
-		print("zqs: corrupt squeezed data stream\n");
-		return nil;
-	}
-	b->rp += ns;
-	return wp;
-}
-
-static ulong*
-unsqueeze(ulong *wp, uchar *rp, uchar *ep, Squeeze *sq3, Squeeze *sq4, ulong top)
-{
-	ulong nx, csum;
-	int code, n;
-
-	if(QFLAG){
-		QREMAP(top);	/* adjust top just once, outside the loop */
-	}
-	csum = chksum;
-	while(rp < ep){
-		/* no function calls within this loop for speed */
-		code = *rp;
-		rp++;
-		n = 0;
-		nx = code>>4;
-		do{
-			if(nx == 0){
-				nx = top;
-			}else{
-				if(nx==1){
-					nx = (((((rp[3]<<8)|rp[2])<<8)|rp[1])<<8)|rp[0];
-					rp += 4;
-				}else if(nx <= 8){	/* 2 to 8 */
-					nx = ((nx-2)<<8) | rp[0];
-					if(CHECK && nx >= sq4->n)
-						return nil;	/* corrupted file */
-					nx = sq4->tab[nx] | rp[1];
-					rp += 2;
-				}else{	/* 9 to 15 */
-					nx = ((nx-9)<<8) | rp[0];
-					if(CHECK && nx >= sq3->n)
-						return nil;	/* corrupted file */
-					nx = sq3->tab[nx];
-					rp++;
-				}
-				if(rp > ep)
-					return nil;	/* corrupted file */
-				if(QFLAG){
-					QREMAP(nx);
-				}
-			}
-			*wp = nx;
-			wp++;
-			csum += nx;
-			nx = code & 0xF;
-		}while(++n == 1);
-	}
-	chksum = csum;
-	return wp;
-}
-
-static int
-rdtab(Block *b, Squeeze *sq, int shift)
-{
-	uchar *p, *ep;
-	ulong v, w;
-	int i;
-
-	if(BLEN(b) < 2)
-		return -1;
-	i = (b->rp[0]<<8) | b->rp[1];
-	if(1)
-		print(" T%d", i);
-	b->rp += 2;
-	if((i -= 2) > 0){
-		if(BLEN(b) < i)
-			return -1;
-	}
-	sq->n = 0;
-	p = b->rp;
-	ep = b->rp+i;
-	b->rp += i;
-	v = 0;
-	while(p < ep){
-		w = 0;
-		do{
-			if(p >= ep)
-				return -1;
-			w = (w<<7) | (*p & 0x7F);
-		}while(*p++ & 0x80);
-		v += w;
-		if(0)
-			print("%d %8.8lux %8.8lux\n", sq->n, v, w);
-		sq->tab[sq->n++] = v<<shift;
-	}
-	return 0;
-}
--- a/os/boot/pc/8250.c
+++ /dev/null
@@ -1,308 +1,0 @@
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-
-/*
- *  INS8250 uart
- */
-enum
-{
-	/*
-	 *  register numbers
-	 */
-	Data=	0,		/* xmit/rcv buffer */
-	Iena=	1,		/* interrupt enable */
-	 Ircv=	(1<<0),		/*  for char rcv'd */
-	 Ixmt=	(1<<1),		/*  for xmit buffer empty */
-	 Irstat=(1<<2),		/*  for change in rcv'er status */
-	 Imstat=(1<<3),		/*  for change in modem status */
-	Istat=	2,		/* interrupt flag (read) */
-	Tctl=	2,		/* test control (write) */
-	Format=	3,		/* byte format */
-	 Bits8=	(3<<0),		/*  8 bits/byte */
-	 Stop2=	(1<<2),		/*  2 stop bits */
-	 Pena=	(1<<3),		/*  generate parity */
-	 Peven=	(1<<4),		/*  even parity */
-	 Pforce=(1<<5),		/*  force parity */
-	 Break=	(1<<6),		/*  generate a break */
-	 Dra=	(1<<7),		/*  address the divisor */
-	Mctl=	4,		/* modem control */
-	 Dtr=	(1<<0),		/*  data terminal ready */
-	 Rts=	(1<<1),		/*  request to send */
-	 Ri=	(1<<2),		/*  ring */
-	 Inton=	(1<<3),		/*  turn on interrupts */
-	 Loop=	(1<<4),		/*  loop back */
-	Lstat=	5,		/* line status */
-	 Inready=(1<<0),	/*  receive buffer full */
-	 Oerror=(1<<1),		/*  receiver overrun */
-	 Perror=(1<<2),		/*  receiver parity error */
-	 Ferror=(1<<3),		/*  rcv framing error */
-	 Outready=(1<<5),	/*  output buffer empty */
-	Mstat=	6,		/* modem status */
-	 Ctsc=	(1<<0),		/*  clear to send changed */
-	 Dsrc=	(1<<1),		/*  data set ready changed */
-	 Rire=	(1<<2),		/*  rising edge of ring indicator */
-	 Dcdc=	(1<<3),		/*  data carrier detect changed */
-	 Cts=	(1<<4),		/*  complement of clear to send line */
-	 Dsr=	(1<<5),		/*  complement of data set ready line */
-	 Ring=	(1<<6),		/*  complement of ring indicator line */
-	 Dcd=	(1<<7),		/*  complement of data carrier detect line */
-	Scratch=7,		/* scratchpad */
-	Dlsb=	0,		/* divisor lsb */
-	Dmsb=	1,		/* divisor msb */
-
-	Serial=	0,
-	Modem=	1,
-};
-
-typedef struct Uart	Uart;
-struct Uart
-{
-	int	port;
-	uchar	sticky[8];	/* sticky write register values */
-	uchar	txbusy;
-
-	void	(*rx)(int);	/* routine to take a received character */
-	int	(*tx)(void);	/* routine to get a character to transmit */
-
-	ulong	frame;
-	ulong	overrun;
-};
-
-static Uart com[2];
-static Uart* uart;
-
-#define UartFREQ 1843200
-
-#define uartwrreg(u,r,v)	outb((u)->port + r, (u)->sticky[r] | (v))
-#define uartrdreg(u,r)		inb((u)->port + r)
-
-/*
- *  set the baud rate by calculating and setting the baudrate
- *  generator constant.  This will work with fairly non-standard
- *  baud rates.
- */
-static void
-uartsetbaud(Uart *up, int rate)
-{
-	ulong brconst;
-
-	brconst = (UartFREQ+8*rate-1)/(16*rate);
-
-	uartwrreg(up, Format, Dra);
-	outb(up->port+Dmsb, (brconst>>8) & 0xff);
-	outb(up->port+Dlsb, brconst & 0xff);
-	uartwrreg(up, Format, 0);
-}
-
-/*
- *  toggle DTR
- */
-static void
-uartdtr(Uart *up, int n)
-{
-	if(n)
-		up->sticky[Mctl] |= Dtr;
-	else
-		up->sticky[Mctl] &= ~Dtr;
-	uartwrreg(up, Mctl, 0);
-}
-
-/*
- *  toggle RTS
- */
-static void
-uartrts(Uart *up, int n)
-{
-	if(n)
-		up->sticky[Mctl] |= Rts;
-	else
-		up->sticky[Mctl] &= ~Rts;
-	uartwrreg(up, Mctl, 0);
-}
-
-static void
-uartintr(Ureg*, void *arg)
-{
-	Uart *up;
-	int ch;
-	int s, l, loops;
-
-	up = arg;
-	for(loops = 0; loops < 1024; loops++){
-		s = uartrdreg(up, Istat);
-		switch(s & 0x3F){
-		case 6:	/* receiver line status */
-			l = uartrdreg(up, Lstat);
-			if(l & Ferror)
-				up->frame++;
-			if(l & Oerror)
-				up->overrun++;
-			break;
-	
-		case 4:	/* received data available */
-		case 12:
-			ch = inb(up->port+Data);
-			if(up->rx)
-				(*up->rx)(ch);
-			break;
-	
-		case 2:	/* transmitter empty */
-			ch = -1;
-			if(up->tx)
-				ch = (*up->tx)();
-			if(ch != -1)
-				outb(up->port+Data, ch);
-			else
-				up->txbusy = 0;
-			break;
-	
-		case 0:	/* modem status */
-			uartrdreg(up, Mstat);
-			break;
-	
-		default:
-			if(s&1)
-				return;
-			print("weird modem interrupt #%2.2ux\n", s);
-			break;
-		}
-	}
-	panic("uartintr: 0x%2.2ux\n", uartrdreg(up, Istat));
-}
-
-/*
- *  turn on a port's interrupts.  set DTR and RTS
- */
-static void
-uartenable(Uart *up)
-{
-	/*
- 	 *  turn on interrupts
-	 */
-	up->sticky[Iena] = 0;
-	if(up->tx)
-		up->sticky[Iena] |= Ixmt;
-	if(up->rx)
-		up->sticky[Iena] |= Ircv|Irstat;
-	uartwrreg(up, Iena, 0);
-
-	/*
-	 *  turn on DTR and RTS
-	 */
-	uartdtr(up, 1);
-	uartrts(up, 1);
-}
-
-static void
-uartdisable(Uart* up)
-{
-	/*
- 	 * Disable interrupts.
-	 */
-	up->sticky[Iena] = 0;
-	uartwrreg(up, Iena, 0);
-	uartdtr(up, 0);
-	uartrts(up, 0);
-}
-
-void
-uartspecial(int port, void (*rx)(int), int (*tx)(void), int baud)
-{
-	Uart *up;
-	int vector;
-
-	switch(port){
-	case 0:
-		port = 0x3F8;
-		vector = VectorUART0;
-		up = &com[0];
-		break;
-	case 1:
-		port = 0x2F8;
-		vector = VectorUART1;
-		up = &com[1];
-		break;
-	default:
-		return;
-	}
-
-	if(uart != nil && uart != up)
-		uartdisable(uart);
-	uart = up;
-
-	if(up->port == 0){
-		up->port = port;
-		setvec(vector, uartintr, up);
-	}
-
-	/*
-	 *  set rate to 9600 baud.
-	 *  8 bits/character.
-	 *  1 stop bit.
-	 *  interrupts enabled.
-	 */
-	uartsetbaud(up, 9600);
-	up->sticky[Format] = Bits8;
-	uartwrreg(up, Format, 0);
-	up->sticky[Mctl] |= Inton;
-	uartwrreg(up, Mctl, 0x0);
-
-	up->rx = rx;
-	up->tx = tx;
-	uartenable(up);
-	if(baud)
-		uartsetbaud(up, baud);
-}
-
-void
-uartputc(int c)
-{
-	int i;
-	Uart *up;
-
-	if((up = uart) == nil)
-		return;
-	for(i = 0; i < 100; i++){
-		if(uartrdreg(up, Lstat) & Outready)
-			break;
-		delay(1);
-	}
-	outb(up->port+Data, c);
-}
-
-void
-uartputs(IOQ *q, char *s, int n)
-{
-	Uart *up;
-	int c, x;
-
-	if((up = uart) == nil)
-		return;
-	while(n--){
-		if(*s == '\n')
-			q->putc(q, '\r');
-		q->putc(q, *s++);
-	}
-	x = splhi();
-	if(up->txbusy == 0 && (c = q->getc(q)) != -1){
-		uartputc(c & 0xFF);
-		up->txbusy = 1;
-	}
-	splx(x);
-}
-
-void
-uartdrain(void)
-{
-	Uart *up;
-	int timeo;
-
-	if((up = uart) == nil)
-		return;
-	for(timeo = 0; timeo < 10000 && up->txbusy; timeo++)
-		delay(1);
-}
--- a/os/boot/pc/LICENCE
+++ /dev/null
@@ -1,237 +1,0 @@
-Lucent Public License Version 1.02
-
-THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS PUBLIC
-LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE
-PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
-
-1. DEFINITIONS
-
-"Contribution" means:
-
-  a. in the case of Lucent Technologies Inc. ("LUCENT"), the Original
-     Program, and
-  b. in the case of each Contributor,
-
-     i. changes to the Program, and
-    ii. additions to the Program;
-
-    where such changes and/or additions to the Program were added to the
-    Program by such Contributor itself or anyone acting on such
-    Contributor's behalf, and the Contributor explicitly consents, in
-    accordance with Section 3C, to characterization of the changes and/or
-    additions as Contributions.
-
-"Contributor" means LUCENT and any other entity that has Contributed a
-Contribution to the Program.
-
-"Distributor" means a Recipient that distributes the Program,
-modifications to the Program, or any part thereof.
-
-"Licensed Patents" mean patent claims licensable by a Contributor
-which are necessarily infringed by the use or sale of its Contribution
-alone or when combined with the Program.
-
-"Original Program" means the original version of the software
-accompanying this Agreement as released by LUCENT, including source
-code, object code and documentation, if any.
-
-"Program" means the Original Program and Contributions or any part
-thereof
-
-"Recipient" means anyone who receives the Program under this
-Agreement, including all Contributors.
-
-2. GRANT OF RIGHTS
-
- a. Subject to the terms of this Agreement, each Contributor hereby
-    grants Recipient a non-exclusive, worldwide, royalty-free copyright
-    license to reproduce, prepare derivative works of, publicly display,
-    publicly perform, distribute and sublicense the Contribution of such
-    Contributor, if any, and such derivative works, in source code and
-    object code form.
-    
- b. Subject to the terms of this Agreement, each Contributor hereby
-    grants Recipient a non-exclusive, worldwide, royalty-free patent
-    license under Licensed Patents to make, use, sell, offer to sell,
-    import and otherwise transfer the Contribution of such Contributor, if
-    any, in source code and object code form. The patent license granted
-    by a Contributor shall also apply to the combination of the
-    Contribution of that Contributor and the Program if, at the time the
-    Contribution is added by the Contributor, such addition of the
-    Contribution causes such combination to be covered by the Licensed
-    Patents. The patent license granted by a Contributor shall not apply
-    to (i) any other combinations which include the Contribution, nor to
-    (ii) Contributions of other Contributors. No hardware per se is
-    licensed hereunder.
-    
- c. Recipient understands that although each Contributor grants the
-    licenses to its Contributions set forth herein, no assurances are
-    provided by any Contributor that the Program does not infringe the
-    patent or other intellectual property rights of any other entity. Each
-    Contributor disclaims any liability to Recipient for claims brought by
-    any other entity based on infringement of intellectual property rights
-    or otherwise. As a condition to exercising the rights and licenses
-    granted hereunder, each Recipient hereby assumes sole responsibility
-    to secure any other intellectual property rights needed, if any. For
-    example, if a third party patent license is required to allow
-    Recipient to distribute the Program, it is Recipient's responsibility
-    to acquire that license before distributing the Program.
-
- d. Each Contributor represents that to its knowledge it has sufficient
-    copyright rights in its Contribution, if any, to grant the copyright
-    license set forth in this Agreement.
-
-3. REQUIREMENTS
-
-A. Distributor may choose to distribute the Program in any form under
-this Agreement or under its own license agreement, provided that:
-
- a. it complies with the terms and conditions of this Agreement;
-
- b. if the Program is distributed in source code or other tangible
-    form, a copy of this Agreement or Distributor's own license agreement
-    is included with each copy of the Program; and
-
- c. if distributed under Distributor's own license agreement, such
-    license agreement:
-
-      i. effectively disclaims on behalf of all Contributors all warranties
-         and conditions, express and implied, including warranties or
-         conditions of title and non-infringement, and implied warranties or
-         conditions of merchantability and fitness for a particular purpose;
-     ii. effectively excludes on behalf of all Contributors all liability
-         for damages, including direct, indirect, special, incidental and
-         consequential damages, such as lost profits; and
-    iii. states that any provisions which differ from this Agreement are
-         offered by that Contributor alone and not by any other party.
-
-B. Each Distributor must include the following in a conspicuous
-   location in the Program:
-
-   Copyright (C) 2003, Lucent Technologies Inc. and others. All Rights
-   Reserved.
-
-C. In addition, each Contributor must identify itself as the
-originator of its Contribution in a manner that reasonably allows
-subsequent Recipients to identify the originator of the Contribution.
-Also, each Contributor must agree that the additions and/or changes
-are intended to be a Contribution. Once a Contribution is contributed,
-it may not thereafter be revoked.
-
-4. COMMERCIAL DISTRIBUTION
-
-Commercial distributors of software may accept certain
-responsibilities with respect to end users, business partners and the
-like. While this license is intended to facilitate the commercial use
-of the Program, the Distributor who includes the Program in a
-commercial product offering should do so in a manner which does not
-create potential liability for Contributors. Therefore, if a
-Distributor includes the Program in a commercial product offering,
-such Distributor ("Commercial Distributor") hereby agrees to defend
-and indemnify every Contributor ("Indemnified Contributor") against
-any losses, damages and costs (collectively"Losses") arising from
-claims, lawsuits and other legal actions brought by a third party
-against the Indemnified Contributor to the extent caused by the acts
-or omissions of such Commercial Distributor in connection with its
-distribution of the Program in a commercial product offering. The
-obligations in this section do not apply to any claims or Losses
-relating to any actual or alleged intellectual property infringement.
-In order to qualify, an Indemnified Contributor must: a) promptly
-notify the Commercial Distributor in writing of such claim, and b)
-allow the Commercial Distributor to control, and cooperate with the
-Commercial Distributor in, the defense and any related settlement
-negotiations. The Indemnified Contributor may participate in any such
-claim at its own expense.
-
-For example, a Distributor might include the Program in a commercial
-product offering, Product X. That Distributor is then a Commercial
-Distributor. If that Commercial Distributor then makes performance
-claims, or offers warranties related to Product X, those performance
-claims and warranties are such Commercial Distributor's responsibility
-alone. Under this section, the Commercial Distributor would have to
-defend claims against the Contributors related to those performance
-claims and warranties, and if a court requires any Contributor to pay
-any damages as a result, the Commercial Distributor must pay those
-damages.
-
-5. NO WARRANTY
-
-EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS
-PROVIDED ON AN"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
-WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY
-OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely
-responsible for determining the appropriateness of using and
-distributing the Program and assumes all risks associated with its
-exercise of rights under this Agreement, including but not limited to
-the risks and costs of program errors, compliance with applicable
-laws, damage to or loss of data, programs or equipment, and
-unavailability or interruption of operations.
-
-6. DISCLAIMER OF LIABILITY
-
-EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR
-ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING
-WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR
-DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
-HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
-
-7. EXPORT CONTROL
-
-Recipient agrees that Recipient alone is responsible for compliance
-with the United States export administration regulations (and the
-export control laws and regulation of any other countries).
-
-8. GENERAL
-
-If any provision of this Agreement is invalid or unenforceable under
-applicable law, it shall not affect the validity or enforceability of
-the remainder of the terms of this Agreement, and without further
-action by the parties hereto, such provision shall be reformed to the
-minimum extent necessary to make such provision valid and enforceable.
-
-If Recipient institutes patent litigation against a Contributor with
-respect to a patent applicable to software (including a cross-claim or
-counterclaim in a lawsuit), then any patent licenses granted by that
-Contributor to such Recipient under this Agreement shall terminate as
-of the date such litigation is filed. In addition, if Recipient
-institutes patent litigation against any entity (including a
-cross-claim or counterclaim in a lawsuit) alleging that the Program
-itself (excluding combinations of the Program with other software or
-hardware) infringes such Recipient's patent(s), then such Recipient's
-rights granted under Section 2(b) shall terminate as of the date such
-litigation is filed.
-
-All Recipient's rights under this Agreement shall terminate if it
-fails to comply with any of the material terms or conditions of this
-Agreement and does not cure such failure in a reasonable period of
-time after becoming aware of such noncompliance. If all Recipient's
-rights under this Agreement terminate, Recipient agrees to cease use
-and distribution of the Program as soon as reasonably practicable.
-However, Recipient's obligations under this Agreement and any licenses
-granted by Recipient relating to the Program shall continue and
-survive.
-
-LUCENT may publish new versions (including revisions) of this
-Agreement from time to time. Each new version of the Agreement will be
-given a distinguishing version number. The Program (including
-Contributions) may always be distributed subject to the version of the
-Agreement under which it was received. In addition, after a new
-version of the Agreement is published, Contributor may elect to
-distribute the Program (including its Contributions) under the new
-version. No one other than LUCENT has the right to modify this
-Agreement. Except as expressly stated in Sections 2(a) and 2(b) above,
-Recipient receives no rights or licenses to the intellectual property
-of any Contributor under this Agreement, whether expressly, by
-implication, estoppel or otherwise. All rights in the Program not
-expressly granted under this Agreement are reserved.
-
-This Agreement is governed by the laws of the State of New York and
-the intellectual property laws of the United States of America. No
-party to this Agreement will bring a legal action under this Agreement
-more than one year after the cause of action arose. Each party waives
-its rights to a jury trial in any resulting litigation.
-
--- a/os/boot/pc/NOTICE
+++ /dev/null
@@ -1,4 +1,0 @@
-Copyright © 1995-2007 Lucent Technologies Inc. and others.  All rights reserved.
-Revisions for use with Inferno © 2003-2007 Vita Nuova Holdings Limited.
-
-This software is provided under the terms of the Lucent Public License, Version 1.02.
--- a/os/boot/pc/ahci.h
+++ /dev/null
@@ -1,275 +1,0 @@
-/*
- * advanced host controller interface (sata)
- * © 2007  coraid, inc
- */
-
-/* ata errors */
-enum {
-	Emed	= 1<<0,		/* media error */
-	Enm	= 1<<1,		/* no media */
-	Eabrt	= 1<<2,		/* abort */
-	Emcr	= 1<<3,		/* media change request */
-	Eidnf	= 1<<4,		/* no user-accessible address */
-	Emc	= 1<<5,		/* media change */
-	Eunc	= 1<<6,		/* data error */
-	Ewp	= 1<<6,		/* write protect */
-	Eicrc	= 1<<7,		/* interface crc error */
-
-	Efatal	= Eidnf|Eicrc,	/* must sw reset */
-};
-
-/* ata status */
-enum {
-	ASerr	= 1<<0,		/* error */
-	ASdrq	= 1<<3,		/* request */
-	ASdf	= 1<<5,		/* fault */
-	ASdrdy	= 1<<6,		/* ready */
-	ASbsy	= 1<<7,		/* busy */
-
-	ASobs	= 1<<1|1<<2|1<<4,
-};
-
-/* pci configuration */
-enum {
-	Abar	= 5,
-};
-
-/*
- * ahci memory configuration
- *
- * 0000-0023	generic host control
- * 0024-009f	reserved
- * 00a0-00ff	vendor specific.
- * 0100-017f	port 0
- * ...
- * 1080-1100	port 31
- */
-
-/* cap bits: supported features */
-enum {
-	Hs64a	= 1<<31,	/* 64-bit addressing */
-	Hsncq	= 1<<30,	/* ncq */
-	Hssntf	= 1<<29,	/* snotification reg. */
-	Hsmps	= 1<<28,	/* mech pres switch */
-	Hsss	= 1<<27,	/* staggered spinup */
-	Hsalp	= 1<<26,	/* aggressive link pm */
-	Hsal	= 1<<25,	/* activity led */
-	Hsclo	= 1<<24,	/* command-list override */
-	Hiss	= 1<<20,	/* for interface speed */
-//	Hsnzo	= 1<<19,
-	Hsam	= 1<<18,	/* ahci-mode only */
-	Hspm	= 1<<17,	/* port multiplier */
-//	Hfbss	= 1<<16,
-	Hpmb	= 1<<15,	/* multiple-block pio */
-	Hssc	= 1<<14,	/* slumber state */
-	Hpsc	= 1<<13,	/* partial-slumber state */
-	Hncs	= 1<<8,		/* n command slots */
-	Hcccs	= 1<<7,		/* coal */
-	Hems	= 1<<6,		/* enclosure mgmt. */
-	Hsxs	= 1<<5,		/* external sata */
-	Hnp	= 1<<0,		/* n ports */
-};
-
-/* ghc bits */
-enum {
-	Hae	= 1<<31,	/* enable ahci */
-	Hie	= 1<<1,		/* " interrupts */
-	Hhr	= 1<<0,		/* hba reset */
-};
-
-typedef struct {
-	ulong	cap;
-	ulong	ghc;
-	ulong	isr;
-	ulong	pi;		/* ports implemented */
-	ulong	ver;
-	ulong	ccc;		/* coaleasing control */
-	ulong	cccports;
-	ulong	emloc;
-	ulong	emctl;
-} Ahba;
-
-enum {
-	Acpds	= 1<<31,	/* cold port detect status */
-	Atfes	= 1<<30,	/* task file error status */
-	Ahbfs	= 1<<29,	/* hba fatal */
-	Ahbds	= 1<<28,	/* hba error (parity error) */
-	Aifs	= 1<<27,	/* interface fatal  §6.1.2 */
-	Ainfs	= 1<<26,	/* interface error (recovered) */
-	Aofs	= 1<<24,	/* too many bytes from disk */
-	Aipms	= 1<<23,	/* incorrect prt mul status */
-	Aprcs	= 1<<22,	/* PhyRdy change status Pxserr.diag.n */
-	Adpms	= 1<<7,		/* mechanical presence status */
-	Apcs 	= 1<<6,		/* port connect  diag.x */
-	Adps 	= 1<<5,		/* descriptor processed */
-	Aufs 	= 1<<4,		/* unknown fis diag.f */
-	Asdbs	= 1<<3,		/* set device bits fis received w/ i bit set */
-	Adss	= 1<<2,		/* dma setup */
-	Apio	= 1<<1,		/* pio setup fis */
-	Adhrs	= 1<<0,		/* device to host register fis */
-
-	IEM	= Acpds|Atfes|Ahbds|Ahbfs|Ahbds|Aifs|Ainfs|Aprcs|Apcs|Adps|
-			Aufs|Asdbs|Adss|Adhrs,
-	Ifatal	= Atfes|Ahbfs|Ahbds|Aifs,
-};
-
-/* serror bits */
-enum {
-	SerrX	= 1<<26,	/* exchanged */
-	SerrF	= 1<<25,	/* unknown fis */
-	SerrT	= 1<<24,	/* transition error */
-	SerrS	= 1<<23,	/* link sequence */
-	SerrH	= 1<<22,	/* handshake */
-	SerrC	= 1<<21,	/* crc */
-	SerrD	= 1<<20,	/* not used by ahci */
-	SerrB	= 1<<19,	/* 10-tp-8 decode */
-	SerrW	= 1<<18,	/* comm wake */
-	SerrI	= 1<<17,	/* phy internal */
-	SerrN	= 1<<16,	/* phyrdy change */
-
-	ErrE	= 1<<11,	/* internal */
-	ErrP	= 1<<10,	/* ata protocol violation */
-	ErrC	= 1<<9,		/* communication */
-	ErrT	= 1<<8,		/* transient */
-	ErrM	= 1<<1,		/* recoverd comm */
-	ErrI	= 1<<0,		/* recovered data integrety */
-
-	ErrAll	= ErrE|ErrP|ErrC|ErrT|ErrM|ErrI,
-	SerrAll	= SerrX|SerrF|SerrT|SerrS|SerrH|SerrC|SerrD|SerrB|SerrW|
-			SerrI|SerrN|ErrAll,
-	SerrBad	= 0x7f<<19,
-};
-
-/* cmd register bits */
-enum {
-	Aicc	= 1<<28,	/* interface communcations control. 4 bits */
-	Aasp	= 1<<27,	/* agressive slumber & partial sleep */
-	Aalpe 	= 1<<26,	/* agressive link pm enable */
-	Adlae	= 1<<25,	/* drive led on atapi */
-	Aatapi	= 1<<24,	/* device is atapi */
-	Aesp	= 1<<21,	/* external sata port */
-	Acpd	= 1<<20,	/* cold presence detect */
-	Ampsp	= 1<<19,	/* mechanical pres. */
-	Ahpcp	= 1<<18,	/* hot plug capable */
-	Apma	= 1<<17,	/* pm attached */
-	Acps	= 1<<16,	/* cold presence state */
-	Acr	= 1<<15,	/* cmdlist running */
-	Afr	= 1<<14,	/* fis running */
-	Ampss	= 1<<13,	/* mechanical presence switch state */
-	Accs	= 1<<8,		/* current command slot 12:08 */
-	Afre	= 1<<4,		/* fis enable receive */
-	Aclo	= 1<<3,		/* command list override */
-	Apod	= 1<<2,		/* power on dev (requires cold-pres. detect) */
-	Asud	= 1<<1,		/* spin-up device;  requires ss capability */
-	Ast	= 1<<0,		/* start */
-
-	Arun	= Ast|Acr|Afre|Afr,
-};
-
-/* ctl register bits */
-enum {
-	Aipm	= 1<<8,		/* interface power mgmt. 3=off */
-	Aspd	= 1<<4,
-	Adet	= 1<<0,		/* device detection */
-};
-
-#define	sstatus	scr0
-#define	sctl	scr2
-#define	serror	scr1
-#define	sactive	scr3
-
-typedef struct {
-	ulong	list;		/* PxCLB must be 1kb aligned. */
-	ulong	listhi;
-	ulong	fis;		/* 256-byte aligned */
-	ulong	fishi;
-	ulong	isr;
-	ulong	ie;		/* interrupt enable */
-	ulong	cmd;
-	ulong	res1;
-	ulong	task;
-	ulong	sig;
-	ulong	scr0;
-	ulong	scr2;
-	ulong	scr1;
-	ulong	scr3;
-	ulong	ci;		/* command issue */
-	ulong	ntf;
-	uchar	res2[8];
-	ulong	vendor;
-} Aport;
-
-/* in host's memory; not memory mapped */
-typedef struct {
-	uchar	*base;
-	uchar	*d;
-	uchar	*p;
-	uchar	*r;
-	uchar	*u;
-	ulong	*devicebits;
-} Afis;
-
-enum {
-	Lprdtl	= 1<<16,	/* physical region descriptor table len */
-	Lpmp	= 1<<12,	/* port multiplier port */
-	Lclear	= 1<<10,	/* clear busy on R_OK */
-	Lbist	= 1<<9,
-	Lreset	= 1<<8,
-	Lpref	= 1<<7,		/* prefetchable */
-	Lwrite	= 1<<6,
-	Latapi	= 1<<5,
-	Lcfl	= 1<<0,		/* command fis length in double words */
-};
-
-/* in hosts memory; memory mapped */
-typedef struct {
-	ulong	flags;
-	ulong	len;
-	ulong	ctab;
-	ulong	ctabhi;
-	uchar	reserved[16];
-} Alist;
-
-typedef struct {
-	ulong	dba;
-	ulong	dbahi;
-	ulong	pad;
-	ulong	count;
-} Aprdt;
-
-typedef struct {
-	uchar	cfis[0x40];
-	uchar	atapi[0x10];
-	uchar	pad[0x30];
-	Aprdt	prdt;
-} Actab;
-
-enum {
-	Ferror	= 1,
-	Fdone	= 2,
-};
-
-enum {
-	Dllba 	= 1,
-	Dsmart	= 1<<1,
-	Dpower	= 1<<2,
-	Dnop	= 1<<3,
-	Datapi	= 1<<4,
-	Datapi16= 1<<5,
-};
-
-typedef struct {
-//	QLock;
-//	Rendez;
-	uchar	flag;
-	uchar	feat;
-	uchar	smart;
-	Afis	fis;
-	Alist	*list;
-	Actab	*ctab;
-} Aportm;
-
-typedef struct {
-	Aport	*p;
-	Aportm	*m;
-} Aportc;
--- a/os/boot/pc/alarm.c
+++ /dev/null
@@ -1,123 +1,0 @@
-#include	"u.h"
-#include	"lib.h"
-#include	"mem.h"
-#include	"dat.h"
-#include	"fns.h"
-#include	"io.h"
-#define	MAXALARM	10
-
-Alarm	alarmtab[MAXALARM];
-
-/*
- * Insert new into list after where
- */
-void
-insert(List **head, List *where, List *new)
-{
-	if(where == 0){
-		new->next = *head;
-		*head = new;
-	}else{
-		new->next = where->next;
-		where->next = new;
-	}
-		
-}
-
-/*
- * Delete old from list.  where->next is known to be old.
- */
-void
-delete(List **head, List *where, List *old)
-{
-	if(where == 0){
-		*head = old->next;
-		return;
-	}
-	where->next = old->next;
-}
-
-Alarm*
-newalarm(void)
-{
-	int i;
-	Alarm *a;
-
-	for(i=0,a=alarmtab; i < nelem(alarmtab); i++,a++)
-		if(a->busy==0 && a->f==0){
-			a->f = 0;
-			a->arg = 0;
-			a->busy = 1;
-			return a;
-		}
-	panic("newalarm");
-	return 0;	/* not reached */
-}
-
-Alarm*
-alarm(int ms, void (*f)(Alarm*), void *arg)
-{
-	Alarm *a, *w, *pw;
-	ulong s;
-
-	if(ms < 0)
-		ms = 0;
-	s = splhi();
-	a = newalarm();
-	a->dt = MS2TK(ms);
-	a->f = f;
-	a->arg = arg;
-	pw = 0;
-	for(w=m->alarm; w; pw=w, w=w->next){
-		if(w->dt <= a->dt){
-			a->dt -= w->dt;
-			continue;
-		}
-		w->dt -= a->dt;
-		break;
-	}
-	insert(&m->alarm, pw, a);
-	splx(s);
-	return a;
-}
-
-void
-cancel(Alarm *a)
-{
-	a->f = 0;
-}
-
-void
-alarminit(void)
-{
-}
-
-#define NA 10		/* alarms per clock tick */
-void
-checkalarms(void)
-{
-	int i, n, s;
-	Alarm *a;
-	void (*f)(Alarm*);
-	Alarm *alist[NA];
-
-	s = splhi();
-	a = m->alarm;
-	if(a){
-		for(n=0; a && a->dt<=0 && n<NA; n++){
-			alist[n] = a;
-			delete(&m->alarm, 0, a);
-			a = m->alarm;
-		}
-		if(a)
-			a->dt--;
-
-		for(i = 0; i < n; i++){
-			f = alist[i]->f;	/* avoid race with cancel */
-			if(f)
-				(*f)(alist[i]);
-			alist[i]->busy = 0;
-		}
-	}
-	splx(s);
-}
--- a/os/boot/pc/aoe.h
+++ /dev/null
@@ -1,76 +1,0 @@
-/*
- * ATA-over-Ethernet
- */
-enum {
-	ACata,
-	ACconfig,
-};
-
-enum {
-	AQCread,
-	AQCtest,
-	AQCprefix,
-	AQCset,
-	AQCfset,
-};
-
-enum {
-	AEcmd	= 1,
-	AEarg,
-	AEdev,
-	AEcfg,
-	AEver,
-};
-
-enum {
-	Aoetype	= 0x88a2,
-	Aoever	= 1,
-
-	AFerr	= 1<<2,
-	AFrsp	= 1<<3,
-
-	AAFwrite= 1,
-	AAFext	= 1<<6,
-};
-
-enum {
-	Crd	= 0x20,
-	Crdext	= 0x24,
-	Cwr	= 0x30,
-	Cwrext	= 0x34,
-	Cid	= 0xec,
-};
-
-typedef struct {
-	uchar	dst[Eaddrlen];
-	uchar	src[Eaddrlen];
-	uchar	type[2];
-	uchar	verflag;
-	uchar	error;
-	uchar	major[2];
-	uchar	minor;
-	uchar	cmd;
-	uchar	tag[4];
-} Aoehdr;
-
-typedef struct {
-	Aoehdr;
-	uchar	aflag;
-	uchar	errfeat;
-	uchar	scnt;
-	uchar	cmdstat;
-	uchar	lba[6];
-	uchar	res[2];
-} Aoeata;
-
-typedef struct {
-	Aoehdr;
-	uchar	bufcnt[2];
-	uchar	fwver[2];
-	uchar	scnt;
-	uchar	verccmd;
-	uchar	cslen[2];
-} Aoeqc;
-
-extern char Echange[];
-extern char Enotup[];
--- a/os/boot/pc/apm.c
+++ /dev/null
@@ -1,16 +1,0 @@
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-
-Apminfo apm;
-
-void
-apminit(void)
-{
-	if(getconf("apm0") && apm.haveinfo)
-		changeconf("apm0=ax=%x ebx=%x cx=%x dx=%x di=%x esi=%x\n",
-			apm.ax, apm.ebx, apm.cx, apm.dx, apm.di, apm.esi);
-}
--- a/os/boot/pc/bcom.c
+++ /dev/null
@@ -1,463 +1,0 @@
-/*
- * ld - DOS boot loader of Plan 9
- */
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-
-#include "fs.h"
-
-Type types[] = {
-	{	Tfloppy,
-		Fini|Ffs,
-		floppyinit, floppyinitdev,
-		floppygetfspart, 0, floppyboot,
-	},
-	{	Tsd,
-		Fini|Ffs,
-		sdinit, sdinitdev,
-		sdgetfspart, sdaddconf, sdboot,
-	},
-	{	Tnil,
-		0,
-		0, 0,
-		0, 0, 0,
-	},
-};
-
-#include "sd.h"
-
-extern SDifc sdataifc;
-extern SDifc sdmylexifc;
-extern SDifc sd53c8xxifc;
-SDifc* sdifc[] = {
-	&sdataifc,
-//	&sdmylexifc,
-//	&sd53c8xxifc,
-	nil,
-};
-
-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;
-
-	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 *defaultpartition = "new";
-
-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;
-	return nil;
-}
-
-static int
-boot(Medium *mp, char *file)
-{
-	static Boot b;
-
-	memset(&b, 0, sizeof b);
-	b.state = INIT9LOAD;
-
-//	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;
-}
-
-char *parts[] = { "dos", "9fat", "fs", 0 };
-
-Medium*
-probe(int type, int flag, int dev)
-{
-	Type *tp;
-	int i;
-	Medium *mp;
-
-	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((flag & mp->flag) && (dev == Dany || dev == i))
-				return mp;
-		}
-	}
-
-	return 0;
-}
-
-extern int loopconst;
-void
-main(void)
-{
-	Medium *mp;
-	int flag;
-	char def[2*NAMELEN], line[80], *p, *file;
-	Type *tp;
-
-	i8042a20();
-	memset(m, 0, sizeof(Mach));
-	trapinit();
-	clockinit();
-	alarminit();
-	spllo();
-
-	kbdinit();
-	
-	if((ulong)&end > (KZERO|(640*1024)))
-		panic("i'm too big");
-
-	/*
-	 * If there were any arguments, MS-DOS leaves a character
-	 * count followed by the arguments in the runtime header.
-	 * Step over the leading space.
-	 */
-	p = (char*)0x80080080;
-	if(p[0]){
-		p[p[0]+1] = 0;
-		p += 2;
-	}
-	else
-		p = 0;
-
-	/*
-	 * Advance command line to first option, if any
-	 */
-	if(p) {
-		while(*p==' ' || *p=='\t')
-			p++;
-		if(*p == 0)
-			p = nil;
-	}
-
-	/*
- 	 * Probe everything, to collect device names.
-	 */
-	probe(Tany, Fnone, Dany);
-
-	if(p != 0) {
-		if((mp = parse(p, &file)) == nil) {
-			print("bad loadfile syntax: %s\n", p);
-			goto done;
-		}
-		boot(mp, file);
-	}
-
-done:
-	flag = 0;
-	for(tp = types; tp->type != Tnil; tp++){
-		for(mp = tp->media; mp; mp = mp->next){
-			if(flag == 0){
-				flag = 1;
-				print("Load devices:");
-			}
-			print(" %s", mp->name);
-		}
-	}
-	if(flag)
-		print("\n");
-
-	for(;;){
-		if(getstr("load from", line, sizeof(line), nil, 0) >= 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;
-}
-
-void*
-ialloc(ulong n, int align)
-{
-
-	static ulong palloc;
-	ulong p;
-	int a;
-
-	if(palloc == 0)
-		palloc = 3*1024*1024;
-
-	p = palloc;
-	if(align <= 0)
-		align = 4;
-	if(a = n % align)
-		n += align - a;
-	if(a = p % align)
-		p += align - a;
-
-	palloc = p+n;
-
-	return memset((void*)(p|KZERO), 0, n);
-}
-
-void*
-xspanalloc(ulong size, int align, ulong span)
-{
-	ulong a, v;
-
-	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){
-		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();
-	consdrain();
-	(*(void(*)(void))(PADDR(entry)))();
-}
-
-char*
-getconf(char*)
-{
-	return nil;
-}
-
-void
-addconf(char*, ...)
-{
-}
-
-void
-uartspecial(int, void(*)(int), int(*)(void), int)
-{
-}
-
-void
-uartputs(IOQ*, char*, int)
-{
-}
-
-void
-uartputc(int)
-{}
-
-void
-uartdrain(void)
-{
-}
--- a/os/boot/pc/boot.c
+++ /dev/null
@@ -1,451 +1,0 @@
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-
-#include "../../../utils/libmach/elf.h"
-
-static uchar elfident[7] = {
-	'\177', 'E', 'L', 'F', '\1', '\1', '\1'
-};
-static Ehdr ehdr, rehdr;
-static Phdr *phdr;
-static int curphdr;
-static ulong curoff;
-static ulong elftotal;
-static long (*swal)(long);
-static ushort (*swab)(ushort);
-
-/*
- * big-endian short
- */
-ushort
-beswab(ushort s)
-{
-	uchar *p;
-
-	p = (uchar*)&s;
-	return (p[0]<<8) | p[1];
-}
-
-/*
- * big-endian long
- */
-long
-beswal(long l)
-{
-	uchar *p;
-
-	p = (uchar*)&l;
-	return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
-}
-
-/*
- * little-endian short
- */
-ushort
-leswab(ushort s)
-{
-	uchar *p;
-
-	p = (uchar*)&s;
-	return (p[1]<<8) | p[0];
-}
-
-/*
- * little-endian long
- */
-long
-leswal(long l)
-{
-	uchar *p;
-
-	p = (uchar*)&l;
-	return (p[3]<<24) | (p[2]<<16) | (p[1]<<8) | p[0];
-}
-
-/*
- * Convert header to canonical form
- */
-static void
-hswal(long *lp, int n, long (*swap) (long))
-{
-	while (n--) {
-		*lp = (*swap) (*lp);
-		lp++;
-	}
-}
-
-static int
-readehdr(Boot *b)
-{
-	int i;
-
-	/* bitswap the header according to the DATA format */
-	if(ehdr.ident[CLASS] != ELFCLASS32) {
-		print("bad ELF class - not 32 bit\n");
-		return 0;
-	}
-	if(ehdr.ident[DATA] == ELFDATA2LSB) {
-		swab = leswab;
-		swal = leswal;
-	} else if(ehdr.ident[DATA] == ELFDATA2MSB) {
-		swab = beswab;
-		swal = beswal;
-	} else {
-		print("bad ELF encoding - not big or little endian\n");
-		return 0;
-	}
-	memmove(&rehdr, &ehdr, sizeof(Ehdr));
-
-	ehdr.type = swab(ehdr.type);
-	ehdr.machine = swab(ehdr.machine);
-	ehdr.version = swal(ehdr.version);
-	ehdr.elfentry = swal(ehdr.elfentry);
-	ehdr.phoff = swal(ehdr.phoff);
-	ehdr.shoff = swal(ehdr.shoff);
-	ehdr.flags = swal(ehdr.flags);
-	ehdr.ehsize = swab(ehdr.ehsize);
-	ehdr.phentsize = swab(ehdr.phentsize);
-	ehdr.phnum = swab(ehdr.phnum);
-	ehdr.shentsize = swab(ehdr.shentsize);
-	ehdr.shnum = swab(ehdr.shnum);
-	ehdr.shstrndx = swab(ehdr.shstrndx);
-	if(ehdr.type != EXEC || ehdr.version != CURRENT)
-		return 0;
-	if(ehdr.phentsize != sizeof(Phdr))
-		return 0;
-
-	if(debug)
-		print("readehdr OK entry 0x%lux\n", ehdr.elfentry);
-
-	curoff = sizeof(Ehdr);
-	i = ehdr.phoff+ehdr.phentsize*ehdr.phnum - curoff;
-	b->state = READPHDR;
-	b->bp = (char*)malloc(i);
-	b->wp = b->bp;
-	b->ep = b->wp + i;
-	phdr = (Phdr*)(b->bp + ehdr.phoff-sizeof(Ehdr));
-	if(debug)
-		print("phdr...");
-
-	return 1;
-}
-
-static int
-nextphdr(Boot *b)
-{
-	Phdr *php;
-	ulong entry, offset;
-	char *paddr;
-
-	if(debug)
-		print("readedata %d\n", curphdr);
-
-	for(; curphdr < ehdr.phnum; curphdr++){
-		php = phdr+curphdr;
-		if(php->type != LOAD)
-			continue;
-		offset = php->offset;
-		paddr = (char*)PADDR(php->paddr);
-		if(offset < curoff){
-			/*
-			 * Can't (be bothered to) rewind the
-			 * input, it might be from tftp. If we
-			 * did then we could boot FreeBSD kernels
-			 * too maybe.
-			 */
-			return 0;
-		}
-		if(php->offset > curoff){
-			b->state = READEPAD;
-			b->bp = (char*)malloc(offset - curoff);
-			b->wp = b->bp;
-			b->ep = b->wp + offset - curoff;
-			if(debug)
-				print("nextphdr %lud...\n", offset - curoff);
-			return 1;
-		}
-		b->state = READEDATA;
-		b->bp = paddr;
-		b->wp = b->bp;
-		b->ep = b->wp+php->filesz;
-		print("%ud+", php->filesz);
-		elftotal += php->filesz;
-		if(debug)
-			print("nextphdr %ud@0x%p\n", php->filesz, paddr);
-
-		return 1;
-	}
-
-	if(curphdr != 0){
-		print("=%lud\n", elftotal);
-		b->state = TRYBOOT;
-		entry = ehdr.elfentry & ~0xF0000000;
-		PLLONG(b->exec.entry, entry);
-		return 1;
-	}
-
-	return 0;
-}
-
-static int
-readepad(Boot *b)
-{
-	Phdr *php;
-
-	php = phdr+curphdr;
-	if(debug)
-		print("readepad %d\n", curphdr);
-	curoff = php->offset;
-
-	return nextphdr(b);
-}
-
-static int
-readedata(Boot *b)
-{
-	Phdr *php;
-
-	php = phdr+curphdr;
-	if(debug)
-		print("readedata %d\n", curphdr);
-	if(php->filesz < php->memsz){
-		print("%lud",  php->memsz-php->filesz);
-		elftotal += php->memsz-php->filesz;
-		memset((char*)(PADDR(php->paddr)+php->filesz), 0, php->memsz-php->filesz);
-	}
-	curoff = php->offset+php->filesz;
-	curphdr++;
-
-	return nextphdr(b);
-}
-
-static int
-readphdr(Boot *b)
-{
-	Phdr *php;
-
-	php = phdr;
-	hswal((long*)php, ehdr.phentsize*ehdr.phnum/sizeof(long), swal);
-	if(debug)
-		print("phdr curoff %lud vaddr 0x%lux paddr 0x%lux\n",
-			curoff, php->vaddr, php->paddr);
-
-	curoff = ehdr.phoff+ehdr.phentsize*ehdr.phnum;
-	curphdr = 0;
-
-	return nextphdr(b);
-}
-
-static int
-addbytes(char **dbuf, char *edbuf, char **sbuf, char *esbuf)
-{
-	int n;
-
-	n = edbuf - *dbuf;
-	if(n <= 0)
-		return 0;
-	if(n > esbuf - *sbuf)
-		n = esbuf - *sbuf;
-	if(n <= 0)
-		return -1;
-
-	memmove(*dbuf, *sbuf, n);
-	*sbuf += n;
-	*dbuf += n;
-	return edbuf - *dbuf;
-}
-
-int
-bootpass(Boot *b, void *vbuf, int nbuf)
-{
-	char *buf, *ebuf;
-	Exec *ep;
-	ulong entry, data, text, bss;
-
-	if(b->state == FAILED)
-		return FAIL;
-
-	if(nbuf == 0)
-		goto Endofinput;
-
-	buf = vbuf;
-	ebuf = buf+nbuf;
-	while(addbytes(&b->wp, b->ep, &buf, ebuf) == 0) {
-		switch(b->state) {
-		case INITKERNEL:
-			b->state = READEXEC;
-			b->bp = (char*)&b->exec;
-			b->wp = b->bp;
-			b->ep = b->bp+sizeof(Exec);
-			break;
-		case READEXEC:
-			ep = &b->exec;
-			if(GLLONG(ep->magic) == I_MAGIC) {
-				b->state = READ9TEXT;
-				b->bp = (char*)PADDR(GLLONG(ep->entry));
-				b->wp = b->bp;
-				b->ep = b->wp+GLLONG(ep->text);
-				print("%lud", GLLONG(ep->text));
-				break;
-			}
-
-			/* check for gzipped kernel */
-			if(b->bp[0] == 0x1F && (uchar)b->bp[1] == 0x8B && b->bp[2] == 0x08) {
-				b->state = READGZIP;
-				b->bp = (char*)malloc(1440*1024);
-				b->wp = b->bp;
-				b->ep = b->wp + 1440*1024;
-				memmove(b->bp, &b->exec, sizeof(Exec));
-				b->wp += sizeof(Exec);
-				print("gz...");
-				break;
-			}
-
-			/*
-			 * Check for ELF.
-			 */
-			if(memcmp(b->bp, elfident, 4) == 0){
-				b->state = READEHDR;
-				b->bp = (char*)&ehdr;
-				b->wp = b->bp;
-				b->ep = b->wp + sizeof(Ehdr);
-				memmove(b->bp, &b->exec, sizeof(Exec));
-				b->wp += sizeof(Exec);
-				print("elf...");
-				break;
-			}
-
-			print("bad kernel format\n");
-			b->state = FAILED;
-			return FAIL;
-
-		case READ9TEXT:
-			ep = &b->exec;
-			b->state = READ9DATA;
-			b->bp = (char*)PGROUND(PADDR(GLLONG(ep->entry))+GLLONG(ep->text));
-			b->wp = b->bp;
-			b->ep = b->wp + GLLONG(ep->data);
-			print("+%ld", GLLONG(ep->data));
-			break;
-	
-		case READ9DATA:
-			ep = &b->exec;
-			bss = GLLONG(ep->bss);
-			print("+%ld=%ld\n",
-				bss, GLLONG(ep->text)+GLLONG(ep->data)+bss);
-			b->state = TRYBOOT;
-			return ENOUGH;
-
-		case READEHDR:
-			if(!readehdr(b)){
-				print("readehdr failed\n");
-				b->state = FAILED;
-				return FAIL;
-			}
-			break;
-
-		case READPHDR:
-			if(!readphdr(b)){
-				b->state = FAILED;
-				return FAIL;
-			}
-			break;
-
-		case READEPAD:
-			if(!readepad(b)){
-				b->state = FAILED;
-				return FAIL;
-			}
-			break;
-
-		case READEDATA:
-			if(!readedata(b)){
-				b->state = FAILED;
-				return FAIL;
-			}
-			if(b->state == TRYBOOT)
-				return ENOUGH;
-			break;
-
-		case TRYBOOT:
-		case READGZIP:
-			return ENOUGH;
-
-		case READ9LOAD:
-		case INIT9LOAD:
-			panic("9load");
-
-		default:
-			panic("bootstate");
-		}
-	}
-	return MORE;
-
-
-Endofinput:
-	/* end of input */
-	switch(b->state) {
-	case INITKERNEL:
-	case READEXEC:
-	case READ9TEXT:
-	case READ9DATA:
-	case READEHDR:
-	case READPHDR:
-	case READEPAD:
-	case READEDATA:
-		print("premature EOF\n");
-		b->state = FAILED;
-		return FAIL;
-	
-	case TRYBOOT:
-		entry = GLLONG(b->exec.entry);
-		print("entry: 0x%lux\n", entry);
-		warp9(PADDR(entry));
-		b->state = FAILED;
-		return FAIL;
-
-	case READGZIP:
-		ep = &b->exec;
-		if(b->bp[0] != 0x1F || (uchar)b->bp[1] != 0x8B || b->bp[2] != 0x08)
-			print("lost magic\n");
-
-		print("%ld => ", b->wp - b->bp);
-		if(gunzip((uchar*)ep, sizeof(*ep), (uchar*)b->bp, b->wp - b->bp) < sizeof(*ep)) {
-			print("badly compressed kernel\n");
-			return FAIL;
-		}
-
-		entry = GLLONG(ep->entry);
-		text = GLLONG(ep->text);
-		data = GLLONG(ep->data);
-		bss = GLLONG(ep->bss);
-		print("%lud+%lud+%lud=%lud\n", text, data, bss, text+data+bss);
-
-		if(gunzip((uchar*)PADDR(entry)-sizeof(Exec), sizeof(Exec)+text+data, 
-		     (uchar*)b->bp, b->wp-b->bp) < sizeof(Exec)+text+data) {
-			print("error uncompressing kernel\n");
-			return FAIL;
-		}
-
-		/* relocate data to start at page boundary */
-		memmove((void*)PGROUND(PADDR(entry+text)), (void*)(PADDR(entry+text)), data);
-
-		print("entry: %lux\n", entry);
-		warp9(PADDR(entry));
-		b->state = FAILED;
-		return FAIL;
-
-	case INIT9LOAD:
-	case READ9LOAD:
-		panic("end 9load");
-
-	default:
-		panic("bootdone");
-	}
-	b->state = FAILED;
-	return FAIL;
-}
--- a/os/boot/pc/bootld.c
+++ /dev/null
@@ -1,108 +1,0 @@
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-
-static int
-addbytes(char **dbuf, char *edbuf, char **sbuf, char *esbuf)
-{
-	int n;
-
-	n = edbuf - *dbuf;
-	if(n <= 0)
-		return 0;
-	if(n > esbuf - *sbuf)
-		n = esbuf - *sbuf;
-	if(n <= 0)
-		return -1;
-
-	memmove(*dbuf, *sbuf, n);
-	*sbuf += n;
-	*dbuf += n;
-	return edbuf - *dbuf;
-}
-
-extern void origin(void);
-
-int
-bootpass(Boot *b, void *vbuf, int nbuf)
-{
-	char *buf, *ebuf, *p, *q;
-	ulong size;
-
-	if(b->state == FAILED)
-		return FAIL;
-
-	if(nbuf == 0)
-		goto Endofinput;
-
-	buf = vbuf;
-	ebuf = buf+nbuf;
-	while(addbytes(&b->wp, b->ep, &buf, ebuf) == 0) {
-		switch(b->state) {
-		case INIT9LOAD:
-			b->state = READ9LOAD;
-			b->bp = (char*)0x10000;
-			b->wp = b->bp;
-			b->ep = b->bp + 256*1024;
-			break;
-
-		case READ9LOAD:
-			return ENOUGH;
-
-		default:
-			panic("bootstate");
-		}
-	}
-	return MORE;
-
-
-Endofinput:
-	/* end of input */
-	print("\n");
-	switch(b->state) {
-	case INIT9LOAD:
-		print("premature EOF\n");
-		b->state = FAILED;
-		return FAIL;
-	
-	case READ9LOAD:
-		size = b->wp - b->bp;
-		if(memcmp(b->bp, origin, 16) != 0) {
-			print("beginning of file does not look right\n");
-			b->state = FAILED;
-			return FAIL;
-		}
-		if(size < 32*1024 || size > 256*1024) {
-			print("got %lud byte loader; not likely\n", size);
-			b->state = FAILED;
-			return FAIL;
-		}
-
-		p = b->bp;
-		q = b->wp;
-		if(q - p > 10000)	/* don't search much past l.s */
-			q = p+10000;
-
-		/*
-		 * The string `JUMP' appears right before
-		 * tokzero, which is where we want to jump.
-		 */
-		for(; p<q; p++) {
-			if(strncmp(p, "JUMP", 4) == 0) {
-				p += 4;
-				warp9((ulong)p);
-			}
-		}
-		print("could not find jump destination\n");
-		b->state = FAILED;
-		return FAIL;
-
-	default:
-		panic("bootdone");
-	}
-	b->state = FAILED;
-	return FAIL;
-}
--- a/os/boot/pc/bootp.c
+++ /dev/null
@@ -1,659 +1,0 @@
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-
-#include "ip.h"
-
-extern int debugload;
-
-uchar broadcast[Eaddrlen] = {
-	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-};
-
-static ushort tftpport = 5000;
-static int Id = 1;
-static Netaddr myaddr;
-static Netaddr server;
-
-typedef struct {
-	uchar	header[4];
-	uchar	data[Segsize];
-} Tftp;
-static Tftp tftpb;
-
-static void
-hnputs(uchar *ptr, ushort val)
-{
-	ptr[0] = val>>8;
-	ptr[1] = val;
-}
-
-static void
-hnputl(uchar *ptr, ulong val)
-{
-	ptr[0] = val>>24;
-	ptr[1] = val>>16;
-	ptr[2] = val>>8;
-	ptr[3] = val;
-}
-
-static ulong
-nhgetl(uchar *ptr)
-{
-	return ((ptr[0]<<24) | (ptr[1]<<16) | (ptr[2]<<8) | ptr[3]);
-}
-
-static ushort
-nhgets(uchar *ptr)
-{
-	return ((ptr[0]<<8) | ptr[1]);
-}
-
-static	short	endian	= 1;
-static	char*	aendian	= (char*)&endian;
-#define	LITTLE	*aendian
-
-static ushort
-ptcl_csum(void *a, int len)
-{
-	uchar *addr;
-	ulong t1, t2;
-	ulong losum, hisum, mdsum, x;
-
-	addr = a;
-	losum = 0;
-	hisum = 0;
-	mdsum = 0;
-
-	x = 0;
-	if((ulong)addr & 1) {
-		if(len) {
-			hisum += addr[0];
-			len--;
-			addr++;
-		}
-		x = 1;
-	}
-	while(len >= 16) {
-		t1 = *(ushort*)(addr+0);
-		t2 = *(ushort*)(addr+2);	mdsum += t1;
-		t1 = *(ushort*)(addr+4);	mdsum += t2;
-		t2 = *(ushort*)(addr+6);	mdsum += t1;
-		t1 = *(ushort*)(addr+8);	mdsum += t2;
-		t2 = *(ushort*)(addr+10);	mdsum += t1;
-		t1 = *(ushort*)(addr+12);	mdsum += t2;
-		t2 = *(ushort*)(addr+14);	mdsum += t1;
-		mdsum += t2;
-		len -= 16;
-		addr += 16;
-	}
-	while(len >= 2) {
-		mdsum += *(ushort*)addr;
-		len -= 2;
-		addr += 2;
-	}
-	if(x) {
-		if(len)
-			losum += addr[0];
-		if(LITTLE)
-			losum += mdsum;
-		else
-			hisum += mdsum;
-	} else {
-		if(len)
-			hisum += addr[0];
-		if(LITTLE)
-			hisum += mdsum;
-		else
-			losum += mdsum;
-	}
-
-	losum += hisum >> 8;
-	losum += (hisum & 0xff) << 8;
-	while(hisum = losum>>16)
-		losum = hisum + (losum & 0xffff);
-
-	return ~losum;
-}
-
-static ushort
-ip_csum(uchar *addr)
-{
-	int len;
-	ulong sum = 0;
-
-	len = (addr[0]&0xf)<<2;
-
-	while(len > 0) {
-		sum += addr[0]<<8 | addr[1] ;
-		len -= 2;
-		addr += 2;
-	}
-
-	sum = (sum & 0xffff) + (sum >> 16);
-	sum = (sum & 0xffff) + (sum >> 16);
-	return (sum^0xffff);
-}
-
-enum {
-	/* this is only true of IPv4, but we're not doing v6 yet */
-	Min_udp_payload = ETHERMINTU - ETHERHDRSIZE - UDP_HDRSIZE,
-};
-
-static void
-udpsend(int ctlrno, Netaddr *a, void *data, int dlen)
-{
-	char payload[ETHERMAXTU];
-	Udphdr *uh;
-	Etherhdr *ip;
-	Etherpkt pkt;
-	int len, ptcllen;
-
-	/*
-	 * if packet is too short, make it longer rather than relying
-	 * on ethernet interface or lower layers to pad it.
-	 */
-	if (dlen < Min_udp_payload) {
-		memmove(payload, data, dlen);
-		data = payload;
-		dlen = Min_udp_payload;
-	}
-
-	uh = (Udphdr*)&pkt;
-
-	memset(uh, 0, sizeof(Etherpkt));
-	memmove(uh->udpcksum+sizeof(uh->udpcksum), data, dlen);
-
-	/*
-	 * UDP portion
-	 */
-	ptcllen = dlen + (UDP_HDRSIZE-UDP_PHDRSIZE);
-	uh->ttl = 0;
-	uh->udpproto = IP_UDPPROTO;
-	uh->frag[0] = 0;
-	uh->frag[1] = 0;
-	hnputs(uh->udpplen, ptcllen);
-	hnputl(uh->udpsrc, myaddr.ip);
-	hnputs(uh->udpsport, myaddr.port);
-	hnputl(uh->udpdst, a->ip);
-	hnputs(uh->udpdport, a->port);
-	hnputs(uh->udplen, ptcllen);
-	uh->udpcksum[0] = 0;
-	uh->udpcksum[1] = 0;
-	dlen = (dlen+1)&~1;
-	hnputs(uh->udpcksum, ptcl_csum(&uh->ttl, dlen+UDP_HDRSIZE));
-
-	/*
-	 * IP portion
-	 */
-	ip = (Etherhdr*)&pkt;
-	len = UDP_EHSIZE+UDP_HDRSIZE+dlen;		/* non-descriptive names */
-	ip->vihl = IP_VER|IP_HLEN;
-	ip->tos = 0;
-	ip->ttl = 255;
-	hnputs(ip->length, len-ETHER_HDR);
-	hnputs(ip->id, Id++);
-	ip->frag[0] = 0;
-	ip->frag[1] = 0;
-	ip->cksum[0] = 0;
-	ip->cksum[1] = 0;
-	hnputs(ip->cksum, ip_csum(&ip->vihl));
-
-	/*
-	 * Ethernet MAC portion
-	 */
-	hnputs(ip->type, ET_IP);
-	memmove(ip->d, a->ea, sizeof(ip->d));
-
-if(debug) {
-	print("udpsend ");
-}
-	ethertxpkt(ctlrno, &pkt, len, Timeout);
-}
-
-static void
-nak(int ctlrno, Netaddr *a, int code, char *msg, int report)
-{
-	int n;
-	char buf[128];
-
-	buf[0] = 0;
-	buf[1] = Tftp_ERROR;
-	buf[2] = 0;
-	buf[3] = code;
-	strcpy(buf+4, msg);
-	n = strlen(msg) + 4 + 1;
-	udpsend(ctlrno, a, buf, n);
-	if(report)
-		print("\ntftp: error(%d): %s\n", code, msg);
-}
-
-static int
-udprecv(int ctlrno, Netaddr *a, void *data, int dlen)
-{
-	int n, len;
-	ushort csm;
-	Udphdr *h;
-	ulong addr, timo;
-	Etherpkt pkt;
-	static int rxactive;
-
-	if(rxactive == 0)
-		timo = 1000;
-	else
-		timo = Timeout;
-	timo += TK2MS(m->ticks);
-	while(timo > TK2MS(m->ticks)){
-		n = etherrxpkt(ctlrno, &pkt, timo-TK2MS(m->ticks));
-		if(n <= 0)
-			continue;
-
-		h = (Udphdr*)&pkt;
-		if(debug)
-			print("udprecv %E to %E...\n", h->s, h->d);
-
-		if(nhgets(h->type) != ET_IP) {
-			if(debug)
-				print("not ip...");
-			continue;
-		}
-
-		if(ip_csum(&h->vihl)) {
-			print("ip chksum error\n");
-			continue;
-		}
-		if(h->vihl != (IP_VER|IP_HLEN)) {
-			print("ip bad vers/hlen\n");
-			continue;
-		}
-
-		if(h->udpproto != IP_UDPPROTO) {
-			if(debug)
-				print("not udp (%d)...", h->udpproto);
-			continue;
-		}
-
-		if(debug)
-			print("okay udp...");
-
-		h->ttl = 0;
-		len = nhgets(h->udplen);
-		hnputs(h->udpplen, len);
-
-		if(nhgets(h->udpcksum)) {
-			csm = ptcl_csum(&h->ttl, len+UDP_PHDRSIZE);
-			if(csm != 0) {
-				print("udp chksum error csum #%4ux len %d\n",
-					csm, n);
-				break;
-			}
-		}
-
-		if(a->port != 0 && nhgets(h->udpsport) != a->port) {
-			if(debug)
-				print("udpport %ux not %ux\n",
-					nhgets(h->udpsport), a->port);
-			continue;
-		}
-
-		addr = nhgetl(h->udpsrc);
-		if(a->ip != Bcastip && a->ip != addr) {
-			if(debug)
-				print("bad ip %lux not %lux\n", addr, a->ip);
-			continue;
-		}
-
-		len -= UDP_HDRSIZE-UDP_PHDRSIZE;
-		if(len > dlen) {
-			print("udp: packet too big: %d > %d; from addr %E\n",
-				len, dlen, h->udpsrc);
-			continue;
-		}
-
-		memmove(data, h->udpcksum+sizeof(h->udpcksum), len);
-		a->ip = addr;
-		a->port = nhgets(h->udpsport);
-		memmove(a->ea, pkt.s, sizeof(a->ea));
-
-		rxactive = 1;
-		return len;
-	}
-
-	return 0;
-}
-
-static int tftpblockno;
-
-/*
- * format of a request packet, from the RFC:
- *
-            2 bytes     string    1 byte     string   1 byte
-            ------------------------------------------------
-           | Opcode |  Filename  |   0  |    Mode    |   0  |
-            ------------------------------------------------
- */
-static int
-tftpopen(int ctlrno, Netaddr *a, char *name, Tftp *tftp)
-{
-	int i, len, rlen, oport;
-	char buf[Segsize+2];
-
-	buf[0] = 0;
-	buf[1] = Tftp_READ;
-	len = 2 + sprint(buf+2, "%s", name) + 1;
-	len += sprint(buf+len, "octet") + 1;
-
-	oport = a->port;
-	for(i = 0; i < 5; i++){
-		a->port = oport;
-		udpsend(ctlrno, a, buf, len);
-		a->port = 0;
-		if((rlen = udprecv(ctlrno, a, tftp, sizeof(Tftp))) < sizeof(tftp->header))
-			continue;
-
-		switch((tftp->header[0]<<8)|tftp->header[1]){
-
-		case Tftp_ERROR:
-			print("tftpopen: error (%d): %s\n",
-				(tftp->header[2]<<8)|tftp->header[3], (char*)tftp->data);
-			return -1;
-
-		case Tftp_DATA:
-			tftpblockno = 1;
-			len = (tftp->header[2]<<8)|tftp->header[3];
-			if(len != tftpblockno){
-				print("tftpopen: block error: %d\n", len);
-				nak(ctlrno, a, 1, "block error", 0);
-				return -1;
-			}
-			rlen -= sizeof(tftp->header);
-			if(rlen < Segsize){
-				/* ACK now, in case we don't later */
-				buf[0] = 0;
-				buf[1] = Tftp_ACK;
-				buf[2] = tftpblockno>>8;
-				buf[3] = tftpblockno;
-				udpsend(ctlrno, a, buf, sizeof(tftp->header));
-			}
-			return rlen;
-		}
-	}
-
-	print("tftpopen: failed to connect to server\n");
-	return -1;
-}
-
-static int
-tftpread(int ctlrno, Netaddr *a, Tftp *tftp, int dlen)
-{
-	uchar buf[4];
-	int try, blockno, len;
-
-	dlen += sizeof(tftp->header);
-
-	for(try = 0; try < 10; try++) {
-		buf[0] = 0;
-		buf[1] = Tftp_ACK;
-		buf[2] = tftpblockno>>8;
-		buf[3] = tftpblockno;
-
-		udpsend(ctlrno, a, buf, sizeof(buf));
-		len = udprecv(ctlrno, a, tftp, dlen);
-		if(len <= sizeof(tftp->header)){
-			if(debug)
-				print("tftpread: too short %d <= %d\n",
-					len, sizeof(tftp->header));
-			continue;
-		}
-		blockno = (tftp->header[2]<<8)|tftp->header[3];
-		if(blockno <= tftpblockno){
-			if(debug)
-				print("tftpread: blkno %d <= %d\n",
-					blockno, tftpblockno);
-			continue;
-		}
-
-		if(blockno == tftpblockno+1) {
-			tftpblockno++;
-			if(len < dlen) {	/* last packet; send final ack */
-				tftpblockno++;
-				buf[0] = 0;
-				buf[1] = Tftp_ACK;
-				buf[2] = tftpblockno>>8;
-				buf[3] = tftpblockno;
-				udpsend(ctlrno, a, buf, sizeof(buf));
-			}
-			return len-sizeof(tftp->header);
-		}
-		print("tftpread: block error: %d, expected %d\n",
-			blockno, tftpblockno+1);
-	}
-
-	return -1;
-}
-
-static int
-bootpopen(int ctlrno, char *file, Bootp *rep, int dotftpopen)
-{
-	Bootp req;
-	int i, n;
-	uchar *ea;
-	char name[128], *filename, *sysname;
-
-	if (debugload)
-		print("bootpopen: ether%d!%s...", ctlrno, file);
-	if((ea = etheraddr(ctlrno)) == 0){
-		print("invalid ctlrno %d\n", ctlrno);
-		return -1;
-	}
-
-	filename = 0;
-	sysname = 0;
-	if(file && *file){
-		strcpy(name, file);
-		if(filename = strchr(name, '!')){
-			sysname = name;
-			*filename++ = 0;
-		}
-		else
-			filename = name;
-	}
-
-	memset(&req, 0, sizeof(req));
-	req.op = Bootrequest;
-	req.htype = 1;			/* ethernet */
-	req.hlen = Eaddrlen;		/* ethernet */
-	memmove(req.chaddr, ea, Eaddrlen);
-	if(filename != nil)
-		strncpy(req.file, filename, sizeof(req.file));
-	if(sysname != nil)
-		strncpy(req.sname, sysname, sizeof(req.sname));
-
-	myaddr.ip = 0;
-	myaddr.port = BPportsrc;
-	memmove(myaddr.ea, ea, Eaddrlen);
-
-	etherrxflush(ctlrno);
-	for(i = 0; i < 10; i++) {
-		server.ip = Bcastip;
-		server.port = BPportdst;
-		memmove(server.ea, broadcast, sizeof(server.ea));
-		udpsend(ctlrno, &server, &req, sizeof(req));
-		if(udprecv(ctlrno, &server, rep, sizeof(*rep)) <= 0)
-			continue;
-		if(memcmp(req.chaddr, rep->chaddr, Eaddrlen))
-			continue;
-		if(rep->htype != 1 || rep->hlen != Eaddrlen)
-			continue;
-		if(sysname == 0 || strcmp(sysname, rep->sname) == 0)
-			break;
-	}
-	if(i >= 10) {
-		print("bootp timed out\n");
-		return -1;
-	}
-
-	if(!dotftpopen)
-		return 0;
-
-	if(filename == 0 || *filename == 0){
-		if(strcmp(rep->file, "/386/9pxeload") == 0)
-			return -1;
-		filename = rep->file;
-	}
-
-	if(rep->sname[0] != '\0')
-		 print("%s ", rep->sname);
-	print("(%d.%d.%d.%d!%d): %s\n",
-		rep->siaddr[0],
-		rep->siaddr[1],
-		rep->siaddr[2],
-		rep->siaddr[3],
-		server.port,
-		filename);
-
-	myaddr.ip = nhgetl(rep->yiaddr);
-	myaddr.port = tftpport++;
-	server.ip = nhgetl(rep->siaddr);
-	server.port = TFTPport;
-
-	if((n = tftpopen(ctlrno, &server, filename, &tftpb)) < 0)
-		return -1;
-
-	return n;
-}
-
-int
-bootpboot(int ctlrno, char *file, Boot *b)
-{
-	int n;
-	Bootp rep;
-
-	if((n = bootpopen(ctlrno, file, &rep, 1)) < 0)
-		return -1;
-
-	while(bootpass(b, tftpb.data, n) == MORE){
-		n = tftpread(ctlrno, &server, &tftpb, sizeof(tftpb.data));
-		if(n < sizeof(tftpb.data))
-			break;
-	}
-
-	if(0 < n && n < sizeof(tftpb.data))	/* got to end of file */
-		bootpass(b, tftpb.data, n);
-	else
-		nak(ctlrno, &server, 3, "ok", 0);	/* tftpclose to abort transfer */
-	bootpass(b, nil, 0);	/* boot if possible */
-	return -1;
-}
-
-#include "fs.h"
-
-#define INIPATHLEN	64
-
-static struct {
-	Fs	fs;
-	char	ini[INIPATHLEN];
-} pxether[MaxEther];
-
-static vlong
-pxediskseek(Fs*, vlong)
-{
-	return -1LL;
-}
-
-static long
-pxediskread(Fs*, void*, long)
-{
-	return -1;
-}
-
-static long
-pxeread(File* f, void* va, long len)
-{
-	int n;
-	Bootp rep;
-	char *p, *v;
-
-	if((n = bootpopen(f->fs->dev, pxether[f->fs->dev].ini, &rep, 1)) < 0)
-		return -1;
-
-	p = v = va;
-	while(n > 0) {
-		if((p-v)+n > len)
-			n = len - (p-v);
-		memmove(p, tftpb.data, n);
-		p += n;
-		if(n != Segsize)
-			break;
-		if((n = tftpread(f->fs->dev, &server, &tftpb, sizeof(tftpb.data))) < 0)
-			return -1;
-	}
-	return p-v;
-}
-
-static int
-pxewalk(File* f, char* name)
-{
-	Bootp rep;
-	char *ini;
-
-	switch(f->walked){
-	default:
-		return -1;
-	case 0:
-		if(strcmp(name, "cfg") == 0){
-			f->walked = 1;
-			return 1;
-		}
-		break;
-	case 1:
-		if(strcmp(name, "pxe") == 0){
-			f->walked = 2;
-			return 1;
-		}
-		break;
-	case 2:
-		if(strcmp(name, "%E") != 0)
-			break;
-		f->walked = 3;
-
-		if(bootpopen(f->fs->dev, nil, &rep, 0) < 0)
-			return 0;
-
-		ini = pxether[f->fs->dev].ini;
-		/* use our mac address instead of relying on a bootp answer */
-		snprint(ini, INIPATHLEN, "/cfg/pxe/%E", (uchar *)myaddr.ea);
-		f->path = ini;
-
-		return 1;
-	}
-	return 0;
-}
-
-void*
-pxegetfspart(int ctlrno, char* part, int)
-{
-	if(!pxe)
-		return nil;
-	if(strcmp(part, "*") != 0)
-		return nil;
-	if(ctlrno >= MaxEther)
-		return nil;
-	if(iniread && getconf("*pxeini") != nil)
-		return nil;
-
-	pxether[ctlrno].fs.dev = ctlrno;
-	pxether[ctlrno].fs.diskread = pxediskread;
-	pxether[ctlrno].fs.diskseek = pxediskseek;
-
-	pxether[ctlrno].fs.read = pxeread;
-	pxether[ctlrno].fs.walk = pxewalk;
-
-	pxether[ctlrno].fs.root.fs = &pxether[ctlrno].fs;
-	pxether[ctlrno].fs.root.walked = 0;
-
-	return &pxether[ctlrno].fs;
-}
--- a/os/boot/pc/cga.c
+++ /dev/null
@@ -1,91 +1,0 @@
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-
-enum {
-	Width		= 160,
-	Height		= 25,
-
-	Attr		= 7,		/* white on black */
-};
-
-#define CGASCREENBASE	((uchar*)KADDR(0xB8000))
-
-static int pos;
-static int screeninitdone;
-
-static uchar
-cgaregr(int index)
-{
-	outb(0x3D4, index);
-	return inb(0x3D4+1) & 0xFF;
-}
-
-static void
-cgaregw(int index, int data)
-{
-	outb(0x3D4, index);
-	outb(0x3D4+1, data);
-}
-
-static void
-movecursor(void)
-{
-	cgaregw(0x0E, (pos/2>>8) & 0xFF);
-	cgaregw(0x0F, pos/2 & 0xFF);
-	CGASCREENBASE[pos+1] = Attr;
-}
-
-static void
-cgascreenputc(int c)
-{
-	int i;
-
-	if(c == '\n'){
-		pos = pos/Width;
-		pos = (pos+1)*Width;
-	}
-	else if(c == '\t'){
-		i = 8 - ((pos/2)&7);
-		while(i-->0)
-			cgascreenputc(' ');
-	}
-	else if(c == '\b'){
-		if(pos >= 2)
-			pos -= 2;
-		cgascreenputc(' ');
-		pos -= 2;
-	}
-	else{
-		CGASCREENBASE[pos++] = c;
-		CGASCREENBASE[pos++] = Attr;
-	}
-	if(pos >= Width*Height){
-		memmove(CGASCREENBASE, &CGASCREENBASE[Width], Width*(Height-1));
-		memset(&CGASCREENBASE[Width*(Height-1)], 0, Width);
-		pos = Width*(Height-1);
-	}
-	movecursor();
-}
-
-static void
-screeninit(void)
-{
-	if(screeninitdone == 0){
-		pos = cgaregr(0x0E)<<8;
-		pos |= cgaregr(0x0F);
-		pos *= 2;
-		screeninitdone = 1;
-	}
-}
-
-void
-cgascreenputs(char* s, int n)
-{
-	if(screeninitdone == 0)
-		screeninit();
-	while(n-- > 0)
-		cgascreenputc(*s++);
-}
--- a/os/boot/pc/cis.c
+++ /dev/null
@@ -1,539 +1,0 @@
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "error.h"
-#include "io.h"
-
-enum{
-	Linktarget = 0x13,
-};
-	
-/*
- *  read and crack the card information structure enough to set
- *  important parameters like power
- */
-/* cis memory walking */
-typedef struct Cisdat {
-	uchar	*cisbase;
-	int	cispos;
-	int	cisskip;
-	int	cislen;
-} Cisdat;
-
-static void	tcfig(PCMslot*, Cisdat*, int);
-static void	tentry(PCMslot*, Cisdat*, int);
-static void	tvers1(PCMslot*, Cisdat*, int);
-static void	tlonglnkmfc(PCMslot*, Cisdat*, int);
-
-static int
-readc(Cisdat *cis, uchar *x)
-{
-	if(cis->cispos >= cis->cislen)
-		return 0;
-	*x = cis->cisbase[cis->cisskip*cis->cispos];
-	cis->cispos++;
-	return 1;
-}
-
-static int
-xcistuple(int slotno, int tuple, int subtuple, void *v, int nv, int attr)
-{
-	PCMmap *m;
-	Cisdat cis;
-	int i, l;
-	uchar *p;
-	uchar type, link, n, c;
-	int this, subtype;
-
-	m = pcmmap(slotno, 0, 0, attr);
-	if(m == 0)
-		return -1;
-
-	cis.cisbase = KADDR(m->isa);
-	cis.cispos = 0;
-	cis.cisskip = attr ? 2 : 1;
-	cis.cislen = m->len;
-
-	/* loop through all the tuples */
-	for(i = 0; i < 1000; i++){
-		this = cis.cispos;
-		if(readc(&cis, &type) != 1)
-			break;
-		if(type == 0xFF)
-			break;
-		if(readc(&cis, &link) != 1)
-			break;
-		if(link == 0xFF)
-			break;
-
-		n = link;
-		if(link > 1 && subtuple != -1){
-			if(readc(&cis, &c) != 1)
-				break;
-			subtype = c;
-			n--;
-		}else
-			subtype = -1;
-
-		if(type == tuple && subtype == subtuple){
-			p = v;
-			for(l=0; l<nv && l<n; l++)
-				if(readc(&cis, p++) != 1)
-					break;
-			pcmunmap(slotno, m);
-			return nv;
-		}
-		cis.cispos = this + (2+link);
-	}
-	pcmunmap(slotno, m);
-	return -1;
-}
-
-int
-pcmcistuple(int slotno, int tuple, int subtuple, void *v, int nv)
-{
-	int n;
-
-	/* try attribute space, then memory */
-	if((n = xcistuple(slotno, tuple, subtuple, v, nv, 1)) >= 0)
-		return n;
-	return xcistuple(slotno, tuple, subtuple, v, nv, 0);
-}
-
-void
-pcmcisread(PCMslot *pp)
-{
-	int this;
-	Cisdat cis;
-	PCMmap *m;
-	uchar type, link;
-
-	memset(pp->ctab, 0, sizeof(pp->ctab));
-	pp->ncfg = 0;
-	memset(pp->cfg, 0, sizeof(pp->cfg));
-	pp->configed = 0;
-	pp->nctab = 0;
-	pp->verstr[0] = 0;
-
-	/*
-	 * Read all tuples in attribute space.
-	 */
-	m = pcmmap(pp->slotno, 0, 0, 1);
-	if(m == 0)
-		return;
-
-	cis.cisbase = KADDR(m->isa);
-	cis.cispos = 0;
-	cis.cisskip = 2;
-	cis.cislen = m->len;
-
-	/* loop through all the tuples */
-	for(;;){
-		this = cis.cispos;
-		if(readc(&cis, &type) != 1)
-			break;
-		if(type == 0xFF)
-			break;
-		if(readc(&cis, &link) != 1)
-			break;
-
-		switch(type){
-		default:
-			break;
-		case 6:
-			tlonglnkmfc(pp, &cis, type);
-			break;
-		case 0x15:
-			tvers1(pp, &cis, type);
-			break;
-		case 0x1A:
-			tcfig(pp, &cis, type);
-			break;
-		case 0x1B:
-			tentry(pp, &cis, type);
-			break;
-		}
-
-		if(link == 0xFF)
-			break;
-		cis.cispos = this + (2+link);
-	}
-	pcmunmap(pp->slotno, m);
-}
-
-static ulong
-getlong(Cisdat *cis, int size)
-{
-	uchar c;
-	int i;
-	ulong x;
-
-	x = 0;
-	for(i = 0; i < size; i++){
-		if(readc(cis, &c) != 1)
-			break;
-		x |= c<<(i*8);
-	}
-	return x;
-}
-
-static void
-tcfig(PCMslot *pp, Cisdat *cis, int )
-{
-	uchar size, rasize, rmsize;
-	uchar last;
-
-	if(readc(cis, &size) != 1)
-		return;
-	rasize = (size&0x3) + 1;
-	rmsize = ((size>>2)&0xf) + 1;
-	if(readc(cis, &last) != 1)
-		return;
-
-	if(pp->ncfg >= 8){
-		print("tcfig: too many configuration registers\n");
-		return;
-	}
-	
-	pp->cfg[pp->ncfg].caddr = getlong(cis, rasize);
-	pp->cfg[pp->ncfg].cpresent = getlong(cis, rmsize);
-	pp->ncfg++;
-}
-
-static ulong vexp[8] =
-{
-	1, 10, 100, 1000, 10000, 100000, 1000000, 10000000
-};
-static ulong vmant[16] =
-{
-	10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80, 90,
-};
-
-static ulong
-microvolt(Cisdat *cis)
-{
-	uchar c;
-	ulong microvolts;
-	ulong exp;
-
-	if(readc(cis, &c) != 1)
-		return 0;
-	exp = vexp[c&0x7];
-	microvolts = vmant[(c>>3)&0xf]*exp;
-	while(c & 0x80){
-		if(readc(cis, &c) != 1)
-			return 0;
-		switch(c){
-		case 0x7d:
-			break;		/* high impedence when sleeping */
-		case 0x7e:
-		case 0x7f:
-			microvolts = 0;	/* no connection */
-			break;
-		default:
-			exp /= 10;
-			microvolts += exp*(c&0x7f);
-		}
-	}
-	return microvolts;
-}
-
-static ulong
-nanoamps(Cisdat *cis)
-{
-	uchar c;
-	ulong nanoamps;
-
-	if(readc(cis, &c) != 1)
-		return 0;
-	nanoamps = vexp[c&0x7]*vmant[(c>>3)&0xf];
-	while(c & 0x80){
-		if(readc(cis, &c) != 1)
-			return 0;
-		if(c == 0x7d || c == 0x7e || c == 0x7f)
-			nanoamps = 0;
-	}
-	return nanoamps;
-}
-
-/*
- * only nominal voltage (feature 1) is important for config,
- * other features must read card to stay in sync.
- */
-static ulong
-power(Cisdat *cis)
-{
-	uchar feature;
-	ulong mv;
-
-	mv = 0;
-	if(readc(cis, &feature) != 1)
-		return 0;
-	if(feature & 1)
-		mv = microvolt(cis);
-	if(feature & 2)
-		microvolt(cis);
-	if(feature & 4)
-		microvolt(cis);
-	if(feature & 8)
-		nanoamps(cis);
-	if(feature & 0x10)
-		nanoamps(cis);
-	if(feature & 0x20)
-		nanoamps(cis);
-	if(feature & 0x40)
-		nanoamps(cis);
-	return mv/1000000;
-}
-
-static ulong mantissa[16] =
-{ 0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80, };
-
-static ulong exponent[8] =
-{ 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, };
-
-static ulong
-ttiming(Cisdat *cis, int scale)
-{
-	uchar unscaled;
-	ulong nanosecs;
-
-	if(readc(cis, &unscaled) != 1)
-		return 0;
-	nanosecs = (mantissa[(unscaled>>3)&0xf]*exponent[unscaled&7])/10;
-	nanosecs = nanosecs * vexp[scale];
-	return nanosecs;
-}
-
-static void
-timing(Cisdat *cis, PCMconftab *ct)
-{
-	uchar c, i;
-
-	if(readc(cis, &c) != 1)
-		return;
-	i = c&0x3;
-	if(i != 3)
-		ct->maxwait = ttiming(cis, i);		/* max wait */
-	i = (c>>2)&0x7;
-	if(i != 7)
-		ct->readywait = ttiming(cis, i);		/* max ready/busy wait */
-	i = (c>>5)&0x7;
-	if(i != 7)
-		ct->otherwait = ttiming(cis, i);		/* reserved wait */
-}
-
-static void
-iospaces(Cisdat *cis, PCMconftab *ct)
-{
-	uchar c;
-	int i, nio;
-
-	ct->nio = 0;
-	if(readc(cis, &c) != 1)
-		return;
-
-	ct->bit16 = ((c>>5)&3) >= 2;
-	if(!(c & 0x80)){
-		ct->io[0].start = 0;
-		ct->io[0].len = 1<<(c&0x1f);
-		ct->nio = 1;
-		return;
-	}
-
-	if(readc(cis, &c) != 1)
-		return;
-
-	/*
-	 * For each of the range descriptions read the
-	 * start address and the length (value is length-1).
-	 */
-	nio = (c&0xf)+1;
-	for(i = 0; i < nio; i++){
-		ct->io[i].start = getlong(cis, (c>>4)&0x3);
-		ct->io[i].len = getlong(cis, (c>>6)&0x3)+1;
-	}
-	ct->nio = nio;
-}
-
-static void
-irq(Cisdat *cis, PCMconftab *ct)
-{
-	uchar c;
-
-	if(readc(cis, &c) != 1)
-		return;
-	ct->irqtype = c & 0xe0;
-	if(c & 0x10)
-		ct->irqs = getlong(cis, 2);
-	else
-		ct->irqs = 1<<(c&0xf);
-	ct->irqs &= 0xDEB8;		/* levels available to card */
-}
-
-static void
-memspace(Cisdat *cis, int asize, int lsize, int host)
-{
-	ulong haddress, address, len;
-
-	len = getlong(cis, lsize)*256;
-	address = getlong(cis, asize)*256;
-	USED(len, address);
-	if(host){
-		haddress = getlong(cis, asize)*256;
-		USED(haddress);
-	}
-}
-
-static void
-tentry(PCMslot *pp, Cisdat *cis, int )
-{
-	uchar c, i, feature;
-	PCMconftab *ct;
-
-	if(pp->nctab >= nelem(pp->ctab))
-		return;
-	if(readc(cis, &c) != 1)
-		return;
-	ct = &pp->ctab[pp->nctab++];
-
-	/* copy from last default config */
-	if(pp->def)
-		*ct = *pp->def;
-
-	ct->index = c & 0x3f;
-
-	/* is this the new default? */
-	if(c & 0x40)
-		pp->def = ct;
-
-	/* memory wait specified? */
-	if(c & 0x80){
-		if(readc(cis, &i) != 1)
-			return;
-		if(i&0x80)
-			ct->memwait = 1;
-	}
-
-	if(readc(cis, &feature) != 1)
-		return;
-	switch(feature&0x3){
-	case 1:
-		ct->vpp1 = ct->vpp2 = power(cis);
-		break;
-	case 2:
-		power(cis);
-		ct->vpp1 = ct->vpp2 = power(cis);
-		break;
-	case 3:
-		power(cis);
-		ct->vpp1 = power(cis);
-		ct->vpp2 = power(cis);
-		break;
-	default:
-		break;
-	}
-	if(feature&0x4)
-		timing(cis, ct);
-	if(feature&0x8)
-		iospaces(cis, ct);
-	if(feature&0x10)
-		irq(cis, ct);
-	switch((feature>>5)&0x3){
-	case 1:
-		memspace(cis, 0, 2, 0);
-		break;
-	case 2:
-		memspace(cis, 2, 2, 0);
-		break;
-	case 3:
-		if(readc(cis, &c) != 1)
-			return;
-		for(i = 0; i <= (c&0x7); i++)
-			memspace(cis, (c>>5)&0x3, (c>>3)&0x3, c&0x80);
-		break;
-	}
-	pp->configed++;
-}
-
-static void
-tvers1(PCMslot *pp, Cisdat *cis, int )
-{
-	uchar c, major, minor, last;
-	int  i;
-
-	if(readc(cis, &major) != 1)
-		return;
-	if(readc(cis, &minor) != 1)
-		return;
-	last = 0;
-	for(i = 0; i < sizeof(pp->verstr)-1; i++){
-		if(readc(cis, &c) != 1)
-			return;
-		if(c == 0)
-			c = ';';
-		if(c == '\n')
-			c = ';';
-		if(c == 0xff)
-			break;
-		if(c == ';' && last == ';')
-			continue;
-		pp->verstr[i] = c;
-		last = c;
-	}
-	pp->verstr[i] = 0;
-}
-
-static void
-tlonglnkmfc(PCMslot *pp, Cisdat *cis, int)
-{
-	int i, npos, opos;
-	uchar nfn, space, expect, type, this, link;
-
-	readc(cis, &nfn);
-	for(i = 0; i < nfn; i++){
-		readc(cis, &space);
-		npos        = getlong(cis, 4);
-		opos        = cis->cispos;
-		cis->cispos = npos;
-		expect      = Linktarget;
-
-		while(1){
-			this = cis->cispos;
-			if(readc(cis, &type) != 1)
-				break;
-			if(type == 0xFF)
-				break;
-			if(readc(cis, &link) != 1)
-				break;
-
-			if(expect && expect != type){
-				print("tlonglnkmfc: expected %X found %X\n",
-					expect, type);
-				break;
-			}
-			expect = 0;
-
-			switch(type){
-			default:
-				break;
-			case 0x15:
-				tvers1(pp, cis, type);
-				break;
-			case 0x1A:
-				tcfig(pp, cis, type);
-				break;
-			case 0x1B:
-				tentry(pp, cis, type);
-				break;
-			}
-
-			if(link == 0xFF)
-				break;
-			cis->cispos = this + (2+link);
-		}
-		cis->cispos = opos;
-	}
-}
--- a/os/boot/pc/clock.c
+++ /dev/null
@@ -1,309 +1,0 @@
-#include	"u.h"
-#include	"lib.h"
-#include	"mem.h"
-#include	"dat.h"
-#include	"fns.h"
-#include	"io.h"
-#include	"ureg.h"
-
-/*
- *  8253 timer
- */
-enum
-{
-	T0cntr=	0x40,		/* counter ports */
-	T1cntr=	0x41,		/* ... */
-	T2cntr=	0x42,		/* ... */
-	Tmode=	0x43,		/* mode port */
-
-	/* commands */
-	Latch0=	0x00,		/* latch counter 0's value */
-	Load0=	0x30,		/* load counter 0 with 2 bytes */
-
-	/* modes */
-	Square=	0x36,		/* perioic square wave */
-
-	Freq=	1193182,	/* Real clock frequency */
-};
-
-static uvlong cpuhz = 66000000;
-static int cpumhz = 66;
-static int loopconst = 100;
-int cpuidax, cpuiddx;
-int havetsc;
-
-extern void _cycles(uvlong*);		/* in l.s */
-extern void wrmsr(int, vlong);
-
-static void
-clockintr(Ureg*, void*)
-{
-	m->ticks++;
-	checkalarms();
-}
-
-#define STEPPING(x)	((x)&0xf)
-#define X86MODEL(x)	(((x)>>4)&0xf)
-#define X86FAMILY(x)	(((x)>>8)&0xf)
-
-enum
-{
-	/* flags */
-	CpuidFPU	= 0x001,	/* on-chip floating point unit */
-	CpuidMCE	= 0x080,	/* machine check exception */
-	CpuidCX8	= 0x100,	/* CMPXCHG8B instruction */
-};
-
-typedef struct
-{
-	int family;
-	int model;
-	int aalcycles;
-	char *name;
-} X86type;
-
-X86type x86intel[] =
-{
-	{ 4,	0,	22,	"486DX", },	/* known chips */
-	{ 4,	1,	22,	"486DX50", },
-	{ 4,	2,	22,	"486SX", },
-	{ 4,	3,	22,	"486DX2", },
-	{ 4,	4,	22,	"486SL", },
-	{ 4,	5,	22,	"486SX2", },
-	{ 4,	7,	22,	"DX2WB", },	/* P24D */
-	{ 4,	8,	22,	"DX4", },	/* P24C */
-	{ 4,	9,	22,	"DX4WB", },	/* P24CT */
-	{ 5,	0,	23,	"P5", },
-	{ 5,	1,	23,	"P5", },
-	{ 5,	2,	23,	"P54C", },
-	{ 5,	3,	23,	"P24T", },
-	{ 5,	4,	23,	"P55C MMX", },
-	{ 5,	7,	23,	"P54C VRT", },
-	{ 6,	1,	16,	"PentiumPro", },/* trial and error */
-	{ 6,	3,	16,	"PentiumII", },
-	{ 6,	5,	16,	"PentiumII/Xeon", },
-	{ 6,	6,	16,	"Celeron", },
-	{ 6,	7,	16,	"PentiumIII/Xeon", },
-	{ 6,	8,	16,	"PentiumIII/Xeon", },
-	{ 6,	0xB,	16,	"PentiumIII/Xeon", },
-	{ 0xF,	1,	16,	"P4", },	/* P4 */
-	{ 0xF,	2,	16,	"PentiumIV/Xeon", },
-
-	{ 3,	-1,	32,	"386", },	/* family defaults */
-	{ 4,	-1,	22,	"486", },
-	{ 5,	-1,	23,	"P5", },
-	{ 6,	-1,	16,	"P6", },
-	{ 0xF,	-1,	16,	"P4", },	/* P4 */
-
-	{ -1,	-1,	16,	"unknown", },	/* total default */
-};
-
-
-/*
- * The AMD processors all implement the CPUID instruction.
- * The later ones also return the processor name via functions
- * 0x80000002, 0x80000003 and 0x80000004 in registers AX, BX, CX
- * and DX:
- *	K5	"AMD-K5(tm) Processor"
- *	K6	"AMD-K6tm w/ multimedia extensions"
- *	K6 3D	"AMD-K6(tm) 3D processor"
- *	K6 3D+	?
- */
-static X86type x86amd[] =
-{
-	{ 5,	0,	23,	"AMD-K5", },	/* guesswork */
-	{ 5,	1,	23,	"AMD-K5", },	/* guesswork */
-	{ 5,	2,	23,	"AMD-K5", },	/* guesswork */
-	{ 5,	3,	23,	"AMD-K5", },	/* guesswork */
-	{ 5,	4,	23,	"AMD Geode GX1", },	/* guesswork */
-	{ 5,	5,	23,	"AMD Geode GX2", },	/* guesswork */
-	{ 5,	6,	11,	"AMD-K6", },	/* trial and error */
-	{ 5,	7,	11,	"AMD-K6", },	/* trial and error */
-	{ 5,	8,	11,	"AMD-K6-2", },	/* trial and error */
-	{ 5,	9,	11,	"AMD-K6-III", },/* trial and error */
-	{ 5,	0xa,	23,	"AMD Geode LX", },	/* guesswork */
-
-	{ 6,	1,	11,	"AMD-Athlon", },/* trial and error */
-	{ 6,	2,	11,	"AMD-Athlon", },/* trial and error */
-
-	{ 4,	-1,	22,	"Am486", },	/* guesswork */
-	{ 5,	-1,	23,	"AMD-K5/K6", },	/* guesswork */
-	{ 6,	-1,	11,	"AMD-Athlon", },/* guesswork */
-	{ 0xF,	-1,	11,	"AMD64", },	/* guesswork */
-
-	{ -1,	-1,	11,	"unknown", },	/* total default */
-};
-
-static X86type	*cputype;
-
-
-void
-delay(int millisecs)
-{
-	millisecs *= loopconst;
-	if(millisecs <= 0)
-		millisecs = 1;
-	aamloop(millisecs);
-}
-
-void
-microdelay(int microsecs)
-{
-	microsecs *= loopconst;
-	microsecs /= 1000;
-	if(microsecs <= 0)
-		microsecs = 1;
-	aamloop(microsecs);
-}
-
-extern void cpuid(char*, int*, int*);
-
-X86type*
-cpuidentify(void)
-{
-	int family, model;
-	X86type *t;
-	char cpuidid[16];
-	int cpuidax, cpuiddx;
-
-	cpuid(cpuidid, &cpuidax, &cpuiddx);
-	if(strncmp(cpuidid, "AuthenticAMD", 12) == 0 ||
-	   strncmp(cpuidid, "Geode by NSC", 12) == 0)
-		t = x86amd;
-	else
-		t = x86intel;
-	family = X86FAMILY(cpuidax);
-	model = X86MODEL(cpuidax);
-	if (0)
-		print("cpuidentify: cpuidax 0x%ux cpuiddx 0x%ux\n",
-			cpuidax, cpuiddx);
-	while(t->name){
-		if((t->family == family && t->model == model)
-		|| (t->family == family && t->model == -1)
-		|| (t->family == -1))
-			break;
-		t++;
-	}
-	if(t->name == nil)
-		panic("cpuidentify");
-
-	if(cpuiddx & 0x10){
-		havetsc = 1;
-		if(cpuiddx & 0x20)
-			wrmsr(0x10, 0);
-	}
-
-	return t;
-}
-
-void
-clockinit(void)
-{
-	uvlong a, b, cpufreq;
-	int loops, incr, x, y;
-	X86type *t;
-
-	/*
-	 *  set vector for clock interrupts
-	 */
-	setvec(VectorCLOCK, clockintr, 0);
-
-	t = cpuidentify();
-
-	/*
-	 *  set clock for 1/HZ seconds
-	 */
-	outb(Tmode, Load0|Square);
-	outb(T0cntr, (Freq/HZ));	/* low byte */
-	outb(T0cntr, (Freq/HZ)>>8);	/* high byte */
-
-	/*
-	 * Introduce a little delay to make sure the count is
-	 * latched and the timer is counting down; with a fast
-	 * enough processor this may not be the case.
-	 * The i8254 (which this probably is) has a read-back
-	 * command which can be used to make sure the counting
-	 * register has been written into the counting element.
-	 */
-	x = (Freq/HZ);
-	for(loops = 0; loops < 100000 && x >= (Freq/HZ); loops++){
-		outb(Tmode, Latch0);
-		x = inb(T0cntr);
-		x |= inb(T0cntr)<<8;
-	}
-
-	/* find biggest loop that doesn't wrap */
-	incr = 16000000/(t->aalcycles*HZ*2);
-	x = 2000;
-	for(loops = incr; loops < 64*1024; loops += incr) {
-	
-		/*
-		 *  measure time for the loop
-		 *
-		 *			MOVL	loops,CX
-		 *	aaml1:	 	AAM
-		 *			LOOP	aaml1
-		 *
-		 *  the time for the loop should be independent of external
-		 *  cache and memory system since it fits in the execution
-		 *  prefetch buffer.
-		 *
-		 */
-		outb(Tmode, Latch0);
-		if(havetsc)
-			_cycles(&a);
-		x = inb(T0cntr);
-		x |= inb(T0cntr)<<8;
-		aamloop(loops);
-		outb(Tmode, Latch0);
-		if(havetsc)
-			_cycles(&b);
-		y = inb(T0cntr);
-		y |= inb(T0cntr)<<8;
-		x -= y;
-	
-		if(x < 0)
-			x += Freq/HZ;
-
-		if(x > Freq/(3*HZ))
-			break;
-	}
-
-	/*
- 	 *  figure out clock frequency and a loop multiplier for delay().
-	 *  counter  goes at twice the frequency, once per transition,
-	 *  i.e., twice per square wave
-	 */
-	cpufreq = (vlong)loops*((t->aalcycles*2*Freq)/x);
-	loopconst = (cpufreq/1000)/t->aalcycles;	/* AAM+LOOP's for 1 ms */
-
-	if(havetsc){
-		/* counter goes up by 2*Freq */
-		b = (b-a)<<1;
-		b *= Freq;
-		b /= x;
-
-		/*
-		 *  round to the nearest megahz
-		 */
-		cpumhz = (b+500000)/1000000L;
-		cpuhz = b;
-	}
-	else{
-		/*
-		 *  add in possible .5% error and convert to MHz
-		 */
-		cpumhz = (cpufreq + cpufreq/200)/1000000;
-		cpuhz = cpufreq;
-	}
-
-	if(debug){
-		int timeo;
-
-		print("%dMHz %s loop %d\n", cpumhz, t->name, loopconst);
-		print("tick...");
-		for(timeo = 0; timeo < 10; timeo++)
-			delay(1000);
-		print("tock...\n");
-	}
-}
--- a/os/boot/pc/conf.c
+++ /dev/null
@@ -1,537 +1,0 @@
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-
-#include "fs.h"
-
-/*
- * Where configuration info is left for the loaded programme.
- * This will turn into a structure as more is done by the boot loader
- * (e.g. why parse the .ini file twice?).
- * There are 3584 bytes available at CONFADDR.
- *
- * The low-level boot routines in l.s leave data for us at CONFADDR,
- * which we pick up before reading the plan9.ini file.
- */
-#define BOOTLINELEN	64
-#define BOOTARGS	((char*)(CONFADDR+BOOTLINELEN))
-#define	BOOTARGSLEN	(3584-0x200-BOOTLINELEN)
-#define	MAXCONF		100
-
-static char *confname[MAXCONF];
-static char *confval[MAXCONF];
-static int nconf;
-
-extern char **ini;
-
-typedef struct {
-	char*	name;
-	int	start;
-	int	end;
-} Mblock;
-
-typedef struct {
-	char*	tag;
-	Mblock*	mb;
-} Mitem;
-
-static Mblock mblock[MAXCONF];
-static int nmblock;
-static Mitem mitem[MAXCONF];
-static int nmitem;
-static char* mdefault;
-static char mdefaultbuf[10];
-static int mtimeout;
-
-static char*
-comma(char* line, char** residue)
-{
-	char *q, *r;
-
-	if((q = strchr(line, ',')) != nil){
-		*q++ = 0;
-		if(*q == ' ')
-			q++;
-	}
-	*residue = q;
-
-	if((r = strchr(line, ' ')) != nil)
-		*r = 0;
-
-	if(*line == ' ')
-		line++;
-	return line;
-}
-
-static Mblock*
-findblock(char* name, char** residue)
-{
-	int i;
-	char *p;
-
-	p = comma(name, residue);
-	for(i = 0; i < nmblock; i++){
-		if(strcmp(p, mblock[i].name) == 0)
-			return &mblock[i];
-	}
-	return nil;
-}
-
-static Mitem*
-finditem(char* name, char** residue)
-{
-	int i;
-	char *p;
-
-	p = comma(name, residue);
-	for(i = 0; i < nmitem; i++){
-		if(strcmp(p, mitem[i].mb->name) == 0)
-			return &mitem[i];
-	}
-	return nil;
-}
-
-static void
-parsemenu(char* str, char* scratch, int len)
-{
-	Mitem *mi;
-	Mblock *mb, *menu;
-	char buf[20], *p, *q, *line[MAXCONF];
-	int i, inblock, n, show;
-
-	inblock = 0;
-	menu = nil;
-	memmove(scratch, str, len);
-	n = getfields(scratch, line, MAXCONF, '\n');
-	if(n >= MAXCONF)
-		print("warning: possibly too many lines in plan9.ini\n");
-	for(i = 0; i < n; i++){
-		p = line[i];
-		if(inblock && *p == '['){
-			mblock[nmblock].end = i;
-			if(strcmp(mblock[nmblock].name, "menu") == 0)
-				menu = &mblock[nmblock];
-			nmblock++;
-			inblock = 0;
-		}
-		if(*p == '['){
-			if(nmblock == 0 && i != 0){
-				mblock[nmblock].name = "common";
-				mblock[nmblock].start = 0;
-				mblock[nmblock].end = i;
-				nmblock++;
-			}
-			q = strchr(p+1, ']');
-			if(q == nil || *(q+1) != 0){
-				print("malformed menu block header - %s\n", p);
-				return;
-			}
-			*q = 0;
-			mblock[nmblock].name = p+1;
-			mblock[nmblock].start = i+1;
-			inblock = 1;
-		}
-	}
-
-	if(inblock){
-		mblock[nmblock].end = i;
-		nmblock++;
-	}
-	if(menu == nil)
-		return;
-	if(nmblock < 2){
-		print("incomplete menu specification\n");
-		return;
-	}
-
-	for(i = menu->start; i < menu->end; i++){
-		p = line[i];
-		if(cistrncmp(p, "menuitem=", 9) == 0){
-			p += 9;
-			if((mb = findblock(p, &q)) == nil){
-				print("no block for menuitem %s\n", p);
-				return;
-			}
-			if(q != nil)
-				mitem[nmitem].tag = q;
-			else
-				mitem[nmitem].tag = mb->name;
-			mitem[nmitem].mb = mb;
-			nmitem++;
-		}
-		else if(cistrncmp(p, "menudefault=", 12) == 0){
-			p += 12;
-			if((mi = finditem(p, &q)) == nil){
-				print("no item for menudefault %s\n", p);
-				return;
-			}
-			if(q != nil)
-				mtimeout = strtol(q, 0, 0);
-			sprint(mdefaultbuf, "%ld", mi-mitem+1);
-			mdefault = mdefaultbuf;
-		}
-		else if(cistrncmp(p, "menuconsole=", 12) == 0){
-			p += 12;
-			p = comma(p, &q);
-			consinit(p, q);
-		}
-		else{
-			print("invalid line in [menu] block - %s\n", p);
-			return;
-		}
-	}
-
-again:
-	print("\nPlan 9 Startup Menu:\n====================\n");
-	for(i = 0; i < nmitem; i++)
-		print("    %d. %s\n", i+1, mitem[i].tag);
-	for(;;){
-		getstr("Selection", buf, sizeof(buf), mdefault, mtimeout);
-		mtimeout = 0;
-		i = strtol(buf, &p, 0)-1;
-		if(i < 0 || i >= nmitem)
-			goto again;
-		switch(*p){
-		case 'p':
-		case 'P':
-			show = 1;
-			print("\n");
-			break;
-		case 0:
-			show = 0;
-			break;
-		default:
-			continue;
-			
-		}
-		mi = &mitem[i];
-	
-		p = str;
-		p += sprint(p, "menuitem=%s\n", mi->mb->name);
-		for(i = 0; i < nmblock; i++){
-			mb = &mblock[i];
-			if(mi->mb != mb && cistrcmp(mb->name, "common") != 0)
-				continue;
-			for(n = mb->start; n < mb->end; n++)
-				p += sprint(p, "%s\n", line[n]);
-		}
-
-		if(show){
-			for(q = str; q < p; q += i){
-				if((i = print(q)) <= 0)
-					break;
-			}
-			goto again;
-		}
-		break;
-	}
-	print("\n");
-}
-
-/*
-static void
-msleep(int msec)
-{
-	ulong start;
-
-	for(start = m->ticks; TK2MS(m->ticks - start) < msec; )
-		;
-}
-*/
-
-void
-readlsconf(void)
-{
-	uchar *p;
-
-	p = (uchar*)CONFADDR;
-	for(;;) {
-		if(strcmp((char*)p, "APM") == 0){
-			apm.haveinfo = 1;
-			apm.ax = *(ushort*)(p+4);
-			apm.cx = *(ushort*)(p+6);
-			apm.dx = *(ushort*)(p+8);
-			apm.di = *(ushort*)(p+10);
-			apm.ebx = *(ulong*)(p+12);
-			apm.esi = *(ulong*)(p+16);
-			print("apm ax=%x cx=%x dx=%x di=%x ebx=%x esi=%x\n",
-				apm.ax, apm.cx, apm.dx, apm.di, apm.ebx, apm.esi);
-			p += 20;
-			continue;
-		}
-		break;
-	}
-}
-
-char*
-getconf(char *name)
-{
-	int i, n, nmatch;
-	char buf[20];
-
-	nmatch = 0;
-	for(i = 0; i < nconf; i++)
-		if(cistrcmp(confname[i], name) == 0)
-			nmatch++;
-
-	switch(nmatch) {
-	default:
-		print("\n");
-		nmatch = 0;
-		for(i = 0; i < nconf; i++)
-			if(cistrcmp(confname[i], name) == 0)
-				print("%d. %s\n", ++nmatch, confval[i]);
-		print("%d. none of the above\n", ++nmatch);
-		do {
-			getstr(name, buf, sizeof(buf), nil, 0);
-			n = atoi(buf);
-		} while(n < 1 || n > nmatch);
-
-		for(i = 0; i < nconf; i++)
-			if(cistrcmp(confname[i], name) == 0)
-				if(--n == 0)
-					return confval[i];
-		break;
-
-	case 1:
-		for(i = 0; i < nconf; i++)
-			if(cistrcmp(confname[i], name) == 0)
-				return confval[i];
-		break;
-
-	case 0:
-		break;
-	}
-	return nil;
-}
-
-void
-addconf(char *fmt, ...)
-{
-	va_list arg;
-
-	va_start(arg, fmt);
-	vseprint(BOOTARGS+strlen(BOOTARGS), BOOTARGS+BOOTARGSLEN, fmt, arg);
-	va_end(arg);
-}
-
-void
-changeconf(char *fmt, ...)
-{
-	va_list arg;
-	char *p, *q, pref[20], buf[128];
-
-	va_start(arg, fmt);
-	vseprint(buf, buf+sizeof buf, fmt, arg);
-	va_end(arg);
-	strncpy(pref+1, buf, 19);
-	pref[19] = '\0';
-	if(p = strchr(pref, '='))
-		*(p+1) = '\0';
-	else
-		print("warning: did not change %s in plan9.ini\n", buf);
-
-	/* find old line by looking for \nwhat= */
-	pref[0] = '\n';
-	if(strncmp(BOOTARGS, pref+1, strlen(pref+1)) == 0)
-		p = BOOTARGS;
-	else if(p = strstr(BOOTARGS, pref))
-		p++;
-	else
-		p = nil;
-
-	/* move rest of args up, deleting what= line. */
-	if(p != nil && (q = strchr(p, '\n')) != nil)
-		memmove(p, q+1, strlen(q+1)+1);
-
-	/* add replacement to end */
-	addconf("%s", buf);
-}
-
-/*
- *  read configuration file
- */
-static char inibuf[BOOTARGSLEN];
-static char id[8] = "ZORT 0\r\n";
-
-int
-dotini(Fs *fs)
-{
-	File rc;
-	int blankline, i, incomment, inspace, n;
-	char *cp, *p, *q, *line[MAXCONF];
-
-	if(fswalk(fs, *ini, &rc) <= 0)
-		return -1;
-
-	cp = inibuf;
-	*cp = 0;
-	n = fsread(&rc, cp, BOOTARGSLEN-1);
-	if(n <= 0)
-		return -1;
-
-	cp[n] = 0;
-
-	/*
-	 * Strip out '\r', change '\t' -> ' '.
-	 * Change runs of spaces into single spaces.
-	 * Strip out trailing spaces, blank lines.
-	 *
-	 * We do this before we make the copy so that if we 
-	 * need to change the copy, it is already fairly clean.
-	 * The main need is in the case when plan9.ini has been
-	 * padded with lots of trailing spaces, as is the case 
-	 * for those created during a distribution install.
-	 */
-	p = cp;
-	blankline = 1;
-	incomment = inspace = 0;
-	for(q = cp; *q; q++){
-		if(*q == '\r')
-			continue;
-		if(*q == '\t')
-			*q = ' ';
-		if(*q == ' '){
-			inspace = 1;
-			continue;
-		}
-		if(*q == '\n'){
-			if(!blankline){
-				if(!incomment)
-					*p++ = '\n';
-				blankline = 1;
-			}
-			incomment = inspace = 0;
-			continue;
-		}
-		if(inspace){
-			if(!blankline && !incomment)
-				*p++ = ' ';
-			inspace = 0;
-		}
-		if(blankline && *q == '#')
-			incomment = 1;
-		blankline = 0;
-		if(!incomment)
-			*p++ = *q;	
-	}
-	if(p > cp && p[-1] != '\n')
-		*p++ = '\n';
-	*p++ = 0;
-	n = p-cp;
-
-	parsemenu(cp, BOOTARGS, n);
-
-	/*
-	 * Keep a copy.
-	 * We could change this to pass the parsed strings
-	 * to the booted programme instead of the raw
-	 * string, then it only gets done once.
-	 */
-	if(strncmp(cp, id, sizeof(id))){
-		memmove(BOOTARGS, id, sizeof(id));
-		if(n+1+sizeof(id) >= BOOTARGSLEN)
-			n -= sizeof(id);
-		memmove(BOOTARGS+sizeof(id), cp, n+1);
-	}
-	else
-		memmove(BOOTARGS, cp, n+1);
-
-	n = getfields(cp, line, MAXCONF, '\n');
-	for(i = 0; i < n; i++){
-		cp = strchr(line[i], '=');
-		if(cp == 0)
-			continue;
-		*cp++ = 0;
-		if(cp - line[i] >= NAMELEN+1)
-			*(line[i]+NAMELEN-1) = 0;
-		confname[nconf] = line[i];
-		confval[nconf] = cp;
-		nconf++;
-	}
-	return 0;
-}
-
-static int
-parseether(uchar *to, char *from)
-{
-	char nip[4];
-	char *p;
-	int i;
-
-	p = from;
-	while(*p == ' ')
-		++p;
-	for(i = 0; i < 6; i++){
-		if(*p == 0)
-			return -1;
-		nip[0] = *p++;
-		if(*p == 0)
-			return -1;
-		nip[1] = *p++;
-		nip[2] = 0;
-		to[i] = strtoul(nip, 0, 16);
-		if(*p == ':')
-			p++;
-	}
-	return 0;
-}
-
-int
-isaconfig(char *class, int ctlrno, ISAConf *isa)
-{
-	char cc[NAMELEN], *p, *q, *r;
-	int n;
-
-	sprint(cc, "%s%d", class, ctlrno);
-	for(n = 0; n < nconf; n++){
-		if(cistrncmp(confname[n], cc, NAMELEN))
-			continue;
-		isa->nopt = 0;
-		p = confval[n];
-		while(*p){
-			while(*p == ' ' || *p == '\t')
-				p++;
-			if(*p == '\0')
-				break;
-			if(cistrncmp(p, "type=", 5) == 0){
-				p += 5;
-				for(q = isa->type; q < &isa->type[NAMELEN-1]; q++){
-					if(*p == '\0' || *p == ' ' || *p == '\t')
-						break;
-					*q = *p++;
-				}
-				*q = '\0';
-			}
-			else if(cistrncmp(p, "port=", 5) == 0)
-				isa->port = strtoul(p+5, &p, 0);
-			else if(cistrncmp(p, "irq=", 4) == 0)
-				isa->irq = strtoul(p+4, &p, 0);
-			else if(cistrncmp(p, "mem=", 4) == 0)
-				isa->mem = strtoul(p+4, &p, 0);
-			else if(cistrncmp(p, "size=", 5) == 0)
-				isa->size = strtoul(p+5, &p, 0);
-			else if(cistrncmp(p, "ea=", 3) == 0){
-				if(parseether(isa->ea, p+3) == -1)
-					memset(isa->ea, 0, 6);
-			}
-			else if(isa->nopt < NISAOPT){
-				r = isa->opt[isa->nopt];
-				while(*p && *p != ' ' && *p != '\t'){
-					*r++ = *p++;
-					if(r-isa->opt[isa->nopt] >= ISAOPTLEN-1)
-						break;
-				}
-				*r = '\0';
-				isa->nopt++;
-			}
-			while(*p && *p != ' ' && *p != '\t')
-				p++;
-		}
-		return 1;
-	}
-	return 0;
-}
--- a/os/boot/pc/console.c
+++ /dev/null
@@ -1,236 +1,0 @@
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-
-IOQ consiq;
-IOQ consoq;
-
-static int useuart;
-
-int	debug = 0;
-
-void
-kbdchar(int c)
-{
-	c &= 0x7F;
-	if(c == 0x10)
-		warp86("\n^P\n", 0);
-	if(c == 0x12)
-		debug = !debug;
-	consiq.putc(&consiq, c);
-}
-
-static int
-consputc(void)
-{
-	return consoq.getc(&consoq);
-}
-
-void
-kbdinit(void)
-{
-	i8042init();
-	qinit(&consiq);
-}
-
-void
-consinit(char* name, char* speed)
-{
-	int baud, port;
-
-	if(name == nil || cistrcmp(name, "cga") == 0)
-		return;
-	port = strtoul(name, 0, 0);
-	if(port < 0 || port > 1)
-		return;
-	if(speed == nil || (baud = strtoul(speed, 0, 0)) == 0)
-		baud = 9600;
-
-	qinit(&consoq);
-
-	uartspecial(port, kbdchar, consputc, baud);
-	useuart = 1;
-	uartputs(&consoq, "\n", 1);
-}
-
-void
-consdrain(void)
-{
-	if(useuart)
-		uartdrain();
-}
-
-void
-consputs(char* s, int n)
-{
-	cgascreenputs(s, n);
-	if(useuart)
-		uartputs(&consoq, s, n);
-}
-
-void
-warp86(char* s, ulong)
-{
-	if(s != nil)
-		print(s);
-	spllo();
-	consdrain();
-
-	i8042reset();
-	print("Takes a licking and keeps on ticking...\n");
-	for(;;)
-		idle();
-}
-
-static int
-getline(char *buf, int size, int timeout)
-{
-	int c, i=0;
-	ulong start;
-	char echo;
-
-	for (;;) {
-		start = m->ticks;
-		do{
-			/* timeout seconds to first char */
-			if(timeout && ((m->ticks - start) > timeout*HZ))
-				return -2;
-			c = consiq.getc(&consiq);
-		}while(c == -1);
-		timeout = 0;
-
-		if(c == '\r')
-			c = '\n'; 		/* turn carriage return into newline */
-		if(c == '\177')
-			c = '\010';		/* turn delete into backspace */
-		if(c == '\025')
-			echo = '\n';		/* echo ^U as a newline */
-		else
-			echo = c;
-		consputs(&echo, 1);
-
-		if(c == '\010'){
-			if(i > 0)
-				i--; /* bs deletes last character */
-			continue;
-		}
-		/* a newline ends a line */
-		if (c == '\n')
-			break;
-		/* ^U wipes out the line */
-		if (c =='\025')
-			return -1;
-		if(i == size)
-			return size;
-		buf[i++] = c;
-	}
-	buf[i] = 0;
-	return i;
-}
-
-int
-getstr(char *prompt, char *buf, int size, char *def, int timeout)
-{
-	int len, isdefault;
-	char pbuf[PRINTSIZE];
-
-	buf[0] = 0;
-	isdefault = (def && *def);
-	if(isdefault == 0){
-		timeout = 0;
-		sprint(pbuf, "%s: ", prompt);
-	}
-	else if(timeout)
-		sprint(pbuf, "%s[default==%s (%ds timeout)]: ", prompt, def, timeout);
-	else
-		sprint(pbuf, "%s[default==%s]: ", prompt, def);
-	for (;;) {
-		print(pbuf);
-		len = getline(buf, size, timeout);
-		switch(len){
-		case 0:
-			/* RETURN */
-			if(isdefault)
-				break;
-			continue;
-		case -1:
-			/* ^U typed */
-			continue;
-		case -2:
-			/* timeout, use default */
-			consputs("\n", 1);
-			len = 0;
-			break;
-		default:
-			break;
-		}
-		if(len >= size){
-			print("line too long\n");
-			continue;
-		}
-		break;
-	}
-	if(len == 0 && isdefault)
-		strcpy(buf, def);
-	return 0;
-}
-
-int
-print(char *fmt, ...)
-{
-	int n;
-	va_list arg;
-	char buf[PRINTSIZE];
-
-	va_start(arg, fmt);
-	n = vseprint(buf, buf+sizeof(buf), fmt, arg) - buf;
-	va_end(arg);
-	consputs(buf, n);
-
-	return n;
-}
-
-int
-sprint(char *s, char *fmt, ...)
-{
-	int n;
-	va_list arg;
-
-	va_start(arg, fmt);
-	n = vseprint(s, s+PRINTSIZE, fmt, arg) - s;
-	va_end(arg);
-
-	return n;
-}
-
-void
-panic(char *fmt, ...)
-{
-	int n;
-	va_list arg;
-	char buf[PRINTSIZE];
-
-	strcpy(buf, "panic: ");
-	va_start(arg, fmt);
-	n = vseprint(buf+7, buf+sizeof(buf), fmt, arg) - buf;
-	va_end(arg);
-	buf[n] = '\n';
-	consputs(buf, n+1);
-
-//floppymemwrite();
-//splhi(); for(;;);
-	if(etherdetach)
-		etherdetach();
-	if(sddetach)
-		sddetach();
-
-	consputs("\nPress almost any key to reset...", 32);
-	spllo();
-	while(consiq.getc(&consiq) == -1)
-		;
-
-	warp86(nil, 0);
-}
--- a/os/boot/pc/dat.h
+++ /dev/null
@@ -1,215 +1,0 @@
-typedef struct List {
-	void	*next;
-} List;
-
-typedef struct Alarm Alarm;
-typedef struct Alarm {
-	List;
-	int	busy;
-	long	dt;
-	void	(*f)(Alarm*);
-	void	*arg;
-} Alarm;
-
-typedef struct Apminfo {
-	int haveinfo;
-	int ax;
-	int cx;
-	int dx;
-	int di;
-	int ebx;
-	int esi;
-} Apminfo;
-
-typedef struct Block Block;
-struct Block {
-	Block*	next;
-	uchar*	rp;			/* first unconsumed byte */
-	uchar*	wp;			/* first empty byte */
-	uchar*	lim;			/* 1 past the end of the buffer */
-	uchar*	base;			/* start of the buffer */
-	ulong	flag;
-};
-#define BLEN(s)	((s)->wp - (s)->rp)
-
-typedef struct IOQ IOQ;
-typedef struct IOQ {
-	uchar	buf[4096];
-	uchar	*in;
-	uchar	*out;
-	int	state;
-	int	(*getc)(IOQ*);
-	int	(*putc)(IOQ*, int);
-	void	*ptr;
-};
-
-enum {
-	Eaddrlen	= 6,
-	/* next two exclude 4-byte ether CRC */
-	ETHERMINTU	= 60,		/* minimum transmit size */
-	ETHERMAXTU	= 1514,		/* maximum transmit size */
-	ETHERHDRSIZE	= 14,		/* size of an ethernet header */
-
-	MaxEther	= 6,
-};
-
-typedef struct {
-	uchar	d[Eaddrlen];
-	uchar	s[Eaddrlen];
-	uchar	type[2];
-	uchar	data[1500];
-	uchar	crc[4];
-} Etherpkt;
-
-extern uchar broadcast[Eaddrlen];
-
-typedef struct Ureg Ureg;
-#pragma incomplete Ureg
-
-typedef struct Segdesc {
-	ulong	d0;
-	ulong	d1;
-} Segdesc;
-
-typedef struct Mach {
-	ulong	ticks;			/* of the clock since boot time */
-	void	*alarm;			/* alarms bound to this clock */
-} Mach;
-
-extern Mach *m;
-
-#define I_MAGIC		((((4*11)+0)*11)+7)
-
-typedef struct Exec Exec;
-struct	Exec
-{
-	uchar	magic[4];		/* magic number */
-	uchar	text[4];	 	/* size of text segment */
-	uchar	data[4];	 	/* size of initialized data */
-	uchar	bss[4];	  		/* size of uninitialized data */
-	uchar	syms[4];	 	/* size of symbol table */
-	uchar	entry[4];	 	/* entry point */
-	uchar	spsz[4];		/* size of sp/pc offset table */
-	uchar	pcsz[4];		/* size of pc/line number table */
-};
-
-/*
- *  a parsed .ini line
- */
-#define ISAOPTLEN	32
-#define NISAOPT		8
-
-typedef struct  ISAConf {
-	char	type[NAMELEN];
-	ulong	port;
-	ulong	irq;
-	ulong	mem;
-	ulong	size;
-	uchar	ea[6];
-
-	int	nopt;
-	char	opt[NISAOPT][ISAOPTLEN];
-} ISAConf;
-
-typedef struct Pcidev Pcidev;
-typedef struct PCMmap PCMmap;
-typedef struct PCMslot PCMslot;
-
-#define BOOTLINE	((char*)CONFADDR)
-
-enum {
-	MB =		(1024*1024),
-};
-#define ROUND(s, sz)	(((s)+((sz)-1))&~((sz)-1))
-
-
-typedef struct Type Type;
-typedef struct Medium Medium;
-typedef struct Boot Boot;
-
-enum {					/* type */
-	Tnil		= 0x00,
-
-	Tfloppy		= 0x01,
-	Tsd		= 0x02,
-	Tether		= 0x03,
-	Tcd		= 0x04,
-	Tbios		= 0x05,
-
-	Tany		= -1,
-};
-
-enum {					/* name and flag */
-	Fnone		= 0x00,
-
-	Nfs		= 0x00,
-	Ffs		= (1<<Nfs),
-	Nboot		= 0x01,
-	Fboot		= (1<<Nboot),
-	Nbootp		= 0x02,
-	Fbootp		= (1<<Nbootp),
-	NName		= 3,
-
-	Fany		= Fbootp|Fboot|Ffs,
-
-	Fini		= 0x10,
-	Fprobe		= 0x80,
-};
-
-typedef struct Type {
-	int	type;
-	int	flag;
-	int	(*init)(void);
-	void	(*initdev)(int, char*);
-	void*	(*getfspart)(int, char*, int);	/* actually returns Dos* */
-	void	(*addconf)(int);
-	int	(*boot)(int, char*, Boot*);
-	void	(*printdevs)(int);
-	char**	parts;
-	char**	inis;
-	int	mask;
-	Medium*	media;
-} Type;
-
-extern void (*etherdetach)(void);
-extern void (*floppydetach)(void);
-extern void (*sddetach)(void);
-
-typedef struct Lock {	/* for ilock, iunlock */
-	int locked;
-	int spl;
-} Lock;
-
-enum {	/* returned by bootpass */
-	MORE, ENOUGH, FAIL
-};
-enum {
-	INITKERNEL,
-	READEXEC,
-	READ9TEXT,
-	READ9DATA,
-	READGZIP,
-	READEHDR,
-	READPHDR,
-	READEPAD,
-	READEDATA,
-	TRYBOOT,
-	INIT9LOAD,
-	READ9LOAD,
-	FAILED
-};
-
-struct Boot {
-	int state;
-
-	Exec exec;
-	char *bp;	/* base ptr */
-	char *wp;	/* write ptr */
-	char *ep;	/* end ptr */
-};
-
-extern int	debug;
-extern Apminfo	apm;
-extern char	*defaultpartition;
-extern int	iniread;
-extern int	pxe;
--- a/os/boot/pc/devbios.c
+++ /dev/null
@@ -1,428 +1,0 @@
-/*
- * boot driver for BIOS devices
- */
-#include <u.h>
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "ureg.h"
-#include "fs.h"
-
-typedef uvlong Devbytes, Devsects;
-
-typedef struct Biosdrive Biosdrive;	/* 1 drive -> ndevs */
-typedef struct Biosdev Biosdev;
-
-enum {
-	Debug = 0,
-	Maxdevs = 4,
-
-	CF = 1,
-	Flopid = 0,			/* first floppy */
-	Baseid = 0x80,			/* first disk */
-
-	/* bios calls: int 13 disk services */
-	Biosinit	= 0,		/* initialise disk & floppy ctlrs */
-	Biosdrvsts,
-	Bioschsrdsects,
-	Biosdrvparam	= 8,
-	Biosctlrinit,
-	Biosreset	=  0xd,		/* reset disk */
-	Biosdrvrdy	= 0x10,
-	Biosdrvtype	= 0x15,
-	Biosckext	= 0x41,
-	Biosrdsect,
-	Biosedrvparam	= 0x48,
-
-	/* disk types */
-	Typenone = 0,
-	Typedisk = 3,
-};
-
-struct Biosdrive {
-	int	ndevs;
-};
-struct Biosdev {
-	Devbytes size;
-	Devbytes offset;
-	uchar	id;			/* drive number; e.g., 0x80 */
-	char	type;
-	ushort	sectsz;
-};
-
-typedef struct Extread {
-	uchar	size;
-	uchar	unused1;
-	uchar	nsects;
-	uchar	unused2;
-	ulong	addr;		/* segment:offset */
-	uvlong	stsect;		/* starting sector */
-} Extread;
-typedef struct Edrvparam {
-	/* from edd 1.1 spec */
-	ushort	size;			/* max. buffer size */
-	ushort	flags;
-	ulong	physcyls;
-	ulong	physheads;
-	ulong	phystracksects;
-	uvlong	physsects;
-	ushort	sectsz;
-	void	*dpte;			/* ~0ull: invalid */
-
-	/* remainder from edd 3.0 spec */
-	ushort	key;			/* 0xbedd if present */
-	uchar	dpilen;
-	uchar	unused1;
-	ushort	unused2;
-	char	bustype[4];		/* "PCI" or "ISA" */
-	char	ifctype[8]; /* "ATA", "ATAPI", "SCSI", "USB", "1394", "FIBRE" */
-	uvlong	ifcpath;
-	uvlong	devpath;
-	uchar	unused3;
-	uchar	dpicksum;
-} Edrvparam;
-
-void	realmode(int intr, Ureg *ureg);		/* from trap.c */
-
-int onlybios0;
-int biosinited;
-
-static Biosdev bdev[Maxdevs];
-static Biosdrive bdrive;
-static Ureg regs;
-
-static int	dreset(uchar drive);
-static Devbytes	extgetsize(Biosdev *);
-static Devsects	getsize(uchar drive, char *type);
-static int	islba(uchar drive);
-
-static int
-biosdiskcall(Ureg *rp, uchar op, ulong bx, ulong dx, ulong si)
-{
-	memset(rp, 0, sizeof *rp);
-	rp->ax = op << 8;
-	rp->bx = bx;
-	rp->dx = dx;			/* often drive id */
-	rp->si = si;
-	/* pass command in *rp, get results from there */
-	realmode(0x13, rp);
-	if (rp->flags & CF) {
-//		print("biosdiskcall: int 13 op 0x%ux drive 0x%lux failed, "
-//			"ah error code 0x%ux\n", op, dx, (uchar)(rp->ax >> 8));
-		return -1;
-	}
-	return 0;
-}
-
-/*
- * Find out what the bios knows about devices.
- * our boot device could be usb; ghod only knows where it will appear.
- */
-int
-biosinit(void)
-{
-	int devid, lba, mask, lastbit;
-	Devbytes size;
-	char type;
-	Biosdev *bdp;
-	static int beenhere;
-
-	mask = lastbit = 0;
-	if (beenhere)
-		return mask;
-	beenhere = 1;
-	/* 9pxeload can't use bios int 13 calls; they wedge the machine */
-	if (pxe || getconf("*nobiosload") != nil || onlybios0 || !biosinited)
-		return mask;
-	for (devid = 0; devid < (1 << 8) && bdrive.ndevs < Maxdevs; devid++) {
-		lba = islba(devid);
-		if(!lba /* || devid != Baseid && dreset(devid) < 0 */ )
-			continue;
-		type = Typedisk;		/* HACK */
-		if (getsize(devid, &type) == 0) { /* no device, end of range */
-			devid &= ~0xf;
-			devid += 0x10;
-			devid--;
-			continue;
-		}
-		lastbit = 1 << bdrive.ndevs;
-		mask |= lastbit;
-		bdp = &bdev[bdrive.ndevs];
-		bdp->id = devid;
-		bdp->type = type;
-		size = extgetsize(bdp);
-		bdp->size = size;
-		print("bios%d: drive 0x%ux: %llud bytes, type %d\n",
-			bdrive.ndevs, devid, size, type);
-		bdrive.ndevs++;
-	}
-	/*
-	 * bioses seem to only be able to read from drive number 0x80
-	 * and certainly can't read from the highest drive number when we
-	 * call them, even if there is only one.  attempting to read from
-	 * the last drive number yields a hung machine or a two-minute pause.
-	 */
-	if (bdrive.ndevs > 0) {
-		if (bdrive.ndevs == 1) {
-			print("biosinit: sorry, only one bios drive; "
-				"can't read last one\n");
-			onlybios0 = 1;
-		} else
-			biosinited = 1;
-		bdrive.ndevs--;	/* omit last drive number; it can't be read */
-		mask &= ~lastbit;
-	}
-	return mask;
-}
-
-void
-biosinitdev(int i, char *name)
-{
-	if(i >= bdrive.ndevs)
-		panic("biosinitdev");
-	sprint(name, "bios%d", i);
-}
-
-void
-biosprintdevs(int i)
-{
-	if(i >= bdrive.ndevs){
-		print("got a print for %d, only got %d\n", i, bdrive.ndevs);
-		panic("biosprintdevs");
-	}
-	print(" bios%d", i);
-}
-
-int
-biosboot(int dev, char *file, Boot *b)
-{
-	Fs *fs;
-
-	if(strncmp(file, "dos!", 4) == 0)
-		file += 4;
-	if(strchr(file, '!') != nil || strcmp(file, "") == 0) {
-		print("syntax is bios0!file\n");
-		return -1;
-	}
-
-	fs = biosgetfspart(dev, "9fat", 1);
-	if(fs == nil)
-		return -1;
-	return fsboot(fs, file, b);
-}
-
-/* read n bytes at sector offset into a from drive id */
-long
-sectread(Biosdev *bdp, void *a, long n, Devsects offset)
-{
-	uchar *biosparam, *cp;
-	Extread *erp;
-
-	if(n < 0 || n > bdp->sectsz)
-		return -1;
-	if(Debug)
-		memset((uchar *)BIOSXCHG, 'r', bdp->sectsz); /* preclean the buffer. */
-
-	biosdiskcall(&regs, Biosdrvrdy, 0, bdp->id, 0);
-
-	/* space for a BIG sector, just in case... */
-	biosparam = (uchar *)BIOSXCHG + 2*1024;
-
-	/* read into BIOSXCHG */
-	erp = (Extread *)biosparam;
-	memset(erp, 0, sizeof *erp);
-	erp->size = sizeof *erp;
-	erp->nsects = 1;
-	erp->addr = PADDR(BIOSXCHG);
-	erp->stsect = offset;
-	if (biosdiskcall(&regs, Biosrdsect, 0, bdp->id, PADDR(erp)) < 0) {
-		print("sectread: bios failed to read %ld @ sector %lld of 0x%ux\n",
-			n, offset, bdp->id);
-		return -1;
-	}
-
-	/* copy into caller's buffer */
-	memmove(a, (char *)BIOSXCHG, n);
-	if(Debug){
-		cp = (uchar *)BIOSXCHG;
-		print("-%ux %ux %ux %ux--%16.16s-\n",
-			cp[0], cp[1], cp[2], cp[3], (char *)cp + 480);
-	}
-	return n;
-}
-
-/* not tested yet. */
-static int
-dreset(uchar drive)
-{
-if (0) {
-print("devbios: resetting disk controllers...");
-	biosdiskcall(&regs, Biosinit, 0, drive, 0);
-print("\n");
-}
-	return regs.ax? -1: 0;		/* ax!=0 on error */
-}
-
-static int
-islba(uchar drive)
-{
-	if (biosdiskcall(&regs, Biosckext, 0x55aa, drive, 0) < 0)
-		return 0;
-	if(regs.bx != 0xaa55){
-		print("islba: buggy bios\n");
-		return 0;
-	}
-	if (Debug)
-		print("islba: drive 0x%ux extensions version %d.%d cx 0x%lux\n",
-			drive, (uchar)(regs.ax >> 8),
-			(uchar)regs.ax, regs.cx); /* cx: 4=edd, 1=use dap */
-	return regs.cx & 1;		/* dap bit */
-}
-
-/*
- * works so so... some floppies are 0x80+x when they shouldn't be,
- * and report lba even if they cannot...
- */
-static Devsects
-getsize(uchar id, char *typep)
-{
-	int dtype;
-
-	if (biosdiskcall(&regs, Biosdrvtype, 0x55aa, id, 0) < 0)
-		return 0;
-
-	dtype = (ushort)regs.ax >> 8;
-	if(dtype == Typenone){
-		print("no such device 0x%ux of type %d\n", id, dtype);
-		return 0;
-	}
-	if(dtype != Typedisk){
-		print("non-disk device 0x%ux of type %d\n", id, dtype);
-		return 0;
-	}
-	*typep = dtype;
-	return (ushort)regs.cx | regs.dx << 16;
-}
-
-/* extended get size */
-static Devbytes
-extgetsize(Biosdev *bdp)
-{
-	Edrvparam *edp;
-
-	edp = (Edrvparam *)BIOSXCHG;
-	memset(edp, 0, sizeof *edp);
-	edp->size = sizeof *edp;
-	edp->dpilen = 36;
-	if (biosdiskcall(&regs, Biosedrvparam, 0, bdp->id, PADDR(edp)) < 0)
-		return 0;
-	if(Debug) {
-		print("extgetsize: drive 0x%ux info flags 0x%ux",
-			bdp->id, edp->flags);
-		if (edp->key == 0xbedd)
-			print(" %s %s", edp->bustype, edp->ifctype);
-		print("\n");
-	}
-	if (edp->sectsz <= 0) {
-		print("extgetsize: drive 0x%ux: non-positive sector size\n",
-			bdp->id);
-		edp->sectsz = 1;		/* don't divide by zero */
-	}
-	bdp->sectsz = edp->sectsz;
-	return edp->physsects * edp->sectsz;
-}
-
-long
-biosread(Fs *fs, void *a, long n)
-{
-	int want, got, part;
-	long totnr, stuck;
-	Devbytes offset;
-	Biosdev *bdp;
-
-	if(fs->dev > bdrive.ndevs)
-		return -1;
-	if (n <= 0)
-		return n;
-	bdp = &bdev[fs->dev];
-	offset = bdp->offset;
-	stuck = 0;
-	for (totnr = 0; totnr < n && stuck < 4; totnr += got) {
-		want = bdp->sectsz;
-		if (totnr + want > n)
-			want = n - totnr;
-		if(Debug)
-			print("bios%d, read: %ld @ off %lld, want: %d, id: 0x%ux\n",
-				fs->dev, n, offset, want, bdp->id);
-		part = offset % bdp->sectsz;
-		if (part != 0) {	/* back up to start of sector */
-			offset -= part;
-			totnr  -= part;
-			if (totnr < 0) {
-				print("biosread: negative count %ld\n", totnr);
-				return -1;
-			}
-		}
-		if ((vlong)offset < 0) {
-			print("biosread: negative offset %lld\n", offset);
-			return -1;
-		}
-		got = sectread(bdp, (char *)a + totnr, want, offset/bdp->sectsz);
-		if(got <= 0){
-//			print("biosread: failed to read %ld @ off %lld of 0x%ux, "
-//				"want %d got %d\n",
-//				n, offset, bdp->id, want, got);
-			return -1;
-		}
-		offset += got;
-		bdp->offset = offset;
-		if (got < bdp->sectsz)
-			stuck++;	/* we'll have to re-read this sector */
-		else
-			stuck = 0;
-	}
-	return totnr;
-}
-
-vlong
-biosseek(Fs *fs, vlong off)
-{
-	if (off < 0) {
-		print("biosseek(fs, %lld) is illegal\n", off);
-		return -1;
-	}
-	if(fs->dev > bdrive.ndevs) {
-		print("biosseek: fs->dev %d > bdrive.ndevs %d\n",
-			fs->dev, bdrive.ndevs);
-		return -1;
-	}
-	bdev[fs->dev].offset = off;	/* do not know size... (yet) */
-	return off;
-}
-
-void *
-biosgetfspart(int i, char *name, int chatty)
-{
-	static Fs fs;
-
-	if(strcmp(name, "9fat") != 0){
-		if(chatty)
-			print("unknown partition bios%d!%s (use bios%d!9fat)\n",
-				i, name, i);
-		return nil;
-	}
-
-	fs.dev = i;
-	fs.diskread = biosread;
-	fs.diskseek = biosseek;
-
-	if(dosinit(&fs) < 0){
-		if(chatty)
-			print("bios%d!%s does not contain a FAT file system\n",
-				i, name);
-		return nil;
-	}
-	return &fs;
-}
--- a/os/boot/pc/devbios.h
+++ /dev/null
@@ -1,22 +1,0 @@
-typedef uvlong Devbytes, Devsects;
-
-typedef struct Biosdrive Biosdrive;	/* 1 drive -> ndevs */
-typedef struct Biosdev Biosdev;
-
-struct Biosdrive {
-	int	ndevs;
-};
-struct Biosdev {
-	Devbytes size;
-	Devbytes offset;
-	uchar	id;
-	char	type;
-};
-
-int	biosboot(int dev, char *file, Boot *b);
-void*	biosgetfspart(int i, char *name, int chatty);
-void	biosinitdev(int i, char *name);
-int	biosinit(void);
-void	biosprintbootdevs(int dev);
-void	biosprintdevs(int i);
-long	biosread(Fs *fs, void *a, long n);
--- a/os/boot/pc/devfloppy.c
+++ /dev/null
@@ -1,853 +1,0 @@
-#include <u.h>
-
-#include	"lib.h"
-#include	"mem.h"
-#include	"dat.h"
-#include	"fns.h"
-#include	"io.h"
-#include	"ureg.h"
-
-#include	"fs.h"
-#include	"devfloppy.h"
-
-
-/* Intel 82077A (8272A compatible) floppy controller */
-
-/* This module expects the following functions to be defined
- * elsewhere: 
- * 
- * inb()
- * outb()
- * floppyexec()
- * floppyeject() 
- * floppysetup0()
- * floppysetup1()
- * dmainit()
- * dmasetup()
- * dmaend()
- * 
- * On DMA systems, floppyexec() should be an empty function; 
- * on non-DMA systems, dmaend() should be an empty function; 
- * dmasetup() may enforce maximum transfer sizes. 
- */
-
-enum {
-	/* file types */
-	Qdir=		0, 
-	Qdata=		(1<<2),
-	Qctl=		(2<<2),
-	Qmask=		(3<<2),
-
-	DMAchan=	2,	/* floppy dma channel */
-};
-
-#define DPRINT if(0)print
-
-FType floppytype[] =
-{
- { "3½HD",	T1440kb, 512, 18, 2, 1, 80, 0x1B, 0x54,	0, },
- { "3½DD",	T1440kb, 512,  9, 2, 1, 80, 0x1B, 0x54, 2, },
- { "3½DD",	T720kb,  512,  9, 2, 1, 80, 0x1B, 0x54, 2, },
- { "5¼HD",	T1200kb, 512, 15, 2, 1, 80, 0x2A, 0x50, 0, },
- { "5¼DD",	T1200kb, 512,  9, 2, 2, 40, 0x2A, 0x50, 1, },
- { "ATT3B1",	T1200kb, 512,  8, 2, 2, 48, 0x2A, 0x50, 1, },
- { "5¼DD",	T360kb,  512,  9, 2, 1, 40, 0x2A, 0x50, 2, },
-};
-
-/*
- *  bytes per sector encoding for the controller.
- *  - index for b2c is is (bytes per sector/128).
- *  - index for c2b is code from b2c
- */
-static int b2c[] =
-{
-[1]	0,
-[2]	1,
-[4]	2,
-[8]	3,
-};
-static int c2b[] =
-{
-	128,
-	256,
-	512,
-	1024,
-};
-
-FController	fl;
-
-#define MOTORBIT(i)	(1<<((i)+4))
-
-/*
- *  predeclared
- */
-static int	cmddone(void*);
-static void	floppyformat(FDrive*, char*);
-static void	floppykproc(void*);
-static void	floppypos(FDrive*,long);
-static int	floppyrecal(FDrive*);
-static int	floppyresult(void);
-static void	floppyrevive(void);
-static vlong	pcfloppyseek(FDrive*, vlong);
-static int	floppysense(void);
-static void	floppywait(int);
-static long	floppyxfer(FDrive*, int, void*, long, long);
-
-static void
-fldump(void)
-{
-	DPRINT("sra %ux srb %ux dor %ux msr %ux dir %ux\n", inb(Psra), inb(Psrb),
-		inb(Pdor), inb(Pmsr), inb(Pdir));
-}
-
-static void
-floppyalarm(Alarm* a)
-{
-	FDrive *dp;
-
-	for(dp = fl.d; dp < &fl.d[fl.ndrive]; dp++){
-		if((fl.motor&MOTORBIT(dp->dev)) && TK2SEC(m->ticks - dp->lasttouched) > 5)
-			floppyoff(dp);
-	}
-
-	alarm(5*1000, floppyalarm, 0);
-	cancel(a);
-}
-
-/*
- *  set floppy drive to its default type
- */
-static void
-floppysetdef(FDrive *dp)
-{
-	FType *t;
-
-	for(t = floppytype; t < &floppytype[nelem(floppytype)]; t++)
-		if(dp->dt == t->dt){
-			dp->t = t;
-			break;
-		}
-}
-
-static void
-_floppydetach(void)
-{
-	/*
-	 *  stop the motors
-	 */
-	fl.motor = 0;
-	delay(10);
-	outb(Pdor, fl.motor | Fintena | Fena);
-	delay(10);
-}
-
-int
-floppyinit(void)
-{
-	FDrive *dp;
-	FType *t;
-	ulong maxtsize;
-	int mask;
-
-	dmainit(DMAchan);
-
-	floppysetup0(&fl);
-
-	/*
-	 *  init dependent parameters
-	 */
-	maxtsize = 0;
-	for(t = floppytype; t < &floppytype[nelem(floppytype)]; t++){
-		t->cap = t->bytes * t->heads * t->sectors * t->tracks;
-		t->bcode = b2c[t->bytes/128];
-		t->tsize = t->bytes * t->sectors;
-		if(maxtsize < t->tsize)
-			maxtsize = t->tsize;
-	}
-
-	fl.selected = fl.d;
-
-	floppydetach = _floppydetach;
-	floppydetach();
-
-	/*
-	 *  init drives
-	 */
-	mask = 0;
-	for(dp = fl.d; dp < &fl.d[fl.ndrive]; dp++){
-		dp->dev = dp - fl.d;
-		if(dp->dt == Tnone)
-			continue;
-		mask |= 1<<dp->dev;
-		floppysetdef(dp);
-		dp->cyl = -1;			/* because we don't know */
-		dp->cache = (uchar*)xspanalloc(maxtsize, BY2PG, 64*1024);
-		dp->ccyl = -1;
-		dp->vers = 0;
-		dp->maxtries = 5;
-	}
-
-	/*
-	 *  first operation will recalibrate
-	 */
-	fl.confused = 1;
-
-	floppysetup1(&fl);
-
-	/* to turn the motor off when inactive */
-	alarm(5*1000, floppyalarm, 0);
-
-	return mask;
-}
-
-void
-floppyinitdev(int i, char *name)
-{
-	if(i >= fl.ndrive)
-		panic("floppyinitdev");
-	sprint(name, "fd%d", i);
-}
-
-void
-floppyprintdevs(int i)
-{
-	if(i >= fl.ndrive)
-		panic("floppyprintdevs");
-	print(" fd%d", i);
-}
-
-int
-floppyboot(int dev, char *file, Boot *b)
-{
-	Fs *fs;
-
-	if(strncmp(file, "dos!", 4) == 0)
-		file += 4;
-	else if(strchr(file, '!') || strcmp(file, "")==0) {
-		print("syntax is fd0!file\n");
-		return -1;
-	}
-
-	fs = floppygetfspart(dev, "dos", 1);
-	if(fs == nil)
-		return -1;
-
-	return fsboot(fs, file, b);
-}
-
-void
-floppyprintbootdevs(int dev)
-{
-	print(" fd%d", dev);
-}
-
-/*
- *  check if the floppy has been replaced under foot.  cause
- *  an error if it has.
- *
- *  a seek and a read clears the condition.  this was determined
- *  experimentally, there has to be a better way.
- *
- *  if the read fails, cycle through the possible floppy
- *  density till one works or we've cycled through all
- *  possibilities for this drive.
- */
-static int
-changed(FDrive *dp)
-{
-	FType *start;
-
-	/*
-	 *  if floppy has changed or first time through
-	 */
-	if((inb(Pdir)&Fchange) || dp->vers == 0){
-		DPRINT("changed\n");
-		fldump();
-		dp->vers++;
-		floppysetdef(dp);
-		dp->maxtries = 3;
-		start = dp->t;
-
-		/* flopppyon fails if there's no drive */
-		dp->confused = 1;	/* make floppyon recal */
-		if(floppyon(dp) < 0)
-			return -1;
-
-		pcfloppyseek(dp, dp->t->heads*dp->t->tsize);
-
-		while(floppyxfer(dp, Fread, dp->cache, 0, dp->t->tsize) <= 0){
-
-			/*
-			 *  if the xfer attempt doesn't clear the changed bit,
-			 *  there's no floppy in the drive
-			 */
-			if(inb(Pdir)&Fchange)
-				return -1;
-
-			while(++dp->t){
-				if(dp->t == &floppytype[nelem(floppytype)])
-					dp->t = floppytype;
-				if(dp->dt == dp->t->dt)
-					break;
-			}
-
-			/* flopppyon fails if there's no drive */
-			if(floppyon(dp) < 0)
-				return -1;
-
-			DPRINT("changed: trying %s\n", dp->t->name);
-			fldump();
-			if(dp->t == start)
-				return -1;
-		}
-	}
-
-	return 0;
-}
-
-static int
-readtrack(FDrive *dp, int cyl, int head)
-{
-	int i, nn, sofar;
-	ulong pos;
-
-	nn = dp->t->tsize;
-	if(dp->ccyl==cyl && dp->chead==head)
-		return nn;
-	pos = (cyl*dp->t->heads+head) * nn;
-	for(sofar = 0; sofar < nn; sofar += i){
-		dp->ccyl = -1;
-		i = floppyxfer(dp, Fread, dp->cache + sofar, pos + sofar, nn - sofar);
-		if(i <= 0)
-			return -1;
-	}
-	dp->ccyl = cyl;
-	dp->chead = head;
-	return nn;
-}
-
-long
-floppyread(Fs *fs, void *a, long n)
-{
-	FDrive *dp;
-	long rv, offset;
-	int sec, head, cyl;
-	long len;
-	uchar *aa;
-
-	aa = a;
-	dp = &fl.d[fs->dev];
-
-	offset = dp->offset;
-	floppyon(dp);
-	if(changed(dp))
-		return -1;
-
-	for(rv = 0; rv < n; rv += len){
-		/*
-		 *  all xfers come out of the track cache
-		 */
-		dp->len = n - rv;
-		floppypos(dp, offset+rv);
-		cyl = dp->tcyl;
-		head = dp->thead;
-		len = dp->len;
-		sec = dp->tsec;
-		if(readtrack(dp, cyl, head) < 0)
-			break;
-		memmove(aa+rv, dp->cache + (sec-1)*dp->t->bytes, len);
-	}
-	dp->offset = offset+rv;
-
-	return rv;
-}
-
-void*
-floppygetfspart(int i, char *name, int chatty)
-{
-	static Fs fs;
-
-	if(strcmp(name, "dos") != 0){
-		if(chatty)
-			print("unknown partition fd%d!%s (use fd%d!dos)\n", i, name, i);
-		return nil;
-	}
-
-	fs.dev = i;
-	fs.diskread = floppyread;
-	fs.diskseek = floppyseek;
-
-	/* sometimes we get spurious errors and doing it again works */
-	if(dosinit(&fs) < 0 && dosinit(&fs) < 0){
-		if(chatty)
-			print("fd%d!%s does not contain a FAT file system\n", i, name);
-		return nil;
-	}
-	return &fs;
-}
-
-static int
-return0(void*)
-{
-	return 0;
-}
-
-static void
-timedsleep(int (*f)(void*), void* arg, int ms)
-{
-	int s;
-	ulong end;
-
-	end = m->ticks + 1 + MS2TK(ms);
-	while(m->ticks < end && !(*f)(arg)){
-		s = spllo();
-		delay(10);
-		splx(s);
-	}
-}
-
-/*
- *  start a floppy drive's motor.
- */
-static int
-floppyon(FDrive *dp)
-{
-	int alreadyon;
-	int tries;
-
-	if(fl.confused)
-		floppyrevive();
-
-	/* start motor and select drive */
-	dp->lasttouched = m->ticks;
-	alreadyon = fl.motor & MOTORBIT(dp->dev);
-	if(!alreadyon){
-		fl.motor |= MOTORBIT(dp->dev);
-		outb(Pdor, fl.motor | Fintena | Fena | dp->dev);
-		/* wait for drive to spin up */
-		timedsleep(return0, 0, 750);
-
-		/* clear any pending interrupts */
-		floppysense();
-	}
-
-	/* set transfer rate */
-	if(fl.rate != dp->t->rate){
-		fl.rate = dp->t->rate;
-		outb(Pdsr, fl.rate);
-	}
-
-	/* get drive to a known cylinder */
-	if(dp->confused)
-		for(tries = 0; tries < 4; tries++)
-			if(floppyrecal(dp) >= 0)
-				break;
-	dp->lasttouched = m->ticks;
-	fl.selected = dp;
-	if(dp->confused)
-		return -1;
-	return 0;
-}
-
-/*
- *  stop the floppy if it hasn't been used in 5 seconds
- */
-static void
-floppyoff(FDrive *dp)
-{
-	fl.motor &= ~MOTORBIT(dp->dev);
-	outb(Pdor, fl.motor | Fintena | Fena | dp->dev);
-}
-
-/*
- *  send a command to the floppy
- */
-static int
-floppycmd(void)
-{
-	int i;
-	int tries;
-
-	fl.nstat = 0;
-	for(i = 0; i < fl.ncmd; i++){
-		for(tries = 0; ; tries++){
-			if((inb(Pmsr)&(Ffrom|Fready)) == Fready)
-				break;
-			if(tries > 1000){
-				DPRINT("cmd %ux can't be sent (%d)\n", fl.cmd[0], i);
-				fldump();
-
-				/* empty fifo, might have been a bad command */
-				floppyresult();
-				return -1;
-			}
-			microdelay(1);
-		}
-		outb(Pfdata, fl.cmd[i]);
-	}
-	return 0;
-}
-
-/*
- *  get a command result from the floppy
- *
- *  when the controller goes ready waiting for a command
- *  (instead of sending results), we're done
- * 
- */
-static int
-floppyresult(void)
-{
-	int i, s;
-	int tries;
-
-	/* get the result of the operation */
-	for(i = 0; i < sizeof(fl.stat); i++){
-		/* wait for status byte */
-		for(tries = 0; ; tries++){
-			s = inb(Pmsr)&(Ffrom|Fready);
-			if(s == Fready){
-				fl.nstat = i;
-				return fl.nstat;
-			}
-			if(s == (Ffrom|Fready))
-				break;
-			if(tries > 1000){
-				DPRINT("floppyresult: %d stats\n", i);
-				fldump();
-				fl.confused = 1;
-				return -1;
-			}
-			microdelay(1);
-		}
-		fl.stat[i] = inb(Pfdata);
-	}
-	fl.nstat = sizeof(fl.stat);
-	return fl.nstat;
-}
-
-/*
- *  calculate physical address of a logical byte offset into the disk
- *
- *  truncate dp->length if it crosses a track boundary
- */
-static void
-floppypos(FDrive *dp, long off)
-{
-	int lsec;
-	int ltrack;
-	int end;
-
-	lsec = off/dp->t->bytes;
-	ltrack = lsec/dp->t->sectors;
-	dp->tcyl = ltrack/dp->t->heads;
-	dp->tsec = (lsec % dp->t->sectors) + 1;
-	dp->thead = (lsec/dp->t->sectors) % dp->t->heads;
-
-	/*
-	 *  can't read across track boundaries.
-	 *  if so, decrement the bytes to be read.
-	 */
-	end = (ltrack+1)*dp->t->sectors*dp->t->bytes;
-	if(off+dp->len > end)
-		dp->len = end - off;
-}
-
-/*
- *  get the interrupt cause from the floppy.
- */
-static int
-floppysense(void)
-{
-	fl.ncmd = 0;
-	fl.cmd[fl.ncmd++] = Fsense;
-	if(floppycmd() < 0)
-		return -1;
-	if(floppyresult() < 2){
-		DPRINT("can't read sense response\n");
-		fldump();
-		fl.confused = 1;
-		return -1;
-	}
-	return 0;
-}
-
-static int
-cmddone(void *a)
-{
-	USED(a);
-	return fl.ncmd == 0;
-}
-
-/*
- *  Wait for a floppy interrupt.  If none occurs in 5 seconds, we
- *  may have missed one.  This only happens on some portables which
- *  do power management behind our backs.  Call the interrupt
- *  routine to try to clear any conditions.
- */
-static void
-floppywait(int slow)
-{
-	timedsleep(cmddone, 0, slow ? 5000 : 1000);
-	if(!cmddone(0)){
-		floppyintr(0);
-		fl.confused = 1;
-	}
-}
-
-/*
- *  we've lost the floppy position, go to cylinder 0.
- */
-static int
-floppyrecal(FDrive *dp)
-{
-	dp->ccyl = -1;
-	dp->cyl = -1;
-
-	fl.ncmd = 0;
-	fl.cmd[fl.ncmd++] = Frecal;
-	fl.cmd[fl.ncmd++] = dp->dev;
-	if(floppycmd() < 0)
-		return -1;
-	floppywait(1);
-	if(fl.nstat < 2){
-		DPRINT("recalibrate: confused %ux\n", inb(Pmsr));
-		fl.confused = 1;
-		return -1;
-	}
-	if((fl.stat[0] & (Codemask|Seekend)) != Seekend){
-		DPRINT("recalibrate: failed\n");
-		dp->confused = 1;
-		return -1;
-	}
-	dp->cyl = fl.stat[1];
-	if(dp->cyl != 0){
-		DPRINT("recalibrate: wrong cylinder %d\n", dp->cyl);
-		dp->cyl = -1;
-		dp->confused = 1;
-		return -1;
-	}
-
-	dp->confused = 0;
-	return 0;
-}
-
-/*
- *  if the controller or a specific drive is in a confused state,
- *  reset it and get back to a kown state
- */
-static void
-floppyrevive(void)
-{
-	FDrive *dp;
-
-	/*
-	 *  reset the controller if it's confused
-	 */
-	if(fl.confused){
-		DPRINT("floppyrevive in\n");
-		fldump();
-
-		/* reset controller and turn all motors off */
-		splhi();
-		fl.ncmd = 1;
-		fl.cmd[0] = 0;
-		outb(Pdor, 0);
-		delay(10);
-		outb(Pdor, Fintena|Fena);
-		delay(10);
-		spllo();
-		fl.motor = 0;
-		fl.confused = 0;
-		floppywait(0);
-
-		/* mark all drives in an unknown state */
-		for(dp = fl.d; dp < &fl.d[fl.ndrive]; dp++)
-			dp->confused = 1;
-
-		/* set rate to a known value */
-		outb(Pdsr, 0);
-		fl.rate = 0;
-
-		DPRINT("floppyrevive out\n");
-		fldump();
-	}
-}
-
-/*
- *  seek to the target cylinder
- *
- *	interrupt, no results
- */
-static vlong
-pcfloppyseek(FDrive *dp, vlong off)
-{
-	floppypos(dp, off);
-	if(dp->cyl == dp->tcyl){
-		dp->offset = off;
-		return off;
-	}
-	dp->cyl = -1;
-
-	fl.ncmd = 0;
-	fl.cmd[fl.ncmd++] = Fseek;
-	fl.cmd[fl.ncmd++] = (dp->thead<<2) | dp->dev;
-	fl.cmd[fl.ncmd++] = dp->tcyl * dp->t->steps;
-	if(floppycmd() < 0)
-		return -1;
-	floppywait(1);
-	if(fl.nstat < 2){
-		DPRINT("seek: confused\n");
-		fl.confused = 1;
-		return -1;
-	}
-	if((fl.stat[0] & (Codemask|Seekend)) != Seekend){
-		DPRINT("seek: failed\n");
-		dp->confused = 1;
-		return -1;
-	}
-
-	dp->cyl = dp->tcyl;
-	dp->offset = off;
-	DPRINT("seek to %d succeeded\n", dp->offset);
-
-	return dp->offset;
-}
-
-/*
- *  read or write to floppy.  try up to three times.
- */
-static long
-floppyxfer(FDrive *dp, int cmd, void *a, long off, long n)
-{
-	long offset;
-	int tries;
-
-	if(off >= dp->t->cap)
-		return 0;
-	if(off + n > dp->t->cap)
-		n = dp->t->cap - off;
-
-	/* retry on error (until it gets ridiculous) */
-	for(tries = 0; tries < dp->maxtries; tries++){
-
-		dp->len = n;
-		if(pcfloppyseek(dp, off) < 0){
-			DPRINT("xfer: seek failed\n");
-			dp->confused = 1;
-			continue;
-		}
-
-		/*
-		 *  set up the dma (dp->len may be trimmed)
-		 */
-		dp->len = dmasetup(DMAchan, a, dp->len, cmd==Fread);
-		if(dp->len < 0){
-	buggery:
-			dmaend(DMAchan);
-			continue;
-		}
-	
-		/*
-		 *  start operation
-		 */
-		fl.ncmd = 0;
-		fl.cmd[fl.ncmd++] = cmd | (dp->t->heads > 1 ? Fmulti : 0);
-		fl.cmd[fl.ncmd++] = (dp->thead<<2) | dp->dev;
-		fl.cmd[fl.ncmd++] = dp->tcyl;
-		fl.cmd[fl.ncmd++] = dp->thead;
-		fl.cmd[fl.ncmd++] = dp->tsec;
-		fl.cmd[fl.ncmd++] = dp->t->bcode;
-		fl.cmd[fl.ncmd++] = dp->t->sectors;
-		fl.cmd[fl.ncmd++] = dp->t->gpl;
-		fl.cmd[fl.ncmd++] = 0xFF;
-		if(floppycmd() < 0)
-			goto buggery;
-
-		/*
-		 *  give bus to DMA, floppyintr() will read result
-		 */
-		floppywait(0);
-		dmaend(DMAchan);
-
-		/*
-		 *  check for errors
-		 */
-		if(fl.nstat < 7){
-			DPRINT("xfer: confused\n");
-			fl.confused = 1;
-			continue;
-		}
-		if((fl.stat[0] & Codemask)!=0 || fl.stat[1] || fl.stat[2]){
-			DPRINT("xfer: failed %ux %ux %ux\n", fl.stat[0],
-				fl.stat[1], fl.stat[2]);
-			DPRINT("offset %lud len %ld\n", off, dp->len);
-			if((fl.stat[0]&Codemask)==Cmdexec && fl.stat[1]==Overrun){
-				DPRINT("DMA overrun: retry\n");
-			} else
-				dp->confused = 1;
-			continue;
-		}
-
-		/*
-		 *  check for correct cylinder
-		 */
-		offset = fl.stat[3] * dp->t->heads + fl.stat[4];
-		offset = offset*dp->t->sectors + fl.stat[5] - 1;
-		offset = offset * c2b[fl.stat[6]];
-		if(offset != off+dp->len){
-			DPRINT("xfer: ends on wrong cyl\n");
-			dp->confused = 1;
-			continue;
-		}
-	
-		dp->lasttouched = m->ticks;
-		dp->maxtries = 20;
-		return dp->len;
-	}
-
-	return -1;
-}
-
-/*
-void
-floppymemwrite(void)
-{
-	int i;
-	int n;
-	uchar *a;
-	FDrive *dp;
-
-	dp = &fl.d[0];
-	a = (uchar*)0x80000000;
-	n = 0;
-	while(n < 1440*1024){
-		i = floppyxfer(dp, Fwrite, a+n, n, 1440*1024-n);
-		if(i <= 0)
-			break;
-		n += i;
-	}
-	print("floppymemwrite wrote %d bytes\n", n);
-splhi(); for(;;);
-}
-*/
-
-static void
-floppyintr(Ureg *ur)
-{
-	USED(ur);
-	switch(fl.cmd[0]&~Fmulti){
-	case Fread:
-	case Fwrite:
-	case Fformat:
-	case Fdumpreg: 
-		floppyresult();
-		break;
-	case Fseek:
-	case Frecal:
-	default:
-		floppysense();	/* to clear interrupt */
-		break;
-	}
-	fl.ncmd = 0;
-}
--- a/os/boot/pc/devfloppy.h
+++ /dev/null
@@ -1,196 +1,0 @@
-typedef	struct FController FController;
-typedef	struct FDrive FDrive;
-typedef struct FType FType;
-
-static void floppyintr(Ureg*);
-static int floppyon(FDrive*);
-static void floppyoff(FDrive*);
-static void floppysetdef(FDrive*);
-
-/*
- *  a floppy drive
- */
-struct FDrive
-{
-	FType	*t;		/* floppy type */
-	int	dt;		/* drive type */
-	int	dev;
-
-	ulong	lasttouched;	/* time last touched */
-	int	cyl;		/* current arm position */
-	int	confused;	/* needs to be recalibrated */
-	int	offset;		/* current offset */
-	int	vers;
-	int	maxtries;
-
-	int	tcyl;		/* target cylinder */
-	int	thead;		/* target head */
-	int	tsec;		/* target sector */
-	long	len;		/* size of xfer */
-
-	uchar	*cache;		/* track cache */
-	int	ccyl;
-	int	chead;
-
-//	Rendez	r;		/* waiting here for motor to spin up */
-	void	*aux;
-};
-
-/*
- *  controller for 4 floppys
- */
-struct FController
-{
-//	QLock;			/* exclusive access to the contoller */
-
-	int	ndrive;
-	FDrive	*d;		/* the floppy drives */
-	FDrive	*selected;
-	int	rate;		/* current rate selected */
-	uchar	cmd[14];	/* command */
-	int	ncmd;		/* # command bytes */
-	uchar	stat[14];	/* command status */
-	int	nstat;		/* # status bytes */
-	int	confused;	/* controler needs to be reset */
-//	Rendez	r;		/* wait here for command termination */
-	int	motor;		/* bit mask of spinning disks */
-//	Rendez	kr;		/* for motor watcher */
-};
-
-/*
- *  floppy types (all MFM encoding)
- */
-struct FType
-{
-	char	*name;
-	int	dt;		/* compatible drive type */
-	int	bytes;		/* bytes/sector */
-	int	sectors;	/* sectors/track */
-	int	heads;		/* number of heads */
-	int	steps;		/* steps per cylinder */
-	int	tracks;		/* tracks/disk */
-	int	gpl;		/* intersector gap length for read/write */	
-	int	fgpl;		/* intersector gap length for format */
-	int	rate;		/* rate code */
-
-	/*
-	 *  these depend on previous entries and are set filled in
-	 *  by floppyinit
-	 */
-	int	bcode;		/* coded version of bytes for the controller */
-	long	cap;		/* drive capacity in bytes */
-	long	tsize;		/* track size in bytes */
-};
-/* bits in the registers */
-enum
-{
-	/* status registers a & b */
-	Psra=		0x3f0,
-	Psrb=		0x3f1,
-
-	/* digital output register */
-	Pdor=		0x3f2,
-	Fintena=	0x8,	/* enable floppy interrupt */
-	Fena=		0x4,	/* 0 == reset controller */
-
-	/* main status register */
-	Pmsr=		0x3f4,
-	Fready=		0x80,	/* ready to be touched */
-	Ffrom=		0x40,	/* data from controller */
-	Ffloppybusy=	0x10,	/* operation not over */
-
-	/* data register */
-	Pfdata=		0x3f5,
-	Frecal=		0x07,	/* recalibrate cmd */
-	Fseek=		0x0f,	/* seek cmd */
-	Fsense=		0x08,	/* sense cmd */
-	Fread=		0x66,	/* read cmd */
-	Freadid=	0x4a,	/* read track id */
-	Fspec=		0x03,	/* set hold times */
-	Fwrite=		0x45,	/* write cmd */
-	Fformat=	0x4d,	/* format cmd */
-	Fmulti=		0x80,	/* or'd with Fread or Fwrite for multi-head */
-	Fdumpreg=	0x0e,	/* dump internal registers */
-
-	/* digital input register */
-	Pdir=		0x3F7,	/* disk changed port (read only) */
-	Pdsr=		0x3F7,	/* data rate select port (write only) */
-	Fchange=	0x80,	/* disk has changed */
-
-	/* status 0 byte */
-	Drivemask=	3<<0,
-	Seekend=	1<<5,
-	Codemask=	(3<<6)|(3<<3),
-	Cmdexec=	1<<6,
-
-	/* status 1 byte */
-	Overrun=	0x10,
-};
-
-/*
- *  types of drive (from PC equipment byte)
- */
-enum
-{
-	Tnone=		0,
-	T360kb=		1,
-	T1200kb=	2,
-	T720kb=		3,
-	T1440kb=	4,
-};
-
-static void
-pcfloppyintr(Ureg *ur, void *a)
-{
-	USED(a);
-
-	floppyintr(ur);
-}
-
-void
-floppysetup0(FController *fl)
-{
-	uchar equip;
-
-	/*
-	 * Read nvram for types of floppies 0 & 1.
-	 * Always try floppy 0.
-	 */
-	equip = nvramread(0x10);
-	fl->ndrive = 1;
-
-	if(equip & 0xf)
-		fl->ndrive++;
-
-	/*
-	 * Allocate the drive storage.
-	 * There's always one.
-	 */
-	fl->d = xalloc(fl->ndrive*sizeof(FDrive));
-	fl->d[0].dt = (equip >> 4) & 0xf;
-	if(fl->d[0].dt == Tnone)
-		fl->d[0].dt = T1440kb;
-
-	if(fl->ndrive == 2)
-		fl->d[1].dt = equip & 0xf;
-}
-
-void
-floppysetup1(FController*)
-{
-//	intrenable(VectorFLOPPY, pcfloppyintr, fl, BUSUNKNOWN);
-	setvec(VectorFLOPPY, pcfloppyintr, 0);
-}
-
-
-static vlong pcfloppyseek(FDrive*, vlong);
-FController	fl;
-
-vlong
-floppyseek(Fs *fs, vlong off)
-{
-	FDrive *dp;
-
-	dp = &fl.d[fs->dev];
-	return pcfloppyseek(dp, off);
-}
--- a/os/boot/pc/devi82365.c
+++ /dev/null
@@ -1,742 +1,0 @@
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "error.h"
-#include "io.h"
-
-/*
- *  Intel 82365SL PCIC controller and compatibles.
- */
-enum
-{
-	/*
-	 *  registers indices
-	 */
-	Rid=		0x0,		/* identification and revision */
-	Ris=		0x1,		/* interface status */
-	Rpc=	 	0x2,		/* power control */
-	 Foutena=	 (1<<7),	/*  output enable */
-	 Fautopower=	 (1<<5),	/*  automatic power switching */
-	 Fcardena=	 (1<<4),	/*  PC card enable */
-	Rigc= 		0x3,		/* interrupt and general control */
-	 Fiocard=	 (1<<5),	/*  I/O card (vs memory) */
-	 Fnotreset=	 (1<<6),	/*  reset if not set */	
-	 FSMIena=	 (1<<4),	/*  enable change interrupt on SMI */ 
-	Rcsc= 		0x4,		/* card status change */
-	Rcscic= 	0x5,		/* card status change interrupt config */
-	 Fchangeena=	 (1<<3),	/*  card changed */
-	 Fbwarnena=	 (1<<1),	/*  card battery warning */
-	 Fbdeadena=	 (1<<0),	/*  card battery dead */
-	Rwe= 		0x6,		/* address window enable */
-	 Fmem16=	 (1<<5),	/*  use A23-A12 to decode address */
-	Rio= 		0x7,		/* I/O control */
-	 Fwidth16=	 (1<<0),	/*  16 bit data width */
-	 Fiocs16=	 (1<<1),	/*  IOCS16 determines data width */
-	 Fzerows=	 (1<<2),	/*  zero wait state */
-	 Ftiming=	 (1<<3),	/*  timing register to use */
-	Riobtm0lo=	0x8,		/* I/O address 0 start low byte */
-	Riobtm0hi=	0x9,		/* I/O address 0 start high byte */
-	Riotop0lo=	0xa,		/* I/O address 0 stop low byte */
-	Riotop0hi=	0xb,		/* I/O address 0 stop high byte */
-	Riobtm1lo=	0xc,		/* I/O address 1 start low byte */
-	Riobtm1hi=	0xd,		/* I/O address 1 start high byte */
-	Riotop1lo=	0xe,		/* I/O address 1 stop low byte */
-	Riotop1hi=	0xf,		/* I/O address 1 stop high byte */
-	Rmap=		0x10,		/* map 0 */
-
-	/*
-	 *  CL-PD67xx extension registers
-	 */
-	Rmisc1=		0x16,		/* misc control 1 */
-	 F5Vdetect=	 (1<<0),
-	 Fvcc3V=	 (1<<1),
-	 Fpmint=	 (1<<2),
-	 Fpsirq=	 (1<<3),
-	 Fspeaker=	 (1<<4),
-	 Finpack=	 (1<<7),
-	Rfifo=		0x17,		/* fifo control */
-	 Fflush=	 (1<<7),	/*  flush fifo */
-	Rmisc2=		0x1E,		/* misc control 2 */
-	 Flowpow=	 (1<<1),	/*  low power mode */
-	Rchipinfo=	0x1F,		/* chip information */
-	Ratactl=	0x26,		/* ATA control */
-
-	/*
-	 *  offsets into the system memory address maps
-	 */
-	Mbtmlo=		0x0,		/* System mem addr mapping start low byte */
-	Mbtmhi=		0x1,		/* System mem addr mapping start high byte */
-	 F16bit=	 (1<<7),	/*  16-bit wide data path */
-	Mtoplo=		0x2,		/* System mem addr mapping stop low byte */
-	Mtophi=		0x3,		/* System mem addr mapping stop high byte */
-	 Ftimer1=	 (1<<6),	/*  timer set 1 */
-	Mofflo=		0x4,		/* Card memory offset address low byte */
-	Moffhi=		0x5,		/* Card memory offset address high byte */
-	 Fregactive=	 (1<<6),	/*  attribute memory */
-
-	/*
-	 *  configuration registers - they start at an offset in attribute
-	 *  memory found in the CIS.
-	 */
-	Rconfig=	0,
-	 Creset=	 (1<<7),	/*  reset device */
-	 Clevel=	 (1<<6),	/*  level sensitive interrupt line */
-	 Cirq=		 (1<<2),	/*  IRQ enable */
-	 Cdecode=	 (1<<1),	/*  address decode */
-	 Cfunc=		 (1<<0),	/*  function enable */
-	Riobase0=	5,
-	Riobase1=	6,
-	Riosize=	9,
-};
-
-static int pcmcia_pcmspecial(char *, ISAConf *);
-static void pcmcia_pcmspecialclose(int);
-
-#define MAP(x,o)	(Rmap + (x)*0x8 + o)
-
-typedef struct I82365	I82365;
-
-/* a controller */
-enum
-{
-	Ti82365,
-	Tpd6710,
-	Tpd6720,
-	Tvg46x,
-};
-struct I82365
-{
-	int	type;
-	int	dev;
-	int	nslot;
-	int	xreg;		/* index register address */
-	int	dreg;		/* data register address */
-	int	irq;
-};
-static I82365 *controller[4];
-static int ncontroller;
-static PCMslot	*slot;
-static PCMslot	*lastslot;
-static nslot;
-
-static void	i82365intr(Ureg*, void*);
-static void	i82365reset(void);
-static int	pcmio(int, ISAConf*);
-
-static void i82365dump(PCMslot*);
-
-void
-devi82365link(void)
-{
-	static int already;
-	char *p;
-
-	if(already)
-		return;
-	already = 1;
-
-	if((p=getconf("pcmcia0")) && strncmp(p, "disabled", 8)==0)
-		return;
-
-	if (_pcmspecial)
-		return;
-	
-	_pcmspecial = pcmcia_pcmspecial;
-	_pcmspecialclose = pcmcia_pcmspecialclose;
-}
-
-/*
- *  reading and writing card registers
- */
-static uchar
-rdreg(PCMslot *pp, int index)
-{
-	outb(((I82365*)pp->cp)->xreg, pp->base + index);
-	return inb(((I82365*)pp->cp)->dreg);
-}
-static void
-wrreg(PCMslot *pp, int index, uchar val)
-{
-	outb(((I82365*)pp->cp)->xreg, pp->base + index);
-	outb(((I82365*)pp->cp)->dreg, val);
-}
-
-/*
- *  get info about card
- */
-static void
-slotinfo(PCMslot *pp)
-{
-	uchar isr;
-
-	isr = rdreg(pp, Ris);
-	pp->occupied = (isr & (3<<2)) == (3<<2);
-	pp->powered = isr & (1<<6);
-	pp->battery = (isr & 3) == 3;
-	pp->wrprot = isr & (1<<4);
-	pp->busy = isr & (1<<5);
-	//pp->msec = TK2MS(MACHP(0)->ticks);
-}
-
-static int
-vcode(int volt)
-{
-	switch(volt){
-	case 5:
-		return 1;
-	case 12:
-		return 2;
-	default:
-		return 0;
-	}
-}
-
-/*
- *  enable the slot card
- */
-static void
-slotena(PCMslot *pp)
-{
-	if(pp->enabled)
-		return;
-
-	/* power up and unreset, wait's are empirical (???) */
-	wrreg(pp, Rpc, Fautopower|Foutena|Fcardena);
-	delay(300);
-	wrreg(pp, Rigc, 0);
-	delay(100);
-	wrreg(pp, Rigc, Fnotreset);
-	delay(500);
-
-	/* get configuration */
-	slotinfo(pp);
-	if(pp->occupied){
-		pcmcisread(pp);
-		pp->enabled = 1;
-	} else
-		wrreg(pp, Rpc, Fautopower);
-}
-
-/*
- *  disable the slot card
- */
-static void
-slotdis(PCMslot *pp)
-{
-	wrreg(pp, Rpc, 0);	/* turn off card power */
-	wrreg(pp, Rwe, 0);	/* no windows */
-	pp->enabled = 0;
-}
-
-/*
- *  status change interrupt
- */
-static void
-i82365intr(Ureg *, void *)
-{
-	uchar csc, was;
-	PCMslot *pp;
-
-	if(slot == 0)
-		return;
-
-	for(pp = slot; pp < lastslot; pp++){
-		csc = rdreg(pp, Rcsc);
-		was = pp->occupied;
-		slotinfo(pp);
-		if(csc & (1<<3) && was != pp->occupied){
-			if(!pp->occupied)
-				slotdis(pp);
-		}
-	}
-}
-
-enum
-{
-	Mshift=	12,
-	Mgran=	(1<<Mshift),	/* granularity of maps */
-	Mmask=	~(Mgran-1),	/* mask for address bits important to the chip */
-};
-
-/*
- *  get a map for pc card region, return corrected len
- */
-PCMmap*
-pcmmap(int slotno, ulong offset, int len, int attr)
-{
-	PCMslot *pp;
-	uchar we, bit;
-	PCMmap *m, *nm;
-	int i;
-	ulong e;
-
-	pp = slot + slotno;
-	lock(&pp->mlock);
-
-	/* convert offset to granularity */
-	if(len <= 0)
-		len = 1;
-	e = ROUND(offset+len, Mgran);
-	offset &= Mmask;
-	len = e - offset;
-
-	/* look for a map that covers the right area */
-	we = rdreg(pp, Rwe);
-	bit = 1;
-	nm = 0;
-	for(m = pp->mmap; m < &pp->mmap[nelem(pp->mmap)]; m++){
-		if((we & bit))
-		if(m->attr == attr)
-		if(offset >= m->ca && e <= m->cea){
-
-			m->ref++;
-			unlock(&pp->mlock);
-			return m;
-		}
-		bit <<= 1;
-		if(nm == 0 && m->ref == 0)
-			nm = m;
-	}
-	m = nm;
-	if(m == 0){
-		unlock(&pp->mlock);
-		return 0;
-	}
-
-	/* if isa space isn't big enough, free it and get more */
-	if(m->len < len){
-		if(m->isa){
-			umbfree(m->isa, m->len);
-			m->len = 0;
-		}
-		m->isa = PADDR(umbmalloc(0, len, Mgran));
-		if(m->isa == 0){
-			print("pcmmap %d: out of isa space\n", len);
-			unlock(&pp->mlock);
-			return 0;
-		}
-		m->len = len;
-	}
-
-	/* set up new map */
-	m->ca = offset;
-	m->cea = m->ca + m->len;
-	m->attr = attr;
-	i = m-pp->mmap;
-	bit = 1<<i;
-	wrreg(pp, Rwe, we & ~bit);		/* disable map before changing it */
-	wrreg(pp, MAP(i, Mbtmlo), m->isa>>Mshift);
-	wrreg(pp, MAP(i, Mbtmhi), (m->isa>>(Mshift+8)) | F16bit);
-	wrreg(pp, MAP(i, Mtoplo), (m->isa+m->len-1)>>Mshift);
-	wrreg(pp, MAP(i, Mtophi), ((m->isa+m->len-1)>>(Mshift+8)));
-	offset -= m->isa;
-	offset &= (1<<25)-1;
-	offset >>= Mshift;
-	wrreg(pp, MAP(i, Mofflo), offset);
-	wrreg(pp, MAP(i, Moffhi), (offset>>8) | (attr ? Fregactive : 0));
-	wrreg(pp, Rwe, we | bit);		/* enable map */
-	m->ref = 1;
-
-	unlock(&pp->mlock);
-	return m;
-}
-
-void
-pcmunmap(int slotno, PCMmap* m)
-{
-	PCMslot *pp;
-
-	pp = slot + slotno;
-	lock(&pp->mlock);
-	m->ref--;
-	unlock(&pp->mlock);
-}
-
-static void
-increfp(PCMslot *pp)
-{
-	lock(pp);
-	if(pp->ref++ == 0)
-		slotena(pp);
-	unlock(pp);
-}
-
-static void
-decrefp(PCMslot *pp)
-{
-	lock(pp);
-	if(pp->ref-- == 1)
-		slotdis(pp);
-	unlock(pp);
-}
-
-/*
- *  look for a card whose version contains 'idstr'
- */
-static int
-pcmcia_pcmspecial(char *idstr, ISAConf *isa)
-{
-	PCMslot *pp;
-	extern char *strstr(char*, char*);
-	int enabled;
-
-	i82365reset();
-	for(pp = slot; pp < lastslot; pp++){
-		if(pp->special)
-			continue;	/* already taken */
-		enabled = 0;
-		/* make sure we don't power on cards when we already know what's
-		 * in them.  We'll reread every two minutes if necessary
-		 */
-		if (pp->verstr[0] == '\0') {
-			increfp(pp);
-			enabled++;
-		}
-
-		if(pp->occupied) {
-			if(strstr(pp->verstr, idstr)){
-				if (!enabled){
-					enabled = 1;
-					increfp(pp);
-				}
-				if(isa == 0 || pcmio(pp->slotno, isa) == 0){
-					pp->special = 1;
-					return pp->slotno;
-				}
-			}
-		} else
-			pp->special = 1;
-		if (enabled)
-			decrefp(pp);
-	}
-	return -1;
-}
-
-static void
-pcmcia_pcmspecialclose(int slotno)
-{
-	PCMslot *pp;
-
-	print("pcmspecialclose called\n");
-	if(slotno >= nslot)
-		panic("pcmspecialclose");
-	pp = slot + slotno;
-	pp->special = 0;
-	decrefp(pp);
-}
-
-static char *chipname[] =
-{
-[Ti82365]	"Intel 82365SL",
-[Tpd6710]	"Cirrus Logic PD6710",
-[Tpd6720]	"Cirrus Logic PD6720",
-[Tvg46x]	"Vadem VG-46x",
-};
-
-static I82365*
-i82365probe(int x, int d, int dev)
-{
-	uchar c, id;
-	I82365 *cp;
-	ISAConf isa;
-	int i, nslot;
-
-	outb(x, Rid + (dev<<7));
-	id = inb(d);
-	if((id & 0xf0) != 0x80)
-		return 0;		/* not a memory & I/O card */
-	if((id & 0x0f) == 0x00)
-		return 0;		/* no revision number, not possible */
-
-	cp = xalloc(sizeof(I82365));
-	cp->xreg = x;
-	cp->dreg = d;
-	cp->dev = dev;
-	cp->type = Ti82365;
-	cp->nslot = 2;
-
-	switch(id){
-	case 0x82:
-	case 0x83:
-	case 0x84:
-		/* could be a cirrus */
-		outb(x, Rchipinfo + (dev<<7));
-		outb(d, 0);
-		c = inb(d);
-		if((c & 0xc0) != 0xc0)
-			break;
-		c = inb(d);
-		if((c & 0xc0) != 0x00)
-			break;
-		if(c & 0x20){
-			cp->type = Tpd6720;
-		} else {
-			cp->type = Tpd6710;
-			cp->nslot = 1;
-		}
-
-		/* low power mode */
-		outb(x, Rmisc2 + (dev<<7));
-		c = inb(d);
-		outb(d, c & ~Flowpow);
-		break;
-	}
-
-	/* if it's not a Cirrus, it could be a Vadem... */
-	if(cp->type == Ti82365){
-		/* unlock the Vadem extended regs */
-		outb(x, 0x0E + (dev<<7));
-		outb(x, 0x37 + (dev<<7));
-
-		/* make the id register show the Vadem id */
-		outb(x, 0x3A + (dev<<7));
-		c = inb(d);
-		outb(d, c|0xC0);
-		outb(x, Rid + (dev<<7));
-		c = inb(d);
-		if(c & 0x08)
-			cp->type = Tvg46x;
-
-		/* go back to Intel compatible id */
-		outb(x, 0x3A + (dev<<7));
-		c = inb(d);
-		outb(d, c & ~0xC0);
-	}
-
-	memset(&isa, 0, sizeof(ISAConf));
-	if(isaconfig("pcmcia", ncontroller, &isa) && isa.irq)
-		cp->irq = isa.irq;
-	else
-		cp->irq = VectorPCMCIA - VectorPIC;
-
-	for(i = 0; i < isa.nopt; i++){
-		if(cistrncmp(isa.opt[i], "nslot=", 6))
-			continue;
-		nslot = strtol(&isa.opt[i][6], nil, 0);
-		if(nslot > 0 && nslot <= 2)
-			cp->nslot = nslot;
-	}
-
-	controller[ncontroller++] = cp;
-	return cp;
-}
-
-static void
-i82365dump(PCMslot *pp)
-{
-	int i;
-
-	for(i = 0; i < 0x40; i++){
-		if((i&0x0F) == 0)
-			print("\n%2.2uX:	", i);
-		if(((i+1) & 0x0F) == 0x08)
-			print(" - ");
-		print("%2.2uX ", rdreg(pp, i));
-	}
-	print("\n");
-}
-
-/*
- *  set up for slot cards
- */
-static void
-i82365reset(void)
-{
-	static int already;
-	int i, j;
-	I82365 *cp;
-	PCMslot *pp;
-
-	if(already)
-		return;
-	already = 1;
-
-
-	/* look for controllers */
-	i82365probe(0x3E0, 0x3E1, 0);
-	i82365probe(0x3E0, 0x3E1, 1);
-	i82365probe(0x3E2, 0x3E3, 0);
-	i82365probe(0x3E2, 0x3E3, 1);
-
-	for(i = 0; i < ncontroller; i++)
-		nslot += controller[i]->nslot;
-	slot = xalloc(nslot * sizeof(PCMslot));
-
-	lastslot = slot;
-	for(i = 0; i < ncontroller; i++){
-		cp = controller[i];
-		print("#y%d: %d slot %s: port 0x%uX irq %d\n",
-			i, cp->nslot, chipname[cp->type], cp->xreg, cp->irq);
-		for(j = 0; j < cp->nslot; j++){
-			pp = lastslot++;
-			pp->slotno = pp - slot;
-			pp->memlen = 64*MB;
-			pp->base = (cp->dev<<7) | (j<<6);
-			pp->cp = cp;
-			pp->msec = ~0;
-			pp->verstr[0] = 0;
-			slotdis(pp);
-
-			/* interrupt on status change */
-			wrreg(pp, Rcscic, (cp->irq<<4) | Fchangeena);
-			rdreg(pp, Rcsc);
-		}
-
-		/* for card management interrupts */
-		setvec(cp->irq+VectorPIC, i82365intr, 0);
-	}
-}
-
-/*
- *  configure the PCMslot for IO.  We assume very heavily that we can read
- *  configuration info from the CIS.  If not, we won't set up correctly.
- */
-static int
-pcmio(int slotno, ISAConf *isa)
-{
-	uchar we, x, *p;
-	PCMslot *pp;
-	PCMconftab *ct, *et, *t;
-	PCMmap *m;
-	int i, index, irq;
-	char *cp;
-
-	irq = isa->irq;
-	if(irq == 2)
-		irq = 9;
-
-	if(slotno > nslot)
-		return -1;
-	pp = slot + slotno;
-
-	if(!pp->occupied)
-		return -1;
-
-	et = &pp->ctab[pp->nctab];
-
-	ct = 0;
-	for(i = 0; i < isa->nopt; i++){
-		if(strncmp(isa->opt[i], "index=", 6))
-			continue;
-		index = strtol(&isa->opt[i][6], &cp, 0);
-		if(cp == &isa->opt[i][6] || index >= pp->nctab)
-			return -1;
-		ct = &pp->ctab[index];
-	}
-
-	if(ct == 0){
-	
-		/* assume default is right */
-		if(pp->def)
-			ct = pp->def;
-		else
-			ct = pp->ctab;
-	
-		/* try for best match */
-		if(ct->nio == 0
-		|| ct->io[0].start != isa->port || ((1<<irq) & ct->irqs) == 0){
-			for(t = pp->ctab; t < et; t++)
-				if(t->nio
-				&& t->io[0].start == isa->port
-				&& ((1<<irq) & t->irqs)){
-					ct = t;
-					break;
-				}
-		}
-		if(ct->nio == 0 || ((1<<irq) & ct->irqs) == 0){
-			for(t = pp->ctab; t < et; t++)
-				if(t->nio && ((1<<irq) & t->irqs)){
-					ct = t;
-					break;
-				}
-		}
-		if(ct->nio == 0){
-			for(t = pp->ctab; t < et; t++)
-				if(t->nio){
-					ct = t;
-					break;
-				}
-		}
-	}
-
-	if(ct == et || ct->nio == 0)
-		return -1;
-	if(isa->port == 0 && ct->io[0].start == 0)
-		return -1;
-
-	/* route interrupts */
-	isa->irq = irq;
-	wrreg(pp, Rigc, irq | Fnotreset | Fiocard);
-	
-	/* set power and enable device */
-	x = vcode(ct->vpp1);
-	wrreg(pp, Rpc, x|Fautopower|Foutena|Fcardena);
-
-	/* 16-bit data path */
-	if(ct->bit16)
-		x = Ftiming|Fiocs16|Fwidth16;
-	else
-		x = Ftiming;
-	if(ct->nio == 2 && ct->io[1].start)
-		x |= x<<4;
-	wrreg(pp, Rio, x);
-
-	/*
-	 * enable io port map 0
-	 * the 'top' register value includes the last valid address
-	 */
-	if(isa->port == 0)
-		isa->port = ct->io[0].start;
-	we = rdreg(pp, Rwe);
-	wrreg(pp, Riobtm0lo, isa->port);
-	wrreg(pp, Riobtm0hi, isa->port>>8);
-	i = isa->port+ct->io[0].len-1;
-	wrreg(pp, Riotop0lo, i);
-	wrreg(pp, Riotop0hi, i>>8);
-	we |= 1<<6;
-	if(ct->nio >= 2 && ct->io[1].start){
-		wrreg(pp, Riobtm1lo, ct->io[1].start);
-		wrreg(pp, Riobtm1hi, ct->io[1].start>>8);
-		i = ct->io[1].start+ct->io[1].len-1;
-		wrreg(pp, Riotop1lo, i);
-		wrreg(pp, Riotop1hi, i>>8);
-		we |= 1<<7;
-	}
-	wrreg(pp, Rwe, we);
-
-	/* only touch Rconfig if it is present */
-	m = pcmmap(slotno, pp->cfg[0].caddr + Rconfig, 0x20, 1);
-	p = KADDR(m->isa + pp->cfg[0].caddr - m->ca);
-	if(pp->cfg[0].cpresent & (1<<Rconfig)){
-		/*  Reset adapter */
-
-		/*  set configuration and interrupt type.
-		 *  if level is possible on the card, use it.
-		 */
-		x = ct->index;
-		if(ct->irqtype & 0x20)
-			x |= Clevel;
-
-		/*  enable the device, enable address decode and
-		 *  irq enable.
-		 */
-		x |= Cfunc|Cdecode|Cirq;
-
-		p[0] = x;
-		//delay(5);
-		microdelay(40);
-	}
-
-	if(pp->cfg[0].cpresent & (1<<Riobase0)){
-		/* set up the iobase 0 */
-		p[Riobase0 << 1] = isa->port;
-		p[Riobase1 << 1] = isa->port >> 8;
-	}
-
-	if(pp->cfg[0].cpresent & (1<<Riosize))
-		p[Riosize << 1] = ct->io[0].len;
-	pcmunmap(slotno, m);
-	return 0;
-}
--- a/os/boot/pc/devpccard.c
+++ /dev/null
@@ -1,1606 +1,0 @@
-/*
-     cardbus and pcmcia (grmph) support.
-*/
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "error.h"
-#include "io.h"
-
-extern int pciscan(int, Pcidev **);
-
-int (*_pcmspecial)(char *, ISAConf *);
-void (*_pcmspecialclose)(int);
-
-int
-pcmspecial(char *idstr, ISAConf *isa)
-{
-	return (_pcmspecial  != nil)? _pcmspecial(idstr, isa): -1;
-}
-
-void
-pcmspecialclose(int a)
-{
-	if (_pcmspecialclose != nil)
-		_pcmspecialclose(a);
-}
-
-static ulong
-ioreserve(ulong, int size, int align, char *)
-{
-	static ulong isaend = 0x400; /*0xfd00*/
-	ulong ioaddr;
-
-	if (align)
-		isaend = ((isaend + align - 1) / align) * align;
-	ioaddr = isaend;
-	isaend += size;
-	return ioaddr;
-}
-
-#define MAP(x,o)	(Rmap + (x)*0x8 + o)
-
-enum {
-	TI_vid = 0x104c,
-	TI_1131_did = 0xAC15,
-	TI_1250_did = 0xAC16,
-	TI_1450_did = 0xAC1B,
-	TI_1251A_did = 0xAC1D,
-	TI_1420_did = 0xAC51,
-
-	Ricoh_vid = 0x1180,
-	Ricoh_475_did = 0x0475,
-	Ricoh_476_did = 0x0476,
-	Ricoh_478_did = 0x0478,
-
-	O2_vid = 0x1217,
-	O2_OZ711M3_did = 0x7134,
-
-	Nslots = 4,		/* Maximum number of CardBus slots to use */
-
-	K = 1024,
-	M = K * K,
-
-	LegacyAddr = 0x3e0,
-	NUMEVENTS = 10,
-
-	TI1131xSC = 0x80,		// system control
-		TI122X_SC_INTRTIE	= 1 << 29,
-	TI12xxIM = 0x8c,		// 
-	TI1131xCC = 0x91,		// card control
-		TI113X_CC_RIENB = 1 << 7,
-		TI113X_CC_ZVENABLE = 1 << 6,
-		TI113X_CC_PCI_IRQ_ENA = 1 << 5,
-		TI113X_CC_PCI_IREQ = 1 << 4,
-		TI113X_CC_PCI_CSC = 1 << 3,
-		TI113X_CC_SPKROUTEN = 1 << 1,
-		TI113X_CC_IFG = 1 << 0,
-	TI1131xDC = 0x92,		// device control
-};
-
-typedef struct Variant Variant;
-struct Variant {
-	ushort	vid;
-	ushort	did;
-	char	*name;
-};
-
-static Variant variant[] = {
-{	Ricoh_vid,	Ricoh_475_did,	"Ricoh 475 PCI/Cardbus bridge",	},
-{	Ricoh_vid,	Ricoh_476_did,	"Ricoh 476 PCI/Cardbus bridge",	},
-{	Ricoh_vid,	Ricoh_478_did,	"Ricoh 478 PCI/Cardbus bridge",	},
-{	TI_vid,		TI_1131_did,	"TI PCI-1131 Cardbus Controller", },
-{	TI_vid,		TI_1250_did,	"TI PCI-1250 Cardbus Controller", },
-{	TI_vid,		TI_1450_did,	"TI PCI-1450 Cardbus Controller", },
-{	TI_vid,		TI_1251A_did,	"TI PCI-1251A Cardbus Controller", },
-{	TI_vid,		TI_1420_did,	"TI PCI-1420 Cardbus Controller", },
-{	O2_vid,		O2_OZ711M3_did,	"O2Micro OZ711M3 MemoryCardBus", },
-};
-
-/* Cardbus registers */
-enum {
-	SocketEvent = 0,
-		SE_CCD = 3 << 1,
-		SE_POWER = 1 << 3,
-	SocketMask = 1,
-	SocketState = 2,
-		SS_CCD = 3 << 1,
-		SS_POWER = 1 << 3,
-		SS_PC16 = 1 << 4,
-		SS_CBC = 1 << 5,
-		SS_NOTCARD = 1 << 7,
-		SS_BADVCC = 1 << 9,
-		SS_5V = 1 << 10,
-		SS_3V = 1 << 11,
-	SocketForce = 3,
-	SocketControl = 4,
-		SC_5V = 0x22,
-		SC_3V = 0x33,
-};
-
-enum {
-	PciPCR_IO = 1 << 0,
-	PciPCR_MEM = 1 << 1,
-	PciPCR_Master = 1 << 2,
-
-	PciPMC = 0xa4,
-
-	Nbars = 6,
-	Ncmd = 10,
-	CBIRQ = 9,
-
-	PC16,
-	PC32,
-};
-
-enum {
-	Ti82365,
-	Tpd6710,
-	Tpd6720,
-	Tvg46x,
-};
-
-/*
- *  Intel 82365SL PCIC controller for the PCMCIA or
- *  Cirrus Logic PD6710/PD6720 which is mostly register compatible
- */
-enum
-{
-	/*
-	 *  registers indices
-	 */
-	Rid=		0x0,		/* identification and revision */
-	Ris=		0x1,		/* interface status */
-	Rpc=	 	0x2,		/* power control */
-	 Foutena=	 (1<<7),	/*  output enable */
-	 Fautopower=	 (1<<5),	/*  automatic power switching */
-	 Fcardena=	 (1<<4),	/*  PC card enable */
-	Rigc= 		0x3,		/* interrupt and general control */
-	 Fiocard=	 (1<<5),	/*  I/O card (vs memory) */
-	 Fnotreset=	 (1<<6),	/*  reset if not set */	
-	 FSMIena=	 (1<<4),	/*  enable change interrupt on SMI */ 
-	Rcsc= 		0x4,		/* card status change */
-	Rcscic= 	0x5,		/* card status change interrupt config */
-	 Fchangeena=	 (1<<3),	/*  card changed */
-	 Fbwarnena=	 (1<<1),	/*  card battery warning */
-	 Fbdeadena=	 (1<<0),	/*  card battery dead */
-	Rwe= 		0x6,		/* address window enable */
-	 Fmem16=	 (1<<5),	/*  use A23-A12 to decode address */
-	Rio= 		0x7,		/* I/O control */
-	 Fwidth16=	 (1<<0),	/*  16 bit data width */
-	 Fiocs16=	 (1<<1),	/*  IOCS16 determines data width */
-	 Fzerows=	 (1<<2),	/*  zero wait state */
-	 Ftiming=	 (1<<3),	/*  timing register to use */
-	Riobtm0lo=	0x8,		/* I/O address 0 start low byte */
-	Riobtm0hi=	0x9,		/* I/O address 0 start high byte */
-	Riotop0lo=	0xa,		/* I/O address 0 stop low byte */
-	Riotop0hi=	0xb,		/* I/O address 0 stop high byte */
-	Riobtm1lo=	0xc,		/* I/O address 1 start low byte */
-	Riobtm1hi=	0xd,		/* I/O address 1 start high byte */
-	Riotop1lo=	0xe,		/* I/O address 1 stop low byte */
-	Riotop1hi=	0xf,		/* I/O address 1 stop high byte */
-	Rmap=		0x10,		/* map 0 */
-
-	/*
-	 *  CL-PD67xx extension registers
-	 */
-	Rmisc1=		0x16,		/* misc control 1 */
-	 F5Vdetect=	 (1<<0),
-	 Fvcc3V=	 (1<<1),
-	 Fpmint=	 (1<<2),
-	 Fpsirq=	 (1<<3),
-	 Fspeaker=	 (1<<4),
-	 Finpack=	 (1<<7),
-	Rfifo=		0x17,		/* fifo control */
-	 Fflush=	 (1<<7),	/*  flush fifo */
-	Rmisc2=		0x1E,		/* misc control 2 */
-	 Flowpow=	 (1<<1),	/*  low power mode */
-	Rchipinfo=	0x1F,		/* chip information */
-	Ratactl=	0x26,		/* ATA control */
-
-	/*
-	 *  offsets into the system memory address maps
-	 */
-	Mbtmlo=		0x0,		/* System mem addr mapping start low byte */
-	Mbtmhi=		0x1,		/* System mem addr mapping start high byte */
-	 F16bit=	 (1<<7),	/*  16-bit wide data path */
-	Mtoplo=		0x2,		/* System mem addr mapping stop low byte */
-	Mtophi=		0x3,		/* System mem addr mapping stop high byte */
-	 Ftimer1=	 (1<<6),	/*  timer set 1 */
-	Mofflo=		0x4,		/* Card memory offset address low byte */
-	Moffhi=		0x5,		/* Card memory offset address high byte */
-	 Fregactive=	 (1<<6),	/*  attribute memory */
-
-	/*
-	 *  configuration registers - they start at an offset in attribute
-	 *  memory found in the CIS.
-	 */
-	Rconfig=	0,
-	 Creset=	 (1<<7),	/*  reset device */
-	 Clevel=	 (1<<6),	/*  level sensitive interrupt line */
-};
-
-/*
- *  read and crack the card information structure enough to set
- *  important parameters like power
- */
-/* cis memory walking */
-typedef struct Cisdat Cisdat;
-struct Cisdat {
-	uchar		*cisbase;
-	int		cispos;
-	int		cisskip;
-	int		cislen;
-};
-
-typedef struct Pcminfo Pcminfo;
-struct Pcminfo {
-	char		verstr[512];		/* Version string */
-	PCMmap		mmap[4];		/* maps, last is always for the kernel */
-	ulong		conf_addr;		/* Config address */
-	uchar		conf_present;		/* Config register present */
-	int		nctab;			/* In use configuration tables */
-	PCMconftab	ctab[8];		/* Configuration tables */
-	PCMconftab	*defctab;		/* Default conftab */
-
-	int		port;			/* Actual port usage */
-	int		irq;			/* Actual IRQ usage */
-};
-
-typedef struct Cardbus Cardbus;
-struct Cardbus {
-	Lock;
-	Variant		*variant;		/* Which CardBus chipset */
-	Pcidev		*pci;			/* The bridge itself */
-	ulong		*regs;			/* Cardbus registers */
-	int		ltype;			/* Legacy type */
-	int		lindex;			/* Legacy port index address */
-	int		ldata;			/* Legacy port data address */
-	int		lbase;			/* Base register for this socket */
-
-	int		state;			/* Current state of card */
-	int		type;			/* Type of card */
-	Pcminfo		linfo;			/* PCMCIA slot info */
-
-	int		special;		/* card is allocated to a driver */
-
-	int		refs;			/* Number of refs to slot */
-	Lock		refslock;		/* inc/dev ref lock */
-};
-
-enum {
-	Mshift=	12,
-	Mgran=	(1<<Mshift),	/* granularity of maps */
-	Mmask=	~(Mgran-1),	/* mask for address bits important to the chip */
-};
-
-static Cardbus cbslots[Nslots];
-static int nslots;
-
-static ulong exponent[8] = { 
-	1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 
-};
-
-static ulong vmant[16] = {
-	10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80, 90,
-};
-
-static ulong mantissa[16] = { 
-	0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80, 
-};
-
-static void cbint(Ureg *, void *);
-static int powerup(Cardbus *);
-static void configure(Cardbus *);
-static void managecard(Cardbus *);
-static void cardmanager(void *);
-static void eject(Cardbus *);
-static void interrupt(Ureg *, void *);
-static void powerdown(Cardbus *cb);
-static void unconfigure(Cardbus *cb);
-
-static void i82365probe(Cardbus *cb, int lindex, int ldata);
-static void i82365configure(Cardbus *cb);
-static PCMmap *isamap(Cardbus *cb, ulong offset, int len, int attr);
-static void isaunmap(PCMmap* m);
-static uchar rdreg(Cardbus *cb, int index);
-static void wrreg(Cardbus *cb, int index, uchar val);
-static int readc(Cisdat *cis, uchar *x);
-static void tvers1(Cardbus *cb, Cisdat *cis, int );
-static void tcfig(Cardbus *cb, Cisdat *cis, int );
-static void tentry(Cardbus *cb, Cisdat *cis, int );
-static int vcode(int volt);
-static int pccard_pcmspecial(char *idstr, ISAConf *isa);
-static void pccard_pcmspecialclose(int slotno);
-
-enum {
-	CardDetected,
-	CardPowered,
-	CardEjected,
-	CardConfigured,
-};
-
-static char *messages[] = {
-[CardDetected]		"CardDetected",
-[CardPowered]		"CardPowered",
-[CardEjected]		"CardEjected",
-[CardConfigured]	"CardConfigured",
-};
-
-enum {
-	SlotEmpty,
-	SlotFull,
-	SlotPowered,
-	SlotConfigured,
-};
-
-static char *states[] = {
-[SlotEmpty]		"SlotEmpty",
-[SlotFull]		"SlotFull",
-[SlotPowered]		"SlotPowered",
-[SlotConfigured]	"SlotConfigured",
-};
-
-static void
-engine(Cardbus *cb, int message)
-{
-	// print("engine(%d): %s(%s)\n", 
-	//	 (int)(cb - cbslots), states[cb->state], messages[message]);
-	switch (cb->state) {
-	case SlotEmpty:
-
-		switch (message) {
-		case CardDetected:
-			cb->state = SlotFull;
-			powerup(cb);
-			break;
-		case CardEjected:
-			break;
-		default:
-			//print("#Y%d: Invalid message %s in SlotEmpty state\n",
-			//	(int)(cb - cbslots), messages[message]);
-			break;
-		}
-		break;
-
-	case SlotFull:
-
-		switch (message) {
-		case CardPowered:
-			cb->state = SlotPowered;
-			configure(cb);
-			break;
-		case CardEjected:
-			cb->state = SlotEmpty;
-			powerdown(cb);
-			break;
-		default:
-			//print("#Y%d: Invalid message %s in SlotFull state\n",
-			//	(int)(cb - cbslots), messages[message]);
-			break;
-		}
-		break;
-
-	case SlotPowered:
-
-		switch (message) {
-		case CardConfigured:
-			cb->state = SlotConfigured;
-			break;
-		case CardEjected:
-			cb->state = SlotEmpty;
-			unconfigure(cb);
-			powerdown(cb);
-			break;
-		default:
-			print("#Y%d: Invalid message %s in SlotPowered state\n",
-				(int)(cb - cbslots), messages[message]);
-			break;
-		}
-		break;
-
-	case SlotConfigured:
-
-		switch (message) {
-		case CardEjected:
-			cb->state = SlotEmpty;
-			unconfigure(cb);
-			powerdown(cb);
-			break;
-		default:
-			//print("#Y%d: Invalid message %s in SlotConfigured state\n",
-			//	(int)(cb - cbslots), messages[message]);
-			break;
-		}
-		break;
-	}
-}
-
-void
-devpccardlink(void)
-{
-	static int initialized;
-	Pcidev *pci;
-	int i;
-	char *p;
-
-	if (initialized) 
-		return;
-	initialized = 1;
-
-	if((p=getconf("pccard0")) && strncmp(p, "disabled", 8)==0)
-		return;
-
-	if(_pcmspecial)
-		return;
-
-
-	/* Allocate legacy space */
-	if (ioalloc(LegacyAddr, 2, 0, "i82365.0") < 0)
-		print("#Y: WARNING: Cannot allocate legacy ports\n");
-
-	/* Find all CardBus controllers */
-	pci = nil;
-	while ((pci = pcimatch(pci, 0, 0)) != nil) {
-		ulong baddr;
-		uchar pin;
-		Cardbus *cb;
-		int slot;
-
-		if(pci->ccrb != 6 || pci->ccru != 7)
-			continue;
-		for (i = 0; i != nelem(variant); i++)
-			if (pci->vid == variant[i].vid && pci->did == variant[i].did)
-				break;
-		if (i == nelem(variant))
-			continue;
-
-		/* initialize this slot */
-		slot = nslots++;
-		cb = &cbslots[slot];
-
-		cb->pci = pci;
-		cb->variant = &variant[i];
-
-		// Set up PCI bus numbers if needed.
-		if (pcicfgr8(pci, PciSBN) == 0) {
-			static int busbase = 0x20;
-
-			pcicfgw8(pci, PciSBN, busbase);
-			pcicfgw8(pci, PciUBN, busbase + 2);
-			busbase += 3;
-		}
-
-		// Patch up intl if needed.
-		if ((pin = pcicfgr8(pci, PciINTP)) != 0 && 
-		    (pci->intl == 0xff || pci->intl == 0)) {
-			pci->intl = pciipin(nil, pin);
-			pcicfgw8(pci, PciINTL, pci->intl);
-
-			if (pci->intl == 0xff || pci->intl == 0)
-				print("#Y%d: No interrupt?\n", (int)(cb - cbslots));
-		}
-		
-		// Don't you love standards!
-		if (pci->vid == TI_vid) {
-			if (pci->did <= TI_1131_did) {
-				uchar cc;
-
-				cc = pcicfgr8(pci, TI1131xCC);
-				cc &= ~(TI113X_CC_PCI_IRQ_ENA |
-						TI113X_CC_PCI_IREQ | 
-						TI113X_CC_PCI_CSC |
-						TI113X_CC_ZVENABLE);
-				cc |= TI113X_CC_PCI_IRQ_ENA | 
-						TI113X_CC_PCI_IREQ | 
-						TI113X_CC_SPKROUTEN;
-				pcicfgw8(pci, TI1131xCC, cc);
-
-				// PCI interrupts only
-				pcicfgw8(pci, TI1131xDC, 
-						pcicfgr8(pci, TI1131xDC) & ~6);
-
-				// CSC ints to PCI bus.
-				wrreg(cb, Rigc, rdreg(cb, Rigc) | 0x10);
-			}
-			else if (pci->did == TI_1250_did) {
-				print("No support yet for the TI_1250_did, prod pb\n");
-			}
-			else if (pci->did == TI_1420_did) {
-				// Disable Vcc protection
-				pcicfgw32(cb->pci, 0x80, 
-					pcicfgr32(cb->pci, 0x80) | (1 << 21));
-			}
-			
-			pcicfgw16(cb->pci, PciPMC, pcicfgr16(cb->pci, PciPMC) & ~3);
-		}
-	
-		if ((baddr = pcicfgr32(cb->pci, PciBAR0)) == 0) {
-			int size = (pci->did == Ricoh_478_did)? 0x10000: 0x1000;
-
-			baddr = upamalloc(baddr, size, size);
-			pcicfgw32(cb->pci, PciBAR0, baddr);
-			cb->regs = (ulong *)KADDR(baddr);
-		}
-		else
-			cb->regs = (ulong *)KADDR(upamalloc(baddr, 4096, 0));
-		cb->state = SlotEmpty;
-
-		/* Don't really know what to do with this... */
-		i82365probe(cb, LegacyAddr, LegacyAddr + 1);
-
-		print("#Y%ld: %s, %.8ulX intl %d\n", cb - cbslots, 
-			 variant[i].name, baddr, pci->intl);
-	}
-
-	if (nslots == 0)
-		return;
-
-	_pcmspecial = pccard_pcmspecial;
-	_pcmspecialclose = pccard_pcmspecialclose;
-
-	for (i = 0; i != nslots; i++) {
-		Cardbus *cb = &cbslots[i];
-
-		if ((cb->regs[SocketState] & SE_CCD) == 0)
-			engine(cb, CardDetected);
-	}
-
-	delay(500);			/* Allow time for power up */
-
-	for (i = 0; i != nslots; i++) {
-		Cardbus *cb = &cbslots[i];
-
-		if (cb->regs[SocketState] & SE_POWER)
-			engine(cb, CardPowered);
-
-		/* Ack and enable interrupts on all events */
-		//cb->regs[SocketEvent] = cb->regs[SocketEvent];
-		//cb->regs[SocketMask] |= 0xF;	
-		//wrreg(cb, Rcscic, 0xC);
-	}
-}
-
-static int
-powerup(Cardbus *cb)
-{
-	ulong state;
-	ushort bcr;
-
-	state = cb->regs[SocketState];
-	if (state & SS_PC16) {
-	
-		// print("#Y%ld: Probed a PC16 card, powering up card\n", cb - cbslots);
-		cb->type = PC16;
-		memset(&cb->linfo, 0, sizeof(Pcminfo));
-
-		/* power up and unreset, wait's are empirical (???) */
-		wrreg(cb, Rpc, Fautopower|Foutena|Fcardena);
-		delay(300);
-		wrreg(cb, Rigc, 0);
-		delay(100);
-		wrreg(cb, Rigc, Fnotreset);
-		delay(500);
-
-		return 1;
-	}
-
-	if (state & SS_CCD)
-		return 0;
-
-	if (state & SS_NOTCARD) {
-		print("#Y%ld: No card inserted\n", cb - cbslots);
-		return 0;
-	}
-
-	if (state & SS_BADVCC) {
-		print("#Y%ld: Bad VCC request to card, powering down card!\n", 
-			 cb - cbslots);
-		cb->regs[SocketControl] = 0;
-		return 0;
-	}
-
-	if ((state & SS_3V) == 0 && (state & SS_5V) == 0) {
-		print("#Y%ld: Unsupported voltage, powering down card!\n", 
-			cb - cbslots);
-		cb->regs[SocketControl] = 0;
-		return 0;
-	}
-
-	//print("#Y%ld: card %spowered at %d volt\n", cb - cbslots, 
-	//	(state & SS_POWER)? "": "not ", 
-	//	(state & SS_3V)? 3: (state & SS_5V)? 5: -1);
-
-	/* Power up the card
-	 * and make sure the secondary bus is not in reset.
-	 */
-	cb->regs[SocketControl] = (state & SS_5V)? SC_5V: SC_3V;
-	delay(50);
-	bcr = pcicfgr16(cb->pci, PciBCR);
-	bcr &= ~0x40;
-	pcicfgw16(cb->pci, PciBCR, bcr);
-	delay(100);
-
-	cb->type = PC32;
-
-	return 1;
-}
-
-static void
-powerdown(Cardbus *cb)
-{
-	ushort bcr;
-
-	if (cb->type == PC16) {
-
-		wrreg(cb, Rpc, 0);	/* turn off card power */
-		wrreg(cb, Rwe, 0);	/* no windows */
-
-		cb->type = -1;
-		return;
-	}
-
-	bcr = pcicfgr16(cb->pci, PciBCR);
-	bcr |= 0x40;
-	pcicfgw16(cb->pci, PciBCR, bcr);
-	cb->regs[SocketControl] = 0;
-	cb->type = -1;
-}
-
-static void
-configure(Cardbus *cb)
-{
-	Pcidev *pci;
-	ulong size, bar;
-	int i, ioindex, memindex, r;
-
-	//print("configuring slot %d (%s)\n", (int)(cb - cbslots), states[cb->state]);
-	if (cb->state == SlotConfigured)
-		return;
-	engine(cb, CardConfigured);
-
-	delay(50);					/* Emperically established */
-
-	if (cb->type == PC16) {
-		i82365configure(cb);
-		return;
-	}
-
-	/* Scan the CardBus for new PCI devices */
-	pciscan(pcicfgr8(cb->pci, PciSBN), &cb->pci->bridge);
-	pci = cb->pci->bridge;
-	while (pci) {
-		r = pcicfgr16(pci, PciPCR);
-		r &= ~(PciPCR_IO|PciPCR_MEM);
-		pcicfgw16(pci, PciPCR, r);
-
-		/*
-		 * Treat the found device as an ordinary PCI card.
-		 * It seems that the CIS is not always present in
-		 * CardBus cards.
-		 * XXX, need to support multifunction cards
-		 */
-		memindex = ioindex = 0;
-		for (i = 0; i != Nbars; i++) {
-
-			if (pci->mem[i].size == 0)
-				continue;
-			if (pci->mem[i].bar & 1) {
-
-				// Allocate I/O space
-				if (ioindex > 1) {
-					print("#Y%ld: WARNING: Can only configure 2 I/O slots\n", cb - cbslots);
-					continue;
-				}
-				bar = ioreserve(-1, pci->mem[i].size, 0, "cardbus");
-				pci->mem[i].bar = bar | 1;
-				pcicfgw32(pci, PciBAR0 + i * sizeof(ulong), 
-					          pci->mem[i].bar);
-				pcicfgw16(cb->pci, PciCBIBR0 + ioindex * 8, bar);
-				pcicfgw16(cb->pci, PciCBILR0 + ioindex * 8, 
-						 bar + pci->mem[i].size - 1);
-				//print("ioindex[%d] %.8uX (%d)\n", 
-				//	ioindex, bar, pci->mem[i].size);
-				ioindex++;
-				continue;
-			}
-
-			// Allocating memory space
-			if (memindex > 1) {
-				print("#Y%ld: WARNING: Can only configure 2 memory slots\n", cb - cbslots);
-				continue;
-			}
-
-			bar = upamalloc(0, pci->mem[i].size, BY2PG);
-			pci->mem[i].bar = bar | (pci->mem[i].bar & 0x80);
-			pcicfgw32(pci, PciBAR0 + i * sizeof(ulong), pci->mem[i].bar);
-			pcicfgw32(cb->pci, PciCBMBR0 + memindex * 8, bar);
-			pcicfgw32(cb->pci, PciCBMLR0 + memindex * 8, 
-					  bar + pci->mem[i].size - 1);
-
-			if (pci->mem[i].bar & 0x80) {
-				/* Enable prefetch */
-				r = pcicfgr16(cb->pci, PciBCR);
-				r |= 1 << (8 + memindex);
-				pcicfgw16(cb->pci, PciBCR, r);
-			}
-
-			//print("memindex[%d] %.8uX (%d)\n", 
-			//	  memindex, bar, pci->mem[i].size);
-			memindex++;
-		}
-
-		if ((size = pcibarsize(pci, PciEBAR0)) > 0) {
-
-			if (memindex > 1)
-				print("#Y%ld: WARNING: Too many memory spaces, not mapping ROM space\n",
-					cb - cbslots);
-			else {
-				pci->rom.bar = upamalloc(0, size, BY2PG);
-				pci->rom.size = size;
-
-				pcicfgw32(pci, PciEBAR0, pci->rom.bar);
-				pcicfgw32(cb->pci, PciCBMBR0 + memindex * 8,
-						 pci->rom.bar);
-				pcicfgw32(cb->pci, PciCBMLR0 + memindex * 8, 
-						 pci->rom.bar + pci->rom.size - 1);
-			}
-		}
-
-		/* Set the basic PCI registers for the device */
-		pci->pcr = pcicfgr16(pci, PciPCR);
-		pci->pcr |= PciPCR_IO|PciPCR_MEM|PciPCR_Master;
-		pci->cls = 8;
-		pci->ltr = 64;
-		pcicfgw16(pci, PciPCR, pci->pcr);
-		pcicfgw8(pci, PciCLS, pci->cls);
-		pcicfgw8(pci, PciLTR, pci->ltr);
-
-		if (pcicfgr8(pci, PciINTP)) {
-			pci->intl = pcicfgr8(cb->pci, PciINTL);
-			pcicfgw8(pci, PciINTL, pci->intl);
-
-			/* Route interrupts to INTA#/B# */
-			pcicfgw16(cb->pci, PciBCR, 
-					  pcicfgr16(cb->pci, PciBCR) & ~(1 << 7));
-		}
-			
-		pci = pci->list;
-	}
-}
-
-static void
-unconfigure(Cardbus *cb)
-{
-	Pcidev *pci;
-	int i, ioindex, memindex, r;
-
-	if (cb->type == PC16) {
-		print("#Y%d: Don't know how to unconfigure a PC16 card\n",
-			 (int)(cb - cbslots));
-
-		memset(&cb->linfo, 0, sizeof(Pcminfo));
-		return;
-	}
-
-	pci = cb->pci->bridge;
-	if (pci == nil) 
-		return;		/* Not configured */
-	cb->pci->bridge = nil;		
-
-	memindex = ioindex = 0;
-	while (pci) {
-		Pcidev *_pci;
-
-		for (i = 0; i != Nbars; i++) {
-			if (pci->mem[i].size == 0)
-				continue;
-			if (pci->mem[i].bar & 1) {
-				iofree(pci->mem[i].bar & ~1);
-				pcicfgw16(cb->pci, PciCBIBR0 + ioindex * 8, 
-						 (ushort)-1);
-				pcicfgw16(cb->pci, PciCBILR0 + ioindex * 8, 0);
-				ioindex++;
-				continue;
-			}
-
-			upafree(pci->mem[i].bar & ~0xF, pci->mem[i].size);
-			pcicfgw32(cb->pci, PciCBMBR0 + memindex * 8, (ulong)-1);
-			pcicfgw32(cb->pci, PciCBMLR0 + memindex * 8, 0);
-			r = pcicfgr16(cb->pci, PciBCR);
-			r &= ~(1 << (8 + memindex));
-			pcicfgw16(cb->pci, PciBCR, r);
-			memindex++;
-		}
-
-		if (pci->rom.bar && memindex < 2) {
-			upafree(pci->rom.bar & ~0xF, pci->rom.size);
-			pcicfgw32(cb->pci, PciCBMBR0 + memindex * 8, (ulong)-1);
-			pcicfgw32(cb->pci, PciCBMLR0 + memindex * 8, 0);
-			memindex++;
-		}
-
-		_pci = pci->list;
-		free(_pci);
-		pci = _pci;
-	}
-}
-
-static void
-i82365configure(Cardbus *cb)
-{
-	int this;
-	Cisdat cis;
-	PCMmap *m;
-	uchar type, link;
-
-	/*
-	 * Read all tuples in attribute space.
-	 */
-	m = isamap(cb, 0, 0, 1);
-	if(m == 0)
-		return;
-
-	cis.cisbase = KADDR(m->isa);
-	cis.cispos = 0;
-	cis.cisskip = 2;
-	cis.cislen = m->len;
-
-	/* loop through all the tuples */
-	for(;;){
-		this = cis.cispos;
-		if(readc(&cis, &type) != 1)
-			break;
-		if(type == 0xFF)
-			break;
-		if(readc(&cis, &link) != 1)
-			break;
-
-		switch(type){
-		default:
-			break;
-		case 0x15:
-			tvers1(cb, &cis, type);
-			break;
-		case 0x1A:
-			tcfig(cb, &cis, type);
-			break;
-		case 0x1B:
-			tentry(cb, &cis, type);
-			break;
-		}
-
-		if(link == 0xFF)
-			break;
-		cis.cispos = this + (2+link);
-	}
-	isaunmap(m);
-}
-
-/*
- *  look for a card whose version contains 'idstr'
- */
-static int
-pccard_pcmspecial(char *idstr, ISAConf *isa)
-{
-	int i, irq;
-	PCMconftab *ct, *et;
-	Pcminfo *pi;
-	Cardbus *cb;
-	uchar x, we, *p;
-
-	cb = nil;
-	for (i = 0; i != nslots; i++) {
-		cb = &cbslots[i];
-
-		lock(cb);
-		if (cb->state == SlotConfigured &&
-		    cb->type == PC16 && 
-		    !cb->special &&
-		    strstr(cb->linfo.verstr, idstr)) 
-			break;
-		unlock(cb);
-	}
-
-	if (i == nslots) {
-		// print("#Y: %s not found\n", idstr);
-		return -1;
-	}
-
-	pi = &cb->linfo;
-
-	/*
- 	  *  configure the PCMslot for IO.  We assume very heavily that we can read
- 	  *  configuration info from the CIS.  If not, we won't set up correctly.
- 	  */
-	irq = isa->irq;
-	if(irq == 2)
-		irq = 9;
-
-	et = &pi->ctab[pi->nctab];
-	ct = nil;
-	for(i = 0; i < isa->nopt; i++){
-		int index;
-		char *cp;
-
-		if(strncmp(isa->opt[i], "index=", 6))
-			continue;
-		index = strtol(&isa->opt[i][6], &cp, 0);
-		if(cp == &isa->opt[i][6] || index >= pi->nctab) {
-			unlock(cb);
-			print("#Y%d: Cannot find index %d in conf table\n", 
-				 (int)(cb - cbslots), index);
-			return -1;
-		}
-		ct = &pi->ctab[index];
-	}
-
-	if(ct == nil){
-		PCMconftab *t;
-
-		/* assume default is right */
-		if(pi->defctab)
-			ct = pi->defctab;
-		else
-			ct = pi->ctab;
-	
-		/* try for best match */
-		if(ct->nio == 0
-		|| ct->io[0].start != isa->port || ((1<<irq) & ct->irqs) == 0){
-			for(t = pi->ctab; t < et; t++)
-				if(t->nio
-				&& t->io[0].start == isa->port
-				&& ((1<<irq) & t->irqs)){
-					ct = t;
-					break;
-				}
-		}
-		if(ct->nio == 0 || ((1<<irq) & ct->irqs) == 0){
-			for(t = pi->ctab; t < et; t++)
-				if(t->nio && ((1<<irq) & t->irqs)){
-					ct = t;
-					break;
-				}
-		}
-		if(ct->nio == 0){
-			for(t = pi->ctab; t < et; t++)
-				if(t->nio){
-					ct = t;
-					break;
-				}
-		}
-	}
-
-	if(ct == et || ct->nio == 0) {
-		unlock(cb);
-		print("#Y%d: No configuration?\n", (int)(cb - cbslots));
-		return -1;
-	}
-	if(isa->port == 0 && ct->io[0].start == 0) {
-		unlock(cb);
-		print("#Y%d: No part or start address\n", (int)(cb - cbslots));
-		return -1;
-	}
-
-	cb->special = 1;	/* taken */
-
-	/* route interrupts */
-	isa->irq = irq;
-	wrreg(cb, Rigc, irq | Fnotreset | Fiocard);
-
-	/* set power and enable device */
-	x = vcode(ct->vpp1);
-	wrreg(cb, Rpc, x|Fautopower|Foutena|Fcardena);
-
-	/* 16-bit data path */
-	if(ct->bit16)
-		x = Ftiming|Fiocs16|Fwidth16;
-	else
-		x = Ftiming;
-	if(ct->nio == 2 && ct->io[1].start)
-		x |= x<<4;
-	wrreg(cb, Rio, x);
-
-	/*
-	 * enable io port map 0
-	 * the 'top' register value includes the last valid address
-	 */
-	if(isa->port == 0)
-		isa->port = ct->io[0].start;
-	we = rdreg(cb, Rwe);
-	wrreg(cb, Riobtm0lo, isa->port);
-	wrreg(cb, Riobtm0hi, isa->port>>8);
-	i = isa->port+ct->io[0].len-1;
-	wrreg(cb, Riotop0lo, i);
-	wrreg(cb, Riotop0hi, i>>8);
-	we |= 1<<6;
-	if(ct->nio == 2 && ct->io[1].start){
-		wrreg(cb, Riobtm1lo, ct->io[1].start);
-		wrreg(cb, Riobtm1hi, ct->io[1].start>>8);
-		i = ct->io[1].start+ct->io[1].len-1;
-		wrreg(cb, Riotop1lo, i);
-		wrreg(cb, Riotop1hi, i>>8);
-		we |= 1<<7;
-	}
-	wrreg(cb, Rwe, we);
-
-	/* only touch Rconfig if it is present */
-	if(pi->conf_present & (1<<Rconfig)){
-		PCMmap *m;
-
-		/*  Reset adapter */
-		m = isamap(cb, pi->conf_addr + Rconfig, 1, 1);
-		p = KADDR(m->isa + pi->conf_addr + Rconfig - m->ca);
-
-		/* set configuration and interrupt type */
-		x = ct->index;
-		if((ct->irqtype & 0x20)/* && ((ct->irqtype & 0x40)==0 || isa->irq>7)*/)
-			x |= Clevel;
-		*p = x;
-		delay(5);
-
-		isaunmap(m);
-	}
-
-	pi->port = isa->port;
-	pi->irq = isa->irq;
-	unlock(cb);
-
-	print("#Y%d: %s irq %ld, port %lX\n", (int)(cb - cbslots), pi->verstr, isa->irq, isa->port);
-	return (int)(cb - cbslots);
-}
-
-static void
-pccard_pcmspecialclose(int slotno)
-{
-	Cardbus *cb = &cbslots[slotno];
-
-	wrreg(cb, Rwe, 0);	/* no windows */
-	cb->special = 0;
-}
-
-static int
-xcistuple(int slotno, int tuple, int subtuple, void *v, int nv, int attr)
-{
-	PCMmap *m;
-	Cisdat cis;
-	int i, l;
-	uchar *p;
-	uchar type, link, n, c;
-	int this, subtype;
-	Cardbus *cb = &cbslots[slotno];
-
-	m = isamap(cb, 0, 0, attr);
-	if(m == 0)
-		return -1;
-
-	cis.cisbase = KADDR(m->isa);
-	cis.cispos = 0;
-	cis.cisskip = attr ? 2 : 1;
-	cis.cislen = m->len;
-
-	/* loop through all the tuples */
-	for(i = 0; i < 1000; i++){
-		this = cis.cispos;
-		if(readc(&cis, &type) != 1)
-			break;
-		if(type == 0xFF)
-			break;
-		if(readc(&cis, &link) != 1)
-			break;
-		if(link == 0xFF)
-			break;
-
-		n = link;
-		if (link > 1 && subtuple != -1) {
-			if (readc(&cis, &c) != 1)
-				break;
-			subtype = c;
-			n--;
-		} else
-			subtype = -1;
-
-		if(type == tuple && subtype == subtuple) {
-			p = v;
-			for(l=0; l<nv && l<n; l++)
-				if(readc(&cis, p++) != 1)
-					break;
-			isaunmap(m);
-			return nv;
-		}
-		cis.cispos = this + (2+link);
-	}
-	isaunmap(m);
-	return -1;
-}
-
-static PCMmap *
-isamap(Cardbus *cb, ulong offset, int len, int attr)
-{
-	uchar we, bit;
-	PCMmap *m, *nm;
-	Pcminfo *pi;
-	int i;
-	ulong e;
-
-	pi = &cb->linfo;
-
-	/* convert offset to granularity */
-	if(len <= 0)
-		len = 1;
-	e = ROUND(offset+len, Mgran);
-	offset &= Mmask;
-	len = e - offset;
-
-	/* look for a map that covers the right area */
-	we = rdreg(cb, Rwe);
-	bit = 1;
-	nm = 0;
-	for(m = pi->mmap; m < &pi->mmap[nelem(pi->mmap)]; m++){
-		if((we & bit))
-		if(m->attr == attr)
-		if(offset >= m->ca && e <= m->cea){
-
-			m->ref++;
-			return m;
-		}
-		bit <<= 1;
-		if(nm == 0 && m->ref == 0)
-			nm = m;
-	}
-	m = nm;
-	if(m == 0)
-		return 0;
-
-	/* if isa space isn't big enough, free it and get more */
-	if(m->len < len){
-		if(m->isa){
-			umbfree(m->isa, m->len);
-			m->len = 0;
-		}
-		m->isa = PADDR(umbmalloc(0, len, Mgran));
-		if(m->isa == 0){
-			print("isamap: out of isa space\n");
-			return 0;
-		}
-		m->len = len;
-	}
-
-	/* set up new map */
-	m->ca = offset;
-	m->cea = m->ca + m->len;
-	m->attr = attr;
-	i = m - pi->mmap;
-	bit = 1<<i;
-	wrreg(cb, Rwe, we & ~bit);		/* disable map before changing it */
-	wrreg(cb, MAP(i, Mbtmlo), m->isa>>Mshift);
-	wrreg(cb, MAP(i, Mbtmhi), (m->isa>>(Mshift+8)) | F16bit);
-	wrreg(cb, MAP(i, Mtoplo), (m->isa+m->len-1)>>Mshift);
-	wrreg(cb, MAP(i, Mtophi), ((m->isa+m->len-1)>>(Mshift+8)));
-	offset -= m->isa;
-	offset &= (1<<25)-1;
-	offset >>= Mshift;
-	wrreg(cb, MAP(i, Mofflo), offset);
-	wrreg(cb, MAP(i, Moffhi), (offset>>8) | (attr ? Fregactive : 0));
-	wrreg(cb, Rwe, we | bit);		/* enable map */
-	m->ref = 1;
-
-	return m;
-}
-
-static void
-isaunmap(PCMmap* m)
-{
-	m->ref--;
-}
-
-/*
- *  reading and writing card registers
- */
-static uchar
-rdreg(Cardbus *cb, int index)
-{
-	outb(cb->lindex, cb->lbase + index);
-	return inb(cb->ldata);
-}
-
-static void
-wrreg(Cardbus *cb, int index, uchar val)
-{
-	outb(cb->lindex, cb->lbase + index);
-	outb(cb->ldata, val);
-}
-
-static int
-readc(Cisdat *cis, uchar *x)
-{
-	if(cis->cispos >= cis->cislen)
-		return 0;
-	*x = cis->cisbase[cis->cisskip*cis->cispos];
-	cis->cispos++;
-	return 1;
-}
-
-static ulong
-getlong(Cisdat *cis, int size)
-{
-	uchar c;
-	int i;
-	ulong x;
-
-	x = 0;
-	for(i = 0; i < size; i++){
-		if(readc(cis, &c) != 1)
-			break;
-		x |= c<<(i*8);
-	}
-	return x;
-}
-
-static void
-tcfig(Cardbus *cb, Cisdat *cis, int )
-{
-	uchar size, rasize, rmsize;
-	uchar last;
-	Pcminfo *pi;
-
-	if(readc(cis, &size) != 1)
-		return;
-	rasize = (size&0x3) + 1;
-	rmsize = ((size>>2)&0xf) + 1;
-	if(readc(cis, &last) != 1)
-		return;
-
-	pi = &cb->linfo;
-	pi->conf_addr = getlong(cis, rasize);
-	pi->conf_present = getlong(cis, rmsize);
-}
-
-static void
-tvers1(Cardbus *cb, Cisdat *cis, int )
-{
-	uchar c, major, minor, last;
-	int  i;
-	Pcminfo *pi;
-
-	pi = &cb->linfo;
-	if(readc(cis, &major) != 1)
-		return;
-	if(readc(cis, &minor) != 1)
-		return;
-	last = 0;
-	for(i = 0; i < sizeof(pi->verstr) - 1; i++){
-		if(readc(cis, &c) != 1)
-			return;
-		if(c == 0)
-			c = ';';
-		if(c == '\n')
-			c = ';';
-		if(c == 0xff)
-			break;
-		if(c == ';' && last == ';')
-			continue;
-		pi->verstr[i] = c;
-		last = c;
-	}
-	pi->verstr[i] = 0;
-}
-
-static ulong
-microvolt(Cisdat *cis)
-{
-	uchar c;
-	ulong microvolts;
-	ulong exp;
-
-	if(readc(cis, &c) != 1)
-		return 0;
-	exp = exponent[c&0x7];
-	microvolts = vmant[(c>>3)&0xf]*exp;
-	while(c & 0x80){
-		if(readc(cis, &c) != 1)
-			return 0;
-		switch(c){
-		case 0x7d:
-			break;		/* high impedence when sleeping */
-		case 0x7e:
-		case 0x7f:
-			microvolts = 0;	/* no connection */
-			break;
-		default:
-			exp /= 10;
-			microvolts += exp*(c&0x7f);
-		}
-	}
-	return microvolts;
-}
-
-static ulong
-nanoamps(Cisdat *cis)
-{
-	uchar c;
-	ulong nanoamps;
-
-	if(readc(cis, &c) != 1)
-		return 0;
-	nanoamps = exponent[c&0x7]*vmant[(c>>3)&0xf];
-	while(c & 0x80){
-		if(readc(cis, &c) != 1)
-			return 0;
-		if(c == 0x7d || c == 0x7e || c == 0x7f)
-			nanoamps = 0;
-	}
-	return nanoamps;
-}
-
-/*
- * only nominal voltage (feature 1) is important for config,
- * other features must read card to stay in sync.
- */
-static ulong
-power(Cisdat *cis)
-{
-	uchar feature;
-	ulong mv;
-
-	mv = 0;
-	if(readc(cis, &feature) != 1)
-		return 0;
-	if(feature & 1)
-		mv = microvolt(cis);
-	if(feature & 2)
-		microvolt(cis);
-	if(feature & 4)
-		microvolt(cis);
-	if(feature & 8)
-		nanoamps(cis);
-	if(feature & 0x10)
-		nanoamps(cis);
-	if(feature & 0x20)
-		nanoamps(cis);
-	if(feature & 0x40)
-		nanoamps(cis);
-	return mv/1000000;
-}
-
-static ulong
-ttiming(Cisdat *cis, int scale)
-{
-	uchar unscaled;
-	ulong nanosecs;
-
-	if(readc(cis, &unscaled) != 1)
-		return 0;
-	nanosecs = (mantissa[(unscaled>>3)&0xf]*exponent[unscaled&7])/10;
-	nanosecs = nanosecs * exponent[scale];
-	return nanosecs;
-}
-
-static void
-timing(Cisdat *cis, PCMconftab *ct)
-{
-	uchar c, i;
-
-	if(readc(cis, &c) != 1)
-		return;
-	i = c&0x3;
-	if(i != 3)
-		ct->maxwait = ttiming(cis, i);		/* max wait */
-	i = (c>>2)&0x7;
-	if(i != 7)
-		ct->readywait = ttiming(cis, i);	/* max ready/busy wait */
-	i = (c>>5)&0x7;
-	if(i != 7)
-		ct->otherwait = ttiming(cis, i);	/* reserved wait */
-}
-
-static void
-iospaces(Cisdat *cis, PCMconftab *ct)
-{
-	uchar c;
-	int i, nio;
-
-	ct->nio = 0;
-	if(readc(cis, &c) != 1)
-		return;
-
-	ct->bit16 = ((c>>5)&3) >= 2;
-	if(!(c & 0x80)){
-		ct->io[0].start = 0;
-		ct->io[0].len = 1<<(c&0x1f);
-		ct->nio = 1;
-		return;
-	}
-
-	if(readc(cis, &c) != 1)
-		return;
-
-	/*
-	 * For each of the range descriptions read the
-	 * start address and the length (value is length-1).
-	 */
-	nio = (c&0xf)+1;
-	for(i = 0; i < nio; i++){
-		ct->io[i].start = getlong(cis, (c>>4)&0x3);
-		ct->io[i].len = getlong(cis, (c>>6)&0x3)+1;
-	}
-	ct->nio = nio;
-}
-
-static void
-irq(Cisdat *cis, PCMconftab *ct)
-{
-	uchar c;
-
-	if(readc(cis, &c) != 1)
-		return;
-	ct->irqtype = c & 0xe0;
-	if(c & 0x10)
-		ct->irqs = getlong(cis, 2);
-	else
-		ct->irqs = 1<<(c&0xf);
-	ct->irqs &= 0xDEB8;		/* levels available to card */
-}
-
-static void
-memspace(Cisdat *cis, int asize, int lsize, int host)
-{
-	ulong haddress, address, len;
-
-	len = getlong(cis, lsize)*256;
-	address = getlong(cis, asize)*256;
-	USED(len, address);
-	if(host){
-		haddress = getlong(cis, asize)*256;
-		USED(haddress);
-	}
-}
-
-static void
-tentry(Cardbus *cb, Cisdat *cis, int )
-{
-	uchar c, i, feature;
-	PCMconftab *ct;
-	Pcminfo *pi;
-
-	pi = &cb->linfo;
-	if(pi->nctab >= nelem(pi->ctab))
-		return;
-	if(readc(cis, &c) != 1)
-		return;
-	ct = &pi->ctab[pi->nctab++];
-
-	/* copy from last default config */
-	if(pi->defctab)
-		*ct = *pi->defctab;
-
-	ct->index = c & 0x3f;
-
-	/* is this the new default? */
-	if(c & 0x40)
-		pi->defctab = ct;
-
-	/* memory wait specified? */
-	if(c & 0x80){
-		if(readc(cis, &i) != 1)
-			return;
-		if(i&0x80)
-			ct->memwait = 1;
-	}
-
-	if(readc(cis, &feature) != 1)
-		return;
-	switch(feature&0x3){
-	case 1:
-		ct->vpp1 = ct->vpp2 = power(cis);
-		break;
-	case 2:
-		power(cis);
-		ct->vpp1 = ct->vpp2 = power(cis);
-		break;
-	case 3:
-		power(cis);
-		ct->vpp1 = power(cis);
-		ct->vpp2 = power(cis);
-		break;
-	default:
-		break;
-	}
-	if(feature&0x4)
-		timing(cis, ct);
-	if(feature&0x8)
-		iospaces(cis, ct);
-	if(feature&0x10)
-		irq(cis, ct);
-	switch((feature>>5)&0x3){
-	case 1:
-		memspace(cis, 0, 2, 0);
-		break;
-	case 2:
-		memspace(cis, 2, 2, 0);
-		break;
-	case 3:
-		if(readc(cis, &c) != 1)
-			return;
-		for(i = 0; i <= (c&0x7); i++)
-			memspace(cis, (c>>5)&0x3, (c>>3)&0x3, c&0x80);
-		break;
-	}
-}
-
-static void
-i82365probe(Cardbus *cb, int lindex, int ldata)
-{
-	uchar c, id;
-	int dev = 0;	/* According to the Ricoh spec 00->3F _and_ 80->BF seem
-				     to be the same socket A (ditto for B). */
-
-	outb(lindex, Rid + (dev<<7));
-	id = inb(ldata);
-	if((id & 0xf0) != 0x80)
-		return;		/* not a memory & I/O card */
-	if((id & 0x0f) == 0x00)
-		return;		/* no revision number, not possible */
-
-	cb->lindex = lindex;
-	cb->ldata = ldata;
-	cb->ltype = Ti82365;
-	cb->lbase = (int)(cb - cbslots) * 0x40;
-
-	switch(id){
-	case 0x82:
-	case 0x83:
-	case 0x84:
-		/* could be a cirrus */
-		outb(cb->lindex, Rchipinfo + (dev<<7));
-		outb(cb->ldata, 0);
-		c = inb(cb->ldata);
-		if((c & 0xc0) != 0xc0)
-			break;
-		c = inb(cb->ldata);
-		if((c & 0xc0) != 0x00)
-			break;
-		if(c & 0x20){
-			cb->ltype = Tpd6720;
-		} else {
-			cb->ltype = Tpd6710;
-		}
-		break;
-	}
-
-	/* if it's not a Cirrus, it could be a Vadem... */
-	if(cb->ltype == Ti82365){
-		/* unlock the Vadem extended regs */
-		outb(cb->lindex, 0x0E + (dev<<7));
-		outb(cb->lindex, 0x37 + (dev<<7));
-
-		/* make the id register show the Vadem id */
-		outb(cb->lindex, 0x3A + (dev<<7));
-		c = inb(cb->ldata);
-		outb(cb->ldata, c|0xC0);
-		outb(cb->lindex, Rid + (dev<<7));
-		c = inb(cb->ldata);
-		if(c & 0x08)
-			cb->ltype = Tvg46x;
-
-		/* go back to Intel compatible id */
-		outb(cb->lindex, 0x3A + (dev<<7));
-		c = inb(cb->ldata);
-		outb(cb->ldata, c & ~0xC0);
-	}
-}
-
-static int
-vcode(int volt)
-{
-	switch(volt){
-	case 5:
-		return 1;
-	case 12:
-		return 2;
-	default:
-		return 0;
-	}
-}
--- a/os/boot/pc/devsd.c
+++ /dev/null
@@ -1,631 +1,0 @@
-/*
- * Storage Device.
- */
-#include "u.h"
-#include "mem.h"
-#include "lib.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "ureg.h"
-#include "error.h"
-
-#include "sd.h"
-#include "fs.h"
-
-#define parttrace 0
-
-
-extern SDifc* sdifc[];
-
-static SDev* sdlist;
-static SDunit** sdunit;
-static int sdnunit;
-static int _sdmask;
-static int cdmask;
-static int sdmask;
-
-enum {
-	Rawcmd,
-	Rawdata,
-	Rawstatus,
-};
-
-void
-sdaddpart(SDunit* unit, char* name, uvlong start, uvlong end)
-{
-	SDpart *pp;
-	int i, partno;
-
-	if(parttrace)
-		print("add %d %s %s %lld %lld\n", unit->npart, unit->name, name, start, end);
-	/*
-	 * Check name not already used
-	 * and look for a free slot.
-	 */
-	if(unit->part != nil){
-		partno = -1;
-		for(i = 0; i < SDnpart; i++){
-			pp = &unit->part[i];
-			if(!pp->valid){
-				if(partno == -1)
-					partno = i;
-				break;
-			}
-			if(strcmp(name, pp->name) == 0){
-				if(pp->start == start && pp->end == end){
-					if(parttrace)
-						print("already present\n");
-					return;
-				}
-			}
-		}
-	}else{
-		if((unit->part = malloc(sizeof(SDpart)*SDnpart)) == nil){
-			if(parttrace)
-				print("malloc failed\n");
-			return;
-		}
-		partno = 0;
-	}
-
-	/*
-	 * Check there is a free slot and size and extent are valid.
-	 */
-	if(partno == -1 || start > end || end > unit->sectors){
-		print("cannot add %s!%s [%llud,%llud) to disk [0,%llud): %s\n",
-			unit->name, name, start, end, unit->sectors, 
-			partno==-1 ? "no free partitions" : "partition boundaries out of range");
-		return;
-	}
-	pp = &unit->part[partno];
-	pp->start = start;
-	pp->end = end;
-	strncpy(pp->name, name, NAMELEN);
-	pp->valid = 1;
-	unit->npart++;
-}
-
-void
-sddelpart(SDunit* unit,  char* name)
-{
-	int i;
-	SDpart *pp;
-
-	if(parttrace)
-		print("del %d %s %s\n", unit->npart, unit->name, name);
-	/*
-	 * Look for the partition to delete.
-	 * Can't delete if someone still has it open.
-	 * If it's the last valid partition zap the
-	 * whole table.
-	 */
-	pp = unit->part;
-	for(i = 0; i < SDnpart; i++){
-		if(strncmp(name, pp->name, NAMELEN) == 0)
-			break;
-		pp++;
-	}
-	if(i >= SDnpart)
-		return;
-	pp->valid = 0;
-
-	unit->npart--;
-	if(unit->npart == 0){
-		free(unit->part);
-		unit->part = nil;
-	}
-}
-
-static int
-sdinitpart(SDunit* unit)
-{
-	unit->sectors = unit->secsize = 0;
-	unit->npart = 0;
-	if(unit->part){
-		free(unit->part);
-		unit->part = nil;
-	}
-
-	if(unit->inquiry[0] & 0xC0)
-		return 0;
-	switch(unit->inquiry[0] & 0x1F){
-	case 0x00:			/* DA */
-	case 0x04:			/* WORM */
-	case 0x05:			/* CD-ROM */
-	case 0x07:			/* MO */
-		break;
-	default:
-		return 0;
-	}
-
-	if(unit->dev->ifc->online == nil || unit->dev->ifc->online(unit) == 0)
-		return 0;
-	sdaddpart(unit, "data", 0, unit->sectors);
-	return 1;
-}
-
-static SDunit*
-sdgetunit(SDev* sdev, int subno)
-{
-	int index;
-	SDunit *unit;
-
-	/*
-	 * Associate a unit with a given device and sub-unit
-	 * number on that device.
-	 * The device will be probed if it has not already been
-	 * successfully accessed.
-	 */
-	qlock(&sdqlock);
-	index = sdev->index+subno;
-	unit = sdunit[index];
-	if(unit == nil){
-		if((unit = malloc(sizeof(SDunit))) == nil){
-			qunlock(&sdqlock);
-			return nil;
-		}
-
-		if(sdev->enabled == 0 && sdev->ifc->enable)
-			sdev->ifc->enable(sdev);
-		sdev->enabled = 1;
-
-		snprint(unit->name, NAMELEN, "sd%c%d", sdev->idno, subno);
-		unit->subno = subno;
-		unit->dev = sdev;
-
-		/*
-		 * No need to lock anything here as this is only
-		 * called before the unit is made available in the
-		 * sdunit[] array.
-		 */
-		if(unit->dev->ifc->verify(unit) == 0){
-			qunlock(&sdqlock);
-			free(unit);
-			return nil;
-		}
-		sdunit[index] = unit;
-	}
-	qunlock(&sdqlock);
-
-	return unit;
-}
-
-static SDunit*
-sdindex2unit(int index)
-{
-	SDev *sdev;
-
-	/*
-	 * Associate a unit with a given index into the top-level
-	 * device directory.
-	 * The device will be probed if it has not already been
-	 * successfully accessed.
-	 */
-	for(sdev = sdlist; sdev != nil; sdev = sdev->next){
-		if(index >= sdev->index && index < sdev->index+sdev->nunit)
-			return sdgetunit(sdev, index-sdev->index);
-	}
-
-	return nil;
-}
-
-static void
-_sddetach(void)
-{
-	SDev *sdev;
-
-	for(sdev = sdlist; sdev != nil; sdev = sdev->next){
-		if(sdev->enabled == 0)
-			continue;
-		if(sdev->ifc->disable)
-			sdev->ifc->disable(sdev);
-		sdev->enabled = 0;
-	}
-}
-
-static void
-sddump(void)
-{
-	SDev *sdev;
-
-	print("sdevs:\n");
-	for(sdev = sdlist; sdev != nil; sdev = sdev->next){
-		print("sdev %c index %d nunit %d: ",
-			sdev->idno, sdev->index, sdev->nunit);
-		print("\n");
-	}
-}
-
-static int
-_sdinit(void)
-{
-	ulong m;
-	int i;
-	SDev *sdev, *tail;
-	SDunit *unit;
-
-	/*
-	 * Probe all configured controllers and make a list
-	 * of devices found, accumulating a possible maximum number
-	 * of units attached and marking each device with an index
-	 * into the linear top-level directory array of units.
-	 */
-	tail = nil;
-	for(i = 0; sdifc[i] != nil; i++){
-		if((sdev = sdifc[i]->pnp()) == nil)
-			continue;
-		if(sdlist != nil)
-			tail->next = sdev;
-		else
-			sdlist = sdev;
-		for(tail = sdev; tail->next != nil; tail = tail->next){
-			tail->index = sdnunit;
-			sdnunit += tail->nunit;
-		}
-		tail->index = sdnunit;
-		sdnunit += tail->nunit;
-	}
-	/*
-	 * Legacy and option code goes here. This will be hard...
-	 */
-
-	/*
-	 * The maximum number of possible units is known, allocate
-	 * placeholders for their datastructures; the units will be
-	 * probed and structures allocated when attached.
-	 * Allocate controller names for the different types.
-	 */
-	if(sdnunit == 0)
-		return 0;
-	if((sdunit = malloc(sdnunit*sizeof(SDunit*))) == nil)
-		return 0;
-	sddetach = _sddetach;
-
-	for(i = 0; sdifc[i] != nil; i++){
-		if(sdifc[i]->id)
-			sdifc[i]->id(sdlist);
-	}
-	if (0)
-		sddump();
-
-	m = 0;
-	cdmask = sdmask = 0;
-	for(i=0; i<sdnunit && i < 32; i++) {
-		unit = sdindex2unit(i);
-		if(unit == nil)
-			continue;
-		sdinitpart(unit);
-		partition(unit);
-		if(unit->npart > 0){	/* BUG */
-			if((unit->inquiry[0] & 0x1F) == 0x05)
-				cdmask |= (1<<i);
-			else
-				sdmask |= (1<<i);
-			m |= (1<<i);
-		}
-	}
-
-//notesdinfo();
-	_sdmask = m;
-	return m;
-}
-
-int
-cdinit(void)
-{
-	if(sdnunit == 0)
-		_sdinit();
-	return cdmask;
-}
-
-int
-sdinit(void)
-{
-	if(sdnunit == 0)
-		_sdinit();
-	return sdmask;
-}
-
-void
-sdinitdev(int i, char *s)
-{
-	SDunit *unit;
-
-	unit = sdindex2unit(i);
-	strcpy(s, unit->name);
-}
-
-void
-sdprintdevs(int i)
-{
-	char *s;
-	SDunit *unit;
-
-	unit = sdindex2unit(i);
-	for(i=0; i<unit->npart; i++){
-		s = unit->part[i].name;
-		if(strncmp(s, "dos", 3) == 0
-		|| strncmp(s, "9fat", 4) == 0
-		|| strncmp(s, "fs", 2) == 0)
-			print(" %s!%s", unit->name, s);
-	}
-}
-
-SDpart*
-sdfindpart(SDunit *unit, char *name)
-{
-	int i;
-
-	if(parttrace)
-		print("findpart %d %s %s\t\n", unit->npart, unit->name, name);
-	for(i=0; i<unit->npart; i++) {
-		if(parttrace)
-			print("%s...", unit->part[i].name);
-		if(strcmp(unit->part[i].name, name) == 0){
-			if(parttrace)
-				print("\n");
-			return &unit->part[i];
-		}
-	}
-	if(parttrace)
-		print("not found\n");
-	return nil;
-}
-
-typedef struct Scsicrud Scsicrud;
-struct Scsicrud {
-	Fs fs;
-	vlong offset;
-	SDunit *unit;
-	SDpart *part;
-};
-
-long
-sdread(Fs *vcrud, void *v, long n)
-{
-	Scsicrud *crud;
-	long x;
-
-	crud = (Scsicrud*)vcrud;
-	x = sdbio(crud->unit, crud->part, v, n, crud->offset);
-	if(x > 0)
-		crud->offset += x;
-	return x;
-}
-
-vlong
-sdseek(Fs *vcrud, vlong seek)
-{
-	((Scsicrud*)vcrud)->offset = seek;
-	return seek;
-}
-
-void*
-sdgetfspart(int i, char *s, int chatty)
-{
-	SDunit *unit;
-	SDpart *p;
-	Scsicrud *crud;
-
-	if(cdmask&(1<<i)){
-		if(strcmp(s, "cdboot") != 0)
-			return nil;
-	}else if(sdmask&(1<<i)){
-		if(strcmp(s, "cdboot") == 0)
-			return nil;
-	}
-
-	unit = sdindex2unit(i);
-	if((p = sdfindpart(unit, s)) == nil){
-		if(chatty)
-			print("unknown partition %s!%s\n", unit->name, s);
-		return nil;
-	}
-	if(p->crud == nil) {
-		crud = malloc(sizeof(Scsicrud));
-		crud->fs.dev = i;
-		crud->fs.diskread = sdread;
-		crud->fs.diskseek = sdseek;
-	//	crud->start = 0;
-		crud->unit = unit;
-		crud->part = p;
-		if(dosinit(&crud->fs) < 0 && dosinit(&crud->fs) < 0 && kfsinit(&crud->fs) < 0){
-			if(chatty)
-				print("partition %s!%s does not contain a DOS or KFS file system\n",
-					unit->name, s);
-			return nil;
-		}
-		p->crud = crud;
-	}
-	return p->crud;
-}
-
-/*
- * Leave partitions around for devsd to pick up.
- * (Needed by boot process; more extensive 
- * partitioning is done by termrc or cpurc).
- */
-void
-sdaddconf(int i)
-{
-	SDunit *unit;
-	SDpart *pp;
-
-	unit = sdindex2unit(i);
-	
-	/*
-	 * If there were no partitions (just data and partition), don't bother.
-	 */
-	if(unit->npart<= 1 || (unit->npart==2 && strcmp(unit->part[1].name, "partition")==0))
-		return;
-
-	addconf("%spart=", unit->name);
-	for(i=1, pp=&unit->part[i]; i<unit->npart; i++, pp++)	/* skip 0, which is "data" */
-		addconf("%s%s %lld %lld", i==1 ? "" : "/", pp->name,
-			pp->start, pp->end);
-	addconf("\n");
-}
-
-int
-sdboot(int dev, char *pname, Boot *b)
-{
-	char *file;
-	Fs *fs;
-
-	if((file = strchr(pname, '!')) == nil) {
-		print("syntax is sdC0!partition!file\n");
-		return -1;
-	}
-	*file++ = '\0';
-
-	fs = sdgetfspart(dev, pname, 1);
-	if(fs == nil)
-		return -1;
-
-	return fsboot(fs, file, b);
-}
-
-long
-sdbio(SDunit *unit, SDpart *pp, void* va, long len, vlong off)
-{
-	long l;
-	ulong bno, max, nb, offset;
-	static uchar *b;
-	char *a;
-	static ulong bsz;
-
-	a = va;
-memset(a, 0xDA, len);
-	qlock(&unit->ctl);
-	if(unit->changed){
-		qunlock(&unit->ctl);
-		return 0;
-	}
-
-	/*
-	 * Check the request is within bounds.
-	 * Removeable drives are locked throughout the I/O
-	 * in case the media changes unexpectedly.
-	 * Non-removeable drives are not locked during the I/O
-	 * to allow the hardware to optimise if it can; this is
-	 * a little fast and loose.
-	 * It's assumed that non-removable media parameters
-	 * (sectors, secsize) can't change once the drive has
-	 * been brought online.
-	 */
-	bno = (off/unit->secsize) + pp->start;
-	nb = ((off+len+unit->secsize-1)/unit->secsize) + pp->start - bno;
-	max = SDmaxio/unit->secsize;
-	if(nb > max)
-		nb = max;
-	if(bno+nb > pp->end)
-		nb = pp->end - bno;
-	if(bno >= pp->end || nb == 0){
-		qunlock(&unit->ctl);
-		return 0;
-	}
-	if(!(unit->inquiry[1] & 0x80))
-		qunlock(&unit->ctl);
-
-	if(bsz < nb*unit->secsize){
-		b = malloc(nb*unit->secsize);
-		bsz = nb*unit->secsize;
-	}
-//	b = sdmalloc(nb*unit->secsize);
-//	if(b == nil)
-//		return 0;
-
-	offset = off%unit->secsize;
-	if((l = unit->dev->ifc->bio(unit, 0, 0, b, nb, bno)) < 0) {
-//		sdfree(b);
-		return 0;
-	}
-
-	if(l < offset)
-		len = 0;
-	else if(len > l - offset)
-		len = l - offset;
-	if(len)
-		memmove(a, b+offset, len);
-//	sdfree(b);
-
-	if(unit->inquiry[1] & 0x80)
-		qunlock(&unit->ctl);
-
-	return len;
-}
-
-#ifdef DMA
-long
-sdrio(SDreq *r, void* a, long n)
-{
-	if(n >= SDmaxio || n < 0)
-		return 0;
-
-	r->data = nil;
-	if(n){
-		if((r->data = malloc(n)) == nil)
-			return 0;
-		if(r->write)
-			memmove(r->data, a, n);
-	}
-	r->dlen = n;
-
-	if(r->unit->dev->ifc->rio(r) != SDok){
-// cgascreenputs("1", 1);
-		if(r->data != nil){
-			sdfree(r->data);
-			r->data = nil;
-		}
-		return 0;
-	}
-// cgascreenputs("2", 1);
-
-	if(!r->write && r->rlen > 0)
-		memmove(a, r->data, r->rlen);
-// cgascreenputs("3", 1);
-	if(r->data != nil){
-		sdfree(r->data);
-		r->data = nil;
-	}
-
-// cgascreenputs("4", 1);
-	return r->rlen;
-}
-#endif /* DMA */
-
-void
-sleep(void*, int (*fn)(void*), void *v)
-{
-	int x;
-	x = spllo();
-	while(!fn(v))
-		;
-	splx(x);
-	return;
-}
-
-void
-tsleep(void*, int (*fn)(void*), void *v, int msec)
-{
-	int x;
-	ulong start;
-
-	x = spllo();
-	for(start = m->ticks; TK2MS(m->ticks - start) < msec
-		&& !fn(v); )
-		;
-	splx(x);
-	return;
-}
-
-void*
-sdmalloc(void *p, ulong sz)
-{
-	if(p != nil) {
-		memset(p, 0, sz);
-		return p;
-	}
-	return malloc(sz);
-}
--- a/os/boot/pc/dma.c
+++ /dev/null
@@ -1,245 +1,0 @@
-#include	"u.h"
-#include	"lib.h"
-#include	"mem.h"
-#include	"dat.h"
-#include	"fns.h"
-
-typedef struct DMAport	DMAport;
-typedef struct DMA	DMA;
-typedef struct DMAxfer	DMAxfer;
-
-enum
-{
-	/*
-	 *  the byte registers for DMA0 are all one byte apart
-	 */
-	Dma0=		0x00,
-	Dma0status=	Dma0+0x8,	/* status port */
-	Dma0reset=	Dma0+0xD,	/* reset port */
-
-	/*
-	 *  the byte registers for DMA1 are all two bytes apart (why?)
-	 */
-	Dma1=		0xC0,
-	Dma1status=	Dma1+2*0x8,	/* status port */
-	Dma1reset=	Dma1+2*0xD,	/* reset port */
-};
-
-/*
- *  state of a dma transfer
- */
-struct DMAxfer
-{
-	ulong	bpa;		/* bounce buffer physical address */
-	void*	bva;		/* bounce buffer virtual address */
-	void*	va;		/* virtual address destination/src */
-	long	len;		/* bytes to be transferred */
-	int	isread;
-};
-
-/*
- *  the dma controllers.  the first half of this structure specifies
- *  the I/O ports used by the DMA controllers.
- */
-struct DMAport
-{
-	uchar	addr[4];	/* current address (4 channels) */
-	uchar	count[4];	/* current count (4 channels) */
-	uchar	page[4];	/* page registers (4 channels) */
-	uchar	cmd;		/* command status register */
-	uchar	req;		/* request registers */
-	uchar	sbm;		/* single bit mask register */
-	uchar	mode;		/* mode register */
-	uchar	cbp;		/* clear byte pointer */
-	uchar	mc;		/* master clear */
-	uchar	cmask;		/* clear mask register */
-	uchar	wam;		/* write all mask register bit */
-};
-
-struct DMA
-{
-	DMAport;
-	int	shift;
-	Lock;
-	DMAxfer	x[4];
-};
-
-DMA dma[2] = {
-	{ 0x00, 0x02, 0x04, 0x06,
-	  0x01, 0x03, 0x05, 0x07,
-	  0x87, 0x83, 0x81, 0x82,
-	  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
-	 0 },
-
-	{ 0xc0, 0xc4, 0xc8, 0xcc,
-	  0xc2, 0xc6, 0xca, 0xce,
-	  0x8f, 0x8b, 0x89, 0x8a,
-	  0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde,
-	 1 },
-};
-
-/*
- *  DMA must be in the first 16MB.  This gets called early by the
- *  initialisation routines of any devices which require DMA to ensure
- *  the allocated bounce buffers are below the 16MB limit.
- */
-void
-dmainit(int chan)
-{
-	DMA *dp;
-	DMAxfer *xp;
-	ulong v;
-	static int once;
-
-	if(once == 0){
-//		if(ioalloc(0x00, 0x10, 0, "dma") < 0
-//		|| ioalloc(0x80, 0x10, 0, "dma") < 0
-//		|| ioalloc(0xd0, 0x10, 0, "dma") < 0)
-//			panic("dmainit");
-		outb(dma[0].mc, 0);
-		outb(dma[1].mc, 0);
-		outb(dma[0].cmask, 0);
-		outb(dma[1].cmask, 0);
-		outb(dma[1].mode, 0xC0);
-		once = 1;
-	}
-
-	dp = &dma[(chan>>2)&1];
-	chan = chan & 3;
-	xp = &dp->x[chan];
-	if(xp->bva != nil)
-		return;
-
-	v = (ulong)xalloc(BY2PG+BY2PG);
-	if(v == 0 || PADDR(v) >= 16*MB){
-		print("dmainit: chan %d: 0x%luX out of range\n", chan, v);
-		xfree((void*)v);
-		v = 0;
-	}
-	xp->bva = (void*)ROUND(v, BY2PG);
-	xp->bpa = PADDR(xp->bva);
-	xp->len = 0;
-	xp->isread = 0;
-}
-
-/*
- *  setup a dma transfer.  if the destination is not in kernel
- *  memory, allocate a page for the transfer.
- *
- *  we assume BIOS has set up the command register before we
- *  are booted.
- *
- *  return the updated transfer length (we can't transfer across 64k
- *  boundaries)
- */
-long
-dmasetup(int chan, void *va, long len, int isread)
-{
-	DMA *dp;
-	ulong pa;
-	uchar mode;
-	DMAxfer *xp;
-
-	dp = &dma[(chan>>2)&1];
-	chan = chan & 3;
-	xp = &dp->x[chan];
-
-	/*
-	 *  if this isn't kernel memory or crossing 64k boundary or above 16 meg
-	 *  use the allocated low memory page.
-	 */
-	pa = PADDR(va);
-	if((((ulong)va)&0xF0000000) != KZERO
-	|| (pa&0xFFFF0000) != ((pa+len)&0xFFFF0000)
-	|| pa > 16*MB) {
-		if(xp->bva == nil)
-			return -1;
-		if(len > BY2PG)
-			len = BY2PG;
-		if(!isread)
-			memmove(xp->bva, va, len);
-		xp->va = va;
-		xp->len = len;
-		xp->isread = isread;
-		pa = xp->bpa;
-	}
-	else
-		xp->len = 0;
-
-	/*
-	 * this setup must be atomic
-	 */
-	ilock(dp);
-	mode = (isread ? 0x44 : 0x48) | chan;
-	outb(dp->mode, mode);	/* single mode dma (give CPU a chance at mem) */
-	outb(dp->page[chan], pa>>16);
-	outb(dp->cbp, 0);		/* set count & address to their first byte */
-	outb(dp->addr[chan], pa>>dp->shift);		/* set address */
-	outb(dp->addr[chan], pa>>(8+dp->shift));
-	outb(dp->count[chan], (len>>dp->shift)-1);		/* set count */
-	outb(dp->count[chan], ((len>>dp->shift)-1)>>8);
-	outb(dp->sbm, chan);		/* enable the channel */
-	iunlock(dp);
-
-	return len;
-}
-
-int
-dmadone(int chan)
-{
-	DMA *dp;
-
-	dp = &dma[(chan>>2)&1];
-	chan = chan & 3;
-
-	return inb(dp->cmd) & (1<<chan);
-}
-
-/*
- *  this must be called after a dma has been completed.
- *
- *  if a page has been allocated for the dma,
- *  copy the data into the actual destination
- *  and free the page.
- */
-void
-dmaend(int chan)
-{
-	DMA *dp;
-	DMAxfer *xp;
-
-	dp = &dma[(chan>>2)&1];
-	chan = chan & 3;
-
-	/*
-	 *  disable the channel
-	 */
-	ilock(dp);
-	outb(dp->sbm, 4|chan);
-	iunlock(dp);
-
-	xp = &dp->x[chan];
-	if(xp->len == 0 || !xp->isread)
-		return;
-
-	/*
-	 *  copy out of temporary page
-	 */
-	memmove(xp->va, xp->bva, xp->len);
-	xp->len = 0;
-}
-
-/*
-int
-dmacount(int chan)
-{
-	int     retval;
-	DMA     *dp;
- 
-	dp = &dma[(chan>>2)&1];
-	outb(dp->cbp, 0);
-	retval = inb(dp->count[chan]);
-	retval |= inb(dp->count[chan]) << 8;
-	return((retval<<dp->shift)+1);
-}
- */
--- a/os/boot/pc/dosboot.c
+++ /dev/null
@@ -1,582 +1,0 @@
-#include	"u.h"
-#include	"lib.h"
-#include	"mem.h"
-#include	"dat.h"
-#include	"fns.h"
-#include	"fs.h"
-
-struct Dosboot{
-	uchar	magic[3];
-	uchar	version[8];
-	uchar	sectsize[2];
-	uchar	clustsize;
-	uchar	nresrv[2];
-	uchar	nfats;
-	uchar	rootsize[2];
-	uchar	volsize[2];
-	uchar	mediadesc;
-	uchar	fatsize[2];
-	uchar	trksize[2];
-	uchar	nheads[2];
-	uchar	nhidden[4];
-	uchar	bigvolsize[4];
-/* fat 32 */
-	uchar	bigfatsize[4];
-	uchar	extflags[2];
-	uchar	fsversion[2];
-	uchar	rootdirstartclust[4];
-	uchar	fsinfosect[2];
-	uchar	backupbootsect[2];
-/* ???
-	uchar	driveno;
-	uchar	reserved0;
-	uchar	bootsig;
-	uchar	volid[4];
-	uchar	label[11];
-	uchar	reserved1[8];
-*/
-};
-
-struct Dosdir{
-	uchar	name[8];
-	uchar	ext[3];
-	uchar	attr;
-	uchar	lowercase;
-	uchar	hundredth;
-	uchar	ctime[2];
-	uchar	cdate[2];
-	uchar	adate[2];
-	uchar	highstart[2];
-	uchar	mtime[2];
-	uchar	mdate[2];
-	uchar	start[2];
-	uchar	length[4];
-};
-
-#define	DOSRONLY	0x01
-#define	DOSHIDDEN	0x02
-#define	DOSSYSTEM	0x04
-#define	DOSVLABEL	0x08
-#define	DOSDIR	0x10
-#define	DOSARCH	0x20
-
-/*
- *  predeclared
- */
-static void	bootdump(Dosboot*);
-static void	setname(Dosfile*, char*);
-
-/*
- *  debugging
- */
-#define chatty	0
-#define chat	if(chatty)print
-
-/*
- *  block io buffers
- */
-enum
-{
-	Nbio=	16,
-};
-typedef struct	Clustbuf	Clustbuf;
-struct Clustbuf
-{
-	int	age;
-	long	sector;
-	uchar	*iobuf;
-	Dos	*dos;
-	int	size;
-};
-Clustbuf	bio[Nbio];
-
-/*
- *  get an io block from an io buffer
- */
-Clustbuf*
-getclust(Dos *dos, long sector)
-{
-	Fs *fs;
-	Clustbuf *p, *oldest;
-	int size;
-
-	chat("getclust @ %ld\n", sector);
-
-	/*
-	 *  if we have it, just return it
-	 */
-	for(p = bio; p < &bio[Nbio]; p++){
-		if(sector == p->sector && dos == p->dos){
-			p->age = m->ticks;
-			chat("getclust %ld in cache\n", sector);
-			return p;
-		}
-	}
-
-	/*
-	 *  otherwise, reuse the oldest entry
-	 */
-	oldest = bio;
-	for(p = &bio[1]; p < &bio[Nbio]; p++){
-		if(p->age <= oldest->age)
-			oldest = p;
-	}
-	p = oldest;
-
-	/*
-	 *  make sure the buffer is big enough
-	 */
-	size = dos->clustsize*dos->sectsize;
-	if(p->iobuf==0 || p->size < size)
-		p->iobuf = ialloc(size, 0);
-	p->size = size;
-
-	/*
-	 *  read in the cluster
-	 */
-	fs = (Fs*)dos;
-	chat("getclust addr %lud %p %p %p\n", (ulong)((sector+dos->start)*(vlong)dos->sectsize),
-		fs, fs->diskseek, fs->diskread);
-	if(fs->diskseek(fs, (sector+dos->start)*(vlong)dos->sectsize) < 0){
-		chat("can't seek block\n");
-		return 0;
-	}
-	if(fs->diskread(fs, p->iobuf, size) != size){
-		chat("can't read block\n");
-		return 0;
-	}
-
-	p->age = m->ticks;
-	p->dos = dos;
-	p->sector = sector;
-	chat("getclust %ld read\n", sector);
-	return p;
-}
-
-/*
- *  walk the fat one level ( n is a current cluster number ).
- *  return the new cluster number or -1 if no more.
- */
-static long
-fatwalk(Dos *dos, int n)
-{
-	ulong k, sect;
-	Clustbuf *p;
-	int o;
-
-	chat("fatwalk %d\n", n);
-
-	if(n < 2 || n >= dos->fatclusters)
-		return -1;
-
-	switch(dos->fatbits){
-	case 12:
-		k = (3*n)/2; break;
-	case 16:
-		k = 2*n; break;
-	case 32:
-		k = 4*n; break;
-	default:
-		return -1;
-	}
-	if(k >= dos->fatsize*dos->sectsize)
-		panic("getfat");
-
-	sect = (k/(dos->sectsize*dos->clustsize))*dos->clustsize + dos->fataddr;
-	o = k%(dos->sectsize*dos->clustsize);
-	p = getclust(dos, sect);
-	k = p->iobuf[o++];
-	if(o >= dos->sectsize*dos->clustsize){
-		p = getclust(dos, sect+dos->clustsize);
-		o = 0;
-	}
-	k |= p->iobuf[o++]<<8;
-	if(dos->fatbits == 12){
-		if(n&1)
-			k >>= 4;
-		else
-			k &= 0xfff;
-		if(k >= 0xff8)
-			k = -1;
-	}
-	else if (dos->fatbits == 32){
-		if(o >= dos->sectsize*dos->clustsize){
-			p = getclust(dos, sect+dos->clustsize);
-			o = 0;
-		}
-		k |= p->iobuf[o++]<<16;
-		k |= p->iobuf[o]<<24;
-		if (k >= 0xfffffff8)
-			k = -1;
-	}
-	else
-		k = k < 0xfff8 ? k : -1;
-	chat("fatwalk %d -> %lud\n", n, k);
-	return k;
-}
-
-/*
- *  map a file's logical cluster address to a physical sector address
- */
-static long
-fileaddr(Dosfile *fp, long ltarget)
-{
-	Dos *dos = fp->dos;
-	long l;
-	long p;
-
-	chat("fileaddr %8.8s %ld\n", fp->name, ltarget);
-	/*
-	 *  root directory is contiguous and easy (unless FAT32)
-	 */
-	if(fp->pstart == 0 && dos->rootsize != 0) {
-		if(ltarget*dos->sectsize*dos->clustsize >= dos->rootsize*sizeof(Dosdir))
-			return -1;
-		l = dos->rootaddr + ltarget*dos->clustsize;
-		chat("fileaddr %ld -> %ld\n", ltarget, l);
-		return l;
-	}
-
-	/*
-	 *  anything else requires a walk through the fat
-	 */
-	if(ltarget >= fp->lcurrent && fp->pcurrent){
-		/* start at the currrent point */
-		l = fp->lcurrent;
-		p = fp->pcurrent;
-	} else {
-		/* go back to the beginning */
-		l = 0;
-		p = fp->pstart;
-	}
-	while(l != ltarget){
-		/* walk the fat */
-		p = fatwalk(dos, p);
-		if(p < 0)
-			return -1;
-		l++;
-	}
-	fp->lcurrent = l;
-	fp->pcurrent = p;
-
-	/*
-	 *  clusters start at 2 instead of 0 (why? - presotto)
-	 */
-	l =  dos->dataaddr + (p-2)*dos->clustsize;
-	chat("fileaddr %ld -> %ld\n", ltarget, l);
-	return l;
-}
-
-/*
- *  read from a dos file
- */
-long
-dosread(Dosfile *fp, void *a, long n)
-{
-	long addr;
-	long rv;
-	int i;
-	int off;
-	Clustbuf *p;
-	uchar *from, *to;
-
-	if((fp->attr & DOSDIR) == 0){
-		if(fp->offset >= fp->length)
-			return 0;
-		if(fp->offset+n > fp->length)
-			n = fp->length - fp->offset;
-	}
-
-	to = a;
-	for(rv = 0; rv < n; rv+=i){
-		/*
-		 *  read the cluster
-		 */
-		addr = fileaddr(fp, fp->offset/fp->dos->clustbytes);
-		if(addr < 0)
-			return -1;
-		p = getclust(fp->dos, addr);
-		if(p == 0)
-			return -1;
-
-		/*
-		 *  copy the bytes we need
-		 */
-		off = fp->offset % fp->dos->clustbytes;
-		from = &p->iobuf[off];
-		i = n - rv;
-		if(i > fp->dos->clustbytes - off)
-			i = fp->dos->clustbytes - off;
-		memmove(to, from, i);
-		to += i;
-		fp->offset += i;
-	}
-
-	return rv;
-}
-
-/*
- *  walk a directory returns
- * 	-1 if something went wrong
- *	 0 if not found
- *	 1 if found
- */
-int
-doswalk(File *f, char *name)
-{
-	Dosdir d;
-	long n;
-	Dosfile *file;
-
-	chat("doswalk %s\n", name);
-
-	file = &f->dos;
-
-	if((file->attr & DOSDIR) == 0){
-		chat("walking non-directory!\n");
-		return -1;
-	}
-
-	setname(file, name);
-
-	file->offset = 0;	/* start at the beginning */
-	while((n = dosread(file, &d, sizeof(d))) == sizeof(d)){
-		chat("comparing to %8.8s.%3.3s\n", (char*)d.name, (char*)d.ext);
-		if(memcmp(file->name, d.name, sizeof(d.name)) != 0)
-			continue;
-		if(memcmp(file->ext, d.ext, sizeof(d.ext)) != 0)
-			continue;
-		if(d.attr & DOSVLABEL){
-			chat("%8.8s.%3.3s is a LABEL\n", (char*)d.name, (char*)d.ext);
-			continue;
-		}
-		file->attr = d.attr;
-		file->pstart = GSHORT(d.start);
-		if (file->dos->fatbits == 32)
-			file->pstart |= GSHORT(d.highstart) << 16;
-		file->length = GLONG(d.length);
-		file->pcurrent = 0;
-		file->lcurrent = 0;
-		file->offset = 0;
-		return 1;
-	}
-	return n >= 0 ? 0 : -1;
-}
-
-/*
- *  instructions that boot blocks can start with
- */
-#define	JMPSHORT	0xeb
-#define JMPNEAR		0xe9
-
-/*
- *  read in a segment
- */
-long
-dosreadseg(File *f, void *va, long len)
-{
-	char *a;
-	long n, sofar;
-	Dosfile *fp;
-
-	fp = &f->dos;
-	a = va;
-	for(sofar = 0; sofar < len; sofar += n){
-		n = 8*1024;
-		if(len - sofar < n)
-			n = len - sofar;
-		n = dosread(fp, a + sofar, n);
-		if(n <= 0)
-			break;
-		print(".");
-	}
-	return sofar;
-}
-
-int
-dosinit(Fs *fs)
-{
-	Clustbuf *p;
-	Dosboot *b;
-	int i;
-	Dos *dos;
-	Dosfile *root;
-
-chat("dosinit0 %p %p %p\n", fs, fs->diskseek, fs->diskread);
-
-	dos = &fs->dos;
-	/* defaults till we know better */
-	dos->sectsize = 512;
-	dos->clustsize = 1;
-
-	/* get first sector */
-	p = getclust(dos, 0);
-	if(p == 0){
-		chat("can't read boot block\n");
-		return -1;
-	}
-
-chat("dosinit0a\n");
-
-	p->dos = 0;
-	b = (Dosboot *)p->iobuf;
-	if(b->magic[0] != JMPNEAR && (b->magic[0] != JMPSHORT || b->magic[2] != 0x90)){
-		chat("no dos file system %x %x %x %x\n",
-			b->magic[0], b->magic[1], b->magic[2], b->magic[3]);
-		return -1;
-	}
-
-	if(chatty)
-		bootdump(b);
-
-	if(b->clustsize == 0) {
-unreasonable:
-		if(chatty){
-			print("unreasonable FAT BPB: ");
-			for(i=0; i<3+8+2+1; i++)
-				print(" %.2ux", p->iobuf[i]);
-			print("\n");
-		}
-		return -1;
-	}
-
-chat("dosinit1\n");
-
-	/*
-	 * Determine the systems' wondrous properties.
-	 * There are heuristics here, but there's no real way
-	 * of knowing if this is a reasonable FAT.
-	 */
-	dos->fatbits = 0;
-	dos->sectsize = GSHORT(b->sectsize);
-	if(dos->sectsize & 0xFF)
-		goto unreasonable;
-	dos->clustsize = b->clustsize;
-	dos->clustbytes = dos->sectsize*dos->clustsize;
-	dos->nresrv = GSHORT(b->nresrv);
-	dos->nfats = b->nfats;
-	dos->fatsize = GSHORT(b->fatsize);
-	dos->rootsize = GSHORT(b->rootsize);
-	dos->volsize = GSHORT(b->volsize);
-	if(dos->volsize == 0)
-		dos->volsize = GLONG(b->bigvolsize);
-	dos->mediadesc = b->mediadesc;
-	if(dos->fatsize == 0) {
-		chat("fat32\n");
-		dos->rootsize = 0;
-		dos->fatsize = GLONG(b->bigfatsize);
-		dos->fatbits = 32;
-	}
-	dos->fataddr = dos->nresrv;
-	if (dos->rootsize == 0) {
-		dos->rootaddr = 0;
-		dos->rootclust = GLONG(b->rootdirstartclust);
-		dos->dataaddr = dos->fataddr + dos->nfats*dos->fatsize;
-	} else {
-		dos->rootaddr = dos->fataddr + dos->nfats*dos->fatsize;
-		i = dos->rootsize*sizeof(Dosdir) + dos->sectsize - 1;
-		i = i/dos->sectsize;
-		dos->dataaddr = dos->rootaddr + i;
-	}
-	dos->fatclusters = 2+(dos->volsize - dos->dataaddr)/dos->clustsize;
-	if(dos->fatbits != 32) {
-		if(dos->fatclusters < 4087)
-			dos->fatbits = 12;
-		else
-			dos->fatbits = 16;
-	}
-	dos->freeptr = 2;
-
-	if(dos->clustbytes < 512 || dos->clustbytes > 64*1024)
-		goto unreasonable;
-
-chat("dosinit2\n");
-
-	/*
-	 *  set up the root
-	 */
-
-	fs->root.fs = fs;
-	root = &fs->root.dos;
-	root->dos = dos;
-	root->pstart = dos->rootsize == 0 ? dos->rootclust : 0;
-	root->pcurrent = root->lcurrent = 0;
-	root->offset = 0;
-	root->attr = DOSDIR;
-	root->length = dos->rootsize*sizeof(Dosdir);
-
-chat("dosinit3\n");
-
-	fs->read = dosreadseg;
-	fs->walk = doswalk;
-	return 0;
-}
-
-static void
-bootdump(Dosboot *b)
-{
-	if(chatty == 0)
-		return;
-	print("magic: 0x%2.2x 0x%2.2x 0x%2.2x ",
-		b->magic[0], b->magic[1], b->magic[2]);
-	print("version: \"%8.8s\"\n", (char*)b->version);
-	print("sectsize: %d ", GSHORT(b->sectsize));
-	print("allocsize: %d ", b->clustsize);
-	print("nresrv: %d ", GSHORT(b->nresrv));
-	print("nfats: %d\n", b->nfats);
-	print("rootsize: %d ", GSHORT(b->rootsize));
-	print("volsize: %d ", GSHORT(b->volsize));
-	print("mediadesc: 0x%2.2x\n", b->mediadesc);
-	print("fatsize: %d ", GSHORT(b->fatsize));
-	print("trksize: %d ", GSHORT(b->trksize));
-	print("nheads: %d ", GSHORT(b->nheads));
-	print("nhidden: %d ", GLONG(b->nhidden));
-	print("bigvolsize: %d\n", GLONG(b->bigvolsize));
-/*
-	print("driveno: %d\n", b->driveno);
-	print("reserved0: 0x%2.2x\n", b->reserved0);
-	print("bootsig: 0x%2.2x\n", b->bootsig);
-	print("volid: 0x%8.8x\n", GLONG(b->volid));
-	print("label: \"%11.11s\"\n", b->label);
-*/
-}
-
-
-/*
- *  set up a dos file name
- */
-static void
-setname(Dosfile *fp, char *from)
-{
-	char *to;
-
-	to = fp->name;
-	for(; *from && to-fp->name < 8; from++, to++){
-		if(*from == '.'){
-			from++;
-			break;
-		}
-		if(*from >= 'a' && *from <= 'z')
-			*to = *from + 'A' - 'a';
-		else
-			*to = *from;
-	}
-	while(to - fp->name < 8)
-		*to++ = ' ';
-	
-	/* from might be 12345678.123: don't save the '.' in ext */
-	if(*from == '.')
-		from++;
-
-	to = fp->ext;
-	for(; *from && to-fp->ext < 3; from++, to++){
-		if(*from >= 'a' && *from <= 'z')
-			*to = *from + 'A' - 'a';
-		else
-			*to = *from;
-	}
-	while(to-fp->ext < 3)
-		*to++ = ' ';
-
-	chat("name is %8.8s.%3.3s\n", fp->name, fp->ext);
-}
--- a/os/boot/pc/dosfs.h
+++ /dev/null
@@ -1,62 +1,0 @@
-typedef struct Dosboot	Dosboot;
-typedef struct Dos	Dos;
-typedef struct Dosdir	Dosdir;
-typedef struct Dosfile	Dosfile;
-typedef struct Dospart	Dospart;
-
-struct Dospart
-{
-	uchar flag;		/* active flag */
-	uchar shead;		/* starting head */
-	uchar scs[2];		/* starting cylinder/sector */
-	uchar type;		/* partition type */
-	uchar ehead;		/* ending head */
-	uchar ecs[2];		/* ending cylinder/sector */
-	uchar start[4];		/* starting sector */
-	uchar len[4];		/* length in sectors */
-};
-
-#define FAT12	0x01
-#define FAT16	0x04
-#define EXTEND	0x05
-#define FATHUGE	0x06
-#define FAT32	0x0b
-#define FAT32X	0x0c
-#define EXTHUGE	0x0f
-#define DMDDO	0x54
-#define PLAN9	0x39
-#define LEXTEND 0x85
-
-struct Dosfile{
-	Dos	*dos;		/* owning dos file system */
-	char	name[8];
-	char	ext[3];
-	uchar	attr;
-	long	length;
-	long	pstart;		/* physical start cluster address */
-	long	pcurrent;	/* physical current cluster address */
-	long	lcurrent;	/* logical current cluster address */
-	long	offset;
-};
-
-struct Dos{
-	long	start;		/* start of file system */
-	int	sectsize;	/* in bytes */
-	int	clustsize;	/* in sectors */
-	int	clustbytes;	/* in bytes */
-	int	nresrv;		/* sectors */
-	int	nfats;		/* usually 2 */
-	int	rootsize;	/* number of entries */
-	int	volsize;	/* in sectors */
-	int	mediadesc;
-	int	fatsize;	/* in sectors */
-	int	fatclusters;
-	int	fatbits;	/* 12 or 16 */
-	long	fataddr;	/* sector number */
-	long	rootaddr;
-	long	rootclust;
-	long	dataaddr;
-	long	freeptr;
-};
-
-extern int	dosinit(Fs*);
--- a/os/boot/pc/eipfmt.c
+++ /dev/null
@@ -1,145 +1,0 @@
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "ip.h"
-
-
-enum 
-{
-	IPaddrlen=	16,
-	IPv4addrlen=	4,
-	IPv4off=	12,
-	IPllen=		4,
-};
-extern	int	fmtstrcpy(Fmt*, char*);
-
-
-/*
- *  prefix of all v4 addresses
- */
-uchar v4prefix[IPaddrlen] = {
-	0, 0, 0, 0,
-	0, 0, 0, 0,
-	0, 0, 0xff, 0xff,
-	0, 0, 0, 0
-};
-
-enum
-{
-	Isprefix= 16,
-};
-
-uchar prefixvals[256] =
-{
-[0x00] 0 | Isprefix,
-[0x80] 1 | Isprefix,
-[0xC0] 2 | Isprefix,
-[0xE0] 3 | Isprefix,
-[0xF0] 4 | Isprefix,
-[0xF8] 5 | Isprefix,
-[0xFC] 6 | Isprefix,
-[0xFE] 7 | Isprefix,
-[0xFF] 8 | Isprefix,
-};
-
-void
-hnputl(void *p, uint v)
-{
-	uchar *a;
-
-	a = p;
-	a[0] = v>>24;
-	a[1] = v>>16;
-	a[2] = v>>8;
-	a[3] = v;
-}
-
-int
-eipfmt(Fmt *f)
-{
-	char buf[5*8];
-	static char *efmt = "%.2lux%.2lux%.2lux%.2lux%.2lux%.2lux";
-	static char *ifmt = "%d.%d.%d.%d";
-	uchar *p, ip[16];
-	ulong *lp;
-	ushort s;
-	int i, j, n, eln, eli;
-
-	switch(f->r) {
-	case 'E':		/* Ethernet address */
-		p = va_arg(f->args, uchar*);
-		snprint(buf, sizeof buf, efmt, p[0], p[1], p[2], p[3], p[4], p[5]);
-		return fmtstrcpy(f, buf);
-
-	case 'I':		/* Ip address */
-		p = va_arg(f->args, uchar*);
-common:
-		if(memcmp(p, v4prefix, 12) == 0){
-			snprint(buf, sizeof buf, ifmt, p[12], p[13], p[14], p[15]);
-			return fmtstrcpy(f, buf);
-		}
-
-		/* find longest elision */
-		eln = eli = -1;
-		for(i = 0; i < 16; i += 2){
-			for(j = i; j < 16; j += 2)
-				if(p[j] != 0 || p[j+1] != 0)
-					break;
-			if(j > i && j - i > eln){
-				eli = i;
-				eln = j - i;
-			}
-		}
-
-		/* print with possible elision */
-		n = 0;
-		for(i = 0; i < 16; i += 2){
-			if(i == eli){
-				n += sprint(buf+n, "::");
-				i += eln;
-				if(i >= 16)
-					break;
-			} else if(i != 0)
-				n += sprint(buf+n, ":");
-			s = (p[i]<<8) + p[i+1];
-			n += sprint(buf+n, "%ux", s);
-		}
-		return fmtstrcpy(f, buf);
-
-	case 'i':		/* v6 address as 4 longs */
-		lp = va_arg(f->args, ulong*);
-		for(i = 0; i < 4; i++)
-			hnputl(ip+4*i, *lp++);
-		p = ip;
-		goto common;
-
-	case 'V':		/* v4 ip address */
-		p = va_arg(f->args, uchar*);
-		snprint(buf, sizeof buf, ifmt, p[0], p[1], p[2], p[3]);
-		return fmtstrcpy(f, buf);
-
-	case 'M':		/* ip mask */
-		p = va_arg(f->args, uchar*);
-
-		/* look for a prefix mask */
-		for(i = 0; i < 16; i++)
-			if(p[i] != 0xff)
-				break;
-		if(i < 16){
-			if((prefixvals[p[i]] & Isprefix) == 0)
-				goto common;
-			for(j = i+1; j < 16; j++)
-				if(p[j] != 0)
-					goto common;
-			n = 8*i + (prefixvals[p[i]] & ~Isprefix);
-		} else
-			n = 8*16;
-
-		/* got one, use /xx format */
-		snprint(buf, sizeof buf, "/%d", n);
-		return fmtstrcpy(f, buf);
-	}
-	return fmtstrcpy(f, "(eipfmt)");
-}
--- a/os/boot/pc/error.h
+++ /dev/null
@@ -1,58 +1,0 @@
-extern char Enoerror[];		/* no error */
-extern char Emount[];		/* inconsistent mount */
-extern char Eunmount[];		/* not mounted */
-extern char Eunion[];		/* not in union */
-extern char Emountrpc[];	/* mount rpc error */
-extern char Eshutdown[];	/* mounted device shut down */
-extern char Enocreate[];	/* mounted directory forbids creation */
-extern char Enonexist[];	/* file does not exist */
-extern char Eexist[];		/* file already exists */
-extern char Ebadsharp[];	/* unknown device in # filename */
-extern char Enotdir[];		/* not a directory */
-extern char Eisdir[];		/* file is a directory */
-extern char Ebadchar[];		/* bad character in file name */
-extern char Efilename[];	/* file name syntax */
-extern char Eperm[];		/* permission denied */
-extern char Ebadusefd[];	/* inappropriate use of fd */
-extern char Ebadarg[];		/* bad arg in system call */
-extern char Einuse[];		/* device or object already in use */
-extern char Eio[];		/* i/o error */
-extern char Etoobig[];		/* read or write too large */
-extern char Etoosmall[];	/* read or write too small */
-extern char Enetaddr[];		/* bad network address */
-extern char Emsgsize[];		/* message is too big for protocol */
-extern char Enetbusy[];		/* network device is busy or allocated */
-extern char Enoproto[];		/* network protocol not supported */
-extern char Enoport[];		/* network port not available */
-extern char Enoifc[];		/* bad interface or no free interface slots */
-extern char Enolisten[];	/* not announced */
-extern char Ehungup[];		/* write to hungup channel */
-extern char Ebadctl[];		/* bad process or channel control request */
-extern char Enodev[];		/* no free devices */
-extern char Enoenv[];		/* no free environment resources */
-extern char Emuxshutdown[];	/* mux server shut down */
-extern char Emuxbusy[];		/* all mux channels busy */
-extern char Emuxmsg[];		/* bad mux message format or mismatch */
-extern char Eprocdied[];	/* process exited */
-extern char Enochild[];		/* no living children */
-extern char Eioload[];		/* i/o error in demand load */
-extern char Enovmem[];		/* virtual memory allocation failed */
-extern char Ebadld[];		/* illegal line discipline */
-extern char Ebadfd[];		/* fd out of range or not open */
-extern char Eisstream[];	/* seek on a stream */
-extern char Ebadexec[];		/* exec header invalid */
-extern char Etimedout[];	/* connection timed out */
-extern char Econrefused[];	/* connection refused */
-extern char Enetunreach[];	/* network unreachable */
-extern char Eintr[];		/* interrupted */
-extern char Eneedservice[];	/* service required for tcp/udp/il calls */
-extern char Enomem[];		/* kernel allocate failed */
-extern char Enoswap[];		/* swap space full */
-extern char Esfnotcached[];	/* subfont not cached */
-extern char Esoverlap[];	/* segments overlap */
-extern char Emouseset[];	/* mouse type already set */
-extern char Erecover[];		/* failed to recover fd */
-extern char Eshort[];		/* i/o count too small */
-extern char Egreg[];		/* ken scheduled it */
-extern char Ebadspec[];		/* bad attach specifier */
-extern char Enoreg[];		/* process has no saved registers */
--- a/os/boot/pc/ether.c
+++ /dev/null
@@ -1,291 +1,0 @@
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "ip.h"
-
-#include "etherif.h"
-
-static Ether ether[MaxEther];
-
-extern int ether2114xreset(Ether*);
-extern int elnk3reset(Ether*);
-extern int i82557reset(Ether*);
-extern int igbepnp(Ether *);
-extern int i82563pnp(Ether *);
-extern int elnk3reset(Ether*);
-extern int ether589reset(Ether*);
-extern int ne2000reset(Ether*);
-extern int wd8003reset(Ether*);
-extern int ec2treset(Ether*);
-extern int amd79c970reset(Ether*);
-extern int rtl8139pnp(Ether*);
-extern int rtl8169pnp(Ether*);
-extern int ether83815reset(Ether*);
-extern int rhinepnp(Ether*);
-extern int ga620pnp(Ether*);
-extern int dp83820pnp(Ether*);
-
-struct {
-	char	*type;
-	int	(*reset)(Ether*);
-	int	noprobe;
-} ethercards[] = {
-	{ "21140", ether2114xreset, 0, },
-	{ "2114x", ether2114xreset, 0, },
-	{ "i82557", i82557reset, 0, },
-	{ "igbe",  igbepnp, 0, },
-	{ "i82563",i82563pnp, 0, },
-	{ "igbepcie",i82563pnp, 0, },
-	{ "elnk3", elnk3reset, 0, },
-	{ "3C509", elnk3reset, 0, },
-	{ "3C575", elnk3reset, 0, },
-	{ "3C589", ether589reset, 1, },
-	{ "3C562", ether589reset, 1, },
-	{ "589E", ether589reset, 1, },
-	{ "NE2000", ne2000reset, 0, },
-	{ "WD8003", wd8003reset, 1, },
-	{ "EC2T", ec2treset, 0, },
-	{ "AMD79C970", amd79c970reset, 0, },
-	{ "RTL8139", rtl8139pnp, 0, },
-	{ "RTL8169", rtl8169pnp, 0, },
-	{ "83815", ether83815reset, 0, },
-	{ "rhine", rhinepnp, 0, },
-	{ "vt6102", rhinepnp, 0, },
-	{ "GA620", ga620pnp, 0, },
-	{ "83820",   dp83820pnp, 0, },
-	{ "dp83820", dp83820pnp, 0, },
-
-	{ 0, }
-};
-
-static void xetherdetach(void);
-
-int
-etherinit(void)
-{
-	Ether *ctlr;
-	int ctlrno, i, mask, n, x;
-
-	fmtinstall('E', eipfmt);
-
-	etherdetach = xetherdetach;
-	mask = 0;
-	for(ctlrno = 0; ctlrno < MaxEther; ctlrno++){
-		ctlr = &ether[ctlrno];
-		memset(ctlr, 0, sizeof(Ether));
-		if(iniread && isaconfig("ether", ctlrno, ctlr) == 0)
-			continue;
-
-		for(n = 0; ethercards[n].type; n++){
-			if(!iniread){
-				if(ethercards[n].noprobe)
-					continue;
-				memset(ctlr, 0, sizeof(Ether));
-				strcpy(ctlr->type, ethercards[n].type);
-			}
-			else if(cistrcmp(ethercards[n].type, ctlr->type))
-				continue;
-			ctlr->ctlrno = ctlrno;
-
-			x = splhi();
-			if((*ethercards[n].reset)(ctlr)){
-				splx(x);
-				if(iniread)
-					break;
-				else
-					continue;
-			}
-
-			ctlr->state = 1;		/* card found */
-			mask |= 1<<ctlrno;
-			if(ctlr->irq == 2)
-				ctlr->irq = 9;
-			setvec(VectorPIC + ctlr->irq, ctlr->interrupt, ctlr);
-
-			print("ether#%d: %s: port 0x%luX irq %lud",
-				ctlr->ctlrno, ctlr->type, ctlr->port, ctlr->irq);
-			if(ctlr->mem)
-				print(" addr 0x%luX", ctlr->mem & ~KZERO);
-			if(ctlr->size)
-				print(" size 0x%luX", ctlr->size);
-			print(": %E\n", ctlr->ea);
-		
-			if(ctlr->nrb == 0)
-				ctlr->nrb = Nrb;
-			ctlr->rb = ialloc(sizeof(RingBuf)*ctlr->nrb, 0);
-			if(ctlr->ntb == 0)
-				ctlr->ntb = Ntb;
-			ctlr->tb = ialloc(sizeof(RingBuf)*ctlr->ntb, 0);
-
-			ctlr->rh = 0;
-			ctlr->ri = 0;
-			for(i = 0; i < ctlr->nrb; i++)
-				ctlr->rb[i].owner = Interface;
-		
-			ctlr->th = 0;
-			ctlr->ti = 0;
-			for(i = 0; i < ctlr->ntb; i++)
-				ctlr->tb[i].owner = Host;
-
-			splx(x);
-			break;
-		}
-	}
-
-	return mask;
-}
-
-void
-etherinitdev(int i, char *s)
-{
-	sprint(s, "ether%d", i);
-}
-
-void
-etherprintdevs(int i)
-{
-	print(" ether%d", i);
-}
-
-static Ether*
-attach(int ctlrno)
-{
-	Ether *ctlr;
-
-	if(ctlrno >= MaxEther || ether[ctlrno].state == 0)
-		return 0;
-
-	ctlr = &ether[ctlrno];
-	if(ctlr->state == 1){		/* card found? */
-		ctlr->state = 2;	/* attaching */
-		(*ctlr->attach)(ctlr);
-	}
-
-	return ctlr;
-}
-
-static void
-xetherdetach(void)
-{
-	Ether *ctlr;
-	int ctlrno, x;
-
-	x = splhi();
-	for(ctlrno = 0; ctlrno < MaxEther; ctlrno++){
-		ctlr = &ether[ctlrno];
-		if(ctlr->detach && ctlr->state != 0)	/* found | attaching? */
-			ctlr->detach(ctlr);
-	}
-	splx(x);
-}
-
-uchar*
-etheraddr(int ctlrno)
-{
-	Ether *ctlr;
-
-	if((ctlr = attach(ctlrno)) == 0)
-		return 0;
-
-	return ctlr->ea;
-}
-
-static int
-wait(RingBuf* ring, uchar owner, int timo)
-{
-	ulong start;
-
-	start = m->ticks;
-	while(TK2MS(m->ticks - start) < timo){
-		if(ring->owner != owner)
-			return 1;
-	}
-
-	return 0;
-}
-
-int
-etherrxpkt(int ctlrno, Etherpkt* pkt, int timo)
-{
-	int n;
-	Ether *ctlr;
-	RingBuf *ring;
-
-	if((ctlr = attach(ctlrno)) == 0)
-		return 0;
-
-	ring = &ctlr->rb[ctlr->rh];
-	if(wait(ring, Interface, timo) == 0){
-		if(debug)
-			print("ether%d: rx timeout\n", ctlrno);
-		return 0;
-	}
-
-	n = ring->len;
-	memmove(pkt, ring->pkt, n);
-	ring->owner = Interface;
-	ctlr->rh = NEXT(ctlr->rh, ctlr->nrb);
-
-	return n;
-}
-
-int
-etherrxflush(int ctlrno)
-{
-	int n;
-	Ether *ctlr;
-	RingBuf *ring;
-
-	if((ctlr = attach(ctlrno)) == 0)
-		return 0;
-
-	n = 0;
-	for(;;){
-		ring = &ctlr->rb[ctlr->rh];
-		if(wait(ring, Interface, 100) == 0)
-			break;
-
-		ring->owner = Interface;
-		ctlr->rh = NEXT(ctlr->rh, ctlr->nrb);
-		n++;
-	}
-
-	return n;
-}
-
-int
-ethertxpkt(int ctlrno, Etherpkt* pkt, int len, int)
-{
-	Ether *ctlr;
-	RingBuf *ring;
-	int s;
-
-	if((ctlr = attach(ctlrno)) == 0)
-		return 0;
-
-	ring = &ctlr->tb[ctlr->th];
-	if(wait(ring, Interface, 1000) == 0){
-		print("ether%d: tx buffer timeout\n", ctlrno);
-		return 0;
-	}
-
-	memmove(pkt->s, ctlr->ea, Eaddrlen);
-	if(debug)
-		print("%E to %E...\n", pkt->s, pkt->d);
-	memmove(ring->pkt, pkt, len);
-	if(len < ETHERMINTU){
-		memset(ring->pkt+len, 0, ETHERMINTU-len);
-		len = ETHERMINTU;
-	}
-	ring->len = len;
-	ring->owner = Interface;
-	ctlr->th = NEXT(ctlr->th, ctlr->ntb);
-	s = splhi();
-	(*ctlr->transmit)(ctlr);
-	splx(s);
-
-	return 1;
-}
--- a/os/boot/pc/ether2000.c
+++ /dev/null
@@ -1,110 +1,0 @@
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-
-#include "etherif.h"
-#include "ether8390.h"
-
-/*
- * Driver written for the 'Notebook Computer Ethernet LAN Adapter',
- * a plug-in to the bus-slot on the rear of the Gateway NOMAD 425DXL
- * laptop. The manual says NE2000 compatible.
- * The interface appears to be pretty well described in the National
- * Semiconductor Local Area Network Databook (1992) as one of the
- * AT evaluation cards.
- *
- * The NE2000 is really just a DP8390[12] plus a data port
- * and a reset port.
- */
-enum {
-	Data		= 0x10,		/* offset from I/O base of data port */
-	Reset		= 0x1F,		/* offset from I/O base of reset port */
-};
-
-int
-ne2000reset(Ether* ether)
-{
-	ushort buf[16];
-	ulong port;
-	Dp8390 *ctlr;
-	int i;
-	uchar ea[Eaddrlen];
-
-	/*
-	 * Set up the software configuration.
-	 * Use defaults for port, irq, mem and size
-	 * if not specified.
-	 */
-	if(ether->port == 0)
-		ether->port = 0x300;
-	if(ether->irq == 0)
-		ether->irq = 2;
-	if(ether->mem == 0)
-		ether->mem = 0x4000;
-	if(ether->size == 0)
-		ether->size = 16*1024;
-	port = ether->port;
-
-	ether->ctlr = malloc(sizeof(Dp8390));
-	ctlr = ether->ctlr;
-	ctlr->width = 2;
-	ctlr->ram = 0;
-
-	ctlr->port = port;
-	ctlr->data = port+Data;
-
-	ctlr->tstart = HOWMANY(ether->mem, Dp8390BufSz);
-	ctlr->pstart = ctlr->tstart + HOWMANY(sizeof(Etherpkt), Dp8390BufSz);
-	ctlr->pstop = ctlr->tstart + HOWMANY(ether->size, Dp8390BufSz);
-
-	ctlr->dummyrr = 1;
-	for(i = 0; i < ether->nopt; i++){
-		if(strcmp(ether->opt[i], "nodummyrr"))
-			continue;
-		ctlr->dummyrr = 0;
-		break;
-	}
-
-	/*
-	 * Reset the board. This is done by doing a read
-	 * followed by a write to the Reset address.
-	 */
-	buf[0] = inb(port+Reset);
-	delay(2);
-	outb(port+Reset, buf[0]);
-	delay(2);
-	
-	/*
-	 * Init the (possible) chip, then use the (possible)
-	 * chip to read the (possible) PROM for ethernet address
-	 * and a marker byte.
-	 * Could just look at the DP8390 command register after
-	 * initialisation has been tried, but that wouldn't be
-	 * enough, there are other ethernet boards which could
-	 * match.
-	 */
-	dp8390reset(ether);
-	memset(buf, 0, sizeof(buf));
-	dp8390read(ctlr, buf, 0, sizeof(buf));
-	if((buf[0x0E] & 0xFF) != 0x57 || (buf[0x0F] & 0xFF) != 0x57){
-		free(ether->ctlr);
-		return -1;
-	}
-
-	/*
-	 * Stupid machine. Shorts were asked for,
-	 * shorts were delivered, although the PROM is a byte array.
-	 * Set the ethernet address.
-	 */
-	memset(ea, 0, Eaddrlen);
-	if(memcmp(ea, ether->ea, Eaddrlen) == 0){
-		for(i = 0; i < sizeof(ether->ea); i++)
-			ether->ea[i] = buf[i];
-	}
-	dp8390setea(ether);
-
-	return 0;
-}
--- a/os/boot/pc/ether2114x.c
+++ /dev/null
@@ -1,1652 +1,0 @@
-/*
- * Digital Semiconductor DECchip 21140 PCI Fast Ethernet LAN Controller
- * as found on the Digital Fast EtherWORKS PCI 10/100 adapter (DE-500-X).
- * To do:
- *	thresholds;
- *	ring sizing;
- *	handle more error conditions;
- *	all the rest of it...
- */
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-
-#include "etherif.h"
-
-#define DEBUG		(0)
-#define debug		if(DEBUG)print
-
-enum {
-	Nrde		= 32,
-	Ntde		= 4,
-};
-
-#define Rbsz		ROUNDUP(sizeof(Etherpkt)+4, 4)
-
-enum {					/* CRS0 - Bus Mode */
-	Swr		= 0x00000001,	/* Software Reset */
-	Bar		= 0x00000002,	/* Bus Arbitration */
-	Dsl		= 0x0000007C,	/* Descriptor Skip Length (field) */
-	Ble		= 0x00000080,	/* Big/Little Endian */
-	Pbl		= 0x00003F00,	/* Programmable Burst Length (field) */
-	Cal		= 0x0000C000,	/* Cache Alignment (field) */
-	Cal8		= 0x00004000,	/* 8 longword boundary alignment */
-	Cal16		= 0x00008000,	/* 16 longword boundary alignment */
-	Cal32		= 0x0000C000,	/* 32 longword boundary alignment */
-	Tap		= 0x000E0000,	/* Transmit Automatic Polling (field) */
-	Dbo		= 0x00100000,	/* Descriptor Byte Ordering Mode */
-	Rml		= 0x00200000,	/* Read Multiple */
-}; 
-
-enum {					/* CSR[57] - Status and Interrupt Enable */
-	Ti		= 0x00000001,	/* Transmit Interrupt */
-	Tps		= 0x00000002,	/* Transmit Process Stopped */
-	Tu		= 0x00000004,	/* Transmit buffer Unavailable */
-	Tjt		= 0x00000008,	/* Transmit Jabber Timeout */
-	Unf		= 0x00000020,	/* transmit UNderFlow */
-	Ri		= 0x00000040,	/* Receive Interrupt */
-	Ru		= 0x00000080,	/* Receive buffer Unavailable */
-	Rps		= 0x00000100,	/* Receive Process Stopped */
-	Rwt		= 0x00000200,	/* Receive Watchdog Timeout */
-	Eti		= 0x00000400,	/* Early Transmit Interrupt */
-	Gte		= 0x00000800,	/* General purpose Timer Expired */
-	Fbe		= 0x00002000,	/* Fatal Bit Error */
-	Ais		= 0x00008000,	/* Abnormal Interrupt Summary */
-	Nis		= 0x00010000,	/* Normal Interrupt Summary */
-	Rs		= 0x000E0000,	/* Receive process State (field) */
-	Ts		= 0x00700000,	/* Transmit process State (field) */
-	Eb		= 0x03800000,	/* Error bits */
-};
-
-enum {					/* CSR6 - Operating Mode */
-	Hp		= 0x00000001,	/* Hash/Perfect receive filtering mode */
-	Sr		= 0x00000002,	/* Start/stop Receive */
-	Ho		= 0x00000004,	/* Hash-Only filtering mode */
-	Pb		= 0x00000008,	/* Pass Bad frames */
-	If		= 0x00000010,	/* Inverse Filtering */
-	Sb		= 0x00000020,	/* Start/stop Backoff counter */
-	Pr		= 0x00000040,	/* Promiscuous Mode */
-	Pm		= 0x00000080,	/* Pass all Multicast */
-	Fd		= 0x00000200,	/* Full Duplex mode */
-	Om		= 0x00000C00,	/* Operating Mode (field) */
-	Fc		= 0x00001000,	/* Force Collision */
-	St		= 0x00002000,	/* Start/stop Transmission Command */
-	Tr		= 0x0000C000,	/* ThReshold control bits (field) */
-	Tr128		= 0x00000000,
-	Tr256		= 0x00004000,
-	Tr512		= 0x00008000,
-	Tr1024		= 0x0000C000,
-	Ca		= 0x00020000,	/* CApture effect enable */
-	Ps		= 0x00040000,	/* Port Select */
-	Hbd		= 0x00080000,	/* HeartBeat Disable */
-	Imm		= 0x00100000,	/* IMMediate mode */
-	Sf		= 0x00200000,	/* Store and Forward */
-	Ttm		= 0x00400000,	/* Transmit Threshold Mode */
-	Pcs		= 0x00800000,	/* PCS function */
-	Scr		= 0x01000000,	/* SCRambler mode */
-	Mbo		= 0x02000000,	/* Must Be One */
-	Ra		= 0x40000000,	/* Receive All */
-	Sc		= 0x80000000,	/* Special Capture effect enable */
-
-	TrMODE		= Tr512,	/* default transmission threshold */
-};
-
-enum {					/* CSR9 - ROM and MII Management */
-	Scs		= 0x00000001,	/* serial ROM chip select */
-	Sclk		= 0x00000002,	/* serial ROM clock */
-	Sdi		= 0x00000004,	/* serial ROM data in */
-	Sdo		= 0x00000008,	/* serial ROM data out */
-	Ss		= 0x00000800,	/* serial ROM select */
-	Wr		= 0x00002000,	/* write */
-	Rd		= 0x00004000,	/* read */
-
-	Mdc		= 0x00010000,	/* MII management clock */
-	Mdo		= 0x00020000,	/* MII management write data */
-	Mii		= 0x00040000,	/* MII management operation mode (W) */
-	Mdi		= 0x00080000,	/* MII management data in */
-};
-
-enum {					/* CSR12 - General-Purpose Port */
-	Gpc		= 0x00000100,	/* General Purpose Control */
-};
-
-typedef struct Des {
-	int	status;
-	int	control;
-	ulong	addr;
-	void*	bp;
-} Des;
-
-enum {					/* status */
-	Of		= 0x00000001,	/* Rx: OverFlow */
-	Ce		= 0x00000002,	/* Rx: CRC Error */
-	Db		= 0x00000004,	/* Rx: Dribbling Bit */
-	Re		= 0x00000008,	/* Rx: Report on MII Error */
-	Rw		= 0x00000010,	/* Rx: Receive Watchdog */
-	Ft		= 0x00000020,	/* Rx: Frame Type */
-	Cs		= 0x00000040,	/* Rx: Collision Seen */
-	Tl		= 0x00000080,	/* Rx: Frame too Long */
-	Ls		= 0x00000100,	/* Rx: Last deScriptor */
-	Fs		= 0x00000200,	/* Rx: First deScriptor */
-	Mf		= 0x00000400,	/* Rx: Multicast Frame */
-	Rf		= 0x00000800,	/* Rx: Runt Frame */
-	Dt		= 0x00003000,	/* Rx: Data Type (field) */
-	De		= 0x00004000,	/* Rx: Descriptor Error */
-	Fl		= 0x3FFF0000,	/* Rx: Frame Length (field) */
-	Ff		= 0x40000000,	/* Rx: Filtering Fail */
-
-	Def		= 0x00000001,	/* Tx: DEFerred */
-	Uf		= 0x00000002,	/* Tx: UnderFlow error */
-	Lf		= 0x00000004,	/* Tx: Link Fail report */
-	Cc		= 0x00000078,	/* Tx: Collision Count (field) */
-	Hf		= 0x00000080,	/* Tx: Heartbeat Fail */
-	Ec		= 0x00000100,	/* Tx: Excessive Collisions */
-	Lc		= 0x00000200,	/* Tx: Late Collision */
-	Nc		= 0x00000400,	/* Tx: No Carrier */
-	Lo		= 0x00000800,	/* Tx: LOss of carrier */
-	To		= 0x00004000,	/* Tx: Transmission jabber timeOut */
-
-	Es		= 0x00008000,	/* [RT]x: Error Summary */
-	Own		= 0x80000000,	/* [RT]x: OWN bit */
-};
-
-enum {					/* control */
-	Bs1		= 0x000007FF,	/* [RT]x: Buffer 1 Size */
-	Bs2		= 0x003FF800,	/* [RT]x: Buffer 2 Size */
-
-	Ch		= 0x01000000,	/* [RT]x: second address CHained */
-	Er		= 0x02000000,	/* [RT]x: End of Ring */
-
-	Ft0		= 0x00400000,	/* Tx: Filtering Type 0 */
-	Dpd		= 0x00800000,	/* Tx: Disabled PaDding */
-	Ac		= 0x04000000,	/* Tx: Add CRC disable */
-	Set		= 0x08000000,	/* Tx: SETup packet */
-	Ft1		= 0x10000000,	/* Tx: Filtering Type 1 */
-	Fseg		= 0x20000000,	/* Tx: First SEGment */
-	Lseg		= 0x40000000,	/* Tx: Last SEGment */
-	Ic		= 0x80000000,	/* Tx: Interrupt on Completion */
-};
-
-enum {					/* PHY registers */
-	Bmcr		= 0,		/* Basic Mode Control */
-	Bmsr		= 1,		/* Basic Mode Status */
-	Phyidr1		= 2,		/* PHY Identifier #1 */
-	Phyidr2		= 3,		/* PHY Identifier #2 */
-	Anar		= 4,		/* Auto-Negotiation Advertisment */
-	Anlpar		= 5,		/* Auto-Negotiation Link Partner Ability */
-	Aner		= 6,		/* Auto-Negotiation Expansion */
-};
-
-enum {					/* Variants */
-	Tulip0		= (0x0009<<16)|0x1011,
-	Tulip1		= (0x0014<<16)|0x1011,
-	Tulip3		= (0x0019<<16)|0x1011,
-	Pnic		= (0x0002<<16)|0x11AD,
-	Pnic2		= (0xC115<<16)|0x11AD,
-};
-
-typedef struct Ctlr Ctlr;
-typedef struct Ctlr {
-	int	port;
-	Pcidev*	pcidev;
-	Ctlr*	next;
-	int	active;
-	int	id;			/* (pcidev->did<<16)|pcidev->vid */
-
-	uchar	*srom;
-	int	sromsz;
-	uchar*	sromea;			/* MAC address */
-	uchar*	leaf;
-	int	sct;			/* selected connection type */
-	int	k;			/* info block count */
-	uchar*	infoblock[16];
-	int	sctk;			/* sct block index */
-	int	curk;			/* current block index */
-	uchar*	type5block;
-
-	int	phy[32];		/* logical to physical map */
-	int	phyreset;		/* reset bitmap */
-	int	curphyad;
-	int	fdx;
-	int	ttm;
-
-	uchar	fd;			/* option */
-	int	medium;			/* option */
-
-	int	csr6;			/* CSR6 - operating mode */
-	int	mask;			/* CSR[57] - interrupt mask */
-	int	mbps;
-
-	Des*	rdr;			/* receive descriptor ring */
-	int	nrdr;			/* size of rdr */
-	int	rdrx;			/* index into rdr */
-
-	Des*	tdr;			/* transmit descriptor ring */
-	int	ntdr;			/* size of tdr */
-	int	tdrh;			/* host index into tdr */
-	int	tdri;			/* interface index into tdr */
-	int	ntq;			/* descriptors active */
-	Block*	setupbp;
-
-	ulong	of;			/* receive statistics */
-	ulong	ce;
-	ulong	cs;
-	ulong	tl;
-	ulong	rf;
-	ulong	de;
-
-	ulong	uf;			/* transmit statistics */
-	ulong	ec;
-	ulong	lc;
-	ulong	nc;
-	ulong	lo;
-	ulong	to;
-
-} Ctlr;
-
-static Ctlr* ctlrhead;
-static Ctlr* ctlrtail;
-
-#define csr32r(c, r)	(inl((c)->port+((r)*8)))
-#define csr32w(c, r, l)	(outl((c)->port+((r)*8), (ulong)(l)))
-
-static void
-attach(Ether* ether)
-{
-	Ctlr *ctlr;
-
-	ctlr = ether->ctlr;
-	if(!(ctlr->csr6 & Sr)){
-		ctlr->csr6 |= Sr;
-		csr32w(ctlr, 6, ctlr->csr6);
-	}
-}
-
-static void
-transmit(Ether* ether)
-{
-	Ctlr *ctlr;
-	Block *bp;
-	Des *des;
-	int control;
-	RingBuf *tb;
-
-	ctlr = ether->ctlr;
-	while(ctlr->ntq < (ctlr->ntdr-1)){
-		if(ctlr->setupbp){
-			bp = ctlr->setupbp;
-			ctlr->setupbp = 0;
-			control = Ic|Set|BLEN(bp);
-		}
-		else{
-			if(ether->ntb == 0)
-				break;
-			tb = &ether->tb[ether->ti];
-			if(tb->owner != Interface)
-				break;
-			bp = allocb(tb->len);
-			memmove(bp->wp, tb->pkt, tb->len);
-			memmove(bp->wp+Eaddrlen, ether->ea, Eaddrlen);
-			bp->wp += tb->len;
-
-			tb->owner = Host;
-			ether->ti = NEXT(ether->ti, ether->ntb);
-
-			control = Ic|Lseg|Fseg|BLEN(bp);
-		}
-
-		ctlr->tdr[PREV(ctlr->tdrh, ctlr->ntdr)].control &= ~Ic;
-		des = &ctlr->tdr[ctlr->tdrh];
-		des->bp = bp;
-		des->addr = PADDR(bp->rp);
-		des->control |= control;
-		ctlr->ntq++;
-		//coherence();
-		des->status = Own;
-		csr32w(ctlr, 1, 0);
-		ctlr->tdrh = NEXT(ctlr->tdrh, ctlr->ntdr);
-	}
-}
-
-static void
-interrupt(Ureg*, void* arg)
-{
-	Ctlr *ctlr;
-	Ether *ether;
-	int len, status;
-	Des *des;
-	RingBuf *ring;
-
-	ether = arg;
-	ctlr = ether->ctlr;
-
-	while((status = csr32r(ctlr, 5)) & (Nis|Ais)){
-		/*
-		 * Acknowledge the interrupts and mask-out
-		 * the ones that are implicitly handled.
-		 */
-		csr32w(ctlr, 5, status);
-		status &= (ctlr->mask & ~(Nis|Ais|Ti));
-
-		/*
-		 * Received packets.
-		 */
-		if(status & Ri){
-			des = &ctlr->rdr[ctlr->rdrx];
-			while((des->status & Own) == 0){
-				len = ((des->status & Fl)>>16)-4;
-				if(des->status & Es){
-					if(des->status & Of)
-						ctlr->of++;
-					if(des->status & Ce)
-						ctlr->ce++;
-					if(des->status & Cs)
-						ctlr->cs++;
-					if(des->status & Tl)
-						ctlr->tl++;
-					if(des->status & Rf)
-						ctlr->rf++;
-					if(des->status & De)
-						ctlr->de++;
-				}
-				else{
-					ring = &ether->rb[ether->ri];
-					if(ring->owner == Interface){
-						ring->owner = Host;
-						ring->len = len;
-						memmove(ring->pkt, des->bp, len);
-						ether->ri = NEXT(ether->ri, ether->nrb);
-					}
-				}
-
-				des->control &= Er;
-				des->control |= Rbsz;
-				des->status = Own;
-
-				ctlr->rdrx = NEXT(ctlr->rdrx, ctlr->nrdr);
-				des = &ctlr->rdr[ctlr->rdrx];
-			}
-			status &= ~Ri;
-		}
-
-		/*
-		 * Check the transmit side:
-		 *	check for Transmit Underflow and Adjust
-		 *	the threshold upwards;
-		 *	free any transmitted buffers and try to
-		 *	top-up the ring.
-		 */
-		if(status & Unf){
-			csr32w(ctlr, 6, ctlr->csr6 & ~St);
-			switch(ctlr->csr6 & Tr){
-			case Tr128:
-				len = Tr256;
-				break;
-			case Tr256:
-				len = Tr512;
-				break;
-			case Tr512:
-				len = Tr1024;
-				break;
-			default:
-			case Tr1024:
-				len = Sf;
-				break;
-			}
-			ctlr->csr6 = (ctlr->csr6 & ~Tr)|len;
-			csr32w(ctlr, 6, ctlr->csr6);
-			csr32w(ctlr, 5, Tps);
-			status &= ~(Unf|Tps);
-		}
-
-		while(ctlr->ntq){
-			des = &ctlr->tdr[ctlr->tdri];
-			if(des->status & Own)
-				break;
-
-			if(des->status & Es){
-				if(des->status & Uf)
-					ctlr->uf++;
-				if(des->status & Ec)
-					ctlr->ec++;
-				if(des->status & Lc)
-					ctlr->lc++;
-				if(des->status & Nc)
-					ctlr->nc++;
-				if(des->status & Lo)
-					ctlr->lo++;
-				if(des->status & To)
-					ctlr->to++;
-			}
-
-			freeb(des->bp);
-			des->control &= Er;
-
-			ctlr->ntq--;
-			ctlr->tdri = NEXT(ctlr->tdri, ctlr->ntdr);
-		}
-		transmit(ether);
-
-		/*
-		 * Anything left not catered for?
-		 */
-		if(status)
-			panic("#l%d: status %8.8uX\n", ether->ctlrno, status);
-	}
-}
-
-static void
-ctlrinit(Ether* ether)
-{
-	Ctlr *ctlr;
-	Des *des;
-	Block *bp;
-	int i;
-	uchar bi[Eaddrlen*2];
-
-	ctlr = ether->ctlr;
-
-	/*
-	 * Allocate and initialise the receive ring;
-	 * allocate and initialise the transmit ring;
-	 * unmask interrupts and start the transmit side;
-	 * create and post a setup packet to initialise
-	 * the physical ethernet address.
-	 */
-	ctlr->rdr = malloc(ctlr->nrdr*sizeof(Des));
-	for(des = ctlr->rdr; des < &ctlr->rdr[ctlr->nrdr]; des++){
-		des->bp = malloc(Rbsz);
-		des->status = Own;
-		des->control = Rbsz;
-		des->addr = PADDR(des->bp);
-	}
-	ctlr->rdr[ctlr->nrdr-1].control |= Er;
-	ctlr->rdrx = 0;
-	csr32w(ctlr, 3, PADDR(ctlr->rdr));
-
-	ctlr->tdr = ialloc(ctlr->ntdr*sizeof(Des), 32);
-	ctlr->tdr[ctlr->ntdr-1].control |= Er;
-	ctlr->tdrh = 0;
-	ctlr->tdri = 0;
-	csr32w(ctlr, 4, PADDR(ctlr->tdr));
-
-	/*
-	 * Clear any bits in the Status Register (CSR5) as
-	 * the PNIC has a different reset value from a true 2114x.
-	 */
-	ctlr->mask = Nis|Ais|Fbe|Rwt|Rps|Ru|Ri|Unf|Tjt|Tps|Ti;
-	csr32w(ctlr, 5, ctlr->mask);
-	csr32w(ctlr, 7, ctlr->mask);
-	ctlr->csr6 |= St;
-	csr32w(ctlr, 6, ctlr->csr6);
-
-	for(i = 0; i < Eaddrlen/2; i++){
-		bi[i*4] = ether->ea[i*2];
-		bi[i*4+1] = ether->ea[i*2+1];
-		bi[i*4+2] = ether->ea[i*2+1];
-		bi[i*4+3] = ether->ea[i*2];
-	}
-	bp = allocb(Eaddrlen*2*16);
-	memset(bp->rp, 0xFF, sizeof(bi));
-	for(i = sizeof(bi); i < sizeof(bi)*16; i += sizeof(bi))
-		memmove(bp->rp+i, bi, sizeof(bi));
-	bp->wp += sizeof(bi)*16;
-
-	ctlr->setupbp = bp;
-	transmit(ether);
-}
-
-static void
-csr9w(Ctlr* ctlr, int data)
-{
-	csr32w(ctlr, 9, data);
-	microdelay(1);
-}
-
-static int
-miimdi(Ctlr* ctlr, int n)
-{
-	int data, i;
-
-	/*
-	 * Read n bits from the MII Management Register.
-	 */
-	data = 0;
-	for(i = n-1; i >= 0; i--){
-		if(csr32r(ctlr, 9) & Mdi)
-			data |= (1<<i);
-		csr9w(ctlr, Mii|Mdc);
-		csr9w(ctlr, Mii);
-	}
-	csr9w(ctlr, 0);
-
-	return data;
-}
-
-static void
-miimdo(Ctlr* ctlr, int bits, int n)
-{
-	int i, mdo;
-
-	/*
-	 * Write n bits to the MII Management Register.
-	 */
-	for(i = n-1; i >= 0; i--){
-		if(bits & (1<<i))
-			mdo = Mdo;
-		else
-			mdo = 0;
-		csr9w(ctlr, mdo);
-		csr9w(ctlr, mdo|Mdc);
-		csr9w(ctlr, mdo);
-	}
-}
-
-static int
-miir(Ctlr* ctlr, int phyad, int regad)
-{
-	int data, i;
-
-	if(ctlr->id == Pnic){
-		i = 1000;
-		csr32w(ctlr, 20, 0x60020000|(phyad<<23)|(regad<<18));
-		do{
-			microdelay(1);
-			data = csr32r(ctlr, 20);
-		}while((data & 0x80000000) && --i);
-
-		if(i == 0)
-			return -1;
-		return data & 0xFFFF;
-	}
-
-	/*
-	 * Preamble;
-	 * ST+OP+PHYAD+REGAD;
-	 * TA + 16 data bits.
-	 */
-	miimdo(ctlr, 0xFFFFFFFF, 32);
-	miimdo(ctlr, 0x1800|(phyad<<5)|regad, 14);
-	data = miimdi(ctlr, 18);
-
-	if(data & 0x10000)
-		return -1;
-
-	return data & 0xFFFF;
-}
-
-static void
-miiw(Ctlr* ctlr, int phyad, int regad, int data)
-{
-	/*
-	 * Preamble;
-	 * ST+OP+PHYAD+REGAD+TA + 16 data bits;
-	 * Z.
-	 */
-	miimdo(ctlr, 0xFFFFFFFF, 32);
-	data &= 0xFFFF;
-	data |= (0x05<<(5+5+2+16))|(phyad<<(5+2+16))|(regad<<(2+16))|(0x02<<16);
-	miimdo(ctlr, data, 32);
-	csr9w(ctlr, Mdc);
-	csr9w(ctlr, 0);
-}
-
-static int
-sromr(Ctlr* ctlr, int r)
-{
-	int i, op, data, size;
-
-	if(ctlr->id == Pnic){
-		i = 1000;
-		csr32w(ctlr, 19, 0x600|r);
-		do{
-			microdelay(1);
-			data = csr32r(ctlr, 19);
-		}while((data & 0x80000000) && --i);
-
-		if(ctlr->sromsz == 0)
-			ctlr->sromsz = 6;
-
-		return csr32r(ctlr, 9) & 0xFFFF;
-	}
-
-	/*
-	 * This sequence for reading a 16-bit register 'r'
-	 * in the EEPROM is taken (pretty much) straight from Section
-	 * 7.4 of the 21140 Hardware Reference Manual.
-	 */
-reread:
-	csr9w(ctlr, Rd|Ss);
-	csr9w(ctlr, Rd|Ss|Scs);
-	csr9w(ctlr, Rd|Ss|Sclk|Scs);
-	csr9w(ctlr, Rd|Ss);
-
-	op = 0x06;
-	for(i = 3-1; i >= 0; i--){
-		data = Rd|Ss|(((op>>i) & 0x01)<<2)|Scs;
-		csr9w(ctlr, data);
-		csr9w(ctlr, data|Sclk);
-		csr9w(ctlr, data);
-	}
-
-	/*
-	 * First time through must work out the EEPROM size.
-	 * This doesn't seem to work on the 21041 as implemented
-	 * in Virtual PC for the Mac, so wire any 21041 to 6,
-	 * it's the only 21041 this code will ever likely see.
-	 */
-	if((size = ctlr->sromsz) == 0){
-		if(ctlr->id == Tulip1)
-			ctlr->sromsz = size = 6;
-		else
-			size = 8;
-	}
-
-	for(size = size-1; size >= 0; size--){
-		data = Rd|Ss|(((r>>size) & 0x01)<<2)|Scs;
-		csr9w(ctlr, data);
-		csr9w(ctlr, data|Sclk);
-		csr9w(ctlr, data);
-		microdelay(1);
-		if(ctlr->sromsz == 0 && !(csr32r(ctlr, 9) & Sdo))
-			break;
-	}
-
-	data = 0;
-	for(i = 16-1; i >= 0; i--){
-		csr9w(ctlr, Rd|Ss|Sclk|Scs);
-		if(csr32r(ctlr, 9) & Sdo)
-			data |= (1<<i);
-		csr9w(ctlr, Rd|Ss|Scs);
-	}
-
-	csr9w(ctlr, 0);
-
-	if(ctlr->sromsz == 0){
-		ctlr->sromsz = 8-size;
-		goto reread;
-	}
-
-	return data & 0xFFFF;
-}
-
-static void
-softreset(Ctlr* ctlr)
-{
-	/*
-	 * Soft-reset the controller and initialise bus mode.
-	 * Delay should be >= 50 PCI cycles (2×S @ 25MHz).
-	 */
-	csr32w(ctlr, 0, Swr);
-	microdelay(10);
-	csr32w(ctlr, 0, Rml|Cal16);
-	delay(1);
-}
-
-static int
-type5block(Ctlr* ctlr, uchar* block)
-{
-	int csr15, i, len;
-
-	/*
-	 * Reset or GPR sequence. Reset should be once only,
-	 * before the GPR sequence.
-	 * Note 'block' is not a pointer to the block head but
-	 * a pointer to the data in the block starting at the
-	 * reset length value so type5block can be used for the
-	 * sequences contained in type 1 and type 3 blocks.
-	 * The SROM docs state the 21140 type 5 block is the
-	 * same as that for the 21143, but the two controllers
-	 * use different registers and sequence-element lengths
-	 * so the 21140 code here is a guess for a real type 5
-	 * sequence.
-	 */
-	len = *block++;
-	if(ctlr->id != Tulip3){
-		for(i = 0; i < len; i++){
-			csr32w(ctlr, 12, *block);
-			block++;
-		}
-		return len;
-	}
-
-	for(i = 0; i < len; i++){
-		csr15 = *block++<<16;
-		csr15 |= *block++<<24;
-		csr32w(ctlr, 15, csr15);
-		debug("%8.8uX ", csr15);
-	}
-	return 2*len;
-}
-
-static int
-typephylink(Ctlr* ctlr, uchar*)
-{
-	int an, bmcr, bmsr, csr6, x;
-
-	/*
-	 * Fail if
-	 *	auto-negotiataion enabled but not complete;
-	 *	no valid link established.
-	 */
-	bmcr = miir(ctlr, ctlr->curphyad, Bmcr);
-	miir(ctlr, ctlr->curphyad, Bmsr);
-	bmsr = miir(ctlr, ctlr->curphyad, Bmsr);
-	debug("bmcr 0x%2.2uX bmsr 0x%2.2uX\n", bmcr, bmsr);
-	if(((bmcr & 0x1000) && !(bmsr & 0x0020)) || !(bmsr & 0x0004))
-		return 0;
-
-	if(bmcr & 0x1000){
-		an = miir(ctlr, ctlr->curphyad, Anar);
-		an &= miir(ctlr, ctlr->curphyad, Anlpar) & 0x3E0;
-		debug("an 0x%2.uX 0x%2.2uX 0x%2.2uX\n",
-	    		miir(ctlr, ctlr->curphyad, Anar),
-			miir(ctlr, ctlr->curphyad, Anlpar),
-			an);
-	
-		if(an & 0x0100)
-			x = 0x4000;
-		else if(an & 0x0080)
-			x = 0x2000;
-		else if(an & 0x0040)
-			x = 0x1000;
-		else if(an & 0x0020)
-			x = 0x0800;
-		else
-			x = 0;
-	}
-	else if((bmcr & 0x2100) == 0x2100)
-		x = 0x4000;
-	else if(bmcr & 0x2000){
-		/*
-		 * If FD capable, force it if necessary.
-		 */
-		if((bmsr & 0x4000) && ctlr->fd){
-			miiw(ctlr, ctlr->curphyad, Bmcr, 0x2100);
-			x = 0x4000;
-		}
-		else
-			x = 0x2000;
-	}
-	else if(bmcr & 0x0100)
-		x = 0x1000;
-	else
-		x = 0x0800;
-
-	csr6 = Sc|Mbo|Hbd|Ps|Ca|TrMODE|Sb;
-	if(ctlr->fdx & x)
-		csr6 |= Fd;
-	if(ctlr->ttm & x)
-		csr6 |= Ttm;