shithub: riscv

Download patch

ref: bbbfbe3dc41004b98531094a9fedacacbc897085
parent: fb9c05bbefed4ef372f4e62e867d4209c473838f
author: cinap_lenrek <cinap_lenrek@centraldogma>
date: Mon May 23 15:21:24 EDT 2011

aux/vga: use devpnp for pci control register io

--- a/sys/src/cmd/aux/vga/pci.c
+++ b/sys/src/cmd/aux/vga/pci.c
@@ -1,267 +1,167 @@
 #include <u.h>
 #include <libc.h>
 #include <bio.h>
+#include <fcall.h>
 
 #include "pci.h"
 #include "vga.h"
 
-/*
- * PCI support code.
- * There really should be a driver for this, it's not terribly safe
- * without locks or restrictions on what can be poked (e.g. Axil NX801).
- */
-enum {					/* configuration mechanism #1 */
-	PciADDR		= 0xCF8,	/* CONFIG_ADDRESS */
-	PciDATA		= 0xCFC,	/* CONFIG_DATA */
-
-					/* configuration mechanism #2 */
-	PciCSE		= 0xCF8,	/* configuration space enable */
-	PciFORWARD	= 0xCFA,	/* which bus */
-
-	MaxFNO		= 7,
-	MaxUBN		= 255,
-};
-
-static int pcicfgmode = -1;
-static int pcimaxdno;
-static Pcidev* pciroot;
 static Pcidev* pcilist;
 static Pcidev* pcitail;
 
-
 static void
 pcicfginit(void)
 {
-	Dir *d;
 	int fd, i, j, n, bno, dno, fno;
-	char buf[1024], *s;
+	char buf[1024], *base, *s;
 	Pcidev *p;
+	Dir *d;
 
-	pcicfgmode = 0x666;
 	trace("pcicfginit\n");
-	fd = open("#$/pci", OREAD);
-	if(fd < 0)
-		return;
-	if((n = dirreadall(fd, &d)) < 0)
-		return;
+	if((fd = open(base = "/dev/pci", OREAD)) < 0)
+		if((fd = open(base = "#$/pci", OREAD)) < 0)
+			return;
+	n = dirreadall(fd, &d);
 	close(fd);
+	if(n < 0)
+		return;
 	
 	for(i=0; i<n; i++) {
-		int nl = strlen(d[i].name);
-		if(d[i].name[nl-3] == 'r' && d[i].name[nl-2] == 'a'  && d[i].name[nl-1] == 'w' ) {
-			trace("pci device %s\n",d[i].name);
-			sprint(buf, "#$/pci/%s", d[i].name);
-			if((fd = open(buf, OREAD)) < 0)
-				return;
-			if((read(fd, buf, 0x30)) <= 0)
-				return;
-			close(fd);
-			
-			bno = strtoul(d[i].name, &s, 10);
-			dno = strtoul(s+1, &s, 10);
-			fno = strtoul(s+1, nil, 10);
-			trace("\t-> %d %d %d\n",bno, dno, fno);
-			p = mallocz(sizeof(*p), 1);
-			p->tbdf = MKBUS(BusPCI, bno, dno, fno);
-			p->vid = *(ulong*)(buf);
-			p->did = *(ushort*)(buf+2);
-			p->rid  = *(uchar*)(buf+PciRID);
-			p->intl = *(uchar*)(buf+PciINTL);
-			p->ccru = *(ushort*)(buf+PciCCRu);
-			
-			int rno = PciBAR0 - 4;
-			for(j = 0; j < nelem(p->mem); j++){
-				rno += 4;
-				p->mem[j].bar = pcicfgr32(p, rno);
-				pcicfgw32(p, rno, -1);
-				ulong v = pcicfgr32(p, rno);
-				pcicfgw32(p, rno, p->mem[i].bar);
-				p->mem[j].size = -(v & ~0xF);
-				trace("\t->mem[%d] = %p %d\n", j, p->mem[j].bar, p->mem[j].size);
-			}
-				
+		if(strstr(d[i].name, "ctl") == nil)
+			continue;
+
+		sprint(buf, "%s", d[i].name);
+		bno = strtoul(buf, &s, 10);
+		dno = strtoul(s+1, &s, 10);
+		fno = strtoul(s+1, nil, 10);
 	
-			if(pcilist != nil)
-				pcitail->list = p;
-			else
-				pcilist = p;
-			pcitail = p;
+		p = mallocz(sizeof(*p), 1);
+		p->tbdf = MKBUS(BusPCI, bno, dno, fno);
+		sprint(buf, "%s/%d.%d.%draw", base, bno, dno, fno);
+		if((p->rawfd = open(buf, ORDWR)) < 0){
+			free(p);
+			continue;
+		}
+		sprint(buf, "%s/%d.%d.%dctl", base, bno, dno, fno);
+		if((fd = open(buf, OREAD)) < 0){
+			close(p->rawfd);
+			free(p);
+			continue;
+		}
+		if((n = read(fd, buf, sizeof(buf)-1)) <= 0){
+			close(p->rawfd);
+			close(fd);
+			free(p);
+			continue;
+		}
+		buf[n] = 0;
+		close(fd);
 
+		p->ccru = strtol(buf + 3, nil, 16);
+		p->vid = strtol(buf + 9, &s, 16);
+		p->did = strtol(s + 1, &s, 16);
+		p->intl = strtol(s + 1, &s, 10);
 
-			trace("\t-> did=%X vid=%X rid=%X intl=%d ccru=%X\n",p->did, p->vid, p->rid,p->intl, p->ccru);
-			
+		p->rid = pcicfgr8(p, PciRID);
+
+		trace("did=%X vid=%X rid=%X intl=%d ccru=%X\n", p->did, p->vid, p->rid, p->intl, p->ccru);
+
+		while(*s == ' '){
+			j = strtol(s+1, &s, 10);
+			if(j < 0 || j >= nelem(p->mem))
+				break;
+			p->mem[j].bar = strtol(s+1, &s, 16);
+			p->mem[j].size = strtol(s+1, &s, 10);
+			trace("\t->mem[%d] = %p %d\n", j, p->mem[j].bar, p->mem[j].size);
 		}
+
+		if(pcilist != nil)
+			pcitail->list = p;
+		else
+			pcilist = p;
+		pcitail = p;
 	}
 }
 
 static int
-pcicfgrw8(int tbdf, int rno, int data, int read)
+pcicfgrw(Pcidev *pcidev, int rno, int data, int len, int read)
 {
-	int o, type, x;
+	uchar buf[4];
 
-	if(pcicfgmode == -1)
-		pcicfginit();
-
-	if(BUSBNO(tbdf))
-		type = 0x01;
-	else
-		type = 0x00;
-	x = -1;
-	if(BUSDNO(tbdf) > pcimaxdno)
-		return x;
-
-	switch(pcicfgmode){
-
-	case 1:
-		o = rno & 0x03;
-		rno &= ~0x03;
-		outportl(PciADDR, 0x80000000|BUSBDF(tbdf)|rno|type);
-		if(read)
-			x = inportb(PciDATA+o);
-		else
-			outportb(PciDATA+o, data);
-		outportl(PciADDR, 0);
-		break;
-
-	case 2:
-		outportb(PciCSE, 0x80|(BUSFNO(tbdf)<<1));
-		outportb(PciFORWARD, BUSBNO(tbdf));
-		if(read)
-			x = inportb((0xC000|(BUSDNO(tbdf)<<8)) + rno);
-		else
-			outportb((0xC000|(BUSDNO(tbdf)<<8)) + rno, data);
-		outportb(PciCSE, 0);
-		break;
+	if(read){
+		memset(buf, 0, sizeof(buf));
+		if(pread(pcidev->rawfd, buf, len, rno) != len)
+			return -1;
+		switch(len){
+		case 1:
+			return GBIT8(buf);
+		case 2:
+			return GBIT16(buf);
+		case 4:
+			return GBIT32(buf);
+		default:
+			abort();
+		}
+	} else {
+		switch(len){
+		case 1:
+			PBIT8(buf, data);
+			break;
+		case 2:
+			PBIT16(buf, data);
+			break;
+		case 4:
+			PBIT32(buf, data);
+			break;
+		default:
+			abort();
+		}
+		if(pwrite(pcidev->rawfd, buf, len, rno) != len)
+			return -1;
 	}
-
-	return x;
+	return 0;
 }
 
 int
 pcicfgr8(Pcidev* pcidev, int rno)
 {
-	return pcicfgrw8(pcidev->tbdf, rno, 0, 1);
+	return pcicfgrw(pcidev, rno, 0, 1, 1);
 }
 
 void
 pcicfgw8(Pcidev* pcidev, int rno, int data)
 {
-	pcicfgrw8(pcidev->tbdf, rno, data, 0);
+	pcicfgrw(pcidev, rno, data, 1, 0);
 }
 
-static int
-pcicfgrw16(int tbdf, int rno, int data, int read)
-{
-	int o, type, x;
-
-	if(pcicfgmode == -1)
-		pcicfginit();
-
-	if(BUSBNO(tbdf))
-		type = 0x01;
-	else
-		type = 0x00;
-	x = -1;
-	if(BUSDNO(tbdf) > pcimaxdno)
-		return x;
-
-	switch(pcicfgmode){
-
-	case 1:
-		o = rno & 0x02;
-		rno &= ~0x03;
-		outportl(PciADDR, 0x80000000|BUSBDF(tbdf)|rno|type);
-		if(read)
-			x = inportw(PciDATA+o);
-		else
-			outportw(PciDATA+o, data);
-		outportl(PciADDR, 0);
-		break;
-
-	case 2:
-		outportb(PciCSE, 0x80|(BUSFNO(tbdf)<<1));
-		outportb(PciFORWARD, BUSBNO(tbdf));
-		if(read)
-			x = inportw((0xC000|(BUSDNO(tbdf)<<8)) + rno);
-		else
-			outportw((0xC000|(BUSDNO(tbdf)<<8)) + rno, data);
-		outportb(PciCSE, 0);
-		break;
-	}
-
-	return x;
-}
-
 int
 pcicfgr16(Pcidev* pcidev, int rno)
 {
-	return pcicfgrw16(pcidev->tbdf, rno, 0, 1);
+	return pcicfgrw(pcidev, rno, 0, 2, 1);
 }
 
 void
 pcicfgw16(Pcidev* pcidev, int rno, int data)
 {
-	pcicfgrw16(pcidev->tbdf, rno, data, 0);
+	pcicfgrw(pcidev, rno, data, 2, 0);
 }
 
-static int
-pcicfgrw32(int tbdf, int rno, int data, int read)
-{
-	int type, x;
-
-	if(pcicfgmode == -1)
-		pcicfginit();
-
-	if(BUSBNO(tbdf))
-		type = 0x01;
-	else
-		type = 0x00;
-	x = -1;
-	if(BUSDNO(tbdf) > pcimaxdno)
-		return x;
-
-	switch(pcicfgmode){
-
-	case 1:
-		rno &= ~0x03;
-		outportl(PciADDR, 0x80000000|BUSBDF(tbdf)|rno|type);
-		if(read)
-			x = inportl(PciDATA);
-		else
-			outportl(PciDATA, data);
-		outportl(PciADDR, 0);
-		break;
-
-	case 2:
-		outportb(PciCSE, 0x80|(BUSFNO(tbdf)<<1));
-		outportb(PciFORWARD, BUSBNO(tbdf));
-		if(read)
-			x = inportl((0xC000|(BUSDNO(tbdf)<<8)) + rno);
-		else
-			outportl((0xC000|(BUSDNO(tbdf)<<8)) + rno, data);
-		outportb(PciCSE, 0);
-		break;
-	}
-
-	return x;
-}
-
 int
 pcicfgr32(Pcidev* pcidev, int rno)
 {
-	return pcicfgrw32(pcidev->tbdf, rno, 0, 1);
+	return pcicfgrw(pcidev, rno, 0, 4, 1);
 }
 
 void
 pcicfgw32(Pcidev* pcidev, int rno, int data)
 {
-	pcicfgrw32(pcidev->tbdf, rno, data, 0);
+	pcicfgrw(pcidev, rno, data, 4, 0);
 }
 
 Pcidev*
 pcimatch(Pcidev* prev, int vid, int did)
 {
-	if(pcicfgmode == -1)
+	if(pcilist == nil)
 		pcicfginit();
 
 	if(prev == nil)
@@ -277,36 +177,3 @@
 	return prev;
 }
 
-void
-pcihinv(Pcidev* p)
-{
-	int i;
-	Pcidev *t;
-
-	if(pcicfgmode == -1)
-		pcicfginit();
-
-
-	if(p == nil) {
-		p = pciroot;
-		Bprint(&stdout, "bus dev type vid  did intl memory\n");
-	}
-	for(t = p; t != nil; t = t->link) {
-		Bprint(&stdout, "%d  %2d/%d %.4ux %.4ux %.4ux %2d  ",
-			BUSBNO(t->tbdf), BUSDNO(t->tbdf), BUSFNO(t->tbdf),
-			t->ccru, t->vid, t->did, t->intl);
-
-		for(i = 0; i < nelem(p->mem); i++) {
-			if(t->mem[i].size == 0)
-				continue;
-			Bprint(&stdout, "%d:%.8lux %d ", i,
-				t->mem[i].bar, t->mem[i].size);
-		}
-		Bprint(&stdout, "\n");
-	}
-	while(p != nil) {
-		if(p->bridge != nil)
-			pcihinv(p->bridge);
-		p = p->link;
-	}
-}
--- a/sys/src/cmd/aux/vga/pci.h
+++ b/sys/src/cmd/aux/vga/pci.h
@@ -99,8 +99,6 @@
 	uchar	intl;			/* interrupt line */
 	ushort	ccru;
 
-
 	Pcidev*	list;
-	Pcidev*	bridge;			/* down a bus */
-	Pcidev*	link;			/* next device on this bno */
+	int rawfd;
 };