~kris/9p

9hist

067a84ef4d5019c744d3aacd09706afd2e0088db — David du Colombier 25 years ago 09349c7
Plan 9 from Bell Labs 2000-10-19
M bitsy/clock.c => bitsy/clock.c +15 -4
@@ 17,6 17,7 @@ typedef struct OSTimer
} OSTimer;

static OSTimer *timerregs = (OSTimer*)OSTIMERREGS;
static int clockinited;

static void	clockintr(Ureg*, void*);



@@ 58,6 59,8 @@ clockinit(void)

	/* post interrupt 1/HZ secs from now */
	timerregs->osmr[0] = timerregs->oscr + ClockFreq/HZ;

	clockinited = 1;
}

vlong


@@ 110,9 113,17 @@ void
delay(int ms)
{
	ulong start;

	while(ms-- > 0){
		start = timerregs->oscr;
		while(timerregs->oscr-start < ClockFreq/1000);
	int i;

	if(clockinited){
		while(ms-- > 0){
			start = timerregs->oscr;
			while(timerregs->oscr-start < ClockFreq/1000);
		}
	} else {
		while(ms-- > 0){
			for(i = 0; i < 1000; i++)
				;
		}
	}
}

M bitsy/devuart.c => bitsy/devuart.c +32 -39
@@ 45,6 45,7 @@ uartsetup(PhysUart *phys, void *regs, ulong freq, char *name)
		return nil;

	p = xalloc(sizeof(Uart));
	memset(p, 0, sizeof(*p));
	uart[nuart] = p;
	strcpy(p->name, name);
	p->dev = nuart++;


@@ 68,7 69,8 @@ uartsetup(PhysUart *phys, void *regs, ulong freq, char *name)
	if(p->iq == nil || p->oq == nil)
		panic("uartsetup");

	p->ip = p->istage;
	p->ir = p->istage;
	p->iw = p->istage;
	p->ie = &p->istage[Stagesize];
	p->op = p->ostage;
	p->oe = p->ostage;


@@ 235,7 237,7 @@ uartclose(Chan *c)
			uartdisable(p);
			qclose(p->iq);
			qclose(p->oq);
			p->ip = p->istage;
			p->ir = p->iw = p->istage;
			p->dcd = p->dsr = p->dohup = 0;
		}
		qunlock(p);


@@ 465,12 467,8 @@ uartflow(void *v)
	Uart *p;

	p = v;
	if(p->modem){
	if(p->modem)
		(*p->phys->rts)(p, 1);
		ilock(&p->rlock);
		p->haveinput = 1;
		iunlock(&p->rlock);
	}
}

/*


@@ 509,6 507,8 @@ uartkick(void *v)
void
uartrecv(Uart *p,  char ch)
{
	uchar *next;

	/* software flow control */
	if(p->xonoff){
		if(ch == CTLS){


@@ 523,59 523,52 @@ uartrecv(Uart *p,  char ch)
	if(p->putc)
		p->putc(p->iq, ch);
	else {
		ilock(&p->rlock);
		if(p->ip < p->ie)
			*p->ip++ = ch;
		p->haveinput = 1;
		iunlock(&p->rlock);
		next = p->iw + 1;
		if(next == p->ie)
			next = p->istage;
		if(next != p->ir){
			*p->iw = ch;
			p->iw = next;
		}
	}
}

/*
 *  we save up input characters till clock time to reduce
 *  per character interrupt overhead.
 *
 *  There's also a bit of code to get a stalled print going.
 *  It shouldn't happen, but it does.  Obviously I don't
 *  understand something.  Since it was there, I bundled a
 *  restart after flow control with it to give some hysteresis
 *  to the hardware flow control.  This makes compressing
 *  modems happier but will probably bother something else.
 *	 -- presotto
 */
static void
uartclock(void)
{
	int n;
	Uart *p;
	uchar *iw;

	for(p = uartalloc.elist; p; p = p->elist){

		/* this amortizes cost of qproduce to many chars */
		if(p->haveinput){
			ilock(&p->rlock);
			if(p->haveinput){
				n = p->ip - p->istage;
				if(n > 0 && p->iq){
					if(n > Stagesize)
						panic("uartclock");
					if(qproduce(p->iq, p->istage, n) < 0)
		if(p->iw != p->ir){
			iw = p->iw;
			if(iw < p->ir){
				if(qproduce(p->iq, p->ir, p->ie-p->ir) < 0){
					(*p->phys->rts)(p, 0);
					p->ir = p->istage;
				} else {
					if(qproduce(p->iq, p->istage, iw-p->istage) < 0)
						(*p->phys->rts)(p, 0);
					else
						p->ip = p->istage;
					p->ir = iw;
				}
				p->haveinput = 0;
			} else {
				if(qproduce(p->iq, p->ir, iw-p->ir) < 0)
					(*p->phys->rts)(p, 0);
				p->ir = iw;
			}
			iunlock(&p->rlock);
		}

		/* hang up if requested */
		if(p->dohup){
			ilock(&p->rlock);
			if(p->dohup){
				qhangup(p->iq, 0);
				qhangup(p->oq, 0);
			}
			qhangup(p->iq, 0);
			qhangup(p->oq, 0);
			p->dohup = 0;
			iunlock(&p->rlock);
		}

		/* this adds hysteresis to hardware/software flow control */

M bitsy/io.h => bitsy/io.h +2 -4
@@ 139,13 139,11 @@ struct Uart
	Queue	*iq;
	Queue	*oq;

	Lock	rlock;			/* receive */
	uchar	istage[Stagesize];
	uchar	*ip;
	uchar	*iw;
	uchar	*ir;
	uchar	*ie;

	int	haveinput;

	Lock	tlock;			/* transmit */
	uchar	ostage[Stagesize];
	uchar	*op;

M bitsy/main.c => bitsy/main.c +3 -3
@@ 35,8 35,9 @@ main(void)
	mmuinit();
	gpioinit();
	trapinit();
	screeninit();
	sa1100_uartsetup(1);
	rs232power(1);
	screeninit();
	printinit();	/* from here on, print works, before this we need iprint */
	clockinit();
	procinit0();


@@ 216,7 217,6 @@ userinit(void)
	k = kmap(s->map[0]->pages[0]);
	memmove((ulong*)VA(k), initcode, sizeof initcode);
	kunmap(k);
//iprint("userinit %lux[0x20] = %lux\n", VA(k), *((ulong*)(VA(k)+0x20)));

	ready(p);
}


@@ 351,7 351,7 @@ confinit(void)
}

GPIOregs *gpioregs;
ulong *egpioreg;
ulong *egpioreg = (ulong*)EGPIOREGS;

static void
gpioinit(void)

M bitsy/mem.h => bitsy/mem.h +1 -1
@@ 144,7 144,7 @@
#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 */
#define CpTest		15		/* W: Test, Clock and Idle Control */

/*
 *  CpControl

M bitsy/mmu.c => bitsy/mmu.c +13 -12
@@ 127,12 127,12 @@ mapspecial(ulong pa, int len)
{
	ulong *t;
	ulong va, i, base, end, off, entry;
	int livelarge;
	int large;
	ulong* rv;

	rv = nil;
	livelarge = len >= 128*1024;
	if(livelarge){
	large = len >= 128*1024;
	if(large){
		base = pa & ~(OneMeg-1);
		end = (pa+len-1) & ~(OneMeg-1);
	} else {


@@ 145,7 145,7 @@ mapspecial(ulong pa, int len)
		switch(l1table[va>>20] & L1TypeMask){
		default:
			/* found unused entry on level 1 table */
			if(livelarge){
			if(large){
				if(rv == nil)
					rv = (ulong*)(va+off);
				l1table[va>>20] = L1Section | L1KernelRW | L1Domain0 |


@@ 171,14 171,14 @@ mapspecial(ulong pa, int len)
				
			continue;
		case L1PageTable:
			if(livelarge)
			if(large)
				continue;
			break;
		}

		/* here if we're using page maps instead of sections */
		t = (ulong*)(l1table[va>>20] & L1PTBaseMask);
		for(i = 0; i < OneMeg; i += BY2PG){
		for(i = 0; i < OneMeg && base <= end; i += BY2PG){
			entry = t[i>>PGSHIFT];

			/* found unused entry on level 2 table */


@@ 196,6 196,7 @@ mapspecial(ulong pa, int len)
	/* didn't fit */
	if(base <= end)
		return nil;
	cacheflush();

	return rv;
}


@@ 359,23 360,23 @@ flushmmu(void)
void
peekmmu(ulong va)
{
	ulong e;
	ulong e, d;

	e = l1table[va>>20];
	switch(e & L1TypeMask){
	default:
		iprint("l1: %lux invalid\n", e);
		iprint("l1: %lux[%lux] = %lux invalid\n", l1table, va>>20, e);
		break;
	case L1PageTable:
		iprint("l1: %lux pt\n", e);
		iprint("l1: %lux[%lux] = %lux pt\n", l1table, va>>20, e);
		va &= OneMeg-1;
		va >>= PGSHIFT;
		e &= L1PTBaseMask;
		e = ((ulong*)e)[va];
		iprint("l2: %lux\n", e);
		d = ((ulong*)e)[va];
		iprint("l2: %lux[%lux] = %lux\n", e, va, d);
		break;
	case L1Section:
		iprint("l1: %lux section\n", e);
		iprint("l1: %lux[%lux] = %lux section\n", l1table, va>>20, e);
		break;
	}
}

M bitsy/sa1110uart.c => bitsy/sa1110uart.c +46 -8
@@ 63,6 63,7 @@ enum
};

Uartregs *uart3regs = UART3REGS;
Uartregs *uart1regs = UART1REGS ;

static void	sa1100_uartbaud(Uart *p, int rate);
static void	sa1100_uartkick(Uart *p);


@@ 160,14 161,21 @@ static void
sa1100_uartbaud(Uart *p, int rate)
{
	ulong brconst;
	ulong ctl3;

	if(rate <= 0)
		return;

	/* disable */
	ctl3 = R(p)->ctl[3];
	R(p)->ctl[3] = 0;

	brconst = p->freq/(16*rate) - 1;
	R(p)->ctl[1] = (brconst>>8) & 0xf;
	R(p)->ctl[2] = brconst;
	R(p)->ctl[2] = brconst & 0xff;

	/* reenable */
	R(p)->ctl[3] = ctl3;
	p->baud = rate;
}



@@ 191,6 199,12 @@ sa1100_uartbreak(Uart *p, int ms)
static void
sa1100_uartbits(Uart *p, int n)
{
	ulong ctl3;

	/* disable */
	ctl3 = R(p)->ctl[3];
	R(p)->ctl[3] = 0;

	switch(n){
	case 7:
		R(p)->ctl[0] &= ~Bits8;


@@ 201,6 215,9 @@ sa1100_uartbits(Uart *p, int n)
	default:
		error(Ebadarg);
	}

	/* reenable */
	R(p)->ctl[3] = ctl3;
}

/*


@@ 209,6 226,12 @@ sa1100_uartbits(Uart *p, int n)
static void
sa1100_uartstop(Uart *p, int n)
{
	ulong ctl3;

	/* disable */
	ctl3 = R(p)->ctl[3];
	R(p)->ctl[3] = 0;

	switch(n){
	case 1:
		R(p)->ctl[0] &= ~Stop2;


@@ 219,6 242,9 @@ sa1100_uartstop(Uart *p, int n)
	default:
		error(Ebadarg);
	}

	/* reenable */
	R(p)->ctl[3] = ctl3;
}

/*


@@ 255,6 281,12 @@ sa1100_uartmodemctl(Uart *p, int on)
static void
sa1100_uartparity(Uart *p, int type)
{
	ulong ctl3;

	/* disable */
	ctl3 = R(p)->ctl[3];
	R(p)->ctl[3] = 0;

	switch(type){
	case 'e':
		R(p)->ctl[0] |= Parity|Even;


@@ 266,6 298,9 @@ sa1100_uartparity(Uart *p, int type)
		R(p)->ctl[0] &= ~(Parity|Even);
		break;
	}

	/* reenable */
	R(p)->ctl[3] = ctl3;
}

/*


@@ 330,6 365,10 @@ sa1100_uartintr(Ureg*, void *x)
	p = x;
	regs = p->regs;

	/* receiver interrupt, snarf bytes */
	while(regs->status[1] & Rnotempty)
		uartrecv(p, regs->data);

	/* remember and reset interrupt causes */
	s = regs->status[0];
	regs->status[0] |= s;


@@ 339,10 378,6 @@ sa1100_uartintr(Ureg*, void *x)
		uartkick(p);
	}

	/* receiver interrupt, snarf bytes */
	while(regs->status[1] & Rnotempty)
		uartrecv(p, regs->data);

	if(s & (ParityError|FrameError|Overrun)){
		if(s & ParityError)
			p->parity++;


@@ 351,6 386,10 @@ sa1100_uartintr(Ureg*, void *x)
		if(s & Overrun)
			p->overrun++;
	}

	/* receiver interrupt, snarf bytes */
	while(regs->status[1] & Rnotempty)
		uartrecv(p, regs->data);
}

typedef struct Gpclkregs Gpclkregs;


@@ 379,7 418,6 @@ void
sa1100_uartsetup(int console)
{
	Uart *p;
	Uartregs *uartregs;

	/* external serial port (eia0) */
	uart3regs = mapspecial(UART3REGS, 64);


@@ 393,8 431,8 @@ sa1100_uartsetup(int console)
	/* port for talking to microcontroller (eia1) */
	gpclkregs = mapspecial(GPCLKREGS, 64);
	gpclkregs->r0 = Gpclk_sus;	/* set uart mode */
	uartregs = mapspecial(UART1REGS, 64);
	p = uartsetup(&sa1100_uart, uartregs, ClockFreq, "serialport1");
	uart1regs = mapspecial(UART1REGS, 64);
	p = uartsetup(&sa1100_uart, uart1regs, ClockFreq, "serialport1");
	sa1100_uartbaud(p, 115200);
	intrenable(IRQuart1b, sa1100_uartintr, p, p->name);
}

M bitsy/screen.c => bitsy/screen.c +197 -21
@@ 13,6 13,8 @@
#include <cursor.h>
#include "screen.h"

#define	MINX	8

enum {
	Wid		= 320,
	Ht		= 240,


@@ 78,7 80,7 @@ enum {

enum {
/* LCD Status Register, lcd->lcsr */
	LFD	=  0,	/*  1 bit */
	LDD	=  0,	/*  1 bit */
	BAU	=  1,	/*  1 bit */
	BER	=  2,	/*  1 bit */
	ABC	=  3,	/*  1 bit */


@@ 107,6 109,15 @@ struct sa1110regs {

Point	ZP = {0, 0};

static Memdata xgdata =
{
	nil,				/* *base */
	nil,				/* *bdata */
	1,					/* ref */
	nil,				/* *imref */
	0,					/* allocd */
};

static Memimage xgscreen =
{
	{ 0, 0, Wid, Ht },	/* r */


@@ 115,7 126,7 @@ static Memimage xgscreen =
	1,					/* nchan */
	RGB16,				/* chan */
	nil,				/* cmap */
	nil,				/* data */
	&xgdata,			/* data */
	0,					/* zero */
	Wid/2,				/* width */
	0,					/* layer */


@@ 125,29 136,39 @@ static Memimage xgscreen =
Memimage *gscreen;
Memimage *conscol;
Memimage *back;
Memimage *hwcursor;

Memsubfont	*memdefont;

struct{
	Point	pos;
	int	bwid;
}out;

Lock	screenlock;

Point	ZP = {0, 0};

static Rectangle window;
static Point curpos;
static int h, w;
int drawdebug;

static	ulong	rep(ulong, int);
static	void	screenwin(void);
static	void	screenputc(char *buf);
static	void	scroll(void);

static void
lcdstop(void) {
	ulong	lccr0;

	lcd->lccr0 &= ~(0<<LEN);	/* disable the LCD */
	while((lcd->lcsr & LDD) == 0)
		sleep(1);
		delay(10);
	lcdpower(0);
}

static void
lcdinit(void)
{
	/* map the lcd regs into the kernel's virtual space */
	lcd = (struct sa1110regs*)mapspecial(LCDREGS, sizeof(struct sa1110regs));;

	/* the following works because main memory is direct mapped */
	lcd->lccr0 &= ~(0<<LEN);	/* disable the LCD */
	while((lcd->lcsr & LDD) == 0)
		sleep(1);

	lcd->dbar1 = framebuf->palette;
	lcd->lccr3 = pcd<<PCD | 0<<ACB | 0<<API | 1<<VSP | 1<<HSP | 0<<PCP | 0<<OEP;
	lcd->lccr2 = (Ht-1)<<LPP | vsw<<VSW | efw<<EFW | bfw<<BFW;


@@ 159,24 180,37 @@ lcdinit(void)
void
screeninit(void)
{

	/* map the lcd regs into the kernel's virtual space */
	lcd = (struct sa1110regs*)mapspecial(LCDREGS, sizeof(struct sa1110regs));;

	framebuf = xspanalloc(sizeof *framebuf, 0x10, 0);
	memset(framebuf->palette, 0, sizeof framebuf->palette);
	memset(framebuf->pixel, 0xf8, sizeof framebuf->pixel);
	/* the following works because main memory is direct mapped */

	framebuf->palette[0] = Pal0;

	print("LCD status before power up: 0x%lux\n", lcd->lcsr);
	iprint("LCD power up\n");
	lcdpower(1);
	print("LCD status after power up: 0x%lux\n", lcd->lcsr);

	lcdinit();
	print("LCD status after lcdinit: 0x%lux\n", lcd->lcsr);

	gscreen = &xgscreen;
	gscreen->data = (struct Memdata *)framebuf->pixel;
	xgdata.bdata = (uchar *)framebuf->pixel;

	memimageinit();
	memdefont = getmemdefont();

	out.pos.x = MINX;
	out.pos.y = 0;
	out.bwid = memdefont->info[' '].width;

	screenwin();
}

void
flushmemscreen(Rectangle)
{
	/* no-op, screen is direct mapped */
}

/* 


@@ 216,5 250,147 @@ blankscreen(int blank)
void
screenputs(char *s, int n)
{
	USED(s, n);
	int i;
	Rune r;
	char buf[4];

	if(!islo()) {
		/* don't deadlock trying to print in interrupt */
		if(!canlock(&screenlock))
			return;	
	}
	else
		lock(&screenlock);

	while(n > 0){
		i = chartorune(&r, s);
		if(i == 0){
			s++;
			--n;
			continue;
		}
		memmove(buf, s, i);
		buf[i] = 0;
		n -= i;
		s += i;
		screenputc(buf);
	}
	unlock(&screenlock);
}

static void
screenwin(void)
{
	Point p, q;
	char *greet;
	Memimage *grey;

	memsetchan(gscreen, RGB16);

	back = memwhite;
	conscol = memblack;

	memfillcolor(gscreen, 0x444488FF);

	w = memdefont->info[' '].width;
	h = memdefont->height;

	window.min = Pt(8, 8);
	window.max = addpt(window.min, Pt(8+w*32, 8+h*14));

	memimagedraw(gscreen, window, memblack, ZP, memopaque, ZP);
	window = insetrect(window, 4);
	memimagedraw(gscreen, window, memwhite, ZP, memopaque, ZP);

	/* a lot of work to get a grey color */
	grey = allocmemimage(Rect(0,0,1,1), RGB16);
	grey->flags |= Frepl;
	grey->clipr = gscreen->r;
	grey->data->bdata[0] = 0x77;
	grey->data->bdata[1] = 0x77;
	memimagedraw(gscreen, Rect(window.min.x, window.min.y,
			window.max.x, window.min.y+h+5+6), grey, ZP, nil, ZP);
	freememimage(grey);
	window = insetrect(window, 5);

	greet = " Plan 9 Console ";
	p = addpt(window.min, Pt(10, 0));
	q = memsubfontwidth(memdefont, greet);
	memimagestring(gscreen, p, conscol, ZP, memdefont, greet);
	window.min.y += h+6;
	curpos = window.min;
	window.max.y = window.min.y+((window.max.y-window.min.y)/h)*h;
}

static void
screenputc(char *buf)
{
	Point p;
	int w, pos;
	Rectangle r;
	static int *xp;
	static int xbuf[256];

	if(xp < xbuf || xp >= &xbuf[sizeof(xbuf)])
		xp = xbuf;

	switch(buf[0]) {
	case '\n':
		if(curpos.y+h >= window.max.y)
			scroll();
		curpos.y += h;
		screenputc("\r");
		break;
	case '\r':
		xp = xbuf;
		curpos.x = window.min.x;
		break;
	case '\t':
		p = memsubfontwidth(memdefont, " ");
		w = p.x;
		*xp++ = curpos.x;
		pos = (curpos.x-window.min.x)/w;
		pos = 8-(pos%8);
		r = Rect(curpos.x, curpos.y, curpos.x+pos*w, curpos.y + h);
		memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min);
		curpos.x += pos*w;
		break;
	case '\b':
		if(xp <= xbuf)
			break;
		xp--;
		r = Rect(*xp, curpos.y, curpos.x, curpos.y + h);
		memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min);
		curpos.x = *xp;
		break;
	default:
		p = memsubfontwidth(memdefont, buf);
		w = p.x;

		if(curpos.x >= window.max.x-w)
			screenputc("\n");

		*xp++ = curpos.x;
		r = Rect(curpos.x, curpos.y, curpos.x+w, curpos.y + h);
		memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min);
		memimagestring(gscreen, curpos, conscol, ZP, memdefont, buf);
		curpos.x += w;
	}
}

static void
scroll(void)
{
	int o;
	Point p;
	Rectangle r;

	o = 8*h;
	r = Rpt(window.min, Pt(window.max.x, window.max.y-o));
	p = Pt(window.min.x, window.min.y+o);
	memimagedraw(gscreen, r, gscreen, p, nil, p);
	r = Rpt(Pt(window.min.x, window.max.y-o), window.max);
	memimagedraw(gscreen, r, back, ZP, nil, ZP);

	curpos.y -= o;
}

M bitsy/trap.c => bitsy/trap.c +20 -21
@@ 26,13 26,14 @@ typedef struct Vctl {

	char	name[NAMELEN];		/* of driver */
	int	irq;
	ulong	irqbit;

	void	(*f)(Ureg*, void*);	/* handler to call */
	void*	a;			/* argument to call it with */
} Vctl;

static Lock vctllock;
static Vctl *vctl[32];
static Vctl *vctl;


/*


@@ 115,15 116,16 @@ intrenable(int irq, void (*f)(Ureg*, void*), void* a, char *name)

	v = xalloc(sizeof(Vctl));
	v->irq = irq;
	v->irqbit = 1<<irq;
	v->f = f;
	v->a = a;
	strncpy(v->name, name, NAMELEN-1);
	v->name[NAMELEN-1] = 0;

	lock(&vctllock);
	v->next = vctl[irq];
	vctl[irq] = v;
	intrregs->icmr |= 1<<irq;
	v->next = vctl;
	vctl = v;
	intrregs->icmr |= v->irqbit;
	unlock(&vctllock);
}



@@ 176,7 178,7 @@ void
trap(Ureg *ureg)
{
	ulong inst;
	int i, found;
	int found;
	Vctl *v;
	int user;
	ulong va;


@@ 193,9 195,18 @@ trap(Ureg *ureg)
	else
		ureg->pc -= 4;

	if((user && (ureg->r13 & 0xf0000000)) || (ureg->psr & 0x10) != 0x10){
		warnregs(ureg, "wierd ureg");
		panic("bad ureg\n");
	if(ureg->type == PsrMirq){
		found = 0;
		va = intrregs->icip;
		for(v = vctl; v != nil; v = v->next){
			if(v->irqbit & va){
				v->f(ureg, v->a);
				found = 1;
			}
		}
		if(!found)
			print("unknown interrupt: %lux\n", intrregs->icip);
		goto out;
	}

	switch(ureg->type){


@@ 258,21 269,9 @@ trap(Ureg *ureg)
	case PsrMund:	/* undefined instruction */
		panic("undefined instruction");
		break;
	case PsrMirq:	/* device interrupt */
		for(i = 0; i < 32; i++){
			found = 0;
			if((1<<i) & intrregs->icip){
				for(v = vctl[i]; v != nil; v = v->next){
					found = 1;
					v->f(ureg, v->a);
				}
				if(!found)
					iprint("interrupt %d with no handler\n", i);
			}
		}
		break;
	}

out:
	if(user && (up->procctl || up->nnote)){
		splhi();
		notify(ureg);

M boot/boot.c => boot/boot.c +1 -0
@@ 156,6 156,7 @@ boot(int argc, char *argv[])
		for(mp = method; mp->name; mp++){
			if(strcmp(mp->name, "local") != 0)
				continue;
			bargc = 1;
			(*mp->config)(mp);
			fd = (*mp->connect)();
			if(fd < 0)

M pc/apm.c => pc/apm.c +18 -8
@@ 1,5 1,12 @@
/*
 * Advanced Power Management 1.2 driver
 * Interface to Advanced Power Management 1.2 BIOS
 *
 * This is, in many ways, a giant hack, and when things settle down 
 * a bit and standardize, hopefully we can write a driver that deals
 * more directly with the hardware and thus might be a bit cleaner.
 * 
 * ACPI might be the answer, but at the moment this is simpler
 * and more widespread.
 */

#include	"u.h"


@@ 39,6 46,9 @@ getreg(ulong *reg, ISAConf *isa, char *name)
 * type is 0 for system segment, 1 for code/data.
 *
 * clearly we know way too much about the memory unit.
 * however, knowing this much about the memory unit
 * means that the memory unit need not know anything
 * about us.
 *
 * what a crock.
 */


@@ 67,13 77,6 @@ loadgdt(void)
	lgdt(ptr);
}

/*
 * Must run before mmuinit, since we modify the GDT that
 * we want the processor to inherit.  I think (but am not sure)
 * that we could run after mmuinit on processor 0 and just
 * modify m->gdt and then call lgdt() as mmuinit() does,
 * but this is a bit simpler and safer.
 */
static	ulong ax, cx, dx, di, ebx, esi;
static Ureg apmu;
static long


@@ 141,6 144,13 @@ apmlink(void)
	}

	/*
	 * The NEC Versa SX bios does not report the correct 16-bit code
	 * segment length when loaded directly from mbr -> 9load (as compared
	 * with going through ld.com).  We'll make both code segments 64k-1 bytes.
	 */
	esi = 0xFFFFFFFF;

	/*
	 * We are required by the BIOS to set up three consecutive segments,
	 * one for the APM 32-bit code, one for the APM 16-bit code, and 
	 * one for the APM data.  The BIOS handler uses the code segment it