Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F109330332
D33011.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
16 KB
Referenced Files
None
Subscribers
None
D33011.diff
View Options
diff --git a/lib/libvmmapi/vmmapi.h b/lib/libvmmapi/vmmapi.h
--- a/lib/libvmmapi/vmmapi.h
+++ b/lib/libvmmapi/vmmapi.h
@@ -180,6 +180,8 @@
vm_paddr_t gpa, size_t len, vm_paddr_t hpa);
int vm_unmap_pptdev_mmio(struct vmctx *ctx, int bus, int slot, int func,
vm_paddr_t gpa, size_t len);
+int vm_get_memory_region_info(struct vmctx *const ctx, vm_paddr_t *const base,
+ vm_paddr_t *const size, const enum vm_memory_region_type type);
int vm_setup_pptdev_msi(struct vmctx *ctx, int vcpu, int bus, int slot,
int func, uint64_t addr, uint64_t msg, int numvec);
int vm_setup_pptdev_msix(struct vmctx *ctx, int vcpu, int bus, int slot,
diff --git a/lib/libvmmapi/vmmapi.c b/lib/libvmmapi/vmmapi.c
--- a/lib/libvmmapi/vmmapi.c
+++ b/lib/libvmmapi/vmmapi.c
@@ -1012,6 +1012,25 @@
return (ioctl(ctx->fd, VM_UNMAP_PPTDEV_MMIO, &pptmmio));
}
+int
+vm_get_memory_region_info(struct vmctx *const ctx, vm_paddr_t *const base,
+ vm_paddr_t *const size, const enum vm_memory_region_type type)
+{
+ struct vm_memory_region_info memory_region_info;
+
+ bzero(&memory_region_info, sizeof(memory_region_info));
+ memory_region_info.type = type;
+
+ const int error = ioctl(ctx->fd, VM_GET_MEMORY_REGION_INFO, &memory_region_info);
+
+ if (base)
+ *base = memory_region_info.base;
+ if (size)
+ *size = memory_region_info.size;
+
+ return (error);
+}
+
int
vm_setup_pptdev_msi(struct vmctx *ctx, int vcpu, int bus, int slot, int func,
uint64_t addr, uint64_t msg, int numvec)
@@ -1687,7 +1706,7 @@
VM_SET_CAPABILITY, VM_GET_CAPABILITY, VM_BIND_PPTDEV,
VM_UNBIND_PPTDEV, VM_MAP_PPTDEV_MMIO, VM_PPTDEV_MSI,
VM_PPTDEV_MSIX, VM_UNMAP_PPTDEV_MMIO, VM_PPTDEV_DISABLE_MSIX,
- VM_INJECT_NMI, VM_STATS, VM_STAT_DESC,
+ VM_GET_MEMORY_REGION_INFO, VM_INJECT_NMI, VM_STATS, VM_STAT_DESC,
VM_SET_X2APIC_STATE, VM_GET_X2APIC_STATE,
VM_GET_HPET_CAPABILITIES, VM_GET_GPA_PMAP, VM_GLA2GPA,
VM_GLA2GPA_NOFAULT,
diff --git a/sys/amd64/include/vmm.h b/sys/amd64/include/vmm.h
--- a/sys/amd64/include/vmm.h
+++ b/sys/amd64/include/vmm.h
@@ -741,6 +741,12 @@
} u;
};
+enum vm_memory_region_type {
+ MEMORY_REGION_INTEL_GSM,
+ MEMORY_REGION_INTEL_OPREGION,
+ MEMORY_REGION_TPM_CONTROL_ADDRESS,
+};
+
/* APIs to inject faults into the guest */
void vm_inject_fault(void *vm, int vcpuid, int vector, int errcode_valid,
int errcode);
diff --git a/sys/amd64/include/vmm_dev.h b/sys/amd64/include/vmm_dev.h
--- a/sys/amd64/include/vmm_dev.h
+++ b/sys/amd64/include/vmm_dev.h
@@ -146,6 +146,17 @@
size_t len;
};
+struct vm_memory_region_info {
+ vm_paddr_t base;
+ vm_paddr_t size;
+ enum vm_memory_region_type type;
+};
+
+#ifdef _KERNEL
+extern vm_paddr_t intel_graphics_stolen_base;
+extern vm_paddr_t intel_graphics_stolen_size;
+#endif
+
struct vm_pptdev_msi {
int vcpu;
int bus;
@@ -309,6 +320,7 @@
IOCNUM_PPTDEV_MSIX = 44,
IOCNUM_PPTDEV_DISABLE_MSIX = 45,
IOCNUM_UNMAP_PPTDEV_MMIO = 46,
+ IOCNUM_GET_MEMORY_REGION_INFO = 47,
/* statistics */
IOCNUM_VM_STATS = 50,
@@ -427,6 +439,8 @@
_IOW('v', IOCNUM_PPTDEV_DISABLE_MSIX, struct vm_pptdev)
#define VM_UNMAP_PPTDEV_MMIO \
_IOW('v', IOCNUM_UNMAP_PPTDEV_MMIO, struct vm_pptdev_mmio)
+#define VM_GET_MEMORY_REGION_INFO \
+ _IOWR('v', IOCNUM_GET_MEMORY_REGION_INFO, struct vm_memory_region_info)
#define VM_INJECT_NMI \
_IOW('v', IOCNUM_INJECT_NMI, struct vm_nmi)
#define VM_STATS \
diff --git a/sys/amd64/vmm/intel/intelgpu.h b/sys/amd64/vmm/intel/intelgpu.h
new file mode 100644
--- /dev/null
+++ b/sys/amd64/vmm/intel/intelgpu.h
@@ -0,0 +1,185 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2021 Beckhoff Automation GmbH & Co. KG
+ * Author: Corvin Köhne <c.koehne@beckhoff.com>
+ */
+
+#pragma once
+
+/*
+ * See
+ * <https://github.com/tianocore/edk2-platforms/blob/82979ab1ca44101e0b92a9c4bda1dfe64a8249f6/Silicon/Intel/IntelSiliconPkg/Include/IndustryStandard/IgdOpRegion.h>
+ */
+
+#define IGD_OPREGION_HEADER_SIGN "IntelGraphicsMem"
+#define IGD_OPREGION_HEADER_MBOX1 BIT0
+#define IGD_OPREGION_HEADER_MBOX2 BIT1
+#define IGD_OPREGION_HEADER_MBOX3 BIT2
+#define IGD_OPREGION_HEADER_MBOX4 BIT3
+#define IGD_OPREGION_HEADER_MBOX5 BIT4
+
+#define IGD_OPREGION_VBT_SIZE_6K (6 * 1024UL)
+
+/**
+ OpRegion structures:
+ Sub-structures define the different parts of the OpRegion followed by the
+ main structure representing the entire OpRegion.
+
+ @note These structures are packed to 1 byte offsets because the exact
+ data location is required by the supporting design specification due to
+ the fact that the data is used by ASL and Graphics driver code compiled
+ separately.
+**/
+#pragma pack(1)
+///
+/// OpRegion Mailbox 0 Header structure. The OpRegion Header is used to
+/// identify a block of memory as the graphics driver OpRegion.
+/// Offset 0x0, Size 0x100
+///
+struct igd_opregion_header {
+ int8_t sign[0x10]; ///< Offset 0x00 OpRegion Signature
+ uint32_t size; ///< Offset 0x10 OpRegion Size
+ uint32_t over; ///< Offset 0x14 OpRegion Structure Version
+ uint8_t sver[0x20]; ///< Offset 0x18 System BIOS Build Version
+ uint8_t vver[0x10]; ///< Offset 0x38 Video BIOS Build Version
+ uint8_t gver[0x10]; ///< Offset 0x48 Graphic Driver Build Version
+ uint32_t mbox; ///< Offset 0x58 Supported Mailboxes
+ uint32_t dmod; ///< Offset 0x5C Driver Model
+ uint32_t pcon; ///< Offset 0x60 Platform Configuration
+ int16_t dver[0x10]; ///< Offset 0x64 GOP Version
+ uint8_t rm01[0x7C]; ///< Offset 0x84 Reserved Must be zero
+};
+
+///
+/// OpRegion Mailbox 1 - Public ACPI Methods
+/// Offset 0x100, Size 0x100
+///
+struct igd_opregion_mbox1 {
+ uint32_t drdy; ///< Offset 0x100 Driver Readiness
+ uint32_t csts; ///< Offset 0x104 Status
+ uint32_t cevt; ///< Offset 0x108 Current Event
+ uint8_t rm11[0x14]; ///< Offset 0x10C Reserved Must be Zero
+ uint32_t didl[8]; ///< Offset 0x120 Supported Display Devices ID List
+ uint32_t
+ cpdl[8]; ///< Offset 0x140 Currently Attached Display Devices List
+ uint32_t
+ cadl[8]; ///< Offset 0x160 Currently Active Display Devices List
+ uint32_t nadl[8]; ///< Offset 0x180 Next Active Devices List
+ uint32_t aslp; ///< Offset 0x1A0 ASL Sleep Time Out
+ uint32_t tidx; ///< Offset 0x1A4 Toggle Table Index
+ uint32_t chpd; ///< Offset 0x1A8 Current Hotplug Enable Indicator
+ uint32_t clid; ///< Offset 0x1AC Current Lid State Indicator
+ uint32_t cdck; ///< Offset 0x1B0 Current Docking State Indicator
+ uint32_t sxsw; ///< Offset 0x1B4 Display Switch Notification on Sx
+ ///< StateResume
+ uint32_t evts; ///< Offset 0x1B8 Events supported by ASL
+ uint32_t cnot; ///< Offset 0x1BC Current OS Notification
+ uint32_t NRDY; ///< Offset 0x1C0 Driver Status
+ uint8_t did2[0x1C]; ///< Offset 0x1C4 Extended Supported Devices ID
+ ///< List(DOD)
+ uint8_t
+ cpd2[0x1C]; ///< Offset 0x1E0 Extended Attached Display Devices List
+ uint8_t rm12[4]; ///< Offset 0x1FC - 0x1FF Reserved Must be zero
+};
+
+///
+/// OpRegion Mailbox 2 - Software SCI Interface
+/// Offset 0x200, Size 0x100
+///
+struct igd_opregion_mbox2 {
+ uint32_t scic; ///< Offset 0x200 Software SCI Command / Status / Data
+ uint32_t parm; ///< Offset 0x204 Software SCI Parameters
+ uint32_t dslp; ///< Offset 0x208 Driver Sleep Time Out
+ uint8_t rm21[0xF4]; ///< Offset 0x20C - 0x2FF Reserved Must be zero
+};
+
+///
+/// OpRegion Mailbox 3 - BIOS/Driver Notification - ASLE Support
+/// Offset 0x300, Size 0x100
+///
+struct igd_opregion_mbox3 {
+ uint32_t ardy; ///< Offset 0x300 Driver Readiness
+ uint32_t aslc; ///< Offset 0x304 ASLE Interrupt Command / Status
+ uint32_t tche; ///< Offset 0x308 Technology Enabled Indicator
+ uint32_t alsi; ///< Offset 0x30C Current ALS Luminance Reading
+ uint32_t bclp; ///< Offset 0x310 Requested Backlight Brightness
+ uint32_t pfit; ///< Offset 0x314 Panel Fitting State or Request
+ uint32_t cblv; ///< Offset 0x318 Current Brightness Level
+ uint16_t bclm[0x14]; ///< Offset 0x31C Backlight Brightness Levels Duty
+ ///< Cycle Mapping Table
+ uint32_t cpfm; ///< Offset 0x344 Current Panel Fitting Mode
+ uint32_t epfm; ///< Offset 0x348 Enabled Panel Fitting Modes
+ uint8_t plut[0x4A]; ///< Offset 0x34C Panel Look Up Table & Identifier
+ uint32_t pfmb; ///< Offset 0x396 PWM Frequency and Minimum Brightness
+ uint32_t ccdv; ///< Offset 0x39A Color Correction Default Values
+ uint32_t pcft; ///< Offset 0x39E Power Conservation Features
+ uint32_t srot; ///< Offset 0x3A2 Supported Rotation Angles
+ uint32_t iuer; ///< Offset 0x3A6 Intel Ultrabook(TM) Event Register
+ uint64_t fdss; ///< Offset 0x3AA DSS Buffer address allocated for IFFS
+ ///< feature
+ uint32_t fdsp; ///< Offset 0x3B2 Size of DSS buffer
+ uint32_t stat; ///< Offset 0x3B6 State Indicator
+ uint64_t rvda; ///< Offset 0x3BA Absolute/Relative Address of Raw VBT
+ ///< Data from OpRegion Base
+ uint32_t rvds; ///< Offset 0x3C2 Raw VBT Data Size
+ uint8_t rsvd2[0x3A]; ///< Offset 0x3C6 - 0x3FF Reserved Must be zero.
+ ///< Bug in spec 0x45(69)
+};
+
+///
+/// OpRegion Mailbox 4 - VBT Video BIOS Table
+/// Offset 0x400, Size 0x1800
+///
+struct igd_opregion_mbox4 {
+ uint8_t rvbt[IGD_OPREGION_VBT_SIZE_6K]; ///< Offset 0x400 - 0x1BFF Raw
+ ///< VBT Data
+};
+
+///
+/// OpRegion Mailbox 5 - BIOS/Driver Notification - Data storage BIOS to Driver
+/// data sync Offset 0x1C00, Size 0x400
+///
+struct igd_opregion_mbox5 {
+ uint32_t phed; ///< Offset 0x1C00 Panel Header
+ uint8_t bddc[0x100]; ///< Offset 0x1C04 Panel EDID (DDC data)
+ uint8_t rm51[0x2FC]; ///< Offset 0x1D04 - 0x1FFF Reserved Must be zero
+};
+
+///
+/// IGD OpRegion Structure
+///
+struct igd_opregion {
+ struct igd_opregion_header
+ header; ///< OpRegion header (Offset 0x0, Size 0x100)
+ struct igd_opregion_mbox1 mbox1; ///< Mailbox 1: Public ACPI Methods
+ ///< (Offset 0x100, Size 0x100)
+ struct igd_opregion_mbox2 mbox2; ///< Mailbox 2: Software SCI Interface
+ ///< (Offset 0x200, Size 0x100)
+ struct igd_opregion_mbox3
+ mbox3; ///< Mailbox 3: BIOS to Driver Notification (Offset 0x300,
+ ///< Size 0x100)
+ struct igd_opregion_mbox4 mbox4; ///< Mailbox 4: Video BIOS Table (VBT)
+ ///< (Offset 0x400, Size 0x1800)
+ struct igd_opregion_mbox5
+ mbox5; ///< Mailbox 5: BIOS to Driver Notification Extension (Offset
+ ///< 0x1C00, Size 0x400)
+};
+
+///
+/// VBT Header Structure
+///
+struct vbt_header {
+ uint8_t product_string[20];
+ uint16_t version;
+ uint16_t header_size;
+ uint16_t table_size;
+ uint8_t checksum;
+ uint8_t reserved1;
+ uint32_t bios_data_offset;
+ uint32_t aim_data_offset[4];
+};
+
+#pragma pack()
+
+int vm_intelgpu_get_opregion(vm_paddr_t *const base, vm_paddr_t *const size);
diff --git a/sys/amd64/vmm/intel/intelgpu.c b/sys/amd64/vmm/intel/intelgpu.c
new file mode 100644
--- /dev/null
+++ b/sys/amd64/vmm/intel/intelgpu.c
@@ -0,0 +1,55 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2021 Beckhoff Automation GmbH & Co. KG
+ * Author: Corvin Köhne <c.koehne@beckhoff.com>
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+
+#include "intelgpu.h"
+
+#define KB (1024UL)
+
+int
+vm_intelgpu_get_opregion(vm_paddr_t *const base, vm_paddr_t *const size)
+{
+ /* intel graphics device is always located at 0:2.0 */
+ device_t dev = pci_find_bsf(0, 2, 0);
+ if (dev == NULL) {
+ return (ENOENT);
+ }
+
+ if ((pci_get_vendor(dev) != PCI_VENDOR_INTEL) ||
+ (pci_get_class(dev) != PCIC_DISPLAY) ||
+ (pci_get_subclass(dev) != PCIS_DISPLAY_VGA)) {
+ return (ENODEV);
+ }
+
+ const uint64_t asls = pci_read_config(dev, PCIR_ASLS_CTL, 4);
+
+ const struct igd_opregion_header *const opregion_header =
+ (struct igd_opregion_header *)pmap_map(NULL, asls,
+ asls + sizeof(*opregion_header), VM_PROT_READ);
+ if (opregion_header == NULL ||
+ memcmp(opregion_header->sign, IGD_OPREGION_HEADER_SIGN,
+ sizeof(opregion_header->sign))) {
+ return (ENODEV);
+ }
+
+ *base = asls;
+ *size = opregion_header->size * KB;
+
+ return (0);
+}
diff --git a/sys/amd64/vmm/io/acpi.h b/sys/amd64/vmm/io/acpi.h
new file mode 100644
--- /dev/null
+++ b/sys/amd64/vmm/io/acpi.h
@@ -0,0 +1,14 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2021 Beckhoff Automation GmbH & Co. KG
+ * Author: Corvin Köhne <c.koehne@beckhoff.com>
+ */
+
+#pragma once
+
+#include <machine/vmm.h>
+#include <machine/vmm_dev.h>
+
+int vmm_tpm2_get_control_address(vm_paddr_t *const base,
+ vm_paddr_t *const size);
diff --git a/sys/amd64/vmm/io/acpi.c b/sys/amd64/vmm/io/acpi.c
new file mode 100644
--- /dev/null
+++ b/sys/amd64/vmm/io/acpi.c
@@ -0,0 +1,37 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2021 Beckhoff Automation GmbH & Co. KG
+ * Author: Corvin Köhne <c.koehne@beckhoff.com>
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+
+#include <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/acpixf.h>
+
+#include "acpi.h"
+int
+vmm_tpm2_get_control_address(vm_paddr_t *const base, vm_paddr_t *const size)
+{
+ ACPI_TABLE_HEADER *tpm_header;
+ if (!ACPI_SUCCESS(AcpiGetTable("TPM2", 1, &tpm_header))) {
+ return (ENOENT);
+ }
+
+ if (base) {
+ const ACPI_TABLE_TPM2 *const tpm_table = (ACPI_TABLE_TPM2 *)
+ tpm_header;
+ *base = tpm_table->ControlAddress;
+ }
+ if (size) {
+ *size = 0;
+ }
+
+ return (0);
+}
diff --git a/sys/amd64/vmm/vmm_dev.c b/sys/amd64/vmm/vmm_dev.c
--- a/sys/amd64/vmm/vmm_dev.c
+++ b/sys/amd64/vmm/vmm_dev.c
@@ -60,9 +60,11 @@
#include <machine/vmm_snapshot.h>
#include <x86/apicreg.h>
+#include "intel/intelgpu.h"
#include "vmm_lapic.h"
#include "vmm_stat.h"
#include "vmm_mem.h"
+#include "io/acpi.h"
#include "io/ppt.h"
#include "io/vatpic.h"
#include "io/vioapic.h"
@@ -373,6 +375,7 @@
struct vm_capability *vmcap;
struct vm_pptdev *pptdev;
struct vm_pptdev_mmio *pptmmio;
+ struct vm_memory_region_info *memory_region_info;
struct vm_pptdev_msi *pptmsi;
struct vm_pptdev_msix *pptmsix;
struct vm_nmi *vmnmi;
@@ -540,6 +543,29 @@
error = ppt_unmap_mmio(sc->vm, pptmmio->bus, pptmmio->slot,
pptmmio->func, pptmmio->gpa, pptmmio->len);
break;
+ case VM_GET_MEMORY_REGION_INFO:
+ memory_region_info = (struct vm_memory_region_info *)data;
+ switch (memory_region_info->type) {
+ case MEMORY_REGION_INTEL_GSM:
+ memory_region_info->base = intel_graphics_stolen_base;
+ memory_region_info->size = intel_graphics_stolen_size;
+ error = 0;
+ break;
+ case MEMORY_REGION_INTEL_OPREGION:
+ error =
+ vm_intelgpu_get_opregion(&memory_region_info->base,
+ &memory_region_info->size);
+ break;
+ case MEMORY_REGION_TPM_CONTROL_ADDRESS:
+ error = vmm_tpm2_get_control_address(
+ &memory_region_info->base,
+ &memory_region_info->size);
+ break;
+ default:
+ error = EINVAL;
+ break;
+ }
+ break;
case VM_BIND_PPTDEV:
pptdev = (struct vm_pptdev *)data;
error = vm_assign_pptdev(sc->vm, pptdev->bus, pptdev->slot,
diff --git a/sys/dev/pci/pcireg.h b/sys/dev/pci/pcireg.h
--- a/sys/dev/pci/pcireg.h
+++ b/sys/dev/pci/pcireg.h
@@ -1098,3 +1098,14 @@
#define PCIM_OSC_CTL_PCIE_PME 0x04 /* PCIe Native Power Mgt Events */
#define PCIM_OSC_CTL_PCIE_AER 0x08 /* PCIe Advanced Error Reporting */
#define PCIM_OSC_CTL_PCIE_CAP_STRUCT 0x10 /* Various Capability Structures */
+
+/*
+ * Intel graphics device definitions
+ */
+#define PCIR_BDSM 0x5C /* Base of Data Stolen Memory register */
+#define PCIR_ASLS_CTL 0xFC /* Opregion start address register */
+
+/*
+ * PCI Vendors
+ */
+#define PCI_VENDOR_INTEL 0x8086
diff --git a/sys/modules/vmm/Makefile b/sys/modules/vmm/Makefile
--- a/sys/modules/vmm/Makefile
+++ b/sys/modules/vmm/Makefile
@@ -29,7 +29,8 @@
x86.c
.PATH: ${SRCTOP}/sys/amd64/vmm/io
-SRCS+= iommu.c \
+SRCS+= acpi.c \
+ iommu.c \
ppt.c \
vatpic.c \
vatpit.c \
@@ -42,6 +43,7 @@
# intel-specific files
.PATH: ${SRCTOP}/sys/amd64/vmm/intel
SRCS+= ept.c \
+ intelgpu.c \
vmcs.c \
vmx_msr.c \
vmx_support.S \
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Feb 4, 4:13 PM (21 h, 15 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16457242
Default Alt Text
D33011.diff (16 KB)
Attached To
Mode
D33011: bhyve: add ioctl to query infos about special memory regions
Attached
Detach File
Event Timeline
Log In to Comment