29 30#include "opt_cpu.h" 31 32#include <sys/param.h> 33#include <sys/systm.h> 34#include <sys/bus.h> 35#include <sys/kernel.h> 36#include <sys/malloc.h> 37#include <sys/module.h> 38#include <sys/sysctl.h> 39 40#include <dev/pci/pcivar.h> 41#include <dev/pci/pcireg.h> 42#include <dev/pci/pcib_private.h> 43#include <isa/isavar.h> 44#ifdef CPU_ELAN 45#include <machine/md_var.h> 46#endif 47#include <machine/legacyvar.h> 48#include <machine/pci_cfgreg.h> 49#include <machine/resource.h> 50 51#include "pcib_if.h" 52 53static int pcibios_pcib_route_interrupt(device_t pcib, device_t dev, 54 int pin); 55 56int 57legacy_pcib_maxslots(device_t dev) 58{ 59 return 31; 60} 61 62/* read configuration space register */ 63 64u_int32_t 65legacy_pcib_read_config(device_t dev, int bus, int slot, int func, 66 int reg, int bytes) 67{ 68 return(pci_cfgregread(bus, slot, func, reg, bytes)); 69} 70 71/* write configuration space register */ 72 73void 74legacy_pcib_write_config(device_t dev, int bus, int slot, int func, 75 int reg, u_int32_t data, int bytes) 76{ 77 pci_cfgregwrite(bus, slot, func, reg, data, bytes); 78} 79 80static const char * 81legacy_pcib_is_host_bridge(int bus, int slot, int func, 82 uint32_t id, uint8_t class, uint8_t subclass, 83 uint8_t *busnum) 84{ 85 const char *s = NULL; 86 static uint8_t pxb[4]; /* hack for 450nx */ 87 88 *busnum = 0; 89 90 switch (id) { 91 case 0x12258086: 92 s = "Intel 824?? host to PCI bridge"; 93 /* XXX This is a guess */ 94 /* *busnum = legacy_pcib_read_config(0, bus, slot, func, 0x41, 1); */ 95 *busnum = bus; 96 break; 97 case 0x71208086: 98 s = "Intel 82810 (i810 GMCH) Host To Hub bridge"; 99 break; 100 case 0x71228086: 101 s = "Intel 82810-DC100 (i810-DC100 GMCH) Host To Hub bridge"; 102 break; 103 case 0x71248086: 104 s = "Intel 82810E (i810E GMCH) Host To Hub bridge"; 105 break; 106 case 0x11308086: 107 s = "Intel 82815 (i815 GMCH) Host To Hub bridge"; 108 break; 109 case 0x71808086: 110 s = "Intel 82443LX (440 LX) host to PCI bridge"; 111 break; 112 case 0x71908086: 113 s = "Intel 82443BX (440 BX) host to PCI bridge"; 114 break; 115 case 0x71928086: 116 s = "Intel 82443BX host to PCI bridge (AGP disabled)"; 117 break; 118 case 0x71948086: 119 s = "Intel 82443MX host to PCI bridge"; 120 break; 121 case 0x71a08086: 122 s = "Intel 82443GX host to PCI bridge"; 123 break; 124 case 0x71a18086: 125 s = "Intel 82443GX host to AGP bridge"; 126 break; 127 case 0x71a28086: 128 s = "Intel 82443GX host to PCI bridge (AGP disabled)"; 129 break; 130 case 0x84c48086: 131 s = "Intel 82454KX/GX (Orion) host to PCI bridge"; 132 *busnum = legacy_pcib_read_config(0, bus, slot, func, 0x4a, 1); 133 break; 134 case 0x84ca8086: 135 /* 136 * For the 450nx chipset, there is a whole bundle of 137 * things pretending to be host bridges. The MIOC will 138 * be seen first and isn't really a pci bridge (the 139 * actual busses are attached to the PXB's). We need to 140 * read the registers of the MIOC to figure out the 141 * bus numbers for the PXB channels. 142 * 143 * Since the MIOC doesn't have a pci bus attached, we 144 * pretend it wasn't there. 145 */ 146 pxb[0] = legacy_pcib_read_config(0, bus, slot, func, 147 0xd0, 1); /* BUSNO[0] */ 148 pxb[1] = legacy_pcib_read_config(0, bus, slot, func, 149 0xd1, 1) + 1; /* SUBA[0]+1 */ 150 pxb[2] = legacy_pcib_read_config(0, bus, slot, func, 151 0xd3, 1); /* BUSNO[1] */ 152 pxb[3] = legacy_pcib_read_config(0, bus, slot, func, 153 0xd4, 1) + 1; /* SUBA[1]+1 */ 154 return NULL; 155 case 0x84cb8086: 156 switch (slot) { 157 case 0x12: 158 s = "Intel 82454NX PXB#0, Bus#A"; 159 *busnum = pxb[0]; 160 break; 161 case 0x13: 162 s = "Intel 82454NX PXB#0, Bus#B"; 163 *busnum = pxb[1]; 164 break; 165 case 0x14: 166 s = "Intel 82454NX PXB#1, Bus#A"; 167 *busnum = pxb[2]; 168 break; 169 case 0x15: 170 s = "Intel 82454NX PXB#1, Bus#B"; 171 *busnum = pxb[3]; 172 break; 173 } 174 break; 175 176 /* AMD -- vendor 0x1022 */ 177 case 0x30001022: 178 s = "AMD Elan SC520 host to PCI bridge"; 179#ifdef CPU_ELAN 180 init_AMD_Elan_sc520(); 181#else 182 printf( 183"*** WARNING: missing CPU_ELAN -- timekeeping may be wrong\n"); 184#endif 185 break; 186 case 0x70061022: 187 s = "AMD-751 host to PCI bridge"; 188 break; 189 case 0x700e1022: 190 s = "AMD-761 host to PCI bridge"; 191 break; 192 193 /* SiS -- vendor 0x1039 */ 194 case 0x04961039: 195 s = "SiS 85c496"; 196 break; 197 case 0x04061039: 198 s = "SiS 85c501"; 199 break; 200 case 0x06011039: 201 s = "SiS 85c601"; 202 break; 203 case 0x55911039: 204 s = "SiS 5591 host to PCI bridge"; 205 break; 206 case 0x00011039: 207 s = "SiS 5591 host to AGP bridge"; 208 break; 209 210 /* VLSI -- vendor 0x1004 */ 211 case 0x00051004: 212 s = "VLSI 82C592 Host to PCI bridge"; 213 break; 214 215 /* XXX Here is MVP3, I got the datasheet but NO M/B to test it */ 216 /* totally. Please let me know if anything wrong. -F */ 217 /* XXX need info on the MVP3 -- any takers? */ 218 case 0x05981106: 219 s = "VIA 82C598MVP (Apollo MVP3) host bridge"; 220 break; 221 222 /* AcerLabs -- vendor 0x10b9 */ 223 /* Funny : The datasheet told me vendor id is "10b8",sub-vendor */ 224 /* id is '10b9" but the register always shows "10b9". -Foxfair */ 225 case 0x154110b9: 226 s = "AcerLabs M1541 (Aladdin-V) PCI host bridge"; 227 break; 228 229 /* OPTi -- vendor 0x1045 */ 230 case 0xc7011045: 231 s = "OPTi 82C700 host to PCI bridge"; 232 break; 233 case 0xc8221045: 234 s = "OPTi 82C822 host to PCI Bridge"; 235 break; 236 237 /* ServerWorks -- vendor 0x1166 */ 238 case 0x00051166: 239 s = "ServerWorks NB6536 2.0HE host to PCI bridge"; 240 *busnum = legacy_pcib_read_config(0, bus, slot, func, 0x44, 1); 241 break; 242 243 case 0x00061166: 244 /* FALLTHROUGH */ 245 case 0x00081166: 246 /* FALLTHROUGH */ 247 case 0x02011166: 248 /* FALLTHROUGH */ 249 case 0x010f1014: /* IBM re-badged ServerWorks chipset */ 250 s = "ServerWorks host to PCI bridge"; 251 *busnum = legacy_pcib_read_config(0, bus, slot, func, 0x44, 1); 252 break; 253 254 case 0x00091166: 255 s = "ServerWorks NB6635 3.0LE host to PCI bridge"; 256 *busnum = legacy_pcib_read_config(0, bus, slot, func, 0x44, 1); 257 break; 258 259 case 0x00101166: 260 s = "ServerWorks CIOB30 host to PCI bridge"; 261 *busnum = legacy_pcib_read_config(0, bus, slot, func, 0x44, 1); 262 break; 263 264 case 0x00111166: 265 /* FALLTHROUGH */ 266 case 0x03021014: /* IBM re-badged ServerWorks chipset */ 267 s = "ServerWorks CMIC-HE host to PCI-X bridge"; 268 *busnum = legacy_pcib_read_config(0, bus, slot, func, 0x44, 1); 269 break; 270 271 /* XXX unknown chipset, but working */ 272 case 0x00171166: 273 /* FALLTHROUGH */ 274 case 0x01011166: 275 s = "ServerWorks host to PCI bridge(unknown chipset)"; 276 *busnum = legacy_pcib_read_config(0, bus, slot, func, 0x44, 1); 277 break; 278 279 /* Compaq/HP -- vendor 0x0e11 */ 280 case 0x60100e11: 281 s = "Compaq/HP Model 6010 HotPlug PCI Bridge"; 282 *busnum = legacy_pcib_read_config(0, bus, slot, func, 0xc8, 1); 283 break; 284 285 /* Integrated Micro Solutions -- vendor 0x10e0 */ 286 case 0x884910e0: 287 s = "Integrated Micro Solutions VL Bridge"; 288 break; 289 290 default: 291 if (class == PCIC_BRIDGE && subclass == PCIS_BRIDGE_HOST) 292 s = "Host to PCI bridge"; 293 break; 294 } 295 296 return s; 297} 298 299/* 300 * Scan the first pci bus for host-pci bridges and add pcib instances 301 * to the nexus for each bridge. 302 */ 303static void 304legacy_pcib_identify(driver_t *driver, device_t parent) 305{ 306 int bus, slot, func; 307 u_int8_t hdrtype; 308 int found = 0; 309 int pcifunchigh; 310 int found824xx = 0; 311 int found_orion = 0; 312 device_t child; 313 devclass_t pci_devclass; 314 315 if (pci_cfgregopen() == 0) 316 return; 317 /* 318 * Check to see if we haven't already had a PCI bus added 319 * via some other means. If we have, bail since otherwise 320 * we're going to end up duplicating it. 321 */ 322 if ((pci_devclass = devclass_find("pci")) && 323 devclass_get_device(pci_devclass, 0)) 324 return; 325 326 327 bus = 0; 328 retry: 329 for (slot = 0; slot <= PCI_SLOTMAX; slot++) { 330 func = 0; 331 hdrtype = legacy_pcib_read_config(0, bus, slot, func, 332 PCIR_HDRTYPE, 1); 333 /* 334 * When enumerating bus devices, the standard says that 335 * one should check the header type and ignore the slots whose 336 * header types that the software doesn't know about. We use 337 * this to filter out devices. 338 */ 339 if ((hdrtype & PCIM_HDRTYPE) > PCI_MAXHDRTYPE) 340 continue; 341 if ((hdrtype & PCIM_MFDEV) && 342 (!found_orion || hdrtype != 0xff)) 343 pcifunchigh = PCI_FUNCMAX; 344 else 345 pcifunchigh = 0; 346 for (func = 0; func <= pcifunchigh; func++) { 347 /* 348 * Read the IDs and class from the device. 349 */ 350 u_int32_t id; 351 u_int8_t class, subclass, busnum; 352 const char *s; 353 device_t *devs; 354 int ndevs, i; 355 356 id = legacy_pcib_read_config(0, bus, slot, func, 357 PCIR_DEVVENDOR, 4); 358 if (id == -1) 359 continue; 360 class = legacy_pcib_read_config(0, bus, slot, func, 361 PCIR_CLASS, 1); 362 subclass = legacy_pcib_read_config(0, bus, slot, func, 363 PCIR_SUBCLASS, 1); 364 365 s = legacy_pcib_is_host_bridge(bus, slot, func, 366 id, class, subclass, 367 &busnum); 368 if (s == NULL) 369 continue; 370 371 /* 372 * Check to see if the physical bus has already 373 * been seen. Eg: hybrid 32 and 64 bit host 374 * bridges to the same logical bus. 375 */ 376 if (device_get_children(parent, &devs, &ndevs) == 0) { 377 for (i = 0; s != NULL && i < ndevs; i++) { 378 if (strcmp(device_get_name(devs[i]), 379 "pcib") != 0) 380 continue; 381 if (legacy_get_pcibus(devs[i]) == busnum) 382 s = NULL; 383 } 384 free(devs, M_TEMP); 385 } 386 387 if (s == NULL) 388 continue; 389 /* 390 * Add at priority 100 to make sure we 391 * go after any motherboard resources 392 */ 393 child = BUS_ADD_CHILD(parent, 100, 394 "pcib", busnum); 395 device_set_desc(child, s); 396 legacy_set_pcibus(child, busnum); 397 398 found = 1; 399 if (id == 0x12258086) 400 found824xx = 1; 401 if (id == 0x84c48086) 402 found_orion = 1; 403 } 404 } 405 if (found824xx && bus == 0) { 406 bus++; 407 goto retry; 408 } 409 410 /* 411 * Make sure we add at least one bridge since some old 412 * hardware doesn't actually have a host-pci bridge device. 413 * Note that pci_cfgregopen() thinks we have PCI devices.. 414 */ 415 if (!found) { 416 if (bootverbose) 417 printf( 418 "legacy_pcib_identify: no bridge found, adding pcib0 anyway\n"); 419 child = BUS_ADD_CHILD(parent, 100, "pcib", 0); 420 legacy_set_pcibus(child, 0); 421 } 422} 423 424static int 425legacy_pcib_probe(device_t dev) 426{ 427 428 if (pci_cfgregopen() == 0) 429 return ENXIO; 430 return -100; 431} 432 433static int 434legacy_pcib_attach(device_t dev) 435{ 436 device_t pir; 437 int bus; 438 439 /* 440 * Look for a PCI BIOS interrupt routing table as that will be 441 * our method of routing interrupts if we have one. 442 */ 443 bus = pcib_get_bus(dev); 444 if (pci_pir_probe(bus, 0)) { 445 pir = BUS_ADD_CHILD(device_get_parent(dev), 0, "pir", 0); 446 if (pir != NULL) 447 device_probe_and_attach(pir); 448 } 449 device_add_child(dev, "pci", bus); 450 return bus_generic_attach(dev); 451} 452 453int 454legacy_pcib_read_ivar(device_t dev, device_t child, int which, 455 uintptr_t *result) 456{ 457 458 switch (which) { 459 case PCIB_IVAR_BUS: 460 *result = legacy_get_pcibus(dev); 461 return 0; 462 } 463 return ENOENT; 464} 465 466int 467legacy_pcib_write_ivar(device_t dev, device_t child, int which, 468 uintptr_t value) 469{ 470 471 switch (which) { 472 case PCIB_IVAR_BUS: 473 legacy_set_pcibus(dev, value); 474 return 0; 475 } 476 return ENOENT; 477} 478 479SYSCTL_DECL(_hw_pci); 480 481static unsigned long legacy_host_mem_start = 0x80000000; 482TUNABLE_ULONG("hw.pci.host_mem_start", &legacy_host_mem_start); 483SYSCTL_ULONG(_hw_pci, OID_AUTO, host_mem_start, CTLFLAG_RDTUN, 484 &legacy_host_mem_start, 0x80000000, 485 "Limit the host bridge memory to being above this address. Must be\n\ 486set at boot via a tunable."); 487 488struct resource * 489legacy_pcib_alloc_resource(device_t dev, device_t child, int type, int *rid, 490 u_long start, u_long end, u_long count, u_int flags) 491{ 492 /* 493 * If no memory preference is given, use upper 32MB slot most 494 * bioses use for their memory window. Typically other bridges 495 * before us get in the way to assert their preferences on memory. 496 * Hardcoding like this sucks, so a more MD/MI way needs to be 497 * found to do it. This is typically only used on older laptops 498 * that don't have pci busses behind pci bridge, so assuming > 32MB 499 * is liekly OK. 500 * 501 * However, this can cause problems for other chipsets, so we make 502 * this tunable by hw.pci.host_mem_start. 503 */ 504 if (type == SYS_RES_MEMORY && start == 0UL && end == ~0UL) 505 start = legacy_host_mem_start; 506 if (type == SYS_RES_IOPORT && start == 0UL && end == ~0UL) 507 start = 0x1000; 508 return (bus_generic_alloc_resource(dev, child, type, rid, start, end, 509 count, flags)); 510} 511 512static device_method_t legacy_pcib_methods[] = { 513 /* Device interface */ 514 DEVMETHOD(device_identify, legacy_pcib_identify), 515 DEVMETHOD(device_probe, legacy_pcib_probe), 516 DEVMETHOD(device_attach, legacy_pcib_attach), 517 DEVMETHOD(device_shutdown, bus_generic_shutdown), 518 DEVMETHOD(device_suspend, bus_generic_suspend), 519 DEVMETHOD(device_resume, bus_generic_resume), 520 521 /* Bus interface */ 522 DEVMETHOD(bus_print_child, bus_generic_print_child), 523 DEVMETHOD(bus_read_ivar, legacy_pcib_read_ivar), 524 DEVMETHOD(bus_write_ivar, legacy_pcib_write_ivar), 525 DEVMETHOD(bus_alloc_resource, legacy_pcib_alloc_resource), 526 DEVMETHOD(bus_release_resource, bus_generic_release_resource), 527 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), 528 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 529 DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), 530 DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), 531 532 /* pcib interface */ 533 DEVMETHOD(pcib_maxslots, legacy_pcib_maxslots), 534 DEVMETHOD(pcib_read_config, legacy_pcib_read_config), 535 DEVMETHOD(pcib_write_config, legacy_pcib_write_config), 536 DEVMETHOD(pcib_route_interrupt, pcibios_pcib_route_interrupt), 537 538 { 0, 0 } 539}; 540
|
592DRIVER_MODULE(pcibus_pnp, isa, pcibus_pnp_driver, pcibus_pnp_devclass, 0, 0); 593 594 595/* 596 * Provide a PCI-PCI bridge driver for PCI busses behind PCI-PCI bridges 597 * that appear in the PCIBIOS Interrupt Routing Table to use the routing 598 * table for interrupt routing when possible. 599 */ 600static int pcibios_pcib_probe(device_t bus); 601 602static device_method_t pcibios_pcib_pci_methods[] = { 603 /* Device interface */ 604 DEVMETHOD(device_probe, pcibios_pcib_probe), 605 DEVMETHOD(device_attach, pcib_attach), 606 DEVMETHOD(device_shutdown, bus_generic_shutdown), 607 DEVMETHOD(device_suspend, bus_generic_suspend), 608 DEVMETHOD(device_resume, bus_generic_resume), 609 610 /* Bus interface */ 611 DEVMETHOD(bus_print_child, bus_generic_print_child), 612 DEVMETHOD(bus_read_ivar, pcib_read_ivar), 613 DEVMETHOD(bus_write_ivar, pcib_write_ivar), 614 DEVMETHOD(bus_alloc_resource, pcib_alloc_resource), 615 DEVMETHOD(bus_release_resource, bus_generic_release_resource), 616 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), 617 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 618 DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), 619 DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), 620 621 /* pcib interface */ 622 DEVMETHOD(pcib_maxslots, pcib_maxslots), 623 DEVMETHOD(pcib_read_config, pcib_read_config), 624 DEVMETHOD(pcib_write_config, pcib_write_config), 625 DEVMETHOD(pcib_route_interrupt, pcibios_pcib_route_interrupt), 626 627 {0, 0} 628}; 629
|