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.h b/usr.sbin/bhyve/pci_gvt-d.h new file mode 100644 --- /dev/null +++ b/usr.sbin/bhyve/pci_gvt-d.h @@ -0,0 +1,14 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2023 Beckhoff Automation GmbH & Co. KG + * Author: Corvin Köhne + */ + +#pragma once + +#include "config.h" +#include "pci_emul.h" + +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_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,23 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2020 Beckhoff Automation GmbH & Co. KG + * Author: Corvin Köhne + */ + +#include + +#include "pci_gvt-d-opregion.h" +#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.c b/usr.sbin/bhyve/pci_passthru.c --- a/usr.sbin/bhyve/pci_passthru.c +++ b/usr.sbin/bhyve/pci_passthru.c @@ -67,12 +67,15 @@ #include "config.h" #include "debug.h" #include "mem.h" +#include "pci_gvt-d.h" #include "pci_passthru.h" #ifndef _PATH_DEVPCI #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 +854,43 @@ 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) + gvt_d_deinit(pi); +} + 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); }