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