~kris/9p

9hist

afbbb67cc61b008c53ef7c0ee021d420fc550626 — David du Colombier 27 years ago cf4f6ff
Plan 9 from Bell Labs 1999-07-14
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();