diff --git a/usr.sbin/bhyve/Makefile b/usr.sbin/bhyve/Makefile --- a/usr.sbin/bhyve/Makefile +++ b/usr.sbin/bhyve/Makefile @@ -46,6 +46,7 @@ pci_emul.c \ pci_hda.c \ pci_fbuf.c \ + pci_gvt-d.c \ pci_hostbridge.c \ pci_irq.c \ pci_lpc.c \ diff --git a/usr.sbin/bhyve/pci_gvt-d.c b/usr.sbin/bhyve/pci_gvt-d.c new file mode 100644 --- /dev/null +++ b/usr.sbin/bhyve/pci_gvt-d.c @@ -0,0 +1,22 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2020 Beckhoff Automation GmbH & Co. KG + * Author: Corvin Köhne + */ + +#include + +#include "pci_gvt-d.h" +#include "pci_passthru.h" + +int +gvt_d_init(struct pci_devinst *const pi __unused, nvlist_t *const nvl __unused) +{ + return (0); +} + +void +gvt_d_deinit(struct pci_devinst *const pi __unused) +{ +} diff --git a/usr.sbin/bhyve/pci_passthru.h b/usr.sbin/bhyve/pci_passthru.h --- a/usr.sbin/bhyve/pci_passthru.h +++ b/usr.sbin/bhyve/pci_passthru.h @@ -9,6 +9,7 @@ #include +#include "config.h" #include "pci_emul.h" struct passthru_mmio_mapping { @@ -37,3 +38,5 @@ struct pcisel *passthru_get_sel(struct passthru_softc *sc); int set_pcir_handler(struct passthru_softc *sc, int reg, int len, cfgread_handler rhandler, cfgwrite_handler whandler); +int gvt_d_init(struct pci_devinst *const pi, nvlist_t *const nvl); +void gvt_d_deinit(struct pci_devinst *const pi); diff --git a/usr.sbin/bhyve/pci_passthru.c b/usr.sbin/bhyve/pci_passthru.c --- a/usr.sbin/bhyve/pci_passthru.c +++ b/usr.sbin/bhyve/pci_passthru.c @@ -64,7 +64,6 @@ #include -#include "config.h" #include "debug.h" #include "mem.h" #include "pci_passthru.h" @@ -73,6 +72,8 @@ #define _PATH_DEVPCI "/dev/pci" #endif +#define PCI_VENDOR_INTEL 0x8086 + #define LEGACY_SUPPORT 1 #define MSIX_TABLE_COUNT(ctrl) (((ctrl) & PCIM_MSIXCTRL_TABLE_SIZE) + 1) @@ -851,6 +852,45 @@ return (true); } +static int +passthru_init_quirks(struct pci_devinst *const pi, nvlist_t *const nvl) +{ + struct passthru_softc *const sc = pi->pi_arg; + + const uint16_t vendor = read_config(&sc->psc_sel, PCIR_VENDOR, 0x02); + const uint8_t class = read_config(&sc->psc_sel, PCIR_CLASS, 0x01); + + /* currently only display devices have quirks */ + if (class != PCIC_DISPLAY) + return (0); + + if (vendor == PCI_VENDOR_INTEL) + return gvt_d_init(pi, nvl); + + return (0); +} + +static void +passthru_deinit_quirks(struct pci_devinst *const pi) +{ + struct passthru_softc *const sc = pi->pi_arg; + + if (sc == NULL) + return; + + const uint16_t vendor = read_config(&sc->psc_sel, PCIR_VENDOR, 0x02); + const uint8_t class = read_config(&sc->psc_sel, PCIR_CLASS, 0x01); + + /* currently only display devices have quirks */ + if (class != PCIC_DISPLAY) + return; + + if (vendor == PCI_VENDOR_INTEL) + return gvt_d_deinit(pi); + + return; +} + static int passthru_init(struct pci_devinst *pi, nvlist_t *nvl) { @@ -919,9 +959,13 @@ if ((error = set_pcir_handler(sc, PCIR_COMMAND, 0x04, NULL, NULL)) != 0) goto done; + if ((error = passthru_init_quirks(pi, nvl)) != 0) + goto done; + error = 0; /* success */ done: if (error) { + passthru_deinit_quirks(pi); free(sc); vm_unassign_pptdev(pi->pi_vmctx, bus, slot, func); }