1 /* 2 * PCI 3 */ 4 typedef unsigned long long uintpci; 5 6 #define BUSUNKNOWN (-1) 7 8 enum { 9 BusCBUS = 0, /* Corollary CBUS */ 10 BusCBUSII, /* Corollary CBUS II */ 11 BusEISA, /* Extended ISA */ 12 BusFUTURE, /* IEEE Futurebus */ 13 BusINTERN, /* Internal bus */ 14 BusISA, /* Industry Standard Architecture */ 15 BusMBI, /* Multibus I */ 16 BusMBII, /* Multibus II */ 17 BusMCA, /* Micro Channel Architecture */ 18 BusMPI, /* MPI */ 19 BusMPSA, /* MPSA */ 20 BusNUBUS, /* Apple Macintosh NuBus */ 21 BusPCI, /* Peripheral Component Interconnect */ 22 BusPCMCIA, /* PC Memory Card International Association */ 23 BusTC, /* DEC TurboChannel */ 24 BusVL, /* VESA Local bus */ 25 BusVME, /* VMEbus */ 26 BusXPRESS, /* Express System Bus */ 27 }; 28 29 #define MKBUS(t,b,d,f) (((t)<<24)|(((b)&0xFF)<<16)|(((d)&0x1F)<<11)|(((f)&0x07)<<8)) 30 #define BUSFNO(tbdf) (((tbdf)>>8)&0x07) 31 #define BUSDNO(tbdf) (((tbdf)>>11)&0x1F) 32 #define BUSBNO(tbdf) (((tbdf)>>16)&0xFF) 33 #define BUSTYPE(tbdf) ((tbdf)>>24) 34 #define BUSBDF(tbdf) ((tbdf)&0x00FFFF00) 35 36 enum { /* type 0 & type 1 pre-defined header */ 37 PciVID = 0x00, /* vendor ID */ 38 PciDID = 0x02, /* device ID */ 39 PciPCR = 0x04, /* command */ 40 PciPSR = 0x06, /* status */ 41 PciRID = 0x08, /* revision ID */ 42 PciCCRp = 0x09, /* programming interface class code */ 43 PciCCRu = 0x0A, /* sub-class code */ 44 PciCCRb = 0x0B, /* base class code */ 45 PciCLS = 0x0C, /* cache line size */ 46 PciLTR = 0x0D, /* latency timer */ 47 PciHDT = 0x0E, /* header type */ 48 PciBST = 0x0F, /* BIST */ 49 50 PciBAR0 = 0x10, /* base address */ 51 PciBAR1 = 0x14, 52 53 PciCAP = 0x34, /* capabilities pointer */ 54 PciINTL = 0x3C, /* interrupt line */ 55 PciINTP = 0x3D, /* interrupt pin */ 56 }; 57 58 /* ccrb (base class code) values; controller types */ 59 enum { 60 Pcibcpci1 = 0, /* pci 1.0; no class codes defined */ 61 Pcibcstore = 1, /* mass storage */ 62 Pcibcnet = 2, /* network */ 63 Pcibcdisp = 3, /* display */ 64 Pcibcmmedia = 4, /* multimedia */ 65 Pcibcmem = 5, /* memory */ 66 Pcibcbridge = 6, /* bridge */ 67 Pcibccomm = 7, /* simple comms (e.g., serial) */ 68 Pcibcbasesys = 8, /* base system */ 69 Pcibcinput = 9, /* input */ 70 Pcibcdock = 0xa, /* docking stations */ 71 Pcibcproc = 0xb, /* processors */ 72 Pcibcserial = 0xc, /* serial bus (e.g., USB) */ 73 Pcibcwireless = 0xd, /* wireless */ 74 Pcibcintell = 0xe, /* intelligent i/o */ 75 Pcibcsatcom = 0xf, /* satellite comms */ 76 Pcibccrypto = 0x10, /* encryption/decryption */ 77 Pcibcdacq = 0x11, /* data acquisition & signal proc. */ 78 }; 79 80 /* ccru (sub-class code) values; common cases only */ 81 enum { 82 /* mass storage */ 83 Pciscscsi = 0, /* SCSI */ 84 Pciscide = 1, /* IDE (ATA) */ 85 Pciscsata = 6, /* SATA */ 86 87 /* network */ 88 Pciscether = 0, /* Ethernet */ 89 90 /* display */ 91 Pciscvga = 0, /* VGA */ 92 Pciscxga = 1, /* XGA */ 93 Pcisc3d = 2, /* 3D */ 94 95 /* bridges */ 96 Pcischostpci = 0, /* host/pci */ 97 Pciscpcicpci = 1, /* pci/pci */ 98 99 /* simple comms */ 100 Pciscserial = 0, /* 16450, etc. */ 101 Pciscmultiser = 1, /* multiport serial */ 102 103 /* serial bus */ 104 Pciscusb = 3, /* USB */ 105 }; 106 107 enum { /* type 0 pre-defined header */ 108 PciCIS = 0x28, /* cardbus CIS pointer */ 109 PciSVID = 0x2C, /* subsystem vendor ID */ 110 PciSID = 0x2E, /* subsystem ID */ 111 PciEBAR0 = 0x30, /* expansion ROM base address */ 112 PciMGNT = 0x3E, /* burst period length */ 113 PciMLT = 0x3F, /* maximum latency between bursts */ 114 }; 115 116 enum { /* type 1 pre-defined header */ 117 PciPBN = 0x18, /* primary bus number */ 118 PciSBN = 0x19, /* secondary bus number */ 119 PciUBN = 0x1A, /* subordinate bus number */ 120 PciSLTR = 0x1B, /* secondary latency timer */ 121 PciIBR = 0x1C, /* I/O base */ 122 PciILR = 0x1D, /* I/O limit */ 123 PciSPSR = 0x1E, /* secondary status */ 124 PciMBR = 0x20, /* memory base */ 125 PciMLR = 0x22, /* memory limit */ 126 PciPMBR = 0x24, /* prefetchable memory base */ 127 PciPMLR = 0x26, /* prefetchable memory limit */ 128 PciPUBR = 0x28, /* prefetchable base upper 32 bits */ 129 PciPULR = 0x2C, /* prefetchable limit upper 32 bits */ 130 PciIUBR = 0x30, /* I/O base upper 16 bits */ 131 PciIULR = 0x32, /* I/O limit upper 16 bits */ 132 PciEBAR1 = 0x28, /* expansion ROM base address */ 133 PciBCR = 0x3E, /* bridge control register */ 134 }; 135 136 enum { /* type 2 pre-defined header */ 137 PciCBExCA = 0x10, 138 PciCBSPSR = 0x16, 139 PciCBPBN = 0x18, /* primary bus number */ 140 PciCBSBN = 0x19, /* secondary bus number */ 141 PciCBUBN = 0x1A, /* subordinate bus number */ 142 PciCBSLTR = 0x1B, /* secondary latency timer */ 143 PciCBMBR0 = 0x1C, 144 PciCBMLR0 = 0x20, 145 PciCBMBR1 = 0x24, 146 PciCBMLR1 = 0x28, 147 PciCBIBR0 = 0x2C, /* I/O base */ 148 PciCBILR0 = 0x30, /* I/O limit */ 149 PciCBIBR1 = 0x34, /* I/O base */ 150 PciCBILR1 = 0x38, /* I/O limit */ 151 PciCBSVID = 0x40, /* subsystem vendor ID */ 152 PciCBSID = 0x42, /* subsystem ID */ 153 PciCBLMBAR = 0x44, /* legacy mode base address */ 154 }; 155 156 enum { 157 /* bar bits */ 158 Barioaddr = 1<<0, /* vs. memory addr */ 159 Barwidthshift = 1, 160 Barwidthmask = 3, 161 Barwidth32 = 0, 162 Barwidth64 = 2, 163 Barprefetch = 1<<3, 164 }; 165 166 enum 167 { /* command register */ 168 IOen = (1<<0), 169 MEMen = (1<<1), 170 MASen = (1<<2), 171 MemWrInv = (1<<4), 172 PErrEn = (1<<6), 173 SErrEn = (1<<8), 174 }; 175 176 /* capabilities */ 177 enum { 178 PciCapPMG = 0x01, /* power management */ 179 PciCapAGP = 0x02, 180 PciCapVPD = 0x03, /* vital product data */ 181 PciCapSID = 0x04, /* slot id */ 182 PciCapMSI = 0x05, 183 PciCapCHS = 0x06, /* compact pci hot swap */ 184 PciCapPCIX = 0x07, 185 PciCapHTC = 0x08, /* hypertransport irq conf */ 186 PciCapVND = 0x09, /* vendor specific information */ 187 PciCapPCIe = 0x10, 188 PciCapMSIX = 0x11, 189 PciCapSATA = 0x12, 190 PciCapHSW = 0x0c, /* hot swap */ 191 }; 192 193 typedef struct Pcidev Pcidev; 194 struct Pcidev 195 { 196 int tbdf; /* type+bus+device+function */ 197 ushort vid; /* vendor ID */ 198 ushort did; /* device ID */ 199 200 ushort pcr; 201 202 uchar rid; 203 uchar ccrp; 204 uchar ccru; 205 uchar ccrb; 206 uchar cls; 207 uchar ltr; 208 209 struct { 210 uintpci bar; /* base address */ 211 int size; 212 } mem[6]; 213 214 uchar intl; /* interrupt line */ 215 216 Pcidev* list; 217 Pcidev* link; /* next device on this bno */ 218 219 Pcidev* parent; /* up a bus */ 220 Pcidev* bridge; /* down a bus */ 221 222 int pmrb; /* power management register block */ 223 224 struct { 225 uintpci bar; 226 int size; 227 } ioa, mema; 228 }; 229 230 #define PCIWINDOW 0 231 #define PCIWADDR(va) (PADDR(va)+PCIWINDOW) 232 233 #pragma varargck type "T" int 234 #pragma varargck type "T" uint 235 236 void pcienable(Pcidev *); 237 void pcidisable(Pcidev *); 238 void pcisetbme(Pcidev* ); 239 Pcidev* pcimatch(Pcidev* prev, int vid, int did); 240 void pciintrenable(int tbdf, void (*f)(Ureg*, void*), void *a); 241 void pciintrdisable(int tbdf, void (*f)(Ureg*, void*), void *a); 242