M alphapc/fns.h => alphapc/fns.h +0 -1
@@ 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);
M alphapc/l.s => alphapc/l.s +0 -4
@@ 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
M carrera/fns.h => carrera/fns.h +0 -1
@@ 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*);
M carrera/l.s => carrera/l.s +0 -4
@@ 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
M mpc/fns.h => mpc/fns.h +0 -1
@@ 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))
M mpc/l.s => mpc/l.s +0 -4
@@ 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
M pc/devastar.c => pc/devastar.c +22 -1
@@ 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;
}
M pc/devata.c => pc/devata.c +14 -0
@@ 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))
M pc/devfloppy.c => pc/devfloppy.c +5 -0
@@ 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
M pc/devi82365.c => pc/devi82365.c +14 -5
@@ 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));
M pc/devlpt.c => pc/devlpt.c +9 -1
@@ 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;
M pc/devrtc.c => pc/devrtc.c +8 -1
@@ 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,
M pc/devvga.c => pc/devvga.c +25 -0
@@ 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)
M pc/dma.c => pc/dma.c +9 -22
@@ 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;
M pc/ether2000.c => pc/ether2000.c +4 -0
@@ 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;
}
M pc/ether2114x.c => pc/ether2114x.c +6 -0
@@ 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
M pc/ether589.c => pc/ether589.c +3 -0
@@ 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;
M pc/ether79c970.c => pc/ether79c970.c +7 -1
@@ 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);
}
}
M pc/ether8003.c => pc/ether8003.c +5 -1
@@ 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;
M pc/ether82557.c => pc/ether82557.c +7 -1
@@ 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);
}
}
M pc/etherelnk3.c => pc/etherelnk3.c +26 -4
@@ 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;
M pc/etherwavelan.c => pc/etherwavelan.c +12 -2
@@ 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");
M pc/floppy.h => pc/floppy.h +7 -0
@@ 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;
}
M pc/fns.h => pc/fns.h +3 -3
@@ 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)
M pc/i8253.c => pc/i8253.c +1 -0
@@ 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
*/
M pc/i8259.c => pc/i8259.c +2 -0
@@ 34,6 34,8 @@ i8259init(void)
{
int x;
+ ioalloc(Int0ctl, 2, 0, "i8259.0");
+ ioalloc(Int1ctl, 2, 0, "i8259.1");
ilock(&i8259lock);
/*
M pc/kbd.c => pc/kbd.c +2 -2
@@ 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);
M pc/main.c => pc/main.c +3 -3
@@ 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;
}
}
M pc/memory.c => pc/memory.c +0 -34
@@ 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);
-}
M pc/ns16552.h => pc/ns16552.h +22 -0
@@ 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);
}
M port/alloc.c => port/alloc.c +185 -60
@@ 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;
+}
M port/allocb.c => port/allocb.c +2 -2
@@ 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;
}
M port/devcons.c => port/devcons.c +1 -4
@@ 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);
M port/devdraw.c => port/devdraw.c +1 -1
@@ 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;
M port/devmnt.c => port/devmnt.c +3 -3
@@ 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
M port/lib.h => port/lib.h +1 -0
@@ 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);
M port/portfns.h => port/portfns.h +5 -1
@@ 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);
M port/qio.c => port/qio.c +1 -1
@@ 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();