Lines Matching +full:bus +full:- +full:addr
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
151 #define PCI_EMUL_ECFG_SIZE (MAXBUSES * 1024 * 1024) /* 1MB per bus */
163 static void pci_cfgrw(int in, int bus, int slot, int func, int coff,
209 * <bus>:<slot>:<func>,<emul>[,<config>]
214 * emul is a string describing the type of PCI device e.g. virtio-net
218 * 1,virtio-net,tap0
229 * Helper function to parse a list of comma-separated options where
260 * pci.<bus>.<slot>.<func>
262 * Where "bus", "slot", and "func" are all decimal values without
279 error = -1; in pci_parse_slot()
295 /* <bus>:<slot>:<func> */ in pci_parse_slot()
303 snum = -1; in pci_parse_slot()
330 if (pde->pe_alias != NULL) in pci_parse_slot()
331 set_config_value_node(nvl, "device", pde->pe_alias); in pci_parse_slot()
333 set_config_value_node(nvl, "device", pde->pe_emu); in pci_parse_slot()
335 if (pde->pe_legacy_config != NULL) in pci_parse_slot()
336 error = pde->pe_legacy_config(nvl, config); in pci_parse_slot()
351 printf("%s\n", pdp->pe_emu); in pci_print_supported_devices()
386 return (-1); in pci_config_read_reg()
406 if (offset < pi->pi_msix.pba_offset) in pci_valid_pba_offset()
409 if (offset >= pi->pi_msix.pba_offset + pi->pi_msix.pba_size) { in pci_valid_pba_offset()
426 return (-1); in pci_emul_msix_twrite()
432 if (tab_index >= pi->pi_msix.table_count) in pci_emul_msix_twrite()
433 return (-1); in pci_emul_msix_twrite()
439 return (-1); in pci_emul_msix_twrite()
441 dest = (char *)(pi->pi_msix.table + tab_index); in pci_emul_msix_twrite()
461 * The PCI standard only allows 4 and 8 byte accesses to the MSI-X in pci_emul_msix_tread()
477 if (tab_index < pi->pi_msix.table_count) { in pci_emul_msix_tread()
478 /* valid MSI-X Table access */ in pci_emul_msix_tread()
479 dest = (char *)(pi->pi_msix.table + tab_index); in pci_emul_msix_tread()
500 if (pi->pi_msix.table != NULL) in pci_msix_table_bar()
501 return (pi->pi_msix.table_bar); in pci_msix_table_bar()
503 return (-1); in pci_msix_table_bar()
510 if (pi->pi_msix.table != NULL) in pci_msix_pba_bar()
511 return (pi->pi_msix.pba_bar); in pci_msix_pba_bar()
513 return (-1); in pci_msix_pba_bar()
522 struct pci_devemu *pe = pdi->pi_d; in pci_emul_io_handler()
529 if (pdi->pi_bar[i].type == PCIBAR_IO && in pci_emul_io_handler()
530 (uint64_t)port >= pdi->pi_bar[i].addr && in pci_emul_io_handler()
532 pdi->pi_bar[i].addr + pdi->pi_bar[i].size) { in pci_emul_io_handler()
533 offset = port - pdi->pi_bar[i].addr; in pci_emul_io_handler()
535 *eax = (*pe->pe_barread)(pdi, i, in pci_emul_io_handler()
538 (*pe->pe_barwrite)(pdi, i, offset, in pci_emul_io_handler()
543 return (-1); in pci_emul_io_handler()
548 uint64_t addr, int size, uint64_t *val, void *arg1, long arg2) in pci_emul_iomem_handler() argument
551 struct pci_devemu *pe = pdi->pi_d; in pci_emul_iomem_handler()
556 assert(pdi->pi_bar[bidx].type == PCIBAR_IO); in pci_emul_iomem_handler()
557 assert(addr >= pdi->pi_bar[bidx].addr && in pci_emul_iomem_handler()
558 addr + size <= pdi->pi_bar[bidx].addr + pdi->pi_bar[bidx].size); in pci_emul_iomem_handler()
561 offset = addr - pdi->pi_bar[bidx].addr; in pci_emul_iomem_handler()
563 *val = (*pe->pe_barread)(pdi, bidx, offset, size); in pci_emul_iomem_handler()
565 (*pe->pe_barwrite)(pdi, bidx, offset, size, *val); in pci_emul_iomem_handler()
573 uint64_t addr, int size, uint64_t *val, void *arg1, long arg2) in pci_emul_mem_handler() argument
576 struct pci_devemu *pe = pdi->pi_d; in pci_emul_mem_handler()
581 assert(pdi->pi_bar[bidx].type == PCIBAR_MEM32 || in pci_emul_mem_handler()
582 pdi->pi_bar[bidx].type == PCIBAR_MEM64); in pci_emul_mem_handler()
583 assert(addr >= pdi->pi_bar[bidx].addr && in pci_emul_mem_handler()
584 addr + size <= pdi->pi_bar[bidx].addr + pdi->pi_bar[bidx].size); in pci_emul_mem_handler()
586 offset = addr - pdi->pi_bar[bidx].addr; in pci_emul_mem_handler()
590 (*pe->pe_barwrite)(pdi, bidx, offset, in pci_emul_mem_handler()
592 (*pe->pe_barwrite)(pdi, bidx, offset + 4, in pci_emul_mem_handler()
595 (*pe->pe_barwrite)(pdi, bidx, offset, in pci_emul_mem_handler()
600 *val = (*pe->pe_barread)(pdi, bidx, in pci_emul_mem_handler()
602 *val |= (*pe->pe_barread)(pdi, bidx, in pci_emul_mem_handler()
605 *val = (*pe->pe_barread)(pdi, bidx, in pci_emul_mem_handler()
616 uint64_t *addr) in pci_emul_alloc_resource() argument
620 assert((size & (size - 1)) == 0); /* must be a power of 2 */ in pci_emul_alloc_resource()
625 *addr = base; in pci_emul_alloc_resource()
629 return (-1); in pci_emul_alloc_resource()
643 pe = pi->pi_d; in modify_bar_registration()
644 type = pi->pi_bar[idx].type; in modify_bar_registration()
652 iop.name = pi->pi_name; in modify_bar_registration()
653 iop.port = pi->pi_bar[idx].addr; in modify_bar_registration()
654 iop.size = pi->pi_bar[idx].size; in modify_bar_registration()
666 mr.name = pi->pi_name; in modify_bar_registration()
667 mr.base = pi->pi_bar[idx].addr; in modify_bar_registration()
668 mr.size = pi->pi_bar[idx].size; in modify_bar_registration()
686 mr.name = pi->pi_name; in modify_bar_registration()
687 mr.base = pi->pi_bar[idx].addr; in modify_bar_registration()
688 mr.size = pi->pi_bar[idx].size; in modify_bar_registration()
708 if (pe->pe_baraddr != NULL) in modify_bar_registration()
709 (*pe->pe_baraddr)(pi, idx, registration, pi->pi_bar[idx].addr); in modify_bar_registration()
730 return (pi->pi_bar[PCI_ROM_IDX].lobits & PCIM_BIOS_ENABLE) == in romen()
763 update_bar_address(struct pci_devinst *pi, uint64_t addr, int idx, int type) in update_bar_address() argument
767 if (pi->pi_bar[idx].type == PCIBAR_IO) in update_bar_address()
778 pi->pi_bar[idx].addr = addr; in update_bar_address()
781 pi->pi_bar[idx].addr &= ~0xffffffffUL; in update_bar_address()
782 pi->pi_bar[idx].addr |= addr; in update_bar_address()
785 pi->pi_bar[idx].addr &= 0xffffffff; in update_bar_address()
786 pi->pi_bar[idx].addr |= addr; in update_bar_address()
803 if ((size & (size - 1)) != 0) in pci_emul_alloc_bar()
828 new_bar->pdi = pdi; in pci_emul_alloc_bar()
829 new_bar->idx = idx; in pci_emul_alloc_bar()
830 new_bar->type = type; in pci_emul_alloc_bar()
831 new_bar->size = size; in pci_emul_alloc_bar()
839 if (bar->size < size) { in pci_emul_alloc_bar()
896 uint64_t *baseptr, limit, addr, mask, lobits, bar; in pci_emul_assign_bar() local
901 addr = mask = lobits = 0; in pci_emul_assign_bar()
912 * Some drivers do not work well if the 64-bit BAR is allocated in pci_emul_assign_bar()
949 error = pci_emul_alloc_resource(baseptr, limit, size, &addr); in pci_emul_assign_bar()
953 addr = 0; in pci_emul_assign_bar()
956 pdi->pi_bar[idx].type = type; in pci_emul_assign_bar()
957 pdi->pi_bar[idx].addr = addr; in pci_emul_assign_bar()
958 pdi->pi_bar[idx].size = size; in pci_emul_assign_bar()
963 if (pdi->pi_bar[idx].lobits != 0) { in pci_emul_assign_bar()
964 lobits = pdi->pi_bar[idx].lobits; in pci_emul_assign_bar()
966 pdi->pi_bar[idx].lobits = lobits; in pci_emul_assign_bar()
970 bar = (addr & mask) | lobits; in pci_emul_assign_bar()
975 pdi->pi_bar[idx + 1].type = PCIBAR_MEMHI64; in pci_emul_assign_bar()
999 void **const addr) in pci_emul_alloc_rom() argument
1003 pci_emul_rombase = vm_create_devmem(pdi->pi_vmctx, VM_PCIROM, in pci_emul_alloc_rom()
1007 return (-1); in pci_emul_alloc_rom()
1021 PCI_EMUL_ROMSIZE - pci_emul_romoffset); in pci_emul_alloc_rom()
1022 warnx("%16lu bytes required by %d/%d/%d", rom_size, pdi->pi_bus, in pci_emul_alloc_rom()
1023 pdi->pi_slot, pdi->pi_func); in pci_emul_alloc_rom()
1024 return (-1); in pci_emul_alloc_rom()
1034 *addr = pci_emul_rombase + pci_emul_romoffset; in pci_emul_alloc_rom()
1037 pdi->pi_romoffset = pci_emul_romoffset; in pci_emul_alloc_rom()
1052 errx(4, "Invalid bootindex %d for %s", bootindex, pi->pi_name); in pci_emul_add_boot_device()
1060 new_device->pdi = pi; in pci_emul_add_boot_device()
1061 new_device->bootindex = bootindex; in pci_emul_add_boot_device()
1065 if (device->bootindex == bootindex) { in pci_emul_add_boot_device()
1068 bootindex, pi->pi_name, device->pdi->pi_name); in pci_emul_add_boot_device()
1069 } else if (device->bootindex > bootindex) { in pci_emul_add_boot_device()
1099 capoff = pi->pi_capend + 1; in pci_emul_add_capability()
1103 return (-1); in pci_emul_add_capability()
1110 pci_set_cfgdata8(pi, pi->pi_prevcap + 1, capoff); in pci_emul_add_capability()
1119 pi->pi_prevcap = capoff; in pci_emul_add_capability()
1120 pi->pi_capend = capoff + reallen - 1; in pci_emul_add_capability()
1131 if (!strcmp(pdp->pe_emu, name)) { in pci_emul_finddev()
1140 pci_emul_init(struct vmctx *ctx, struct pci_devemu *pde, int bus, int slot, in pci_emul_init() argument
1148 pdi->pi_vmctx = ctx; in pci_emul_init()
1149 pdi->pi_bus = bus; in pci_emul_init()
1150 pdi->pi_slot = slot; in pci_emul_init()
1151 pdi->pi_func = func; in pci_emul_init()
1152 pthread_mutex_init(&pdi->pi_lintr.lock, NULL); in pci_emul_init()
1153 pdi->pi_lintr.pin = 0; in pci_emul_init()
1154 pdi->pi_lintr.state = IDLE; in pci_emul_init()
1155 pci_irq_init_irq(&pdi->pi_lintr.irq); in pci_emul_init()
1156 pdi->pi_d = pde; in pci_emul_init()
1157 snprintf(pdi->pi_name, PI_NAMESZ, "%s@pci.%d.%d.%d", pde->pe_emu, bus, in pci_emul_init()
1167 err = (*pde->pe_init)(pdi, fi->fi_config); in pci_emul_init()
1169 fi->fi_devi = pdi; in pci_emul_init()
1182 assert((msgnum & (msgnum - 1)) == 0 && msgnum >= 1 && msgnum <= 32); in pci_populate_msicap()
1183 mmc = ffs(msgnum) - 1; in pci_populate_msicap()
1186 msicap->capid = PCIY_MSI; in pci_populate_msicap()
1187 msicap->nextptr = nextptr; in pci_populate_msicap()
1188 msicap->msgctrl = PCIM_MSICTRL_64BIT | (mmc << 1); in pci_populate_msicap()
1209 msixcap->capid = PCIY_MSIX; in pci_populate_msixcap()
1214 * Note: Table size N is encoded as N-1 in pci_populate_msixcap()
1216 msixcap->msgctrl = msgnum - 1; in pci_populate_msixcap()
1219 * MSI-X BAR setup: in pci_populate_msixcap()
1220 * - MSI-X table start at offset 0 in pci_populate_msixcap()
1221 * - PBA table starts at a 4K aligned offset after the MSI-X table in pci_populate_msixcap()
1223 msixcap->table_info = barnum & PCIM_MSIX_BIR_MASK; in pci_populate_msixcap()
1224 msixcap->pba_info = msix_tab_size | (barnum & PCIM_MSIX_BIR_MASK); in pci_populate_msixcap()
1236 pi->pi_msix.table = calloc(1, table_size); in pci_msix_table_init()
1240 pi->pi_msix.table[i].vector_control |= PCIM_MSIX_VCTRL_MASK; in pci_msix_table_init()
1257 pi->pi_msix.table_bar = barnum; in pci_emul_add_msixcap()
1258 pi->pi_msix.pba_bar = barnum; in pci_emul_add_msixcap()
1259 pi->pi_msix.table_offset = 0; in pci_emul_add_msixcap()
1260 pi->pi_msix.table_count = msgnum; in pci_emul_add_msixcap()
1261 pi->pi_msix.pba_offset = tab_size; in pci_emul_add_msixcap()
1262 pi->pi_msix.pba_size = PBA_SIZE(msgnum); in pci_emul_add_msixcap()
1268 /* allocate memory for MSI-X Table and PBA */ in pci_emul_add_msixcap()
1270 tab_size + pi->pi_msix.pba_size); in pci_emul_add_msixcap()
1283 off = offset - capoff; in msixcap_cfgwrite()
1292 pi->pi_msix.enabled = val & PCIM_MSIXCTRL_MSIX_ENABLE; in msixcap_cfgwrite()
1293 pi->pi_msix.function_mask = val & PCIM_MSIXCTRL_FUNCTION_MASK; in msixcap_cfgwrite()
1309 * we do not overwrite read-only fields. in msicap_cfgwrite()
1311 if ((offset - capoff) == 2 && bytes == 2) { in msicap_cfgwrite()
1328 pi->pi_msi.enabled = msgctrl & PCIM_MSICTRL_MSI_ENABLE ? 1 : 0; in msicap_cfgwrite()
1329 if (pi->pi_msi.enabled) { in msicap_cfgwrite()
1330 pi->pi_msi.addr = addrlo; in msicap_cfgwrite()
1331 pi->pi_msi.msg_data = msgdata; in msicap_cfgwrite()
1332 pi->pi_msi.maxmsgnum = 1 << (mme >> 4); in msicap_cfgwrite()
1334 pi->pi_msi.maxmsgnum = 0; in msicap_cfgwrite()
1358 * Use the integrated endpoint type for endpoints on a root complex bus. in pci_emul_add_pciecap()
1360 * NB: bhyve currently only supports a single PCI bus that is the root in pci_emul_add_pciecap()
1361 * complex bus, so all endpoints are integrated. in pci_emul_add_pciecap()
1363 if ((type == PCIEM_TYPE_ENDPOINT) && (pi->pi_bus == 0)) in pci_emul_add_pciecap()
1388 /* Do not allow un-aligned writes */ in pci_emul_capwrite()
1389 if ((offset & (bytes - 1)) != 0) in pci_emul_capwrite()
1410 * However, some o/s's do 4-byte writes that include these. in pci_emul_capwrite()
1445 if (offset >= CAP_START_OFFSET && offset <= pi->pi_capend) in pci_emul_iscap()
1453 uint64_t addr __unused, int size __unused, uint64_t *val, in pci_emul_fallback_handler()
1468 pci_emul_ecfg_handler(struct vcpu *vcpu __unused, int dir, uint64_t addr, in pci_emul_ecfg_handler() argument
1471 int bus, slot, func, coff, in; in pci_emul_ecfg_handler() local
1473 coff = addr & 0xfff; in pci_emul_ecfg_handler()
1474 func = (addr >> 12) & 0x7; in pci_emul_ecfg_handler()
1475 slot = (addr >> 15) & 0x1f; in pci_emul_ecfg_handler()
1476 bus = (addr >> 20) & 0xff; in pci_emul_ecfg_handler()
1480 pci_cfgrw(in, bus, slot, func, coff, bytes, (uint32_t *)val); in pci_emul_ecfg_handler()
1505 device->pdi->pi_slot, device->pdi->pi_func); in init_bootorder()
1528 int bus, slot, func; in init_pci() local
1544 for (bus = 0; bus < MAXBUSES; bus++) { in init_pci()
1545 snprintf(node_name, sizeof(node_name), "pci.%d", bus); in init_pci()
1549 pci_businfo[bus] = calloc(1, sizeof(struct businfo)); in init_pci()
1550 bi = pci_businfo[bus]; in init_pci()
1554 * this bus. in init_pci()
1556 bi->iobase = pci_emul_iobase; in init_pci()
1557 bi->membase32 = pci_emul_membase32; in init_pci()
1558 bi->membase64 = pci_emul_membase64; in init_pci()
1562 si = &bi->slotinfo[slot]; in init_pci()
1564 fi = &si->si_funcs[func]; in init_pci()
1566 "pci.%d.%d.%d", bus, slot, func); in init_pci()
1571 fi->fi_config = nvl; in init_pci()
1575 "\"device\" value", bus, slot, func); in init_pci()
1581 "device \"%s\"", bus, slot, func, in init_pci()
1585 if (pde->pe_alias != NULL) { in init_pci()
1588 bus, slot, func, emul, in init_pci()
1589 pde->pe_alias); in init_pci()
1592 fi->fi_pde = pde; in init_pci()
1593 error = pci_emul_init(ctx, pde, bus, slot, in init_pci()
1604 pci_emul_assign_bar(bar->pdi, bar->idx, bar->type, in init_pci()
1605 bar->size); in init_pci()
1612 * this bus to give a guest some flexibility if it wants to in init_pci()
1617 bi->iolimit = pci_emul_iobase; in init_pci()
1622 bi->memlimit32 = pci_emul_membase32; in init_pci()
1627 bi->memlimit64 = pci_emul_membase64; in init_pci()
1635 for (bus = 0; bus < MAXBUSES; bus++) { in init_pci()
1636 if ((bi = pci_businfo[bus]) == NULL) in init_pci()
1640 si = &bi->slotinfo[slot]; in init_pci()
1642 fi = &si->si_funcs[func]; in init_pci()
1643 if (fi->fi_devi == NULL) in init_pci()
1645 pci_lintr_route(fi->fi_devi); in init_pci()
1662 * [0xC0000000, 0xE0000000) PCI hole (32-bit BAR allocation) in init_pci()
1666 * [roundup(4GB + highmem, 32GB), ...) PCI 64-bit BAR allocation in init_pci()
1670 * [0xA0000000, 0xE0000000) PCI 32-bit BAR allocation in init_pci()
1673 * [roundup(4GB + highmem, 32GB), ...) PCI 64-bit BAR allocation in init_pci()
1689 mr.size = (4ULL * 1024 * 1024 * 1024) - lowmem; in init_pci()
1709 pci_apic_prt_entry(int bus __unused, int slot, int pin, struct pci_irq *irq, in pci_apic_prt_entry()
1716 dsdt_line(" 0x%02X,", pin - 1); in pci_apic_prt_entry()
1718 dsdt_line(" 0x%X", irq->ioapic_irq); in pci_apic_prt_entry()
1723 pci_pirq_prt_entry(int bus __unused, int slot, int pin, struct pci_irq *irq, in pci_pirq_prt_entry()
1728 name = lpc_pirq_name(irq->pirq_pin); in pci_pirq_prt_entry()
1734 dsdt_line(" 0x%02X,", pin - 1); in pci_pirq_prt_entry()
1744 * corresponding to each PCI bus.
1747 pci_bus_write_dsdt(int bus) in pci_bus_write_dsdt() argument
1755 * If there are no devices on this 'bus' then just return. in pci_bus_write_dsdt()
1757 if ((bi = pci_businfo[bus]) == NULL) { in pci_bus_write_dsdt()
1759 * Bus 0 is special because it decodes the I/O ports used in pci_bus_write_dsdt()
1763 if (bus != 0) in pci_bus_write_dsdt()
1767 dsdt_line(" Device (PC%02X)", bus); in pci_bus_write_dsdt()
1773 dsdt_line(" Return (0x%08X)", bus); in pci_bus_write_dsdt()
1780 dsdt_line(" 0x%04X, // Range Minimum", bus); in pci_bus_write_dsdt()
1781 dsdt_line(" 0x%04X, // Range Maximum", bus); in pci_bus_write_dsdt()
1787 if (bus == 0) { in pci_bus_write_dsdt()
1806 PCI_EMUL_IOBASE - 1); in pci_bus_write_dsdt()
1809 PCI_EMUL_IOBASE - 0x0D00); in pci_bus_write_dsdt()
1824 dsdt_line(" 0x%04X, // Range Minimum", bi->iobase); in pci_bus_write_dsdt()
1826 bi->iolimit - 1); in pci_bus_write_dsdt()
1829 bi->iolimit - bi->iobase); in pci_bus_write_dsdt()
1832 /* mmio window (32-bit) */ in pci_bus_write_dsdt()
1836 dsdt_line(" 0x%08X, // Range Minimum\n", bi->membase32); in pci_bus_write_dsdt()
1838 bi->memlimit32 - 1); in pci_bus_write_dsdt()
1841 bi->memlimit32 - bi->membase32); in pci_bus_write_dsdt()
1844 /* mmio window (64-bit) */ in pci_bus_write_dsdt()
1848 dsdt_line(" 0x%016lX, // Range Minimum\n", bi->membase64); in pci_bus_write_dsdt()
1850 bi->memlimit64 - 1); in pci_bus_write_dsdt()
1853 bi->memlimit64 - bi->membase64); in pci_bus_write_dsdt()
1858 if (pci_count_lintr(bus) != 0) { in pci_bus_write_dsdt()
1862 pci_walk_lintr(bus, pci_pirq_prt_entry, NULL); in pci_bus_write_dsdt()
1866 pci_walk_lintr(bus, pci_apic_prt_entry, NULL); in pci_bus_write_dsdt()
1885 si = &bi->slotinfo[slot]; in pci_bus_write_dsdt()
1887 pi = si->si_funcs[func].fi_devi; in pci_bus_write_dsdt()
1888 if (pi != NULL && pi->pi_d->pe_write_dsdt != NULL) in pci_bus_write_dsdt()
1889 pi->pi_d->pe_write_dsdt(pi); in pci_bus_write_dsdt()
1902 int bus; in pci_write_dsdt() local
1913 for (bus = 0; bus < MAXBUSES; bus++) in pci_write_dsdt()
1914 pci_bus_write_dsdt(bus); in pci_write_dsdt()
1920 pci_bus_configured(int bus) in pci_bus_configured() argument
1922 assert(bus >= 0 && bus < MAXBUSES); in pci_bus_configured()
1923 return (pci_businfo[bus] != NULL); in pci_bus_configured()
1929 return (pi->pi_msi.enabled); in pci_msi_enabled()
1935 if (pi->pi_msi.enabled) in pci_msi_maxmsgnum()
1936 return (pi->pi_msi.maxmsgnum); in pci_msi_maxmsgnum()
1945 return (pi->pi_msix.enabled && !pi->pi_msi.enabled); in pci_msix_enabled()
1956 if (pi->pi_msix.function_mask) in pci_generate_msix()
1959 if (index >= pi->pi_msix.table_count) in pci_generate_msix()
1962 mte = &pi->pi_msix.table[index]; in pci_generate_msix()
1963 if ((mte->vector_control & PCIM_MSIX_VCTRL_MASK) == 0) { in pci_generate_msix()
1965 vm_raise_msi(pi->pi_vmctx, mte->addr, mte->msg_data, in pci_generate_msix()
1966 pi->pi_bus, pi->pi_slot, pi->pi_func); in pci_generate_msix()
1975 vm_raise_msi(pi->pi_vmctx, pi->pi_msi.addr, in pci_generate_msi()
1976 pi->pi_msi.msg_data + index, in pci_generate_msi()
1977 pi->pi_bus, pi->pi_slot, pi->pi_func); in pci_generate_msi()
1987 return (!(pi->pi_msi.enabled || pi->pi_msix.enabled || in pci_lintr_permitted()
1998 bi = pci_businfo[pi->pi_bus]; in pci_lintr_request()
2005 si = &bi->slotinfo[pi->pi_slot]; in pci_lintr_request()
2007 bestcount = si->si_intpins[0].ii_count; in pci_lintr_request()
2009 if (si->si_intpins[pin].ii_count < bestcount) { in pci_lintr_request()
2011 bestcount = si->si_intpins[pin].ii_count; in pci_lintr_request()
2015 si->si_intpins[bestpin].ii_count++; in pci_lintr_request()
2016 pi->pi_lintr.pin = bestpin + 1; in pci_lintr_request()
2027 if (pi->pi_lintr.pin == 0) in pci_lintr_route()
2030 bi = pci_businfo[pi->pi_bus]; in pci_lintr_route()
2032 ii = &bi->slotinfo[pi->pi_slot].si_intpins[pi->pi_lintr.pin - 1]; in pci_lintr_route()
2033 irq = &ii->ii_irq; in pci_lintr_route()
2035 pi->pi_lintr.irq = *irq; in pci_lintr_route()
2043 assert(pi->pi_lintr.pin > 0); in pci_lintr_assert()
2045 pthread_mutex_lock(&pi->pi_lintr.lock); in pci_lintr_assert()
2046 if (pi->pi_lintr.state == IDLE) { in pci_lintr_assert()
2048 pi->pi_lintr.state = ASSERTED; in pci_lintr_assert()
2051 pi->pi_lintr.state = PENDING; in pci_lintr_assert()
2053 pthread_mutex_unlock(&pi->pi_lintr.lock); in pci_lintr_assert()
2060 assert(pi->pi_lintr.pin > 0); in pci_lintr_deassert()
2062 pthread_mutex_lock(&pi->pi_lintr.lock); in pci_lintr_deassert()
2063 if (pi->pi_lintr.state == ASSERTED) { in pci_lintr_deassert()
2064 pi->pi_lintr.state = IDLE; in pci_lintr_deassert()
2066 } else if (pi->pi_lintr.state == PENDING) in pci_lintr_deassert()
2067 pi->pi_lintr.state = IDLE; in pci_lintr_deassert()
2068 pthread_mutex_unlock(&pi->pi_lintr.lock); in pci_lintr_deassert()
2075 pthread_mutex_lock(&pi->pi_lintr.lock); in pci_lintr_update()
2076 if (pi->pi_lintr.state == ASSERTED && !pci_lintr_permitted(pi)) { in pci_lintr_update()
2078 pi->pi_lintr.state = PENDING; in pci_lintr_update()
2079 } else if (pi->pi_lintr.state == PENDING && pci_lintr_permitted(pi)) { in pci_lintr_update()
2080 pi->pi_lintr.state = ASSERTED; in pci_lintr_update()
2083 pthread_mutex_unlock(&pi->pi_lintr.lock); in pci_lintr_update()
2087 pci_count_lintr(int bus) in pci_count_lintr() argument
2093 if (pci_businfo[bus] != NULL) { in pci_count_lintr()
2095 slotinfo = &pci_businfo[bus]->slotinfo[slot]; in pci_count_lintr()
2097 if (slotinfo->si_intpins[pin].ii_count != 0) in pci_count_lintr()
2106 pci_walk_lintr(int bus, pci_lintr_cb cb, void *arg) in pci_walk_lintr() argument
2113 if ((bi = pci_businfo[bus]) == NULL) in pci_walk_lintr()
2117 si = &bi->slotinfo[slot]; in pci_walk_lintr()
2119 ii = &si->si_intpins[pin]; in pci_walk_lintr()
2120 if (ii->ii_count != 0) in pci_walk_lintr()
2121 cb(bus, slot, pin + 1, &ii->ii_irq, arg); in pci_walk_lintr()
2127 * Return 1 if the emulated device in 'slot' is a multi-function device.
2131 pci_emul_is_mfdev(int bus, int slot) in pci_emul_is_mfdev() argument
2138 if ((bi = pci_businfo[bus]) != NULL) { in pci_emul_is_mfdev()
2139 si = &bi->slotinfo[slot]; in pci_emul_is_mfdev()
2141 if (si->si_funcs[f].fi_devi != NULL) { in pci_emul_is_mfdev()
2151 * whether or not is a multi-function being emulated in the pci 'slot'.
2154 pci_emul_hdrtype_fixup(int bus, int slot, int off, int bytes, uint32_t *rv) in pci_emul_hdrtype_fixup() argument
2159 mfdev = pci_emul_is_mfdev(bus, slot); in pci_emul_hdrtype_fixup()
2196 switch (pi->pi_bar[i].type) { in pci_emul_cmd_changed()
2210 /* skip (un-)register of ROM if it disabled */ in pci_emul_cmd_changed()
2245 * From PCI Local Bus Specification 3.0 sections 6.2.2 and 6.2.3. in pci_emul_cmdsts_write()
2263 pci_cfgrw(int in, int bus, int slot, int func, int coff, int bytes, in pci_cfgrw() argument
2271 uint64_t addr, bar, mask; in pci_cfgrw() local
2273 if ((bi = pci_businfo[bus]) != NULL) { in pci_cfgrw()
2274 si = &bi->slotinfo[slot]; in pci_cfgrw()
2275 pi = si->si_funcs[func].fi_devi; in pci_cfgrw()
2281 * guest is doing an un-aligned access. in pci_cfgrw()
2284 (coff & (bytes - 1)) != 0) { in pci_cfgrw()
2309 pe = pi->pi_d; in pci_cfgrw()
2316 if (pe->pe_cfgread != NULL) { in pci_cfgrw()
2317 needcfg = pe->pe_cfgread(pi, coff, bytes, valp); in pci_cfgrw()
2325 pci_emul_hdrtype_fixup(bus, slot, coff, bytes, valp); in pci_cfgrw()
2328 if (pe->pe_cfgwrite != NULL && in pci_cfgrw()
2329 (*pe->pe_cfgwrite)(pi, coff, bytes, *valp) == 0) in pci_cfgrw()
2338 * 4-byte aligned. in pci_cfgrw()
2344 idx = (coff - PCIR_BAR(0)) / 4; in pci_cfgrw()
2352 mask = ~(pi->pi_bar[idx].size - 1); in pci_cfgrw()
2353 switch (pi->pi_bar[idx].type) { in pci_cfgrw()
2355 pi->pi_bar[idx].addr = bar = 0; in pci_cfgrw()
2358 addr = *valp & mask; in pci_cfgrw()
2360 addr &= PCI_EMUL_IOMASK; in pci_cfgrw()
2362 bar = addr | pi->pi_bar[idx].lobits; in pci_cfgrw()
2366 if (addr != pi->pi_bar[idx].addr) { in pci_cfgrw()
2367 update_bar_address(pi, addr, idx, in pci_cfgrw()
2372 addr = bar = *valp & mask; in pci_cfgrw()
2373 bar |= pi->pi_bar[idx].lobits; in pci_cfgrw()
2374 if (addr != pi->pi_bar[idx].addr) { in pci_cfgrw()
2375 update_bar_address(pi, addr, idx, in pci_cfgrw()
2380 addr = bar = *valp & mask; in pci_cfgrw()
2381 bar |= pi->pi_bar[idx].lobits; in pci_cfgrw()
2382 if (addr != (uint32_t)pi->pi_bar[idx].addr) { in pci_cfgrw()
2383 update_bar_address(pi, addr, idx, in pci_cfgrw()
2388 mask = ~(pi->pi_bar[idx - 1].size - 1); in pci_cfgrw()
2389 addr = ((uint64_t)*valp << 32) & mask; in pci_cfgrw()
2390 bar = addr >> 32; in pci_cfgrw()
2391 if (bar != pi->pi_bar[idx - 1].addr >> 32) { in pci_cfgrw()
2392 update_bar_address(pi, addr, idx - 1, in pci_cfgrw()
2397 addr = bar = *valp & mask; in pci_cfgrw()
2401 pi->pi_bar[idx].addr = addr; in pci_cfgrw()
2402 pi->pi_bar[idx].lobits = *valp & in pci_cfgrw()
2408 bar |= pi->pi_bar[idx].lobits; in pci_cfgrw()
2466 coff = cfgoff + (port - CONF1_DATA_PORT); in pci_emul_cfgdata()
2494 pi = meta->dev_data; in pci_snapshot_pci_dev()
2496 SNAPSHOT_VAR_OR_LEAVE(pi->pi_msi.enabled, meta, ret, done); in pci_snapshot_pci_dev()
2497 SNAPSHOT_VAR_OR_LEAVE(pi->pi_msi.addr, meta, ret, done); in pci_snapshot_pci_dev()
2498 SNAPSHOT_VAR_OR_LEAVE(pi->pi_msi.msg_data, meta, ret, done); in pci_snapshot_pci_dev()
2499 SNAPSHOT_VAR_OR_LEAVE(pi->pi_msi.maxmsgnum, meta, ret, done); in pci_snapshot_pci_dev()
2501 SNAPSHOT_VAR_OR_LEAVE(pi->pi_msix.enabled, meta, ret, done); in pci_snapshot_pci_dev()
2502 SNAPSHOT_VAR_OR_LEAVE(pi->pi_msix.table_bar, meta, ret, done); in pci_snapshot_pci_dev()
2503 SNAPSHOT_VAR_OR_LEAVE(pi->pi_msix.pba_bar, meta, ret, done); in pci_snapshot_pci_dev()
2504 SNAPSHOT_VAR_OR_LEAVE(pi->pi_msix.table_offset, meta, ret, done); in pci_snapshot_pci_dev()
2505 SNAPSHOT_VAR_OR_LEAVE(pi->pi_msix.table_count, meta, ret, done); in pci_snapshot_pci_dev()
2506 SNAPSHOT_VAR_OR_LEAVE(pi->pi_msix.pba_offset, meta, ret, done); in pci_snapshot_pci_dev()
2507 SNAPSHOT_VAR_OR_LEAVE(pi->pi_msix.pba_size, meta, ret, done); in pci_snapshot_pci_dev()
2508 SNAPSHOT_VAR_OR_LEAVE(pi->pi_msix.function_mask, meta, ret, done); in pci_snapshot_pci_dev()
2510 SNAPSHOT_BUF_OR_LEAVE(pi->pi_cfgdata, sizeof(pi->pi_cfgdata), in pci_snapshot_pci_dev()
2513 for (i = 0; i < (int)nitems(pi->pi_bar); i++) { in pci_snapshot_pci_dev()
2514 SNAPSHOT_VAR_OR_LEAVE(pi->pi_bar[i].type, meta, ret, done); in pci_snapshot_pci_dev()
2515 SNAPSHOT_VAR_OR_LEAVE(pi->pi_bar[i].size, meta, ret, done); in pci_snapshot_pci_dev()
2516 SNAPSHOT_VAR_OR_LEAVE(pi->pi_bar[i].addr, meta, ret, done); in pci_snapshot_pci_dev()
2519 /* Restore MSI-X table. */ in pci_snapshot_pci_dev()
2520 for (i = 0; i < pi->pi_msix.table_count; i++) { in pci_snapshot_pci_dev()
2521 SNAPSHOT_VAR_OR_LEAVE(pi->pi_msix.table[i].addr, in pci_snapshot_pci_dev()
2523 SNAPSHOT_VAR_OR_LEAVE(pi->pi_msix.table[i].msg_data, in pci_snapshot_pci_dev()
2525 SNAPSHOT_VAR_OR_LEAVE(pi->pi_msix.table[i].vector_control, in pci_snapshot_pci_dev()
2540 assert(meta->dev_name != NULL); in pci_snapshot()
2542 pdi = meta->dev_data; in pci_snapshot()
2543 pde = pdi->pi_d; in pci_snapshot()
2545 if (pde->pe_snapshot == NULL) in pci_snapshot()
2550 ret = (*pde->pe_snapshot)(meta); in pci_snapshot()
2558 struct pci_devemu *pde = pdi->pi_d; in pci_pause()
2560 if (pde->pe_pause == NULL) { in pci_pause()
2565 return (*pde->pe_pause)(pdi); in pci_pause()
2571 struct pci_devemu *pde = pdi->pi_d; in pci_resume()
2573 if (pde->pe_resume == NULL) { in pci_resume()
2578 return (*pde->pe_resume)(pdi); in pci_resume()
2605 pi->pi_arg = sc; in pci_emul_dinit()
2631 struct pci_emul_dsoftc *sc = pi->pi_arg; in pci_emul_diow()
2641 sc->ioregs[offset] = value & 0xff; in pci_emul_diow()
2643 *(uint16_t *)&sc->ioregs[offset] = value & 0xffff; in pci_emul_diow()
2645 *(uint32_t *)&sc->ioregs[offset] = value; in pci_emul_diow()
2669 i = baridx - 1; /* 'memregs' index */ in pci_emul_diow()
2672 sc->memregs[i][offset] = value; in pci_emul_diow()
2674 *(uint16_t *)&sc->memregs[i][offset] = value; in pci_emul_diow()
2676 *(uint32_t *)&sc->memregs[i][offset] = value; in pci_emul_diow()
2678 *(uint64_t *)&sc->memregs[i][offset] = value; in pci_emul_diow()
2696 struct pci_emul_dsoftc *sc = pi->pi_arg; in pci_emul_dior()
2709 value = sc->ioregs[offset]; in pci_emul_dior()
2711 value = *(uint16_t *) &sc->ioregs[offset]; in pci_emul_dior()
2713 value = *(uint32_t *) &sc->ioregs[offset]; in pci_emul_dior()
2726 i = baridx - 1; /* 'memregs' index */ in pci_emul_dior()
2729 value = sc->memregs[i][offset]; in pci_emul_dior()
2731 value = *(uint16_t *) &sc->memregs[i][offset]; in pci_emul_dior()
2733 value = *(uint32_t *) &sc->memregs[i][offset]; in pci_emul_dior()
2735 value = *(uint64_t *) &sc->memregs[i][offset]; in pci_emul_dior()
2754 unsigned bus = 0, slot = 0, func = 0; in pci_next() local
2759 bus = cursor ? cursor->pi_bus : 0; in pci_next()
2760 slot = cursor ? cursor->pi_slot : 0; in pci_next()
2761 func = cursor ? (cursor->pi_func + 1) : 0; in pci_next()
2763 for (; bus < MAXBUSES; bus++) { in pci_next()
2764 if ((bi = pci_businfo[bus]) == NULL) in pci_next()
2771 si = &bi->slotinfo[slot]; in pci_next()
2775 fi = &si->si_funcs[func]; in pci_next()
2776 if (fi->fi_devi == NULL) in pci_next()
2779 return (fi->fi_devi); in pci_next()