qemu/include/hw/pci/pci_device.h
<<
>>
Prefs
   1#ifndef QEMU_PCI_DEVICE_H
   2#define QEMU_PCI_DEVICE_H
   3
   4#include "hw/pci/pci.h"
   5#include "hw/pci/pcie.h"
   6
   7#define TYPE_PCI_DEVICE "pci-device"
   8typedef struct PCIDeviceClass PCIDeviceClass;
   9DECLARE_OBJ_CHECKERS(PCIDevice, PCIDeviceClass,
  10                     PCI_DEVICE, TYPE_PCI_DEVICE)
  11
  12/*
  13 * Implemented by devices that can be plugged on CXL buses. In the spec, this is
  14 * actually a "CXL Component, but we name it device to match the PCI naming.
  15 */
  16#define INTERFACE_CXL_DEVICE "cxl-device"
  17
  18/* Implemented by devices that can be plugged on PCI Express buses */
  19#define INTERFACE_PCIE_DEVICE "pci-express-device"
  20
  21/* Implemented by devices that can be plugged on Conventional PCI buses */
  22#define INTERFACE_CONVENTIONAL_PCI_DEVICE "conventional-pci-device"
  23
  24struct PCIDeviceClass {
  25    DeviceClass parent_class;
  26
  27    void (*realize)(PCIDevice *dev, Error **errp);
  28    PCIUnregisterFunc *exit;
  29    PCIConfigReadFunc *config_read;
  30    PCIConfigWriteFunc *config_write;
  31
  32    uint16_t vendor_id;
  33    uint16_t device_id;
  34    uint8_t revision;
  35    uint16_t class_id;
  36    uint16_t subsystem_vendor_id;       /* only for header type = 0 */
  37    uint16_t subsystem_id;              /* only for header type = 0 */
  38
  39    const char *romfile;                /* rom bar */
  40};
  41
  42enum PCIReqIDType {
  43    PCI_REQ_ID_INVALID = 0,
  44    PCI_REQ_ID_BDF,
  45    PCI_REQ_ID_SECONDARY_BUS,
  46    PCI_REQ_ID_MAX,
  47};
  48typedef enum PCIReqIDType PCIReqIDType;
  49
  50struct PCIReqIDCache {
  51    PCIDevice *dev;
  52    PCIReqIDType type;
  53};
  54typedef struct PCIReqIDCache PCIReqIDCache;
  55
  56struct PCIDevice {
  57    DeviceState qdev;
  58    bool partially_hotplugged;
  59    bool has_power;
  60
  61    /* PCI config space */
  62    uint8_t *config;
  63
  64    /*
  65     * Used to enable config checks on load. Note that writable bits are
  66     * never checked even if set in cmask.
  67     */
  68    uint8_t *cmask;
  69
  70    /* Used to implement R/W bytes */
  71    uint8_t *wmask;
  72
  73    /* Used to implement RW1C(Write 1 to Clear) bytes */
  74    uint8_t *w1cmask;
  75
  76    /* Used to allocate config space for capabilities. */
  77    uint8_t *used;
  78
  79    /* the following fields are read only */
  80    int32_t devfn;
  81    /*
  82     * Cached device to fetch requester ID from, to avoid the PCI tree
  83     * walking every time we invoke PCI request (e.g., MSI). For
  84     * conventional PCI root complex, this field is meaningless.
  85     */
  86    PCIReqIDCache requester_id_cache;
  87    char name[64];
  88    PCIIORegion io_regions[PCI_NUM_REGIONS];
  89    AddressSpace bus_master_as;
  90    MemoryRegion bus_master_container_region;
  91    MemoryRegion bus_master_enable_region;
  92
  93    /* do not access the following fields */
  94    PCIConfigReadFunc *config_read;
  95    PCIConfigWriteFunc *config_write;
  96
  97    /* Legacy PCI VGA regions */
  98    MemoryRegion *vga_regions[QEMU_PCI_VGA_NUM_REGIONS];
  99    bool has_vga;
 100
 101    /* Current IRQ levels.  Used internally by the generic PCI code.  */
 102    uint8_t irq_state;
 103
 104    /* Capability bits */
 105    uint32_t cap_present;
 106
 107    /* Offset of MSI-X capability in config space */
 108    uint8_t msix_cap;
 109
 110    /* MSI-X entries */
 111    int msix_entries_nr;
 112
 113    /* Space to store MSIX table & pending bit array */
 114    uint8_t *msix_table;
 115    uint8_t *msix_pba;
 116
 117    /* May be used by INTx or MSI during interrupt notification */
 118    void *irq_opaque;
 119
 120    MSITriggerFunc *msi_trigger;
 121    MSIPrepareMessageFunc *msi_prepare_message;
 122    MSIxPrepareMessageFunc *msix_prepare_message;
 123
 124    /* MemoryRegion container for msix exclusive BAR setup */
 125    MemoryRegion msix_exclusive_bar;
 126    /* Memory Regions for MSIX table and pending bit entries. */
 127    MemoryRegion msix_table_mmio;
 128    MemoryRegion msix_pba_mmio;
 129    /* Reference-count for entries actually in use by driver. */
 130    unsigned *msix_entry_used;
 131    /* MSIX function mask set or MSIX disabled */
 132    bool msix_function_masked;
 133    /* Version id needed for VMState */
 134    int32_t version_id;
 135
 136    /* Offset of MSI capability in config space */
 137    uint8_t msi_cap;
 138
 139    /* PCI Express */
 140    PCIExpressDevice exp;
 141
 142    /* SHPC */
 143    SHPCDevice *shpc;
 144
 145    /* Location of option rom */
 146    char *romfile;
 147    uint32_t romsize;
 148    bool has_rom;
 149    MemoryRegion rom;
 150    uint32_t rom_bar;
 151
 152    /* INTx routing notifier */
 153    PCIINTxRoutingNotifier intx_routing_notifier;
 154
 155    /* MSI-X notifiers */
 156    MSIVectorUseNotifier msix_vector_use_notifier;
 157    MSIVectorReleaseNotifier msix_vector_release_notifier;
 158    MSIVectorPollNotifier msix_vector_poll_notifier;
 159
 160    /* ID of standby device in net_failover pair */
 161    char *failover_pair_id;
 162    uint32_t acpi_index;
 163};
 164
 165static inline int pci_intx(PCIDevice *pci_dev)
 166{
 167    return pci_get_byte(pci_dev->config + PCI_INTERRUPT_PIN) - 1;
 168}
 169
 170static inline int pci_is_cxl(const PCIDevice *d)
 171{
 172    return d->cap_present & QEMU_PCIE_CAP_CXL;
 173}
 174
 175static inline int pci_is_express(const PCIDevice *d)
 176{
 177    return d->cap_present & QEMU_PCI_CAP_EXPRESS;
 178}
 179
 180static inline int pci_is_express_downstream_port(const PCIDevice *d)
 181{
 182    uint8_t type;
 183
 184    if (!pci_is_express(d) || !d->exp.exp_cap) {
 185        return 0;
 186    }
 187
 188    type = pcie_cap_get_type(d);
 189
 190    return type == PCI_EXP_TYPE_DOWNSTREAM || type == PCI_EXP_TYPE_ROOT_PORT;
 191}
 192
 193static inline int pci_is_vf(const PCIDevice *d)
 194{
 195    return d->exp.sriov_vf.pf != NULL;
 196}
 197
 198static inline uint32_t pci_config_size(const PCIDevice *d)
 199{
 200    return pci_is_express(d) ? PCIE_CONFIG_SPACE_SIZE : PCI_CONFIG_SPACE_SIZE;
 201}
 202
 203static inline uint16_t pci_get_bdf(PCIDevice *dev)
 204{
 205    return PCI_BUILD_BDF(pci_bus_num(pci_get_bus(dev)), dev->devfn);
 206}
 207
 208uint16_t pci_requester_id(PCIDevice *dev);
 209
 210/* DMA access functions */
 211static inline AddressSpace *pci_get_address_space(PCIDevice *dev)
 212{
 213    return &dev->bus_master_as;
 214}
 215
 216/**
 217 * pci_dma_rw: Read from or write to an address space from PCI device.
 218 *
 219 * Return a MemTxResult indicating whether the operation succeeded
 220 * or failed (eg unassigned memory, device rejected the transaction,
 221 * IOMMU fault).
 222 *
 223 * @dev: #PCIDevice doing the memory access
 224 * @addr: address within the #PCIDevice address space
 225 * @buf: buffer with the data transferred
 226 * @len: the number of bytes to read or write
 227 * @dir: indicates the transfer direction
 228 */
 229static inline MemTxResult pci_dma_rw(PCIDevice *dev, dma_addr_t addr,
 230                                     void *buf, dma_addr_t len,
 231                                     DMADirection dir, MemTxAttrs attrs)
 232{
 233    return dma_memory_rw(pci_get_address_space(dev), addr, buf, len,
 234                         dir, attrs);
 235}
 236
 237/**
 238 * pci_dma_read: Read from an address space from PCI device.
 239 *
 240 * Return a MemTxResult indicating whether the operation succeeded
 241 * or failed (eg unassigned memory, device rejected the transaction,
 242 * IOMMU fault).  Called within RCU critical section.
 243 *
 244 * @dev: #PCIDevice doing the memory access
 245 * @addr: address within the #PCIDevice address space
 246 * @buf: buffer with the data transferred
 247 * @len: length of the data transferred
 248 */
 249static inline MemTxResult pci_dma_read(PCIDevice *dev, dma_addr_t addr,
 250                                       void *buf, dma_addr_t len)
 251{
 252    return pci_dma_rw(dev, addr, buf, len,
 253                      DMA_DIRECTION_TO_DEVICE, MEMTXATTRS_UNSPECIFIED);
 254}
 255
 256/**
 257 * pci_dma_write: Write to address space from PCI device.
 258 *
 259 * Return a MemTxResult indicating whether the operation succeeded
 260 * or failed (eg unassigned memory, device rejected the transaction,
 261 * IOMMU fault).
 262 *
 263 * @dev: #PCIDevice doing the memory access
 264 * @addr: address within the #PCIDevice address space
 265 * @buf: buffer with the data transferred
 266 * @len: the number of bytes to write
 267 */
 268static inline MemTxResult pci_dma_write(PCIDevice *dev, dma_addr_t addr,
 269                                        const void *buf, dma_addr_t len)
 270{
 271    return pci_dma_rw(dev, addr, (void *) buf, len,
 272                      DMA_DIRECTION_FROM_DEVICE, MEMTXATTRS_UNSPECIFIED);
 273}
 274
 275#define PCI_DMA_DEFINE_LDST(_l, _s, _bits) \
 276    static inline MemTxResult ld##_l##_pci_dma(PCIDevice *dev, \
 277                                               dma_addr_t addr, \
 278                                               uint##_bits##_t *val, \
 279                                               MemTxAttrs attrs) \
 280    { \
 281        return ld##_l##_dma(pci_get_address_space(dev), addr, val, attrs); \
 282    } \
 283    static inline MemTxResult st##_s##_pci_dma(PCIDevice *dev, \
 284                                               dma_addr_t addr, \
 285                                               uint##_bits##_t val, \
 286                                               MemTxAttrs attrs) \
 287    { \
 288        return st##_s##_dma(pci_get_address_space(dev), addr, val, attrs); \
 289    }
 290
 291PCI_DMA_DEFINE_LDST(ub, b, 8);
 292PCI_DMA_DEFINE_LDST(uw_le, w_le, 16)
 293PCI_DMA_DEFINE_LDST(l_le, l_le, 32);
 294PCI_DMA_DEFINE_LDST(q_le, q_le, 64);
 295PCI_DMA_DEFINE_LDST(uw_be, w_be, 16)
 296PCI_DMA_DEFINE_LDST(l_be, l_be, 32);
 297PCI_DMA_DEFINE_LDST(q_be, q_be, 64);
 298
 299#undef PCI_DMA_DEFINE_LDST
 300
 301/**
 302 * pci_dma_map: Map device PCI address space range into host virtual address
 303 * @dev: #PCIDevice to be accessed
 304 * @addr: address within that device's address space
 305 * @plen: pointer to length of buffer; updated on return to indicate
 306 *        if only a subset of the requested range has been mapped
 307 * @dir: indicates the transfer direction
 308 *
 309 * Return: A host pointer, or %NULL if the resources needed to
 310 *         perform the mapping are exhausted (in that case *@plen
 311 *         is set to zero).
 312 */
 313static inline void *pci_dma_map(PCIDevice *dev, dma_addr_t addr,
 314                                dma_addr_t *plen, DMADirection dir)
 315{
 316    return dma_memory_map(pci_get_address_space(dev), addr, plen, dir,
 317                          MEMTXATTRS_UNSPECIFIED);
 318}
 319
 320static inline void pci_dma_unmap(PCIDevice *dev, void *buffer, dma_addr_t len,
 321                                 DMADirection dir, dma_addr_t access_len)
 322{
 323    dma_memory_unmap(pci_get_address_space(dev), buffer, len, dir, access_len);
 324}
 325
 326static inline void pci_dma_sglist_init(QEMUSGList *qsg, PCIDevice *dev,
 327                                       int alloc_hint)
 328{
 329    qemu_sglist_init(qsg, DEVICE(dev), alloc_hint, pci_get_address_space(dev));
 330}
 331
 332extern const VMStateDescription vmstate_pci_device;
 333
 334#define VMSTATE_PCI_DEVICE(_field, _state) {                         \
 335    .name       = (stringify(_field)),                               \
 336    .size       = sizeof(PCIDevice),                                 \
 337    .vmsd       = &vmstate_pci_device,                               \
 338    .flags      = VMS_STRUCT,                                        \
 339    .offset     = vmstate_offset_value(_state, _field, PCIDevice),   \
 340}
 341
 342#define VMSTATE_PCI_DEVICE_POINTER(_field, _state) {                 \
 343    .name       = (stringify(_field)),                               \
 344    .size       = sizeof(PCIDevice),                                 \
 345    .vmsd       = &vmstate_pci_device,                               \
 346    .flags      = VMS_STRUCT | VMS_POINTER,                          \
 347    .offset     = vmstate_offset_pointer(_state, _field, PCIDevice), \
 348}
 349
 350#endif
 351