From ebb118e0e3a65829192f24cbab12830ce32e3289 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sat, 27 Jul 1991 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1991-07-27 --- gnot/trap.c | 1 + pc/devfloppy.c | 559 ++++++++++++++++++++++++++++++++++++++++++++++ pc/headland.c | 53 +++++ pc/main.c | 1 - pc/trap.c | 1 + pc/vga.c | 130 +++++++++-- port/alarm.c | 12 +- port/chan.c | 12 +- port/devcons.c | 11 + port/devscc.c | 8 + port/portdat.h | 4 +- port/portfns.h | 2 + port/proc.c | 41 ++-- port/qlock.c | 3 - port/swap.c | 3 +- port/tcpinput.c | 2 +- power/devduart.c | 8 + power/devhotrod.c | 6 +- power/trap.c | 1 + ss/trap.c | 1 + 20 files changed, 810 insertions(+), 49 deletions(-) create mode 100644 pc/devfloppy.c diff --git a/gnot/trap.c b/gnot/trap.c index 9ebd7f2cc71cf96966b08207418bd6e11080d05a..f3d7998861b872705ae780cecbbf07c2dcedb4f6 100644 --- a/gnot/trap.c +++ b/gnot/trap.c @@ -148,6 +148,7 @@ notify(Ureg *ur) unlock(&u->p->debug); return; } + u->p->notepending = 0; if(u->note[0].flag!=NUser && (u->notified || u->notify==0)){ if(u->note[0].flag == NDebug) pprint("suicide: %s\n", u->note[0].msg); diff --git a/pc/devfloppy.c b/pc/devfloppy.c new file mode 100644 index 0000000000000000000000000000000000000000..e92a22104d1ddc2189262dadfd54757e935a7cf1 --- /dev/null +++ b/pc/devfloppy.c @@ -0,0 +1,559 @@ +#include "u.h" +#include "lib.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" +#include "io.h" +#include "ureg.h" + +typedef struct Drive Drive; +typedef struct Controller Controller; +typedef struct Type Type; + +enum +{ + Fmotor= 0x3f2, /* motor port */ + Fintena= 0x4, /* enable floppy interrupt */ + Fena= 0x8, /* 0 == reset controller */ + + Fstatus= 0x3f4, /* controller main status port */ + Fready= 0x80, /* ready to be touched */ + Ffrom= 0x40, /* data from controller */ + Fbusy= 0x10, /* operation not over */ + + Fdata= 0x3f5, /* controller data port */ + Frecal= 0x7, /* recalibrate cmd */ + Fseek= 0xf, /* seek cmd */ + Fsense= 0x8, /* sense cmd */ + Fread= 0x66, /* read cmd */ + Fwrite= 0x47, /* write cmd */ + Fmulti= 0x80, /* or'd with Fread or Fwrite for multi-head */ + + DMAmode0= 0xb, + DMAmode1= 0xc, + DMAaddr= 0x4, + DMAtop= 0x81, + DMAinit= 0xa, + DMAcount= 0x5, + + Nfloppy= 4, /* floppies/controller */ + + /* sector size encodings */ + S128= 0, + S256= 1, + S512= 2, + S1024= 3, + + /* status 0 byte */ + Drivemask= 3<<0, + Seekend= 1<<5, + Codemask= (3<<6)|(3<<3), +}; + +/* + * floppy types + */ +struct Type +{ + char *name; + 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 */ + long cap; /* drive capacity in bytes */ +}; +Type floppytype[] = +{ + { "MF2HD", S512, 18, 2, 1, 80, 0x1B, 0x54, 512*2*18*80 }, + { "MF2DD", S512, 9, 2, 1, 80, 0x1B, 0x54, 512*2*9*80 }, + { "F2HD", S512, 15, 2, 1, 80, 0x2A, 0x50, 512*15*2*80 }, + { "F2DD", S512, 8, 2, 1, 40, 0x2A, 0x50, 512*8*2*40 }, + { "F1DD", S512, 8, 1, 1, 40, 0x2A, 0x50, 512*8*1*40 }, +}; +static int secbytes[] = +{ + 128, + 256, + 512, + 1024 +}; + +/* + * a floppy drive + */ +struct Drive +{ + QLock; + Type *t; + int dev; + + ulong lasttouched; /* time last touched */ + int motoron; /* motor is on */ + int cyl; /* current cylinder */ + long offset; /* current offset */ + int confused; /* needs to be recalibrated (or worse) */ + + int tcyl; /* target cylinder */ + int thead; /* target head */ + int tsec; /* target sector */ + long len; + + int busy; /* true if drive is seeking */ + Rendez r; /* waiting for operation termination */ +}; + +/* + * NEC PD765A controller for 4 floppys + */ +struct Controller +{ + QLock; + Drive d[Nfloppy]; /* the floppy drives */ + int busy; /* true if a read or write in progress */ + uchar stat[8]; /* status of an operation */ + int confused; +}; + +Controller floppy[1]; + +/* + * start a floppy drive's motor. set an alarm for 1 second later to + * mark it as started (we get no interrupt to tell us). + * + * assume the caller qlocked the drive. + */ +void +floppystart(Drive *dp) +{ + int cmd; + + dp->lasttouched = m->ticks; + if(dp->motoron) + return; + + cmd = (1<<(dp->dev+4)) | Fintena | Fena | dp->dev; + outb(Fmotor, cmd); + dp->busy = 1; + tsleep(&dp->r, noreturn, 0, 1000); + dp->motoron = 1; + dp->busy = 0; + dp->lasttouched = m->ticks; +} + +/* + * stop the floppy if it hasn't been used in 5 seconds + */ +void +floppystop(Drive *dp) +{ + int cmd; + + if(!canqlock(dp)) + return; + cmd = Fintena | Fena | dp->dev; + outb(Fmotor, cmd); + dp->motoron = 0; +} +void +floppykproc(Alarm* a) +{ + Drive *dp; + + if(waserror()) + for(dp = floppy.d; dp < &floppy.d[Nfloppy]; dp++){ + if(dp->motoron && TK2SEC(m->ticks - dp->lasttouched) > 5) + floppystop(dp); + } + + alarm(5*1000, floppyalarm, 0); + cancel(a); +} + +int +floppysend(int data) +{ + int tries; + uchar c; + + for(tries = 0; tries < 100; tries++){ + /* + * see if its ready for data + */ + c = inb(Fstatus); + if((c&(Ffrom|Fready)) != Fready) + continue; + + /* + * send the data + */ + outb(Fdata, data); + return 0; + } + return -1; +} + +int +floppyrcv(void) +{ + int tries; + uchar c; + + for(tries = 0; tries < 100; tries++){ + /* + * see if its ready for data + */ + c = inb(Fstatus); + if((c&(Ffrom|Fready)) != (Ffrom|Fready)) + continue; + + /* + * get data + */ + return inb(Fdata)&0xff; + } + return -1; +} + +int +floppyrdstat(int n) +{ + int i; + int c; + + for(i = 0; i < n; i++){ + c = floppyrcv(); + if(c < 0) + return -1; + floppy.stat[i] = c; + } + return 0; +} + +void +floppypos(Drive *dp, long off) +{ + int lsec; + int end; + int cyl; + + lsec = off/secbytes[dp->t->bytes]; + dp->tcyl = lsec/(dp->t->sectors*dp->t->heads); + dp->tsec = (lsec % dp->t->sectors) + 1; + dp->thead = (lsec/dp->t->sectors) % dp->t->heads; + + /* + * can't read across cylinder boundaries. + * if so, decrement the bytes to be read. + */ + lsec = (off+dp->len)/secbytes[dp->t->bytes]; + cyl = lsec/(dp->t->sectors*dp->t->heads); + if(cyl != dp->tcyl){ + dp->len -= (lsec % dp->t->sectors)*secbytes[dp->t->bytes]; + dp->len -= ((lsec/dp->t->sectors) % dp->t->heads)*secbytes[dp->t->bytes] + *dp->t->sectors; + } + + dp->lasttouched = m->ticks; + floppy.intr = 0; +} + +void +floppywait(void) +{ + int tries; + + for(tries = 0; tries < 100 && floppy.intr == 0; tries++) + delay(5); + if(tries >= 100) + print("tired floopy\n"); + floppy.intr = 0; +} + +int +floppysense(Drive *dp) +{ + /* + * ask for floppy status + */ + if(floppysend(Fsense) < 0){ + floppy.confused = 1; + return -1; + } + if(floppyrdstat(2) < 0){ + floppy.confused = 1; + dp->confused = 1; + return -1; + } + + /* + * make sure it's the right drive + */ + if((floppy.stat[0] & Drivemask) != dp-floppy.d){ + print("sense failed\n"); + dp->confused = 1; + return -1; + } + return 0; +} + +int +floppyrecal(Drive *dp) +{ + floppy.intr = 0; + if(floppysend(Frecal) < 0 + || floppysend(dp - floppy.d) < 0){ + floppy.confused = 0; + return -1; + } + floppywait(); + + /* + * get return values + */ + if(floppysense(dp) < 0) + return -1; + + /* + * see if it worked + */ + if((floppy.stat[0] & (Codemask|Seekend)) != Seekend){ + print("recalibrate failed\n"); + dp->confused = 1; + return -1; + } + + /* + * see what cylinder we got to + */ + dp->tcyl = 0; + dp->cyl = floppy.stat[1]/dp->t->steps; + if(dp->cyl != dp->tcyl){ + print("recalibrate went to wrong cylinder %d\n", dp->cyl); + dp->confused = 1; + return -1; + } + + dp->confused = 0; + return 0; +} + +void +floppyinit(void) +{ + Drive *dp; + + for(dp = floppy.d; dp < &floppy.d[Nfloppy]; dp++){ + dp->t = &floppytype[0]; + dp->cyl = -1; + dp->motoron = 1; + floppystop(dp); + } + setvec(22, floppyintr); + alarm(5*1000, floppyalarm, (void *)0); +} + +void +floppyreset(void) +{ + Drive *dp; + + /* + * reset the floppy if'n it's confused + */ + if(floppy.confused){ + /* reset controller and turn all motors off */ + floppy.intr = 0; + splhi(); + outb(Fmotor, 0); + delay(1); + outb(Fmotor, Fintena|Fena); + spllo(); + for(dp = floppy.d; dp < &floppy.d[Nfloppy]; dp++){ + dp->motoron = 0; + dp->confused = 1; + } + floppywait(); + floppy.confused = 0; + } + + /* + * recalibrate any confused drives + */ + for(dp = floppy.d; floppy.confused == 0 && dp < &floppy.d[Nfloppy]; dp++){ + if(dp->confused == 0) + floppyrecal(dp); + + } + +} + +long +floppyseek(int dev, long off) +{ + Drive *dp; + + dp = &floppy.d[dev]; + + if(floppy.confused || dp->confused) + floppyreset(); + + floppystart(dp); + + floppypos(dp, off); + if(dp->cyl == dp->tcyl){ + dp->offset = off; + return off; + } + + /* + * tell floppy to seek + */ + if(floppysend(Fseek) < 0 + || floppysend((dp->thead<<2) | dev) < 0 + || floppysend(dp->tcyl * dp->t->steps) < 0){ + print("seek cmd failed\n"); + floppy.confused = 1; + return -1; + } + + /* + * wait for interrupt + */ + floppywait(); + + /* + * get floppy status + */ + if(floppysense(dp) < 0) + return -1; + + /* + * see if it worked + */ + if((floppy.stat[0] & (Codemask|Seekend)) != Seekend){ + print("seek failed\n"); + dp->confused = 1; + return -1; + } + + /* + * see what cylinder we got to + */ + dp->cyl = floppy.stat[1]/dp->t->steps; + if(dp->cyl != dp->tcyl){ + print("seek went to wrong cylinder %d instead of %d\n", dp->cyl, dp->tcyl); + dp->confused = 1; + return -1; + } + + dp->offset = off; + return dp->offset; +} + +long +floppyxfer(Drive *dp, int cmd, void *a, long n) +{ + int dev; + ulong addr; + long offset; + + addr = (ulong)a; + dev = dp - floppy.d; + + /* + * dma can't cross 64 k boundaries + */ + if((addr & 0xffff0000) != ((addr+n) & 0xffff0000)) + n -= (addr+n)&0xffff; + + dp->len = n; + floppyseek(dev, dp->offset); + +/* print("tcyl %d, thead %d, tsec %d, addr %lux, n %d\n", + dp->tcyl, dp->thead, dp->tsec, addr, n);/**/ + + /* + * set up the dma + */ + outb(DMAmode1, cmd==Fread ? 0x46 : 0x4a); + outb(DMAmode0, cmd==Fread ? 0x46 : 0x4a); + outb(DMAaddr, addr); + outb(DMAaddr, addr>>8); + outb(DMAtop, addr>>16); + outb(DMAcount, n-1); + outb(DMAcount, (n-1)>>8); + outb(DMAinit, 2); + + /* + * tell floppy to go + */ + cmd = cmd | (dp->t->heads > 1 ? Fmulti : 0); + if(floppysend(cmd) < 0 + || floppysend((dp->thead<<2) | dev) < 0 + || floppysend(dp->tcyl * dp->t->steps) < 0 + || floppysend(dp->thead) < 0 + || floppysend(dp->tsec) < 0 + || floppysend(dp->t->bytes) < 0 + || floppysend(dp->t->sectors) < 0 + || floppysend(dp->t->gpl) < 0 + || floppysend(0xFF) < 0){ + print("xfer cmd failed\n"); + floppy.confused = 1; + return -1; + } + + floppywait(); + + /* + * get status + */ + if(floppyrdstat(7) < 0){ + print("xfer status failed\n"); + floppy.confused = 1; + return -1; + } + + if((floppy.stat[0] & Codemask)!=0 || floppy.stat[1] || floppy.stat[2]){ +print("xfer failed %lux %lux %lux\n", floppy.stat[0], + floppy.stat[1], floppy.stat[2]); + dp->confused = 1; + return -1; + } + + offset = (floppy.stat[3]/dp->t->steps) * dp->t->heads + floppy.stat[4]; + offset = offset*dp->t->sectors + floppy.stat[5] - 1; + offset = offset * secbytes[floppy.stat[6]]; + if(offset != dp->offset+n){ + print("new offset %d instead of %d\n", offset, dp->offset+dp->len); + dp->confused = 1; + return -1;/**/ + } + + dp->offset += dp->len; + return dp->len; +} + +long +floppyread(int dev, void *a, long n) +{ + Drive *dp; + long rv, i; + uchar *aa = a; + + dp = &floppy.d[dev]; + for(rv = 0; rv < n; rv += i){ + i = floppyxfer(dp, Fread, aa+rv, n-rv); + if(i <= 0) + break; + } + return rv; +} + +void +floppyintr(Ureg *ur) +{ + floppy.intr = 1; +} diff --git a/pc/headland.c b/pc/headland.c index 0febe9874cb4d64989af73470c0659ca01354b03..684c8c797bc11b727315b6e6dcab5aefca8398ac 100644 --- a/pc/headland.c +++ b/pc/headland.c @@ -17,6 +17,35 @@ enum A20ena= (1<<1), /* enable address line 20 */ }; +/* + * ports used by the DMA controllers + */ +typedef struct DMA DMA; +struct DMA { + 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 */ +}; + +DMA dma[2] = { + { 0x00, 0x02, 0x04, 0x06, + 0x01, 0x03, 0x05, 0x07, + 0x87, 0x83, 0x81, 0x82, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + { 0xc0, 0xc6, 0xca, 0xce, + 0xc4, 0xc8, 0xcc, 0xcf, + 0x80, 0x8b, 0x89, 0x8a, + 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde }, +}; + /* * enable address bit 20 */ @@ -38,3 +67,27 @@ exit(void) print("exiting\n"); outb(Head, Reset); } + +/* + * setup a dma transfer. return count actually set up. we DMA up + * to a page. + */ +long +dmasetup(int d, int chan, Page *pg, long len, int isread) +{ + DMA *dp; + ulong addr; + + dp = &dma[d]; + addr = (ulong)a; + addr &= ~KZERO; + + outb(dp->cbp, isread ? 0x46 : 0x4a); + outb(dp->mode, isread ? 0x46 : 0x4a); + outb(dp->addr, addr); + outb(dp->addr, addr>>8); + outb(dp->page, addr>>16); + outb(dp->count, len-1); + outb(dp->count, (len-1)>>8); + outb(dp->sbm, 2); +} diff --git a/pc/main.c b/pc/main.c index 3c2d6870123aa1b1c6040933cdbd773a54610aae..a710d858c014d7a44f3e425f1595399488b7ae7b 100644 --- a/pc/main.c +++ b/pc/main.c @@ -19,7 +19,6 @@ main(void) screeninit(); printinit(); mmuinit(); - vgainit(); trapinit(); kbdinit(); clockinit(); diff --git a/pc/trap.c b/pc/trap.c index 971ced4005306571c1802933ac071e73f86591eb..47be159fab8b1c6196295f6a4c0da35171962292 100644 --- a/pc/trap.c +++ b/pc/trap.c @@ -279,6 +279,7 @@ notify(Ureg *ur) unlock(&u->p->debug); return; } + u->p->notepending = 0; if(u->note[0].flag!=NUser && (u->notified || u->notify==0)){ if(u->note[0].flag == NDebug) pprint("suicide: %s\n", u->note[0].msg); diff --git a/pc/vga.c b/pc/vga.c index 1bd90cda1169c3154bad1a9c964aa69b17539558..a04c358eff2f7317efcbd0acfb21ed00324074f8 100644 --- a/pc/vga.c +++ b/pc/vga.c @@ -8,44 +8,142 @@ enum { GRX= 0x3CE, /* index to graphics registers */ - GR= 0x3CF, /* graphics registers 0-8 */ + GR= 0x3CF, /* graphics registers */ + Grot= 0x03, /* data rotate register */ + Gmode= 0x05, /* mode register */ + Gmisc= 0x06, /* miscillaneous register */ + Grms= 0x04, /* read map select register */ SRX= 0x3C4, /* index to sequence registers */ - SR= 0x3C5, /* sequence registers 0-7 */ + SR= 0x3C5, /* sequence registers */ + Sclock= 0x01, /* clocking register */ + Smode= 0x04, /* mode register */ + Smmask= 0x02, /* map mask */ + CRX= 0x3D4, /* index to crt registers */ + CR= 0x3D5, /* crt registers */ + Cmode= 0x17, /* mode register */ + Cmsl= 0x09, /* max scan line */ + ARX= 0x3C0, /* index to attribute registers */ + AR= 0x3C1, /* attribute registers */ + Amode= 0x10, /* mode register */ + Acpe= 0x12, /* color plane enable */ }; +/* + * screen dimensions + */ +#define MAXX 640 +#define MAXY 480 + +/* + * routines for setting vga registers + */ void srout(int reg, int val) { outb(SRX, reg); outb(SR, val); } - void grout(int reg, int val) { outb(GRX, reg); outb(GR, val); } +void +arout(int reg, int val) +{ + inb(0x3DA); + outb(ARX, reg | 0x20); + outb(AR, val); +} +void +crout(int reg, int val) +{ + outb(CRX, reg); + outb(CR, val); +} + +/* + * m is a bit mask of planes to be affected by CPU writes + */ +vgawrmask(int m) +{ + srout(Smmask, m&0xf); +} /* - * look at VGA registers + * p is the plane that will respond to CPU reads + */ +vgardplane(int p) +{ + grout(Grms, p&3); +} + +/* + * partial screen munching squares + */ +#define DELTA 1 +#define DADDR ((long *) 0) +#define SIDE 256 +void +munch(void) +{ + ulong x,y,i,d; + uchar *screen, tab[8], *p; + + screen = (uchar *)(0xA0000 | KZERO); + d=0; + tab[0] = 0x80; + tab[1] = 0x40; + tab[2] = 0x20; + tab[3] = 0x10; + tab[4] = 0x08; + tab[5] = 0x04; + tab[6] = 0x02; + tab[7] = 0x01; + + for(i=0; ialarmlock); } - if(m == MACHP(0) && canqlock(&alarms)){ + if(m == MACHP(0) && canlock(&alarms)){ now = MACHP(0)->ticks; while((rp = alarms.head) && rp->alarm <= now){ if(rp->alarm != 0L){ @@ -124,7 +124,7 @@ checkalarms(void) } alarms.head = rp->palarm; } - qunlock(&alarms); + unlock(&alarms); } } @@ -143,7 +143,7 @@ procalarm(ulong time) else when += MACHP(0)->ticks; - qlock(&alarms); + lock(&alarms); l = &alarms.head; for(f = *l; f; f = f->palarm){ if(u->p == f){ @@ -170,7 +170,7 @@ procalarm(ulong time) alarms.head = u->p; done: u->p->alarm = when; - qunlock(&alarms); + unlock(&alarms); return TK2MS(old); } diff --git a/port/chan.c b/port/chan.c index 49bf132de0d3fb57cbd5bfb23217dde58bbc3117..7ceaff4a05a6d5a363d0200a33db1830fe3803db 100644 --- a/port/chan.c +++ b/port/chan.c @@ -5,7 +5,6 @@ #include "fns.h" #include "errno.h" - struct{ Lock; Chan *free; @@ -612,6 +611,7 @@ namec(char *name, int amode, int omode, ulong perm) close(cc); nexterror(); } + nameok(elem); if((nc=walk(cc, elem, 1)) != 0){ poperror(); close(c); @@ -665,6 +665,16 @@ char isfrog[]={ [0x7f] 1, }; +void +nameok(char *elem) +{ + while(*elem) { + if((*elem&0x80) || isfrog[*elem]) + error(Ebadchar); + elem++; + } +} + /* * name[0] should not be a slash. * Advance name to next element in path, copying current element into elem. diff --git a/port/devcons.c b/port/devcons.c index 9943a8de10b51e1eede1db99a06feeae193e0edd..66776a8910aeab7a17b48ca5116ffc06a67fb6a4 100644 --- a/port/devcons.c +++ b/port/devcons.c @@ -234,6 +234,17 @@ echo(int c) } } +/* + * turn '\r' into '\n' before putting it into the queue + */ +int +kbdcr2nl(IOQ *q, int ch) +{ + if(ch == '\r') + ch = '\n'; + return kbdputc(q, ch); +} + /* * Put character into read queue at interrupt time. * Always called splhi from proc 0. diff --git a/port/devscc.c b/port/devscc.c index 3de80800f63589e97821752a34792ef2c6ccd02d..7bd35cfb7895d8f10f9f05649de245c2edfc2349 100644 --- a/port/devscc.c +++ b/port/devscc.c @@ -370,6 +370,14 @@ sccspecial(int port, IOQ *oq, IOQ *iq, int baud) sp->iq = iq; sccenable(sp); sccsetbaud(sp, baud); + + if(iq){ + /* + * Stupid HACK to undo a stupid hack + */ + if(iq == &kbdq) + kbdq.putc = kbdcr2nl; + } } static void scctimer(Alarm*); diff --git a/port/portdat.h b/port/portdat.h index 3d45eb1815a83ca7339c591a2ad5c568de165a4b..e24e25193289deed3725ddac06d883085e9084c4 100644 --- a/port/portdat.h +++ b/port/portdat.h @@ -70,7 +70,7 @@ struct Alarm struct Alarms { - QLock; + Lock; Proc *head; }; @@ -492,7 +492,7 @@ struct Proc Lock debug; /* to access debugging elements of User */ Rendez *r; /* rendezvous point slept on */ Rendez sleep; /* place for tsleep and syssleep */ - int wokeup; /* whether sleep was interrupted */ + int notepending; /* note issued but not acted on */ ulong pc; /* DEBUG only */ int kp; /* true if a kernel process */ Proc *palarm; /* Next alarm time */ diff --git a/port/portfns.h b/port/portfns.h index ead0af9bc824948bcabc70c941f8a30aa18be611..eb0b40429764dc55d8621435b78a8b97731175e4 100644 --- a/port/portfns.h +++ b/port/portfns.h @@ -96,6 +96,7 @@ void isdir(Chan*); int ispages(void*); void kbdclock(void); int kbdputc(IOQ*, int); +int kbdcr2nl(IOQ*, int); void kbdrepeat(int); void kickpager(void); int kprint(char*, ...); @@ -113,6 +114,7 @@ void mntdump(void); int mount(Chan*, Chan*, int); int mouseputc(IOQ*, int); Chan* namec(char*, int, int, ulong); +void nameok(char*); Alarm* newalarm(void); Chan* newchan(void); Egrp* newegrp(void); diff --git a/port/proc.c b/port/proc.c index d4cce3eb779e552a0f930d8cc9e1919d20cd5324..7dc888ae04eda6e11a1331b31d5aca2ce0c809ce 100644 --- a/port/proc.c +++ b/port/proc.c @@ -238,6 +238,7 @@ loop: p->fpstate = FPinit; p->kp = 0; p->procctl = 0; + p->notepending = 0; memset(p->seg, 0, sizeof p->seg); lock(&pidalloc); p->pid = ++pidalloc.pid; @@ -282,12 +283,15 @@ sleep1(Rendez *r, int (*f)(void*), void *arg) * at interrupt time. lock is mutual exclusion */ s = splhi(); + p = u->p; + p->r = r; /* early so postnote knows */ lock(r); /* * if condition happened, never mind */ - if((*f)(arg)){ + if((*f)(arg)){ + p->r = 0; unlock(r); splx(s); return; @@ -297,11 +301,8 @@ sleep1(Rendez *r, int (*f)(void*), void *arg) * now we are committed to * change state and call scheduler */ - p = u->p; if(r->p) print("double sleep %d %d\n", r->p->pid, p->pid); - p->r = r; - p->wokeup = 0; p->state = Wakeme; r->p = p; unlock(r); @@ -310,10 +311,14 @@ sleep1(Rendez *r, int (*f)(void*), void *arg) void sleep(Rendez *r, int (*f)(void*), void *arg) { + Proc *p; + + p = u->p; sleep1(r, f, arg); - sched(); - if(u->p->wokeup){ - u->p->wokeup = 0; + if(p->notepending == 0) + sched(); /* notepending may go true while asleep */ + if(p->notepending){ + p->notepending = 0; error(Eintr); } } @@ -322,13 +327,17 @@ void tsleep(Rendez *r, int (*f)(void*), void *arg, int ms) { Alarm *a; + Proc *p; + p = u->p; sleep1(r, f, arg); - a = alarm(ms, twakeme, r); - sched(); - cancel(a); - if(u->p->wokeup){ - u->p->wokeup = 0; + if(p->notepending == 0){ + a = alarm(ms, twakeme, r); + sched(); /* notepending may go true while asleep */ + cancel(a); + } + if(p->notepending){ + p->notepending = 0; error(Eintr); } } @@ -397,6 +406,7 @@ postnote(Proc *p, int dolock, char *n, int flag) kunmap(k); return 0; } + p->notepending = 1; strcpy(up->note[up->nnote].msg, n); up->note[up->nnote++].flag = flag; if(up != u) @@ -404,15 +414,14 @@ postnote(Proc *p, int dolock, char *n, int flag) if(dolock) unlock(&p->debug); - if(r = p->r) { /* assign = */ - /* wake up */ + if(r = p->r){ /* assign = */ + /* wake up; can't call wakeup itself because we're racing with it */ s = splhi(); lock(r); - if(p->r==r && r->p==p){ + if(p->r==r && r->p==p){ /* check we won the race */ r->p = 0; if(p->state != Wakeme) panic("postnote wakeup: not Wakeme"); - p->wokeup = 1; p->r = 0; ready(p); } diff --git a/port/qlock.c b/port/qlock.c index 3596a991b5fc892ea2368915618347f95e766d67..5dceace5faba4e34496d0e28f8e68b4e1b17867c 100644 --- a/port/qlock.c +++ b/port/qlock.c @@ -53,10 +53,7 @@ qunlock(QLock *q) unlock(&q->queue); ready(p); }else{ - /* horrible botch because clock does a canqlock */ - int s = splhi(); unlock(&q->use); unlock(&q->queue); - splx(s); } } diff --git a/port/swap.c b/port/swap.c index cda70a5817c10f10fcb54e2bb0883d4a55fe521a..4c0bb367df51cae73501f9a1d68027831c1faf81 100644 --- a/port/swap.c +++ b/port/swap.c @@ -123,7 +123,8 @@ pager(void *junk) executeio(); } } - else { + else + if(palloc.freecount < HIGHWATER) { /* Emulate the old system if no swap channel */ print("no physical memory\n"); tsleep(&swapalloc.r, return0, 0, 1000); diff --git a/port/tcpinput.c b/port/tcpinput.c index f76d9fc3fa7d871ed8f66f2dd01bc74e651573cd..4433c78f628dfa2979c2608abf982a4e0ea165d0 100644 --- a/port/tcpinput.c +++ b/port/tcpinput.c @@ -9,7 +9,7 @@ int tcpdbg = 0; #define DPRINT if(tcpdbg) print -#define LPRINT print +#define LPRINT if(tcpdbg) print extern Queue *Tcpoutput; QLock reseqlock; diff --git a/power/devduart.c b/power/devduart.c index b50981f9b3c775a7a17eb92a263c55740ba23240..cae0242b2874e1131566cb94cda4aa25a0054942 100644 --- a/power/devduart.c +++ b/power/devduart.c @@ -466,6 +466,7 @@ void duartspecial(int port, IOQ *oq, IOQ *iq, int baud) { Duartport *dp = &duartport[port]; + IOQ *zq; dp->nostream = 1; if(oq){ @@ -476,6 +477,13 @@ duartspecial(int port, IOQ *oq, IOQ *iq, int baud) if(iq){ dp->iq = iq; dp->iq->ptr = dp; + + /* + * Stupid HACK to undo a stupid hack + */ + zq = &kbdq; + if(iq == zq) + kbdq.putc = kbdcr2nl; } duartenable(dp); duartbaud(dp, baud); diff --git a/power/devhotrod.c b/power/devhotrod.c index 8e9b758816c8b96ecc6381f22b4e682257c04def..6a48cbb346b7214a4cc91618c168e0ad62dfb431 100644 --- a/power/devhotrod.c +++ b/power/devhotrod.c @@ -26,7 +26,7 @@ ulong testbuf[NTESTBUF]; /* * If 1, ENABCKSUM causes data transfers to have checksums */ -#define ENABCKSUM 0 +#define ENABCKSUM 1 typedef struct Hotrod Hotrod; @@ -72,11 +72,14 @@ hotsend(Hotrod *h, Hotmsg *m) lock(h); mp = (Hotmsg**)&h->addr->reqstq[h->wi]; +print("send 1 %lux\n", MP2VME(m)); delay(500); *mp = (Hotmsg*)MP2VME(m); +print("send 2\n"); delay(500); h->wi++; if(h->wi >= NRQ) h->wi = 0; unlock(h); +print("send 3\n"); delay(500); return mp; } @@ -211,7 +214,6 @@ hotrodopen(Chan *c, int omode) } for(;;){ -for(;;); print("-"); mem(hp->addr, &hp->addr->ram[(mp->param[0]-0x40000)/sizeof(ulong)], mp->param[1]); } diff --git a/power/trap.c b/power/trap.c index d9b54dbc67afb33591a02f7981bf05eace7ce487..4bc444d2d204b110d5b0a1db3b50041b8ca58111 100644 --- a/power/trap.c +++ b/power/trap.c @@ -377,6 +377,7 @@ notify(Ureg *ur) unlock(&u->p->debug); return; } + u->p->notepending = 0; if(u->note[0].flag!=NUser && (u->notified || u->notify==0)){ if(u->note[0].flag == NDebug) pprint("suicide: %s\n", u->note[0].msg); diff --git a/ss/trap.c b/ss/trap.c index 4cbbaa350ccb25c22819bf173a5348977432066c..fc2f0a30b0fad3d4be907c4d63ef8da0330a3b35 100644 --- a/ss/trap.c +++ b/ss/trap.c @@ -218,6 +218,7 @@ notify(Ureg *ur) ulong sp; lock(&u->p->debug); + u->p->notepending = 0; if(u->nnote==0){ unlock(&u->p->debug); return;