bhyve: add empty GVT-d emulation
Don't emulate anything yet. Just check if the user would like to pass an Intel GPU to the guest. Reviewed by: jhb, markj MFC after: 1 week Sponsored by: Beckhoff Automation GmbH & Co. KG Differential Revision: https://reviews.freebsd.org/D40038
This commit is contained in:
parent
9f135336f5
commit
90c3a1b662
@ -46,6 +46,7 @@ SRCS= \
|
|||||||
pci_e82545.c \
|
pci_e82545.c \
|
||||||
pci_emul.c \
|
pci_emul.c \
|
||||||
pci_fbuf.c \
|
pci_fbuf.c \
|
||||||
|
pci_gvt-d.c \
|
||||||
pci_hda.c \
|
pci_hda.c \
|
||||||
pci_hostbridge.c \
|
pci_hostbridge.c \
|
||||||
pci_irq.c \
|
pci_irq.c \
|
||||||
|
55
usr.sbin/bhyve/pci_gvt-d.c
Normal file
55
usr.sbin/bhyve/pci_gvt-d.c
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
/*-
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 Beckhoff Automation GmbH & Co. KG
|
||||||
|
* Author: Corvin Köhne <c.koehne@beckhoff.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <dev/pci/pcireg.h>
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "pci_gvt-d-opregion.h"
|
||||||
|
#include "pci_passthru.h"
|
||||||
|
|
||||||
|
#define PCI_VENDOR_INTEL 0x8086
|
||||||
|
|
||||||
|
static int
|
||||||
|
gvt_d_probe(struct pci_devinst *const pi)
|
||||||
|
{
|
||||||
|
struct passthru_softc *sc;
|
||||||
|
uint16_t vendor;
|
||||||
|
uint8_t class;
|
||||||
|
|
||||||
|
sc = pi->pi_arg;
|
||||||
|
|
||||||
|
vendor = read_config(passthru_get_sel(sc), PCIR_VENDOR, 0x02);
|
||||||
|
if (vendor != PCI_VENDOR_INTEL)
|
||||||
|
return (ENXIO);
|
||||||
|
|
||||||
|
class = read_config(passthru_get_sel(sc), PCIR_CLASS, 0x01);
|
||||||
|
if (class != PCIC_DISPLAY)
|
||||||
|
return (ENXIO);
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
gvt_d_init(struct pci_devinst *const pi __unused, nvlist_t *const nvl __unused)
|
||||||
|
{
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gvt_d_deinit(struct pci_devinst *const pi __unused)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct passthru_dev gvt_d_dev = {
|
||||||
|
.probe = gvt_d_probe,
|
||||||
|
.init = gvt_d_init,
|
||||||
|
.deinit = gvt_d_deinit,
|
||||||
|
};
|
||||||
|
PASSTHRU_DEV_SET(gvt_d_dev);
|
@ -64,7 +64,6 @@ __FBSDID("$FreeBSD$");
|
|||||||
|
|
||||||
#include <machine/vmm.h>
|
#include <machine/vmm.h>
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#include "pci_passthru.h"
|
#include "pci_passthru.h"
|
||||||
@ -82,6 +81,8 @@ __FBSDID("$FreeBSD$");
|
|||||||
|
|
||||||
static int pcifd = -1;
|
static int pcifd = -1;
|
||||||
|
|
||||||
|
SET_DECLARE(passthru_dev_set, struct passthru_dev);
|
||||||
|
|
||||||
struct passthru_softc {
|
struct passthru_softc {
|
||||||
struct pci_devinst *psc_pi;
|
struct pci_devinst *psc_pi;
|
||||||
/* ROM is handled like a BAR */
|
/* ROM is handled like a BAR */
|
||||||
@ -856,6 +857,8 @@ passthru_init(struct pci_devinst *pi, nvlist_t *nvl)
|
|||||||
{
|
{
|
||||||
int bus, slot, func, error, memflags;
|
int bus, slot, func, error, memflags;
|
||||||
struct passthru_softc *sc;
|
struct passthru_softc *sc;
|
||||||
|
struct passthru_dev **devpp;
|
||||||
|
struct passthru_dev *devp, *dev = NULL;
|
||||||
const char *value;
|
const char *value;
|
||||||
|
|
||||||
sc = NULL;
|
sc = NULL;
|
||||||
@ -919,9 +922,26 @@ passthru_init(struct pci_devinst *pi, nvlist_t *nvl)
|
|||||||
if ((error = set_pcir_handler(sc, PCIR_COMMAND, 0x04, NULL, NULL)) != 0)
|
if ((error = set_pcir_handler(sc, PCIR_COMMAND, 0x04, NULL, NULL)) != 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
|
SET_FOREACH(devpp, passthru_dev_set) {
|
||||||
|
devp = *devpp;
|
||||||
|
assert(devp->probe != NULL);
|
||||||
|
if (devp->probe(pi) == 0) {
|
||||||
|
dev = devp;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dev != NULL) {
|
||||||
|
error = dev->init(pi, nvl);
|
||||||
|
if (error != 0)
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
error = 0; /* success */
|
error = 0; /* success */
|
||||||
done:
|
done:
|
||||||
if (error) {
|
if (error) {
|
||||||
|
if (dev != NULL)
|
||||||
|
dev->deinit(pi);
|
||||||
free(sc);
|
free(sc);
|
||||||
vm_unassign_pptdev(pi->pi_vmctx, bus, slot, func);
|
vm_unassign_pptdev(pi->pi_vmctx, bus, slot, func);
|
||||||
}
|
}
|
||||||
|
@ -7,8 +7,11 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <sys/linker_set.h>
|
||||||
|
|
||||||
#include <vmmapi.h>
|
#include <vmmapi.h>
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
#include "pci_emul.h"
|
#include "pci_emul.h"
|
||||||
|
|
||||||
struct passthru_mmio_mapping {
|
struct passthru_mmio_mapping {
|
||||||
@ -21,6 +24,13 @@ struct passthru_mmio_mapping {
|
|||||||
|
|
||||||
struct passthru_softc;
|
struct passthru_softc;
|
||||||
|
|
||||||
|
struct passthru_dev {
|
||||||
|
int (*probe)(struct pci_devinst *pi);
|
||||||
|
int (*init)(struct pci_devinst *pi, nvlist_t *nvl);
|
||||||
|
void (*deinit)(struct pci_devinst *pi);
|
||||||
|
};
|
||||||
|
#define PASSTHRU_DEV_SET(x) DATA_SET(passthru_dev_set, x)
|
||||||
|
|
||||||
typedef int (*cfgread_handler)(struct passthru_softc *sc,
|
typedef int (*cfgread_handler)(struct passthru_softc *sc,
|
||||||
struct pci_devinst *pi, int coff, int bytes, uint32_t *rv);
|
struct pci_devinst *pi, int coff, int bytes, uint32_t *rv);
|
||||||
typedef int (*cfgwrite_handler)(struct passthru_softc *sc,
|
typedef int (*cfgwrite_handler)(struct passthru_softc *sc,
|
||||||
|
Loading…
Reference in New Issue
Block a user