From afbbb67cc61b008c53ef7c0ee021d420fc550626 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Wed, 14 Jul 1999 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1999-07-14 --- alphapc/fns.h | 1 - alphapc/l.s | 4 - carrera/fns.h | 1 - carrera/l.s | 4 - mpc/fns.h | 1 - mpc/l.s | 4 - pc/devastar.c | 23 ++++- pc/devata.c | 14 +++ pc/devfloppy.c | 5 + pc/devi82365.c | 19 +++- pc/devlpt.c | 10 +- pc/devrtc.c | 9 +- pc/devvga.c | 25 +++++ pc/dma.c | 31 ++---- pc/ether2000.c | 4 + pc/ether2114x.c | 6 ++ pc/ether589.c | 3 + pc/ether79c970.c | 8 +- pc/ether8003.c | 6 +- pc/ether82557.c | 8 +- pc/etherelnk3.c | 30 +++++- pc/etherwavelan.c | 14 ++- pc/floppy.h | 7 ++ pc/fns.h | 6 +- pc/i8253.c | 1 + pc/i8259.c | 2 + pc/kbd.c | 4 +- pc/main.c | 6 +- pc/memory.c | 34 ------- pc/ns16552.h | 22 +++++ port/alloc.c | 245 ++++++++++++++++++++++++++++++++++------------ port/allocb.c | 4 +- port/devcons.c | 5 +- port/devdraw.c | 2 +- port/devmnt.c | 6 +- port/lib.h | 1 + port/portfns.h | 6 +- port/qio.c | 2 +- 38 files changed, 415 insertions(+), 168 deletions(-) diff --git a/alphapc/fns.h b/alphapc/fns.h index 701712d2f78bbf32a709c6dc33dc21452c08064a..fe5ee2e96ae02fe6363d1e4c23bd9dbcb202e6e8 100644 --- a/alphapc/fns.h +++ b/alphapc/fns.h @@ -26,7 +26,6 @@ void firmware(void); #define flushpage(s) icflush() void fpenab(int); void fptrap(Ureg*); -ulong getcallerpc(void*); char *getconf(char*); ulong getfcr(void); ulong getstatus(void); diff --git a/alphapc/l.s b/alphapc/l.s index b50ebf97135c0482fb722761e3f513ef830cef50..e1ff930bd4b86112ad15d1aba5ceb67ccab26b91 100644 --- a/alphapc/l.s +++ b/alphapc/l.s @@ -169,10 +169,6 @@ tas1: tas2: RET -TEXT getcallerpc(SB), $-8 - MOVL 0(SP), R0 - RET - TEXT fpenab(SB), $-8 MOVQ R0, R16 CALL_PAL $PALwrfen diff --git a/carrera/fns.h b/carrera/fns.h index 52193611f982cba9113a411df9f6da9f91c28f62..3ee2781383662cd9e89de46f3d60cb265bd051ef 100644 --- a/carrera/fns.h +++ b/carrera/fns.h @@ -19,7 +19,6 @@ ulong fcr31(void); void firmware(int); #define flushpage(s) icflush((void*)(s), BY2PG) void fptrap(Ureg*); -ulong getcallerpc(void*); ulong getstatus(void); void gettlb(int, ulong*); int gettlbp(ulong, ulong*); diff --git a/carrera/l.s b/carrera/l.s index 0e2b0e032cab64db1dde6b831b6e0d099004dce4..cc6a7dd100b2bdfd62588de12ad5fbc581acd916 100644 --- a/carrera/l.s +++ b/carrera/l.s @@ -785,10 +785,6 @@ ccache: WAIT RET -TEXT getcallerpc(SB), $0 - MOVW 0(SP), R1 - RET - TEXT rdcount(SB), $0 MOVW M(COUNT), R1 NOOP diff --git a/mpc/fns.h b/mpc/fns.h index 104a2b08c5ec2ac2be53c247d15d9bf31a9b208f..48becbc79a6f2a6d48a2387cd537ba090746c841 100644 --- a/mpc/fns.h +++ b/mpc/fns.h @@ -98,7 +98,6 @@ int unsac(uchar *dst, uchar *src, int n, int nsrc); void wbflush(void); #define waserror() (up->nerrlab++, setlabel(&up->errlab[up->nerrlab-1])) -ulong getcallerpc(void*); // identity map between kernel physical and virtual addresses #define KADDR(a) ((void*)(a)) diff --git a/mpc/l.s b/mpc/l.s index 0883f4951272209f700f332a9139e55b86ff17f2..5d2a11714139cbc6bd43d04152fe63a3455f2714 100644 --- a/mpc/l.s +++ b/mpc/l.s @@ -407,10 +407,6 @@ TEXT putdec(SB), $0 MOVW R3, SPR(DEC) RETURN -TEXT getcallerpc(SB), $-4 - MOVW 0(R1), R3 - RETURN - TEXT getdar(SB), $0 MOVW SPR(DAR), R3 RETURN diff --git a/pc/devastar.c b/pc/devastar.c index 9f61dc43b0a5df751299be5490a4b211af851b38..8193180f755e28682e175ff089d8a8a4fd851cff 100644 --- a/pc/devastar.c +++ b/pc/devastar.c @@ -413,6 +413,7 @@ astarreset(void) int i, x; Astar *a; Pcidev *p; + char name[8]; p = nil; for(i = 0; i < Maxcard; i++){ @@ -456,6 +457,14 @@ astarreset(void) a->addr = (uchar*)a->mem; a->gcb = (GCB*)(a->mem+0x10000); + sprint(name, "astar%d", i); + if(ioalloc(a->port, p->mem[2].size, 0, name) < 0){ + print("#G%d: port 0x%lux in use", a->id, a->port); + xfree(a); + astar[nastar] = 0; + continue; + } + /* * Toggle the software reset and wait for * the adapter local init status to indicate done. @@ -528,28 +537,40 @@ static int astarsetup(Astar *a) { int i, found; + char name[8]; /* see if the card exists */ found = 0; if(a->port == 0) for(i = 0; isaport[i]; i++){ a->port = isaport[i]; + sprint(name, "astar%d", a->id); + if(ioalloc(a->port, 6, 0, name) < 0) + continue; found = astarprobe(isaport[i]); if(found){ isaport[i] = -1; break; } } - else + else { + sprint(name, "astar%d", a->id); + if(ioalloc(a->port, 6, 0, name) < 0){ + print("#G%d: port 0x%lux in use\n", a->id, a->port); + return -1; + } found = astarprobe(a->port); + } if(!found){ print("#G%d: not found\n", a->id); + iofree(a->port); return -1; } /* check interrupt level */ if(isairqcode[a->irq] == -1){ print("#G%d: bad irq %lud\n", a->id, a->irq); + iofree(a->port); return -1; } diff --git a/pc/devata.c b/pc/devata.c index 21066ca8e75ef4b9e8c3b4443b1429febcec0c02..d7e92da71516ec88498e4c1768cff92e7e924a03 100644 --- a/pc/devata.c +++ b/pc/devata.c @@ -425,6 +425,7 @@ atactlrprobe(int ctlrno, Atadev* devp, int irq, int resetok) Controller *ctlr; int atapi, cmdport, ctlport, mask, once, timo; uchar error, status, msb, lsb; + char name[13]; cmdport = devp->cmdport; ctlport = devp->ctlport; @@ -591,6 +592,19 @@ atapislave: xfree(ctlr); return -1; } + sprint(name, "ata%dcmd", ctlrno); + if(ioalloc(devp->cmdport, 0x8, 0, name) < 0){ + print("#H%d: cmd port %d in use", ctlrno, devp->cmdport); + xfree(ctlr); + return -1; + } + sprint(name, "ata%dctl", ctlrno); + if(ioalloc(devp->ctlport+Pctl, 1, 0, name) < 0){ + iofree(devp->cmdport); + print("#H%d: ctl port %d in use", ctlrno, devp->ctlport); + xfree(ctlr); + return -1; + } atactlr[ctlrno] = ctlr; if(have640b && (ctlrno & 0x01)) diff --git a/pc/devfloppy.c b/pc/devfloppy.c index 173d3f502c032392e5dda99b9da98799923dbdf9..74559e8bfab31b511a0f1b1e3a0ef8ee49131328 100644 --- a/pc/devfloppy.c +++ b/pc/devfloppy.c @@ -146,6 +146,8 @@ floppyreset(void) ulong maxtsize; floppysetup0(&fl); + if(fl.ndrive == 0) + return; /* * init dependent parameters @@ -201,6 +203,9 @@ floppyattach(char *spec) { static int kstarted; + if(fl.ndrive == 0) + error(Enodev); + if(kstarted == 0){ /* * watchdog to turn off the motors diff --git a/pc/devi82365.c b/pc/devi82365.c index ba7c49db442d5621bef0e49c47875ddb3096b317..6c6df77e12a6f90f855b8d647547cc3e2a0b47f9 100644 --- a/pc/devi82365.c +++ b/pc/devi82365.c @@ -618,11 +618,20 @@ i82365reset(void) if(isaconfig("pcmcia", 0, &isa) && isa.irq) irq = isa.irq; - /* look for controllers */ - i82386probe(0x3E0, 0x3E1, 0); - i82386probe(0x3E0, 0x3E1, 1); - i82386probe(0x3E2, 0x3E3, 0); - i82386probe(0x3E2, 0x3E3, 1); + /* look for controllers if the ports aren't already taken */ + if(ioalloc(0x3E0, 2, 0, "i82386.0") >= 0){ + i82386probe(0x3E0, 0x3E1, 0); + i82386probe(0x3E0, 0x3E1, 1); + if(ncontroller == 0) + iofree(0x3E0); + } + if(ioalloc(0x3E2, 2, 0, "i82386.1") >= 0){ + i = ncontroller; + i82386probe(0x3E2, 0x3E3, 0); + i82386probe(0x3E2, 0x3E3, 1); + if(ncontroller == i) + iofree(0x3E2); + } for(i = 0; i < ncontroller; i++) nslot += controller[i]->nslot; slot = xalloc(nslot * sizeof(Slot)); diff --git a/pc/devlpt.c b/pc/devlpt.c index f77352c1feb6c2b46430a89c588224412a2f5d67..792131fe7f7b0423b02866114432df661c6156a8 100644 --- a/pc/devlpt.c +++ b/pc/devlpt.c @@ -14,7 +14,8 @@ static int lptbase[] = { 0x3bc, /* lpt2 */ 0x278 /* lpt3 (sic) */ }; -#define NDEV (sizeof lptbase/sizeof lptbase[0]) +#define NDEV nelem(lptbase) +static int lptallocd[NDEV]; /* offsets, and bits in the registers */ enum @@ -75,6 +76,7 @@ lptattach(char *spec) { Chan *c; int i = (spec && *spec) ? strtol(spec, 0, 0) : 1; + char name[5]; static int set; if(!set){ @@ -84,6 +86,12 @@ lptattach(char *spec) } if(i < 1 || i > NDEV) error(Ebadarg); + if(lptallocd[i-1] == 0){ + sprint(name, "lpt%d", i-1); + if(ioalloc(lptbase[i-1], 3, 0, name) < 0) + error("lpt port space in use"); + lptallocd[i-1] = 1; + } c = devattach('L', spec); c->dev = i-1; return c; diff --git a/pc/devrtc.c b/pc/devrtc.c index 4c2e31f0b187dc2cbda355ee873c2182e356d510..14fc598c18d60d1e5547cb4a2de3d998de6c310d 100644 --- a/pc/devrtc.c +++ b/pc/devrtc.c @@ -52,6 +52,13 @@ Dirtab rtcdir[]={ static ulong rtc2sec(Rtc*); static void sec2rtc(ulong, Rtc*); +void +rtcinit(void) +{ + if(ioalloc(Paddr, 2, 0, "rtc/nvr") < 0) + panic("rtcinit: ioalloc failed"); +} + static Chan* rtcattach(char* spec) { @@ -298,7 +305,7 @@ Dev rtcdevtab = { "rtc", devreset, - devinit, + rtcinit, rtcattach, devclone, rtcwalk, diff --git a/pc/devvga.c b/pc/devvga.c index 44648b4ccae21bad9e3dd4b014939b939209d3d7..96230a2893583ada1ee22e6aabd5e86b5db2fc46 100644 --- a/pc/devvga.c +++ b/pc/devvga.c @@ -31,6 +31,11 @@ static Dirtab vgadir[] = { static void vgareset(void) { + /* reserve the 'standard' vga registers */ + if(ioalloc(0x2b0, 0x2df-0x2b0+1, 0, "vga") < 0) + panic("vga ports already allocated"); + if(ioalloc(0x3c0, 0x3da-0x3c0+1, 0, "vga") < 0) + panic("vga ports already allocated"); conf.monitor = 1; } @@ -65,6 +70,20 @@ vgaclose(Chan*) { } +static void +checkport(int start, int end) +{ + /* standard vga regs are OK */ + if(start >= 0x2b0 && end <= 0x2df+1) + return; + if(start >= 0x3c0 && end <= 0x3da+1) + return; + + if(iounused(start, end)) + return; + error(Eperm); +} + static long vgaread(Chan* c, void* a, long n, vlong off) { @@ -112,6 +131,7 @@ vgaread(Chan* c, void* a, long n, vlong off) case Qvgaiob: port = offset; + checkport(offset, offset+n); for(p = a; port < offset+n; port++) *p++ = inb(port); return n; @@ -119,6 +139,7 @@ vgaread(Chan* c, void* a, long n, vlong off) case Qvgaiow: if((n & 0x01) || (offset & 0x01)) error(Ebadarg); + checkport(offset, offset+n+1); n /= 2; sp = a; for(port = offset; port < offset+n; port += 2) @@ -128,6 +149,7 @@ vgaread(Chan* c, void* a, long n, vlong off) case Qvgaiol: if((n & 0x03) || (offset & 0x03)) error(Ebadarg); + checkport(offset, offset+n+3); n /= 4; lp = a; for(port = offset; port < offset+n; port += 4) @@ -278,6 +300,7 @@ vgawrite(Chan* c, void* a, long n, vlong off) case Qvgaiob: p = a; + checkport(offset, offset+n); for(port = offset; port < offset+n; port++) outb(port, *p++); return n; @@ -285,6 +308,7 @@ vgawrite(Chan* c, void* a, long n, vlong off) case Qvgaiow: if((n & 01) || (offset & 01)) error(Ebadarg); + checkport(offset, offset+n+1); n /= 2; sp = a; for(port = offset; port < offset+n; port += 2) @@ -294,6 +318,7 @@ vgawrite(Chan* c, void* a, long n, vlong off) case Qvgaiol: if((n & 0x03) || (offset & 0x03)) error(Ebadarg); + checkport(offset, offset+n+3); n /= 4; lp = a; for(port = offset; port < offset+n; port += 4) diff --git a/pc/dma.c b/pc/dma.c index 80d509e519af4646c7f1fd8752d6161f9f245a77..9da7bddd424b9fb773d7a71402860b340dfc0fce 100644 --- a/pc/dma.c +++ b/pc/dma.c @@ -8,23 +8,6 @@ typedef struct DMAport DMAport; typedef struct DMA DMA; typedef struct DMAxfer DMAxfer; -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 */ -}; - /* * state of a dma transfer */ @@ -89,11 +72,15 @@ dmainit(int chan, int maxtransfer) { DMA *dp; DMAxfer *xp; - - if(ioalloc(0x00, 0x10, 0) < 0 - || ioalloc(0x80, 0x10, 0) < 0 - || ioalloc(0xd0, 0x10, 0) < 0) - panic("dmainit"); + static int once; + + if(once == 0){ + if(ioalloc(0x00, 0x10, 0, "dma") < 0 + || ioalloc(0x80, 0x10, 0, "dma") < 0 + || ioalloc(0xd0, 0x10, 0, "dma") < 0) + panic("dmainit"); + once = 1; + } if(maxtransfer > 64*1024) maxtransfer = 64*1024; diff --git a/pc/ether2000.c b/pc/ether2000.c index 22f97227cf365cfedbc08027dd7838d3f75a28c7..9b9aa5c7c6005c8e126b7515791d96a232a4afe1 100644 --- a/pc/ether2000.c +++ b/pc/ether2000.c @@ -50,6 +50,9 @@ reset(Ether* ether) ether->size = 16*1024; port = ether->port; + if(ioalloc(ether->port, 0x20, 0, "ne2000") < 0) + return -1; + ether->ctlr = malloc(sizeof(Dp8390)); ctlr = ether->ctlr; ctlr->width = 2; @@ -92,6 +95,7 @@ reset(Ether* ether) memset(buf, 0, sizeof(buf)); dp8390read(ctlr, buf, 0, sizeof(buf)); if((buf[0x0E] & 0xFF) != 0x57 || (buf[0x0F] & 0xFF) != 0x57){ + iofree(ether->port); free(ether->ctlr); return -1; } diff --git a/pc/ether2114x.c b/pc/ether2114x.c index 0ce4ad724dd4ef0e334e8569b32e12709faccfe3..7391fe15c39304b97c7bc2a019e68bbb2a4afddb 100644 --- a/pc/ether2114x.c +++ b/pc/ether2114x.c @@ -1304,6 +1304,12 @@ dec2114xpci(void) ctlr->port = p->mem[0].bar & ~0x01; ctlr->pcidev = p; + if(ioalloc(ctlr->port, p->mem[0].size, 0, "dec2114x") < 0){ + print("dec2114x: port %d in use\n", ctlr->port); + free(ctlr); + continue; + } + /* * Some cards (e.g. ANA-6910FX) seem to need the Ps bit * set or they don't always work right after a hardware diff --git a/pc/ether589.c b/pc/ether589.c index d8931e2ddcc712827f6f61b23e1604100f822889..791f422b4d4224d133e662a735ee27a1ac9bc4f3 100644 --- a/pc/ether589.c +++ b/pc/ether589.c @@ -120,6 +120,9 @@ reset(Ether* ether) ether->port = 0x240; port = ether->port; + if(ioalloc(port, 0x10, 0, "3C589") < 0) + return -1; + if((slot = pcmspecial(ether->type, ether)) < 0) return -1; diff --git a/pc/ether79c970.c b/pc/ether79c970.c index 9779e971808f2735b774c6a02e9745873a50c313..7a7cb0b83eb4144e010858443c4050693e83dd7a 100644 --- a/pc/ether79c970.c +++ b/pc/ether79c970.c @@ -444,10 +444,16 @@ static void amd79c970pci(void) { Pcidev *p; + int port; p = nil; while(p = pcimatch(p, 0x1022, 0x2000)){ - amd79c970adapter(&adapter, p->mem[0].bar & ~0x01, p->intl, p->tbdf); + port = p->mem[0].bar & ~0x01; + if(ioalloc(port, p->mem[0].size, 0, "amd79c970") < 0){ + print("amd79c970: port %d in use\n", port); + continue; + } + amd79c970adapter(&adapter, port, p->intl, p->tbdf); pcisetbme(p); } } diff --git a/pc/ether8003.c b/pc/ether8003.c index 40fddfe81cbd99c5b6f15678340d412dc20807f4..299e17e551f3f5241f7d503493f27f6274c8709a 100644 --- a/pc/ether8003.c +++ b/pc/ether8003.c @@ -203,6 +203,8 @@ reset(Ether* ether) ether->mem = 0xD0000; if(ether->size == 0) ether->size = 8*1024; + if(ioalloc(ether->port, 0x20, 0, "wd8003") < 0) + return -1; /* * Look for the interface. Read the LAN address ROM @@ -221,8 +223,10 @@ reset(Ether* ether) id = inb(port+Id); sum += id; sum += inb(port+Cksum); - if(sum != 0xFF) + if(sum != 0xFF){ + iofree(ether->port); return -1; + } ether->ctlr = malloc(sizeof(Dp8390)); ctlr = ether->ctlr; diff --git a/pc/ether82557.c b/pc/ether82557.c index 8bbbc2dc608c228126da33e30b4b3f3a661fe761..3c1605096cc1413e3d7a6576b73822e319fcdee7 100644 --- a/pc/ether82557.c +++ b/pc/ether82557.c @@ -897,6 +897,7 @@ static void i82557pci(void) { Pcidev *p; + int port; p = nil; while(p = pcimatch(p, 0x8086, 0x1229)){ @@ -905,7 +906,12 @@ i82557pci(void) * bar[1] is the I/O port register address (32 bytes) and * bar[2] is for the flash ROM (1MB). */ - i82557adapter(&adapter, p->mem[1].bar & ~0x01, p->intl, p->tbdf); + port = p->mem[1].bar & ~0x01; + if(ioalloc(port, p->mem[1].size, 0, "i82557pci") < 0){ + print("i82557pci: port %d in use\n", port); + continue; + } + i82557adapter(&adapter, port, p->intl, p->tbdf); pcisetbme(p); } } diff --git a/pc/etherelnk3.c b/pc/etherelnk3.c index 0f217549ce483ef9379404931f5968017f26b8d5..19af50acdc79af4e63fa7d12ab15b192a6fdbf2d 100644 --- a/pc/etherelnk3.c +++ b/pc/etherelnk3.c @@ -1312,12 +1312,19 @@ tcm509isa(void) * it fully. */ while(port = activate()){ + if(ioalloc(port, 0x20, 0, "tcm509isa") < 0){ + print("tcm509isa:port %d in use\n", port); + continue; + } + /* * 6. Tag the adapter so it won't respond in future. */ outb(IDport, 0xD1); - if(port == 0x3F0) + if(port == 0x3F0){ + iofree(port); continue; + } /* * 6. Activate the adapter by writing the Activate command @@ -1367,11 +1374,19 @@ tcm5XXeisa(void) */ for(slot = 1; slot < MaxEISA; slot++){ port = slot*0x1000; - if(ins(port+0xC80+ManufacturerID) != 0x6D50) + if(ioalloc(port, 0x1000, 0, "tcm5XXeisa") < 0){ + print("tcm5XXeisa: port %d in use\n", port); + continue; + } + if(ins(port+0xC80+ManufacturerID) != 0x6D50){ + iofree(port); continue; + } x = ins(port+0xC80+ProductID); - if((x & 0xF0FF) != 0x9050 && (x & 0xFF00) != 0x5900) + if((x & 0xF0FF) != 0x9050 && (x & 0xFF00) != 0x5900){ + iofree(port); continue; + } COMMAND(port, SelectRegisterWindow, Wsetup); outs(port+ConfigControl, Ena); @@ -1393,6 +1408,10 @@ tcm59Xpci(void) p = nil; while(p = pcimatch(p, 0x10B7, 0)){ port = p->mem[0].bar & ~0x01; + if(ioalloc(port, p->mem[0].size, 0, "tcm59Xpci") < 0){ + print("tcm59Xpci: port %d in use\n", port); + continue; + } irq = p->intl; COMMAND(port, GlobalReset, 0); while(STATUS(port) & commandInProgress) @@ -1416,8 +1435,11 @@ tcm5XXpcmcia(Ether* ether) int i; for(i = 0; tcmpcmcia[i] != nil; i++){ - if(!cistrcmp(ether->type, tcmpcmcia[i])) + if(!cistrcmp(ether->type, tcmpcmcia[i])){ + if(ioalloc(ether->port, 0x20, 0, "tcm5XXpcmcia") < 0) + return 0; return ether->port; + } } return 0; diff --git a/pc/etherwavelan.c b/pc/etherwavelan.c index e4adaa9c67e1e460d7a967fbe9bf5a8ed1450048..ec7cd678482b86f824d9bcddd7755ed1088b2117 100644 --- a/pc/etherwavelan.c +++ b/pc/etherwavelan.c @@ -804,6 +804,10 @@ reset(Ether* ether) return -1; } + if(ioalloc(port, 0x20, 0, "wavelan") < 0){ + print("wavelan: port %d in use\n", port); + return -1; + } print("#l%dWaveLAN: slot %d, port 0x%ulX irq %ld type %s\n", ether->ctlrno, slot, ether->port, ether->irq, ether->type); @@ -813,6 +817,7 @@ reset(Ether* ether) /* map a piece of memory (Attribute memory) first */ m = pcmmap(slot, 0, 0x5000, 1); if (m==0) { + iofree(port); return 1; } /* read ethernet address from the card and put in ether->ea */ @@ -843,6 +848,7 @@ reset(Ether* ether) outb(HACR(port), HACR_DEFAULT); if(inb(HASR(port)) & HASR_NO_CLK) { + iofree(port); print("wavelan: modem not connected\n"); return 1; } @@ -852,11 +858,15 @@ reset(Ether* ether) outb(LCCR(port), OP0_RESET); /* reset the LAN controller */ delay(10); - if (wavelan_hw_config(port, ether) == FALSE) + if (wavelan_hw_config(port, ether) == FALSE){ + iofree(port); return 1; + } - if (wavelan_diag(ether, port) == 1) + if (wavelan_diag(ether, port) == 1){ + iofree(port); return 1; + } wavelan_ru_start(ether, port); print("wavelan: init done; receiver started\n"); diff --git a/pc/floppy.h b/pc/floppy.h index 2a3a49fb5ccab43fde8d7cee7f3e194dab2ec8bf..4f31670b6e272cd6f0d22d04efe6f67590863dad 100644 --- a/pc/floppy.h +++ b/pc/floppy.h @@ -136,6 +136,13 @@ pcfloppyintr(Ureg *ur, void *a) void floppysetup0(FController *fl) { + fl->ndrive = 0; + if(ioalloc(Psra, 6, 0, "floppy") < 0) + return; + if(ioalloc(Pdir, 1, 0, "floppy") < 0){ + iofree(Psra); + return; + } fl->ndrive = 2; } diff --git a/pc/fns.h b/pc/fns.h index 510ea00dae8759ebeaa99be4f0e82d31075cf84c..dca73c8c821ab5865d05f32d6f35cd80b8e09914 100644 --- a/pc/fns.h +++ b/pc/fns.h @@ -48,9 +48,10 @@ void inss(int, void*, int); ulong inl(int); void insl(int, void*, int); void intrenable(int, void (*)(Ureg*, void*), void*, int); -void iofree(ulong, int); +void iofree(int); void ioinit(void); -ulong ioalloc(ulong, int, int); +int iounused(int, int); +int ioalloc(int, int, int, char*); int iprint(char*, ...); int isaconfig(char*, int, ISAConf*); void kbdinit(void); @@ -118,7 +119,6 @@ int xchgw(ushort*, int); ulong TK2MS(ulong); /* ticks to milliseconds */ #define waserror() (up->nerrlab++, setlabel(&up->errlab[up->nerrlab-1])) -#define getcallerpc(x) (((ulong*)(x))[-1]) #define KADDR(a) ((void*)((ulong)(a)|KZERO)) #define PADDR(a) ((ulong)(a)&~KZERO) diff --git a/pc/i8253.c b/pc/i8253.c index f3b9ca2f39d6bfe227fc7984d280405391e81b91..d3ab91fe0e06fea0135813009cdfe977d963b00f 100644 --- a/pc/i8253.c +++ b/pc/i8253.c @@ -35,6 +35,7 @@ i8253init(int aalcycles, int havecycleclock) if(initialised == 0){ initialised = 1; + ioalloc(T0cntr, 4, 0, "i8253"); /* * set clock for 1/HZ seconds */ diff --git a/pc/i8259.c b/pc/i8259.c index 7e1e117425b308d16a39fdbe67ff6b4c19da422a..ca87f1d9fe976a56a5ab5673fa712ac7620b6411 100644 --- a/pc/i8259.c +++ b/pc/i8259.c @@ -34,6 +34,8 @@ i8259init(void) { int x; + ioalloc(Int0ctl, 2, 0, "i8259.0"); + ioalloc(Int1ctl, 2, 0, "i8259.1"); ilock(&i8259lock); /* diff --git a/pc/kbd.c b/pc/kbd.c index db59d30e310a0c840b9e2ebaa4088b75a6cd8105..09c69247bb13581a51fddeed9e45f4c9d5196314 100644 --- a/pc/kbd.c +++ b/pc/kbd.c @@ -398,8 +398,8 @@ kbdinit(void) panic("kbdinit"); qnoblock(kbdq, 1); - ioalloc(Data, 1, 0); - ioalloc(Cmd, 1, 0); + ioalloc(Data, 1, 0, "kbd"); + ioalloc(Cmd, 1, 0, "kbd"); intrenable(IrqKBD, i8042intr, 0, BUSUNKNOWN); diff --git a/pc/main.c b/pc/main.c index d0d13db6c2b9d66ffe44fb4108cc734d5c34f400..82c5181dcd3a309333175b97f66fee57f6f64d6d 100644 --- a/pc/main.c +++ b/pc/main.c @@ -435,7 +435,7 @@ confinit(void) * 4MB on the first Image chunk allocation. */ if(conf.npage*BY2PG < 16*MB) - poolconfig(imagmem, 0, 4*1024*1024, 0, nil); + imagmem->minarena = 4*1024*1024; } conf.upages = conf.npage - kpages; conf.ialloc = (kpages/2)*BY2PG; @@ -451,14 +451,14 @@ confinit(void) + conf.nimage*sizeof(Image) + conf.nswap + conf.nswppo*sizeof(Page); - poolconfig(mainmem, kpages, 0, 0, nil); + mainmem->maxsize = kpages; if(!cpuserver){ /* * give terminals lots of image memory, too; the dynamic * allocation will balance the load properly, hopefully. * be careful with 32-bit overflow. */ - poolconfig(imagmem, kpages, 0, 0, nil); + imagmem->maxsize = kpages; } } diff --git a/pc/memory.c b/pc/memory.c index 8491f9aa586fe2145e7218bd367ca82d55aabf9f..a33d8f0bed18b5f95d1b14c4c3067180a4996c7e 100644 --- a/pc/memory.c +++ b/pc/memory.c @@ -76,13 +76,6 @@ static RMap rmapumbrw = { &mapumbrw[nelem(mapumbrw)-1], }; -static Map mapiospace[256]; -static RMap rmapiospace = { - "x86 IO port space", - mapiospace, - &mapiospace[nelem(mapiospace)-1], -}; - void memdebug(void) { @@ -553,30 +546,3 @@ upafree(ulong pa, int size) mapfree(&xrmapupa, pa, size); } - -/* - * since mapalloc uses 0 to mean no allocation, add one to pa - * to shift the whole io range up one in the map. - */ -void -ioinit(void) -{ - mapfree(&rmapiospace, 1, (1<<24)+1); -} - -ulong -ioalloc(ulong pa, int size, int align) -{ - ulong a; - - if((a = mapalloc(&rmapiospace, ++pa, size, align)) == 0) - return 0; - - return --a; -} - -void -iofree(ulong pa, int size) -{ - mapfree(&rmapiospace, ++pa, size); -} diff --git a/pc/ns16552.h b/pc/ns16552.h index 678bde28de5421fc395e89a66177ee7f93557710..30e380c5d5ef5161cbe24ba85460524ed43aedfb 100644 --- a/pc/ns16552.h +++ b/pc/ns16552.h @@ -93,8 +93,12 @@ ns16552install(void) already = 1; /* first two ports are always there and always the normal frequency */ + if(ioalloc(0x3f8, 8, 0, "eia0") < 0) + print("eia0: port %d in use\n", 0x3f8); ns16552setup(0x3F8, UartFREQ, "eia0", Ns550); intrenable(IrqUART0, ns16552intrx, (void*)0, BUSUNKNOWN); + if(ioalloc(0x2F8, 8, 0, "eia1") < 0) + print("eia1: port %d in use\n", 0x2F8); ns16552setup(0x2F8, UartFREQ, "eia1", Ns550); intrenable(IrqUART1, ns16552intrx, (void*)1, BUSUNKNOWN); addclock0link(uartclock); @@ -129,6 +133,12 @@ ns16552install(void) if(sc->freq == 0) sc->freq = UartFREQ; sc->first = nuart; + if(ioalloc(sc->port, 8*sc->size, 0, "mp008") < 0){ + print("mp008: port %lud in use\n", sc->port); + xfree(sc); + scard[nscard] = 0; + continue; + } intrenable(sc->irq, mp008intr, sc, BUSUNKNOWN); port = sc->port; for(j=0; j < sc->size; j++){ @@ -145,6 +155,12 @@ ns16552install(void) if(sc->freq == 0) sc->freq = UartFREQ*4; sprint(name, "eia%d00", nscard); + if(ioalloc(sc->port, 8, 0, name) < 0){ + print("%s: port %lud in use\n", name, sc->port); + xfree(sc); + scard[nscard] = 0; + continue; + } ns16552setup(sc->port, sc->freq, name, Ns650); /* @@ -165,6 +181,12 @@ ns16552install(void) if(sc->freq == 0) sc->freq = UartFREQ; sprint(name, "eia%d00", nscard); + if(ioalloc(sc->port, 8, 0, name) < 0){ + print("%s: port %lud in use\n", name, sc->port); + xfree(sc); + scard[nscard] = 0; + continue; + } ns16552setup(sc->port, sc->freq, name, Ns550); intrenable(sc->irq, ns16552intrx, (void*)(nuart-1), BUSUNKNOWN); } diff --git a/port/alloc.c b/port/alloc.c index 03eb6c551c993fd5430a7dc263bb4813cb0f9729..7adef9120f4231cd97f5d9f2ae1f30e4da63b1bf 100644 --- a/port/alloc.c +++ b/port/alloc.c @@ -6,9 +6,10 @@ #include "error.h" #include "pool.h" -enum { - POOL_STUPID = 0x80000000, -}; +static void poolprint(Pool*, char*, ...); +static void ppanic(Pool*, char*, ...); +static void plock(Pool*); +static void punlock(Pool*); static Pool pmainmem = { .name= "Main", @@ -17,7 +18,12 @@ static Pool pmainmem = { .quantum= 32, .alloc= xalloc, .merge= xmerge, - .flags= 0, + .flags= POOL_TOLERANCE, + + .lock= plock, + .unlock= punlock, + .print= poolprint, + .panic= ppanic, }; static Pool pimagmem = { @@ -28,26 +34,140 @@ static Pool pimagmem = { .alloc= xalloc, .merge= xmerge, .flags= 0, + + .lock= plock, + .unlock= punlock, + .print= poolprint, + .panic= ppanic, }; Pool* mainmem = &pmainmem; Pool* imagmem = &pimagmem; +/* + * because we can't print while we're holding the locks, + * we have the save the message and print it once we let go. + */ +static void +poolprint(Pool *p, char *fmt, ...) +{ + va_list v; + int n; + + va_start(v, fmt); + n = doprint(p->msg, p->msg+sizeof p->msg, fmt, v)-p->msg; + va_end(v); + if(n >= sizeof p->msg); + n = sizeof(p->msg)-1; + if(n < 0) + n = 0; + p->msg[n] = 0; +} + +static void +ppanic(Pool *p, char *fmt, ...) +{ + va_list v; + int n; + + va_start(v, fmt); + n = doprint(p->msg, p->msg+sizeof p->msg, fmt, v)-p->msg; + va_end(v); + if(n >= sizeof p->msg); + n = sizeof(p->msg)-1; + if(n < 0) + n = 0; + p->msg[n] = 0; + iunlock(&p->lk); + panic("%s", p->msg); +} + +static void +plock(Pool *p) +{ + ilock(&p->lk); + p->msg[0] = 0; +} + +static void +punlock(Pool *p) +{ + char msg[sizeof p->msg]; + + if(p->msg[0] == 0){ + iunlock(&p->lk); + return; + } + + memmove(msg, p->msg, sizeof msg); + iunlock(&p->lk); + print("%.*s", sizeof p->msg, msg); +} + +void +poolsummary(Pool *p) +{ + print("%s max %lud cur %lud free %lud alloc %lud\n", p->name, + p->maxsize, p->cursize, p->curfree, p->curalloc); +} + +void +mallocsummary(void) +{ + poolsummary(mainmem); + poolsummary(imagmem); +} + +/* everything from here down should be the same in libc, libdebugmalloc, and the kernel */ +/* - except the code for malloc(), which alternately doesn't clear or does. */ +/* - except the code for smalloc(), which lives only in the kernel. */ + +/* + * Npadlong is the number of 32-bit longs to leave at the beginning of + * each allocated buffer for our own bookkeeping. We return to the callers + * a pointer that points immediately after our bookkeeping area. Incoming pointers + * must be decremented by that much, and outgoing pointers incremented. + * The malloc tag is stored at MallocOffset from the beginning of the block, + * and the realloc tag at ReallocOffset. The offsets are from the true beginning + * of the block, not the beginning the caller sees. + * + * The extra if(Npadlong != 0) in various places is a hint for the compiler to + * compile out function calls that would otherwise be no-ops. + */ + +/* non tracing + * +enum { + Npadlong = 0, + MallocOffset = 0, + ReallocOffset = 0, +}; + * + */ + +/* tracing */ +enum { + Npadlong = 2, + MallocOffset = 0, + ReallocOffset = 1 +}; + + void* smalloc(ulong size) { void *v; - ulong *l; for(;;) { - v = poolalloc(mainmem, size+8); + v = poolalloc(mainmem, size+Npadlong*sizeof(ulong)); if(v != nil) break; tsleep(&up->sleep, return0, 0, 100); } - l = v; - l[0] = getcallerpc(&size); - v = l+2; + if(Npadlong){ + v = (ulong*)v+Npadlong; + setmalloctag(v, getcallerpc(&size)); + } memset(v, 0, size); return v; } @@ -55,14 +175,13 @@ smalloc(ulong size) void* malloc(ulong size) { - ulong *l; void *v; - v = poolalloc(mainmem, size+8); - if(v != nil) { - l = v; - l[0] = getcallerpc(&size); - v = l+2; + v = poolalloc(mainmem, size+Npadlong*sizeof(ulong)); + if(Npadlong && v != nil) { + v = (ulong*)v+Npadlong; + setmalloctag(v, getcallerpc(&size)); + setrealloctag(v, 0); memset(v, 0, size); } return v; @@ -72,13 +191,12 @@ void* mallocz(ulong size, int clr) { void *v; - ulong *l; - v = poolalloc(mainmem, size+8); - if(v != nil) { - l = v; - l[0] = getcallerpc(&size); - v = l+2; + v = poolalloc(mainmem, size+Npadlong*sizeof(ulong)); + if(Npadlong && v != nil){ + v = (ulong*)v+Npadlong; + setmalloctag(v, getcallerpc(&size)); + setrealloctag(v, 0); } if(clr && v != nil) memset(v, 0, size); @@ -88,73 +206,80 @@ mallocz(ulong size, int clr) void free(void *v) { - if(v != nil) { -if(0) if(mainmem->flags & POOL_STUPID) { - print("A"); - delay(50); - } - poolfree(mainmem, (uchar*)v-8); -if(0) if(mainmem->flags & POOL_STUPID) { - print("a"); - delay(50); - } - } + if(v != nil) + poolfree(mainmem, (ulong*)v-Npadlong); } void* realloc(void *v, ulong size) { - ulong *l; void *nv; - long nsize; - if(size == 0) { - free(v); - return nil; - } - if(v == nil) - return malloc(size); + if(v != nil) + v = (ulong*)v-Npadlong; + if(Npadlong !=0 && size != 0) + size += Npadlong*sizeof(ulong); - nv = (uchar*)v-8; - nsize = size+8; - if(l = poolrealloc(mainmem, nv, nsize)) - return l+2; - return nil; + if(nv = poolrealloc(mainmem, v, size)){ + nv = (ulong*)nv+Npadlong; + setrealloctag(nv, getcallerpc(&v)); + if(v == nil) + setmalloctag(nv, getcallerpc(&v)); + } + return nv; } ulong msize(void *v) { - return poolmsize(mainmem, (uchar*)v-8)-8; + return poolmsize(mainmem, (ulong*)v-Npadlong)-Npadlong*sizeof(ulong); } void* calloc(ulong n, ulong szelem) { - return mallocz(n*szelem, 1); -} - -void -poolsummary(Pool *p) -{ - print("%s max %lud cur %lud free %lud alloc %lud\n", p->name, - p->maxsize, p->cursize, p->curfree, p->curalloc); + void *v; + if(v = mallocz(n*szelem, 1)) + setmalloctag(v, getcallerpc(&n)); + return v; } void -mallocsummary(void) +setmalloctag(void *v, ulong pc) { - poolsummary(mainmem); - poolsummary(imagmem); + ulong *u; + USED(v, pc); + if(Npadlong <= MallocOffset || v == nil) + return; + u = v; + u[-Npadlong+MallocOffset] = pc; } void -tagwithpc(void *v, ulong pc) +setrealloctag(void *v, ulong pc) { ulong *u; - if(v == nil) + USED(v, pc); + if(Npadlong <= ReallocOffset || v == nil) return; u = v; - u[-2] = pc; + u[-Npadlong+ReallocOffset] = pc; +} + +ulong +getmalloctag(void *v) +{ + USED(v); + if(Npadlong <= MallocOffset) + return ~0; + return ((ulong*)v)[-Npadlong+MallocOffset]; } +ulong +getrealloctag(void *v) +{ + USED(v); + if(Npadlong <= ReallocOffset) + return ((ulong*)v)[-Npadlong+ReallocOffset]; + return ~0; +} diff --git a/port/allocb.c b/port/allocb.c index d654ca34dbb43a7341b75832276e8a926ae7e990..030ac1aff46e739ff7d2a7118f2408506b96b413 100644 --- a/port/allocb.c +++ b/port/allocb.c @@ -50,7 +50,7 @@ allocb(int size) if(b->rp < b->base) panic("allocb"); b->wp = b->rp; - tagwithpc(b, getcallerpc(&size)); + setmalloctag(b, getcallerpc(&size)); return b; } @@ -102,7 +102,7 @@ iallocb(int size) ilock(&ialloc); ialloc.bytes += b->lim - b->base; iunlock(&ialloc); - tagwithpc(b, getcallerpc(&size)); + setmalloctag(b, getcallerpc(&size)); return b; } diff --git a/port/devcons.c b/port/devcons.c index ff7150f2d84fda706165666c65423ea9851e5560..5226ac92d8d77bdaf013076e7792d153369a2d36 100644 --- a/port/devcons.c +++ b/port/devcons.c @@ -389,7 +389,7 @@ static Dirtab consdir[]={ "sysstat", {Qsysstat}, 0, 0666, "time", {Qtime}, 7*NUMSIZE, 0664, "user", {Quser}, NAMELEN, 0666, - "zero", {Qzero}, 0, 0666, + "zero", {Qzero}, 0, 0444, }; int @@ -817,9 +817,6 @@ conswrite(Chan *c, void *va, long n, vlong off) sysname[n-1] = 0; break; - case Qzero: - return n; - default: print("conswrite: %lud\n", c->qid.path); error(Egreg); diff --git a/port/devdraw.c b/port/devdraw.c index 3b1c559b150d4262fd91a23e011db814bbb9c8c4..f5e4a0827d61ab4e09196c78a2cf865670d59b77 100644 --- a/port/devdraw.c +++ b/port/devdraw.c @@ -996,7 +996,7 @@ drawread(Chan *c, void *a, long n, vlong off) case Qcolormap: drawactive(1); /* to restore map from backup */ - p = malloc(4*12*256); + p = malloc(4*12*256+1); if(p == 0) error(Enomem); m = 0; diff --git a/port/devmnt.c b/port/devmnt.c index 0b81769ab12218e0d08a0a6be94e2267e706d8d4..8daef19b94a07242bada30e8ee1c85ff85f18efe 100644 --- a/port/devmnt.c +++ b/port/devmnt.c @@ -398,7 +398,7 @@ mntclunk(Chan *c, int t) } void -mclose(Mnt *m, Chan *c) +mclose(Mnt *m, Chan*) { Mntrpc *q, *r; @@ -894,7 +894,7 @@ mntqrm(Mnt *m, Mntrpc *r) } void -recoverchan(Mnt *m, Chan *c) +recoverchan(Mnt*, Chan*) { panic("recoverchan"); #ifdef asdf @@ -1060,7 +1060,7 @@ panic("mntrecover\n"); } void -mntrepl(char *buf) +mntrepl(char*) { panic("mntrepl"); #ifdef asdf diff --git a/port/lib.h b/port/lib.h index c43f18947d6892991a728ee9addebebea640f387..58349115330d8ed65b96e1ef19793e8133007a81 100644 --- a/port/lib.h +++ b/port/lib.h @@ -66,6 +66,7 @@ extern int print(char*, ...); /* * one-of-a-kind */ +ulong getcallerpc(void*); extern long strtol(char*, char**, int); extern ulong strtoul(char*, char**, int); extern vlong strtoll(char*, char**, int); diff --git a/port/portfns.h b/port/portfns.h index e49555b6533087168bf84148a17219f31f86402c..b446ef05f2f205786ae403343efee2198b68dba3 100644 --- a/port/portfns.h +++ b/port/portfns.h @@ -7,6 +7,7 @@ void alarmkproc(void*); Block* allocb(int); int anyhigher(void); int anyready(void); +#define assert(x) if(x);else panic("assert(x) failed"); Image* attachimage(int, Chan*, ulong, ulong); long authcheck(Chan*, char*, int); long authcheckread(Chan*, char*, int n); @@ -111,6 +112,8 @@ void freepte(Segment*, Pte*); void freesegs(int); void freesession(Session*); void getcolor(ulong, ulong*, ulong*, ulong*); +ulong getmalloctag(void*); +ulong getrealloctag(void*); void gotolabel(Label*); int haswaitq(void*); long hostdomainwrite(char*, int); @@ -289,6 +292,8 @@ void segpage(Segment*, Page*); int setcolor(ulong, ulong, ulong, ulong); void setkernur(Ureg*, Proc*); int setlabel(Label*); +void setmalloctag(void*, ulong); +void setrealloctag(void*, ulong); void setregisters(Ureg*, char*, char*, int); void setswapchan(Chan*); char* skipslash(char*); @@ -303,7 +308,6 @@ char* srvname(Chan*); int swapcount(ulong); int swapfull(void); void swapinit(void); -void tagwithpc(void*, ulong); vlong todget(vlong*); void todfix(void); void todsetfreq(vlong); diff --git a/port/qio.c b/port/qio.c index 80de40757a1078ff6b3af9457b1d7ed0a9172461..57ee03317340da94c0f9f599952bd55e4fbda6f5 100644 --- a/port/qio.c +++ b/port/qio.c @@ -974,7 +974,7 @@ qwrite(Queue *q, void *vp, int len) n = Maxatomic; b = allocb(n); - tagwithpc(b, (up->text[0]<<24)|(up->text[1]<<16)|(up->text[2]<<8)|up->text[3]); + setmalloctag(b, (up->text[0]<<24)|(up->text[1]<<16)|(up->text[2]<<8)|up->text[3]); if(waserror()){ freeb(b); nexterror();