xref: /kvmtool/include/kvm/pci.h (revision b0d56e3c994a0feb3ffb519cecda5c1f6da8b1ab)
160742802SPekka Enberg #ifndef KVM__PCI_H
260742802SPekka Enberg #define KVM__PCI_H
360742802SPekka Enberg 
43fdf659dSSasha Levin #include <linux/types.h>
51de74957SSasha Levin #include <linux/kvm.h>
620c64ecaSPekka Enberg #include <linux/pci_regs.h>
7*b0d56e3cSJean-Philippe Brucker #include <linux/virtio_pci.h>
8aa73be70SMatt Evans #include <endian.h>
92f6384f9SAlexandru Elisei #include <stdbool.h>
1076f9c841SCyrill Gorcunov 
11b5981636SWill Deacon #include "kvm/devices.h"
12f7c17d7cSPekka Enberg #include "kvm/msi.h"
13ff01b5dbSJean-Philippe Brucker #include "kvm/fdt.h"
14e69b7663SAlexandru Elisei #include "kvm/kvm-arch.h"
15d0297a59SMatt Evans 
16465edc9dSAlexandru Elisei #define pci_dev_err(pci_hdr, fmt, ...) \
1734bfe5f6SAlexandru Elisei 	pr_err("[%04x:%04x] " fmt, (pci_hdr)->vendor_id, (pci_hdr)->device_id, ##__VA_ARGS__)
18465edc9dSAlexandru Elisei #define pci_dev_warn(pci_hdr, fmt, ...) \
1934bfe5f6SAlexandru Elisei 	pr_warning("[%04x:%04x] " fmt, (pci_hdr)->vendor_id, (pci_hdr)->device_id, ##__VA_ARGS__)
20465edc9dSAlexandru Elisei #define pci_dev_info(pci_hdr, fmt, ...) \
2134bfe5f6SAlexandru Elisei 	pr_info("[%04x:%04x] " fmt, (pci_hdr)->vendor_id, (pci_hdr)->device_id, ##__VA_ARGS__)
22465edc9dSAlexandru Elisei #define pci_dev_dbg(pci_hdr, fmt, ...) \
2334bfe5f6SAlexandru Elisei 	pr_debug("[%04x:%04x] " fmt, (pci_hdr)->vendor_id, (pci_hdr)->device_id, ##__VA_ARGS__)
24465edc9dSAlexandru Elisei #define pci_dev_die(pci_hdr, fmt, ...) \
2534bfe5f6SAlexandru Elisei 	die("[%04x:%04x] " fmt, (pci_hdr)->vendor_id, (pci_hdr)->device_id, ##__VA_ARGS__)
26465edc9dSAlexandru Elisei 
274402a581SPekka Enberg /*
284402a581SPekka Enberg  * PCI Configuration Mechanism #1 I/O ports. See Section 3.7.4.1.
294402a581SPekka Enberg  * ("Configuration Mechanism #1") of the PCI Local Bus Specification 2.1 for
304402a581SPekka Enberg  * details.
314402a581SPekka Enberg  */
32305b72ceSCyrill Gorcunov #define PCI_CONFIG_ADDRESS	0xcf8
33305b72ceSCyrill Gorcunov #define PCI_CONFIG_DATA		0xcfc
342b9e4709SCyrill Gorcunov #define PCI_CONFIG_BUS_FORWARD	0xcfa
3595d13a52SSasha Levin #define PCI_IO_SIZE		0x100
36854aa2efSJulien Thierry #define PCI_IOPORT_START	0x6200
37305b72ceSCyrill Gorcunov 
386078a454SJean-Philippe Brucker struct kvm;
396078a454SJean-Philippe Brucker 
40e69b7663SAlexandru Elisei /*
41e69b7663SAlexandru Elisei  * On some distributions, pci_regs.h doesn't define PCI_CFG_SPACE_SIZE and
42e69b7663SAlexandru Elisei  * PCI_CFG_SPACE_EXP_SIZE, so we define our own.
43e69b7663SAlexandru Elisei  */
44e69b7663SAlexandru Elisei #define PCI_CFG_SIZE_LEGACY		(1ULL << 24)
45e69b7663SAlexandru Elisei #define PCI_DEV_CFG_SIZE_LEGACY		256
46e69b7663SAlexandru Elisei #define PCI_CFG_SIZE_EXTENDED		(1ULL << 28)
47e69b7663SAlexandru Elisei #define PCI_DEV_CFG_SIZE_EXTENDED 	4096
48e69b7663SAlexandru Elisei 
49e69b7663SAlexandru Elisei #ifdef ARCH_HAS_PCI_EXP
5025c1dc6cSAlexandru Elisei #define arch_has_pci_exp()	(true)
5125c1dc6cSAlexandru Elisei 
52e69b7663SAlexandru Elisei #define PCI_CFG_SIZE		PCI_CFG_SIZE_EXTENDED
53e69b7663SAlexandru Elisei #define PCI_DEV_CFG_SIZE	PCI_DEV_CFG_SIZE_EXTENDED
54e69b7663SAlexandru Elisei 
55e69b7663SAlexandru Elisei union pci_config_address {
56e69b7663SAlexandru Elisei 	struct {
57e69b7663SAlexandru Elisei #if __BYTE_ORDER == __LITTLE_ENDIAN
58e69b7663SAlexandru Elisei 		unsigned	reg_offset	: 2;		/* 1  .. 0  */
59e69b7663SAlexandru Elisei 		unsigned	register_number	: 10;		/* 11 .. 2  */
60e69b7663SAlexandru Elisei 		unsigned	function_number	: 3;		/* 14 .. 12 */
61e69b7663SAlexandru Elisei 		unsigned	device_number	: 5;		/* 19 .. 15 */
62e69b7663SAlexandru Elisei 		unsigned	bus_number	: 8;		/* 27 .. 20 */
63e69b7663SAlexandru Elisei 		unsigned	reserved	: 3;		/* 30 .. 28 */
64e69b7663SAlexandru Elisei 		unsigned	enable_bit	: 1;		/* 31       */
65e69b7663SAlexandru Elisei #else
66e69b7663SAlexandru Elisei 		unsigned	enable_bit	: 1;		/* 31       */
67e69b7663SAlexandru Elisei 		unsigned	reserved	: 3;		/* 30 .. 28 */
68e69b7663SAlexandru Elisei 		unsigned	bus_number	: 8;		/* 27 .. 20 */
69e69b7663SAlexandru Elisei 		unsigned	device_number	: 5;		/* 19 .. 15 */
70e69b7663SAlexandru Elisei 		unsigned	function_number	: 3;		/* 14 .. 12 */
71e69b7663SAlexandru Elisei 		unsigned	register_number	: 10;		/* 11 .. 2  */
72e69b7663SAlexandru Elisei 		unsigned	reg_offset	: 2;		/* 1  .. 0  */
73e69b7663SAlexandru Elisei #endif
74e69b7663SAlexandru Elisei 	};
75e69b7663SAlexandru Elisei 	u32 w;
76e69b7663SAlexandru Elisei };
77e69b7663SAlexandru Elisei 
78e69b7663SAlexandru Elisei #else
7925c1dc6cSAlexandru Elisei #define arch_has_pci_exp()	(false)
8025c1dc6cSAlexandru Elisei 
81e69b7663SAlexandru Elisei #define PCI_CFG_SIZE		PCI_CFG_SIZE_LEGACY
82e69b7663SAlexandru Elisei #define PCI_DEV_CFG_SIZE	PCI_DEV_CFG_SIZE_LEGACY
83e69b7663SAlexandru Elisei 
84aa73be70SMatt Evans union pci_config_address {
85aa73be70SMatt Evans 	struct {
86aa73be70SMatt Evans #if __BYTE_ORDER == __LITTLE_ENDIAN
87d0297a59SMatt Evans 		unsigned	reg_offset	: 2;		/* 1  .. 0  */
884402a581SPekka Enberg 		unsigned	register_number	: 6;		/* 7  .. 2  */
894402a581SPekka Enberg 		unsigned	function_number	: 3;		/* 10 .. 8  */
904402a581SPekka Enberg 		unsigned	device_number	: 5;		/* 15 .. 11 */
914402a581SPekka Enberg 		unsigned	bus_number	: 8;		/* 23 .. 16 */
924402a581SPekka Enberg 		unsigned	reserved	: 7;		/* 30 .. 24 */
934402a581SPekka Enberg 		unsigned	enable_bit	: 1;		/* 31       */
94aa73be70SMatt Evans #else
95aa73be70SMatt Evans 		unsigned	enable_bit	: 1;		/* 31       */
96aa73be70SMatt Evans 		unsigned	reserved	: 7;		/* 30 .. 24 */
97aa73be70SMatt Evans 		unsigned	bus_number	: 8;		/* 23 .. 16 */
98aa73be70SMatt Evans 		unsigned	device_number	: 5;		/* 15 .. 11 */
99aa73be70SMatt Evans 		unsigned	function_number	: 3;		/* 10 .. 8  */
100aa73be70SMatt Evans 		unsigned	register_number	: 6;		/* 7  .. 2  */
101d0297a59SMatt Evans 		unsigned	reg_offset	: 2;		/* 1  .. 0  */
102aa73be70SMatt Evans #endif
103aa73be70SMatt Evans 	};
104aa73be70SMatt Evans 	u32 w;
1054402a581SPekka Enberg };
106e69b7663SAlexandru Elisei #endif /* ARCH_HAS_PCI_EXP */
107e69b7663SAlexandru Elisei 
108e69b7663SAlexandru Elisei #define PCI_DEV_CFG_MASK	(PCI_DEV_CFG_SIZE - 1)
1094402a581SPekka Enberg 
110bc485053SSasha Levin struct msix_table {
1111de74957SSasha Levin 	struct msi_msg msg;
112bc485053SSasha Levin 	u32 ctrl;
113bc485053SSasha Levin };
114bc485053SSasha Levin 
115bc485053SSasha Levin struct msix_cap {
116bc485053SSasha Levin 	u8 cap;
117bc485053SSasha Levin 	u8 next;
11806f48103SSasha Levin 	u16 ctrl;
119bc485053SSasha Levin 	u32 table_offset;
12006f48103SSasha Levin 	u32 pba_offset;
121bc485053SSasha Levin };
122bc485053SSasha Levin 
1238dd28afeSJean-Philippe Brucker struct msi_cap_64 {
1248dd28afeSJean-Philippe Brucker 	u8 cap;
1258dd28afeSJean-Philippe Brucker 	u8 next;
1268dd28afeSJean-Philippe Brucker 	u16 ctrl;
1278dd28afeSJean-Philippe Brucker 	u32 address_lo;
1288dd28afeSJean-Philippe Brucker 	u32 address_hi;
1298dd28afeSJean-Philippe Brucker 	u16 data;
1308dd28afeSJean-Philippe Brucker 	u16 _align;
1318dd28afeSJean-Philippe Brucker 	u32 mask_bits;
1328dd28afeSJean-Philippe Brucker 	u32 pend_bits;
1338dd28afeSJean-Philippe Brucker };
1348dd28afeSJean-Philippe Brucker 
1358dd28afeSJean-Philippe Brucker struct msi_cap_32 {
1368dd28afeSJean-Philippe Brucker 	u8 cap;
1378dd28afeSJean-Philippe Brucker 	u8 next;
1388dd28afeSJean-Philippe Brucker 	u16 ctrl;
1398dd28afeSJean-Philippe Brucker 	u32 address_lo;
1408dd28afeSJean-Philippe Brucker 	u16 data;
1418dd28afeSJean-Philippe Brucker 	u16 _align;
1428dd28afeSJean-Philippe Brucker 	u32 mask_bits;
1438dd28afeSJean-Philippe Brucker 	u32 pend_bits;
1448dd28afeSJean-Philippe Brucker };
1458dd28afeSJean-Philippe Brucker 
146*b0d56e3cSJean-Philippe Brucker struct virtio_caps {
147*b0d56e3cSJean-Philippe Brucker 	struct virtio_pci_cap		common;
148*b0d56e3cSJean-Philippe Brucker 	struct virtio_pci_notify_cap	notify;
149*b0d56e3cSJean-Philippe Brucker 	struct virtio_pci_cap		isr;
150*b0d56e3cSJean-Philippe Brucker 	struct virtio_pci_cap		device;
151*b0d56e3cSJean-Philippe Brucker 	struct virtio_pci_cfg_cap	pci;
152*b0d56e3cSJean-Philippe Brucker };
153*b0d56e3cSJean-Philippe Brucker 
1541a51c93dSJean-Philippe Brucker struct pci_cap_hdr {
1551a51c93dSJean-Philippe Brucker 	u8	type;
1561a51c93dSJean-Philippe Brucker 	u8	next;
1571a51c93dSJean-Philippe Brucker };
1581a51c93dSJean-Philippe Brucker 
15925c1dc6cSAlexandru Elisei struct pci_exp_cap {
16025c1dc6cSAlexandru Elisei 	u8 cap;
16125c1dc6cSAlexandru Elisei 	u8 next;
16225c1dc6cSAlexandru Elisei 	u16 cap_reg;
16325c1dc6cSAlexandru Elisei 	u32 dev_cap;
16425c1dc6cSAlexandru Elisei 	u16 dev_ctrl;
16525c1dc6cSAlexandru Elisei 	u16 dev_status;
16625c1dc6cSAlexandru Elisei 	u32 link_cap;
16725c1dc6cSAlexandru Elisei 	u16 link_ctrl;
16825c1dc6cSAlexandru Elisei 	u16 link_status;
16925c1dc6cSAlexandru Elisei 	u32 slot_cap;
17025c1dc6cSAlexandru Elisei 	u16 slot_ctrl;
17125c1dc6cSAlexandru Elisei 	u16 slot_status;
17225c1dc6cSAlexandru Elisei 	u16 root_ctrl;
17325c1dc6cSAlexandru Elisei 	u16 root_cap;
17425c1dc6cSAlexandru Elisei 	u32 root_status;
17525c1dc6cSAlexandru Elisei };
17625c1dc6cSAlexandru Elisei 
1775a8e4f25SAlexandru Elisei struct pci_device_header;
1785a8e4f25SAlexandru Elisei 
1795a8e4f25SAlexandru Elisei typedef int (*bar_activate_fn_t)(struct kvm *kvm,
1805a8e4f25SAlexandru Elisei 				 struct pci_device_header *pci_hdr,
1815a8e4f25SAlexandru Elisei 				 int bar_num, void *data);
1825a8e4f25SAlexandru Elisei typedef int (*bar_deactivate_fn_t)(struct kvm *kvm,
1835a8e4f25SAlexandru Elisei 				   struct pci_device_header *pci_hdr,
1845a8e4f25SAlexandru Elisei 				   int bar_num, void *data);
1855a8e4f25SAlexandru Elisei 
186023fdaaeSJean-Philippe Brucker #define PCI_BAR_OFFSET(b)	(offsetof(struct pci_device_header, bar[b]))
187023fdaaeSJean-Philippe Brucker 
188023fdaaeSJean-Philippe Brucker struct pci_config_operations {
189023fdaaeSJean-Philippe Brucker 	void (*write)(struct kvm *kvm, struct pci_device_header *pci_hdr,
190e69b7663SAlexandru Elisei 		      u16 offset, void *data, int sz);
191023fdaaeSJean-Philippe Brucker 	void (*read)(struct kvm *kvm, struct pci_device_header *pci_hdr,
192e69b7663SAlexandru Elisei 		     u16 offset, void *data, int sz);
193023fdaaeSJean-Philippe Brucker };
194023fdaaeSJean-Philippe Brucker 
19576f9c841SCyrill Gorcunov struct pci_device_header {
196023fdaaeSJean-Philippe Brucker 	/* Configuration space, as seen by the guest */
197023fdaaeSJean-Philippe Brucker 	union {
198023fdaaeSJean-Philippe Brucker 		struct {
1993fdf659dSSasha Levin 			u16		vendor_id;
2003fdf659dSSasha Levin 			u16		device_id;
2013fdf659dSSasha Levin 			u16		command;
2023fdf659dSSasha Levin 			u16		status;
203aa73be70SMatt Evans 			u8		revision_id;
204aa73be70SMatt Evans 			u8		class[3];
2053fdf659dSSasha Levin 			u8		cacheline_size;
2063fdf659dSSasha Levin 			u8		latency_timer;
2073fdf659dSSasha Levin 			u8		header_type;
2083fdf659dSSasha Levin 			u8		bist;
2093fdf659dSSasha Levin 			u32		bar[6];
2103fdf659dSSasha Levin 			u32		card_bus;
2113fdf659dSSasha Levin 			u16		subsys_vendor_id;
2123fdf659dSSasha Levin 			u16		subsys_id;
2133fdf659dSSasha Levin 			u32		exp_rom_bar;
214aa73be70SMatt Evans 			u8		capabilities;
215aa73be70SMatt Evans 			u8		reserved1[3];
2163fdf659dSSasha Levin 			u32		reserved2;
2173fdf659dSSasha Levin 			u8		irq_line;
2183fdf659dSSasha Levin 			u8		irq_pin;
2193fdf659dSSasha Levin 			u8		min_gnt;
2203fdf659dSSasha Levin 			u8		max_lat;
221bc485053SSasha Levin 			struct msix_cap msix;
22225c1dc6cSAlexandru Elisei 			/* Used only by architectures which support PCIE */
22325c1dc6cSAlexandru Elisei 			struct pci_exp_cap pci_exp;
224*b0d56e3cSJean-Philippe Brucker 			struct virtio_caps virtio;
225aa73be70SMatt Evans 		} __attribute__((packed));
226023fdaaeSJean-Philippe Brucker 		/* Pad to PCI config space size */
227023fdaaeSJean-Philippe Brucker 		u8	__pad[PCI_DEV_CFG_SIZE];
228023fdaaeSJean-Philippe Brucker 	};
229023fdaaeSJean-Philippe Brucker 
230023fdaaeSJean-Philippe Brucker 	/* Private to lkvm */
231023fdaaeSJean-Philippe Brucker 	u32			bar_size[6];
232465edc9dSAlexandru Elisei 	bool			bar_active[6];
2335a8e4f25SAlexandru Elisei 	bar_activate_fn_t	bar_activate_fn;
2345a8e4f25SAlexandru Elisei 	bar_deactivate_fn_t	bar_deactivate_fn;
2355a8e4f25SAlexandru Elisei 	void *data;
236023fdaaeSJean-Philippe Brucker 	struct pci_config_operations	cfg_ops;
237ff01b5dbSJean-Philippe Brucker 	/*
238ff01b5dbSJean-Philippe Brucker 	 * PCI INTx# are level-triggered, but virtual device often feature
239ff01b5dbSJean-Philippe Brucker 	 * edge-triggered INTx# for convenience.
240ff01b5dbSJean-Philippe Brucker 	 */
241ff01b5dbSJean-Philippe Brucker 	enum irq_type	irq_type;
242023fdaaeSJean-Philippe Brucker };
24376f9c841SCyrill Gorcunov 
2441a51c93dSJean-Philippe Brucker #define PCI_CAP(pci_hdr, pos) ((void *)(pci_hdr) + (pos))
245*b0d56e3cSJean-Philippe Brucker #define PCI_CAP_OFF(pci_hdr, cap) ((void *)&(pci_hdr)->cap - (void *)(pci_hdr))
2461a51c93dSJean-Philippe Brucker 
2471a51c93dSJean-Philippe Brucker #define pci_for_each_cap(pos, cap, hdr)				\
2481a51c93dSJean-Philippe Brucker 	for ((pos) = (hdr)->capabilities & ~3;			\
2491a51c93dSJean-Philippe Brucker 	     (cap) = PCI_CAP(hdr, pos), (pos) != 0;		\
2501a51c93dSJean-Philippe Brucker 	     (pos) = ((struct pci_cap_hdr *)(cap))->next & ~3)
2511a51c93dSJean-Philippe Brucker 
2526d987703SSasha Levin int pci__init(struct kvm *kvm);
2536d987703SSasha Levin int pci__exit(struct kvm *kvm);
254d0297a59SMatt Evans struct pci_device_header *pci__find_dev(u8 dev_num);
255854aa2efSJulien Thierry u32 pci_get_mmio_block(u32 size);
256854aa2efSJulien Thierry u16 pci_get_io_port_block(u32 size);
257c0c45eedSAndre Przywara int pci__assign_irq(struct pci_device_header *pci_hdr);
258d0297a59SMatt Evans void pci__config_wr(struct kvm *kvm, union pci_config_address addr, void *data, int size);
259d0297a59SMatt Evans void pci__config_rd(struct kvm *kvm, union pci_config_address addr, void *data, int size);
26060742802SPekka Enberg 
2611a51c93dSJean-Philippe Brucker void *pci_find_cap(struct pci_device_header *hdr, u8 cap_type);
2621a51c93dSJean-Philippe Brucker 
2635a8e4f25SAlexandru Elisei int pci__register_bar_regions(struct kvm *kvm, struct pci_device_header *pci_hdr,
2645a8e4f25SAlexandru Elisei 			      bar_activate_fn_t bar_activate_fn,
2655a8e4f25SAlexandru Elisei 			      bar_deactivate_fn_t bar_deactivate_fn, void *data);
2665a8e4f25SAlexandru Elisei 
__pci__memory_space_enabled(u16 command)2672f6384f9SAlexandru Elisei static inline bool __pci__memory_space_enabled(u16 command)
2682f6384f9SAlexandru Elisei {
2692f6384f9SAlexandru Elisei 	return command & PCI_COMMAND_MEMORY;
2702f6384f9SAlexandru Elisei }
2712f6384f9SAlexandru Elisei 
pci__memory_space_enabled(struct pci_device_header * pci_hdr)2722f6384f9SAlexandru Elisei static inline bool pci__memory_space_enabled(struct pci_device_header *pci_hdr)
2732f6384f9SAlexandru Elisei {
2742f6384f9SAlexandru Elisei 	return __pci__memory_space_enabled(pci_hdr->command);
2752f6384f9SAlexandru Elisei }
2762f6384f9SAlexandru Elisei 
__pci__io_space_enabled(u16 command)2772f6384f9SAlexandru Elisei static inline bool __pci__io_space_enabled(u16 command)
2782f6384f9SAlexandru Elisei {
2792f6384f9SAlexandru Elisei 	return command & PCI_COMMAND_IO;
2802f6384f9SAlexandru Elisei }
2812f6384f9SAlexandru Elisei 
pci__io_space_enabled(struct pci_device_header * pci_hdr)2822f6384f9SAlexandru Elisei static inline bool pci__io_space_enabled(struct pci_device_header *pci_hdr)
2832f6384f9SAlexandru Elisei {
2842f6384f9SAlexandru Elisei 	return __pci__io_space_enabled(pci_hdr->command);
2852f6384f9SAlexandru Elisei }
2862f6384f9SAlexandru Elisei 
__pci__bar_is_io(u32 bar)2872f6384f9SAlexandru Elisei static inline bool __pci__bar_is_io(u32 bar)
2882f6384f9SAlexandru Elisei {
2892f6384f9SAlexandru Elisei 	return bar & PCI_BASE_ADDRESS_SPACE_IO;
2902f6384f9SAlexandru Elisei }
2912f6384f9SAlexandru Elisei 
pci__bar_is_io(struct pci_device_header * pci_hdr,int bar_num)2922f6384f9SAlexandru Elisei static inline bool pci__bar_is_io(struct pci_device_header *pci_hdr, int bar_num)
2932f6384f9SAlexandru Elisei {
2942f6384f9SAlexandru Elisei 	return __pci__bar_is_io(pci_hdr->bar[bar_num]);
2952f6384f9SAlexandru Elisei }
2962f6384f9SAlexandru Elisei 
pci__bar_is_memory(struct pci_device_header * pci_hdr,int bar_num)2972f6384f9SAlexandru Elisei static inline bool pci__bar_is_memory(struct pci_device_header *pci_hdr, int bar_num)
2982f6384f9SAlexandru Elisei {
2992f6384f9SAlexandru Elisei 	return !pci__bar_is_io(pci_hdr, bar_num);
3002f6384f9SAlexandru Elisei }
3012f6384f9SAlexandru Elisei 
__pci__bar_address(u32 bar)3022f6384f9SAlexandru Elisei static inline u32 __pci__bar_address(u32 bar)
3032f6384f9SAlexandru Elisei {
3042f6384f9SAlexandru Elisei 	if (__pci__bar_is_io(bar))
3052f6384f9SAlexandru Elisei 		return bar & PCI_BASE_ADDRESS_IO_MASK;
3062f6384f9SAlexandru Elisei 	return bar & PCI_BASE_ADDRESS_MEM_MASK;
3072f6384f9SAlexandru Elisei }
3082f6384f9SAlexandru Elisei 
pci__bar_address(struct pci_device_header * pci_hdr,int bar_num)3092f6384f9SAlexandru Elisei static inline u32 pci__bar_address(struct pci_device_header *pci_hdr, int bar_num)
3102f6384f9SAlexandru Elisei {
3112f6384f9SAlexandru Elisei 	return __pci__bar_address(pci_hdr->bar[bar_num]);
3122f6384f9SAlexandru Elisei }
3132f6384f9SAlexandru Elisei 
pci__bar_size(struct pci_device_header * pci_hdr,int bar_num)3142f6384f9SAlexandru Elisei static inline u32 pci__bar_size(struct pci_device_header *pci_hdr, int bar_num)
3152f6384f9SAlexandru Elisei {
3162f6384f9SAlexandru Elisei 	return pci_hdr->bar_size[bar_num];
3172f6384f9SAlexandru Elisei }
3182f6384f9SAlexandru Elisei 
31960742802SPekka Enberg #endif /* KVM__PCI_H */
320