shithub: riscv

Download patch

ref: 8243b6600f4c8d60e520aa1b20368ae9575aabf9
parent: 3bebd3f5e278d77b1eb526cd9f924b0777043d2b
author: cinap_lenrek <[email protected]>
date: Sat Jun 6 12:04:24 EDT 2020

pc/ether*: use 64-bit physical addresses and check pci membar types and sizes

--- a/sys/src/9/pc/ether82543gc.c
+++ b/sys/src/9/pc/ether82543gc.c
@@ -350,7 +350,7 @@
 
 typedef struct Ctlr Ctlr;
 typedef struct Ctlr {
-	int	port;
+	uvlong	port;
 	Pcidev*	pcidev;
 	Ctlr*	next;
 	int	active;
@@ -1252,10 +1252,13 @@
 	void *mem;
 	Pcidev *p;
 	Ctlr *ctlr;
+	uvlong io;
 
 	p = nil;
 	while(p = pcimatch(p, 0, 0)){
 		if(p->ccrb != 0x02 || p->ccru != 0)
+			continue;
+		if(p->mem[0].bar & 1)
 			continue;
 
 		switch((p->did<<16)|p->vid){
--- a/sys/src/9/pc/ether82563.c
+++ b/sys/src/9/pc/ether82563.c
@@ -502,7 +502,7 @@
 
 typedef struct Ctlr Ctlr;
 struct Ctlr {
-	ulong	port;
+	uvlong	port;
 	Pcidev	*pcidev;
 	Ctlr	*next;
 	int	active;
@@ -1667,7 +1667,10 @@
 	if(c->pcidev->mem[1].bar == 0)
 		return fload32(c);	/* i219 */
 
-	va = vmap(c->pcidev->mem[1].bar & ~0x0f, c->pcidev->mem[1].size);
+	if(c->pcidev->mem[1].bar & 1)
+		return -1;
+
+	va = vmap(c->pcidev->mem[1].bar & ~0xF, c->pcidev->mem[1].size);
 	if(va == nil)
 		return -1;
 	f.reg = va;
@@ -2025,6 +2028,8 @@
 
 	for(p = nil; p = pcimatch(p, 0x8086, 0);){
 		hbafixup(p);
+		if(p->mem[0].bar & 1)
+			continue;
 		if((type = didtype(p->did)) == -1)
 			continue;
 		ctlr = malloc(sizeof(Ctlr));
@@ -2035,7 +2040,7 @@
 		ctlr->type = type;
 		ctlr->pcidev = p;
 		ctlr->rbsz = ROUND(cttab[type].mtu, 1024);
-		ctlr->port = p->mem[0].bar & ~0x0F;
+		ctlr->port = p->mem[0].bar & ~0xF;
 		if(i82563ctlrhead != nil)
 			i82563ctlrtail->next = ctlr;
 		else
@@ -2052,7 +2057,7 @@
 	p = ctlr->pcidev;
 	ctlr->nic = vmap(ctlr->port, p->mem[0].size);
 	if(ctlr->nic == nil){
-		print("%s: can't map 0x%lux\n", cname(ctlr), ctlr->port);
+		print("%s: can't map %llux\n", cname(ctlr), ctlr->port);
 		return -1;
 	}
 	pcienable(p);
--- a/sys/src/9/pc/ether82598.c
+++ b/sys/src/9/pc/ether82598.c
@@ -267,7 +267,7 @@
 typedef struct {
 	Pcidev	*p;
 	Ether	*edev;
-	uintptr	io;
+	uvlong	io;
 	u32int	*reg;
 	u32int	*regmsi;
 	uchar	flag;
@@ -848,7 +848,7 @@
 static void
 scan(void)
 {
-	uintptr io, iomsi;
+	uvlong io, iomsi;
 	void *mem, *memmsi;
 	int pciregs, pcimsix;
 	Ctlr *c;
@@ -856,6 +856,7 @@
 
 	p = 0;
 	while(p = pcimatch(p, 0x8086, 0)){
+		pciregs = 0;
 		switch(p->did){
 		case 0x10c6:		/* 82598 af dual port */
 		case 0x10c7:		/* 82598 af single port */
@@ -868,11 +869,12 @@
 		case 0x1528:		/* T540-T1 */
 			pcimsix = 4;
 			break;
-
 		default:
 			continue;
 		}
-		pciregs = 0;
+		if((p->mem[pciregs].bar & 1) != 0
+		|| (p->mem[pcimsix].bar & 1) != 0)
+			continue;
 		if(nctlr == nelem(ctlrtab)){
 			print("i82598: too many controllers\n");
 			return;
@@ -885,7 +887,7 @@
 		io = p->mem[pciregs].bar & ~0xf;
 		mem = vmap(io, p->mem[pciregs].size);
 		if(mem == nil){
-			print("i82598: can't map regs %#p\n", io);
+			print("i82598: can't map regs %llux\n", io);
 			free(c);
 			continue;
 		}
@@ -892,7 +894,7 @@
 		iomsi = p->mem[pcimsix].bar & ~0xf;
 		memmsi = vmap(iomsi, p->mem[pcimsix].size);
 		if(memmsi == nil){
-			print("i82598: can't map msi-x regs %#p\n", iomsi);
+			print("i82598: can't map msi-x regs %llux\n", iomsi);
 			vunmap(mem, p->mem[pciregs].size);
 			free(c);
 			continue;
--- a/sys/src/9/pc/etherbcm.c
+++ b/sys/src/9/pc/etherbcm.c
@@ -23,11 +23,11 @@
 struct Ctlr {
 	Lock txlock, imlock;
 	Ctlr *link;
+	uvlong port;
 	Pcidev *pdev;
 	ulong *nic, *status;
 	/* One Ring to find them, One Ring to bring them all and in the darkness bind them */
 	ulong *recvret, *recvprod, *sendr;
-	ulong port;
 	ulong recvreti, recvprodi, sendri, sendcleani;
 	Block **sends, **recvs;
 	int active, duplex;
@@ -704,6 +704,9 @@
 			continue;
 		if(pdev->vid != 0x14e4)
 			continue;
+		if(pdev->mem[0].bar & 1)
+			continue;
+
 		switch(pdev->did){
 		default:
 			continue;
@@ -790,7 +793,6 @@
 		case 0x1670: 	/* ??? */
 			break;
 		}
-
 		ctlr = malloc(sizeof(Ctlr));
 		if(ctlr == nil) {
 			print("bcm: unable to alloc Ctlr\n");
@@ -805,16 +807,17 @@
 			free(ctlr);
 			continue;
 		}
-		mem = vmap(pdev->mem[0].bar & ~0x0F, pdev->mem[0].size);
+		ctlr->port = pdev->mem[0].bar & ~0xF;
+		mem = vmap(ctlr->port, pdev->mem[0].size);
 		if(mem == nil) {
-			print("bcm: can't map %8.8luX\n", pdev->mem[0].bar);
+			print("bcm: can't map %llux\n", ctlr->port);
 			free(ctlr->sends);
+			free(ctlr->recvs);
 			free(ctlr);
 			continue;
 		}
 		ctlr->pdev = pdev;
 		ctlr->nic = mem;
-		ctlr->port = pdev->mem[0].bar & ~0x0F;
 		ctlr->status = xspanalloc(20, 16, 0);
 		ctlr->recvprod = xspanalloc(32 * RecvProdRingLen, 16, 0);
 		ctlr->recvret = xspanalloc(32 * RecvRetRingLen, 16, 0);
--- a/sys/src/9/pc/etherdp83820.c
+++ b/sys/src/9/pc/etherdp83820.c
@@ -342,7 +342,7 @@
 
 typedef struct Ctlr Ctlr;
 typedef struct Ctlr {
-	int	port;
+	uvlong	port;
 	Pcidev*	pcidev;
 	Ctlr*	next;
 	int	active;
@@ -1148,6 +1148,8 @@
 	while(p = pcimatch(p, 0, 0)){
 		if(p->ccrb != Pcibcnet || p->ccru != Pciscether)
 			continue;
+		if(p->mem[1].bar & 1)
+			continue;
 
 		switch((p->did<<16)|p->vid){
 		default:
@@ -1156,9 +1158,9 @@
 			break;
 		}
 
-		mem = vmap(p->mem[1].bar & ~0x0F, p->mem[1].size);
-		if(mem == 0){
-			print("DP83820: can't map %8.8luX\n", p->mem[1].bar);
+		mem = vmap(p->mem[1].bar & ~0xF, p->mem[1].size);
+		if(mem == nil){
+			print("DP83820: can't map %llux\n", p->mem[1].bar & ~0xF);
 			continue;
 		}
 
@@ -1167,7 +1169,7 @@
 			print("DP83820: can't allocate memory\n");
 			continue;
 		}
-		ctlr->port = p->mem[1].bar & ~0x0F;
+		ctlr->port = p->mem[1].bar & ~0xF;
 		ctlr->pcidev = p;
 		pcienable(p);
 		ctlr->id = (p->did<<16)|p->vid;
--- a/sys/src/9/pc/etherelnk3.c
+++ b/sys/src/9/pc/etherelnk3.c
@@ -425,7 +425,7 @@
 	int	ts;			/* threshold shift */
 	int	upenabled;
 	int	dnenabled;
-	ulong	cbfnpa;			/* CardBus functions */
+	uvlong	cbfnpa;			/* CardBus functions */
 	ulong*	cbfn;
 } Ctlr;
 
@@ -1496,12 +1496,12 @@
 		case 0x5157:
 			ctlr->eepromcmd = EepromRead8bRegister;
 			ctlr->cbfnpa = p->mem[2].bar&~0x0F;
-			ctlr->cbfn = vmap(p->mem[2].bar&~0x0F, p->mem[2].size);
+			ctlr->cbfn = vmap(ctlr->cbfnpa, p->mem[2].size);
 			break;
 		case 0x6056:
 			ctlr->eepromcmd = EepromReadOffRegister;
 			ctlr->cbfnpa = p->mem[2].bar&~0x0F;
-			ctlr->cbfn = vmap(p->mem[2].bar&~0x0F, p->mem[2].size);
+			ctlr->cbfn = vmap(ctlr->cbfnpa, p->mem[2].size);
 			break;
 		}
 		pcisetbme(p);
--- a/sys/src/9/pc/etherga620.c
+++ b/sys/src/9/pc/etherga620.c
@@ -251,7 +251,7 @@
 
 typedef struct Ctlr Ctlr;
 struct Ctlr {
-	int	port;
+	uvlong	port;
 	Pcidev*	pcidev;
 	Ctlr*	next;
 	int	active;
@@ -575,7 +575,7 @@
 			 * 3rd arg of 1 selects gigabit only; 2 10/100 only.
 			 */
 			ga620command(ctlr, 0x0B, 0x00, 0x00);
-			print("#l%d: ga620: port %8.8uX: firmware is up\n",
+			print("#l%d: ga620: port %8.8lluX: firmware is up\n",
 				edev->ctlrno, ctlr->port);
 			break;
 		case 0x04:		/* statistics updated */
@@ -1152,6 +1152,8 @@
 	while(p = pcimatch(p, 0, 0)){
 		if(p->ccrb != 0x02 || p->ccru != 0)
 			continue;
+		if(p->mem[0].bar & 1)
+			continue;
 
 		switch(p->did<<16 | p->vid){
 		default:
@@ -1165,9 +1167,9 @@
 			break;
 		}
 
-		mem = vmap(p->mem[0].bar & ~0x0F, p->mem[0].size);
-		if(mem == 0){
-			print("ga620: can't map %8.8luX\n", p->mem[0].bar);
+		mem = vmap(p->mem[0].bar & ~0xF, p->mem[0].size);
+		if(mem == nil){
+			print("ga620: can't map %llux\n", p->mem[0].bar & ~0xF);
 			continue;
 		}
 
@@ -1176,7 +1178,7 @@
 			print("ga620: can't allocate memory\n");
 			continue;
 		}
-		ctlr->port = p->mem[0].bar & ~0x0F;
+		ctlr->port = p->mem[0].bar & ~0xF;
 		ctlr->pcidev = p;
 		pcienable(p);
 
--- a/sys/src/9/pc/etherigbe.c
+++ b/sys/src/9/pc/etherigbe.c
@@ -451,7 +451,7 @@
 
 typedef struct Ctlr Ctlr;
 typedef struct Ctlr {
-	int	port;
+	uvlong	port;
 	Pcidev*	pcidev;
 	Ctlr*	next;
 	Ether*	edev;
@@ -1919,6 +1919,8 @@
 	while(p = pcimatch(p, 0, 0)){
 		if(p->ccrb != 0x02 || p->ccru != 0)
 			continue;
+		if(p->mem[0].bar & 1)
+			continue;
 
 		switch((p->did<<16)|p->vid){
 		default:
@@ -1942,9 +1944,9 @@
 			break;
 		}
 
-		mem = vmap(p->mem[0].bar & ~0x0F, p->mem[0].size);
+		mem = vmap(p->mem[0].bar & ~0xF, p->mem[0].size);
 		if(mem == nil){
-			print("igbe: can't map %8.8luX\n", p->mem[0].bar);
+			print("igbe: can't map %llux\n", p->mem[0].bar & ~0xF);
 			continue;
 		}
 		cls = pcicfgr8(p, PciCLS);
--- a/sys/src/9/pc/etheriwl.c
+++ b/sys/src/9/pc/etheriwl.c
@@ -321,11 +321,11 @@
 	QLock;
 
 	Ctlr *link;
+	uvlong port;
 	Pcidev *pdev;
 	Wifi *wifi;
 
 	int type;
-	int port;
 	int power;
 	int active;
 	int broken;
@@ -2457,6 +2457,8 @@
 			continue;
 		if(pdev->vid != 0x8086)
 			continue;
+		if(pdev->mem[0].bar & 1)
+			continue;
 
 		switch(pdev->did){
 		default:
@@ -2493,10 +2495,10 @@
 			print("iwl: unable to alloc Ctlr\n");
 			continue;
 		}
-		ctlr->port = pdev->mem[0].bar & ~0x0F;
-		mem = vmap(pdev->mem[0].bar & ~0x0F, pdev->mem[0].size);
+		ctlr->port = pdev->mem[0].bar & ~0xF;
+		mem = vmap(ctlr->port, pdev->mem[0].size);
 		if(mem == nil) {
-			print("iwl: can't map %8.8luX\n", pdev->mem[0].bar);
+			print("iwl: can't map %llux\n", ctlr->port);
 			free(ctlr);
 			continue;
 		}
--- a/sys/src/9/pc/etherm10g.c
+++ b/sys/src/9/pc/etherm10g.c
@@ -192,11 +192,11 @@
 typedef struct Ctlr Ctlr;
 typedef struct Ctlr {
 	QLock;
-	int	state;
-	int	kprocs;
 	uvlong	port;
 	Pcidev*	pcidev;
 	Ctlr*	next;
+	int	state;
+	int	kprocs;
 	int	active;
 	int	id;		/* do we need this? */
 
@@ -808,23 +808,24 @@
 static int
 setmem(Pcidev *p, Ctlr *c)
 {
-	ulong i;
 	uvlong raddr;
-	Done *d;
 	void *mem;
+	Done *d;
+	ulong i;
 
 	c->tx.segsz = 2048;
 	c->ramsz = 2*MiB - (2*48*KiB + 32*KiB) - 0x100;
 	if(c->ramsz > p->mem[0].size)
 		return -1;
-
-	raddr = p->mem[0].bar & ~0x0F;
+	if(p->mem[0].bar & 1)
+		return -1;
+	raddr = p->mem[0].bar & ~0xF;
 	mem = vmap(raddr, p->mem[0].size);
 	if(mem == nil){
-		print("m10g: can't map %8.8lux\n", p->mem[0].bar);
+		print("m10g: can't map %llux\n", raddr);
 		return -1;
 	}
-	dprint("%llux <- vmap(mem[0].size = %ux)\n", raddr, p->mem[0].size);
+	dprint("%llux <- vmap(mem[0].size = %d)\n", raddr, p->mem[0].size);
 	c->port = raddr;
 	c->ram = mem;
 	c->cmd = malign(sizeof *c->cmd);
--- a/sys/src/9/pc/etherrt2860.c
+++ b/sys/src/9/pc/etherrt2860.c
@@ -925,6 +925,7 @@
 	QLock;
 
 	Ctlr *link;
+	uvlong port;
 	Pcidev *pdev;
 	Wifi *wifi;
 
@@ -967,8 +968,6 @@
 	u32int txpow40mhz_5ghz[5];
 
 	int flags;
-
-	int port;
 	int power;
 	int active;
 	int broken;
@@ -3480,6 +3479,8 @@
 			continue;
 		if(pdev->vid != 0x1814) /* Ralink */
 			continue;
+		if(pdev->mem[0].bar & 1)
+			continue;
 
 		switch(pdev->did){
 		default:
@@ -3494,10 +3495,10 @@
 			print("rt2860: unable to alloc Ctlr\n");
 			continue;
 		}
-		ctlr->port = pdev->mem[0].bar & ~0x0F;
-		mem = vmap(pdev->mem[0].bar & ~0x0F, pdev->mem[0].size);
+		ctlr->port = pdev->mem[0].bar & ~0xF;
+		mem = vmap(ctlr->port, pdev->mem[0].size);
 		if(mem == nil){
-			print("rt2860: can't map %8.8luX\n", pdev->mem[0].bar);
+			print("rt2860: can't map %llux\n", ctlr->port);
 			free(ctlr);
 			continue;
 		}
--- a/sys/src/9/pc/etherwavelan.c
+++ b/sys/src/9/pc/etherwavelan.c
@@ -111,8 +111,9 @@
 		/*
 		 * On the Prism, bar[0] is the memory-mapped register address (4KB),
 		 */
-		if(p->mem[0].size != 4096){
-			print("wavelanpci: %.4ux %.4ux: unlikely mmio size\n", p->vid, p->did);
+		if((p->mem[0].bar & 1) != 0 || p->mem[0].size != 4096){
+			print("wavelanpci: %.4ux %.4ux: unlikely mmio bar %llux size %d\n",
+				p->vid, p->did, p->mem[0].bar, p->mem[0].size);
 			continue;
 		}
 
@@ -124,7 +125,8 @@
 		ctlr->pcidev = p;
 		mem = vmap(p->mem[0].bar&~0xF, p->mem[0].size);
 		if(mem == nil){
-			print("wavelanpci: %.4ux %.4ux: vmap 0x%.8lux %d failed\n", p->vid, p->did, p->mem[0].bar&~0xF, p->mem[0].size);
+			print("wavelanpci: %.4ux %.4ux: vmap %llux %d failed\n",
+				p->vid, p->did, p->mem[0].bar&~0xF, p->mem[0].size);
 			free(ctlr);
 			continue;
 		}
--- a/sys/src/9/pc/etherwpi.c
+++ b/sys/src/9/pc/etherwpi.c
@@ -235,10 +235,10 @@
 	QLock;
 
 	Ctlr *link;
+	uvlong port;
 	Pcidev *pdev;
 	Wifi *wifi;
 
-	int port;
 	int power;
 	int active;
 	int broken;
@@ -1789,6 +1789,9 @@
 			break;
 		}
 
+		if(pdev->mem[0].bar & 1)
+			continue;
+
 		/* Clear device-specific "PCI retry timeout" register (41h). */
 		if(pcicfgr8(pdev, 0x41) != 0)
 			pcicfgw8(pdev, 0x41, 0);
@@ -1798,10 +1801,10 @@
 			print("wpi: unable to alloc Ctlr\n");
 			continue;
 		}
-		ctlr->port = pdev->mem[0].bar & ~0x0F;
-		mem = vmap(pdev->mem[0].bar & ~0x0F, pdev->mem[0].size);
+		ctlr->port = pdev->mem[0].bar & ~0xF;
+		mem = vmap(ctlr->port, pdev->mem[0].size);
 		if(mem == nil) {
-			print("wpi: can't map %8.8luX\n", pdev->mem[0].bar);
+			print("wpi: can't map %llux\n", ctlr->port);
 			free(ctlr);
 			continue;
 		}
--- a/sys/src/9/pc/etherx550.c
+++ b/sys/src/9/pc/etherx550.c
@@ -804,12 +804,10 @@
 	iunlock(&c->imlock);
 }
 
-extern void addvgaseg(char*, ulong, ulong);
-
 static void
 scan(void)
 {
-	uintptr io, iomsi;
+	uvlong io, iomsi;
 	void *mem, *memmsi;
 	int pciregs, pcimsix;
 	Ctlr *c;
@@ -819,6 +817,9 @@
 	while(p = pcimatch(p, 0x8086, 0x15c8)){	/* X553/X550-AT 10GBASE-T */
 		pcimsix = 4;
 		pciregs = 0;
+		if((p->mem[pciregs].bar & 1) != 0
+		|| (p->mem[pcimsix].bar & 1) != 0)
+			continue;
 		if(nctlr == nelem(ctlrtab)){
 			print("iX550: too many controllers\n");
 			return;
@@ -828,21 +829,17 @@
 			print("iX550: can't allocate memory\n");
 			continue;
 		}
-		io = p->mem[pciregs].bar & ~0xf;
+		io = p->mem[pciregs].bar & ~0xF;
 		mem = vmap(io, p->mem[pciregs].size);
 		if(mem == nil){
-			print("iX550: can't map regs %#p\n", io);
+			print("iX550: can't map regs %llux\n", io);
 			free(c);
 			continue;
 		}
-		if (nctlr == 0)
-			addvgaseg("pci.ctlr0.bar0", p->mem[pciregs].bar & ~0xf, p->mem[pciregs].size);
-		else if (nctlr == 1)
-			addvgaseg("pci.ctlr1.bar0", p->mem[pciregs].bar & ~0xf, p->mem[pciregs].size);
-		iomsi = p->mem[pcimsix].bar & ~0xf;
+		iomsi = p->mem[pcimsix].bar & ~0xF;
 		memmsi = vmap(iomsi, p->mem[pcimsix].size);
 		if(memmsi == nil){
-			print("iX550: can't map msi-x regs %#p\n", iomsi);
+			print("iX550: can't map msi-x regs %llux\n", iomsi);
 			vunmap(mem, p->mem[pciregs].size);
 			free(c);
 			continue;
@@ -855,9 +852,9 @@
 		c->rbsz = ROUND(Mtu, 1024);
 		if(reset(c)){
 			print("iX550: can't reset\n");
-			free(c);
 			vunmap(mem, p->mem[pciregs].size);
 			vunmap(memmsi, p->mem[pcimsix].size);
+			free(c);
 			continue;
 		}
 		pcisetbme(p);
--- a/sys/src/9/pc/etheryuk.c
+++ b/sys/src/9/pc/etheryuk.c
@@ -680,7 +680,7 @@
 	uchar	rev;
 	uchar	nports;
 	uchar	portno;
-	uintptr	io;
+	uvlong	io;
 	uchar	*reg8;
 	ushort	*reg16;
 	uint	*reg;
@@ -2129,10 +2129,12 @@
 	Pcidev *p;
 
 	p = c->p;
+	if(p->mem[0].bar & 1)
+		return -1;
 	c->io = p->mem[0].bar&~0xf;
 	mem = vmap(c->io, p->mem[0].size);
 	if(mem == nil){
-		print("yuk: cant map %#p\n", c->io);
+		print("yuk: cant map %llux\n", c->io);
 		return -1;
 	}
 	pcienable(p);