From 7428ad83a37707fcfa44bb341902eb466bdf53fb Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Thu, 1 Aug 1991 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1991-08-01 --- pc/clock.c | 7 +- pc/dat.h | 2 + pc/devuart.c | 629 ++++++++++++++++++++++++++++++++++++++++++++++++++ pc/fault386.c | 4 +- pc/io.h | 4 +- pc/kbd.c | 5 +- pc/main.c | 8 +- pc/mmu.c | 10 +- pc/trap.c | 15 +- pc/vga.c | 27 ++- port/page.c | 3 + 11 files changed, 670 insertions(+), 44 deletions(-) create mode 100644 pc/devuart.c diff --git a/pc/clock.c b/pc/clock.c index 19ad234fcbc83421939adf3019ed7cb10bb0bcc0..11c8f11211ebebb8b89219151ed2c38099ee67ad 100644 --- a/pc/clock.c +++ b/pc/clock.c @@ -69,14 +69,13 @@ clock(Ureg *ur) if (p->state==Running) p->time[p->insyscall]++; } -/* - if(u && (ur->flags&IFLAG) && p && p->state==Running){ + +/* if(u && p && p->state==Running){ if(anyready()){ if(p->hasspin) p->hasspin = 0; else sched(); } - } -/**/ + }/**/ } diff --git a/pc/dat.h b/pc/dat.h index fa39abd6f9dbb99c2dc8bff8725de74693f00c26..c4866de315b0d25f99356f789c346d311719f784 100644 --- a/pc/dat.h +++ b/pc/dat.h @@ -189,3 +189,5 @@ struct extern Mach *m; extern User *u; + +extern int flipD[]; /* for flipping bitblt destination polarity */ diff --git a/pc/devuart.c b/pc/devuart.c new file mode 100644 index 0000000000000000000000000000000000000000..bffa29005bf9eb1adc2630f9eace81638b0cea6f --- /dev/null +++ b/pc/devuart.c @@ -0,0 +1,629 @@ +#include "u.h" +#include "lib.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" +#include "io.h" +#include "errno.h" + +#include "devtab.h" + +/* + * Driver for an NS16450 serial port + */ +enum +{ + /* + * register numbers + */ + Data= 0, /* xmit/rcv buffer */ + Iena= 1, /* interrupt enable */ + Ircv= (1<<0), /* interrupt on receive */ + Ixmt= (1<<1), /* interrupt on xmit */ + Istat= 2, /* interrupt flag */ + 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 */ + Dcd= (1<<3), /* carrier */ + Loop= (1<<4), /* loop bask */ + Lstat= 5, /* line status */ + Inready=(1<<0), /* receive buffer full */ + Outbusy=(1<<5), /* output buffer full */ + Mstat= 6, /* modem status */ + Scratch=7, /* scratchpad */ + Dlsb= 0, /* divisor lsb */ + Dmsb= 1, /* divisor msb */ +}; + +typedef struct Uart Uart; +struct Uart +{ + QLock; + int port; + ushort sticky[16]; /* sticky write register values */ + int printing; /* true if printing */ + + /* console interface */ + int nostream; /* can't use the stream interface */ + IOQ *iq; /* input character queue */ + IOQ *oq; /* output character queue */ + + /* stream interface */ + Queue *wq; /* write queue */ + Rendez r; /* kproc waiting for input */ + Alarm *a; /* alarm for waking the kernel process */ + int delay; /* between character input and waking kproc */ + int kstarted; /* kproc started */ + uchar delim[256/8]; /* characters that act as delimiters */ +}; + +Uart uart[2]; + +#define UartFREQ 1846200 + +#define uartwrreg(u,r,v) outb(u->port + r, u->sticky[r] | v) +#define uartrdreg(u,r) inb(u->port + r) + +void uartintr(Uart*); +void uartintr0(Ureg*); +void uartintr1(Ureg*); +void uartsetup(void); + +/* + * set the baud rate by calculating and setting the baudrate + * generator constant. This will work with fairly non-standard + * baud rates. + */ +void +uartsetbaud(Uart *up, int rate) +{ + ulong brconst; + + brconst = (UartFREQ+8*rate-1)/16*rate; + + uartwrreg(up, Format, Dra); + uartwrreg(up, Dmsb, (brconst>>8) & 0xff); + uartwrreg(up, Dlsb, brconst & 0xff); + uartwrreg(up, Format, 0); +} + +/* + * toggle DTR + */ +void +uartdtr(Uart *up, int n) +{ + if(n) + up->sticky[Mctl] |= Dtr; + else + up->sticky[Mctl] &= ~Dtr; + uartwrreg(up, Mctl, 0); +} + +/* + * toggle RTS + */ +void +uartrts(Uart *up, int n) +{ + if(n) + up->sticky[Mctl] |= Rts; + else + up->sticky[Mctl] &= ~Rts; + uartwrreg(up, Mctl, 0); +} + +/* + * send break + */ +void +uartbreak(Uart *up, int ms) +{ + uartwrreg(up, Format, Break); + tsleep(&u->p->sleep, return0, 0, ms); + uartwrreg(up, Format, 0); +} + +/* + * default is 9600 baud, 1 stop bit, 8 bit chars, no interrupts, + * transmit and receive enabled, interrupts disabled. + */ +void +uartsetup(void) +{ + Uart *up; + static int already; + + if(already) + return; + already = 1; + + /* + * get port addresses + */ + uart[0].port = 0x3F8; + uart[1].port = 0x2F8; + setvec(Uart0vec, uartintr0); + setvec(Uart1vec, uartintr1); + + for(up = uart; up < &uart[2]; up++){ + memset(up->sticky, 0, sizeof(up->sticky)); + + /* + * set rate to 9600 baud. + * 8 bits/character. + * 1 stop bit. + */ + uartsetbaud(up, 9600); + up->sticky[Format] = Bits8; + uartwrreg(up, Format, 0); + } +} + +/* + * Queue n characters for output; if queue is full, we lose characters. + * Get the output going if it isn't already. + */ +void +uartputs(IOQ *cq, char *s, int n) +{ + Uart *up = cq->ptr; + int st, ch, x; + + x = splhi(); + lock(cq); + puts(cq, s, n); + if(up->printing == 0){ + ch = getc(cq); +print("", ch);/**/ + if(ch >= 0){ + up->printing = 1; + while(uartrdreg(up, Lstat) & Outbusy) + ; + outb(up->port + Data, ch); + } + } + unlock(cq); + splx(x); +} + +/* + * a uart interrupt (a damn lot of work for one character) + */ +void +uartintr(Uart *up) +{ + int s; + int ch; + IOQ *cq; + + switch(uartrdreg(up, Istat)){ + case 3: + /* + * get any input characters + */ + cq = up->iq; + while(uartrdreg(up, Lstat) & Inready){ + ch = uartrdreg(up, Data) & 0xff; + if(cq->putc) + (*cq->putc)(cq, ch); + else { + putc(cq, ch); + if(up->delim[ch/8] & (1<<(ch&7)) ) + wakeup(&cq->r); + } + } + break; + case 5: + /* + * send next output character + */ + if((s & Outbusy)==0){ + cq = up->oq; + lock(cq); + ch = getc(cq); + if(ch < 0){ + up->printing = 0; + wakeup(&cq->r); + }else + outb(up->port + Data, ch); + unlock(cq); + } + break; + } +} +void +uartintr0(Ureg *ur) +{ + uartintr(&uart[0]); +} +void +uartintr1(Ureg *ur) +{ + uartintr(&uart[1]); +} + +/* + * turn on a port's interrupts. set DTR and RTS + */ +void +uartenable(Uart *up) +{ + /* + * set up i/o routines + */ + if(up->oq){ + up->oq->puts = uartputs; + up->oq->ptr = up; + up->sticky[Iena] |= Ixmt; + } + if(up->iq){ + up->iq->ptr = up; + up->sticky[Iena] |= Ircv; + } + + /* + * turn on interrupts + */ + uartwrreg(up, Iena, 0); + + /* + * turn on DTR and RTS + */ + uartdtr(up, 1); + uartrts(up, 1); +} + +/* + * set up an uart port as something other than a stream + */ +void +uartspecial(int port, IOQ *oq, IOQ *iq, int baud) +{ + Uart *up = &uart[port]; + + uartsetup(); + up->nostream = 1; + up->oq = oq; + up->iq = iq; + uartenable(up); + uartsetbaud(up, baud); + + if(iq){ + /* + * Stupid HACK to undo a stupid hack + */ + if(iq == &kbdq) + kbdq.putc = kbdcr2nl; + } +} + +static void uarttimer(Alarm*); +static int uartputc(IOQ *, int); +static void uartstopen(Queue*, Stream*); +static void uartstclose(Queue*); +static void uartoput(Queue*, Block*); +static void uartkproc(void *); +Qinfo uartinfo = +{ + nullput, + uartoput, + uartstopen, + uartstclose, + "uart" +}; + +/* + * create a helper process per port + */ +static void +uarttimer(Alarm *a) +{ + Uart *up = a->arg; + + cancel(a); + up->a = 0; + wakeup(&up->iq->r); +} + +static int +uartputc(IOQ *cq, int ch) +{ + Uart *up = cq->ptr; int r; + + r = putc(cq, ch); + + /* + * pass upstream within up->delay milliseconds + */ + if(up->a==0){ + if(up->delay == 0) + wakeup(&cq->r); + else + up->a = alarm(up->delay, uarttimer, up); + } + return r; +} + +static void +uartstopen(Queue *q, Stream *s) +{ + Uart *up; + char name[NAMELEN]; + + kprint("uartstopen: q=0x%ux, inuse=%d, type=%d, dev=%d, id=%d\n", + q, s->inuse, s->type, s->dev, s->id); + up = &uart[s->id]; + qlock(up); + up->wq = WR(q); + WR(q)->ptr = up; + RD(q)->ptr = up; + up->delay = 64; + up->iq->putc = uartputc; + qunlock(up); + + /* start with all characters as delimiters */ + memset(up->delim, 1, sizeof(up->delim)); + + if(up->kstarted == 0){ + up->kstarted = 1; + sprint(name, "uart%d", s->id); + kproc(name, uartkproc, up); + } +} + +static void +uartstclose(Queue *q) +{ + Uart *up = q->ptr; + + qlock(up); + kprint("uartstclose: q=0x%ux, id=%d\n", q, up-uart); + up->wq = 0; + up->iq->putc = 0; + WR(q)->ptr = 0; + RD(q)->ptr = 0; + qunlock(up); +} + +static void +uartoput(Queue *q, Block *bp) +{ + Uart *up = q->ptr; + IOQ *cq; + int n, m; + + if(up == 0){ + freeb(bp); + return; + } + cq = up->oq; + if(waserror()){ + freeb(bp); + nexterror(); + } + if(bp->type == M_CTL){ + while (cangetc(cq)) /* let output drain */ + sleep(&cq->r, cangetc, cq); + n = strtoul((char *)(bp->rptr+1), 0, 0); + switch(*bp->rptr){ + case 'B': + case 'b': + uartsetbaud(up, n); + break; + case 'D': + case 'd': + uartdtr(up, n); + break; + case 'K': + case 'k': + uartbreak(up, n); + break; + case 'R': + case 'r': + uartrts(up, n); + break; + case 'W': + case 'w': + if(n>=0 && n<1000) + up->delay = n; + break; + } + }else while((m = BLEN(bp)) > 0){ + while ((n = canputc(cq)) == 0){ +print("uartoput: sleeping\n"); + sleep(&cq->r, canputc, cq); + } + if(n > m) + n = m; + (*cq->puts)(cq, bp->rptr, n); + bp->rptr += n; + } + freeb(bp); + poperror(); +} + +/* + * process to send bytes upstream for a port + */ +static void +uartkproc(void *a) +{ + Uart *up = a; + IOQ *cq = up->iq; + Block *bp; + int n; + +loop: + while ((n = cangetc(cq)) == 0){ +print("uart0 sleeping/n"); + sleep(&cq->r, cangetc, cq); + } + qlock(up); + if(up->wq == 0){ + cq->out = cq->in; + }else{ + bp = allocb(n); + bp->flags |= S_DELIM; + bp->wptr += gets(cq, bp->wptr, n); + PUTNEXT(RD(up->wq), bp); + } + qunlock(up); + goto loop; +} + +enum{ + Qdir= 0, + Qtty0= STREAMQID(0, Sdataqid), + Qtty0ctl= STREAMQID(0, Sctlqid), + Qtty1= STREAMQID(1, Sdataqid), + Qtty1ctl= STREAMQID(1, Sctlqid), +}; + +Dirtab uartdir[]={ + "tty0", {Qtty0}, 0, 0666, + "tty0ctl", {Qtty0ctl}, 0, 0666, + "tty1", {Qtty1}, 0, 0666, + "tty1ctl", {Qtty1ctl}, 0, 0666, +}; + +#define NUart (sizeof uartdir/sizeof(Dirtab)) + +/* + * allocate the queues if no one else has + */ +void +uartreset(void) +{ + Uart *up; + + uartsetup(); + for(up = uart; up < &uart[2]; up++){ + if(up->nostream) + continue; + up->iq = ialloc(sizeof(IOQ), 0); + initq(up->iq); + up->oq = ialloc(sizeof(IOQ), 0); + initq(up->oq); + uartenable(up); + } +} + +void +uartinit(void) +{ +} + +Chan* +uartattach(char *upec) +{ + return devattach('t', upec); +} + +Chan* +uartclone(Chan *c, Chan *nc) +{ + return devclone(c, nc); +} + +int +uartwalk(Chan *c, char *name) +{ + return devwalk(c, name, uartdir, NUart, devgen); +} + +void +uartstat(Chan *c, char *dp) +{ + switch(c->qid.path){ + case Qtty0: + streamstat(c, dp, "tty0"); + break; + case Qtty1: + streamstat(c, dp, "tty1"); + break; + default: + devstat(c, dp, uartdir, NUart, devgen); + break; + } +} + +Chan* +uartopen(Chan *c, int omode) +{ + Uart *up; + + switch(c->qid.path){ + case Qtty0: + case Qtty0ctl: + up = &uart[0]; + break; + case Qtty1: + case Qtty1ctl: + up = &uart[1]; + break; + default: + up = 0; + break; + } + + if(up && up->nostream) + errors("in use"); + + if((c->qid.path & CHDIR) == 0) + streamopen(c, &uartinfo); + return devopen(c, omode, uartdir, NUart, devgen); +} + +void +uartcreate(Chan *c, char *name, int omode, ulong perm) +{ + error(Eperm); +} + +void +uartclose(Chan *c) +{ + if(c->stream) + streamclose(c); +} + +long +uartread(Chan *c, void *buf, long n, ulong offset) +{ + switch(c->qid.path&~CHDIR){ + case Qdir: + return devdirread(c, buf, n, uartdir, NUart, devgen); + case Qtty1ctl: + case Qtty0ctl: + return 0; + } + return streamread(c, buf, n); +} + +long +uartwrite(Chan *c, void *va, long n, ulong offset) +{ + return streamwrite(c, va, n, 0); +} + +void +uartremove(Chan *c) +{ + error(Eperm); +} + +void +uartwstat(Chan *c, char *dp) +{ + error(Eperm); +} diff --git a/pc/fault386.c b/pc/fault386.c index a2f9fbdbf976aaa8b898f53a473c01b4f2fa04ae..e95741b8da5c79f2986fdb5aeb076dff46bea91b 100644 --- a/pc/fault386.c +++ b/pc/fault386.c @@ -20,8 +20,6 @@ fault386(Ureg *ur) insyscall = u->p->insyscall; u->p->insyscall = 1; addr = getcr2(); -print("fault386 %lux ur %lux\n", addr, ur); -dumpregs(ur); if(faulting) panic("double fault\n"); faulting = 1; @@ -37,7 +35,7 @@ dumpregs(ur); } u->p->state = MMUing; dumpregs(ur); - panic("fault: 0x%lux", addr); + panic("fault: 0x%lux 0x%lux", addr); } faulting = 0; u->p->insyscall = insyscall; diff --git a/pc/io.h b/pc/io.h index d744d5b7049b5193deeed605a06eadfae4d05db1..f20e2737bad17075e96c87ce48fe0101da0a5a1d 100644 --- a/pc/io.h +++ b/pc/io.h @@ -7,8 +7,8 @@ enum Int0vec= 16, /* first 8259 */ Clockvec= Int0vec+0, /* clock interrupts */ Kbdvec= Int0vec+1, /* keyboard interrupts */ - ComBvec= Int0vec+3, /* inerrupt from uart b */ - ComAvec= Int0vec+4, /* inerrupt from uart a */ + Uart0vec= Int0vec+3, /* inerrupt from uart b */ + Uart1vec= Int0vec+4, /* inerrupt from uart a */ Floppyvec= Int0vec+6, /* floppy interrupts */ Int1vec= Int0vec+8, /* second 8259 */ Mousevec= Int1vec+4, /* mouse interrupt */ diff --git a/pc/kbd.c b/pc/kbd.c index 93d807a43b9d6f6184797f99d1d88f9fa72f6561..d44d5918cb550f7e1c21be41405f133047adaf7a 100644 --- a/pc/kbd.c +++ b/pc/kbd.c @@ -294,9 +294,7 @@ kbdinit(void) mousecmd(0xF4, -1); /* resolution */ - mousecmd(0xE8, 0x03); -print("res set\n"); -delay(5000); +/* mousecmd(0xE8, 0x03); /**/ } /* @@ -333,7 +331,6 @@ mymouseputc(int c) mouse.newbuttons = b[msg[0]&7]; mouse.dx = msg[1]; mouse.dy = -msg[2]; -print("%d %d\n", mouse.dx, mouse.dy); mouse.track = 1; mouseclock(); } diff --git a/pc/main.c b/pc/main.c index 76fd47bb8750d538f61a7a9a1566afce0af28fe8..2bd54b4c4e4f8863fae1bb4001ef0cb3184b9479 100644 --- a/pc/main.c +++ b/pc/main.c @@ -28,7 +28,9 @@ main(void) grpinit(); chaninit(); alarminit(); +print("chandevreset\n"); delay(1000); chandevreset(); +print("streaminit\n"); delay(1000); streaminit(); swapinit(); pageinit(); @@ -65,7 +67,6 @@ init0(void) u->p->state = Running; u->p->mach = m; -print("go low\n"); spllo(); /* @@ -77,9 +78,6 @@ print("go low\n"); chandevinit(); -print("going to user\n"); -delay(1000); - touser(); } @@ -183,7 +181,7 @@ confinit(void) conf.base1 = 1024*1024; conf.npage = conf.npage0 + conf.npage1; - conf.maxialloc = (conf.npage0*BY2PG-PGROUND((ulong)&end)); + conf.maxialloc = 2*1024*1024; mul = 1; conf.nproc = 20 + 20*mul; diff --git a/pc/mmu.c b/pc/mmu.c index 4be1a687959cfe92a6cec617dbae7ddd25ba5078..741d8dccf595900719b238b1b3b115c0bd20d2d9 100644 --- a/pc/mmu.c +++ b/pc/mmu.c @@ -218,7 +218,7 @@ putmmu(ulong va, ulong pa, Page *pg) Proc *p; int i = 0; -print("putmmu %lux %lux\n", va, pa); /**/ +/*print("putmmu %lux %lux\n", va, pa); /**/ if(u==0) panic("putmmu"); p = u->p; @@ -238,21 +238,21 @@ print("putmmu %lux %lux\n", va, pa); /**/ * if bottom level page table missing, allocate one */ pg = p->mmu[i]; -print("toppt[%d] was %lux\n", topoff, toppt[topoff]); +/*print("toppt[%d] was %lux\n", topoff, toppt[topoff]);/**/ if(pg == 0){ pg = p->mmu[i] = newpage(1, 0, 0); p->mmue[i] = PPN(pg->pa) | PTEVALID | PTEUSER | PTEWRITE; toppt[topoff] = p->mmue[i]; -print("toppt[%d] now %lux\n", topoff, toppt[topoff]); +/*print("toppt[%d] now %lux\n", topoff, toppt[topoff]);/**/ } /* * fill in the bottom level page table */ pt = (ulong*)(p->mmu[i]->pa|KZERO); -print("%lux[%d] was %lux\n", pt, BTMOFF(va), pt[BTMOFF(va)]); +/*print("%lux[%d] was %lux\n", pt, BTMOFF(va), pt[BTMOFF(va)]);/**/ pt[BTMOFF(va)] = pa | PTEUSER; -print("%lux[%d] now %lux\n", pt, BTMOFF(va), pt[BTMOFF(va)]); +/*print("%lux[%d] now %lux\n", pt, BTMOFF(va), pt[BTMOFF(va)]);/**/ /* flush cached mmu entries */ putcr3(((ulong)toppt)&~KZERO); diff --git a/pc/trap.c b/pc/trap.c index 7c28904b2a0917a425d9c4b527abc0d51b059862..1eff53b5f66a4be0e822ed68d3159b0197256f56 100644 --- a/pc/trap.c +++ b/pc/trap.c @@ -176,14 +176,10 @@ trap(Ureg *ur) if(v>=256 || ivec[v] == 0) panic("bad trap type %d %lux\n", v, ur->pc); - /* - * call the trap routine - */ - (*ivec[v])(ur); - /* * tell the 8259 that we're done with the - * highest level interrupt + * highest level interrupt (interrupts are still + * off at this point) */ c = v&~0x7; if(c==Int0vec || c==Int1vec){ @@ -191,6 +187,11 @@ trap(Ureg *ur) if(c == Int1vec) outb(Int1ctl, EOI); } + + /* + * call the trap routine + */ + (*ivec[v])(ur); } /* @@ -268,10 +269,10 @@ syscall(Ureg *ur) panic("error stack"); } u->p->insyscall = 0; + ur->ax = ret; if(ax == NOTED) noted(ur, *(ulong*)(sp+BY2WD)); else if(u->nnote && ax!=FORK){ - ur->ax = ret; notify(ur); } return ret; diff --git a/pc/vga.c b/pc/vga.c index a7f08d758424e232c0cbebe80be2bf13b683e6a7..418aa852bb0c78cd2dff50157c2dbc31bbc02c0f 100644 --- a/pc/vga.c +++ b/pc/vga.c @@ -166,27 +166,26 @@ screeninit(void) srout(Sclock, 0x01); /* 8 bits/char */ srout(Smmask, 0x0f); /* enable all 4 color planes for writing */ + /* + * swizzle the font longs. + * we do it here since the font is initialized with big endian longs. + */ + defont = &defont0; + l = defont->bits->base; + for(i = defont->bits->width*Dy(defont->bits->r); i > 0; i--, l++) + *l = (*l<<24) | ((*l>>8)&0x0000ff00) | ((*l<<8)&0x00ff0000) | (*l>>24); + /* * zero out display */ - defont = &defont0; /* save space; let bitblt do the conversion work */ - gbitblt(&gscreen, Pt(0, 0), &gscreen, gscreen.r, 0); /**/ + gbitblt(&gscreen, Pt(0, 0), &gscreen, gscreen.r, flipD[0]); /* - * stick print at the top + * start printing at the top of screen */ out.pos.x = MINX; out.pos.y = 0; out.bwid = defont0.info[' '].width; - - /* - * swizzle the damn font longs. - * we do it here since the font is in a machine independent (i.e. - * made for the 68020) format. - */ - l = defont->bits->base; - for(i = defont->bits->width*Dy(defont->bits->r); i > 0; i--, l++) - *l = (*l<<24) | ((*l>>8)&0x0000ff00) | ((*l<<8)&0x00ff0000) | (*l>>24); } void @@ -201,7 +200,7 @@ screenputc(int c) 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), 0); + Rect(0, out.pos.y, gscreen.r.max.x, out.pos.y+2*defont0.height), flipD[0]); }else if(c == '\t'){ out.pos.x += (8-((out.pos.x-MINX)/out.bwid&7))*out.bwid; if(out.pos.x >= gscreen.r.max.x) @@ -217,7 +216,7 @@ screenputc(int c) screenputc('\n'); buf[0] = c&0x7F; buf[1] = 0; - out.pos = gstring(&gscreen, out.pos, defont, buf, S); + out.pos = gstring(&gscreen, out.pos, defont, buf, flipD[S]); } } diff --git a/port/page.c b/port/page.c index 2299aabb6cc0fba69895f916d7502b8f1dc98211..3a7a65321be666190c43d9ccc62e30626e58de44 100644 --- a/port/page.c +++ b/port/page.c @@ -65,6 +65,9 @@ ialloc(ulong n, int align) if(align) palloc.addr = PGROUND(palloc.addr); + if(palloc.addr+n > conf.base0 + conf.npage0*BY2PG) + palloc.addr = conf.base1; + memset((void*)(palloc.addr|KZERO), 0, n); p = palloc.addr; palloc.addr += n;