From 067a84ef4d5019c744d3aacd09706afd2e0088db Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Thu, 19 Oct 2000 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2000-10-19 --- bitsy/clock.c | 19 +++- bitsy/devuart.c | 71 +++++++-------- bitsy/io.h | 6 +- bitsy/main.c | 6 +- bitsy/mem.h | 2 +- bitsy/mmu.c | 25 +++--- bitsy/sa1110uart.c | 54 +++++++++-- bitsy/screen.c | 218 ++++++++++++++++++++++++++++++++++++++++----- bitsy/trap.c | 41 +++++---- boot/boot.c | 1 + pc/apm.c | 26 ++++-- 11 files changed, 348 insertions(+), 121 deletions(-) diff --git a/bitsy/clock.c b/bitsy/clock.c index 11ef0713fbe2ee44340c8e99f077f65a71810909..44e9c2fb67f9ed047d99585f1b0d504a5eea0c65 100644 --- a/bitsy/clock.c +++ b/bitsy/clock.c @@ -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++) + ; + } } } diff --git a/bitsy/devuart.c b/bitsy/devuart.c index 03b6aed570dcf5959e011c8072d7d87af6b2989e..072e9d135f14cb22d03d1075f796a3d574512946 100644 --- a/bitsy/devuart.c +++ b/bitsy/devuart.c @@ -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 */ diff --git a/bitsy/io.h b/bitsy/io.h index fa5c8b508141c3d60550a5ceab1cb6472bfa49db..6c50da230543e2a0a4b55bcc92358b02a5edaf45 100644 --- a/bitsy/io.h +++ b/bitsy/io.h @@ -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; diff --git a/bitsy/main.c b/bitsy/main.c index c133cc5981043ca2ea90d6f2f8ca38b81a05382b..cfdcd5d97283820dae6eaad5f7608e7fb2ae1fd3 100644 --- a/bitsy/main.c +++ b/bitsy/main.c @@ -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) diff --git a/bitsy/mem.h b/bitsy/mem.h index 76b49ae7541c3cfd6ebb493683ae3925ddd9094f..8f6a7385cb7edc2276b1935c5e07c542efa3daa1 100644 --- a/bitsy/mem.h +++ b/bitsy/mem.h @@ -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 diff --git a/bitsy/mmu.c b/bitsy/mmu.c index 06dd12015c1a18bb8ac79e4835f0765c20ad729c..04cd25a9b9058db674a999320198239e78f9edc4 100644 --- a/bitsy/mmu.c +++ b/bitsy/mmu.c @@ -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; } } diff --git a/bitsy/sa1110uart.c b/bitsy/sa1110uart.c index 49741706f8b2fdfc57224287fb65fd88a855416a..3bc1325e1f71b40b5ef580e80aa5c227427a6f0b 100644 --- a/bitsy/sa1110uart.c +++ b/bitsy/sa1110uart.c @@ -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); } diff --git a/bitsy/screen.c b/bitsy/screen.c index f5c5901763e6e29340b585ea835f1c0856b124a0..0f790f4e11f11488b38d175f394ef89a462fe298 100644 --- a/bitsy/screen.c +++ b/bitsy/screen.c @@ -13,6 +13,8 @@ #include #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<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<lcsr & LDD) == 0) - sleep(1); - lcd->dbar1 = framebuf->palette; lcd->lccr3 = pcd<lccr2 = (Ht-1)<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; } diff --git a/bitsy/trap.c b/bitsy/trap.c index b5e6c89d841deb93bc5842fdeed0c30e8ffbb953..2ba7e89fae8a30a330b3ce1b69f64f754acb5d0c 100644 --- a/bitsy/trap.c +++ b/bitsy/trap.c @@ -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<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<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<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); diff --git a/boot/boot.c b/boot/boot.c index 4a566813286fca311cb075f070bf285700a80beb..7ff97a24267c587d6177846fe171977c8e8d81c9 100644 --- a/boot/boot.c +++ b/boot/boot.c @@ -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) diff --git a/pc/apm.c b/pc/apm.c index babdd6939036e65fb6ae31201f635c0bb4c0e553..3e5797a99d17dd3a5d36aed6e78b507848533f00 100644 --- a/pc/apm.c +++ b/pc/apm.c @@ -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 @@ -140,6 +143,13 @@ apmlink(void) return; } + /* + * 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