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 ---