blob: e201711dfe183945f17e690ff99d700f28bdea03 [file] [log] [blame]
Cornelia Huck80e8b3d2021-06-10 15:59:36 +02001#ifndef _PCI_H_
2#define _PCI_H_
Andrew Jones456c55b2016-01-18 19:01:02 +01003/*
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 */
Michael S. Tsirkin4932b582013-04-03 11:52:33 +030011#include "libcflat.h"
12
13typedef uint16_t pcidevaddr_t;
14enum {
Alexander Gordeevebb58e72016-11-07 11:14:33 +010015 PCIDEVADDR_INVALID = 0xffff,
Michael S. Tsirkin4932b582013-04-03 11:52:33 +030016};
Alexander Gordeevebb58e72016-11-07 11:14:33 +010017
Peter Xue954ce22016-12-12 11:08:15 +080018#define PCI_BAR_NUM 6
Peter Xu4d6cefa2016-12-12 11:08:14 +080019#define PCI_DEVFN_MAX 256
20
Alexander Gordeev68cf12d2017-03-27 16:32:14 +020021#define ASSERT_BAR_NUM(bar_num) \
22 do { assert(bar_num >= 0 && bar_num < PCI_BAR_NUM); } while (0)
23
Peter Xu92d2c192016-12-12 11:08:18 +080024#define PCI_BDF_GET_DEVFN(x) ((x) & 0xff)
25#define PCI_BDF_GET_BUS(x) (((x) >> 8) & 0xff)
26
Peter Xu4d6cefa2016-12-12 11:08:14 +080027struct pci_dev {
28 uint16_t bdf;
Peter Xu903b0512016-12-12 11:08:19 +080029 uint16_t msi_offset;
Peter Xue954ce22016-12-12 11:08:15 +080030 phys_addr_t resource[PCI_BAR_NUM];
Peter Xu4d6cefa2016-12-12 11:08:14 +080031};
32
33extern void pci_dev_init(struct pci_dev *dev, pcidevaddr_t bdf);
Peter Xu66082ed2016-12-12 11:08:16 +080034extern void pci_cmd_set_clr(struct pci_dev *dev, uint16_t set, uint16_t clr);
Andrew Jonescdccea72017-01-16 16:32:13 +010035typedef void (*pci_cap_handler_t)(struct pci_dev *dev, int cap_offset, int cap_id);
36extern void pci_cap_walk(struct pci_dev *dev, pci_cap_handler_t handler);
Peter Xu66082ed2016-12-12 11:08:16 +080037extern void pci_enable_defaults(struct pci_dev *dev);
Peter Xu903b0512016-12-12 11:08:19 +080038extern bool pci_setup_msi(struct pci_dev *dev, uint64_t msi_addr,
39 uint32_t msi_data);
Peter Xu4d6cefa2016-12-12 11:08:14 +080040
Peter Xu92d2c192016-12-12 11:08:18 +080041typedef phys_addr_t iova_t;
42
Alexander Gordeev33d78b02016-11-07 11:14:42 +010043extern bool pci_probe(void);
Alexander Gordeeve4611522016-11-07 11:14:41 +010044extern void pci_print(void);
Alexander Gordeeve1cad5c2016-11-07 11:14:40 +010045extern bool pci_dev_exists(pcidevaddr_t dev);
Alexander Gordeevfa80a742016-11-07 11:14:35 +010046extern pcidevaddr_t pci_find_dev(uint16_t vendor_id, uint16_t device_id);
Alexander Gordeev2455ef22016-11-07 11:14:38 +010047
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 */
Peter Xu4d6cefa2016-12-12 11:08:14 +080060extern phys_addr_t pci_bar_get_addr(struct pci_dev *dev, int bar_num);
61extern void pci_bar_set_addr(struct pci_dev *dev, int bar_num, phys_addr_t addr);
62extern phys_addr_t pci_bar_size(struct pci_dev *dev, int bar_num);
63extern uint32_t pci_bar_get(struct pci_dev *dev, int bar_num);
Alexander Gordeev33d78b02016-11-07 11:14:42 +010064extern uint32_t pci_bar_mask(uint32_t bar);
Peter Xu4d6cefa2016-12-12 11:08:14 +080065extern bool pci_bar_is64(struct pci_dev *dev, int bar_num);
66extern bool pci_bar_is_memory(struct pci_dev *dev, int bar_num);
67extern bool pci_bar_is_valid(struct pci_dev *dev, int bar_num);
68extern void pci_bar_print(struct pci_dev *dev, int bar_num);
Alexander Gordeevcb026022017-02-28 19:08:30 +010069extern void pci_dev_print_id(struct pci_dev *dev);
70extern void pci_dev_print(struct pci_dev *dev);
Peter Xu352096c2016-12-30 16:55:53 +080071extern uint8_t pci_intx_line(struct pci_dev *dev);
Peter Xu19daf1c2016-12-30 16:55:54 +080072void pci_msi_set_enable(struct pci_dev *dev, bool enabled);
Michael S. Tsirkin4932b582013-04-03 11:52:33 +030073
Peter Xu7d4c5322016-12-12 11:08:07 +080074extern int pci_testdev(void);
Alexander Gordeeve4125c02016-11-07 11:14:43 +010075
Andrew Jones289ebf82016-01-18 19:01:03 +010076/*
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
Alexander Gordeeve4125c02016-11-07 11:14:43 +010084/*
85 * pci-testdev supports at least three types of tests (via mmio and
86 * portio BARs): no-eventfd, wildcard-eventfd and datamatch-eventfd
87 */
Peter Xue954ce22016-12-12 11:08:15 +080088#define PCI_TESTDEV_BAR_MEM 0
89#define PCI_TESTDEV_BAR_IO 1
Andrew Jones289ebf82016-01-18 19:01:03 +010090#define PCI_TESTDEV_NUM_BARS 2
Alexander Gordeeve4125c02016-11-07 11:14:43 +010091#define PCI_TESTDEV_NUM_TESTS 3
Andrew Jones289ebf82016-01-18 19:01:03 +010092
93struct 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
Alexander Gordeeve4611522016-11-07 11:14:41 +0100103#define PCI_HEADER_TYPE_MASK 0x7f
104
Cornelia Huck80e8b3d2021-06-10 15:59:36 +0200105#endif /* _PCI_H_ */