44#include <sys/kernel.h>
46#include <sys/malloc.h>
47#include <sys/module.h>
51#include <sys/sysctl.h>
53#include <sys/taskqueue.h>
80static void pcib_pcie_ab_timeout(
void *arg,
int pending);
81static void pcib_pcie_cc_timeout(
void *arg,
int pending);
82static void pcib_pcie_dll_timeout(
void *arg,
int pending);
93 DEVMETHOD(device_shutdown, bus_generic_shutdown),
103 DEVMETHOD(bus_adjust_resource, pcib_adjust_resource),
104 DEVMETHOD(bus_release_resource, pcib_release_resource),
106 DEVMETHOD(bus_adjust_resource, bus_generic_adjust_resource),
107 DEVMETHOD(bus_release_resource, bus_generic_release_resource),
109 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
110 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
111 DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
112 DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
142#if defined(NEW_PCIB) || defined(PCI_HP)
147static int pci_clear_pcib;
148SYSCTL_INT(_hw_pci, OID_AUTO, clear_pcib, CTLFLAG_RDTUN, &pci_clear_pcib, 0,
149 "Clear firmware-assigned resources for PCI-PCI bridge I/O windows.");
155static struct pcib_window *
156pcib_get_resource_window(
struct pcib_softc *sc,
int type,
struct resource *r)
160 if (rman_is_region_manager(r, &sc->io.rman))
165 if (rman_get_flags(r) & RF_PREFETCHABLE &&
166 rman_is_region_manager(r, &sc->pmem.rman))
168 if (rman_is_region_manager(r, &sc->mem.rman))
180pcib_is_resource_managed(
struct pcib_softc *sc,
int type,
struct resource *r)
184 if (
type == PCI_RES_BUS)
185 return (rman_is_region_manager(r, &sc->
bus.rman));
187 return (pcib_get_resource_window(sc,
type, r) != NULL);
191pcib_is_window_open(
struct pcib_window *pw)
194 return (pw->valid && pw->base < pw->limit);
207 PCI_ENABLE_IO(device_get_parent(sc->
dev), sc->
dev,
type);
211pcib_write_windows(
struct pcib_softc *sc,
int mask)
217 if (sc->io.valid && mask & WIN_IO) {
221 sc->io.base >> 16, 2);
223 sc->io.limit >> 16, 2);
229 if (mask & WIN_MEM) {
234 if (sc->pmem.valid && mask & WIN_PMEM) {
238 sc->pmem.base >> 32, 4);
240 sc->pmem.limit >> 32, 4);
252pcib_is_isa_range(
struct pcib_softc *sc, rman_res_t
start, rman_res_t end,
255 rman_res_t next_alias;
277 if ((
start & 0x300) != 0)
279 next_alias = (
start & ~0x3fful) | 0x100;
280 if (next_alias <= end)
286 device_printf(sc->
dev,
287 "I/O range %#jx-%#jx overlaps with an ISA alias\n",
start,
293pcib_add_window_resources(
struct pcib_window *w,
struct resource **res,
296 struct resource **newarray;
299 newarray = malloc(
sizeof(
struct resource *) * (w->count +
count),
302 bcopy(w->res, newarray,
sizeof(
struct resource *) * w->count);
303 bcopy(res, newarray + w->count,
sizeof(
struct resource *) *
count);
304 free(w->res, M_DEVBUF);
308 for (i = 0; i <
count; i++) {
309 error = rman_manage_region(&w->rman, rman_get_start(res[i]),
310 rman_get_end(res[i]));
312 panic(
"Failed to add resource to rman");
316typedef void (nonisa_callback)(rman_res_t
start, rman_res_t end,
void *arg);
319pcib_walk_nonisa_ranges(rman_res_t
start, rman_res_t end, nonisa_callback *cb,
331 if (
start <= 65535) {
339 while (
start <= MIN(end, 65535)) {
340 next_end = MIN(
start | 0xff, end);
341 cb(
start, next_end, arg);
350count_ranges(rman_res_t
start, rman_res_t end,
void *arg)
359 struct resource **res;
365alloc_ranges(rman_res_t
start, rman_res_t end,
void *arg)
367 struct alloc_state *as;
368 struct pcib_window *w;
378 device_printf(as->sc->dev,
379 "allocating non-ISA range %#jx-%#jx\n",
start, end);
380 as->res[as->count] = bus_alloc_resource(as->sc->dev, SYS_RES_IOPORT,
382 if (as->res[as->count] == NULL)
389pcib_alloc_nonisa_ranges(
struct pcib_softc *sc, rman_res_t
start, rman_res_t end)
391 struct alloc_state as;
396 pcib_walk_nonisa_ranges(
start, end, count_ranges, &new_count);
399 as.res = malloc(
sizeof(
struct resource *) * new_count, M_DEVBUF,
404 pcib_walk_nonisa_ranges(
start, end, alloc_ranges, &as);
406 for (i = 0; i < as.count; i++)
407 bus_release_resource(sc->
dev, SYS_RES_IOPORT,
408 sc->io.reg, as.res[i]);
409 free(as.res, M_DEVBUF);
412 KASSERT(as.count == new_count, (
"%s: count mismatch", __func__));
415 pcib_add_window_resources(&sc->io, as.res, as.count);
416 free(as.res, M_DEVBUF);
421pcib_alloc_window(
struct pcib_softc *sc,
struct pcib_window *w,
int type,
424 struct resource *res;
428 if (max_address != (rman_res_t)max_address)
430 w->rman.rm_start = 0;
431 w->rman.rm_end = max_address;
432 w->rman.rm_type = RMAN_ARRAY;
433 snprintf(buf,
sizeof(buf),
"%s %s window",
434 device_get_nameunit(sc->
dev), w->name);
435 w->rman.rm_descr = strdup(buf, M_DEVBUF);
436 error = rman_init(&w->rman);
438 panic(
"Failed to initialize %s %s rman",
439 device_get_nameunit(sc->
dev), w->name);
441 if (!pcib_is_window_open(w))
444 if (w->base > max_address || w->limit > max_address) {
445 device_printf(sc->
dev,
446 "initial %s window has too many bits, ignoring\n", w->name);
450 (void)pcib_alloc_nonisa_ranges(sc, w->base, w->limit);
453 res = bus_alloc_resource(sc->
dev,
type, &
rid, w->base, w->limit,
454 w->limit - w->base + 1, flags);
456 pcib_add_window_resources(w, &res, 1);
458 if (w->res == NULL) {
459 device_printf(sc->
dev,
460 "failed to allocate initial %s window: %#jx-%#jx\n",
461 w->name, (uintmax_t)w->base, (uintmax_t)w->limit);
462 w->base = max_address;
464 pcib_write_windows(sc, w->mask);
467 pcib_activate_window(sc,
type);
482 if (pci_clear_pcib) {
505 sc->io.mask = WIN_IO;
506 sc->io.name =
"I/O port";
520 pcib_alloc_window(sc, &sc->io, SYS_RES_IOPORT, 0, max);
527 sc->mem.mask = WIN_MEM;
528 sc->mem.name =
"memory";
533 pcib_alloc_window(sc, &sc->mem, SYS_RES_MEMORY, 0, 0xffffffff);
551 if (sc->pmem.valid) {
554 sc->pmem.mask = WIN_PMEM;
555 sc->pmem.name =
"prefetch";
562 max = 0xffffffffffffffff;
569 pcib_alloc_window(sc, &sc->pmem, SYS_RES_MEMORY,
570 RF_PREFETCHABLE, max);
575pcib_release_window(
struct pcib_softc *sc,
struct pcib_window *w,
int type)
584 error = rman_fini(&w->rman);
586 device_printf(
dev,
"failed to release %s rman\n", w->name);
589 free(__DECONST(
char *, w->rman.rm_descr), M_DEVBUF);
591 for (i = 0; i < w->count; i++) {
592 error = bus_free_resource(
dev,
type, w->res[i]);
595 "failed to release %s resource: %d\n", w->name,
598 free(w->res, M_DEVBUF);
605 pcib_release_window(sc, &sc->pmem, SYS_RES_MEMORY);
606 pcib_release_window(sc, &sc->mem, SYS_RES_MEMORY);
607 pcib_release_window(sc, &sc->io, SYS_RES_IOPORT);
621 int error,
rid, sec_reg;
633 panic(
"not a PCI bridge");
635 bus->sec = pci_read_config(
dev, sec_reg, 1);
636 bus->sub = pci_read_config(
dev,
bus->sub_reg, 1);
638 bus->rman.rm_start = 0;
640 bus->rman.rm_type = RMAN_ARRAY;
641 snprintf(buf,
sizeof(buf),
"%s bus numbers", device_get_nameunit(
dev));
642 bus->rman.rm_descr = strdup(buf, M_DEVBUF);
643 error = rman_init(&
bus->rman);
645 panic(
"Failed to initialize %s bus number rman",
646 device_get_nameunit(
dev));
653 bus->res = bus_alloc_resource_anywhere(
dev, PCI_RES_BUS, &
rid,
655 if (
bus->res == NULL) {
660 bus->res = bus_alloc_resource_anywhere(
dev, PCI_RES_BUS, &
rid,
662 }
else if (rman_get_size(
bus->res) < min_count)
667 (void)bus_adjust_resource(
dev, PCI_RES_BUS,
bus->res,
668 rman_get_start(
bus->res), rman_get_start(
bus->res) +
674 if (
bus->res != NULL) {
675 error = rman_manage_region(&
bus->rman, rman_get_start(
bus->res),
676 rman_get_end(
bus->res));
678 panic(
"Failed to add resource to rman");
679 bus->sec = rman_get_start(
bus->res);
680 bus->sub = rman_get_end(
bus->res);
689 error = rman_fini(&
bus->rman);
691 device_printf(
dev,
"failed to release bus number rman\n");
694 free(__DECONST(
char *,
bus->rman.rm_descr), M_DEVBUF);
696 error = bus_free_resource(
dev, PCI_RES_BUS,
bus->res);
699 "failed to release bus numbers resource: %d\n", error);
702static struct resource *
704 rman_res_t
start, rman_res_t end, rman_res_t
count, u_int flags)
706 struct resource *res;
708 res = rman_reserve_resource(&
bus->rman,
start, end,
count, flags,
714 device_printf(
bus->dev,
715 "allocated bus range (%ju-%ju) for rid %d of %s\n",
716 rman_get_start(res), rman_get_end(res), *
rid,
717 pcib_child_name(
child));
718 rman_set_rid(res, *
rid);
733 old_end = rman_get_end(
bus->res);
734 KASSERT(new_end > old_end, (
"attempt to shrink subbus"));
735 error = bus_adjust_resource(
bus->dev, PCI_RES_BUS,
bus->res,
736 rman_get_start(
bus->res), new_end);
740 device_printf(
bus->dev,
"grew bus range to %ju-%ju\n",
741 rman_get_start(
bus->res), rman_get_end(
bus->res));
742 error = rman_manage_region(&
bus->rman, old_end + 1,
743 rman_get_end(
bus->res));
745 panic(
"Failed to add resource to rman");
746 bus->sub = rman_get_end(
bus->res);
747 pci_write_config(
bus->dev,
bus->sub_reg,
bus->sub, 1);
753 rman_res_t
start, rman_res_t end, rman_res_t
count, u_int flags)
755 struct resource *res;
756 rman_res_t start_free, end_free, new_end;
771 if (rman_last_free_region(&
bus->rman, &start_free, &end_free) != 0 ||
772 end_free !=
bus->sub)
773 start_free =
bus->sub + 1;
774 if (start_free <
start)
776 new_end = start_free +
count - 1;
787 device_printf(
bus->dev,
788 "attempting to grow bus range for %ju buses\n",
count);
789 printf(
"\tback candidate range: %ju-%ju\n", start_free,
792 if (pcib_grow_subbus(
bus, new_end) == 0)
937static int pci_enable_pcie_hp = 1;
938SYSCTL_INT(_hw_pci, OID_AUTO, enable_pcie_hp, CTLFLAG_RDTUN,
939 &pci_enable_pcie_hp, 0,
940 "Enable support for native PCI-express HotPlug.");
942TASKQUEUE_DEFINE_THREAD(pci_hp);
949 uint16_t link_sta, slot_sta;
951 if (!pci_enable_pcie_hp)
993 device_printf(
dev,
"Unable to activate hot plug feature.\n");
1009pcib_pcie_hotplug_command(
struct pcib_softc *sc, uint16_t
val, uint16_t mask)
1020 new = (ctl & ~mask) |
val;
1024 device_printf(
dev,
"HotPlug command: %04x -> %04x\n", ctl,
new);
1030 taskqueue_enqueue_timeout(taskqueue_pci_hp,
1036pcib_pcie_hotplug_command_completed(
struct pcib_softc *sc)
1043 device_printf(
dev,
"Command Completed\n");
1046 taskqueue_cancel_timeout(taskqueue_pci_hp, &sc->
pcie_cc_task, NULL);
1047 sc->
flags &= ~PCIB_HOTPLUG_CMD_PENDING;
1089 if (!pcib_hotplug_inserted(sc))
1100pcib_pcie_hotplug_update(
struct pcib_softc *sc, uint16_t
val, uint16_t mask,
1103 bool card_inserted, ei_engaged;
1108 sc->
flags &= ~PCIB_DETACHING;
1110 card_inserted = pcib_hotplug_inserted(sc);
1141 if (card_inserted != ei_engaged)
1151 if (card_inserted &&
1156 device_printf(sc->
dev,
1157 "Data Link Layer inactive\n");
1159 taskqueue_enqueue_timeout(taskqueue_pci_hp,
1162 taskqueue_cancel_timeout(taskqueue_pci_hp, &sc->
pcie_dll_task,
1165 pcib_pcie_hotplug_command(sc,
val, mask);
1172 if (schedule_task &&
1173 (pcib_hotplug_present(sc) != 0) != (sc->
child != NULL))
1174 taskqueue_enqueue(taskqueue_pci_hp, &sc->
pcie_hp_task);
1178pcib_pcie_intr_hotplug(
void *arg)
1182 uint16_t old_slot_sta;
1194 device_printf(
dev,
"HotPlug interrupt: %#x\n",
1200 "Attention Button Pressed: Detach Cancelled\n");
1201 sc->
flags &= ~PCIB_DETACH_PENDING;
1202 taskqueue_cancel_timeout(taskqueue_pci_hp,
1207 "Attention Button Pressed: Detaching in 5 seconds\n");
1209 taskqueue_enqueue_timeout(taskqueue_pci_hp,
1214 device_printf(
dev,
"Power Fault Detected\n");
1216 device_printf(
dev,
"MRL Sensor Changed to %s\n",
1220 device_printf(
dev,
"Presence Detect Changed to %s\n",
1224 pcib_pcie_hotplug_command_completed(sc);
1229 "Data Link Layer State Changed to %s\n",
1231 "active" :
"inactive");
1234 pcib_pcie_hotplug_update(sc, 0, 0,
true);
1239pcib_pcie_hotplug_task(
void *context,
int pending)
1247 if (pcib_hotplug_present(sc) != 0) {
1248 if (sc->
child == NULL) {
1249 sc->
child = device_add_child(
dev,
"pci", -1);
1250 bus_generic_attach(
dev);
1253 if (sc->
child != NULL) {
1254 if (device_delete_child(
dev, sc->
child) == 0)
1262pcib_pcie_ab_timeout(
void *arg,
int pending)
1269 sc->
flags &= ~PCIB_DETACH_PENDING;
1270 pcib_pcie_hotplug_update(sc, 0, 0,
true);
1276pcib_pcie_cc_timeout(
void *arg,
int pending)
1285 device_printf(
dev,
"HotPlug Command Timed Out\n");
1286 sc->
flags &= ~PCIB_HOTPLUG_CMD_PENDING;
1289 "Missed HotPlug interrupt waiting for Command Completion\n");
1290 pcib_pcie_intr_hotplug(sc);
1296pcib_pcie_dll_timeout(
void *arg,
int pending)
1306 "Timed out waiting for Data Link Layer Active\n");
1308 pcib_pcie_hotplug_update(sc, 0, 0,
true);
1311 "Missed HotPlug interrupt waiting for DLL Active\n");
1312 pcib_pcie_intr_hotplug(sc);
1333 error = pci_alloc_msix(
dev, &
count);
1338 if (
rid < 0 && pci_msi_count(
dev) > 0) {
1340 error = pci_alloc_msi(
dev, &
count);
1349 RF_ACTIVE | RF_SHAREABLE);
1352 "Failed to allocate interrupt for PCI-e events\n");
1354 pci_release_msi(
dev);
1358 error = bus_setup_intr(
dev, sc->
pcie_irq, INTR_TYPE_MISC|INTR_MPSAFE,
1359 NULL, pcib_pcie_intr_hotplug, sc, &sc->
pcie_ihand);
1361 device_printf(
dev,
"Failed to setup PCI-e interrupt handler\n");
1364 pci_release_msi(
dev);
1380 error = bus_free_resource(
dev, SYS_RES_IRQ, sc->
pcie_irq);
1383 return (pci_release_msi(
dev));
1393 TASK_INIT(&sc->
pcie_hp_task, 0, pcib_pcie_hotplug_task, sc);
1394 TIMEOUT_TASK_INIT(taskqueue_pci_hp, &sc->
pcie_ab_task, 0,
1395 pcib_pcie_ab_timeout, sc);
1396 TIMEOUT_TASK_INIT(taskqueue_pci_hp, &sc->
pcie_cc_task, 0,
1397 pcib_pcie_cc_timeout, sc);
1399 pcib_pcie_dll_timeout, sc);
1403 if (pcib_alloc_pcie_irq(sc) != 0)
1432 pcib_pcie_hotplug_update(sc,
val, mask,
false);
1443 sc->
flags &= ~PCIB_DETACH_PENDING;
1444 taskqueue_cancel_timeout(taskqueue_pci_hp, &sc->
pcie_ab_task,
1450 taskqueue_cancel_timeout(taskqueue_pci_hp, &sc->
pcie_cc_task,
1452 tsleep(sc, 0,
"hpcmd", hz);
1453 sc->
flags &= ~PCIB_HOTPLUG_CMD_PENDING;
1468 pcib_pcie_hotplug_update(sc,
val, mask,
false);
1470 error = pcib_release_pcie_irq(sc);
1474 taskqueue_drain_timeout(taskqueue_pci_hp, &sc->
pcie_ab_task);
1475 taskqueue_drain_timeout(taskqueue_pci_hp, &sc->
pcie_cc_task);
1476 taskqueue_drain_timeout(taskqueue_pci_hp, &sc->
pcie_dll_task);
1512 pcib_write_windows(sc, WIN_IO | WIN_MEM | WIN_PMEM);
1530 device_set_desc(
dev,
"PCI-PCI bridge");
1540 struct sysctl_ctx_list *sctx;
1541 struct sysctl_oid *soid;
1544 sc = device_get_softc(
dev);
1551#if !(defined(NEW_PCIB) && defined(PCI_RES_BUS))
1568 sctx = device_get_sysctl_ctx(
dev);
1569 soid = device_get_sysctl_tree(
dev);
1570 SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO,
"domain",
1571 CTLFLAG_RD, &sc->
domain, 0,
"Domain number");
1572 SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO,
"pribus",
1573 CTLFLAG_RD, &sc->
pribus, 0,
"Primary bus number");
1574 SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO,
"secbus",
1575 CTLFLAG_RD, &sc->
bus.
sec, 0,
"Secondary bus number");
1576 SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO,
"subbus",
1577 CTLFLAG_RD, &sc->
bus.
sub, 0,
"Subordinate bus number");
1582 switch (pci_get_devid(
dev)) {
1583#if !(defined(NEW_PCIB) && defined(PCI_RES_BUS))
1588 supbus = pci_read_config(
dev, 0x41, 1);
1589 if (supbus != 0xff) {
1590 sc->
bus.
sec = supbus + 1;
1591 sc->
bus.
sub = supbus + 1;
1610#if !(defined(NEW_PCIB) && defined(PCI_RES_BUS))
1616 if ((cp = kern_getenv(
"smbios.planar.maker")) == NULL)
1618 if (strncmp(cp,
"Compal", 6) != 0) {
1623 if ((cp = kern_getenv(
"smbios.planar.product")) == NULL)
1625 if (strncmp(cp,
"08A0", 4) != 0) {
1653 if ((pci_get_devid(
dev) & 0xff00ffff) == 0x24008086 ||
1658 pcib_probe_hotplug(sc);
1662 pcib_setup_secbus(
dev, &sc->
bus, 1);
1664 pcib_probe_windows(sc);
1668 pcib_setup_hotplug(sc);
1671 device_printf(
dev,
" domain %d\n", sc->
domain);
1672 device_printf(
dev,
" secondary bus %d\n", sc->
bus.
sec);
1673 device_printf(
dev,
" subordinate bus %d\n", sc->
bus.
sub);
1675 if (pcib_is_window_open(&sc->io))
1676 device_printf(
dev,
" I/O decode 0x%jx-0x%jx\n",
1677 (uintmax_t)sc->io.base, (uintmax_t)sc->io.limit);
1678 if (pcib_is_window_open(&sc->mem))
1679 device_printf(
dev,
" memory decode 0x%jx-0x%jx\n",
1680 (uintmax_t)sc->mem.base, (uintmax_t)sc->mem.limit);
1681 if (pcib_is_window_open(&sc->pmem))
1682 device_printf(
dev,
" prefetched decode 0x%jx-0x%jx\n",
1683 (uintmax_t)sc->pmem.base, (uintmax_t)sc->pmem.limit);
1686 device_printf(
dev,
" I/O decode 0x%x-0x%x\n",
1689 device_printf(
dev,
" memory decode 0x%jx-0x%jx\n",
1692 device_printf(
dev,
" prefetched decode 0x%jx-0x%jx\n",
1697 device_printf(
dev,
" special decode ");
1704 printf(
"%sVGA", comma ?
", " :
"");
1708 printf(
"%ssubtractive", comma ?
", " :
"");
1718 pci_enable_busmaster(
dev);
1727 return (pcib_hotplug_present(sc) != 0);
1737 sc = device_get_softc(
dev);
1744 if (!pcib_present(sc)) {
1750 sc->
child = device_add_child(
dev,
"pci", -1);
1751 return (bus_generic_attach(
dev));
1765#if defined(PCI_HP) || defined(NEW_PCIB)
1770#if defined(PCI_HP) || defined(NEW_PCIB)
1771 sc = device_get_softc(
dev);
1773 error = bus_generic_detach(
dev);
1778 error = pcib_detach_hotplug(sc);
1783 error = device_delete_children(
dev);
1787 pcib_free_windows(sc);
1789 pcib_free_secbus(
dev, &sc->
bus);
1800 return (bus_generic_suspend(
dev));
1814 return (bus_generic_resume(
dev));
1839 retval = bus_child_present(
dev);
1841 retval = pcib_hotplug_present(sc);
1844 return (bus_child_present(
dev));
1854 case PCIB_IVAR_DOMAIN:
1869 case PCIB_IVAR_DOMAIN:
1882static struct resource *
1883pcib_suballoc_resource(
struct pcib_softc *sc,
struct pcib_window *w,
1885 rman_res_t
count, u_int flags)
1887 struct resource *res;
1889 if (!pcib_is_window_open(w))
1892 res = rman_reserve_resource(&w->rman,
start, end,
count,
1893 flags & ~RF_ACTIVE,
child);
1898 device_printf(sc->
dev,
1899 "allocated %s range (%#jx-%#jx) for rid %x of %s\n",
1900 w->name, rman_get_start(res), rman_get_end(res), *
rid,
1901 pcib_child_name(
child));
1902 rman_set_rid(res, *
rid);
1909 if (flags & RF_ACTIVE) {
1910 if (bus_activate_resource(
child,
type, *
rid, res) != 0) {
1911 rman_release_resource(res);
1921pcib_alloc_new_window(
struct pcib_softc *sc,
struct pcib_window *w,
int type,
1922 rman_res_t
start, rman_res_t end, rman_res_t
count, u_int flags)
1924 struct resource *res;
1925 rman_res_t base, limit, wmask;
1939 for (base = 0xf000; (long)base >= 0; base -= 0x1000) {
1940 limit = base + 0xfff;
1956 if (end -
count + 1 < 0x400)
1959 if (end -
count + 1 < base)
1963 if (pcib_alloc_nonisa_ranges(sc, base, limit) == 0) {
1972 wmask = ((rman_res_t)1 << w->step) - 1;
1973 if (RF_ALIGNMENT(flags) < w->step) {
1974 flags &= ~RF_ALIGNMENT_MASK;
1975 flags |= RF_ALIGNMENT_LOG2(w->step);
1979 count = roundup2(
count, (rman_res_t)1 << w->step);
1982 flags & ~RF_ACTIVE);
1985 pcib_add_window_resources(w, &res, 1);
1986 pcib_activate_window(sc,
type);
1987 w->base = rman_get_start(res);
1988 w->limit = rman_get_end(res);
1994pcib_expand_window(
struct pcib_softc *sc,
struct pcib_window *w,
int type,
1995 rman_res_t base, rman_res_t limit)
1997 struct resource *res;
1998 int error, i, force_64k_base;
2000 KASSERT(base <= w->base && limit >= w->limit,
2001 (
"attempting to shrink window"));
2007 KASSERT(limit == w->limit || base == w->base,
2008 (
"attempting to grow both ends of a window"));
2019 (limit <= 65535 || (base <= 65535 && base != w->base))) {
2020 KASSERT(limit == w->limit || limit <= 65535,
2021 (
"attempting to grow both ends across 64k ISA alias"));
2023 if (base != w->base)
2024 error = pcib_alloc_nonisa_ranges(sc, base, w->base - 1);
2026 error = pcib_alloc_nonisa_ranges(sc, w->limit + 1,
2041 for (i = 0; i < w->count; i++) {
2042 if (rman_get_end(w->res[i]) == w->limit)
2045 KASSERT(i != w->count, (
"did not find existing resource"));
2056 KASSERT(rman_get_start(res) == 65536,
2057 (
"existing resource mismatch"));
2060 KASSERT(w->base == rman_get_start(res),
2061 (
"existing resource mismatch"));
2065 error = bus_adjust_resource(sc->
dev,
type, res, force_64k_base ?
2066 rman_get_start(res) : base, limit);
2071 if (w->base != base) {
2072 error = rman_manage_region(&w->rman, base, w->base - 1);
2075 error = rman_manage_region(&w->rman, w->limit + 1, limit);
2080 device_printf(sc->
dev,
2081 "failed to expand %s resource manager\n", w->name);
2082 (void)bus_adjust_resource(sc->
dev,
type, res, force_64k_base ?
2083 rman_get_start(res) : w->base, w->limit);
2092pcib_grow_window(
struct pcib_softc *sc,
struct pcib_window *w,
int type,
2093 rman_res_t
start, rman_res_t end, rman_res_t
count, u_int flags)
2095 rman_res_t align, start_free, end_free, front, back, wmask;
2110 if (end > w->rman.rm_end)
2111 end = w->rman.rm_end;
2114 wmask = ((rman_res_t)1 << w->step) - 1;
2120 if (w->res == NULL) {
2125 device_printf(sc->
dev,
2126 "failed to allocate initial %s window (%#jx-%#jx,%#jx)\n",
2131 device_printf(sc->
dev,
2132 "allocated initial %s window of %#jx-%#jx\n",
2133 w->name, (uintmax_t)w->base, (uintmax_t)w->limit);
2157 device_printf(sc->
dev,
2158 "attempting to grow %s window for (%#jx-%#jx,%#jx)\n",
2160 align = (rman_res_t)1 << RF_ALIGNMENT(flags);
2161 if (start < w->base) {
2162 if (rman_first_free_region(&w->rman, &start_free, &end_free) !=
2163 0 || start_free != w->base)
2169 end_free &= ~(align - 1);
2171 front = end_free - (
count - 1);
2180 if (front >=
start && front <= end_free) {
2182 printf(
"\tfront candidate range: %#jx-%#jx\n",
2185 front = w->base - front;
2190 if (end > w->limit) {
2191 if (rman_last_free_region(&w->rman, &start_free, &end_free) !=
2192 0 || end_free != w->limit)
2193 start_free = w->limit + 1;
2194 if (start_free <
start)
2198 start_free = roundup2(start_free, align);
2199 back = start_free +
count - 1;
2208 if (back <= end && start_free <= back) {
2210 printf(
"\tback candidate range: %#jx-%#jx\n",
2224 while (front != 0 || back != 0) {
2225 if (front != 0 && (front <= back || back == 0)) {
2226 error = pcib_expand_window(sc, w,
type, w->base - front,
2232 error = pcib_expand_window(sc, w,
type, w->base,
2243 device_printf(sc->
dev,
"grew %s window to %#jx-%#jx\n",
2244 w->name, (uintmax_t)w->base, (uintmax_t)w->limit);
2248 KASSERT((w->base & wmask) == 0, (
"start address is not aligned"));
2249 KASSERT((w->limit & wmask) == wmask, (
"end address is not aligned"));
2250 pcib_write_windows(sc, w->mask);
2260 rman_res_t
start, rman_res_t end, rman_res_t
count, u_int flags)
2265 sc = device_get_softc(
dev);
2272 if ((
type == SYS_RES_IOPORT && pci_is_vga_ioport_range(
start, end)) ||
2273 (
type == SYS_RES_MEMORY && pci_is_vga_memory_range(
start, end))) {
2287 case SYS_RES_IOPORT:
2288 if (pcib_is_isa_range(sc,
start, end,
count))
2296 r = pcib_suballoc_resource(sc, &sc->io,
child,
type,
2299 case SYS_RES_MEMORY:
2308 if (flags & RF_PREFETCHABLE) {
2309 r = pcib_suballoc_resource(sc, &sc->pmem,
child,
type,
2314 r = pcib_suballoc_resource(sc, &sc->mem,
child,
type,
rid,
2318 if (flags & RF_PREFETCHABLE) {
2319 if (pcib_grow_window(sc, &sc->pmem,
type,
start, end,
2320 count, flags) == 0) {
2321 r = pcib_suballoc_resource(sc, &sc->pmem,
child,
2328 flags & ~RF_PREFETCHABLE) == 0)
2329 r = pcib_suballoc_resource(sc, &sc->mem,
child,
type,
2348pcib_adjust_resource(device_t
bus, device_t
child,
int type,
struct resource *r,
2349 rman_res_t
start, rman_res_t end)
2352 struct pcib_window *w;
2356 sc = device_get_softc(
bus);
2362 if (!pcib_is_resource_managed(sc,
type, r))
2363 return (bus_generic_adjust_resource(
bus,
child,
type, r,
2367 if (
type == PCI_RES_BUS) {
2376 error = pcib_grow_subbus(&sc->
bus, end);
2387 w = pcib_get_resource_window(sc,
type, r);
2389 (
"%s: no window for resource (%#jx-%#jx) type %d",
2390 __func__, rman_get_start(r), rman_get_end(r),
type));
2396 if (start < w->base || end > w->limit) {
2397 wmask = ((rman_res_t)1 << w->step) - 1;
2398 error = pcib_expand_window(sc, w,
type,
2399 MIN(
start & ~wmask, w->base),
2400 MAX(end | wmask, w->limit));
2404 device_printf(sc->
dev,
2405 "grew %s window to %#jx-%#jx\n",
2406 w->name, (uintmax_t)w->base,
2407 (uintmax_t)w->limit);
2408 pcib_write_windows(sc, w->mask);
2412 return (rman_adjust_resource(r,
start, end));
2422 sc = device_get_softc(
dev);
2423 if (pcib_is_resource_managed(sc,
type, r)) {
2424 if (rman_get_flags(r) & RF_ACTIVE) {
2429 return (rman_release_resource(r));
2440 rman_res_t
start, rman_res_t end, rman_res_t
count, u_int flags)
2443 const char *
name, *suffix;
2456 case SYS_RES_IOPORT:
2466 if (!ok && pci_is_vga_ioport_range(
start, end))
2490 device_printf(
dev,
"ioport: end (%jx) < start (%jx)\n",
2497 device_printf(
dev,
"%s%srequested unsupported I/O "
2498 "range 0x%jx-0x%jx (decoding 0x%x-0x%x)\n",
2504 "%s%srequested I/O range 0x%jx-0x%jx: in range\n",
2508 case SYS_RES_MEMORY:
2519 if (!ok && pci_is_vga_memory_range(
start, end))
2525 if (
flags & RF_PREFETCHABLE) {
2559 device_printf(
dev,
"memory: end (%jx) < start (%jx)\n",
2565 if (!ok && bootverbose)
2567 "%s%srequested unsupported memory range %#jx-%#jx "
2568 "(decoding %#jx-%#jx, %#jx-%#jx)\n",
2575 device_printf(
dev,
"%s%srequested memory range "
2576 "0x%jx-0x%jx: good\n",
2602 sc = device_get_softc(
pcib);
2607 (
"Non-zero slot number with ARI enabled!"));
2631#if !defined(__amd64__) && !defined(__i386__)
2655 sc = device_get_softc(
dev);
2668 sc = device_get_softc(
dev);
2682 sc = device_get_softc(
pcib);
2703 sc = device_get_softc(
dev);
2704 if (!pcib_present(sc)) {
2711 return (0xffffffff);
2716 return(PCIB_READ_CONFIG(device_get_parent(device_get_parent(
dev)), b, s,
2726 sc = device_get_softc(
dev);
2727 if (!pcib_present(sc))
2731 PCIB_WRITE_CONFIG(device_get_parent(device_get_parent(
dev)), b, s, f,
2756 parent_intpin = (pci_get_slot(
dev) + (
pin - 1)) % 4;
2762 bus = device_get_parent(
pcib);
2763 intnum = PCIB_ROUTE_INTERRUPT(device_get_parent(
bus),
pcib, parent_intpin + 1);
2764 if (PCI_INTERRUPT_VALID(intnum) && bootverbose) {
2765 device_printf(
pcib,
"slot %d INT%c is routed to irq %d\n",
2766 pci_get_slot(
dev),
'A' +
pin - 1, intnum);
2780 bus = device_get_parent(
pcib);
2791 bus = device_get_parent(
pcib);
2804 bus = device_get_parent(
pcib);
2805 return (PCIB_ALLOC_MSIX(device_get_parent(
bus),
dev,
irq));
2814 bus = device_get_parent(
pcib);
2815 return (PCIB_RELEASE_MSIX(device_get_parent(
bus),
dev,
irq));
2826 bus = device_get_parent(
pcib);
2841 bus = device_get_parent(
pcib);
2850 sc = device_get_softc(
pcib);
2864 bus_dev = device_get_parent(
pcib);
2865 return (PCIB_GET_ID(device_get_parent(bus_dev),
dev,
type,
id));
2868 sc = device_get_softc(
pcib);
2900 sc = device_get_softc(
pcib);
2920 error = pci_find_extcap(
dev,
PCIZ_ARI, &ari_cap_off);
2928 ari_ver = pci_read_config(
dev, ari_cap_off, 4);
2932 "Unsupported version of ARI (%d) detected\n",
2991 bus = device_get_parent(
pcib);
2992 return (PCIB_REQUEST_FEATURE(device_get_parent(
bus),
dev,
feature));
2998 struct pci_devinfo *pdinfo;
3002 if (
dev == NULL || device_get_parent(
child) !=
dev)
3005 if (device_get_devclass(
child) != devclass_find(
"pci"))
3007 pdinfo = device_get_ivars(
dev);
3008 if (pdinfo->cfg.pcie.pcie_location != 0 &&
3011 error = bus_helper_reset_prepare(
child, flags);
3014 pdinfo->cfg.pcie.pcie_location);
3016 bus_helper_reset_post(
child, flags);
int pcie_link_reset(device_t port, int pcie_location)
uint32_t pcie_read_config(device_t dev, int reg, int width)
int pci_msi_device_blacklisted(device_t dev)
void pcie_write_config(device_t dev, int reg, uint32_t value, int width)
int pci_msix_device_blacklisted(device_t dev)
void pci_ht_map_msi(device_t dev, uint64_t addr)
SYSCTL_INT(_hw_pci, OID_AUTO, enable_io_modes, CTLFLAG_RWTUN, &pci_enable_io_modes, 1, "Enable I/O and memory bits in the config register. Some BIOSes do not" " enable these bits correctly. We'd like to do this all the time, but" " there are some peripherals that this causes problems with.")
static int pcib_ari_maxslots(device_t dev)
static __inline void pcib_xlate_ari(device_t pcib, int bus, int *slot, int *func)
static uint32_t pcib_read_config(device_t dev, u_int b, u_int s, u_int f, u_int reg, int width)
static void pcib_get_io_decode(struct pcib_softc *sc)
EARLY_DRIVER_MODULE(pcib, pci, pcib_driver, pcib_devclass, NULL, NULL, BUS_PASS_BUS)
static void pcib_set_io_decode(struct pcib_softc *sc)
int pcib_maxslots(device_t dev)
static void pcib_set_mem_decode(struct pcib_softc *sc)
void pcib_bridge_init(device_t dev)
static int pcib_is_nonprefetch_open(struct pcib_softc *sc)
void pcib_attach_common(device_t dev)
int pcib_child_present(device_t dev, device_t child)
static void pcib_ari_decode_rid(device_t pcib, uint16_t rid, int *bus, int *slot, int *func)
static int pcib_try_enable_ari(device_t pcib, device_t dev)
int pcib_attach(device_t dev)
static device_method_t pcib_methods[]
int pcib_alloc_msix(device_t pcib, device_t dev, int *irq)
static int pcib_ari_get_id(device_t pcib, device_t dev, enum pci_id_type type, uintptr_t *id)
int pcib_release_msix(device_t pcib, device_t dev, int irq)
DEFINE_CLASS_0(pcib, pcib_driver, pcib_methods, sizeof(struct pcib_softc))
static int pcib_is_prefetch_open(struct pcib_softc *sc)
static void pcib_enable_ari(struct pcib_softc *sc, uint32_t pcie_pos)
int pcib_alloc_msi(device_t pcib, device_t dev, int count, int maxcount, int *irqs)
static int pcib_ari_enabled(device_t pcib)
int pcib_release_msi(device_t pcib, device_t dev, int count, int *irqs)
struct resource * pcib_alloc_resource(device_t dev, device_t child, int type, int *rid, rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
static int pcib_reset_child(device_t dev, device_t child, int flags)
int pcib_route_interrupt(device_t pcib, device_t dev, int pin)
static int pcib_request_feature_default(device_t pcib, device_t dev, enum pci_feature feature)
int pcib_request_feature_allow(device_t pcib, device_t dev, enum pci_feature feature)
static int pcib_power_for_sleep(device_t pcib, device_t dev, int *pstate)
static int pcib_ari_maxfuncs(device_t dev)
static int pcib_probe(device_t dev)
static void pcib_get_mem_decode(struct pcib_softc *sc)
static void pcib_cfg_save(struct pcib_softc *sc)
static void pcib_cfg_restore(struct pcib_softc *sc)
int pcib_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
int pcib_attach_child(device_t dev)
static int pcib_resume(device_t dev)
static int pcib_is_io_open(struct pcib_softc *sc)
int pcib_map_msi(device_t pcib, device_t dev, int irq, uint64_t *addr, uint32_t *data)
static int pcib_suspend(device_t dev)
static void pcib_write_config(device_t dev, u_int b, u_int s, u_int f, u_int reg, uint32_t val, int width)
int pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
int pcib_request_feature(device_t dev, enum pci_feature feature)
int pcib_detach(device_t dev)
static devclass_t pcib_devclass
#define PCIB_DISABLE_MSIX
#define PCIB_HP_UNLOCK(sc)
#define PCIB_SUPPORTED_ARI_VER
#define PCIB_HOTPLUG_CMD_PENDING
#define PCIB_DETACH_PENDING
#define PCI_PPBIOLIMIT(h, l)
#define PCI_RID2FUNC(rid)
#define PCIEM_SLOT_CTL_PI_ON
#define PCIE_ARI_RID2SLOT(rid)
#define PCIEM_SLOT_CAP_MRLSP
#define PCIEM_SLOT_CTL_PCC
#define PCI_PPBIOBASE(h, l)
#define PCIEM_SLOT_CAP_NCCS
#define PCIEM_SLOT_STA_EIS
#define PCIEM_SLOT_CTL_PFDE
#define PCIEM_SLOT_CTL_PDCE
#define PCIEM_SLOT_STA_PFD
#define PCIEM_TYPE_DOWNSTREAM_PORT
#define PCIEM_LINK_STA_DL_ACTIVE
#define PCIEM_SLOT_CTL_MRLSCE
#define PCIER_DEVICE_CTL2
#define PCI_EXTCAP_VER(ecap)
#define PCI_RID(bus, slot, func)
#define PCIEM_SLOT_STA_PDC
#define PCIEM_SLOT_CTL_DLLSCE
#define PCIEM_SLOT_STA_MRLSS
#define PCIEM_SLOT_STA_MRLSC
#define PCIP_BRIDGE_PCI_SUBTRACTIVE
#define PCIEM_SLOT_STA_DLLSC
#define PCIEM_SLOT_CTL_PIC
#define PCIEM_SLOT_CTL_PI_BLINK
#define PCIEM_SLOT_CAP_HPC
#define PCIER_DEVICE_CAP2
#define PCI_PPBMEMLIMIT(h, l)
#define PCIEM_SLOT_CTL_ABPE
#define PCIEM_SLOT_CAP_PIP
#define PCIEM_SLOT_CTL_CCIE
#define PCIEM_SLOT_STA_PDS
#define PCIE_ARI_SLOT(func)
#define PCIEM_SLOT_CTL_AI_OFF
#define PCIEM_SLOT_CTL_EIC
#define PCI_RID2SLOT(rid)
#define PCIEM_SLOT_STA_CC
#define PCIEM_TYPE_ROOT_PORT
#define PCIEM_SLOT_CTL_PC_ON
#define PCIM_HDRTYPE_BRIDGE
#define PCIEM_SLOT_CTL_AIC
#define PCIE_ARI_RID2FUNC(rid)
#define PCIEM_SLOT_CAP_APB
#define PCIEM_SLOT_CTL_PC_OFF
#define PCIB_BCR_ISA_ENABLE
#define PCI_ARI_RID(bus, func)
#define PCIEM_SLOT_STA_ABP
#define PCIM_HDRTYPE_CARDBUS
#define PCI_PPBMEMBASE(h, l)
#define PCIEM_SLOT_CTL_HPIE
#define PCIE_ARI_FUNC(func)
#define PCIB_BCR_VGA_ENABLE
#define PCIEM_SLOT_CAP_EIP
#define PCIEM_LINK_CAP_DL_ACTIVE
#define PCIEM_SLOT_CAP_PCP
#define PCIEM_SLOT_CTL_PI_OFF
#define PCIEM_SLOT_CAP_AIP
struct timeout_task pcie_dll_task
struct resource * pcie_irq
struct mtx * pcie_hp_lock
struct timeout_task pcie_cc_task
struct timeout_task pcie_ab_task