diff --git a/usr.sbin/bhyve/bhyve_config.5 b/usr.sbin/bhyve/bhyve_config.5 --- a/usr.sbin/bhyve/bhyve_config.5 +++ b/usr.sbin/bhyve/bhyve_config.5 @@ -534,6 +534,20 @@ Settings for the COM4 serial port device. .It Va pc-testdev Ta bool Ta false Ta Enable the PC debug/test device. +.It Va pcir.* Ta integer Ta Ta +Values of PCI register. +It also accepts the value +.Ar host +to use the pci id of the host system. +This value is required for the Intel GOP driver to work properly. +.Bl -column "subvendor" "Default" +.It Sy Name Ta Sy Default +.It Va vendor Ta 0x8086 +.It Va device Ta 0x7000 +.It Va revid Ta 0 +.It Va subvendor Ta 0 +.It Va subdevice Ta 0 +.El .El .Ss NVMe Controller Settings Each NVMe controller supports a single storage device. diff --git a/usr.sbin/bhyve/pci_lpc.c b/usr.sbin/bhyve/pci_lpc.c --- a/usr.sbin/bhyve/pci_lpc.c +++ b/usr.sbin/bhyve/pci_lpc.c @@ -51,6 +51,7 @@ #include "pci_emul.h" #include "pci_irq.h" #include "pci_lpc.h" +#include "pci_passthru.h" #include "pctestdev.h" #include "uart_emul.h" @@ -432,10 +433,35 @@ #define LPC_DEV 0x7000 #define LPC_VENDOR 0x8086 +#define LPC_REVID 0x00 +#define LPC_SUBVEND_0 0x0000 +#define LPC_SUBDEV_0 0x0000 static int -pci_lpc_init(struct pci_devinst *pi, nvlist_t *nvl __unused) +pci_lpc_get_sel(struct pcisel *const sel) { + assert(sel != NULL); + + memset(sel, 0, sizeof(*sel)); + + for (uint8_t slot = 0; slot <= PCI_SLOTMAX; ++slot) { + sel->pc_dev = slot; + if ((read_config(sel, PCIR_CLASS, 1) == PCIC_BRIDGE) && + (read_config(sel, PCIR_SUBCLASS, 1) == PCIS_BRIDGE_ISA)) { + return (0); + } + } + + return (-1); +} + +static int +pci_lpc_init(struct pci_devinst *pi, nvlist_t *nvl) +{ + struct pcisel sel = { 0 }; + uint16_t device, subdevice, subvendor, vendor; + uint8_t revid; + /* * Do not allow more than one LPC bridge to be configured. */ @@ -457,11 +483,25 @@ if (lpc_init(pi->pi_vmctx) != 0) return (-1); + if (pci_lpc_get_sel(&sel) != 0) + return (-1); + + vendor = pci_config_read_reg(&sel, nvl, PCIR_VENDOR, 2, LPC_VENDOR); + device = pci_config_read_reg(&sel, nvl, PCIR_DEVICE, 2, LPC_DEV); + revid = pci_config_read_reg(&sel, nvl, PCIR_REVID, 1, LPC_REVID); + subvendor = pci_config_read_reg(&sel, nvl, PCIR_SUBVEND_0, 2, + LPC_SUBVEND_0); + subdevice = pci_config_read_reg(&sel, nvl, PCIR_SUBDEV_0, 2, + LPC_SUBDEV_0); + /* initialize config space */ - pci_set_cfgdata16(pi, PCIR_DEVICE, LPC_DEV); - pci_set_cfgdata16(pi, PCIR_VENDOR, LPC_VENDOR); + pci_set_cfgdata16(pi, PCIR_VENDOR, vendor); + pci_set_cfgdata16(pi, PCIR_DEVICE, device); pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_BRIDGE); pci_set_cfgdata8(pi, PCIR_SUBCLASS, PCIS_BRIDGE_ISA); + pci_set_cfgdata8(pi, PCIR_REVID, revid); + pci_set_cfgdata16(pi, PCIR_SUBVEND_0, subvendor); + pci_set_cfgdata16(pi, PCIR_SUBDEV_0, subdevice); lpc_bridge = pi;