shithub: riscv

Download patch

ref: 3bcc34f27623cf7858a7c224470ec70359cfcd48
parent: 93f6ce24f46cc596060d859ff97a276e80e1d5c5
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sat Jun 6 10:58:20 EDT 2020

pc, pc64: implement 64-bit pci membar support

--- a/sys/src/9/pc/io.h
+++ b/sys/src/9/pc/io.h
@@ -232,14 +232,6 @@
 	PciCapHSW       = 0x0c,         /* hot swap */
 };
 
-typedef struct Pcisiz Pcisiz;
-struct Pcisiz
-{
-	Pcidev*	dev;
-	int	siz;
-	int	bar;
-};
-
 typedef struct Pcidev Pcidev;
 struct Pcidev
 {
@@ -257,12 +249,12 @@
 	uchar	ltr;
 
 	struct {
-		ulong	bar;		/* base address */
+		uvlong	bar;		/* base address */
 		int	size;
 	} mem[6];
 
 	struct {
-		ulong	bar;	
+		uvlong	bar;	
 		int	size;
 	} rom;
 	uchar	intl;			/* interrupt line */
@@ -273,7 +265,7 @@
 	Pcidev*	parent;			/* up a bus */
 	Pcidev*	bridge;			/* down a bus */
 	struct {
-		ulong	bar;
+		uvlong	bar;
 		int	size;
 	} ioa, mema;
 
--- a/sys/src/9/pc/pci.c
+++ b/sys/src/9/pc/pci.c
@@ -35,6 +35,15 @@
 	SErrEn		= (1<<8),
 };
 
+typedef struct Pcisiz Pcisiz;
+struct Pcisiz
+{
+	Pcidev*	dev;
+	int	siz;
+	int	bar;
+	int	typ;
+};
+
 static Lock pcicfglock;
 static Lock pcicfginitlock;
 static int pcicfgmode = -1;
@@ -156,11 +165,12 @@
 }
 
 static void
-pcibusmap(Pcidev *root, ulong *pmema, ulong *pioa, int wrreg)
+pcibusmap(Pcidev *root, uvlong *pmema, ulong *pioa, int wrreg)
 {
 	Pcidev *p;
 	int ntb, i, size, rno, hole;
-	ulong v, mema, ioa, sioa, smema, base, limit;
+	uvlong mema, smema, base, limit;
+	ulong ioa, sioa, v;
 	Pcisiz *table, *tptr, *mtb, *itb;
 
 	if(!nobios)
@@ -169,7 +179,7 @@
 	ioa = *pioa;
 	mema = *pmema;
 
-	DBG("pcibusmap wr=%d %T mem=%luX io=%luX\n",
+	DBG("pcibusmap wr=%d %T mem=%lluX io=%luX\n",
 		wrreg, root->tbdf, mema, ioa);
 
 	ntb = 0;
@@ -211,16 +221,18 @@
 			itb->dev = p;
 			itb->bar = -1;
 			itb->siz = p->ioa.size;
+			itb->typ = 0;
 			itb++;
 
 			mtb->dev = p;
 			mtb->bar = -1;
 			mtb->siz = p->mema.size;
+			mtb->typ = 0;
 			mtb++;
 			continue;
 		}
 
-		for(i = 0; i <= 5; i++) {
+		for(i = 0; i < nelem(p->mem); i++) {
 			rno = PciBAR0 + i*4;
 			v = pcicfgrw32(p->tbdf, rno, 0, 1);
 			size = pcibarsize(p, rno);
@@ -232,6 +244,7 @@
 				itb->dev = p;
 				itb->bar = i;
 				itb->siz = size;
+				itb->typ = 1;
 				itb++;
 			}
 			else {
@@ -238,10 +251,10 @@
 				mtb->dev = p;
 				mtb->bar = i;
 				mtb->siz = size;
-				mtb++;
-
-				if((v & 7) == 4)
+				mtb->typ = v & 7;
+				if(mtb->typ & 4)
 					i++;
+				mtb++;
 			}
 		}
 	}
@@ -282,7 +295,7 @@
 		hole = tptr->siz;
 		if(tptr->bar == -1)
 			hole = 1<<20;
-		mema = (mema+hole-1) & ~(hole-1);
+		mema = (mema+hole-1) & ~((uvlong)hole-1);
 
 		p = tptr->dev;
 		if(tptr->bar == -1)
@@ -289,9 +302,16 @@
 			p->mema.bar = mema;
 		else {
 			p->pcr |= MEMen;
-			p->mem[tptr->bar].bar = mema;
-			if(wrreg)
-				pcicfgrw32(p->tbdf, PciBAR0+(tptr->bar*4), mema, 0);
+			p->mem[tptr->bar].bar = mema|tptr->typ;
+			if(wrreg){
+				rno = PciBAR0+(tptr->bar*4);
+				pcicfgrw32(p->tbdf, rno, mema|tptr->typ, 0);
+				if(tptr->bar < nelem(p->mem)-1 && (tptr->typ & 4) != 0){
+					p->mem[tptr->bar+1].bar = 0;
+					p->mem[tptr->bar+1].size = 0;
+					pcicfgrw32(p->tbdf, rno+4, mema>>32, 0);
+				}
+			}
 		}
 		mema += tptr->siz;
 	}
@@ -425,21 +445,14 @@
 				if((hdt & 0x7F) != 0)
 					break;
 				rno = PciBAR0;
-				for(i = 0; i <= 5; i++) {
-					p->mem[i].bar = pcicfgr32(p, rno);
+				for(i = 0; i < nelem(p->mem); i++) {
+					p->mem[i].bar = (ulong)pcicfgr32(p, rno);
 					p->mem[i].size = pcibarsize(p, rno);
-					if((p->mem[i].bar & 7) == 4 && i < 5){
-						ulong hi;
-
+					if((p->mem[i].bar & 7) == 4 && i < nelem(p->mem)-1){
 						rno += 4;
-						hi = pcicfgr32(p, rno);
-						if(hi != 0){
-							print("ignoring 64-bit bar %d: %llux %d from %T\n",
-								i, (uvlong)hi<<32 | p->mem[i].bar, p->mem[i].size, p->tbdf);
-							p->mem[i].bar = 0;
-							p->mem[i].size = 0;
-						}
-						i++;
+						p->mem[i++].bar |= (uvlong)pcicfgr32(p, rno) << 32;
+						p->mem[i].bar = 0;
+						p->mem[i].size = 0;
 					}
 					rno += 4;
 				}
@@ -923,7 +936,7 @@
 }
 
 void
-pcibussize(Pcidev *root, ulong *msize, ulong *iosize)
+pcibussize(Pcidev *root, uvlong *msize, ulong *iosize)
 {
 	*msize = 0;
 	*iosize = 0;
@@ -935,7 +948,8 @@
 {
 	char *p;
 	Pcidev **list;
-	ulong mema, ioa;
+	uvlong mema;
+	ulong ioa;
 	int bno, n, pcibios;
 
 	lock(&pcicfginitlock);
@@ -1052,10 +1066,10 @@
 		ioa = 0x1000;
 		mema = 0x90000000;
 
-		DBG("Mask sizes: mem=%lux io=%lux\n", mema, ioa);
+		DBG("Mask sizes: mem=%llux io=%lux\n", mema, ioa);
 
 		pcibusmap(pciroot, &mema, &ioa, 1);
-		DBG("Sizes2: mem=%lux io=%lux\n", mema, ioa);
+		DBG("Sizes2: mem=%llux io=%lux\n", mema, ioa);
 
 		goto out;
 	}
@@ -1083,8 +1097,8 @@
 	 */
 	for(p=pciroot; p; p=p->list)
 		for(i=0; i<nelem(p->mem); i++)
-			if((p->mem[i].bar&~4) != 0 && (p->mem[i].bar&1) == 0)
-				upaalloc(p->mem[i].bar&~0x0F, p->mem[i].size, 0);
+			if(p->mem[i].size && (p->mem[i].bar&1) == 0 && (p->mem[i].bar&~0xF) != 0)
+				upaalloc(p->mem[i].bar&~0xF, p->mem[i].size, 0);
 }
 
 static int
@@ -1330,13 +1344,13 @@
 		for(i = 0; i < nelem(p->mem); i++) {
 			if(t->mem[i].size == 0)
 				continue;
-			print("%d:%.8lux %d ", i,
+			print("%d:%.8llux %d ", i,
 				t->mem[i].bar, t->mem[i].size);
 		}
 		if(t->ioa.bar || t->ioa.size)
-			print("ioa:%.8lux %d ", t->ioa.bar, t->ioa.size);
+			print("ioa:%.8llux %d ", t->ioa.bar, t->ioa.size);
 		if(t->mema.bar || t->mema.size)
-			print("mema:%.8lux %d ", t->mema.bar, t->mema.size);
+			print("mema:%.8llux %d ", t->mema.bar, t->mema.size);
 		if(t->bridge)
 			print("->%d", BUSBNO(t->bridge->tbdf));
 		print("\n");
@@ -1589,8 +1603,13 @@
 		delay(100);		/* D3: minimum delay 50ms */
 
 		/* restore registers */
-		for(i = 0; i < 6; i++)
+		for(i = 0; i < nelem(p->mem); i++){
 			pcicfgw32(p, PciBAR0+i*4, p->mem[i].bar);
+			if((p->mem[i].bar&7) == 4 && i < nelem(p->mem)-1){
+				pcicfgw32(p, PciBAR0+i*4+4, p->mem[i].bar>>32);
+				i++;
+			}
+		}
 		pcicfgw8(p, PciINTL, p->intl);
 		pcicfgw8(p, PciLTR, p->ltr);
 		pcicfgw8(p, PciCLS, p->cls);
@@ -1602,7 +1621,7 @@
 		pcr = IOen|MEMen|MASen;
 	else {
 		pcr = 0;
-		for(i = 0; i < 6; i++){
+		for(i = 0; i < nelem(p->mem); i++){
 			if(p->mem[i].size == 0)
 				continue;
 			if(p->mem[i].bar & 1)