From 23038bbb7f87b4fa696f4f86f3f8a05a40ccb53e Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Wed, 31 Jul 1991 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1991-07-31 --- gnot/trap.c | 49 +------ pc/devfloppy.c | 372 ++++++++++++++++++++++++++++++++---------------- pc/fns.h | 26 ---- pc/headland.c | 17 +++ pc/io.h | 35 ++--- pc/kbd.c | 177 ++++++++++++++++------- pc/l.s | 32 +++++ pc/trap.c | 122 +++++++++------- pc/vga.c | 2 +- port/devbit.c | 9 +- port/portdat.h | 2 +- port/segment.c | 2 +- port/systab.h | 47 ++++++ power/segment.h | 2 +- power/trap.c | 50 +------ ss/trap.c | 43 +----- 16 files changed, 564 insertions(+), 423 deletions(-) create mode 100644 port/systab.h diff --git a/gnot/trap.c b/gnot/trap.c index f3d7998861b872705ae780cecbbf07c2dcedb4f6..d094d9a9f03f27a28b5dae4746e795c5cc8069fa 100644 --- a/gnot/trap.c +++ b/gnot/trap.c @@ -233,52 +233,7 @@ noted(Ureg *ur, ulong arg0) } } -#undef CHDIR /* BUG */ -#include "/sys/src/libc/9syscall/sys.h" - -typedef long Syscall(ulong*); -Syscall sysr1, sysfork, sysexec, sysgetpid, syssleep, sysexits, sysdeath, syswait; -Syscall sysopen, sysclose, sysread, syswrite, sysseek, syserrstr, sysaccess, sysstat, sysfstat; -Syscall sysdup, syschdir, sysforkpgrp, sysbind, sysmount, syspipe, syscreate; -Syscall sysbrk_, sysremove, syswstat, sysfwstat, sysnotify, sysnoted, sysalarm; -Syscall syssegattach, syssegdetach, syssegfree, syssegflush, syssegbrk; - -Syscall *systab[]={ - sysr1, - syserrstr, - sysbind, - syschdir, - sysclose, - sysdup, - sysalarm, - sysexec, - sysexits, - sysfork, - sysforkpgrp, - sysfstat, - syssegbrk, - sysmount, - sysopen, - sysread, - sysseek, - syssleep, - sysstat, - syswait, - syswrite, - syspipe, - syscreate, - sysdeath, - sysbrk_, - sysremove, - syswstat, - sysfwstat, - sysnotify, - sysnoted, - syssegattach, - syssegdetach, - syssegfree, - syssegflush, -}; +#include "../port/systab.h" long syscall(Ureg *aur) @@ -314,7 +269,7 @@ syscall(Ureg *aur) u->nerrlab = 0; ret = -1; if(!waserror()){ - if(r0 >= sizeof systab/BY2WD){ + if(r0 >= sizeof systab/sizeof systab[0]){ pprint("bad sys call number %d pc %lux\n", r0, ((Ureg*)UREGADDR)->pc); msg = "sys: bad sys call"; Bad: diff --git a/pc/devfloppy.c b/pc/devfloppy.c index 798445fde4678fe733acd5e9eded675647ad8183..2470a55063af797de23a1ea712e9baa5f8eb4e8a 100644 --- a/pc/devfloppy.c +++ b/pc/devfloppy.c @@ -29,7 +29,7 @@ enum Fwrite= 0x47, /* write cmd */ Fmulti= 0x80, /* or'd with Fread or Fwrite for multi-head */ - Nfloppy= 4, /* floppies/controller */ + Ndrive= 4, /* floppies/controller */ DMAchan= 2, /* floppy dma channel */ @@ -46,8 +46,8 @@ enum /* file types */ Qdir= 0, - Qdata= 16, - Qstruct= 32, + Qdata= 1, + Qstruct= 2, }; /* @@ -62,23 +62,41 @@ struct Type int steps; /* steps per cylinder */ int tracks; /* tracks/disk */ int gpl; /* intersector gap length for read/write */ - int fgpl; /* intersector gap length for format */ + int fgpl; /* intersector gap length for format */ + + /* + * these depend on previous entries and are set filled in + * by floppyinit + */ + int bcode; /* coded version of bytes for the controller */ 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 }, + { "MF2HD", 512, 18, 2, 1, 80, 0x1B, 0x54, }, + { "MF2DD", 512, 9, 2, 1, 80, 0x1B, 0x54, }, + { "F2HD", 512, 15, 2, 1, 80, 0x2A, 0x50, }, + { "F2DD", 512, 8, 2, 2, 40, 0x2A, 0x50, }, + { "F1DD", 512, 8, 1, 2, 40, 0x2A, 0x50, }, +}; +#define NTYPES (sizeof(floppytype)/sizeof(Type)) + +/* + * bytes/sector encoding for the controller, index is (bytes per sector/128) + */ +static int b2c[] = +{ +[1] 0, +[2] 1, +[4] 2, +[8] 3, }; -static int secbytes[] = +static int c2b[] = { 128, 256, 512, - 1024 + 1024, }; /* @@ -86,7 +104,8 @@ static int secbytes[] = */ struct Drive { - QLock; + QLock; /* exclusive access to the drive */ + Type *t; int dev; @@ -99,10 +118,10 @@ struct Drive int tcyl; /* target cylinder */ int thead; /* target head */ int tsec; /* target sector */ - long len; + long len; /* size of xfer */ int busy; /* true if drive is seeking */ - Rendez r; /* waiting for operation termination */ + Rendez r; /* waiting here for motor to spin up */ }; /* @@ -110,30 +129,133 @@ struct Drive */ struct Controller { - QLock; - Drive d[Nfloppy]; /* the floppy drives */ + QLock; /* exclusive access to the contoller */ + + Drive d[Ndrive]; /* the floppy drives */ int busy; /* true if a read or write in progress */ uchar stat[8]; /* status of an operation */ int confused; + int intr; /* true if interrupt occured */ + Rendez r; /* wait here for command termination */ }; Controller floppy; +/* + * predeclared + */ +static void motoron(Drive*); +static void motoroff(Drive*); +static void floppykproc(void*); +static int floppysend(int); +static int floppyrcv(void); +static int floppyresult(int); +static void floppypos(Drive*); +static int floppysense(Drive*); +static int interrupted(void*); +static int floppyrecal(Drive*); +static void floppyrevive(void); +static long floppyseek(Drive*); +static long floppyxfer(Drive*, int, void*, long); +static void floppyintr(Ureg*); + +static int +floppygen(Chan *c, Dirtab *tab, long ntab, long s, Dir *dp) +{ + long l; + Drive *dp; + + if(s >= ntab) + return -1; + if(c->dev >= Ndrive) + return -1; + + tab += s; + dp = &floppy.d[c->dev]; + if((tab->qid.path&~Mask) == Qdata) + l = dp->t->cap; + else + l = 8; + devdir(c, tab->qid, tab->name, l, tab->perm, dp); + return 1; +} + +void +floppyreset(void) +{ + Drive *dp; + + for(dp = floppy.d; dp < &floppy.d[Ndrive]; dp++){ + dp->dev = dp - floppy.d; + dp->t = &floppytype[0]; /* default type */ + dp->motoron = 1; + dp->cyl = -1; + motoroff(dp); + } + setvec(Floppyvec, floppyintr); +} + +void +floppyinit(void) +{ + Type *t; + + /* + * init dependent parameters + */ + for(t = floppytype; t < &floppytype[NTYPES], t++){ + t->cap = t->bytes * t->heads * t->sectors * t->tracks; + t->bcode = bcode[t->bytes/128]; + } + + /* + * watchdog to turn off the motors + */ + kproc(floppykproc, 0); +} +long +floppyread(Chan *c, void *a, long n) +{ + Drive *dp; + long rv, i; + uchar *aa = a; + + dp = &floppy.d[c->dev]; + for(rv = 0; rv < n; rv += i){ + i = floppyxfer(dp, Fread, aa+rv, n-rv); + if(i <= 0) + break; + } + return rv; +} + +long +floppywrite(Chan *c, void *a, long n) +{ + Drive *dp; + long rv, i; + uchar *aa = a; + + dp = &floppy.d[c->dev]; + for(rv = 0; rv < n; rv += i){ + i = floppyxfer(dp, Fwrite, aa+rv, n-rv); + if(i <= 0) + break; + } + return rv; +} + /* * 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) +static void +motoron(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; @@ -146,8 +268,8 @@ floppystart(Drive *dp) /* * stop the floppy if it hasn't been used in 5 seconds */ -void -floppystop(Drive *dp) +static void +motoroff(Drive *dp) { int cmd; @@ -155,22 +277,25 @@ floppystop(Drive *dp) outb(Fmotor, cmd); dp->motoron = 0; } -void -floppykproc(Alarm* a) +static void +floppykproc(void *a) { Drive *dp; - for(dp = floppy.d; dp < &floppy.d[Nfloppy]; dp++){ + for(dp = floppy.d; dp < &floppy.d[Ndrive]; dp++){ if(dp->motoron && TK2SEC(m->ticks - dp->lasttouched) > 5 && canqlock(dp)){ if(TK2SEC(m->ticks - dp->lasttouched) > 5) - floppystop(dp); + motoroff(dp); qunlock(dp); } } } -int +/* + * send a byte to the floppy + */ +static int floppysend(int data) { int tries; @@ -193,7 +318,10 @@ floppysend(int data) return -1; } -int +/* + * get a byte from the floppy + */ +static int floppyrcv(void) { int tries; @@ -215,8 +343,11 @@ floppyrcv(void) return -1; } -int -floppyrdstat(int n) +/* + * read a command result message from the floppy + */ +static int +floppyresult(int n) { int i; int c; @@ -230,14 +361,19 @@ floppyrdstat(int n) return 0; } -void -floppypos(Drive *dp, long off) +/* + * calculate physical address of a logical byte offset into the disk + * + * truncate dp->length if it crosses a cylinder boundary + */ +static void +floppypos(Drive *dp) { int lsec; int end; int cyl; - lsec = off/secbytes[dp->t->bytes]; + lsec = dp->off/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; @@ -246,16 +382,20 @@ floppypos(Drive *dp, long off) * can't read across cylinder boundaries. * if so, decrement the bytes to be read. */ - lsec = (off+dp->len)/secbytes[dp->t->bytes]; + lsec = (dp->off+dp->len)/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->len -= (lsec % dp->t->sectors)*dp->t->bytes; + dp->len -= ((lsec/dp->t->sectors) % dp->t->heads)*dp->t->bytes *dp->t->sectors; } } -int +/* + * get the interrupt cause from the floppy. we need to do this + * after seeks and recalibrations since they don't return results. + */ +static int floppysense(Drive *dp) { /* @@ -265,7 +405,7 @@ floppysense(Drive *dp) floppy.confused = 1; return -1; } - if(floppyrdstat(2) < 0){ + if(floppyresult(2) < 0){ floppy.confused = 1; dp->confused = 1; return -1; @@ -282,7 +422,19 @@ floppysense(Drive *dp) return 0; } -int +/* + * return true if interrupt occurred + */ +static int +interrupted(void *a) +{ + return floppy.intr; +} + +/* + * we've lost the floppy position, go to cylinder 0. + */ +static int floppyrecal(Drive *dp) { floppy.intr = 0; @@ -291,7 +443,7 @@ floppyrecal(Drive *dp) floppy.confused = 0; return -1; } - floppywait(); + sleep(&floppy.r, interrupted, 0); /* * get return values @@ -323,33 +475,17 @@ floppyrecal(Drive *dp) return 0; } +/* + * if the controller or a specific drive is in a confused state, + * reset it and get back to a kown state + */ void -floppyreset(void) -{ - Drive *dp; - - for(dp = floppy.d; dp < &floppy.d[Nfloppy]; dp++){ - dp->dev = dp - floppy.d; - dp->t = &floppytype[0]; /* default type */ - dp->motoron = 1; - dp->cyl = -1; - floppystop(dp); - } -} - -void -floppyinit(void) -{ - kproc(floppykproc, 0); -} - -void -floppyreset(void) +floppyrevive(void) { Drive *dp; /* - * reset the floppy if'n it's confused + * reset the floppy if it's confused */ if(floppy.confused){ /* reset controller and turn all motors off */ @@ -359,18 +495,18 @@ floppyreset(void) delay(1); outb(Fmotor, Fintena|Fena); spllo(); - for(dp = floppy.d; dp < &floppy.d[Nfloppy]; dp++){ + for(dp = floppy.d; dp < &floppy.d[Ndrive]; dp++){ dp->motoron = 0; dp->confused = 1; } - floppywait(); + sleep(&floppy.r, interrupted, 0); floppy.confused = 0; } /* * recalibrate any confused drives */ - for(dp = floppy.d; floppy.confused == 0 && dp < &floppy.d[Nfloppy]; dp++){ + for(dp = floppy.d; floppy.confused == 0 && dp < &floppy.d[Ndrive]; dp++){ if(dp->confused == 0) floppyrecal(dp); @@ -378,19 +514,9 @@ floppyreset(void) } -long -floppyseek(int dev, long off) +static long +floppyseek(Drive *dp) { - 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; @@ -400,7 +526,7 @@ floppyseek(int dev, long off) * tell floppy to seek */ if(floppysend(Fseek) < 0 - || floppysend((dp->thead<<2) | dev) < 0 + || floppysend((dp->thead<<2) | dp->dev) < 0 || floppysend(dp->tcyl * dp->t->steps) < 0){ print("seek cmd failed\n"); floppy.confused = 1; @@ -410,7 +536,7 @@ floppyseek(int dev, long off) /* * wait for interrupt */ - floppywait(); + sleep(&floppy.r, interrupted, 0); /* * get floppy status @@ -441,42 +567,47 @@ floppyseek(int dev, long off) return dp->offset; } -long +static long floppyxfer(Drive *dp, int cmd, void *a, long n) { - int dev; ulong addr; long offset; addr = (ulong)a; - dev = dp - floppy.d; + + qlock(&floppy); + qlock(dp); + if(waserror){ + qunlock(&floppy); + qunlock(dp); + } /* - * dma can't cross 64 k boundaries + * get floppy reset and spinning */ - if((addr & 0xffff0000) != ((addr+n) & 0xffff0000)) - n -= (addr+n)&0xffff; + if(floppy.confused || dp->confused) + floppyrevive(); + if(!dp->motoron) + motoron(dp); + /* + * calculate new position and seek to it (dp->len may be trimmed) + */ dp->len = n; - floppyseek(dev, dp->offset); + floppypos(dp); + if(floppyseek(dp) < 0) + errors("seeking floppy"); -/* print("tcyl %d, thead %d, tsec %d, addr %lux, n %d\n", +print("tcyl %d, thead %d, tsec %d, addr %lux, n %d\n", dp->tcyl, dp->thead, dp->tsec, addr, n);/**/ /* - * set up the dma + * set up the dma (dp->len may be trimmed) */ - 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); + dp->len = dmasetup(2, a, dp->len, cmd==Fread); /* - * tell floppy to go + * start operation */ cmd = cmd | (dp->t->heads > 1 ? Fmulti : 0); if(floppysend(cmd) < 0 @@ -484,64 +615,53 @@ floppyxfer(Drive *dp, int cmd, void *a, long n) || floppysend(dp->tcyl * dp->t->steps) < 0 || floppysend(dp->thead) < 0 || floppysend(dp->tsec) < 0 - || floppysend(dp->t->bytes) < 0 + || floppysend(dp->t->bcode) < 0 || floppysend(dp->t->sectors) < 0 || floppysend(dp->t->gpl) < 0 || floppysend(0xFF) < 0){ print("xfer cmd failed\n"); floppy.confused = 1; - return -1; + errors("floppy command failed"); } - floppywait(); + sleep(&floppy.r, interrupted, 0); /* * get status */ - if(floppyrdstat(7) < 0){ - print("xfer status failed\n"); + if(floppyresult(7) < 0){ +print("xfer status failed\n"); floppy.confused = 1; - return -1; + errors("floppy result failed"); } 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; + errors("floppy drive lost"); } 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]]; + offset = offset * c2b[floppy.stat[6]]; if(offset != dp->offset+n){ - print("new offset %d instead of %d\n", offset, dp->offset+dp->len); +print("new offset %d instead of %d\n", offset, dp->offset+dp->len); dp->confused = 1; - return -1;/**/ + errors("floppy drive lost"); } + qunlock(&floppy); + qunlock(dp); + poperror(); + 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 +static void floppyintr(Ureg *ur) { floppy.intr = 1; + wakeup(&floppy.r); } diff --git a/pc/fns.h b/pc/fns.h index 2d406e5ab87c886906d09de3cc9d8fe0fe6451d9..66a035e6ab432620d0dd22589ede374db90d8b8d 100644 --- a/pc/fns.h +++ b/pc/fns.h @@ -18,32 +18,6 @@ void fprestore(FPsave*); ulong getcr2(void); void idle(void); int inb(int); -void intr0(void); -void intr1(void); -void intr2(void); -void intr3(void); -void intr4(void); -void intr5(void); -void intr6(void); -void intr7(void); -void intr8(void); -void intr9(void); -void intr10(void); -void intr11(void); -void intr12(void); -void intr13(void); -void intr14(void); -void intr15(void); -void intr16(void); -void intr17(void); -void intr18(void); -void intr19(void); -void intr20(void); -void intr21(void); -void intr22(void); -void intr23(void); -void intr64(void); -void intrbad(void); void kbdinit(void); void kbdintr(Ureg*); void mmuinit(void); diff --git a/pc/headland.c b/pc/headland.c index 15f9baacae8deee2a3b2fd67284f77d9baa4142f..7f348d77d0a84e52423525e1215d67b3e6343879 100644 --- a/pc/headland.c +++ b/pc/headland.c @@ -13,6 +13,20 @@ enum Head= 0x92, /* control port */ Reset= (1<<0), /* reset the 386 */ A20ena= (1<<1), /* enable address line 20 */ + + /* + * the byte registers for DMA0 are all one byte apart + */ + Dma0= 0x00, + Dma0status= Dma0+0x8, /* status port */ + Dma0reset= Dma0+0xD, /* reset port */ + + /* + * the byte registers for DMA1 are all two bytes apart (why?) + */ + Dma1= 0xC0, + Dma1status= Dma1+2*0x8, /* status port */ + Dma1reset= Dma1+2*0xD, /* reset port */ }; /* @@ -96,6 +110,9 @@ exit(void) * * we assume BIOS has set up the command register before we * are booted. + * + * return the updated transfer length (we can't transfer across 64k + * boundaries) */ long dmasetup(int chan, void *va, long len, int isread) diff --git a/pc/io.h b/pc/io.h index 6b850438234cee0a42143b0af324b3124ffecac1..d744d5b7049b5193deeed605a06eadfae4d05db1 100644 --- a/pc/io.h +++ b/pc/io.h @@ -1,31 +1,16 @@ /* - * programmable interrupt vectors (for the 8259) + * programmable interrupt vectors (for the 8259's) */ enum { Faultvec= 14, /* page fault */ - Int0vec= 16, /* first interrupt vector used by the 8259 */ - Clockvec= Int0vec+0, /* clock interrupts */ - Kbdvec= Int0vec+1, /* keyboard interrupts */ - Mousevec= Int0vec+12, /* mouse interrupt */ -}; - -/* - * 8237 dma controllers - */ -enum -{ - /* - * the byte registers for DMA0 are all one byte apart - */ - Dma0= 0x00, - Dma0status= Dma0+0x8, /* status port */ - Dma0reset= Dma0+0xD, /* reset port */ - - /* - * the byte registers for DMA1 are all two bytes apart (why?) - */ - Dma1= 0xC0, - Dma1status= Dma1+2*0x8, /* status port */ - Dma1reset= Dma1+2*0xD, /* reset port */ + 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 */ + Floppyvec= Int0vec+6, /* floppy interrupts */ + Int1vec= Int0vec+8, /* second 8259 */ + Mousevec= Int1vec+4, /* mouse interrupt */ + Hardvec= Int1vec+6, /* hard disk */ }; diff --git a/pc/kbd.c b/pc/kbd.c index c3469582840a869d4c8e6abeffa16fd3cf896cad..93d807a43b9d6f6184797f99d1d88f9fa72f6561 100644 --- a/pc/kbd.c +++ b/pc/kbd.c @@ -5,6 +5,10 @@ #include "fns.h" #include "io.h" +#include +#include +#include "screen.h" + enum { Data= 0x60, /* data port */ @@ -16,7 +20,7 @@ enum { Inhibit= 0x10, /* keyboard/mouse inhibited */ Minready= 0x20, /* mouse character ready */ Rtimeout= 0x40, /* general timeout */ - Parity= 0x80, /* 1 == error */ + Parity= 0x80, Cmd= 0x64, /* command port (write only) */ @@ -24,7 +28,7 @@ enum { PF= Spec|0x20, /* num pad function key */ View= Spec|0x00, /* view (shift window up) */ - F= Spec|0x40, /* function key */ + KF= Spec|0x40, /* function key */ Shift= Spec|0x60, Break= Spec|0x61, Ctrl= Spec|0x62, @@ -33,16 +37,16 @@ enum { Num= Spec|0x65, No= Spec|0x7F, /* no mapping */ - Home= F|13, - Up= F|14, - Pgup= F|15, - Print= F|16, + Home= KF|13, + Up= KF|14, + Pgup= KF|15, + Print= KF|16, Left= View, Right= View, End= '\r', Down= View, Pgdown= View, - Ins= F|20, + Ins= KF|20, Del= 0x7F, }; @@ -55,11 +59,11 @@ uchar kbtab[] = [0x20] 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', [0x28] '\'', '`', Shift, '\\', 'z', 'x', 'c', 'v', [0x30] 'b', 'n', 'm', ',', '.', '/', Shift, No, -[0x38] Latin, ' ', Caps, F|1, F|2, F|3, F|4, F|5, -[0x40] F|6, F|7, F|8, F|9, F|10, Num, F|12, Home, +[0x38] Latin, ' ', Caps, KF|1, KF|2, KF|3, KF|4, KF|5, +[0x40] KF|6, KF|7, KF|8, KF|9, KF|10, Num, KF|12, Home, [0x48] No, No, No, No, No, No, No, No, -[0x50] No, No, No, No, No, No, No, F|11, -[0x58] F|12, No, No, No, No, No, No, No, +[0x50] No, No, No, No, No, No, No, KF|11, +[0x58] KF|12, No, No, No, No, No, No, No, }; uchar kbtabshift[] = @@ -71,11 +75,11 @@ uchar kbtabshift[] = [0x20] 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', [0x28] '"', '~', Shift, '|', 'Z', 'X', 'C', 'V', [0x30] 'B', 'N', 'M', '<', '>', '?', Shift, No, -[0x38] Latin, ' ', Caps, F|1, F|2, F|3, F|4, F|5, -[0x40] F|6, F|7, F|8, F|9, F|10, Num, F|12, Home, +[0x38] Latin, ' ', Caps, KF|1, KF|2, KF|3, KF|4, KF|5, +[0x40] KF|6, KF|7, KF|8, KF|9, KF|10, Num, KF|12, Home, [0x48] No, No, No, No, No, No, No, No, -[0x50] No, No, No, No, No, No, No, F|11, -[0x58] F|12, No, No, No, No, No, No, No, +[0x50] No, No, No, No, No, No, No, KF|11, +[0x58] KF|12, No, No, No, No, No, No, No, }; uchar kbtabesc1[] = @@ -236,45 +240,110 @@ latin1(int k1, int k2) return 0; } +static void +mousecmd(int cmd, int arg) +{ + unsigned int c; + + do { + while(inb(Status) & Outbusy) + ; + outb(Cmd, 0xD4); + while(inb(Status) & Outbusy) + ; + outb(Data, cmd); + if(arg >= 0){ + while(inb(Status) & Outbusy) + ; + outb(Data, arg); + } + while(!(inb(Status) & Inready)) + ; + c = inb(Data); + } while(c == 0xFE); + if(c != 0xFA) + print("mouse command returns bad status %lux", c); +} + void kbdinit(void) { - uchar c; + int c, s; initq(&kbdq); setvec(Kbdvec, kbdintr); + initq(&mouseq); + setvec(Mousevec, kbdintr); /* wait for a quiescent controller */ while((c = inb(Status)) & (Outbusy | Inready)) if(c & Inready) inb(Data); - /* read controller command byte */ - outb(Cmd, 0x20); - while(!(inb(Status) & Inready)) - ; - c = inb(Data); -print("input completed\n"); -delay(5000); - - /* enable mouse and mouse interupts */ - c = (c&~0x20) | 0x02; + /* enable kbd/mouse xfers and interrupts */ outb(Cmd, 0x60); while(inb(Status) & Outbusy) ; - outb(Data, c); -print("mouse enabled\n"); + outb(Data, 0x47); + while(inb(Status) & Outbusy) + ; + outb(Cmd, 0xA8); + + /* make mouse streaming (and enabled) */ + mousecmd(0xEA, -1); + mousecmd(0xF4, -1); + + /* resolution */ + mousecmd(0xE8, 0x03); +print("res set\n"); delay(5000); +} - initq(&mouseq); - setvec(Mousevec, kbdintr); +/* + * mouse message is three bytes + * + * byte 0 - 0 0 SDY SDX 1 M R L + * byte 1 - DX + * byte 2 - DY + */ +static void +mymouseputc(int c) +{ + static short msg[3]; + static int nb; + static uchar b[] = {0, 4, 1, 5, 2, 6, 3, 7}; + static lastdx, lastdy; + int diff; + extern Mouseinfo mouse; + + /* + * check byte 0 for consistency + */ + if(nb==0 && (c&0xc8)!=0x08) + return; + + msg[nb] = c; + if(++nb == 3){ + nb = 0; + if(msg[0] & 0x10) + msg[1] |= 0xFF00; + if(msg[0] & 0x20) + msg[2] |= 0xFF00; + + 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(); + } } /* * keyboard interrupt */ -void -kbdintr(Ureg *ur) +int +kbdintr0(void) { int s, c, nc; static int esc1, esc2; @@ -286,18 +355,23 @@ kbdintr(Ureg *ur) int keyup; /* - * get status and character + * get status */ s = inb(Status); + if(!(s&Inready)) + return -1; + + /* + * get the character + */ c = inb(Data); /* * if it's the mouse... */ if(s & Minready){ -print("mousechar\n"); - mouseputc(&mouseq, c); - return; + mymouseputc(c); + return 0; } keyup = c&0x80; @@ -305,7 +379,7 @@ print("mousechar\n"); if(c > sizeof kbtab){ print("unknown key %ux\n", c|keyup); kbdputc(&kbdq, k1); - return; + return 0; } /* @@ -313,10 +387,10 @@ print("mousechar\n"); */ if(c == 0xe0){ esc1 = 1; - return; + return 0; } else if(c == 0xe1){ esc2 = 2; - return; + return 0; } if(esc1){ @@ -324,7 +398,7 @@ print("mousechar\n"); esc1 = 0; } else if(esc2){ esc2--; - return; + return 0; } else if(shift) c = kbtabshift[c]; else @@ -345,7 +419,7 @@ print("mousechar\n"); ctl = 0; break; } - return; + return 0; } /* @@ -358,7 +432,7 @@ print("mousechar\n"); case 1: k1 = c; lstate = 2; - return; + return 0; case 2: k2 = c; lstate = 0; @@ -375,21 +449,28 @@ print("mousechar\n"); switch(c){ case Caps: caps ^= 1; - return; + return 0; case Num: num ^= 1; - return; + return 0; case Shift: shift = 1; - return; + return 0; case Latin: lstate = 1; - return; + return 0; case Ctrl: ctl = 1; - return; + return 0; } } kbdputc(&kbdq, c); - return; + return 0; +} + +void +kbdintr(Ureg *ur) +{ + while(kbdintr0() == 0) + ; } diff --git a/pc/l.s b/pc/l.s index fbce3cfa236604c5a64ef0683c750bf4a264d574..f4fa78a8ac1e9eb10244793cc99edf1918c90283 100644 --- a/pc/l.s +++ b/pc/l.s @@ -347,6 +347,38 @@ TEXT intr23(SB),$0 PUSHL $0 PUSHL $23 JMP intrcommon +TEXT intr24(SB),$0 + PUSHL $0 + PUSHL $24 + JMP intrcommon +TEXT intr25(SB),$0 + PUSHL $0 + PUSHL $25 + JMP intrcommon +TEXT intr26(SB),$0 + PUSHL $0 + PUSHL $26 + JMP intrcommon +TEXT intr27(SB),$0 + PUSHL $0 + PUSHL $27 + JMP intrcommon +TEXT intr28(SB),$0 + PUSHL $0 + PUSHL $28 + JMP intrcommon +TEXT intr29(SB),$0 + PUSHL $0 + PUSHL $29 + JMP intrcommon +TEXT intr30(SB),$0 + PUSHL $0 + PUSHL $30 + JMP intrcommon +TEXT intr31(SB),$0 + PUSHL $0 + PUSHL $31 + JMP intrcommon TEXT intr64(SB),$0 PUSHL $0 PUSHL $64 diff --git a/pc/trap.c b/pc/trap.c index 47be159fab8b1c6196295f6a4c0da35171962292..7c28904b2a0917a425d9c4b527abc0d51b059862 100644 --- a/pc/trap.c +++ b/pc/trap.c @@ -10,6 +10,17 @@ void noted(Ureg*, ulong); void notify(Ureg*); +void intr0(void), intr1(void), intr2(void), intr3(void); +void intr4(void), intr5(void), intr6(void), intr7(void); +void intr8(void), intr9(void), intr10(void), intr11(void); +void intr12(void), intr13(void), intr14(void), intr15(void); +void intr16(void), intr17(void), intr18(void), intr19(void); +void intr20(void), intr21(void), intr22(void), intr23(void); +void intr24(void), intr25(void), intr26(void), intr27(void); +void intr28(void), intr29(void), intr30(void), intr31(void); +void intr64(void); +void intrbad(void); + /* * 8259 interrupt controllers */ @@ -23,8 +34,8 @@ enum EOI= 0x20, /* non-specific end of interrupt */ }; -int int0mask = 7; /* interrupts enabled for first 8259 */ -int int1mask = 7; /* interrupts enabled for second 8259 */ +int int0mask = 0xff; /* interrupts enabled for first 8259 */ +int int1mask = 0xff; /* interrupts enabled for second 8259 */ /* * trap/interrupt gates @@ -50,6 +61,9 @@ setvec(int v, void (*r)(Ureg*)) if((v&~0x7) == Int0vec){ int0mask &= ~(1<<(v&7)); outb(Int0aux, int0mask); + } else if((v&~0x7) == Int1vec){ + int1mask &= ~(1<<(v&7)); + outb(Int1aux, int1mask); } } @@ -61,6 +75,12 @@ trapinit(void) { int i; + /* + * set all interrupts to panics + */ + for(i = 32; i < 256; i++) + sethvec(i, intrbad, SEGIG, 0); + /* * set the standard traps */ @@ -80,6 +100,10 @@ trapinit(void) sethvec(13, intr13, SEGIG, 0); sethvec(14, intr14, SEGIG, 0); sethvec(15, intr15, SEGIG, 0); + + /* + * set the standard devices + */ sethvec(16, intr16, SEGIG, 0); sethvec(17, intr17, SEGIG, 0); sethvec(18, intr18, SEGIG, 0); @@ -88,12 +112,14 @@ trapinit(void) sethvec(21, intr21, SEGIG, 0); sethvec(22, intr22, SEGIG, 0); sethvec(23, intr23, SEGIG, 0); - - /* - * set all others to unknown interrupts - */ - for(i = 24; i < 256; i++) - sethvec(i, intrbad, SEGIG, 0); + sethvec(24, intr24, SEGIG, 0); + sethvec(25, intr25, SEGIG, 0); + sethvec(26, intr26, SEGIG, 0); + sethvec(27, intr27, SEGIG, 0); + sethvec(28, intr28, SEGIG, 0); + sethvec(29, intr29, SEGIG, 0); + sethvec(30, intr30, SEGIG, 0); + sethvec(31, intr31, SEGIG, 0); /* * system calls @@ -115,8 +141,26 @@ trapinit(void) outb(Int0ctl, 0x11); /* ICW1 - edge triggered, master, ICW4 will be sent */ outb(Int0aux, Int0vec); /* ICW2 - interrupt vector offset */ - outb(Int0aux, 0x04); /* ICW3 - master level 2 */ + outb(Int0aux, 0x04); /* ICW3 - have slave on level 2 */ outb(Int0aux, 0x01); /* ICW4 - 8086 mode, not buffered */ + + /* + * Set up the second 8259 interrupt processor. + * Make 8259 interrupts start at CPU vector Int0vec. + * Set the 8259 as master with edge triggered + * input with fully nested interrupts. + */ + outb(Int1ctl, 0x11); /* ICW1 - edge triggered, master, + ICW4 will be sent */ + outb(Int1aux, Int1vec); /* ICW2 - interrupt vector offset */ + outb(Int1aux, 0x02); /* ICW3 - I am a slave on level 2 */ + outb(Int1aux, 0x01); /* ICW4 - 8086 mode, not buffered */ + + /* + * pass #2 8259 interrupts to #1 + */ + int0mask &= ~0x04; + outb(Int0aux, int0mask); } /* @@ -125,19 +169,28 @@ trapinit(void) void trap(Ureg *ur) { - if(ur->trap>=256 || ivec[ur->trap] == 0) - panic("bad trap type %d %lux\n", ur->trap, ur->pc); + int v; + int c; + + v = ur->trap; + if(v>=256 || ivec[v] == 0) + panic("bad trap type %d %lux\n", v, ur->pc); /* * call the trap routine */ - (*ivec[ur->trap])(ur); + (*ivec[v])(ur); /* * tell the 8259 that we're done with the * highest level interrupt */ - outb(Int0ctl, EOI); + c = v&~0x7; + if(c==Int0vec || c==Int1vec){ + outb(Int0ctl, EOI); + if(c == Int1vec) + outb(Int1ctl, EOI); + } } /* @@ -173,48 +226,7 @@ execpc(ulong entry) /* * system calls */ -#undef CHDIR /* BUG */ -#include "/sys/src/libc/9syscall/sys.h" - -typedef long Syscall(ulong*); -Syscall sysr1, sysfork, sysexec, sysgetpid, syssleep, sysexits, sysdeath, syswait; -Syscall sysopen, sysclose, sysread, syswrite, sysseek, syserrstr, sysaccess, sysstat, sysfstat; -Syscall sysdup, syschdir, sysforkpgrp, sysbind, sysmount, syspipe, syscreate; -Syscall sysbrk_, sysremove, syswstat, sysfwstat, sysnotify, sysnoted, sysalarm; - -Syscall *systab[]={ - sysr1, - syserrstr, - sysbind, - syschdir, - sysclose, - sysdup, - sysalarm, - sysexec, - sysexits, - sysfork, - sysforkpgrp, - sysfstat, - sysdeath, - sysmount, - sysopen, - sysread, - sysseek, - syssleep, - sysstat, - syswait, - syswrite, - syspipe, - syscreate, - sysdeath, - sysbrk_, - sysremove, - syswstat, - sysfwstat, - sysnotify, - sysnoted, - sysdeath, /* sysfilsys */ -}; +#include "../port/systab.h" long syscall(Ureg *ur) diff --git a/pc/vga.c b/pc/vga.c index 70d47c557482647f9256628bf15787565dbf5b79..a7f08d758424e232c0cbebe80be2bf13b683e6a7 100644 --- a/pc/vga.c +++ b/pc/vga.c @@ -240,7 +240,7 @@ getcolor(ulong p, ulong *pr, ulong *pg, ulong *pb) ulong ans; /* - * The magnum monochrome says 0 is black (zero intensity) + * The safari monochrome says 0 is black (zero intensity) */ if(p == 0) ans = 0; diff --git a/port/devbit.c b/port/devbit.c index e31c2694ea1b89f1dffd8b14a446736236a9786a..1e4b77775f0b4f3160731446bf72929060df5d73 100644 --- a/port/devbit.c +++ b/port/devbit.c @@ -1133,12 +1133,17 @@ void Cursortocursor(Cursor *c) { int i; + uchar *p; lock(&cursor); memmove(&cursor, c, sizeof(Cursor)); for(i=0; i<16; i++){ - setbits[i] = (c->set[2*i]<<24) + (c->set[2*i+1]<<16); - clrbits[i] = (c->clr[2*i]<<24) + (c->clr[2*i+1]<<16); + p = (uchar*)&setbits[i]; + *p = c->set[2*i]; + *(p+1) = c->set[2*i+1]; + p = (uchar*)&clrbits[i]; + *p = c->clr[2*i]; + *(p+1) = c->clr[2*i+1]; } unlock(&cursor); } diff --git a/port/portdat.h b/port/portdat.h index e24e25193289deed3725ddac06d883085e9084c4..f6943fb2807b0f88ca93cd4b14c0e4d8ad8118fa 100644 --- a/port/portdat.h +++ b/port/portdat.h @@ -582,7 +582,7 @@ enum { Streambhi= 32, /* block count high water mark */ }; -#define MAXSYSARG 6 /* for mount(fd, mpt, flag, arg, srv, authfd) */ +#define MAXSYSARG 6 /* for mount(fd, mpt, flag, arg, srv) */ #define PRINTSIZE 256 #define NUMSIZE 12 /* size of formatted number */ diff --git a/port/segment.c b/port/segment.c index 00f8ba08410ff9a9f7b2aae033850ecee4ba3ccb..6f7c41319dd3bcbf135849c44dce10799518d36b 100644 --- a/port/segment.c +++ b/port/segment.c @@ -442,7 +442,7 @@ segattach(Proc *p, ulong attr, char *name, ulong va, ulong len) errors("segments overlap"); } - for(ps = physseg; *(ps->name); ps++) + for(ps = physseg; ps->name; ps++) if(strcmp(name, ps->name) == 0) goto found; diff --git a/port/systab.h b/port/systab.h new file mode 100644 index 0000000000000000000000000000000000000000..483f3c2fa678ef93538ded8d913ae40a3aa0ebfd --- /dev/null +++ b/port/systab.h @@ -0,0 +1,47 @@ +#undef CHDIR /* BUG */ +#include "/sys/src/libc/9syscall/sys.h" + +typedef long Syscall(ulong*); +Syscall sysbind, sysbrk_, syschdir, sysclose, syscreate, sysdeath; +Syscall sysdup, syserrstr, sysexec, sysexits, sysfork, sysforkpgrp; +Syscall sysfstat, sysfwstat, sysgetpid, sysmount, sysnoted; +Syscall sysnotify, sysopen, syspipe, sysr1, sysread, sysremove, sysseek; +Syscall syssleep, sysstat, syswait, syswrite, syswstat, sysalarm, syssegbrk; +Syscall syssegattach, syssegdetach, syssegfree, syssegflush; + +Syscall *systab[]={ + [SYSR1] sysr1, + [ERRSTR] syserrstr, + [BIND] sysbind, + [CHDIR] syschdir, + [CLOSE] sysclose, + [DUP] sysdup, + [ALARM] sysalarm, + [EXEC] sysexec, + [EXITS] sysexits, + [FORK] sysfork, + [FORKPGRP] sysforkpgrp, + [FSTAT] sysfstat, + [SEGBRK] syssegbrk, + [MOUNT] sysmount, + [OPEN] sysopen, + [READ] sysread, + [SEEK] sysseek, + [SLEEP] syssleep, + [STAT] sysstat, + [WAIT] syswait, + [WRITE] syswrite, + [PIPE] syspipe, + [CREATE] syscreate, + [___USERSTR___] sysdeath, + [BRK_] sysbrk_, + [REMOVE] sysremove, + [WSTAT] syswstat, + [FWSTAT] sysfwstat, + [NOTIFY] sysnotify, + [NOTED] sysnoted, + [SEGATTACH] syssegattach, + [SEGDETACH] syssegdetach, + [SEGFREE] syssegfree, + [SEGFLUSH] syssegflush, +}; diff --git a/power/segment.h b/power/segment.h index 4684efad0c2ccaba7aa393e361b7cd8c535570ab..8ff7b1d053dde1db314631cb6e0b81abdbf64a15 100644 --- a/power/segment.h +++ b/power/segment.h @@ -12,7 +12,7 @@ struct Physseg Page *(*pgalloc)(ulong); /* Allocation if we need it */ void (*pgfree)(Page*); }physseg[] = { - { SG_SHARED, "lock", 0, 1024*BY2PG, &lkpage, &lkpgfree }, + { SG_PHYSICAL, "lock", 0, 1024*BY2PG, &lkpage, &lkpgfree }, { SG_SHARED, "shared", 0, SEGMAXSIZE, &snewpage, &putpage }, { SG_PHYSICAL, "kmem", KZERO, SEGMAXSIZE, 0, 0 }, { SG_BSS, "memory", 0, SEGMAXSIZE, &snewpage, &putpage }, diff --git a/power/trap.c b/power/trap.c index 4bc444d2d204b110d5b0a1db3b50041b8ca58111..fbec0bdd2a9d0458c7d5f2b9ced2c33928e9bdce 100644 --- a/power/trap.c +++ b/power/trap.c @@ -461,53 +461,7 @@ noted(Ureg **urp, ulong arg0) } -#undef CHDIR /* BUG */ -#include "/sys/src/libc/9syscall/sys.h" - -typedef long Syscall(ulong*); -Syscall sysbind, sysbrk_, syschdir, sysclose, syscreate, sysdeath; -Syscall sysdup, syserrstr, sysexec, sysexits, sysfork, sysforkpgrp; -Syscall sysfstat, sysfwstat, sysgetpid, sysmount, sysnoted; -Syscall sysnotify, sysopen, syspipe, sysr1, sysread, sysremove, sysseek; -Syscall syssleep, sysstat, syswait, syswrite, syswstat, sysalarm, syssegbrk; -Syscall syssegattach, syssegdetach, syssegfree, syssegflush; - -Syscall *systab[]={ - [SYSR1] sysr1, - [ERRSTR] syserrstr, - [BIND] sysbind, - [CHDIR] syschdir, - [CLOSE] sysclose, - [DUP] sysdup, - [ALARM] sysalarm, - [EXEC] sysexec, - [EXITS] sysexits, - [FORK] sysfork, - [FORKPGRP] sysforkpgrp, - [FSTAT] sysfstat, - [SEGBRK] syssegbrk, - [MOUNT] sysmount, - [OPEN] sysopen, - [READ] sysread, - [SEEK] sysseek, - [SLEEP] syssleep, - [STAT] sysstat, - [WAIT] syswait, - [WRITE] syswrite, - [PIPE] syspipe, - [CREATE] syscreate, - [___USERSTR___] sysdeath, - [BRK_] sysbrk_, - [REMOVE] sysremove, - [WSTAT] syswstat, - [FWSTAT] sysfwstat, - [NOTIFY] sysnotify, - [NOTED] sysnoted, - [SEGATTACH] syssegattach, - [SEGDETACH] syssegdetach, - [SEGFREE] syssegfree, - [SEGFLUSH] syssegflush, -}; +#include "../port/systab.h" long syscall(Ureg *aur) @@ -543,7 +497,7 @@ syscall(Ureg *aur) u->nerrlab = 0; ret = -1; if(!waserror()){ - if(r1 >= sizeof systab/BY2WD){ + if(r1 >= sizeof systab/sizeof systab[0]){ pprint("bad sys call number %d pc %lux\n", r1, ((Ureg*)UREGADDR)->pc); msg = "sys: bad sys call"; Bad: diff --git a/ss/trap.c b/ss/trap.c index fc2f0a30b0fad3d4be907c4d63ef8da0330a3b35..68810afcd3ab4325c0e643940af4e4f2b35202e4 100644 --- a/ss/trap.c +++ b/ss/trap.c @@ -306,48 +306,7 @@ noted(Ureg **urp, ulong arg0) } } -#undef CHDIR /* BUG */ -#include "/sys/src/libc/9syscall/sys.h" - -typedef long Syscall(ulong*); -Syscall sysr1, sysfork, sysexec, sysgetpid, syssleep, sysexits, sysdeath, syswait; -Syscall sysopen, sysclose, sysread, syswrite, sysseek, syserrstr, sysaccess, sysstat, sysfstat; -Syscall sysdup, syschdir, sysforkpgrp, sysbind, sysmount, syspipe, syscreate; -Syscall sysbrk_, sysremove, syswstat, sysfwstat, sysnotify, sysnoted, sysalarm; - -Syscall *systab[]={ - sysr1, - syserrstr, - sysbind, - syschdir, - sysclose, - sysdup, - sysalarm, - sysexec, - sysexits, - sysfork, - sysforkpgrp, - sysfstat, - sysdeath, - sysmount, - sysopen, - sysread, - sysseek, - syssleep, - sysstat, - syswait, - syswrite, - syspipe, - syscreate, - sysdeath, - sysbrk_, - sysremove, - syswstat, - sysfwstat, - sysnotify, - sysnoted, - sysdeath, /* sysfilsys */ -}; +#include "../port/systab.h" long syscall(Ureg *aur)