pci.h revision d6d46343942c38ef0d231ffb6ec12eb5f5fb77b1
/** @file
* PCI - The PCI Controller And Devices. (DEV)
*/
/*
* Copyright (C) 2006-2007 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*
* The contents of this file may alternatively be used under the terms
* of the Common Development and Distribution License Version 1.0
* (CDDL) only, as it comes in the "COPYING.CDDL" file of the
* VirtualBox OSE 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.
*/
#ifndef ___VBox_pci_h
#define ___VBox_pci_h
/** @defgroup grp_pci PCI - The PCI Controller.
* @{
*/
/** Pointer to a PCI device. */
typedef struct PCIDevice *PPCIDEVICE;
/**
* PCI configuration word 4 (command) and word 6 (status).
*/
typedef enum PCICONFIGCOMMAND
{
PCI_COMMAND_IOACCESS = 0x0001,
PCI_COMMAND_MEMACCESS = 0x0002,
PCI_COMMAND_BUSMASTER = 0x0004
/**
* PCI Address space specification.
* This is used when registering a I/O region.
*/
/** Note: There are all sorts of dirty dependencies on the values in the
* pci device. Be careful when changing this.
*/
typedef enum PCIADDRESSSPACE
{
/** Memory. */
PCI_ADDRESS_SPACE_MEM = 0x00,
/** I/O space. */
PCI_ADDRESS_SPACE_IO = 0x01,
/** 32-bit BAR. */
PCI_ADDRESS_SPACE_BAR32 = 0x00,
/** 64-bit BAR. */
PCI_ADDRESS_SPACE_BAR64 = 0x04,
/** Prefetch memory. */
/**
* Callback function for mapping an PCI I/O region.
*
* @return VBox status code.
* @param pPciDev Pointer to PCI device. Use pPciDev->pDevIns to get the device instance.
* @param iRegion The region number.
* @param GCPhysAddress Physical address of the region. If enmType is PCI_ADDRESS_SPACE_IO, this
* is an I/O port, otherwise it's a physical address.
*
* NIL_RTGCPHYS indicates that a MMIO2 mapping is about to be unmapped and
* that the device deregister access handlers for it and update its internal
* state to reflect this.
*
* @param enmType One of the PCI_ADDRESS_SPACE_* values.
*
* @remarks The address is *NOT* relative to pci_mem_base.
*/
typedef DECLCALLBACK(int) FNPCIIOREGIONMAP(PPCIDEVICE pPciDev, /*unsigned*/ int iRegion, RTGCPHYS GCPhysAddress, uint32_t cb, PCIADDRESSSPACE enmType);
/** Pointer to a FNPCIIOREGIONMAP() function. */
typedef FNPCIIOREGIONMAP *PFNPCIIOREGIONMAP;
/** @name PCI Configuration Space Registers
* @{ */
/* Commented out values common for different header types */
/* Common part of the header */
#define VBOX_PCI_CLASS_PROG 0x09 /**< 8-bit RO - - register-level programming class code (device specific). */
#define VBOX_PCI_LATENCY_TIMER 0x0d /**< 8-bit RW - - master latency timer, hardwired to 0 for PCIe */
#define VBOX_PCI_HEADER_TYPE 0x0e /**< 8-bit RO - - header type (0 - device, 1 - bridge, 2 - CardBus bridge) */
#define VBOX_PCI_CAPABILITY_LIST 0x34 /**< 8-bit RO? - - linked list of new capabilities implemented by the device, 2 bottom bits reserved */
/* Type 0 header, device */
/* #define VBOX_PCI_CAPABILITY_LIST 0x34 */ /**< 8-bit? ?? */
/* #define VBOX_PCI_INTERRUPT_LINE 0x3c */ /**< 8-bit RW - - interrupt line. */
/* #define VBOX_PCI_INTERRUPT_PIN 0x3d */ /**< 8-bit RO - - interrupt pin. */
#define VBOX_PCI_MAX_LAT 0x3f /**< 8-bit RO - - how often the device needs access to the PCI bus (in 1/4 microsecond units) */
/* Type 1 header, PCI-to-PCI bridge */
/* #define VBOX_PCI_BASE_ADDRESS_0 0x10 */ /**< 32-bit RW */
/* #define VBOX_PCI_BASE_ADDRESS_1 0x14 */ /**< 32-bit RW */
#define VBOX_PCI_SUBORDINATE_BUS 0x1a /**< 8-bit ?? - - highest subordinate bus number. (behind the bridge) */
#define VBOX_PCI_PREF_LIMIT_UPPER32 0x2c /**< 32-bit ?? - - prefetchable memory range high limit. */
/* #define VBOX_PCI_CAPABILITY_LIST 0x34 */ /**< 8-bit? ?? */
/* #define VBOX_PCI_RESERVED_35 0x35 */ /**< 8-bit ?? - - reserved */
/* #define VBOX_PCI_RESERVED_36 0x36 */ /**< 8-bit ?? - - reserved */
/* #define VBOX_PCI_RESERVED_37 0x37 */ /**< 8-bit ?? - - reserved */
/* Type 2 header, PCI-to-CardBus bridge */
/* #define VBOX_PCI_SUBORDINATE_BUS 0x1a */ /**< 8-bit ?? - - highest subordinate bus number. (behind the bridge) */
/* #define VBOX_PCI_SEC_LATENCY_TIMER 0x1b */ /**< 8-bit ?? - - secondary latency timer. */
/* #define VBOX_PCI_INTERRUPT_LINE 0x3c */ /**< 8-bit RW - - interrupt line. */
/* #define VBOX_PCI_INTERRUPT_PIN 0x3d */ /**< 8-bit RO - - interrupt pin. */
/* #define VBOX_PCI_BRIDGE_CONTROL 0x3e */ /**< 16-bit? ?? - - bridge control */
/** @} */
/* Possible values in status bitmask */
#define VBOX_PCI_STATUS_DEVSEL_FAST 0x000
#define VBOX_PCI_STATUS_DEVSEL_MEDIUM 0x200
#define VBOX_PCI_STATUS_DEVSEL_SLOW 0x400
/* Command bitmask */
/* Capability list values (capability offset 0) */
/* Next value pointer in offset 1, or 0 if none */
/* Extended Capabilities (PCI-X 2.0 and Express), start at 0x100, next - bits [20..32] */
#define VBOX_PCI_EXT_CAP_ID_ARI 0x0e
#define VBOX_PCI_EXT_CAP_ID_ATS 0x0f
#define VBOX_PCI_EXT_CAP_ID_SRIOV 0x10
/* MSI flags, aka Message Control (2 bytes, capability offset 2) */
/* Encoding for 3-bit patterns for message queue (per chapter 6.8.1 of PCI spec),
someone very similar to log_2().
000 1
001 2
010 4
011 8
100 16
101 32
110 Reserved
111 Reserved */
#define VBOX_PCI_MSI_FLAGS_QSIZE 0x0070 /* Message queue size configured (i.e. vectors per device allocated) */
#define VBOX_PCI_MSI_FLAGS_QMASK 0x000e /* Maximum queue size available (i.e. vectors per device possible) */
/* MSI-X flags (2 bytes, capability offset 2) */
/* Power management flags (2 bytes, capability offset 2) */
/* Power management control flags (2 bytes, capability offset 4) */
/* PCI-X config flags (2 bytes, capability offset 2) */
#define VBOX_PCI_X_CMD_MAX_OUTSTANDING_SPLIT_TRANS 0x0070
/* PCI-X config flags (4 bytes, capability offset 4) */
#define VBOX_PCI_X_STATUS_COMPLEX 0x00100000 /* Device Complexity, 0 = simple device, 1 = bridge device */
#define VBOX_PCI_X_STATUS_MAX_READ 0x00600000 /* Designed Max Memory Read Count, 0 = 512 bytes, 1 = 1024, 2 = 2048, 3 = 4096 */
/* PCI Express config flags (2 bytes, capability offset 2) */
/* PCI Express device capabilities (4 bytes, capability offset 4) */
/* PCI Express device control (2 bytes, capability offset 8) */
/* PCI Express device status (2 bytes, capability offset 10) */
/* PCI Express link capabilities (4 bytes, capability offset 12) */
/* PCI Express link control (2 bytes, capability offset 16) */
/* PCI Express link status (2 bytes, capability offset 18) */
/* PCI Express slot capabilities (4 bytes, capability offset 20) */
/* PCI Express slot control (2 bytes, capability offset 24) */
/* PCI Express slot status (2 bytes, capability offset 26) */
/* PCI Express root control (2 bytes, capability offset 28) */
/* PCI Express root capabilities (2 bytes, capability offset 30) */
/* PCI Express root status (4 bytes, capability offset 32) */
/**
* Callback function for reading from the PCI configuration space.
*
* @returns The register value.
* @param pPciDev Pointer to PCI device. Use pPciDev->pDevIns to get the device instance.
* @param Address The configuration space register address. [0..4096]
* @param cb The register size. [1,2,4]
*/
/** Pointer to a FNPCICONFIGREAD() function. */
typedef FNPCICONFIGREAD *PFNPCICONFIGREAD;
/** Pointer to a PFNPCICONFIGREAD. */
typedef PFNPCICONFIGREAD *PPFNPCICONFIGREAD;
/**
* Callback function for writing to the PCI configuration space.
*
* @param pPciDev Pointer to PCI device. Use pPciDev->pDevIns to get the device instance.
* @param Address The configuration space register address. [0..4096]
* @param u32Value The value that's being written. The number of bits actually used from
* this value is determined by the cb parameter.
* @param cb The register size. [1,2,4]
*/
typedef DECLCALLBACK(void) FNPCICONFIGWRITE(PPCIDEVICE pPciDev, uint32_t Address, uint32_t u32Value, unsigned cb);
/** Pointer to a FNPCICONFIGWRITE() function. */
typedef FNPCICONFIGWRITE *PFNPCICONFIGWRITE;
/** Pointer to a PFNPCICONFIGWRITE. */
typedef PFNPCICONFIGWRITE *PPFNPCICONFIGWRITE;
/** Fixed I/O region number for ROM. */
#define PCI_ROM_SLOT 6
#define VBOX_PCI_ROM_SLOT 6
/** Max number of I/O regions. */
#define PCI_NUM_REGIONS 7
#define VBOX_PCI_NUM_REGIONS 7
/*
* Hack to include the PCIDEVICEINT structure at the right place
* to avoid duplications of FNPCIIOREGIONMAP and PCI_NUM_REGIONS.
*/
#ifdef PCI_INCLUDE_PRIVATE
# include "PCIInternal.h"
#endif
/**
* PCI Device structure.
*/
typedef struct PCIDevice
{
/** PCI config space. */
/** Internal data. */
union
{
#ifdef PCIDEVICEINT_DECLARED
PCIDEVICEINT s;
#endif
char padding[328];
} Int;
/** Read only data.
* @{
*/
/** PCI device number on the pci bus. */
/** Device name. */
/** Pointer to the device instance which registered the device. */
/** @} */
} PCIDEVICE;
/* @todo: handle extended space access */
{
}
{
}
{
}
{
return RT_H2LE_U16(u16Value);
}
{
}
{
return RT_H2LE_U32(u32Value);
}
{
}
{
return RT_H2LE_U64(u64Value);
}
/**
* Sets the vendor id config register.
* @param pPciDev The PCI device.
* @param u16VendorId The vendor id.
*/
{
}
/**
* Gets the vendor id config register.
* @returns the vendor id.
* @param pPciDev The PCI device.
*/
{
}
/**
* Sets the device id config register.
* @param pPciDev The PCI device.
* @param u16DeviceId The device id.
*/
{
}
/**
* Gets the device id config register.
* @returns the device id.
* @param pPciDev The PCI device.
*/
{
}
/**
* Sets the command config register.
*
* @param pPciDev The PCI device.
* @param u16Command The command register value.
*/
{
}
/**
* Gets the command config register.
* @returns The command register value.
* @param pPciDev The PCI device.
*/
{
}
/**
* Checks if INTx interrupts disabled in the command config register.
* @returns true if disabled.
* @param pPciDev The PCI device.
*/
{
}
/**
* Gets the status config register.
*
* @returns status config register.
* @param pPciDev The PCI device.
*/
{
}
/**
* Sets the status config register.
*
* @param pPciDev The PCI device.
* @param u16Status The status register value.
*/
{
}
/**
* Sets the revision id config register.
*
* @param pPciDev The PCI device.
* @param u8RevisionId The revision id.
*/
{
}
/**
* Sets the register level programming class config register.
*
* @param pPciDev The PCI device.
* @param u8ClassProg The new value.
*/
{
}
/**
* Sets the sub-class (aka device class) config register.
*
* @param pPciDev The PCI device.
* @param u8SubClass The sub-class.
*/
{
}
/**
* Sets the base class config register.
*
* @param pPciDev The PCI device.
* @param u8BaseClass The base class.
*/
{
}
/**
* Sets the header type config register.
*
* @param pPciDev The PCI device.
* @param u8HdrType The header type.
*/
{
}
/**
* Gets the header type config register.
*
* @param pPciDev The PCI device.
* @returns u8HdrType The header type.
*/
{
}
/**
* Sets the BIST (built-in self-test) config register.
*
* @param pPciDev The PCI device.
* @param u8Bist The BIST value.
*/
{
}
/**
* Gets the BIST (built-in self-test) config register.
*
* @param pPciDev The PCI device.
* @returns u8Bist The BIST.
*/
{
}
/**
* Sets a base address config register.
*
* @param pPciDev The PCI device.
* @param fIOSpace Whether it's I/O (true) or memory (false) space.
* @param fPrefetchable Whether the memory is prefetachable. Must be false if fIOSpace == true.
* @param f64Bit Whether the memory can be mapped anywhere in the 64-bit address space. Otherwise restrict to 32-bit.
* @param u32Addr The address value.
*/
DECLINLINE(void) PCIDevSetBaseAddress(PPCIDEVICE pPciDev, uint8_t iReg, bool fIOSpace, bool fPrefetchable, bool f64Bit, uint32_t u32Addr)
{
if (fIOSpace)
{
}
else
{
if (fPrefetchable)
if (f64Bit)
}
switch (iReg)
{
case 0: iReg = VBOX_PCI_BASE_ADDRESS_0; break;
default: AssertFailedReturnVoid();
}
}
/**
* Sets the sub-system vendor id config register.
*
* @param pPciDev The PCI device.
* @param u16SubSysVendorId The sub-system vendor id.
*/
{
}
/**
* Gets the sub-system vendor id config register.
* @returns the sub-system vendor id.
* @param pPciDev The PCI device.
*/
{
}
/**
* Sets the sub-system id config register.
*
* @param pPciDev The PCI device.
* @param u16SubSystemId The sub-system id.
*/
{
}
/**
* Gets the sub-system id config register.
* @returns the sub-system id.
* @param pPciDev The PCI device.
*/
{
}
/**
* Sets offset to capability list.
*
* @param pPciDev The PCI device.
* @param u8Offset The offset to capability list.
*/
{
}
/**
* Returns offset to capability list.
*
* @returns offset to capability list.
* @param pPciDev The PCI device.
*/
{
}
/**
* Sets the interrupt line config register.
*
* @param pPciDev The PCI device.
* @param u8Line The interrupt line.
*/
{
}
/**
* Gets the interrupt line config register.
*
* @returns The interrupt line.
* @param pPciDev The PCI device.
*/
{
}
/**
* Sets the interrupt pin config register.
*
* @param pPciDev The PCI device.
* @param u8Pin The interrupt pin.
*/
{
}
/**
* Gets the interrupt pin config register.
*
* @returns The interrupt pin.
* @param pPciDev The PCI device.
*/
{
}
#ifdef PCIDEVICEINT_DECLARED
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
#endif /* PCIDEVICEINT_DECLARED */
#if defined(__cplusplus) && defined(IN_RING3)
/**
* Document me.
*
* @remarks C++ classes (structs included) are not generally accepted in
* VMM devices or drivers. An exception may be granted for this class
* if it's contained to ring-3 and that this is a one time exception
* which sets no precedent.
*/
struct PciBusAddress
{
/** @todo r=bird: Add 'm', or 'm_' to data members. This is general
* practice in most of the source tree. */
int iBus;
int iDevice;
int iFn;
{
clear();
}
{
}
{
return *this;
}
{
}
void init(const PciBusAddress &a)
{
}
bool operator<(const PciBusAddress &a) const
{
return true;
return false;
return true;
return false;
return true;
return false;
return false;
}
bool operator==(const PciBusAddress &a) const
{
}
bool operator!=(const PciBusAddress &a) const
{
}
bool valid() const
{
}
{
}
{
return *this;
}
};
#endif /* __cplusplus */
/** @} */
#endif