1 /*-
2 * Copyright (c) 2011 NetApp, Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $FreeBSD$
27 */
28
29 #ifndef _PCI_CORE_H_
30 #define _PCI_CORE_H_
31
32 #include <sys/queue.h>
33
34 #include <assert.h>
35 #include <stdbool.h>
36 #include "types.h"
37 #include "pcireg.h"
38 #include "log.h"
39
40 #define PCI_BARMAX PCIR_MAX_BAR_0 /* BAR registers in a Type 0 header */
41 #define PCI_BDF(b, d, f) (((b & 0xFF) << 8) | ((d & 0x1F) << 3) | ((f & 0x7)))
42
43 #define PCI_EMUL_MEMBASE32 0x80000000UL /* 2GB */
44 #define PCI_EMUL_MEMLIMIT32 0xE0000000UL /* 3.5GB */
45
46 #define PCI_EMUL_ECFG_BASE 0xE0000000UL /* 3.5GB */
47
48 #define PCI_EMUL_MEMBASE64 0x4000000000UL /* 256GB */
49 #define PCI_EMUL_MEMLIMIT64 0x8000000000UL /* 512GB */
50
51 #define VSSRAM_MAX_SIZE 0x00800000UL
52 #define VSSRAM_BASE_GPA (PCI_EMUL_MEMBASE32 - VSSRAM_MAX_SIZE)
53
54 /* GVT BARs + PTDEV IO BARs */
55 #define REGION_NUMS 32
56
57 struct vmctx;
58 struct pci_vdev;
59 struct memory_region;
60
61 struct pci_vdev_ops {
62 char *class_name; /* Name of device class */
63
64 /* instance creation */
65 int (*vdev_init)(struct vmctx *, struct pci_vdev *,
66 char *opts);
67
68 /* instance deinit */
69 void (*vdev_deinit)(struct vmctx *, struct pci_vdev *,
70 char *opts);
71
72 /* ACPI DSDT enumeration */
73 void (*vdev_write_dsdt)(struct pci_vdev *);
74
75 /* ops related to physical resources */
76 void (*vdev_phys_access)(struct vmctx *ctx, struct pci_vdev *dev);
77
78 /* config space read/write callbacks */
79 int (*vdev_cfgwrite)(struct vmctx *ctx, int vcpu,
80 struct pci_vdev *pi, int offset,
81 int bytes, uint32_t val);
82 int (*vdev_cfgread)(struct vmctx *ctx, int vcpu,
83 struct pci_vdev *pi, int offset,
84 int bytes, uint32_t *retval);
85
86 /* BAR read/write callbacks */
87 void (*vdev_barwrite)(struct vmctx *ctx, int vcpu,
88 struct pci_vdev *pi, int baridx,
89 uint64_t offset, int size, uint64_t value);
90 uint64_t (*vdev_barread)(struct vmctx *ctx, int vcpu,
91 struct pci_vdev *pi, int baridx,
92 uint64_t offset, int size);
93 };
94
95 /*
96 * Put all PCI instances' addresses into one section named pci_devemu_set
97 * so that DM could enumerate and initialize each of them.
98 */
99 #define DEFINE_PCI_DEVTYPE(x) DATA_SET(pci_vdev_ops_set, x)
100
101 enum pcibar_type {
102 PCIBAR_NONE,
103 PCIBAR_IO,
104 PCIBAR_MEM32,
105 PCIBAR_MEM64,
106 PCIBAR_MEMHI64,
107 /* the type for ROM bar. It will be allocated from PCI_EMUL_MEM32 region */
108 PCIBAR_ROM
109 };
110
111 struct pcibar {
112 enum pcibar_type type; /* io or memory */
113 uint64_t size;
114 uint64_t addr;
115 bool sizing;
116 };
117
118 #define PI_NAMESZ 40
119
120 struct msix_table_entry {
121 uint64_t addr;
122 uint32_t msg_data;
123 uint32_t vector_control;
124 } __attribute__((packed));
125
126 /*
127 * In case the structure is modified to hold extra information, use a define
128 * for the size that should be emulated.
129 */
130 #define MSIX_TABLE_ENTRY_SIZE 16
131 #define MAX_MSIX_TABLE_ENTRIES 2048
132 #define PBA_SIZE(msgnum) (roundup2((msgnum), 64) / 8)
133
134 enum lintr_stat {
135 IDLE,
136 ASSERTED,
137 PENDING
138 };
139
140 #define PCI_ROMBAR (PCIR_MAX_BAR_0 + 1) /* ROM BAR index in Type 0 Header */
141 struct pci_vdev {
142 struct pci_vdev_ops *dev_ops;
143 struct vmctx *vmctx;
144 uint8_t bus, slot, func;
145 char name[PI_NAMESZ];
146 int bar_getsize;
147 int prevcap;
148 int capend;
149
150 struct {
151 int8_t pin;
152 enum lintr_stat state;
153 int pirq_pin;
154 int ioapic_irq;
155 pthread_mutex_t lock;
156 } lintr;
157
158 struct {
159 int enabled;
160 uint64_t addr;
161 uint64_t msg_data;
162 int maxmsgnum;
163 } msi;
164
165 struct {
166 int enabled;
167 int table_bar;
168 int pba_bar;
169 uint32_t table_offset;
170 int table_count;
171 uint32_t pba_offset;
172 int pba_size;
173 int function_mask;
174 struct msix_table_entry *table; /* allocated at runtime */
175 void *pba_page;
176 int pba_page_offset;
177 } msix;
178
179 void *arg; /* devemu-private data */
180
181 uint8_t cfgdata[PCI_REGMAX + 1];
182 /* 0..5 is used for PCI MMIO/IO bar. 6 is used for PCI ROMbar */
183 struct pcibar bar[PCI_BARMAX + 2];
184 };
185
186 struct gsi_dev {
187 /*
188 * For PCI devices, use a string "b:d.f" to stand for the device's BDF,
189 * such as "00:00.0".
190 * For non-PCI devices, use the device's name to stand for the device,
191 * such as "timer".
192 */
193 char *dev_name;
194 uint8_t gsi;
195 };
196
197 extern struct gsi_dev gsi_dev_mapping_tables[];
198 extern int num_gsi_dev_mapping_tables;
199
200 struct msicap {
201 uint8_t capid;
202 uint8_t nextptr;
203 uint16_t msgctrl;
204 uint32_t addrlo;
205 uint32_t addrhi;
206 uint16_t msgdata;
207 uint16_t reserve;
208 uint32_t maskbit;
209 uint32_t pendbit;
210 } __attribute__((packed));
211 static_assert(sizeof(struct msicap) == 24, "compile-time assertion failed");
212
213 struct msixcap {
214 uint8_t capid;
215 uint8_t nextptr;
216 uint16_t msgctrl;
217 uint32_t table_info; /* bar index and offset within it */
218 uint32_t pba_info; /* bar index and offset within it */
219 } __attribute__((packed));
220 static_assert(sizeof(struct msixcap) == 12, "compile-time assertion failed");
221
222 struct pciecap {
223 uint8_t capid;
224 uint8_t nextptr;
225 uint16_t pcie_capabilities;
226
227 uint32_t dev_capabilities; /* all devices */
228 uint16_t dev_control;
229 uint16_t dev_status;
230
231 uint32_t link_capabilities; /* devices with links */
232 uint16_t link_control;
233 uint16_t link_status;
234
235 uint32_t slot_capabilities; /* ports with slots */
236 uint16_t slot_control;
237 uint16_t slot_status;
238
239 uint16_t root_control; /* root ports */
240 uint16_t root_capabilities;
241 uint32_t root_status;
242
243 uint32_t dev_capabilities2; /* all devices */
244 uint16_t dev_control2;
245 uint16_t dev_status2;
246
247 uint32_t link_capabilities2; /* devices with links */
248 uint16_t link_control2;
249 uint16_t link_status2;
250
251 uint32_t slot_capabilities2; /* ports with slots */
252 uint16_t slot_control2;
253 uint16_t slot_status2;
254 } __attribute__((packed));
255 static_assert(sizeof(struct pciecap) == 60, "compile-time assertion failed");
256
257 struct io_rsvd_rgn {
258 uint64_t start;
259 uint64_t end;
260 int idx;
261 int bar_type;
262 /* if vdev=NULL, it also indicates this io_rsvd_rgn is not used */
263 struct pci_vdev *vdev;
264 };
265
266 extern struct io_rsvd_rgn reserved_bar_regions[REGION_NUMS];
267 int reserve_io_rgn(uint64_t start,
268 uint64_t end, int idx, int bar_type, struct pci_vdev *vdev);
269 void destory_io_rsvd_rgns(struct pci_vdev *vdev);
270
271 /* Reserved region in e820 table for GVT
272 * for GVT-g use:
273 * [0xDF000000, 0xDF800000) 8M, GOP FB, used OvmfPkg/GvtGopDxe for 1080p@30
274 * [0xDFFFD000, 0xDFFFF000) 8K, OpRegion, used by GvtGopDxe and GVT-g
275 * [0xDFFFF000, 0XE0000000) 4K, Reserved, not used
276 * for TGL/EHL GVT-d use: identical mapping, same with host layout
277 * [gpu_opregion_hpa, gpu_opregion_hpa+size) 16K, OpRegion and Extended OpRegion
278 * [gpu_dsm_hpa, gpu_dsm_hpa+size] 64M, Date Stolen Memory
279 * for WHL/KBL GVT-d use:
280 * [0x7BFFC000, 0x7BFFE000) 8K, OpRegion, used by native GOP and gfx driver
281 * [0x7BFFE000, 0X7C000000] 8K, Extended OpRegion, store raw VBT
282 * [0x7C000000, 0x80000000] 64M, DSM, used by native GOP and gfx driver
283 * OpRegion: 8KB(0x2000)
284 * [ OpRegion Header ] Offset: 0x0
285 * [ Mailbox #1: ACPI ] Offset: 0x100
286 * [ Mailbox #2: SWSCI ] Offset: 0x200
287 * [ Mailbox #3: ASLE ] Offset: 0x300
288 * [ Mailbox #4: VBT ] Offset: 0x400
289 * [ Mailbox #5: ASLE EXT ] Offset: 0x1C00
290 * Extended OpRegion: 8KB(0x2000)
291 * [ Raw VBT ] Offset: 0x0
292 * If VBT <= 6KB, stores in Mailbox #4
293 * If VBT > 6KB, stores in Extended OpRegion
294 * ASLE.rvda stores the location of VBT.
295 * For OpRegion 2.1+: ASLE.rvda = offset to OpRegion base address
296 * For OpRegion 2.0: ASLE.rvda = physical address, not support currently
297 */
298 #define GPU_DSM_GPA 0x7C000000
299 #define GPU_OPREGION_SIZE 0x5000
300 /*
301 * TODO: Forced DSM/OPREGION size requires native BIOS configuration.
302 * This limitation need remove in future
303 */
304 uint32_t get_gpu_rsvmem_base_gpa(void);
305 uint32_t get_gpu_rsvmem_size(void);
306
307 typedef void (*pci_lintr_cb)(int b, int s, int pin, int pirq_pin,
308 int ioapic_irq, void *arg);
309
310 int init_pci(struct vmctx *ctx);
311 void deinit_pci(struct vmctx *ctx);
312 void msicap_cfgwrite(struct pci_vdev *pi, int capoff, int offset,
313 int bytes, uint32_t val);
314 void msixcap_cfgwrite(struct pci_vdev *pi, int capoff, int offset,
315 int bytes, uint32_t val);
316 void pci_callback(void);
317
318 /*
319 * @brief allocate bar region for virtual PCI device
320 *
321 * @param dev Pointer to struct pci_vdev representing virtual PCI device.
322 * @param idx the bar_idx for the request bar region
323 * @param type the region type for the request bar region
324 * @param size the region size for the request bar region
325 * It can support the allocation of bar_region for bar_idx 0..5 and
326 * the bar type can be PCIBAR_IO/PCIBAR_MEM32/PCIBAR_MEM64.
327 * It can support the allocation of ROM bar for PCI_ROMBAR and only allow
328 * that the bar type is PCIBAR_ROM.
329 *
330 * @Return 0 indicates that the allocation is successful.
331 * error indicates that it fails in the allocation of bar region.
332 */
333 int pci_emul_alloc_bar(struct pci_vdev *pdi, int idx,
334 enum pcibar_type type, uint64_t size);
335 int pci_emul_alloc_pbar(struct pci_vdev *pdi, int idx,
336 uint64_t hostbase, enum pcibar_type type,
337 uint64_t size);
338 void pci_emul_free_bar(struct pci_vdev *pdi, int idx);
339 void pci_emul_free_bars(struct pci_vdev *pdi);
340 int pci_emul_add_capability(struct pci_vdev *dev, u_char *capdata,
341 int caplen);
342 int pci_emul_find_capability(struct pci_vdev *dev, uint8_t capid,
343 int *p_capoff);
344 int pci_emul_add_msicap(struct pci_vdev *pi, int msgnum);
345 int pci_emul_add_pciecap(struct pci_vdev *pi, int pcie_device_type);
346
347 /**
348 * @brief Generate a MSI interrupt to guest
349 *
350 * @param dev Pointer to struct pci_vdev representing virtual PCI device.
351 * @param index Message data index.
352 */
353 void pci_generate_msi(struct pci_vdev *dev, int index);
354
355 /**
356 * @brief Generate a MSI-X interrupt to guest
357 *
358 * @param dev Pointer to struct pci_vdev representing virtual PCI device.
359 * @param index MSIs table entry index.
360 */
361 void pci_generate_msix(struct pci_vdev *dev, int index);
362
363 /**
364 * @brief Assert INTx pin of virtual PCI device
365 *
366 * @param dev Pointer to struct pci_vdev representing virtual PCI device.
367 */
368 void pci_lintr_assert(struct pci_vdev *dev);
369
370 /**
371 * @brief Deassert INTx pin of virtual PCI device
372 *
373 * @param dev Pointer to struct pci_vdev representing virtual PCI device.
374 */
375 void pci_lintr_deassert(struct pci_vdev *dev);
376
377 void pci_lintr_request(struct pci_vdev *pi);
378 void pci_lintr_release(struct pci_vdev *pi);
379 int pci_msi_enabled(struct pci_vdev *pi);
380 int pci_msix_enabled(struct pci_vdev *pi);
381 int pci_msix_table_bar(struct pci_vdev *pi);
382 int pci_msix_pba_bar(struct pci_vdev *pi);
383 int pci_msi_maxmsgnum(struct pci_vdev *pi);
384 int pci_parse_slot(char *opt);
385 int pci_populate_msicap(struct msicap *cap, int msgs, int nextptr);
386 int pci_emul_add_msixcap(struct pci_vdev *pi, int msgnum, int barnum);
387 int pci_emul_msix_twrite(struct pci_vdev *pi, uint64_t offset, int size,
388 uint64_t value);
389 uint64_t pci_emul_msix_tread(struct pci_vdev *pi, uint64_t offset, int size);
390 int pci_count_lintr(int bus);
391 void pci_walk_lintr(int bus, pci_lintr_cb cb, void *arg);
392 void pci_write_dsdt(void);
393 int pci_bus_configured(int bus);
394 int emulate_pci_cfgrw(struct vmctx *ctx, int vcpu, int in, int bus,
395 int slot, int func, int reg, int bytes, int *value);
396 int create_gsi_sharing_groups(void);
397 void update_pt_info(uint16_t phys_bdf);
398 int check_gsi_sharing_violation(void);
399 int pciaccess_init(void);
400 void pciaccess_cleanup(void);
401 int parse_bdf(char *s, int *bus, int *dev, int *func, int base);
402 struct pci_vdev *pci_get_vdev_info(int slot);
403
404
405 /**
406 * @brief Set virtual PCI device's configuration space in 1 byte width
407 *
408 * @param dev Pointer to struct pci_vdev representing virtual PCI device.
409 * @param offset Offset in configuration space.
410 * @param val Value in 1 byte.
411 */
412 static inline void
pci_set_cfgdata8(struct pci_vdev * dev,int offset,uint8_t val)413 pci_set_cfgdata8(struct pci_vdev *dev, int offset, uint8_t val)
414 {
415 if (offset > PCI_REGMAX) {
416 pr_err("%s: out of range of PCI config space!\n", __func__);
417 return;
418 }
419 *(uint8_t *)(dev->cfgdata + offset) = val;
420 }
421
422 /**
423 * @brief Set virtual PCI device's configuration space in 2 bytes width
424 *
425 * @param dev Pointer to struct pci_vdev representing virtual PCI device.
426 * @param offset Offset in configuration space.
427 * @param val Value in 2 bytes.
428 */
429 static inline void
pci_set_cfgdata16(struct pci_vdev * dev,int offset,uint16_t val)430 pci_set_cfgdata16(struct pci_vdev *dev, int offset, uint16_t val)
431 {
432 if ((offset > PCI_REGMAX - 1) || (offset & 1) != 0) {
433 pr_err("%s: out of range of PCI config space!\n", __func__);
434 return;
435 }
436 *(uint16_t *)(dev->cfgdata + offset) = val;
437 }
438
439 /**
440 * @brief Set virtual PCI device's configuration space in 4 bytes width
441 *
442 * @param dev Pointer to struct pci_vdev representing virtual PCI device.
443 * @param offset Offset in configuration space.
444 * @param val Value in 4 bytes.
445 */
446 static inline void
pci_set_cfgdata32(struct pci_vdev * dev,int offset,uint32_t val)447 pci_set_cfgdata32(struct pci_vdev *dev, int offset, uint32_t val)
448 {
449 if ((offset > PCI_REGMAX - 3) || (offset & 3) != 0) {
450 pr_err("%s: out of range of PCI config space!\n", __func__);
451 return;
452 }
453 *(uint32_t *)(dev->cfgdata + offset) = val;
454 }
455
456 /**
457 * @brief Get virtual PCI device's configuration space in 1 byte width
458 *
459 * @param dev Pointer to struct pci_vdev representing virtual PCI device.
460 * @param offset Offset in configuration space.
461 *
462 * @return The configuration value in 1 byte.
463 */
464 static inline uint8_t
pci_get_cfgdata8(struct pci_vdev * dev,int offset)465 pci_get_cfgdata8(struct pci_vdev *dev, int offset)
466 {
467 if (offset > PCI_REGMAX) {
468 pr_err("%s: out of range of PCI config space!\n", __func__);
469 return 0xff;
470 }
471 return (*(uint8_t *)(dev->cfgdata + offset));
472 }
473
474 /**
475 * @brief Get virtual PCI device's configuration space in 2 byte width
476 *
477 * @param dev Pointer to struct pci_vdev representing virtual PCI device.
478 * @param offset Offset in configuration space.
479 *
480 * @return The configuration value in 2 bytes.
481 */
482 static inline uint16_t
pci_get_cfgdata16(struct pci_vdev * dev,int offset)483 pci_get_cfgdata16(struct pci_vdev *dev, int offset)
484 {
485 if ((offset > PCI_REGMAX - 1) || (offset & 1) != 0) {
486 pr_err("%s: out of range of PCI config space!\n", __func__);
487 return 0xffff;
488 }
489 return (*(uint16_t *)(dev->cfgdata + offset));
490 }
491
492 /**
493 * @brief Get virtual PCI device's configuration space in 4 byte width
494 *
495 * @param dev Pointer to struct pci_vdev representing virtual PCI device.
496 * @param offset Offset in configuration space.
497 *
498 * @return The configuration value in 4 bytes.
499 */
500 static inline uint32_t
pci_get_cfgdata32(struct pci_vdev * dev,int offset)501 pci_get_cfgdata32(struct pci_vdev *dev, int offset)
502 {
503 if ((offset > PCI_REGMAX - 3) || (offset & 3) != 0) {
504 pr_err("%s: out of range of PCI config space!\n", __func__);
505 return 0xffffffff;
506 }
507 return (*(uint32_t *)(dev->cfgdata + offset));
508 }
509
510 #endif /* _PCI_CORE_H_ */
511