diff options
author | cinap_lenrek <cinap_lenrek@centraldogma> | 2011-05-23 19:21:24 +0000 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@centraldogma> | 2011-05-23 19:21:24 +0000 |
commit | bbbfbe3dc41004b98531094a9fedacacbc897085 (patch) | |
tree | 6a77e4525c92cc30a1679b20fc0e7d025eed313f | |
parent | fb9c05bbefed4ef372f4e62e867d4209c473838f (diff) |
aux/vga: use devpnp for pci control register io
-rw-r--r-- | sys/src/cmd/aux/vga/pci.c | 331 | ||||
-rw-r--r-- | sys/src/cmd/aux/vga/pci.h | 4 |
2 files changed, 100 insertions, 235 deletions
diff --git a/sys/src/cmd/aux/vga/pci.c b/sys/src/cmd/aux/vga/pci.c index 3151a9d73..50ebc0186 100644 --- 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(pcilist != nil) - pcitail->list = p; - else - pcilist = p; - pcitail = p; - + if(strstr(d[i].name, "ctl") == nil) + continue; - trace("\t-> did=%X vid=%X rid=%X intl=%d ccru=%X\n",p->did, p->vid, p->rid,p->intl, p->ccru); - + sprint(buf, "%s", d[i].name); + bno = strtoul(buf, &s, 10); + dno = strtoul(s+1, &s, 10); + fno = strtoul(s+1, nil, 10); + + 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; } - } -} - -static int -pcicfgrw8(int tbdf, int rno, int data, int read) -{ - int o, type, x; + 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); - if(pcicfgmode == -1) - pcicfginit(); + 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); - if(BUSBNO(tbdf)) - type = 0x01; - else - type = 0x00; - x = -1; - if(BUSDNO(tbdf) > pcimaxdno) - return x; + p->rid = pcicfgr8(p, PciRID); - switch(pcicfgmode){ + trace("did=%X vid=%X rid=%X intl=%d ccru=%X\n", p->did, p->vid, p->rid, p->intl, p->ccru); - 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; + 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); + } - case 2: - outportb(PciCSE, 0x80|(BUSFNO(tbdf)<<1)); - outportb(PciFORWARD, BUSBNO(tbdf)); - if(read) - x = inportb((0xC000|(BUSDNO(tbdf)<<8)) + rno); + if(pcilist != nil) + pcitail->list = p; else - outportb((0xC000|(BUSDNO(tbdf)<<8)) + rno, data); - outportb(PciCSE, 0); - break; + pcilist = p; + pcitail = p; } +} - return x; +static int +pcicfgrw(Pcidev *pcidev, int rno, int data, int len, int read) +{ + uchar buf[4]; + + 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 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); -} - -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; + pcicfgrw(pcidev, rno, data, 1, 0); } 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); -} - -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; + pcicfgrw(pcidev, rno, data, 2, 0); } 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 @@ pcimatch(Pcidev* prev, int vid, int did) 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; - } -} diff --git a/sys/src/cmd/aux/vga/pci.h b/sys/src/cmd/aux/vga/pci.h index 12d423072..03a11bf38 100644 --- a/sys/src/cmd/aux/vga/pci.h +++ b/sys/src/cmd/aux/vga/pci.h @@ -99,8 +99,6 @@ typedef struct Pcidev { uchar intl; /* interrupt line */ ushort ccru; - Pcidev* list; - Pcidev* bridge; /* down a bus */ - Pcidev* link; /* next device on this bno */ + int rawfd; }; |