sync pci.c to nix. Reference: /n/atom/patch/applied2013/fsamd64pci Date: Tue Sep 17 14:53:12 CES 2013 Signed-off-by: quanstro@quanstro.net --- /sys/src/fs/port/lib.h Tue Sep 17 14:46:36 2013 +++ /sys/src/fs/port/lib.h Tue Sep 17 14:46:36 2013 @@ -144,6 +144,8 @@ */ #define assert(x) if(x){}else _assert("x") int getfields(char*, char**, int, int, char*); +int tokenize(char*, char**, int); +int gettokens(char *, char **, int, char *); void qsort(void*, long, long, int (*)(void*, void*)); int decrypt(void*, void*, int); int encrypt(void*, void*, int); --- /sys/src/fs/amd64/pci.c Tue Sep 17 14:46:37 2013 +++ /sys/src/fs/amd64/pci.c Tue Sep 17 14:46:38 2013 @@ -74,7 +74,7 @@ snprint(buf, sizeof buf, "%s", p); f = f0; - n = getfields(buf, f, nelem(f0), 1, "."); + n = gettokens(buf, f, nelem(f0), "."); memset(t, 0, sizeof t); t[0] = BusPCI; if((bus = strtobus(f[0])) != BUSUNKNOWN){ @@ -89,26 +89,30 @@ return MKBUS(t[0], t[1], t[2], t[3]); } -static u32int -pcimask(u32int v) +static int +Tfmt(Fmt* fmt) { - u32int m; + char buf[32], *p, *e; + int type, tbdf; - m = 8*sizeof(v); - for(m = 1<<(m-1); m != 0; m >>= 1) { - if(m & v) - break; + p = buf; + e = buf+sizeof buf; + tbdf = va_arg(fmt->args, int); + if(tbdf == -1) + return fmtstrcpy(fmt, "isa"); + if(fmt->flags & FmtLong){ + type = BUSTYPE(tbdf); + if(type == 12) + p = seprint(p, e, "pci."); + else + p = seprint(p, e, "%d.", type); } - - m--; - if((v & m) == 0) - return v; - - v |= m; - return v+1; + seprint(p, e, "%d.%d.%d", + BUSBNO(tbdf), BUSDNO(tbdf), BUSFNO(tbdf)); + return fmtstrcpy(fmt, buf); } -u32int +static u32int pcibarsize(Pcidev *p, int rno) { u32int v, size; @@ -242,6 +246,11 @@ pcicfgw32(p, PciPBN, maxubn<<16 | sbn<<8 | bno); } else { + /* + * You can't go back. This shouldn't be possible, but the + * Iwill DK8-HTX seems to have decreasing subordinate + * bus numbers Need to look more closely at his. + */ if(ubn > maxubn) maxubn = ubn; pcilscan(sbn, &p->bridge); @@ -331,29 +340,6 @@ uchar checksum; }; -static int -Tfmt(Fmt* fmt) -{ - char buf[32], *p, *e; - int type, tbdf; - - p = buf; - e = buf+sizeof buf; - tbdf = va_arg(fmt->args, int); - if(tbdf == -1) - return fmtstrcpy(fmt, "isa"); - if(fmt->flags & FmtLong){ - type = BUSTYPE(tbdf); - if(type == 12) - p = seprint(p, e, "pci."); - else - p = seprint(p, e, "%d.", type); - } - seprint(p, e, "%d.%d.%d", - BUSBNO(tbdf), BUSDNO(tbdf), BUSFNO(tbdf)); - return fmtstrcpy(fmt, buf); -} - static void pcirouting(void) { @@ -374,7 +360,6 @@ r = (Router *)p; - fmtinstall(L'T', Tfmt); if(0) print("PCI interrupt routing table version %d.%d at %.6llux\n", r->version[0], r->version[1], (uintptr)r & 0xfffff); @@ -439,21 +424,6 @@ } static void -cmd_pcihinv(int argc, char *argv[]) -{ - int i, flags = 0; - - for (i = 1; i < argc; i++) - if (strcmp(argv[i], "-v") == 0) - flags |= 1; - else { - print("unknown pcihinv option %s; options are: -v\n", argv[i]); - return; - } - pcihinv(nil, flags); /* print the whole device tree */ -} - -static void pcicfginit(void) { int bno, n; @@ -467,9 +437,7 @@ return; } - cmd_install("pcihinv", "-- pci inventory", cmd_pcihinv); - -// fmtinstall('T', fmtT); + fmtinstall('T', Tfmt); /* * Try to determine if PCI Mode1 configuration implemented. @@ -493,15 +461,15 @@ list = &pciroot; for(bno = 0; bno <= Maxbus; bno++) { bno = pcilscan(bno, list); - while(*list) + while(*list != nil) list = &(*list)->link; } + pcirouting(); -// pcireservemem(); unlock(&pcicfginitlock); if(getconf("*pcihinv")) - pcihinv(pciroot, 1); + pcihinv(nil); } static int @@ -576,7 +544,7 @@ pcicfgrw(p->tbdf, rno, data, Write, 2); } -int +uint pcicfgr32(Pcidev *p, int rno) { return pcicfgrw(p->tbdf, rno, 0, Read, 4); @@ -588,14 +556,6 @@ pcicfgrw(p->tbdf, rno, data, Write, 4); } -void -pciclrmwi(Pcidev* p) -{ - p->pcr &= ~MemWrInv; - pcicfgw16(p, PciPCR, p->pcr); -} - - Pcidev* pcimatch(Pcidev* prev, int vid, int did) { @@ -620,131 +580,19 @@ return p; } -static char * -ccru2name(int ccru) -{ - switch (ccru) { - case 0x01: /* mass storage controller */ - return "disks"; - case 0x02: /* network controller */ - return "net"; /* probably ether */ - case 0x03: /* display controller */ - return "video"; - case 0x04: /* multimedia device */ - return "audio"; - case 0x07: /* simple communication controllers */ - return "serial"; - case 0x08: /* base system peripherals */ - return "basic"; - case 0x09: /* input devices */ - return "input"; - case 0x0A: /* docking stations */ - return "dock"; - case 0x0B: /* processors */ - return "cpu"; - case 0x0C: /* serial bus controllers */ - return "usb"; - case 0x00: - return "memct0"; - case 0x05: /* memory controller */ - return "memctl"; - case 0x06: /* bridge device */ - return "bridge"; - default: - return "*gok*"; - } -} - -static char * -vid2name(int vid) -{ - switch (vid) { - case 0x1000: - return "ncr"; - case 0x1002: - return "ati"; - case 0x100b: - return "natsemi"; - case 0x1011: - return "dec"; - case 0x1013: - return "cirrus"; - case 0x1022: - return "amd"; - case 0x1023: - return "cyber?"; - case 0x102b: - return "matrox"; - case 0x102c: - return "hiq"; - case 0x1039: - return "sis"; - case 0x104b: - return "mylex"; - case 0x105a: - return "promise"; - case 0x105d: - return "number9"; - case 0x10a9: - return "sgi"; - case 0x10b7: - return "3com"; - case 0x10c8: - return "neomagic"; /* or magicgraph */ - case 0x10de: - return "nvidia"; - case 0x10ec: - return "realtek"; - case 0x11ab: - return "marvell"; - case 0x11ad: - return "(pnic?)"; - case 0x121a: - return "voodoo"; - case 0x12ae: - return "alteon"; - case 0x1385: - return "netgear"; - case 0x14c1: - return "myri"; - case 0x15ad: - return "vmware"; - case 0x16ec: - return "usrobot"; - case 0x5333: /* "S" "3". har, har. */ - return "s3"; - case 0x8086: - return "intel"; - default: - return "*GOK*"; - } -} - void -pcihinv(Pcidev* p, uint flags) +pcihinv(Pcidev* p) { int i; Pcidev *t; if(p == nil) { p = pciroot; - print("bus dev type "); - if (flags) - print("%7s", ""); - print("vid "); - if (flags) - print("%8s", ""); - print("did intl memory\n"); + print("tbdf: type vid did intl memory\n"); } for(t = p; t != nil; t = t->link) { - print("%d.%2d.%d %.4ux", BUSBNO(t->tbdf), BUSDNO(t->tbdf), - BUSFNO(t->tbdf), t->ccru); - if (flags) - print(" %-6s", ccru2name(t->ccru)); - print(" %.4ux", t->vid); - if (flags) - print(" %-7s", vid2name(t->vid)); - print(" %.4ux %2d ", t->did, t->intl); + print("%T: %.2ux %.4ux/%.4ux %.2d", + t->tbdf, t->ccru, t->vid, t->did, t->intl); for(i = 0; i < nelem(p->mem); i++) { if(t->mem[i].size == 0) @@ -752,13 +600,13 @@ print("%d:%#P %d ", i, t->mem[i].bar, t->mem[i].size); } - if(t->bridge) + if(t->bridge != nil) print("->%d", BUSBNO(t->bridge->tbdf)); print("\n"); } while(p != nil) { if(p->bridge != nil) - pcihinv(p->bridge, flags); + pcihinv(p->bridge); p = p->link; } } @@ -775,6 +623,20 @@ } void +pcisetioe(Pcidev* p) +{ + p->pcr |= IOen; + pcicfgw16(p, PciPCR, p->pcr); +} + +void +pciclrioe(Pcidev* p) +{ + p->pcr &= ~IOen; + pcicfgw16(p, PciPCR, p->pcr); +} + +void pcisetbme(Pcidev* p) { p->pcr |= MASen; @@ -788,6 +650,20 @@ pcicfgw16(p, PciPCR, p->pcr); } +void +pcisetmwi(Pcidev* p) +{ + p->pcr |= MemWrInv; + pcicfgw16(p, PciPCR, p->pcr); +} + +void +pciclrmwi(Pcidev* p) +{ + p->pcr &= ~MemWrInv; + pcicfgw16(p, PciPCR, p->pcr); +} + int pcicap(Pcidev *p, int cap) { @@ -822,3 +698,50 @@ return -1; } +enum { + Pmgcap = 2, /* capabilities; 2 bytes*/ + Pmgctl = 4, /* ctl/status; 2 bytes */ + Pmgbrg = 6, /* bridge support */ + Pmgdata = 7, +}; + +int +pcigetpms(Pcidev* p) +{ + int ptr; + + if((ptr = pcicap(p, PciCapPMG)) == -1) + return -1; + return pcicfgr16(p, ptr+Pmgctl) & 0x0003; +} + +int +pcisetpms(Pcidev* p, int state) +{ + int pmc, pmcsr, ptr; + + if((ptr = pcicap(p, PciCapPMG)) == -1) + return -1; + + pmc = pcicfgr16(p, ptr+Pmgcap); + pmcsr = pcicfgr16(p, ptr+Pmgctl); + + switch(state){ + default: + return -1; + case 0: + break; + case 1: + if(!(pmc & 0x0200)) + return -1; + break; + case 2: + if(!(pmc & 0x0400)) + return -1; + break; + case 3: + break; + } + pcicfgw16(p, ptr+4, (pmcsr & ~3) | state); + return pmcsr & 3; +} --- /sys/src/fs/amd64/io.h Tue Sep 17 14:46:39 2013 +++ /sys/src/fs/amd64/io.h Tue Sep 17 14:46:39 2013 @@ -1,3 +1,9 @@ +typedef struct Hwconf Hwconf; +typedef struct Pciconf Pciconf; +typedef struct Pcidev Pcidev; +typedef struct Vctl Vctl; +typedef struct Vkey Vkey; + enum { VectorNMI = 2, /* non-maskable interrupt */ VectorBPT = 3, /* breakpoint */ @@ -59,9 +65,6 @@ IdtMAX = 255, }; -typedef struct Vkey Vkey; -typedef struct Vctl Vctl; - struct Vkey { int tbdf; /* pci: ioapic or msi sources */ int irq; /* 8259-emulating sources */ @@ -78,16 +81,11 @@ void* a; /* argument to call it with */ char name[NAMELEN]; /* of driver */ char *type; + int (*isr)(int); /* get isr bit for this irq */ int (*eoi)(int); /* eoi */ int (*mask)(Vkey*, int); /* interrupt enable returns masked vector */ - int vno; /* cpu vector */ -}; - -enum{ - Pat = 1<<16, - Mmx = 1<<23, - Sse2 = 1<<26, + int vno; }; void* intrenable(int, void (*)(Ureg*, void*), void*, int, char*); @@ -96,10 +94,6 @@ #define NVRAUTHADDR 0 enum { - MaxEther = 8, -}; - -enum { BusCBUS = 0, /* Corollary CBUS */ BusCBUSII, /* Corollary CBUS II */ BusEISA, /* Extended ISA */ @@ -148,80 +142,13 @@ PciBAR0 = 0x10, /* base address */ PciBAR1 = 0x14, + PciCP = 0x34, /* capabilities pointer */ + PciINTL = 0x3C, /* interrupt line */ PciINTP = 0x3D, /* interrupt pin */ }; -/* capabilities */ -enum { - PciCapPMG = 0x01, /* power management */ - PciCapAGP = 0x02, - PciCapVPD = 0x03, /* vital product data */ - PciCapSID = 0x04, /* slot id */ - PciCapMSI = 0x05, - PciCapCHS = 0x06, /* compact pci hot swap */ - PciCapPCIX = 0x07, - PciCapHTC = 0x08, /* hypertransport irq conf */ - PciCapVND = 0x09, /* vendor specific information */ - PciCapPCIe = 0x10, - PciCapMSIX = 0x11, - PciCapSATA = 0x12, - PciCapHSW = 0x0c, /* hot swap */ -}; - -/* ccrb (base class code) values; controller types */ -enum { - Pcibcpci1 = 0, /* pci 1.0; no class codes defined */ - Pcibcstore = 1, /* mass storage */ - Pcibcnet = 2, /* network */ - Pcibcdisp = 3, /* display */ - Pcibcmmedia = 4, /* multimedia */ - Pcibcmem = 5, /* memory */ - Pcibcbridge = 6, /* bridge */ - Pcibccomm = 7, /* simple comms (e.g., serial) */ - Pcibcbasesys = 8, /* base system */ - Pcibcinput = 9, /* input */ - Pcibcdock = 0xa, /* docking stations */ - Pcibcproc = 0xb, /* processors */ - Pcibcserial = 0xc, /* serial bus (e.g., USB) */ - Pcibcwireless = 0xd, /* wireless */ - Pcibcintell = 0xe, /* intelligent i/o */ - Pcibcsatcom = 0xf, /* satellite comms */ - Pcibccrypto = 0x10, /* encryption/decryption */ - Pcibcdacq = 0x11, /* data acquisition & signal proc. */ -}; - -/* ccru (sub-class code) values; common cases only */ -enum { - /* mass storage */ - Pciscscsi = 0, /* SCSI */ - Pciscide = 1, /* IDE (ATA) */ - - /* network */ - Pciscether = 0, /* Ethernet */ - - /* display */ - Pciscvga = 0, /* VGA */ - Pciscxga = 1, /* XGA */ - Pcisc3d = 2, /* 3D */ - - /* bridges */ - Pcischostpci = 0, /* host/pci */ - Pciscpcicpci = 1, /* pci/pci */ - - /* simple comms */ - Pciscserial = 0, /* 16450, etc. */ - Pciscmultiser = 1, /* multiport serial */ - - /* serial bus */ - Pciscusb = 3, /* USB */ -}; - enum { /* type 0 pre-defined header */ - PciBAR2 = 0x18, - PciBAR3 = 0x1C, - PciBAR4 = 0x20, - PciBAR5 = 0x24, PciCIS = 0x28, /* cardbus CIS pointer */ PciSVID = 0x2C, /* subsystem vendor ID */ PciSID = 0x2E, /* cardbus CIS pointer */ @@ -250,60 +177,48 @@ PciBCR = 0x3E, /* bridge control register */ }; -typedef struct Pcidev Pcidev; -typedef struct Pcidev { +/* capabilities */ +enum { + PciCapPMG = 0x01, /* power management */ + PciCapAGP = 0x02, + PciCapVPD = 0x03, /* vital product data */ + PciCapSID = 0x04, /* slot id */ + PciCapMSI = 0x05, + PciCapCHS = 0x06, /* compact pci hot swap */ + PciCapPCIX = 0x07, + PciCapHTC = 0x08, /* hypertransport irq conf */ + PciCapVND = 0x09, /* vendor specific information */ + PciCapPCIe = 0x10, + PciCapMSIX = 0x11, + PciCapSATA = 0x12, + PciCapHSW = 0x0c, /* hot swap */ +}; + +struct Pcidev { int tbdf; /* type+bus+device+function */ ushort vid; /* vendor ID */ ushort did; /* device ID */ - struct { - uintmem bar; /* base address */ - int size; - } mem[6], rom, ioa, mema; + ushort pcr; uchar rid; uchar ccrp; - uchar ccrb; - uchar intl; /* interrupt line */ uchar ccru; - ushort pcr; + uchar ccrb; uchar cls; uchar ltr; + uchar intl; /* interrupt line */ + + struct { + uintmem bar; /* base address */ + int size; + } mem[6]; Pcidev* list; - Pcidev* bridge; /* down a bus */ Pcidev* link; /* next device on this bno */ -} Pcidev; - -typedef struct Pcisiz Pcisiz; -struct Pcisiz{ - Pcidev* dev; - int siz; - int bar; -}; - -int pcicap(Pcidev*, int); -int pcicfgr8(Pcidev*, int); -int pcicfgr16(Pcidev*, int); -int pcicfgr32(Pcidev*, int); -void pcicfgw8(Pcidev*, int, int); -void pcicfgw16(Pcidev*, int, int); -void pcicfgw32(Pcidev*, int, int); -void pciclrmwi(Pcidev*); -void pcihinv(Pcidev*, uint); -Pcidev* pcimatch(Pcidev*, int, int); -Pcidev* pcimatchtbdf(int); -void pcireset(void); -void pcisetbme(Pcidev*); -void pciclrbme(Pcidev*); -int strtotbdf(char*, char**, int); - -enum { - Npciopt = 10, - Pcioptlen = 32, + Pcidev* bridge; /* down a bus */ }; -typedef struct Pciconf Pciconf; struct Pciconf { char *type; uintmem port; @@ -317,8 +232,31 @@ char *opt[8]; }; -extern int pciconfig(char*, int, Pciconf*); +int pcicap(Pcidev*, int); +int pcicfgr16(Pcidev*, int); +uint pcicfgr32(Pcidev*, int); +int pcicfgr8(Pcidev*, int); +void pcicfgw16(Pcidev*, int, int); +void pcicfgw32(Pcidev*, int, int); +void pcicfgw8(Pcidev*, int, int); +void pciclrbme(Pcidev*); +void pciclriome(Pcidev*); +void pciclrmwi(Pcidev*); +int pciconfig(char*, int, Pciconf*); +int pcigetpms(Pcidev*); +void pcihinv(Pcidev*); +Pcidev* pcimatch(Pcidev*, int, int); +Pcidev* pcimatchtbdf(int); +void pcireset(void); +void pcisetbme(Pcidev*); +void pcisetioe(Pcidev*); +void pcisetmwi(Pcidev*); +int pcisetpms(Pcidev*, int); +int strtotbdf(char*, char**, int); + #define PCIWINDOW 0 #define PCIWADDR(va) (PADDR(va)+PCIWINDOW) #define Pciwaddrl(va) ((u32int)PCIWADDR(va)) #define Pciwaddrh(va) ((u32int)(PCIWADDR(va)>>32)) + +#pragma varargck type "T" int --- /sys/src/fs/amd64/iasata.c Tue Sep 17 14:46:41 2013 +++ /sys/src/fs/amd64/iasata.c Tue Sep 17 14:46:42 2013 @@ -1440,7 +1440,7 @@ type = Tjmicron; break; } - if(p->ccrb == Pcibcstore && (uchar)p->ccru == 6 && p->ccrp == 1) + if(p->ccrb == 1 && (uchar)p->ccru == 6 && p->ccrp == 1) return type; return -1; } @@ -1468,7 +1468,7 @@ } c = iactlr + niactlr; memset(c, 0, sizeof *c); - io = p->mem[Abar].bar & ~0xfull; + io = p->mem[Abar].bar & ~(uintmem)0xf; c->mmio = vmap(io, p->mem[Abar].size); if(c->mmio == nil){ print("%s: address %#p in use did %.4ux\n", --- /sys/src/fs/amd64/etherif.h Tue Sep 17 14:46:43 2013 +++ /sys/src/fs/amd64/etherif.h Tue Sep 17 14:46:43 2013 @@ -33,6 +33,10 @@ int (*reset)(Ether*); }; +enum { + MaxEther = 8, +}; + extern Etherctlr etherctlr[]; extern int netherctlr; extern Ether etherif[MaxEther];