xref: /kvm-unit-tests/lib/pci.h (revision e954ce23cd9f942b3ddf16f4932087b3ee789259)
1 #ifndef PCI_H
2 #define PCI_H
3 /*
4  * API for scanning a PCI bus for a given device, as well to access
5  * BAR registers.
6  *
7  * Copyright (C) 2013, Red Hat Inc, Michael S. Tsirkin <mst@redhat.com>
8  *
9  * This work is licensed under the terms of the GNU LGPL, version 2.
10  */
11 #include "libcflat.h"
12 
13 typedef uint16_t pcidevaddr_t;
14 enum {
15 	PCIDEVADDR_INVALID = 0xffff,
16 };
17 
18 #define PCI_BAR_NUM                     6
19 #define PCI_DEVFN_MAX                   256
20 
21 struct pci_dev {
22 	uint16_t bdf;
23 	phys_addr_t resource[PCI_BAR_NUM];
24 };
25 
26 extern void pci_dev_init(struct pci_dev *dev, pcidevaddr_t bdf);
27 extern void pci_scan_bars(struct pci_dev *dev);
28 
29 extern bool pci_probe(void);
30 extern void pci_print(void);
31 extern bool pci_dev_exists(pcidevaddr_t dev);
32 extern pcidevaddr_t pci_find_dev(uint16_t vendor_id, uint16_t device_id);
33 
34 /*
35  * @bar_num in all BAR access functions below is the index of the 32-bit
36  * register starting from the PCI_BASE_ADDRESS_0 offset.
37  *
38  * In cases where the BAR size is 64-bit, a caller should still provide
39  * @bar_num in terms of 32-bit words. For example, if a device has a 64-bit
40  * BAR#0 and a 32-bit BAR#1, then caller should provide 2 to address BAR#1,
41  * not 1.
42  *
43  * It is expected the caller is aware of the device BAR layout and never
44  * tries to address the middle of a 64-bit register.
45  */
46 extern phys_addr_t pci_bar_get_addr(struct pci_dev *dev, int bar_num);
47 extern void pci_bar_set_addr(struct pci_dev *dev, int bar_num, phys_addr_t addr);
48 extern phys_addr_t pci_bar_size(struct pci_dev *dev, int bar_num);
49 extern uint32_t pci_bar_get(struct pci_dev *dev, int bar_num);
50 extern uint32_t pci_bar_mask(uint32_t bar);
51 extern bool pci_bar_is64(struct pci_dev *dev, int bar_num);
52 extern bool pci_bar_is_memory(struct pci_dev *dev, int bar_num);
53 extern bool pci_bar_is_valid(struct pci_dev *dev, int bar_num);
54 extern void pci_bar_print(struct pci_dev *dev, int bar_num);
55 extern void pci_dev_print_id(pcidevaddr_t dev);
56 
57 extern int pci_testdev(void);
58 
59 /*
60  * pci-testdev is a driver for the pci-testdev qemu pci device. The
61  * device enables testing mmio and portio exits, and measuring their
62  * speed.
63  */
64 #define PCI_VENDOR_ID_REDHAT		0x1b36
65 #define PCI_DEVICE_ID_REDHAT_TEST	0x0005
66 
67 /*
68  * pci-testdev supports at least three types of tests (via mmio and
69  * portio BARs): no-eventfd, wildcard-eventfd and datamatch-eventfd
70  */
71 #define PCI_TESTDEV_BAR_MEM		0
72 #define PCI_TESTDEV_BAR_IO		1
73 #define PCI_TESTDEV_NUM_BARS		2
74 #define PCI_TESTDEV_NUM_TESTS		3
75 
76 struct pci_test_dev_hdr {
77 	uint8_t  test;
78 	uint8_t  width;
79 	uint8_t  pad0[2];
80 	uint32_t offset;
81 	uint32_t data;
82 	uint32_t count;
83 	uint8_t  name[];
84 };
85 
86 #define  PCI_HEADER_TYPE_MASK		0x7f
87 
88 #endif /* PCI_H */
89