xref: /openbmc/qemu/hw/vfio/pci.h (revision 43b48cfc3e8ff745a10a6b78a55519d5cf7ec5e8)
1  /*
2   * vfio based device assignment support - PCI devices
3   *
4   * Copyright Red Hat, Inc. 2012-2015
5   *
6   * Authors:
7   *  Alex Williamson <alex.williamson@redhat.com>
8   *
9   * This work is licensed under the terms of the GNU GPL, version 2.  See
10   * the COPYING file in the top-level directory.
11   */
12  #ifndef HW_VFIO_VFIO_PCI_H
13  #define HW_VFIO_VFIO_PCI_H
14  
15  #include "qemu-common.h"
16  #include "exec/memory.h"
17  #include "hw/pci/pci.h"
18  #include "hw/vfio/vfio-common.h"
19  #include "qemu/event_notifier.h"
20  #include "qemu/queue.h"
21  #include "qemu/timer.h"
22  
23  #define PCI_ANY_ID (~0)
24  
25  struct VFIOPCIDevice;
26  
27  typedef struct VFIOQuirk {
28      QLIST_ENTRY(VFIOQuirk) next;
29      void *data;
30      int nr_mem;
31      MemoryRegion *mem;
32  } VFIOQuirk;
33  
34  typedef struct VFIOBAR {
35      VFIORegion region;
36      bool ioport;
37      bool mem64;
38      QLIST_HEAD(, VFIOQuirk) quirks;
39  } VFIOBAR;
40  
41  typedef struct VFIOVGARegion {
42      MemoryRegion mem;
43      off_t offset;
44      int nr;
45      QLIST_HEAD(, VFIOQuirk) quirks;
46  } VFIOVGARegion;
47  
48  typedef struct VFIOVGA {
49      off_t fd_offset;
50      int fd;
51      VFIOVGARegion region[QEMU_PCI_VGA_NUM_REGIONS];
52  } VFIOVGA;
53  
54  typedef struct VFIOINTx {
55      bool pending; /* interrupt pending */
56      bool kvm_accel; /* set when QEMU bypass through KVM enabled */
57      uint8_t pin; /* which pin to pull for qemu_set_irq */
58      EventNotifier interrupt; /* eventfd triggered on interrupt */
59      EventNotifier unmask; /* eventfd for unmask on QEMU bypass */
60      PCIINTxRoute route; /* routing info for QEMU bypass */
61      uint32_t mmap_timeout; /* delay to re-enable mmaps after interrupt */
62      QEMUTimer *mmap_timer; /* enable mmaps after periods w/o interrupts */
63  } VFIOINTx;
64  
65  typedef struct VFIOMSIVector {
66      /*
67       * Two interrupt paths are configured per vector.  The first, is only used
68       * for interrupts injected via QEMU.  This is typically the non-accel path,
69       * but may also be used when we want QEMU to handle masking and pending
70       * bits.  The KVM path bypasses QEMU and is therefore higher performance,
71       * but requires masking at the device.  virq is used to track the MSI route
72       * through KVM, thus kvm_interrupt is only available when virq is set to a
73       * valid (>= 0) value.
74       */
75      EventNotifier interrupt;
76      EventNotifier kvm_interrupt;
77      struct VFIOPCIDevice *vdev; /* back pointer to device */
78      int virq;
79      bool use;
80  } VFIOMSIVector;
81  
82  enum {
83      VFIO_INT_NONE = 0,
84      VFIO_INT_INTx = 1,
85      VFIO_INT_MSI  = 2,
86      VFIO_INT_MSIX = 3,
87  };
88  
89  /* Cache of MSI-X setup plus extra mmap and memory region for split BAR map */
90  typedef struct VFIOMSIXInfo {
91      uint8_t table_bar;
92      uint8_t pba_bar;
93      uint16_t entries;
94      uint32_t table_offset;
95      uint32_t pba_offset;
96      MemoryRegion mmap_mem;
97      void *mmap;
98      unsigned long *pending;
99  } VFIOMSIXInfo;
100  
101  typedef struct VFIOPCIDevice {
102      PCIDevice pdev;
103      VFIODevice vbasedev;
104      VFIOINTx intx;
105      unsigned int config_size;
106      uint8_t *emulated_config_bits; /* QEMU emulated bits, little-endian */
107      off_t config_offset; /* Offset of config space region within device fd */
108      unsigned int rom_size;
109      off_t rom_offset; /* Offset of ROM region within device fd */
110      void *rom;
111      int msi_cap_size;
112      VFIOMSIVector *msi_vectors;
113      VFIOMSIXInfo *msix;
114      int nr_vectors; /* Number of MSI/MSIX vectors currently in use */
115      int interrupt; /* Current interrupt type */
116      VFIOBAR bars[PCI_NUM_REGIONS - 1]; /* No ROM */
117      VFIOVGA vga; /* 0xa0000, 0x3b0, 0x3c0 */
118      PCIHostDeviceAddress host;
119      EventNotifier err_notifier;
120      EventNotifier req_notifier;
121      int (*resetfn)(struct VFIOPCIDevice *);
122      uint32_t vendor_id;
123      uint32_t device_id;
124      uint32_t sub_vendor_id;
125      uint32_t sub_device_id;
126      uint32_t features;
127  #define VFIO_FEATURE_ENABLE_VGA_BIT 0
128  #define VFIO_FEATURE_ENABLE_VGA (1 << VFIO_FEATURE_ENABLE_VGA_BIT)
129  #define VFIO_FEATURE_ENABLE_REQ_BIT 1
130  #define VFIO_FEATURE_ENABLE_REQ (1 << VFIO_FEATURE_ENABLE_REQ_BIT)
131      int32_t bootindex;
132      uint8_t pm_cap;
133      bool has_vga;
134      bool pci_aer;
135      bool req_enabled;
136      bool has_flr;
137      bool has_pm_reset;
138      bool rom_read_failed;
139      bool no_kvm_intx;
140      bool no_kvm_msi;
141      bool no_kvm_msix;
142  } VFIOPCIDevice;
143  
144  uint32_t vfio_pci_read_config(PCIDevice *pdev, uint32_t addr, int len);
145  void vfio_pci_write_config(PCIDevice *pdev,
146                             uint32_t addr, uint32_t val, int len);
147  
148  uint64_t vfio_vga_read(void *opaque, hwaddr addr, unsigned size);
149  void vfio_vga_write(void *opaque, hwaddr addr, uint64_t data, unsigned size);
150  
151  bool vfio_blacklist_opt_rom(VFIOPCIDevice *vdev);
152  void vfio_vga_quirk_setup(VFIOPCIDevice *vdev);
153  void vfio_vga_quirk_teardown(VFIOPCIDevice *vdev);
154  void vfio_vga_quirk_free(VFIOPCIDevice *vdev);
155  void vfio_bar_quirk_setup(VFIOPCIDevice *vdev, int nr);
156  void vfio_bar_quirk_teardown(VFIOPCIDevice *vdev, int nr);
157  void vfio_bar_quirk_free(VFIOPCIDevice *vdev, int nr);
158  void vfio_setup_resetfn_quirk(VFIOPCIDevice *vdev);
159  
160  #endif /* HW_VFIO_VFIO_PCI_H */
161