pci_emul.c (01d53c34e79afaad757088e5fbb4846f02a8beca) | pci_emul.c (55c13f6e7a412cc4bd0ea3fc183cd7c5c2348f01) |
---|---|
1/*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2011 NetApp, Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 38 unchanged lines hidden (view full) --- 47#include <machine/vmm_snapshot.h> 48#include <vmmapi.h> 49 50#include "acpi.h" 51#include "bhyverun.h" 52#include "config.h" 53#include "debug.h" 54#include "inout.h" | 1/*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2011 NetApp, Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 38 unchanged lines hidden (view full) --- 47#include <machine/vmm_snapshot.h> 48#include <vmmapi.h> 49 50#include "acpi.h" 51#include "bhyverun.h" 52#include "config.h" 53#include "debug.h" 54#include "inout.h" |
55#include "ioapic.h" | 55#ifdef __amd64__ 56#include "amd64/ioapic.h" 57#endif |
56#include "mem.h" 57#include "pci_emul.h" | 58#include "mem.h" 59#include "pci_emul.h" |
58#include "pci_irq.h" 59#include "pci_lpc.h" | 60#ifdef __amd64__ 61#include "amd64/pci_irq.h" 62#include "amd64/pci_lpc.h" 63#endif |
60#include "pci_passthru.h" 61#include "qemu_fwcfg.h" 62 63#define CONF1_ADDR_PORT 0x0cf8 64#define CONF1_DATA_PORT 0x0cfc 65 66#define CONF1_ENABLE 0x80000000ul 67 --- 70 unchanged lines hidden (view full) --- 138/* 139 * OVMF always uses 0xC0000000 as base address for 32 bit PCI MMIO. Don't 140 * change this address without changing it in OVMF. 141 */ 142#define PCI_EMUL_MEMBASE32 0xC0000000 143#define PCI_EMUL_MEMLIMIT32 PCI_EMUL_ECFG_BASE 144#define PCI_EMUL_MEMSIZE64 (32*GB) 145 | 64#include "pci_passthru.h" 65#include "qemu_fwcfg.h" 66 67#define CONF1_ADDR_PORT 0x0cf8 68#define CONF1_DATA_PORT 0x0cfc 69 70#define CONF1_ENABLE 0x80000000ul 71 --- 70 unchanged lines hidden (view full) --- 142/* 143 * OVMF always uses 0xC0000000 as base address for 32 bit PCI MMIO. Don't 144 * change this address without changing it in OVMF. 145 */ 146#define PCI_EMUL_MEMBASE32 0xC0000000 147#define PCI_EMUL_MEMLIMIT32 PCI_EMUL_ECFG_BASE 148#define PCI_EMUL_MEMSIZE64 (32*GB) 149 |
146static struct pci_devemu *pci_emul_finddev(const char *name); | 150#ifdef __amd64__ |
147static void pci_lintr_route(struct pci_devinst *pi); 148static void pci_lintr_update(struct pci_devinst *pi); | 151static void pci_lintr_route(struct pci_devinst *pi); 152static void pci_lintr_update(struct pci_devinst *pi); |
153#endif 154 155static struct pci_devemu *pci_emul_finddev(const char *name); |
|
149static void pci_cfgrw(int in, int bus, int slot, int func, int coff, 150 int bytes, uint32_t *val); 151 152static __inline void 153CFGWRITE(struct pci_devinst *pi, int coff, uint32_t val, int bytes) 154{ 155 156 if (bytes == 1) --- 899 unchanged lines hidden (view full) --- 1056 int err; 1057 1058 pdi = calloc(1, sizeof(struct pci_devinst)); 1059 1060 pdi->pi_vmctx = ctx; 1061 pdi->pi_bus = bus; 1062 pdi->pi_slot = slot; 1063 pdi->pi_func = func; | 156static void pci_cfgrw(int in, int bus, int slot, int func, int coff, 157 int bytes, uint32_t *val); 158 159static __inline void 160CFGWRITE(struct pci_devinst *pi, int coff, uint32_t val, int bytes) 161{ 162 163 if (bytes == 1) --- 899 unchanged lines hidden (view full) --- 1063 int err; 1064 1065 pdi = calloc(1, sizeof(struct pci_devinst)); 1066 1067 pdi->pi_vmctx = ctx; 1068 pdi->pi_bus = bus; 1069 pdi->pi_slot = slot; 1070 pdi->pi_func = func; |
1071#ifdef __amd64__ |
|
1064 pthread_mutex_init(&pdi->pi_lintr.lock, NULL); 1065 pdi->pi_lintr.pin = 0; 1066 pdi->pi_lintr.state = IDLE; 1067 pdi->pi_lintr.pirq_pin = 0; 1068 pdi->pi_lintr.ioapic_irq = 0; | 1072 pthread_mutex_init(&pdi->pi_lintr.lock, NULL); 1073 pdi->pi_lintr.pin = 0; 1074 pdi->pi_lintr.state = IDLE; 1075 pdi->pi_lintr.pirq_pin = 0; 1076 pdi->pi_lintr.ioapic_irq = 0; |
1077#endif |
|
1069 pdi->pi_d = pde; 1070 snprintf(pdi->pi_name, PI_NAMESZ, "%s@pci.%d.%d.%d", pde->pe_emu, bus, 1071 slot, func); 1072 1073 /* Disable legacy interrupts */ 1074 pci_set_cfgdata8(pdi, PCIR_INTLINE, 255); 1075 pci_set_cfgdata8(pdi, PCIR_INTPIN, 0); 1076 --- 121 unchanged lines hidden (view full) --- 1198 rwmask = PCIM_MSIXCTRL_MSIX_ENABLE | PCIM_MSIXCTRL_FUNCTION_MASK; 1199 msgctrl = pci_get_cfgdata16(pi, offset); 1200 msgctrl &= ~rwmask; 1201 msgctrl |= val & rwmask; 1202 val = msgctrl; 1203 1204 pi->pi_msix.enabled = val & PCIM_MSIXCTRL_MSIX_ENABLE; 1205 pi->pi_msix.function_mask = val & PCIM_MSIXCTRL_FUNCTION_MASK; | 1078 pdi->pi_d = pde; 1079 snprintf(pdi->pi_name, PI_NAMESZ, "%s@pci.%d.%d.%d", pde->pe_emu, bus, 1080 slot, func); 1081 1082 /* Disable legacy interrupts */ 1083 pci_set_cfgdata8(pdi, PCIR_INTLINE, 255); 1084 pci_set_cfgdata8(pdi, PCIR_INTPIN, 0); 1085 --- 121 unchanged lines hidden (view full) --- 1207 rwmask = PCIM_MSIXCTRL_MSIX_ENABLE | PCIM_MSIXCTRL_FUNCTION_MASK; 1208 msgctrl = pci_get_cfgdata16(pi, offset); 1209 msgctrl &= ~rwmask; 1210 msgctrl |= val & rwmask; 1211 val = msgctrl; 1212 1213 pi->pi_msix.enabled = val & PCIM_MSIXCTRL_MSIX_ENABLE; 1214 pi->pi_msix.function_mask = val & PCIM_MSIXCTRL_FUNCTION_MASK; |
1215#ifdef __amd64__ |
|
1206 pci_lintr_update(pi); | 1216 pci_lintr_update(pi); |
1217#endif |
|
1207 } 1208 1209 CFGWRITE(pi, offset, val, bytes); 1210} 1211 1212static void 1213msicap_cfgwrite(struct pci_devinst *pi, int capoff, int offset, 1214 int bytes, uint32_t val) --- 25 unchanged lines hidden (view full) --- 1240 pi->pi_msi.enabled = msgctrl & PCIM_MSICTRL_MSI_ENABLE ? 1 : 0; 1241 if (pi->pi_msi.enabled) { 1242 pi->pi_msi.addr = addrlo; 1243 pi->pi_msi.msg_data = msgdata; 1244 pi->pi_msi.maxmsgnum = 1 << (mme >> 4); 1245 } else { 1246 pi->pi_msi.maxmsgnum = 0; 1247 } | 1218 } 1219 1220 CFGWRITE(pi, offset, val, bytes); 1221} 1222 1223static void 1224msicap_cfgwrite(struct pci_devinst *pi, int capoff, int offset, 1225 int bytes, uint32_t val) --- 25 unchanged lines hidden (view full) --- 1251 pi->pi_msi.enabled = msgctrl & PCIM_MSICTRL_MSI_ENABLE ? 1 : 0; 1252 if (pi->pi_msi.enabled) { 1253 pi->pi_msi.addr = addrlo; 1254 pi->pi_msi.msg_data = msgdata; 1255 pi->pi_msi.maxmsgnum = 1 << (mme >> 4); 1256 } else { 1257 pi->pi_msi.maxmsgnum = 0; 1258 } |
1259#ifdef __amd64__ |
|
1248 pci_lintr_update(pi); | 1260 pci_lintr_update(pi); |
1261#endif |
|
1249} 1250 1251static void 1252pciecap_cfgwrite(struct pci_devinst *pi, int capoff __unused, int offset, 1253 int bytes, uint32_t val) 1254{ 1255 1256 /* XXX don't write to the readonly parts */ --- 276 unchanged lines hidden (view full) --- 1533 bi->memlimit32 = pci_emul_membase32; 1534 1535 pci_emul_membase64 += BUSMEM64_ROUNDUP; 1536 pci_emul_membase64 = roundup2(pci_emul_membase64, 1537 BUSMEM64_ROUNDUP); 1538 bi->memlimit64 = pci_emul_membase64; 1539 } 1540 | 1262} 1263 1264static void 1265pciecap_cfgwrite(struct pci_devinst *pi, int capoff __unused, int offset, 1266 int bytes, uint32_t val) 1267{ 1268 1269 /* XXX don't write to the readonly parts */ --- 276 unchanged lines hidden (view full) --- 1546 bi->memlimit32 = pci_emul_membase32; 1547 1548 pci_emul_membase64 += BUSMEM64_ROUNDUP; 1549 pci_emul_membase64 = roundup2(pci_emul_membase64, 1550 BUSMEM64_ROUNDUP); 1551 bi->memlimit64 = pci_emul_membase64; 1552 } 1553 |
1554#ifdef __amd64__ |
|
1541 /* 1542 * PCI backends are initialized before routing INTx interrupts 1543 * so that LPC devices are able to reserve ISA IRQs before 1544 * routing PIRQ pins. 1545 */ 1546 for (bus = 0; bus < MAXBUSES; bus++) { 1547 if ((bi = pci_businfo[bus]) == NULL) 1548 continue; --- 4 unchanged lines hidden (view full) --- 1553 fi = &si->si_funcs[func]; 1554 if (fi->fi_devi == NULL) 1555 continue; 1556 pci_lintr_route(fi->fi_devi); 1557 } 1558 } 1559 } 1560 lpc_pirq_routed(); | 1555 /* 1556 * PCI backends are initialized before routing INTx interrupts 1557 * so that LPC devices are able to reserve ISA IRQs before 1558 * routing PIRQ pins. 1559 */ 1560 for (bus = 0; bus < MAXBUSES; bus++) { 1561 if ((bi = pci_businfo[bus]) == NULL) 1562 continue; --- 4 unchanged lines hidden (view full) --- 1567 fi = &si->si_funcs[func]; 1568 if (fi->fi_devi == NULL) 1569 continue; 1570 pci_lintr_route(fi->fi_devi); 1571 } 1572 } 1573 } 1574 lpc_pirq_routed(); |
1575#endif |
|
1561 1562 if ((error = init_bootorder()) != 0) { 1563 warnx("%s: Unable to init bootorder", __func__); 1564 return (error); 1565 } 1566 1567 /* 1568 * The guest physical memory map looks like the following: --- 27 unchanged lines hidden (view full) --- 1596 mr.size = PCI_EMUL_ECFG_SIZE; 1597 mr.handler = pci_emul_ecfg_handler; 1598 error = register_mem(&mr); 1599 assert(error == 0); 1600 1601 return (0); 1602} 1603 | 1576 1577 if ((error = init_bootorder()) != 0) { 1578 warnx("%s: Unable to init bootorder", __func__); 1579 return (error); 1580 } 1581 1582 /* 1583 * The guest physical memory map looks like the following: --- 27 unchanged lines hidden (view full) --- 1611 mr.size = PCI_EMUL_ECFG_SIZE; 1612 mr.handler = pci_emul_ecfg_handler; 1613 error = register_mem(&mr); 1614 assert(error == 0); 1615 1616 return (0); 1617} 1618 |
1619#ifdef __amd64__ |
|
1604static void 1605pci_apic_prt_entry(int bus __unused, int slot, int pin, int pirq_pin __unused, 1606 int ioapic_irq, void *arg __unused) 1607{ 1608 1609 dsdt_line(" Package ()"); 1610 dsdt_line(" {"); 1611 dsdt_line(" 0x%X,", slot << 16 | 0xffff); --- 16 unchanged lines hidden (view full) --- 1628 dsdt_line(" {"); 1629 dsdt_line(" 0x%X,", slot << 16 | 0xffff); 1630 dsdt_line(" 0x%02X,", pin - 1); 1631 dsdt_line(" %s,", name); 1632 dsdt_line(" 0x00"); 1633 dsdt_line(" },"); 1634 free(name); 1635} | 1620static void 1621pci_apic_prt_entry(int bus __unused, int slot, int pin, int pirq_pin __unused, 1622 int ioapic_irq, void *arg __unused) 1623{ 1624 1625 dsdt_line(" Package ()"); 1626 dsdt_line(" {"); 1627 dsdt_line(" 0x%X,", slot << 16 | 0xffff); --- 16 unchanged lines hidden (view full) --- 1644 dsdt_line(" {"); 1645 dsdt_line(" 0x%X,", slot << 16 | 0xffff); 1646 dsdt_line(" 0x%02X,", pin - 1); 1647 dsdt_line(" %s,", name); 1648 dsdt_line(" 0x00"); 1649 dsdt_line(" },"); 1650 free(name); 1651} |
1652#endif |
|
1636 1637/* 1638 * A bhyve virtual machine has a flat PCI hierarchy with a root port 1639 * corresponding to each PCI bus. 1640 */ 1641static void 1642pci_bus_write_dsdt(int bus) 1643{ 1644 struct businfo *bi; 1645 struct slotinfo *si; 1646 struct pci_devinst *pi; | 1653 1654/* 1655 * A bhyve virtual machine has a flat PCI hierarchy with a root port 1656 * corresponding to each PCI bus. 1657 */ 1658static void 1659pci_bus_write_dsdt(int bus) 1660{ 1661 struct businfo *bi; 1662 struct slotinfo *si; 1663 struct pci_devinst *pi; |
1647 int count, func, slot; | 1664 int func, slot; |
1648 1649 /* 1650 * If there are no devices on this 'bus' then just return. 1651 */ 1652 if ((bi = pci_businfo[bus]) == NULL) { 1653 /* 1654 * Bus 0 is special because it decodes the I/O ports used 1655 * for PCI config space access even if there are no devices --- 86 unchanged lines hidden (view full) --- 1742 dsdt_line(" 0x%016lX, // Range Maximum\n", 1743 bi->memlimit64 - 1); 1744 dsdt_line(" 0x0000000000000000, // Translation Offset"); 1745 dsdt_line(" 0x%016lX, // Length\n", 1746 bi->memlimit64 - bi->membase64); 1747 dsdt_line(" ,, , AddressRangeMemory, TypeStatic)"); 1748 dsdt_line(" })"); 1749 | 1665 1666 /* 1667 * If there are no devices on this 'bus' then just return. 1668 */ 1669 if ((bi = pci_businfo[bus]) == NULL) { 1670 /* 1671 * Bus 0 is special because it decodes the I/O ports used 1672 * for PCI config space access even if there are no devices --- 86 unchanged lines hidden (view full) --- 1759 dsdt_line(" 0x%016lX, // Range Maximum\n", 1760 bi->memlimit64 - 1); 1761 dsdt_line(" 0x0000000000000000, // Translation Offset"); 1762 dsdt_line(" 0x%016lX, // Length\n", 1763 bi->memlimit64 - bi->membase64); 1764 dsdt_line(" ,, , AddressRangeMemory, TypeStatic)"); 1765 dsdt_line(" })"); 1766 |
1750 count = pci_count_lintr(bus); 1751 if (count != 0) { | 1767#ifdef __amd64__ 1768 if (pci_count_lintr(bus) != 0) { |
1752 dsdt_indent(2); 1753 dsdt_line("Name (PPRT, Package ()"); 1754 dsdt_line("{"); 1755 pci_walk_lintr(bus, pci_pirq_prt_entry, NULL); 1756 dsdt_line("})"); 1757 dsdt_line("Name (APRT, Package ()"); 1758 dsdt_line("{"); 1759 pci_walk_lintr(bus, pci_apic_prt_entry, NULL); --- 6 unchanged lines hidden (view full) --- 1766 dsdt_line(" }"); 1767 dsdt_line(" Else"); 1768 dsdt_line(" {"); 1769 dsdt_line(" Return (PPRT)"); 1770 dsdt_line(" }"); 1771 dsdt_line("}"); 1772 dsdt_unindent(2); 1773 } | 1769 dsdt_indent(2); 1770 dsdt_line("Name (PPRT, Package ()"); 1771 dsdt_line("{"); 1772 pci_walk_lintr(bus, pci_pirq_prt_entry, NULL); 1773 dsdt_line("})"); 1774 dsdt_line("Name (APRT, Package ()"); 1775 dsdt_line("{"); 1776 pci_walk_lintr(bus, pci_apic_prt_entry, NULL); --- 6 unchanged lines hidden (view full) --- 1783 dsdt_line(" }"); 1784 dsdt_line(" Else"); 1785 dsdt_line(" {"); 1786 dsdt_line(" Return (PPRT)"); 1787 dsdt_line(" }"); 1788 dsdt_line("}"); 1789 dsdt_unindent(2); 1790 } |
1791#endif |
|
1774 1775 dsdt_indent(2); 1776 for (slot = 0; slot < MAXSLOTS; slot++) { 1777 si = &bi->slotinfo[slot]; 1778 for (func = 0; func < MAXFUNCS; func++) { 1779 pi = si->si_funcs[func].fi_devi; 1780 if (pi != NULL && pi->pi_d->pe_write_dsdt != NULL) 1781 pi->pi_d->pe_write_dsdt(pi); --- 79 unchanged lines hidden (view full) --- 1861{ 1862 1863 if (pci_msi_enabled(pi) && index < pci_msi_maxmsgnum(pi)) { 1864 vm_lapic_msi(pi->pi_vmctx, pi->pi_msi.addr, 1865 pi->pi_msi.msg_data + index); 1866 } 1867} 1868 | 1792 1793 dsdt_indent(2); 1794 for (slot = 0; slot < MAXSLOTS; slot++) { 1795 si = &bi->slotinfo[slot]; 1796 for (func = 0; func < MAXFUNCS; func++) { 1797 pi = si->si_funcs[func].fi_devi; 1798 if (pi != NULL && pi->pi_d->pe_write_dsdt != NULL) 1799 pi->pi_d->pe_write_dsdt(pi); --- 79 unchanged lines hidden (view full) --- 1879{ 1880 1881 if (pci_msi_enabled(pi) && index < pci_msi_maxmsgnum(pi)) { 1882 vm_lapic_msi(pi->pi_vmctx, pi->pi_msi.addr, 1883 pi->pi_msi.msg_data + index); 1884 } 1885} 1886 |
1887#ifdef __amd64__ |
|
1869static bool 1870pci_lintr_permitted(struct pci_devinst *pi) 1871{ 1872 uint16_t cmd; 1873 1874 cmd = pci_get_cfgdata16(pi, PCIR_COMMAND); 1875 return (!(pi->pi_msi.enabled || pi->pi_msix.enabled || 1876 (cmd & PCIM_CMD_INTxDIS))); --- 144 unchanged lines hidden (view full) --- 2021 for (pin = 0; pin < 4; pin++) { 2022 ii = &si->si_intpins[pin]; 2023 if (ii->ii_count != 0) 2024 cb(bus, slot, pin + 1, ii->ii_pirq_pin, 2025 ii->ii_ioapic_irq, arg); 2026 } 2027 } 2028} | 1888static bool 1889pci_lintr_permitted(struct pci_devinst *pi) 1890{ 1891 uint16_t cmd; 1892 1893 cmd = pci_get_cfgdata16(pi, PCIR_COMMAND); 1894 return (!(pi->pi_msi.enabled || pi->pi_msix.enabled || 1895 (cmd & PCIM_CMD_INTxDIS))); --- 144 unchanged lines hidden (view full) --- 2040 for (pin = 0; pin < 4; pin++) { 2041 ii = &si->si_intpins[pin]; 2042 if (ii->ii_count != 0) 2043 cb(bus, slot, pin + 1, ii->ii_pirq_pin, 2044 ii->ii_ioapic_irq, arg); 2045 } 2046 } 2047} |
2048#endif /* __amd64__ */ |
|
2029 2030/* 2031 * Return 1 if the emulated device in 'slot' is a multi-function device. 2032 * Return 0 otherwise. 2033 */ 2034static int 2035pci_emul_is_mfdev(int bus, int slot) 2036{ --- 88 unchanged lines hidden (view full) --- 2125 unregister_bar(pi, i); 2126 } 2127 break; 2128 default: 2129 assert(0); 2130 } 2131 } 2132 | 2049 2050/* 2051 * Return 1 if the emulated device in 'slot' is a multi-function device. 2052 * Return 0 otherwise. 2053 */ 2054static int 2055pci_emul_is_mfdev(int bus, int slot) 2056{ --- 88 unchanged lines hidden (view full) --- 2145 unregister_bar(pi, i); 2146 } 2147 break; 2148 default: 2149 assert(0); 2150 } 2151 } 2152 |
2153#ifdef __amd64__ |
|
2133 /* 2134 * If INTx has been unmasked and is pending, assert the 2135 * interrupt. 2136 */ 2137 pci_lintr_update(pi); | 2154 /* 2155 * If INTx has been unmasked and is pending, assert the 2156 * interrupt. 2157 */ 2158 pci_lintr_update(pi); |
2159#endif |
|
2138} 2139 2140static void 2141pci_emul_cmdsts_write(struct pci_devinst *pi, int coff, uint32_t new, int bytes) 2142{ 2143 int rshift; 2144 uint32_t cmd, old, readonly; 2145 --- 560 unchanged lines hidden --- | 2160} 2161 2162static void 2163pci_emul_cmdsts_write(struct pci_devinst *pi, int coff, uint32_t new, int bytes) 2164{ 2165 int rshift; 2166 uint32_t cmd, old, readonly; 2167 --- 560 unchanged lines hidden --- |