Lines Matching +full:rom +full:- +full:14 +full:h
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
29 #include <sys/param.h>
30 #include <sys/linker_set.h>
31 #include <sys/mman.h>
33 #include <ctype.h>
34 #include <err.h>
35 #include <errno.h>
36 #include <pthread.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <strings.h>
41 #include <assert.h>
42 #include <stdbool.h>
43 #include <sysexits.h>
45 #include <machine/vmm.h>
46 #include <machine/vmm_snapshot.h>
47 #include <vmmapi.h>
49 #include "acpi.h"
50 #include "bhyverun.h"
51 #include "bootrom.h"
52 #include "config.h"
53 #include "debug.h"
55 #include "amd64/inout.h"
57 #include "mem.h"
58 #include "pci_emul.h"
60 #include "amd64/pci_lpc.h"
61 #include "pci_passthru.h"
63 #include "qemu_fwcfg.h"
213 * emul is a string describing the type of PCI device e.g. virtio-net
217 * 1,virtio-net,tap0
228 * Helper function to parse a list of comma-separated options where
278 error = -1; in pci_parse_slot()
302 snum = -1; in pci_parse_slot()
329 if (pde->pe_alias != NULL) in pci_parse_slot()
330 set_config_value_node(nvl, "device", pde->pe_alias); in pci_parse_slot()
332 set_config_value_node(nvl, "device", pde->pe_emu); in pci_parse_slot()
334 if (pde->pe_legacy_config != NULL) in pci_parse_slot()
335 error = pde->pe_legacy_config(nvl, config); in pci_parse_slot()
350 printf("%s\n", pdp->pe_emu); in pci_print_supported_devices()
385 return (-1); in pci_config_read_reg()
405 if (offset < pi->pi_msix.pba_offset) in pci_valid_pba_offset()
408 if (offset >= pi->pi_msix.pba_offset + pi->pi_msix.pba_size) { in pci_valid_pba_offset()
425 return (-1); in pci_emul_msix_twrite()
431 if (tab_index >= pi->pi_msix.table_count) in pci_emul_msix_twrite()
432 return (-1); in pci_emul_msix_twrite()
438 return (-1); in pci_emul_msix_twrite()
440 dest = (char *)(pi->pi_msix.table + tab_index); in pci_emul_msix_twrite()
460 * The PCI standard only allows 4 and 8 byte accesses to the MSI-X in pci_emul_msix_tread()
476 if (tab_index < pi->pi_msix.table_count) { in pci_emul_msix_tread()
477 /* valid MSI-X Table access */ in pci_emul_msix_tread()
478 dest = (char *)(pi->pi_msix.table + tab_index); in pci_emul_msix_tread()
499 if (pi->pi_msix.table != NULL) in pci_msix_table_bar()
500 return (pi->pi_msix.table_bar); in pci_msix_table_bar()
502 return (-1); in pci_msix_table_bar()
509 if (pi->pi_msix.table != NULL) in pci_msix_pba_bar()
510 return (pi->pi_msix.pba_bar); in pci_msix_pba_bar()
512 return (-1); in pci_msix_pba_bar()
521 struct pci_devemu *pe = pdi->pi_d; in pci_emul_io_handler()
528 if (pdi->pi_bar[i].type == PCIBAR_IO && in pci_emul_io_handler()
529 (uint64_t)port >= pdi->pi_bar[i].addr && in pci_emul_io_handler()
531 pdi->pi_bar[i].addr + pdi->pi_bar[i].size) { in pci_emul_io_handler()
532 offset = port - pdi->pi_bar[i].addr; in pci_emul_io_handler()
534 *eax = (*pe->pe_barread)(pdi, i, in pci_emul_io_handler()
537 (*pe->pe_barwrite)(pdi, i, offset, in pci_emul_io_handler()
542 return (-1); in pci_emul_io_handler()
550 struct pci_devemu *pe = pdi->pi_d; in pci_emul_iomem_handler()
555 assert(pdi->pi_bar[bidx].type == PCIBAR_IO); in pci_emul_iomem_handler()
556 assert(addr >= pdi->pi_bar[bidx].addr && in pci_emul_iomem_handler()
557 addr + size <= pdi->pi_bar[bidx].addr + pdi->pi_bar[bidx].size); in pci_emul_iomem_handler()
560 offset = addr - pdi->pi_bar[bidx].addr; in pci_emul_iomem_handler()
562 *val = (*pe->pe_barread)(pdi, bidx, offset, size); in pci_emul_iomem_handler()
564 (*pe->pe_barwrite)(pdi, bidx, offset, size, *val); in pci_emul_iomem_handler()
575 struct pci_devemu *pe = pdi->pi_d; in pci_emul_mem_handler()
580 assert(pdi->pi_bar[bidx].type == PCIBAR_MEM32 || in pci_emul_mem_handler()
581 pdi->pi_bar[bidx].type == PCIBAR_MEM64); in pci_emul_mem_handler()
582 assert(addr >= pdi->pi_bar[bidx].addr && in pci_emul_mem_handler()
583 addr + size <= pdi->pi_bar[bidx].addr + pdi->pi_bar[bidx].size); in pci_emul_mem_handler()
585 offset = addr - pdi->pi_bar[bidx].addr; in pci_emul_mem_handler()
589 (*pe->pe_barwrite)(pdi, bidx, offset, in pci_emul_mem_handler()
591 (*pe->pe_barwrite)(pdi, bidx, offset + 4, in pci_emul_mem_handler()
594 (*pe->pe_barwrite)(pdi, bidx, offset, in pci_emul_mem_handler()
599 *val = (*pe->pe_barread)(pdi, bidx, in pci_emul_mem_handler()
601 *val |= (*pe->pe_barread)(pdi, bidx, in pci_emul_mem_handler()
604 *val = (*pe->pe_barread)(pdi, bidx, in pci_emul_mem_handler()
619 assert((size & (size - 1)) == 0); /* must be a power of 2 */ in pci_emul_alloc_resource()
628 return (-1); in pci_emul_alloc_resource()
642 pe = pi->pi_d; in modify_bar_registration()
643 type = pi->pi_bar[idx].type; in modify_bar_registration()
651 iop.name = pi->pi_name; in modify_bar_registration()
652 iop.port = pi->pi_bar[idx].addr; in modify_bar_registration()
653 iop.size = pi->pi_bar[idx].size; in modify_bar_registration()
665 mr.name = pi->pi_name; in modify_bar_registration()
666 mr.base = pi->pi_bar[idx].addr; in modify_bar_registration()
667 mr.size = pi->pi_bar[idx].size; in modify_bar_registration()
685 mr.name = pi->pi_name; in modify_bar_registration()
686 mr.base = pi->pi_bar[idx].addr; in modify_bar_registration()
687 mr.size = pi->pi_bar[idx].size; in modify_bar_registration()
707 if (pe->pe_baraddr != NULL) in modify_bar_registration()
708 (*pe->pe_baraddr)(pi, idx, registration, pi->pi_bar[idx].addr); in modify_bar_registration()
725 /* Is the ROM enabled for the emulated pci device? */
729 return (pi->pi_bar[PCI_ROM_IDX].lobits & PCIM_BIOS_ENABLE) == in romen()
766 if (pi->pi_bar[idx].type == PCIBAR_IO) in update_bar_address()
777 pi->pi_bar[idx].addr = addr; in update_bar_address()
780 pi->pi_bar[idx].addr &= ~0xffffffffUL; in update_bar_address()
781 pi->pi_bar[idx].addr |= addr; in update_bar_address()
784 pi->pi_bar[idx].addr &= 0xffffffff; in update_bar_address()
785 pi->pi_bar[idx].addr |= addr; in update_bar_address()
802 if ((size & (size - 1)) != 0) in pci_emul_alloc_bar()
827 new_bar->pdi = pdi; in pci_emul_alloc_bar()
828 new_bar->idx = idx; in pci_emul_alloc_bar()
829 new_bar->type = type; in pci_emul_alloc_bar()
830 new_bar->size = size; in pci_emul_alloc_bar()
838 if (bar->size < size) { in pci_emul_alloc_bar()
858 * Enable PCI BARs only if we don't have a boot ROM, i.e., bhyveload was in pci_emul_alloc_bar()
860 * ROM to handle this. in pci_emul_alloc_bar()
911 * Some drivers do not work well if the 64-bit BAR is allocated in pci_emul_assign_bar()
936 /* do not claim memory for ROM. OVMF will do it for us. */ in pci_emul_assign_bar()
955 pdi->pi_bar[idx].type = type; in pci_emul_assign_bar()
956 pdi->pi_bar[idx].addr = addr; in pci_emul_assign_bar()
957 pdi->pi_bar[idx].size = size; in pci_emul_assign_bar()
962 if (pdi->pi_bar[idx].lobits != 0) { in pci_emul_assign_bar()
963 lobits = pdi->pi_bar[idx].lobits; in pci_emul_assign_bar()
965 pdi->pi_bar[idx].lobits = lobits; in pci_emul_assign_bar()
974 pdi->pi_bar[idx + 1].type = PCIBAR_MEMHI64; in pci_emul_assign_bar()
1000 /* allocate ROM space once on first call */ in pci_emul_alloc_rom()
1002 pci_emul_rombase = vm_create_devmem(pdi->pi_vmctx, VM_PCIROM, in pci_emul_alloc_rom()
1005 warnx("%s: failed to create rom segment", __func__); in pci_emul_alloc_rom()
1006 return (-1); in pci_emul_alloc_rom()
1012 /* ROM size should be a power of 2 and greater than 2 KB */ in pci_emul_alloc_rom()
1016 /* check if ROM fits into ROM space */ in pci_emul_alloc_rom()
1018 warnx("%s: no space left in rom segment:", __func__); in pci_emul_alloc_rom()
1020 PCI_EMUL_ROMSIZE - pci_emul_romoffset); in pci_emul_alloc_rom()
1021 warnx("%16lu bytes required by %d/%d/%d", rom_size, pdi->pi_bus, in pci_emul_alloc_rom()
1022 pdi->pi_slot, pdi->pi_func); in pci_emul_alloc_rom()
1023 return (-1); in pci_emul_alloc_rom()
1026 /* allocate ROM BAR */ in pci_emul_alloc_rom()
1035 /* save offset into ROM Space */ in pci_emul_alloc_rom()
1036 pdi->pi_romoffset = pci_emul_romoffset; in pci_emul_alloc_rom()
1038 /* increase offset for next ROM */ in pci_emul_alloc_rom()
1051 errx(4, "Invalid bootindex %d for %s", bootindex, pi->pi_name); in pci_emul_add_boot_device()
1059 new_device->pdi = pi; in pci_emul_add_boot_device()
1060 new_device->bootindex = bootindex; in pci_emul_add_boot_device()
1064 if (device->bootindex == bootindex) { in pci_emul_add_boot_device()
1067 bootindex, pi->pi_name, device->pdi->pi_name); in pci_emul_add_boot_device()
1068 } else if (device->bootindex > bootindex) { in pci_emul_add_boot_device()
1098 capoff = pi->pi_capend + 1; in pci_emul_add_capability()
1102 return (-1); in pci_emul_add_capability()
1109 pci_set_cfgdata8(pi, pi->pi_prevcap + 1, capoff); in pci_emul_add_capability()
1118 pi->pi_prevcap = capoff; in pci_emul_add_capability()
1119 pi->pi_capend = capoff + reallen - 1; in pci_emul_add_capability()
1130 if (!strcmp(pdp->pe_emu, name)) { in pci_emul_finddev()
1147 pdi->pi_vmctx = ctx; in pci_emul_init()
1148 pdi->pi_bus = bus; in pci_emul_init()
1149 pdi->pi_slot = slot; in pci_emul_init()
1150 pdi->pi_func = func; in pci_emul_init()
1151 pthread_mutex_init(&pdi->pi_lintr.lock, NULL); in pci_emul_init()
1152 pdi->pi_lintr.pin = 0; in pci_emul_init()
1153 pdi->pi_lintr.state = IDLE; in pci_emul_init()
1154 pci_irq_init_irq(&pdi->pi_lintr.irq); in pci_emul_init()
1155 pdi->pi_d = pde; in pci_emul_init()
1156 snprintf(pdi->pi_name, PI_NAMESZ, "%s@pci.%d.%d.%d", pde->pe_emu, bus, in pci_emul_init()
1166 err = (*pde->pe_init)(pdi, fi->fi_config); in pci_emul_init()
1168 fi->fi_devi = pdi; in pci_emul_init()
1181 assert((msgnum & (msgnum - 1)) == 0 && msgnum >= 1 && msgnum <= 32); in pci_populate_msicap()
1182 mmc = ffs(msgnum) - 1; in pci_populate_msicap()
1185 msicap->capid = PCIY_MSI; in pci_populate_msicap()
1186 msicap->nextptr = nextptr; in pci_populate_msicap()
1187 msicap->msgctrl = PCIM_MSICTRL_64BIT | (mmc << 1); in pci_populate_msicap()
1208 msixcap->capid = PCIY_MSIX; in pci_populate_msixcap()
1213 * Note: Table size N is encoded as N-1 in pci_populate_msixcap()
1215 msixcap->msgctrl = msgnum - 1; in pci_populate_msixcap()
1218 * MSI-X BAR setup: in pci_populate_msixcap()
1219 * - MSI-X table start at offset 0 in pci_populate_msixcap()
1220 * - PBA table starts at a 4K aligned offset after the MSI-X table in pci_populate_msixcap()
1222 msixcap->table_info = barnum & PCIM_MSIX_BIR_MASK; in pci_populate_msixcap()
1223 msixcap->pba_info = msix_tab_size | (barnum & PCIM_MSIX_BIR_MASK); in pci_populate_msixcap()
1235 pi->pi_msix.table = calloc(1, table_size); in pci_msix_table_init()
1239 pi->pi_msix.table[i].vector_control |= PCIM_MSIX_VCTRL_MASK; in pci_msix_table_init()
1256 pi->pi_msix.table_bar = barnum; in pci_emul_add_msixcap()
1257 pi->pi_msix.pba_bar = barnum; in pci_emul_add_msixcap()
1258 pi->pi_msix.table_offset = 0; in pci_emul_add_msixcap()
1259 pi->pi_msix.table_count = msgnum; in pci_emul_add_msixcap()
1260 pi->pi_msix.pba_offset = tab_size; in pci_emul_add_msixcap()
1261 pi->pi_msix.pba_size = PBA_SIZE(msgnum); in pci_emul_add_msixcap()
1267 /* allocate memory for MSI-X Table and PBA */ in pci_emul_add_msixcap()
1269 tab_size + pi->pi_msix.pba_size); in pci_emul_add_msixcap()
1282 off = offset - capoff; in msixcap_cfgwrite()
1291 pi->pi_msix.enabled = val & PCIM_MSIXCTRL_MSIX_ENABLE; in msixcap_cfgwrite()
1292 pi->pi_msix.function_mask = val & PCIM_MSIXCTRL_FUNCTION_MASK; in msixcap_cfgwrite()
1308 * we do not overwrite read-only fields. in msicap_cfgwrite()
1310 if ((offset - capoff) == 2 && bytes == 2) { in msicap_cfgwrite()
1327 pi->pi_msi.enabled = msgctrl & PCIM_MSICTRL_MSI_ENABLE ? 1 : 0; in msicap_cfgwrite()
1328 if (pi->pi_msi.enabled) { in msicap_cfgwrite()
1329 pi->pi_msi.addr = addrlo; in msicap_cfgwrite()
1330 pi->pi_msi.msg_data = msgdata; in msicap_cfgwrite()
1331 pi->pi_msi.maxmsgnum = 1 << (mme >> 4); in msicap_cfgwrite()
1333 pi->pi_msi.maxmsgnum = 0; in msicap_cfgwrite()
1362 if ((type == PCIEM_TYPE_ENDPOINT) && (pi->pi_bus == 0)) in pci_emul_add_pciecap()
1387 /* Do not allow un-aligned writes */ in pci_emul_capwrite()
1388 if ((offset & (bytes - 1)) != 0) in pci_emul_capwrite()
1409 * However, some o/s's do 4-byte writes that include these. in pci_emul_capwrite()
1444 if (offset >= CAP_START_OFFSET && offset <= pi->pi_capend) in pci_emul_iscap()
1504 device->pdi->pi_slot, device->pdi->pi_func); in init_bootorder()
1555 bi->iobase = pci_emul_iobase; in init_pci()
1556 bi->membase32 = pci_emul_membase32; in init_pci()
1557 bi->membase64 = pci_emul_membase64; in init_pci()
1561 si = &bi->slotinfo[slot]; in init_pci()
1563 fi = &si->si_funcs[func]; in init_pci()
1570 fi->fi_config = nvl; in init_pci()
1584 if (pde->pe_alias != NULL) { in init_pci()
1588 pde->pe_alias); in init_pci()
1591 fi->fi_pde = pde; in init_pci()
1603 pci_emul_assign_bar(bar->pdi, bar->idx, bar->type, in init_pci()
1604 bar->size); in init_pci()
1616 bi->iolimit = pci_emul_iobase; in init_pci()
1621 bi->memlimit32 = pci_emul_membase32; in init_pci()
1626 bi->memlimit64 = pci_emul_membase64; in init_pci()
1639 si = &bi->slotinfo[slot]; in init_pci()
1641 fi = &si->si_funcs[func]; in init_pci()
1642 if (fi->fi_devi == NULL) in init_pci()
1644 pci_lintr_route(fi->fi_devi); in init_pci()
1661 * [0xC0000000, 0xE0000000) PCI hole (32-bit BAR allocation) in init_pci()
1665 * [roundup(4GB + highmem, 32GB), ...) PCI 64-bit BAR allocation in init_pci()
1669 * [0xA0000000, 0xE0000000) PCI 32-bit BAR allocation in init_pci()
1672 * [roundup(4GB + highmem, 32GB), ...) PCI 64-bit BAR allocation in init_pci()
1688 mr.size = (4ULL * 1024 * 1024 * 1024) - lowmem; in init_pci()
1715 dsdt_line(" 0x%02X,", pin - 1); in pci_apic_prt_entry()
1717 dsdt_line(" 0x%X", irq->ioapic_irq); in pci_apic_prt_entry()
1727 name = lpc_pirq_name(irq->pirq_pin); in pci_pirq_prt_entry()
1733 dsdt_line(" 0x%02X,", pin - 1); in pci_pirq_prt_entry()
1805 PCI_EMUL_IOBASE - 1); in pci_bus_write_dsdt()
1808 PCI_EMUL_IOBASE - 0x0D00); in pci_bus_write_dsdt()
1823 dsdt_line(" 0x%04X, // Range Minimum", bi->iobase); in pci_bus_write_dsdt()
1825 bi->iolimit - 1); in pci_bus_write_dsdt()
1828 bi->iolimit - bi->iobase); in pci_bus_write_dsdt()
1831 /* mmio window (32-bit) */ in pci_bus_write_dsdt()
1835 dsdt_line(" 0x%08X, // Range Minimum\n", bi->membase32); in pci_bus_write_dsdt()
1837 bi->memlimit32 - 1); in pci_bus_write_dsdt()
1840 bi->memlimit32 - bi->membase32); in pci_bus_write_dsdt()
1843 /* mmio window (64-bit) */ in pci_bus_write_dsdt()
1847 dsdt_line(" 0x%016lX, // Range Minimum\n", bi->membase64); in pci_bus_write_dsdt()
1849 bi->memlimit64 - 1); in pci_bus_write_dsdt()
1852 bi->memlimit64 - bi->membase64); in pci_bus_write_dsdt()
1884 si = &bi->slotinfo[slot]; in pci_bus_write_dsdt()
1886 pi = si->si_funcs[func].fi_devi; in pci_bus_write_dsdt()
1887 if (pi != NULL && pi->pi_d->pe_write_dsdt != NULL) in pci_bus_write_dsdt()
1888 pi->pi_d->pe_write_dsdt(pi); in pci_bus_write_dsdt()
1928 return (pi->pi_msi.enabled); in pci_msi_enabled()
1934 if (pi->pi_msi.enabled) in pci_msi_maxmsgnum()
1935 return (pi->pi_msi.maxmsgnum); in pci_msi_maxmsgnum()
1944 return (pi->pi_msix.enabled && !pi->pi_msi.enabled); in pci_msix_enabled()
1955 if (pi->pi_msix.function_mask) in pci_generate_msix()
1958 if (index >= pi->pi_msix.table_count) in pci_generate_msix()
1961 mte = &pi->pi_msix.table[index]; in pci_generate_msix()
1962 if ((mte->vector_control & PCIM_MSIX_VCTRL_MASK) == 0) { in pci_generate_msix()
1964 vm_raise_msi(pi->pi_vmctx, mte->addr, mte->msg_data, in pci_generate_msix()
1965 pi->pi_bus, pi->pi_slot, pi->pi_func); in pci_generate_msix()
1974 vm_raise_msi(pi->pi_vmctx, pi->pi_msi.addr, in pci_generate_msi()
1975 pi->pi_msi.msg_data + index, in pci_generate_msi()
1976 pi->pi_bus, pi->pi_slot, pi->pi_func); in pci_generate_msi()
1986 return (!(pi->pi_msi.enabled || pi->pi_msix.enabled || in pci_lintr_permitted()
1997 bi = pci_businfo[pi->pi_bus]; in pci_lintr_request()
2004 si = &bi->slotinfo[pi->pi_slot]; in pci_lintr_request()
2006 bestcount = si->si_intpins[0].ii_count; in pci_lintr_request()
2008 if (si->si_intpins[pin].ii_count < bestcount) { in pci_lintr_request()
2010 bestcount = si->si_intpins[pin].ii_count; in pci_lintr_request()
2014 si->si_intpins[bestpin].ii_count++; in pci_lintr_request()
2015 pi->pi_lintr.pin = bestpin + 1; in pci_lintr_request()
2026 if (pi->pi_lintr.pin == 0) in pci_lintr_route()
2029 bi = pci_businfo[pi->pi_bus]; in pci_lintr_route()
2031 ii = &bi->slotinfo[pi->pi_slot].si_intpins[pi->pi_lintr.pin - 1]; in pci_lintr_route()
2032 irq = &ii->ii_irq; in pci_lintr_route()
2034 pi->pi_lintr.irq = *irq; in pci_lintr_route()
2042 assert(pi->pi_lintr.pin > 0); in pci_lintr_assert()
2044 pthread_mutex_lock(&pi->pi_lintr.lock); in pci_lintr_assert()
2045 if (pi->pi_lintr.state == IDLE) { in pci_lintr_assert()
2047 pi->pi_lintr.state = ASSERTED; in pci_lintr_assert()
2050 pi->pi_lintr.state = PENDING; in pci_lintr_assert()
2052 pthread_mutex_unlock(&pi->pi_lintr.lock); in pci_lintr_assert()
2059 assert(pi->pi_lintr.pin > 0); in pci_lintr_deassert()
2061 pthread_mutex_lock(&pi->pi_lintr.lock); in pci_lintr_deassert()
2062 if (pi->pi_lintr.state == ASSERTED) { in pci_lintr_deassert()
2063 pi->pi_lintr.state = IDLE; in pci_lintr_deassert()
2065 } else if (pi->pi_lintr.state == PENDING) in pci_lintr_deassert()
2066 pi->pi_lintr.state = IDLE; in pci_lintr_deassert()
2067 pthread_mutex_unlock(&pi->pi_lintr.lock); in pci_lintr_deassert()
2074 pthread_mutex_lock(&pi->pi_lintr.lock); in pci_lintr_update()
2075 if (pi->pi_lintr.state == ASSERTED && !pci_lintr_permitted(pi)) { in pci_lintr_update()
2077 pi->pi_lintr.state = PENDING; in pci_lintr_update()
2078 } else if (pi->pi_lintr.state == PENDING && pci_lintr_permitted(pi)) { in pci_lintr_update()
2079 pi->pi_lintr.state = ASSERTED; in pci_lintr_update()
2082 pthread_mutex_unlock(&pi->pi_lintr.lock); in pci_lintr_update()
2094 slotinfo = &pci_businfo[bus]->slotinfo[slot]; in pci_count_lintr()
2096 if (slotinfo->si_intpins[pin].ii_count != 0) in pci_count_lintr()
2116 si = &bi->slotinfo[slot]; in pci_walk_lintr()
2118 ii = &si->si_intpins[pin]; in pci_walk_lintr()
2119 if (ii->ii_count != 0) in pci_walk_lintr()
2120 cb(bus, slot, pin + 1, &ii->ii_irq, arg); in pci_walk_lintr()
2126 * Return 1 if the emulated device in 'slot' is a multi-function device.
2138 si = &bi->slotinfo[slot]; in pci_emul_is_mfdev()
2140 if (si->si_funcs[f].fi_devi != NULL) { in pci_emul_is_mfdev()
2150 * whether or not is a multi-function being emulated in the pci 'slot'.
2195 switch (pi->pi_bar[i].type) { in pci_emul_cmd_changed()
2209 /* skip (un-)register of ROM if it disabled */ in pci_emul_cmd_changed()
2246 * XXX Bits 8, 11, 12, 13, 14 and 15 in the status register are in pci_emul_cmdsts_write()
2273 si = &bi->slotinfo[slot]; in pci_cfgrw()
2274 pi = si->si_funcs[func].fi_devi; in pci_cfgrw()
2280 * guest is doing an un-aligned access. in pci_cfgrw()
2283 (coff & (bytes - 1)) != 0) { in pci_cfgrw()
2308 pe = pi->pi_d; in pci_cfgrw()
2315 if (pe->pe_cfgread != NULL) { in pci_cfgrw()
2316 needcfg = pe->pe_cfgread(pi, coff, bytes, valp); in pci_cfgrw()
2327 if (pe->pe_cfgwrite != NULL && in pci_cfgrw()
2328 (*pe->pe_cfgwrite)(pi, coff, bytes, *valp) == 0) in pci_cfgrw()
2332 * Special handling for write to BAR and ROM registers in pci_cfgrw()
2337 * 4-byte aligned. in pci_cfgrw()
2343 idx = (coff - PCIR_BAR(0)) / 4; in pci_cfgrw()
2351 mask = ~(pi->pi_bar[idx].size - 1); in pci_cfgrw()
2352 switch (pi->pi_bar[idx].type) { in pci_cfgrw()
2354 pi->pi_bar[idx].addr = bar = 0; in pci_cfgrw()
2361 bar = addr | pi->pi_bar[idx].lobits; in pci_cfgrw()
2365 if (addr != pi->pi_bar[idx].addr) { in pci_cfgrw()
2372 bar |= pi->pi_bar[idx].lobits; in pci_cfgrw()
2373 if (addr != pi->pi_bar[idx].addr) { in pci_cfgrw()
2380 bar |= pi->pi_bar[idx].lobits; in pci_cfgrw()
2381 if (addr != (uint32_t)pi->pi_bar[idx].addr) { in pci_cfgrw()
2387 mask = ~(pi->pi_bar[idx - 1].size - 1); in pci_cfgrw()
2390 if (bar != pi->pi_bar[idx - 1].addr >> 32) { in pci_cfgrw()
2391 update_bar_address(pi, addr, idx - 1, in pci_cfgrw()
2400 pi->pi_bar[idx].addr = addr; in pci_cfgrw()
2401 pi->pi_bar[idx].lobits = *valp & in pci_cfgrw()
2407 bar |= pi->pi_bar[idx].lobits; in pci_cfgrw()
2465 coff = cfgoff + (port - CONF1_DATA_PORT); in pci_emul_cfgdata()
2493 pi = meta->dev_data; in pci_snapshot_pci_dev()
2495 SNAPSHOT_VAR_OR_LEAVE(pi->pi_msi.enabled, meta, ret, done); in pci_snapshot_pci_dev()
2496 SNAPSHOT_VAR_OR_LEAVE(pi->pi_msi.addr, meta, ret, done); in pci_snapshot_pci_dev()
2497 SNAPSHOT_VAR_OR_LEAVE(pi->pi_msi.msg_data, meta, ret, done); in pci_snapshot_pci_dev()
2498 SNAPSHOT_VAR_OR_LEAVE(pi->pi_msi.maxmsgnum, meta, ret, done); in pci_snapshot_pci_dev()
2500 SNAPSHOT_VAR_OR_LEAVE(pi->pi_msix.enabled, meta, ret, done); in pci_snapshot_pci_dev()
2501 SNAPSHOT_VAR_OR_LEAVE(pi->pi_msix.table_bar, meta, ret, done); in pci_snapshot_pci_dev()
2502 SNAPSHOT_VAR_OR_LEAVE(pi->pi_msix.pba_bar, meta, ret, done); in pci_snapshot_pci_dev()
2503 SNAPSHOT_VAR_OR_LEAVE(pi->pi_msix.table_offset, meta, ret, done); in pci_snapshot_pci_dev()
2504 SNAPSHOT_VAR_OR_LEAVE(pi->pi_msix.table_count, meta, ret, done); in pci_snapshot_pci_dev()
2505 SNAPSHOT_VAR_OR_LEAVE(pi->pi_msix.pba_offset, meta, ret, done); in pci_snapshot_pci_dev()
2506 SNAPSHOT_VAR_OR_LEAVE(pi->pi_msix.pba_size, meta, ret, done); in pci_snapshot_pci_dev()
2507 SNAPSHOT_VAR_OR_LEAVE(pi->pi_msix.function_mask, meta, ret, done); in pci_snapshot_pci_dev()
2509 SNAPSHOT_BUF_OR_LEAVE(pi->pi_cfgdata, sizeof(pi->pi_cfgdata), in pci_snapshot_pci_dev()
2512 for (i = 0; i < (int)nitems(pi->pi_bar); i++) { in pci_snapshot_pci_dev()
2513 SNAPSHOT_VAR_OR_LEAVE(pi->pi_bar[i].type, meta, ret, done); in pci_snapshot_pci_dev()
2514 SNAPSHOT_VAR_OR_LEAVE(pi->pi_bar[i].size, meta, ret, done); in pci_snapshot_pci_dev()
2515 SNAPSHOT_VAR_OR_LEAVE(pi->pi_bar[i].addr, meta, ret, done); in pci_snapshot_pci_dev()
2518 /* Restore MSI-X table. */ in pci_snapshot_pci_dev()
2519 for (i = 0; i < pi->pi_msix.table_count; i++) { in pci_snapshot_pci_dev()
2520 SNAPSHOT_VAR_OR_LEAVE(pi->pi_msix.table[i].addr, in pci_snapshot_pci_dev()
2522 SNAPSHOT_VAR_OR_LEAVE(pi->pi_msix.table[i].msg_data, in pci_snapshot_pci_dev()
2524 SNAPSHOT_VAR_OR_LEAVE(pi->pi_msix.table[i].vector_control, in pci_snapshot_pci_dev()
2539 assert(meta->dev_name != NULL); in pci_snapshot()
2541 pdi = meta->dev_data; in pci_snapshot()
2542 pde = pdi->pi_d; in pci_snapshot()
2544 if (pde->pe_snapshot == NULL) in pci_snapshot()
2549 ret = (*pde->pe_snapshot)(meta); in pci_snapshot()
2557 struct pci_devemu *pde = pdi->pi_d; in pci_pause()
2559 if (pde->pe_pause == NULL) { in pci_pause()
2564 return (*pde->pe_pause)(pdi); in pci_pause()
2570 struct pci_devemu *pde = pdi->pi_d; in pci_resume()
2572 if (pde->pe_resume == NULL) { in pci_resume()
2577 return (*pde->pe_resume)(pdi); in pci_resume()
2604 pi->pi_arg = sc; in pci_emul_dinit()
2630 struct pci_emul_dsoftc *sc = pi->pi_arg; in pci_emul_diow()
2640 sc->ioregs[offset] = value & 0xff; in pci_emul_diow()
2642 *(uint16_t *)&sc->ioregs[offset] = value & 0xffff; in pci_emul_diow()
2644 *(uint32_t *)&sc->ioregs[offset] = value; in pci_emul_diow()
2668 i = baridx - 1; /* 'memregs' index */ in pci_emul_diow()
2671 sc->memregs[i][offset] = value; in pci_emul_diow()
2673 *(uint16_t *)&sc->memregs[i][offset] = value; in pci_emul_diow()
2675 *(uint32_t *)&sc->memregs[i][offset] = value; in pci_emul_diow()
2677 *(uint64_t *)&sc->memregs[i][offset] = value; in pci_emul_diow()
2695 struct pci_emul_dsoftc *sc = pi->pi_arg; in pci_emul_dior()
2708 value = sc->ioregs[offset]; in pci_emul_dior()
2710 value = *(uint16_t *) &sc->ioregs[offset]; in pci_emul_dior()
2712 value = *(uint32_t *) &sc->ioregs[offset]; in pci_emul_dior()
2725 i = baridx - 1; /* 'memregs' index */ in pci_emul_dior()
2728 value = sc->memregs[i][offset]; in pci_emul_dior()
2730 value = *(uint16_t *) &sc->memregs[i][offset]; in pci_emul_dior()
2732 value = *(uint32_t *) &sc->memregs[i][offset]; in pci_emul_dior()
2734 value = *(uint64_t *) &sc->memregs[i][offset]; in pci_emul_dior()
2758 bus = cursor ? cursor->pi_bus : 0; in pci_next()
2759 slot = cursor ? cursor->pi_slot : 0; in pci_next()
2760 func = cursor ? (cursor->pi_func + 1) : 0; in pci_next()
2770 si = &bi->slotinfo[slot]; in pci_next()
2774 fi = &si->si_funcs[func]; in pci_next()
2775 if (fi->fi_devi == NULL) in pci_next()
2778 return (fi->fi_devi); in pci_next()