xref: /kvm-unit-tests/lib/pci.h (revision 80e8b3d82fc53befe77728786530d286a78d0d78)
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 #define ASSERT_BAR_NUM(bar_num)	\
22 	do { assert(bar_num >= 0 && bar_num < PCI_BAR_NUM); } while (0)
23 
24 #define PCI_BDF_GET_DEVFN(x)            ((x) & 0xff)
25 #define PCI_BDF_GET_BUS(x)              (((x) >> 8) & 0xff)
26 
27 struct pci_dev {
28 	uint16_t bdf;
29 	uint16_t msi_offset;
30 	phys_addr_t resource[PCI_BAR_NUM];
31 };
32 
33 extern void pci_dev_init(struct pci_dev *dev, pcidevaddr_t bdf);
34 extern void pci_cmd_set_clr(struct pci_dev *dev, uint16_t set, uint16_t clr);
35 typedef void (*pci_cap_handler_t)(struct pci_dev *dev, int cap_offset, int cap_id);
36 extern void pci_cap_walk(struct pci_dev *dev, pci_cap_handler_t handler);
37 extern void pci_enable_defaults(struct pci_dev *dev);
38 extern bool pci_setup_msi(struct pci_dev *dev, uint64_t msi_addr,
39 			  uint32_t msi_data);
40 
41 typedef phys_addr_t iova_t;
42 
43 extern bool pci_probe(void);
44 extern void pci_print(void);
45 extern bool pci_dev_exists(pcidevaddr_t dev);
46 extern pcidevaddr_t pci_find_dev(uint16_t vendor_id, uint16_t device_id);
47 
48 /*
49  * @bar_num in all BAR access functions below is the index of the 32-bit
50  * register starting from the PCI_BASE_ADDRESS_0 offset.
51  *
52  * In cases where the BAR size is 64-bit, a caller should still provide
53  * @bar_num in terms of 32-bit words. For example, if a device has a 64-bit
54  * BAR#0 and a 32-bit BAR#1, then caller should provide 2 to address BAR#1,
55  * not 1.
56  *
57  * It is expected the caller is aware of the device BAR layout and never
58  * tries to address the middle of a 64-bit register.
59  */
60 extern phys_addr_t pci_bar_get_addr(struct pci_dev *dev, int bar_num);
61 extern void pci_bar_set_addr(struct pci_dev *dev, int bar_num, phys_addr_t addr);
62 extern phys_addr_t pci_bar_size(struct pci_dev *dev, int bar_num);
63 extern uint32_t pci_bar_get(struct pci_dev *dev, int bar_num);
64 extern uint32_t pci_bar_mask(uint32_t bar);
65 extern bool pci_bar_is64(struct pci_dev *dev, int bar_num);
66 extern bool pci_bar_is_memory(struct pci_dev *dev, int bar_num);
67 extern bool pci_bar_is_valid(struct pci_dev *dev, int bar_num);
68 extern void pci_bar_print(struct pci_dev *dev, int bar_num);
69 extern void pci_dev_print_id(struct pci_dev *dev);
70 extern void pci_dev_print(struct pci_dev *dev);
71 extern uint8_t pci_intx_line(struct pci_dev *dev);
72 void pci_msi_set_enable(struct pci_dev *dev, bool enabled);
73 
74 extern int pci_testdev(void);
75 
76 /*
77  * pci-testdev is a driver for the pci-testdev qemu pci device. The
78  * device enables testing mmio and portio exits, and measuring their
79  * speed.
80  */
81 #define PCI_VENDOR_ID_REDHAT		0x1b36
82 #define PCI_DEVICE_ID_REDHAT_TEST	0x0005
83 
84 /*
85  * pci-testdev supports at least three types of tests (via mmio and
86  * portio BARs): no-eventfd, wildcard-eventfd and datamatch-eventfd
87  */
88 #define PCI_TESTDEV_BAR_MEM		0
89 #define PCI_TESTDEV_BAR_IO		1
90 #define PCI_TESTDEV_NUM_BARS		2
91 #define PCI_TESTDEV_NUM_TESTS		3
92 
93 struct pci_test_dev_hdr {
94 	uint8_t  test;
95 	uint8_t  width;
96 	uint8_t  pad0[2];
97 	uint32_t offset;
98 	uint32_t data;
99 	uint32_t count;
100 	uint8_t  name[];
101 };
102 
103 #define  PCI_HEADER_TYPE_MASK		0x7f
104 
105 #endif /* _PCI_H_ */
106