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