1 #ifndef _XEN_VPCI_H_
2 #define _XEN_VPCI_H_
3 
4 #ifdef CONFIG_HAS_VPCI
5 
6 #include <xen/pci.h>
7 #include <xen/types.h>
8 #include <xen/list.h>
9 
10 typedef uint32_t vpci_read_t(const struct pci_dev *pdev, unsigned int reg,
11                              void *data);
12 
13 typedef void vpci_write_t(const struct pci_dev *pdev, unsigned int reg,
14                           uint32_t val, void *data);
15 
16 typedef int vpci_register_init_t(struct pci_dev *dev);
17 
18 #define VPCI_PRIORITY_HIGH      "1"
19 #define VPCI_PRIORITY_MIDDLE    "5"
20 #define VPCI_PRIORITY_LOW       "9"
21 
22 #define VPCI_ECAM_BDF(addr)     (((addr) & 0x0ffff000) >> 12)
23 
24 /*
25  * Maximum number of devices supported by the virtual bus topology:
26  * each PCI bus supports 32 devices/slots at max or up to 256 when
27  * there are multi-function ones which are not yet supported.
28  * This limit implies only segment 0, bus 0 is supported.
29  */
30 #define VPCI_MAX_VIRT_DEV       (PCI_SLOT(~0) + 1)
31 
32 #define REGISTER_VPCI_INIT(x, p)                \
33   static vpci_register_init_t *const x##_entry  \
34                __used_section(".data.vpci." p) = (x)
35 
36 /* Assign vPCI to device by adding handlers. */
37 int __must_check vpci_assign_device(struct pci_dev *pdev);
38 
39 /* Remove all handlers and free vpci related structures. */
40 void vpci_deassign_device(struct pci_dev *pdev);
41 
42 /* Add/remove a register handler. */
43 int __must_check vpci_add_register_mask(struct vpci *vpci,
44                                         vpci_read_t *read_handler,
45                                         vpci_write_t *write_handler,
46                                         unsigned int offset, unsigned int size,
47                                         void *data, uint32_t ro_mask,
48                                         uint32_t rw1c_mask, uint32_t rsvdp_mask,
49                                         uint32_t rsvdz_mask);
vpci_add_register(struct vpci * vpci,vpci_read_t * read_handler,vpci_write_t * write_handler,unsigned int offset,unsigned int size,void * data)50 static inline int __must_check vpci_add_register(struct vpci *vpci,
51                                                  vpci_read_t *read_handler,
52                                                  vpci_write_t *write_handler,
53                                                  unsigned int offset,
54                                                  unsigned int size, void *data)
55 {
56     return vpci_add_register_mask(vpci, read_handler, write_handler, offset,
57                                   size, data, 0, 0, 0, 0);
58 }
59 
60 int __must_check vpci_remove_register(struct vpci *vpci, unsigned int offset,
61                                       unsigned int size);
62 
63 /* Generic read/write handlers for the PCI config space. */
64 uint32_t vpci_read(pci_sbdf_t sbdf, unsigned int reg, unsigned int size);
65 void vpci_write(pci_sbdf_t sbdf, unsigned int reg, unsigned int size,
66                 uint32_t data);
67 
68 /* Helper to return the value passed in data. */
69 uint32_t cf_check vpci_read_val(
70     const struct pci_dev *pdev, unsigned int reg, void *data);
71 
72 /* Passthrough handlers. */
73 uint32_t cf_check vpci_hw_read8(
74     const struct pci_dev *pdev, unsigned int reg, void *data);
75 uint32_t cf_check vpci_hw_read16(
76     const struct pci_dev *pdev, unsigned int reg, void *data);
77 uint32_t cf_check vpci_hw_read32(
78     const struct pci_dev *pdev, unsigned int reg, void *data);
79 void cf_check vpci_hw_write16(
80     const struct pci_dev *pdev, unsigned int reg, uint32_t val, void *data);
81 
82 /*
83  * Check for pending vPCI operations on this vcpu. Returns true if the vcpu
84  * should not run.
85  */
86 bool __must_check vpci_process_pending(struct vcpu *v);
87 
88 struct vpci {
89     /* List of vPCI handlers for a device. */
90     struct list_head handlers;
91     spinlock_t lock;
92 
93 #ifdef __XEN__
94     /* Hide the rest of the vpci struct from the user-space test harness. */
95     struct vpci_header {
96         /* Information about the PCI BARs of this device. */
97         struct vpci_bar {
98             /* Physical (host) address. */
99             uint64_t addr;
100             /* Guest address. */
101             uint64_t guest_addr;
102             uint64_t size;
103             struct rangeset *mem;
104             enum {
105                 VPCI_BAR_EMPTY,
106                 VPCI_BAR_IO,
107                 VPCI_BAR_MEM32,
108                 VPCI_BAR_MEM64_LO,
109                 VPCI_BAR_MEM64_HI,
110                 VPCI_BAR_ROM,
111             } type;
112             bool prefetchable : 1;
113             /* Store whether the BAR is mapped into guest p2m. */
114             bool enabled      : 1;
115         } bars[PCI_HEADER_NORMAL_NR_BARS + 1];
116         /* At most 6 BARS + 1 expansion ROM BAR. */
117 
118         /* Guest (domU only) view of the PCI_COMMAND register. */
119         uint16_t guest_cmd;
120 
121         /*
122          * Store whether the ROM enable bit is set (doesn't imply ROM BAR
123          * is mapped into guest p2m) if there's a ROM BAR on the device.
124          */
125         bool rom_enabled      : 1;
126         /*
127          * Cache whether memory decoding is enabled from our PoV.
128          * Some devices have a sticky memory decoding so that can't be relied
129          * upon to know whether BARs are mapped into the guest p2m.
130          */
131         bool bars_mapped      : 1;
132         /* FIXME: currently there's no support for SR-IOV. */
133     } header;
134 
135     /* MSI data. */
136     struct vpci_msi {
137       /* Address. */
138         uint64_t address;
139         /* Mask bitfield. */
140         uint32_t mask;
141         /* Data. */
142         uint16_t data;
143         /* Number of vectors configured. */
144         uint8_t vectors     : 6;
145         /* Supports per-vector masking? */
146         bool masking        : 1;
147         /* 64-bit address capable? */
148         bool address64      : 1;
149         /* Enabled? */
150         bool enabled        : 1;
151         /* Arch-specific data. */
152         struct vpci_arch_msi arch;
153     } *msi;
154 
155     /* MSI-X data. */
156     struct vpci_msix {
157         struct pci_dev *pdev;
158         /* List link. */
159         struct list_head next;
160         /* Table information. */
161 #define VPCI_MSIX_TABLE     0
162 #define VPCI_MSIX_PBA       1
163 #define VPCI_MSIX_MEM_NUM   2
164         uint32_t tables[VPCI_MSIX_MEM_NUM];
165         /* Maximum number of vectors supported by the device. */
166         uint16_t max_entries : 12;
167         /* MSI-X enabled? */
168         bool enabled         : 1;
169         /* Masked? */
170         bool masked          : 1;
171         /* Partial table map. */
172 #define VPCI_MSIX_TBL_HEAD 0
173 #define VPCI_MSIX_TBL_TAIL 1
174 #define VPCI_MSIX_PBA_HEAD 2
175 #define VPCI_MSIX_PBA_TAIL 3
176         void __iomem *table[4];
177         /* Entries. */
178         struct vpci_msix_entry {
179             uint64_t addr;
180             uint32_t data;
181             bool masked  : 1;
182             bool updated : 1;
183             struct vpci_arch_msix_entry arch;
184         } entries[];
185     } *msix;
186 #ifdef CONFIG_HAS_VPCI_GUEST_SUPPORT
187     /* Guest SBDF of the device. */
188 #define INVALID_GUEST_SBDF ((pci_sbdf_t){ .sbdf = ~0U })
189     pci_sbdf_t guest_sbdf;
190 #endif
191 #endif
192 };
193 
194 struct vpci_vcpu {
195     /* Per-vcpu structure to store state while {un}mapping of PCI BARs. */
196     struct pci_dev *pdev;
197     uint16_t cmd;
198     bool rom_only : 1;
199 };
200 
201 #ifdef __XEN__
202 void vpci_dump_msi(void);
203 
204 /* Make sure there's a hole in the p2m for the MSIX mmio areas. */
205 int vpci_make_msix_hole(const struct pci_dev *pdev);
206 
207 /* Arch-specific vPCI MSI helpers. */
208 void vpci_msi_arch_mask(struct vpci_msi *msi, const struct pci_dev *pdev,
209                         unsigned int entry, bool mask);
210 int __must_check vpci_msi_arch_enable(struct vpci_msi *msi,
211                                       const struct pci_dev *pdev,
212                                       unsigned int vectors);
213 void vpci_msi_arch_disable(struct vpci_msi *msi, const struct pci_dev *pdev);
214 void vpci_msi_arch_update(struct vpci_msi *msi, const struct pci_dev *pdev);
215 void vpci_msi_arch_init(struct vpci_msi *msi);
216 void vpci_msi_arch_print(const struct vpci_msi *msi);
217 
218 /* Arch-specific vPCI MSI-X helpers. */
219 void vpci_msix_arch_mask_entry(struct vpci_msix_entry *entry,
220                                const struct pci_dev *pdev, bool mask);
221 int __must_check vpci_msix_arch_enable_entry(struct vpci_msix_entry *entry,
222                                              const struct pci_dev *pdev,
223                                              paddr_t table_base);
224 int __must_check vpci_msix_arch_disable_entry(struct vpci_msix_entry *entry,
225                                               const struct pci_dev *pdev);
226 void vpci_msix_arch_init_entry(struct vpci_msix_entry *entry);
227 int vpci_msix_arch_print(const struct vpci_msix *msix);
228 
229 /*
230  * Helper functions to fetch MSIX related data. They are used by both the
231  * emulated MSIX code and the BAR handlers.
232  */
vmsix_table_base(const struct vpci * vpci,unsigned int nr)233 static inline paddr_t vmsix_table_base(const struct vpci *vpci, unsigned int nr)
234 {
235     return vpci->header.bars[vpci->msix->tables[nr] &
236                              PCI_MSIX_BIRMASK].guest_addr;
237 }
238 
vmsix_table_addr(const struct vpci * vpci,unsigned int nr)239 static inline paddr_t vmsix_table_addr(const struct vpci *vpci, unsigned int nr)
240 {
241     return vmsix_table_base(vpci, nr) +
242            (vpci->msix->tables[nr] & ~PCI_MSIX_BIRMASK);
243 }
244 
245 /*
246  * Note regarding the size calculation of the PBA: the spec mentions "The last
247  * QWORD will not necessarily be fully populated", so it implies that the PBA
248  * size is 64-bit aligned.
249  */
vmsix_table_size(const struct vpci * vpci,unsigned int nr)250 static inline size_t vmsix_table_size(const struct vpci *vpci, unsigned int nr)
251 {
252     return
253         (nr == VPCI_MSIX_TABLE) ? vpci->msix->max_entries * PCI_MSIX_ENTRY_SIZE
254                                 : ROUNDUP(DIV_ROUND_UP(vpci->msix->max_entries,
255                                                        8), 8);
256 }
257 
vmsix_entry_nr(const struct vpci_msix * msix,const struct vpci_msix_entry * entry)258 static inline unsigned int vmsix_entry_nr(const struct vpci_msix *msix,
259                                           const struct vpci_msix_entry *entry)
260 {
261     return entry - msix->entries;
262 }
263 
264 bool vpci_access_allowed(unsigned int reg, unsigned int len);
265 
266 /* ECAM mmio read/write helpers */
267 bool vpci_ecam_write(pci_sbdf_t sbdf, unsigned int reg, unsigned int len,
268                      unsigned long data);
269 
270 bool vpci_ecam_read(pci_sbdf_t sbdf, unsigned int reg, unsigned int len,
271                     unsigned long *data);
272 
273 #endif /* __XEN__ */
274 
275 #else /* !CONFIG_HAS_VPCI */
276 struct vpci_vcpu {};
277 
vpci_assign_device(struct pci_dev * pdev)278 static inline int vpci_assign_device(struct pci_dev *pdev)
279 {
280     return 0;
281 }
282 
vpci_deassign_device(struct pci_dev * pdev)283 static inline void vpci_deassign_device(struct pci_dev *pdev) { }
284 
vpci_dump_msi(void)285 static inline void vpci_dump_msi(void) { }
286 
vpci_read(pci_sbdf_t sbdf,unsigned int reg,unsigned int size)287 static inline uint32_t vpci_read(pci_sbdf_t sbdf, unsigned int reg,
288                                  unsigned int size)
289 {
290     ASSERT_UNREACHABLE();
291     return ~(uint32_t)0;
292 }
293 
vpci_write(pci_sbdf_t sbdf,unsigned int reg,unsigned int size,uint32_t data)294 static inline void vpci_write(pci_sbdf_t sbdf, unsigned int reg,
295                               unsigned int size, uint32_t data)
296 {
297     ASSERT_UNREACHABLE();
298 }
299 
vpci_process_pending(struct vcpu * v)300 static inline bool __must_check vpci_process_pending(struct vcpu *v)
301 {
302     ASSERT_UNREACHABLE();
303     return false;
304 }
305 #endif
306 
307 #endif
308 
309 /*
310  * Local variables:
311  * mode: C
312  * c-file-style: "BSD"
313  * c-basic-offset: 4
314  * tab-width: 4
315  * indent-tabs-mode: nil
316  * End:
317  */
318