summaryrefslogtreecommitdiffstats
path: root/include/VBox/rawpci.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/VBox/rawpci.h')
-rw-r--r--include/VBox/rawpci.h618
1 files changed, 618 insertions, 0 deletions
diff --git a/include/VBox/rawpci.h b/include/VBox/rawpci.h
new file mode 100644
index 00000000..290983c0
--- /dev/null
+++ b/include/VBox/rawpci.h
@@ -0,0 +1,618 @@
+/** @file
+ * Raw PCI Devices (aka PCI pass-through). (VMM)
+ */
+
+/*
+ * Copyright (C) 2010-2022 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
+ * in the VirtualBox distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
+ */
+
+#ifndef VBOX_INCLUDED_rawpci_h
+#define VBOX_INCLUDED_rawpci_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <VBox/types.h>
+#include <VBox/sup.h>
+
+RT_C_DECLS_BEGIN
+
+/**
+ * Handle for the raw PCI device.
+ */
+typedef uint32_t PCIRAWDEVHANDLE;
+
+/**
+ * Handle for the ISR.
+ */
+typedef uint32_t PCIRAWISRHANDLE;
+
+/**
+ * Physical memory action enumeration.
+ */
+typedef enum PCIRAWMEMINFOACTION
+{
+ /** Pages mapped. */
+ PCIRAW_MEMINFO_MAP,
+ /** Pages unmapped. */
+ PCIRAW_MEMINFO_UNMAP,
+ /** The usual 32-bit type blow up. */
+ PCIRAW_MEMINFO_32BIT_HACK = 0x7fffffff
+} PCIRAWMEMINFOACTION;
+
+/**
+ * Per-VM capability flag bits.
+ */
+typedef enum PCIRAWVMFLAGS
+{
+ /** If we can use IOMMU in this VM. */
+ PCIRAW_VMFLAGS_HAS_IOMMU = (1 << 0),
+ PCIRAW_VMFLAGS_32BIT_HACK = 0x7fffffff
+} PCIRAWVMFLAGS;
+
+/* Forward declaration. */
+struct RAWPCIPERVM;
+
+/**
+ * Callback to notify raw PCI subsystem about mapping/unmapping of
+ * host pages to the guest. Typical usecase is to register physical
+ * RAM pages with IOMMU, so that it could allow DMA for PCI devices
+ * directly from the guest RAM.
+ * Region shall be one or more contigous (both host and guest) pages
+ * of physical memory.
+ *
+ * @returns VBox status code.
+ *
+ * @param pVmData The per VM data.
+ * @param HCPhysStart Physical address of region start on the host.
+ * @param GCPhysStart Physical address of region start on the guest.
+ * @param cbMem Region size in bytes.
+ * @param enmAction Action performed (i.e. if page was mapped
+ * or unmapped).
+ */
+typedef DECLCALLBACKTYPE(int, FNRAWPCICONTIGPHYSMEMINFO,(struct RAWPCIPERVM *pVmData, RTHCPHYS HCPhysStart,
+ RTGCPHYS GCPhysStart, uint64_t cbMem, PCIRAWMEMINFOACTION enmAction));
+typedef FNRAWPCICONTIGPHYSMEMINFO *PFNRAWPCICONTIGPHYSMEMINFO;
+
+/** Data being part of the VM structure. */
+typedef struct RAWPCIPERVM
+{
+ /** Shall only be interpreted by the host PCI driver. */
+ RTR0PTR pDriverData;
+ /** Callback called when mapping of host pages to the guest changes. */
+ PFNRAWPCICONTIGPHYSMEMINFO pfnContigMemInfo;
+ /** Flags describing VM capabilities (such as IOMMU presence). */
+ uint32_t fVmCaps;
+} RAWPCIPERVM;
+typedef RAWPCIPERVM *PRAWPCIPERVM;
+
+/** Parameters buffer for PCIRAWR0_DO_OPEN_DEVICE call */
+typedef struct
+{
+ /* in */
+ uint32_t PciAddress;
+ uint32_t fFlags;
+ /* out */
+ PCIRAWDEVHANDLE Device;
+ uint32_t fDevFlags;
+} PCIRAWREQOPENDEVICE;
+
+/** Parameters buffer for PCIRAWR0_DO_CLOSE_DEVICE call */
+typedef struct
+{
+ /* in */
+ uint32_t fFlags;
+} PCIRAWREQCLOSEDEVICE;
+
+/** Parameters buffer for PCIRAWR0_DO_GET_REGION_INFO call */
+typedef struct
+{
+ /* in */
+ int32_t iRegion;
+ /* out */
+ RTGCPHYS RegionStart;
+ uint64_t u64RegionSize;
+ bool fPresent;
+ uint32_t fFlags;
+} PCIRAWREQGETREGIONINFO;
+
+/** Parameters buffer for PCIRAWR0_DO_MAP_REGION call. */
+typedef struct
+{
+ /* in */
+ RTGCPHYS StartAddress;
+ uint64_t iRegionSize;
+ int32_t iRegion;
+ uint32_t fFlags;
+ /* out */
+ RTR3PTR pvAddressR3;
+ RTR0PTR pvAddressR0;
+} PCIRAWREQMAPREGION;
+
+/** Parameters buffer for PCIRAWR0_DO_UNMAP_REGION call. */
+typedef struct
+{
+ /* in */
+ RTGCPHYS StartAddress;
+ uint64_t iRegionSize;
+ RTR3PTR pvAddressR3;
+ RTR0PTR pvAddressR0;
+ int32_t iRegion;
+} PCIRAWREQUNMAPREGION;
+
+/** Parameters buffer for PCIRAWR0_DO_PIO_WRITE call. */
+typedef struct
+{
+ /* in */
+ uint16_t iPort;
+ uint16_t cb;
+ uint32_t iValue;
+} PCIRAWREQPIOWRITE;
+
+/** Parameters buffer for PCIRAWR0_DO_PIO_READ call. */
+typedef struct
+{
+ /* in */
+ uint16_t iPort;
+ uint16_t cb;
+ /* out */
+ uint32_t iValue;
+} PCIRAWREQPIOREAD;
+
+/** Memory operand. */
+typedef struct
+{
+ union
+ {
+ uint8_t u8;
+ uint16_t u16;
+ uint32_t u32;
+ uint64_t u64;
+ } u;
+ uint8_t cb;
+} PCIRAWMEMLOC;
+
+/** Parameters buffer for PCIRAWR0_DO_MMIO_WRITE call. */
+typedef struct
+{
+ /* in */
+ RTR0PTR Address;
+ PCIRAWMEMLOC Value;
+} PCIRAWREQMMIOWRITE;
+
+/** Parameters buffer for PCIRAWR0_DO_MMIO_READ call. */
+typedef struct
+{
+ /* in */
+ RTR0PTR Address;
+ /* inout (Value.cb is in) */
+ PCIRAWMEMLOC Value;
+} PCIRAWREQMMIOREAD;
+
+/* Parameters buffer for PCIRAWR0_DO_PCICFG_WRITE call. */
+typedef struct
+{
+ /* in */
+ uint32_t iOffset;
+ PCIRAWMEMLOC Value;
+} PCIRAWREQPCICFGWRITE;
+
+/** Parameters buffer for PCIRAWR0_DO_PCICFG_READ call. */
+typedef struct
+{
+ /* in */
+ uint32_t iOffset;
+ /* inout (Value.cb is in) */
+ PCIRAWMEMLOC Value;
+} PCIRAWREQPCICFGREAD;
+
+/** Parameters buffer for PCIRAWR0_DO_GET_IRQ call. */
+typedef struct PCIRAWREQGETIRQ
+{
+ /* in */
+ int64_t iTimeout;
+ /* out */
+ int32_t iIrq;
+} PCIRAWREQGETIRQ;
+
+/** Parameters buffer for PCIRAWR0_DO_POWER_STATE_CHANGE call. */
+typedef struct PCIRAWREQPOWERSTATECHANGE
+{
+ /* in */
+ uint32_t iState;
+ /* in/out */
+ uint64_t u64Param;
+} PCIRAWREQPOWERSTATECHANGE;
+
+/**
+ * Request buffer use for communication with the driver.
+ */
+typedef struct PCIRAWSENDREQ
+{
+ /** The request header. */
+ SUPVMMR0REQHDR Hdr;
+ /** Alternative to passing the taking the session from the VM handle.
+ * Either use this member or use the VM handle, don't do both.
+ */
+ PSUPDRVSESSION pSession;
+ /** Request type. */
+ int32_t iRequest;
+ /** Host device request targetted to. */
+ PCIRAWDEVHANDLE TargetDevice;
+ /** Call parameters. */
+ union
+ {
+ PCIRAWREQOPENDEVICE aOpenDevice;
+ PCIRAWREQCLOSEDEVICE aCloseDevice;
+ PCIRAWREQGETREGIONINFO aGetRegionInfo;
+ PCIRAWREQMAPREGION aMapRegion;
+ PCIRAWREQUNMAPREGION aUnmapRegion;
+ PCIRAWREQPIOWRITE aPioWrite;
+ PCIRAWREQPIOREAD aPioRead;
+ PCIRAWREQMMIOWRITE aMmioWrite;
+ PCIRAWREQMMIOREAD aMmioRead;
+ PCIRAWREQPCICFGWRITE aPciCfgWrite;
+ PCIRAWREQPCICFGREAD aPciCfgRead;
+ PCIRAWREQGETIRQ aGetIrq;
+ PCIRAWREQPOWERSTATECHANGE aPowerStateChange;
+ } u;
+} PCIRAWSENDREQ;
+typedef PCIRAWSENDREQ *PPCIRAWSENDREQ;
+
+/**
+ * Operations performed by the driver.
+ */
+typedef enum PCIRAWR0OPERATION
+{
+ /* Open device. */
+ PCIRAWR0_DO_OPEN_DEVICE,
+ /* Close device. */
+ PCIRAWR0_DO_CLOSE_DEVICE,
+ /* Get PCI region info. */
+ PCIRAWR0_DO_GET_REGION_INFO,
+ /* Map PCI region into VM address space. */
+ PCIRAWR0_DO_MAP_REGION,
+ /* Unmap PCI region from VM address space. */
+ PCIRAWR0_DO_UNMAP_REGION,
+ /* Perform PIO write. */
+ PCIRAWR0_DO_PIO_WRITE,
+ /* Perform PIO read. */
+ PCIRAWR0_DO_PIO_READ,
+ /* Perform MMIO write. */
+ PCIRAWR0_DO_MMIO_WRITE,
+ /* Perform MMIO read. */
+ PCIRAWR0_DO_MMIO_READ,
+ /* Perform PCI config write. */
+ PCIRAWR0_DO_PCICFG_WRITE,
+ /* Perform PCI config read. */
+ PCIRAWR0_DO_PCICFG_READ,
+ /* Get next IRQ for the device. */
+ PCIRAWR0_DO_GET_IRQ,
+ /* Enable getting IRQs for the device. */
+ PCIRAWR0_DO_ENABLE_IRQ,
+ /* Disable getting IRQs for the device. */
+ PCIRAWR0_DO_DISABLE_IRQ,
+ /* Notify driver about guest power state change. */
+ PCIRAWR0_DO_POWER_STATE_CHANGE,
+ /** The usual 32-bit type blow up. */
+ PCIRAWR0_DO_32BIT_HACK = 0x7fffffff
+} PCIRAWR0OPERATION;
+
+/**
+ * Power state enumeration.
+ */
+typedef enum PCIRAWPOWERSTATE
+{
+ /* Power on. */
+ PCIRAW_POWER_ON,
+ /* Power off. */
+ PCIRAW_POWER_OFF,
+ /* Suspend. */
+ PCIRAW_POWER_SUSPEND,
+ /* Resume. */
+ PCIRAW_POWER_RESUME,
+ /* Reset. */
+ PCIRAW_POWER_RESET,
+ /** The usual 32-bit type blow up. */
+ PCIRAW_POWER_32BIT_HACK = 0x7fffffff
+} PCIRAWPOWERSTATE;
+
+
+/** Forward declarations. */
+typedef struct RAWPCIFACTORY *PRAWPCIFACTORY;
+typedef struct RAWPCIDEVPORT *PRAWPCIDEVPORT;
+
+/**
+ * Interrupt service routine callback.
+ *
+ * @returns if interrupt was processed.
+ *
+ * @param pvContext Opaque user data passed to the handler.
+ * @param iIrq Interrupt number.
+ */
+typedef DECLCALLBACKTYPE(bool, FNRAWPCIISR,(void *pvContext, int32_t iIrq));
+typedef FNRAWPCIISR *PFNRAWPCIISR;
+
+/**
+ * This is the port on the device interface, i.e. the driver side which the
+ * host device is connected to.
+ *
+ * This is only used for the in-kernel PCI device connections.
+ */
+typedef struct RAWPCIDEVPORT
+{
+ /** Structure version number. (RAWPCIDEVPORT_VERSION) */
+ uint32_t u32Version;
+
+ /**
+ * Init device.
+ *
+ * @param pPort Pointer to this structure.
+ * @param fFlags Initialization flags.
+ */
+ DECLR0CALLBACKMEMBER(int, pfnInit,(PRAWPCIDEVPORT pPort,
+ uint32_t fFlags));
+
+
+ /**
+ * Deinit device.
+ *
+ * @param pPort Pointer to this structure.
+ * @param fFlags Initialization flags.
+ */
+ DECLR0CALLBACKMEMBER(int, pfnDeinit,(PRAWPCIDEVPORT pPort,
+ uint32_t fFlags));
+
+
+ /**
+ * Destroy device.
+ *
+ * @param pPort Pointer to this structure.
+ */
+ DECLR0CALLBACKMEMBER(int, pfnDestroy,(PRAWPCIDEVPORT pPort));
+
+ /**
+ * Get PCI region info.
+ *
+ * @param pPort Pointer to this structure.
+ * @param iRegion Region number.
+ * @param pRegionStart Where to start the region address.
+ * @param pu64RegionSize Where to store the region size.
+ * @param pfPresent Where to store if the region is present.
+ * @param pfFlags Where to store the flags.
+ */
+ DECLR0CALLBACKMEMBER(int, pfnGetRegionInfo,(PRAWPCIDEVPORT pPort,
+ int32_t iRegion,
+ RTHCPHYS *pRegionStart,
+ uint64_t *pu64RegionSize,
+ bool *pfPresent,
+ uint32_t *pfFlags));
+
+
+ /**
+ * Map PCI region.
+ *
+ * @param pPort Pointer to this structure.
+ * @param iRegion Region number.
+ * @param RegionStart Region start.
+ * @param u64RegionSize Region size.
+ * @param fFlags Flags.
+ * @param pRegionBaseR0 Where to store the R0 address.
+ */
+ DECLR0CALLBACKMEMBER(int, pfnMapRegion,(PRAWPCIDEVPORT pPort,
+ int32_t iRegion,
+ RTHCPHYS RegionStart,
+ uint64_t u64RegionSize,
+ int32_t fFlags,
+ RTR0PTR *pRegionBaseR0));
+
+ /**
+ * Unmap PCI region.
+ *
+ * @param pPort Pointer to this structure.
+ * @param iRegion Region number.
+ * @param RegionStart Region start.
+ * @param u64RegionSize Region size.
+ * @param RegionBase Base address.
+ */
+ DECLR0CALLBACKMEMBER(int, pfnUnmapRegion,(PRAWPCIDEVPORT pPort,
+ int32_t iRegion,
+ RTHCPHYS RegionStart,
+ uint64_t u64RegionSize,
+ RTR0PTR RegionBase));
+
+ /**
+ * Read device PCI register.
+ *
+ * @param pPort Pointer to this structure.
+ * @param Register PCI register.
+ * @param pValue Read value (with desired read width).
+ */
+ DECLR0CALLBACKMEMBER(int, pfnPciCfgRead,(PRAWPCIDEVPORT pPort,
+ uint32_t Register,
+ PCIRAWMEMLOC *pValue));
+
+
+ /**
+ * Write device PCI register.
+ *
+ * @param pPort Pointer to this structure.
+ * @param Register PCI register.
+ * @param pValue Write value (with desired write width).
+ */
+ DECLR0CALLBACKMEMBER(int, pfnPciCfgWrite,(PRAWPCIDEVPORT pPort,
+ uint32_t Register,
+ PCIRAWMEMLOC *pValue));
+
+ /**
+ * Request to register interrupt handler.
+ *
+ * @param pPort Pointer to this structure.
+ * @param pfnHandler Pointer to the handler.
+ * @param pIrqContext Context passed to the handler.
+ * @param phIsr Handle for the ISR, .
+ */
+ DECLR0CALLBACKMEMBER(int, pfnRegisterIrqHandler,(PRAWPCIDEVPORT pPort,
+ PFNRAWPCIISR pfnHandler,
+ void* pIrqContext,
+ PCIRAWISRHANDLE *phIsr));
+
+ /**
+ * Request to unregister interrupt handler.
+ *
+ * @param pPort Pointer to this structure.
+ * @param hIsr Handle of ISR to unregister (retured by earlier pfnRegisterIrqHandler).
+ */
+ DECLR0CALLBACKMEMBER(int, pfnUnregisterIrqHandler,(PRAWPCIDEVPORT pPort,
+ PCIRAWISRHANDLE hIsr));
+
+ /**
+ * Power state change notification.
+ *
+ * @param pPort Pointer to this structure.
+ * @param aState New power state.
+ * @param pu64Param State-specific in/out parameter.
+ */
+ DECLR0CALLBACKMEMBER(int, pfnPowerStateChange,(PRAWPCIDEVPORT pPort,
+ PCIRAWPOWERSTATE aState,
+ uint64_t *pu64Param));
+
+ /** Structure version number. (RAWPCIDEVPORT_VERSION) */
+ uint32_t u32VersionEnd;
+} RAWPCIDEVPORT;
+/** Version number for the RAWPCIDEVPORT::u32Version and RAWPCIIFPORT::u32VersionEnd fields. */
+#define RAWPCIDEVPORT_VERSION UINT32_C(0xAFBDCC02)
+
+/**
+ * The component factory interface for create a raw PCI interfaces.
+ */
+typedef struct RAWPCIFACTORY
+{
+ /**
+ * Release this factory.
+ *
+ * SUPR0ComponentQueryFactory (SUPDRVFACTORY::pfnQueryFactoryInterface to be precise)
+ * will retain a reference to the factory and the caller has to call this method to
+ * release it once the pfnCreateAndConnect call(s) has been done.
+ *
+ * @param pFactory Pointer to this structure.
+ */
+ DECLR0CALLBACKMEMBER(void, pfnRelease,(PRAWPCIFACTORY pFactory));
+
+ /**
+ * Create an instance for the specfied host PCI card and connects it
+ * to the driver.
+ *
+ *
+ * @returns VBox status code.
+ *
+ * @param pFactory Pointer to this structure.
+ * @param u32HostAddress Address of PCI device on the host.
+ * @param fFlags Creation flags.
+ * @param pVmCtx Context of VM where device is created.
+ * @param ppDevPort Where to store the pointer to the device port
+ * on success.
+ * @param pfDevFlags Where to store the device flags.
+ *
+ */
+ DECLR0CALLBACKMEMBER(int, pfnCreateAndConnect,(PRAWPCIFACTORY pFactory,
+ uint32_t u32HostAddress,
+ uint32_t fFlags,
+ PRAWPCIPERVM pVmCtx,
+ PRAWPCIDEVPORT *ppDevPort,
+ uint32_t *pfDevFlags));
+
+
+ /**
+ * Initialize per-VM data related to PCI passthrough.
+ *
+ * @returns VBox status code.
+ *
+ * @param pFactory Pointer to this structure.
+ * @param pVM The cross context VM structure.
+ * @param pVmData Pointer to PCI data.
+ */
+ DECLR0CALLBACKMEMBER(int, pfnInitVm,(PRAWPCIFACTORY pFactory,
+ PVM pVM,
+ PRAWPCIPERVM pVmData));
+
+ /**
+ * Deinitialize per-VM data related to PCI passthrough.
+ *
+ * @returns VBox status code.
+ *
+ * @param pFactory Pointer to this structure.
+ * @param pVM The cross context VM structure.
+ * @param pVmData Pointer to PCI data.
+ */
+ DECLR0CALLBACKMEMBER(void, pfnDeinitVm,(PRAWPCIFACTORY pFactory,
+ PVM pVM,
+ PRAWPCIPERVM pVmData));
+} RAWPCIFACTORY;
+
+#define RAWPCIFACTORY_UUID_STR "ea089839-4171-476f-adfb-9e7ab1cbd0fb"
+
+/**
+ * Flags passed to pfnPciDeviceConstructStart(), to notify driver
+ * about options to be used to open device.
+ */
+typedef enum PCIRAWDRIVERFLAGS
+{
+ /** If runtime shall try to detach host driver. */
+ PCIRAWDRIVERRFLAG_DETACH_HOST_DRIVER = (1 << 0),
+ /** The usual 32-bit type blow up. */
+ PCIRAWDRIVERRFLAG_32BIT_HACK = 0x7fffffff
+} PCIRAWDRIVERFLAGS;
+
+/**
+ * Flags used to describe PCI region, matches to PCIADDRESSSPACE
+ * in pci.h.
+ */
+typedef enum PCIRAWADDRESSSPACE
+{
+ /** Memory. */
+ PCIRAW_ADDRESS_SPACE_MEM = 0x00,
+ /** I/O space. */
+ PCIRAW_ADDRESS_SPACE_IO = 0x01,
+ /** 32-bit BAR. */
+ PCIRAW_ADDRESS_SPACE_BAR32 = 0x00,
+ /** 64-bit BAR. */
+ PCIRAW_ADDRESS_SPACE_BAR64 = 0x04,
+ /** Prefetch memory. */
+ PCIRAW_ADDRESS_SPACE_MEM_PREFETCH = 0x08,
+ /** The usual 32-bit type blow up. */
+ PCIRAW_ADDRESS_SPACE_32BIT_HACK = 0x7fffffff
+} PCIRAWADDRESSSPACE;
+
+RT_C_DECLS_END
+
+/* #define VBOX_WITH_SHARED_PCI_INTERRUPTS */
+
+#endif /* !VBOX_INCLUDED_rawpci_h */