xref: /kvmtool/include/kvm/pci.h (revision d0297a59b50ef9013e3482ba30535742bd5bf1c2)
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>
71de74957SSasha Levin #include <linux/msi.h>
8aa73be70SMatt Evans #include <endian.h>
976f9c841SCyrill Gorcunov 
10*d0297a59SMatt Evans #include "kvm/kvm.h"
11*d0297a59SMatt Evans 
129d755a36SMatt Evans #define PCI_MAX_DEVICES			256
134402a581SPekka Enberg /*
144402a581SPekka Enberg  * PCI Configuration Mechanism #1 I/O ports. See Section 3.7.4.1.
154402a581SPekka Enberg  * ("Configuration Mechanism #1") of the PCI Local Bus Specification 2.1 for
164402a581SPekka Enberg  * details.
174402a581SPekka Enberg  */
18305b72ceSCyrill Gorcunov #define PCI_CONFIG_ADDRESS	0xcf8
19305b72ceSCyrill Gorcunov #define PCI_CONFIG_DATA		0xcfc
202b9e4709SCyrill Gorcunov #define PCI_CONFIG_BUS_FORWARD	0xcfa
2195d13a52SSasha Levin #define PCI_IO_SIZE		0x100
22305b72ceSCyrill Gorcunov 
23aa73be70SMatt Evans union pci_config_address {
24aa73be70SMatt Evans 	struct {
25aa73be70SMatt Evans #if __BYTE_ORDER == __LITTLE_ENDIAN
26*d0297a59SMatt Evans 		unsigned	reg_offset	: 2;		/* 1  .. 0  */
274402a581SPekka Enberg 		unsigned	register_number	: 6;		/* 7  .. 2  */
284402a581SPekka Enberg 		unsigned	function_number	: 3;		/* 10 .. 8  */
294402a581SPekka Enberg 		unsigned	device_number	: 5;		/* 15 .. 11 */
304402a581SPekka Enberg 		unsigned	bus_number	: 8;		/* 23 .. 16 */
314402a581SPekka Enberg 		unsigned	reserved	: 7;		/* 30 .. 24 */
324402a581SPekka Enberg 		unsigned	enable_bit	: 1;		/* 31       */
33aa73be70SMatt Evans #else
34aa73be70SMatt Evans 		unsigned	enable_bit	: 1;		/* 31       */
35aa73be70SMatt Evans 		unsigned	reserved	: 7;		/* 30 .. 24 */
36aa73be70SMatt Evans 		unsigned	bus_number	: 8;		/* 23 .. 16 */
37aa73be70SMatt Evans 		unsigned	device_number	: 5;		/* 15 .. 11 */
38aa73be70SMatt Evans 		unsigned	function_number	: 3;		/* 10 .. 8  */
39aa73be70SMatt Evans 		unsigned	register_number	: 6;		/* 7  .. 2  */
40*d0297a59SMatt Evans 		unsigned	reg_offset	: 2;		/* 1  .. 0  */
41aa73be70SMatt Evans #endif
42aa73be70SMatt Evans 	};
43aa73be70SMatt Evans 	u32 w;
444402a581SPekka Enberg };
454402a581SPekka Enberg 
46bc485053SSasha Levin struct msix_table {
471de74957SSasha Levin 	struct msi_msg msg;
48bc485053SSasha Levin 	u32 ctrl;
49bc485053SSasha Levin };
50bc485053SSasha Levin 
51bc485053SSasha Levin struct msix_cap {
52bc485053SSasha Levin 	u8 cap;
53bc485053SSasha Levin 	u8 next;
5406f48103SSasha Levin 	u16 ctrl;
55bc485053SSasha Levin 	u32 table_offset;
5606f48103SSasha Levin 	u32 pba_offset;
57bc485053SSasha Levin };
58bc485053SSasha Levin 
5976f9c841SCyrill Gorcunov struct pci_device_header {
603fdf659dSSasha Levin 	u16		vendor_id;
613fdf659dSSasha Levin 	u16		device_id;
623fdf659dSSasha Levin 	u16		command;
633fdf659dSSasha Levin 	u16		status;
64aa73be70SMatt Evans 	u8		revision_id;
65aa73be70SMatt Evans 	u8		class[3];
663fdf659dSSasha Levin 	u8		cacheline_size;
673fdf659dSSasha Levin 	u8		latency_timer;
683fdf659dSSasha Levin 	u8		header_type;
693fdf659dSSasha Levin 	u8		bist;
703fdf659dSSasha Levin 	u32		bar[6];
713fdf659dSSasha Levin 	u32		card_bus;
723fdf659dSSasha Levin 	u16		subsys_vendor_id;
733fdf659dSSasha Levin 	u16		subsys_id;
743fdf659dSSasha Levin 	u32		exp_rom_bar;
75aa73be70SMatt Evans 	u8		capabilities;
76aa73be70SMatt Evans 	u8		reserved1[3];
773fdf659dSSasha Levin 	u32		reserved2;
783fdf659dSSasha Levin 	u8		irq_line;
793fdf659dSSasha Levin 	u8		irq_pin;
803fdf659dSSasha Levin 	u8		min_gnt;
813fdf659dSSasha Levin 	u8		max_lat;
82bc485053SSasha Levin 	struct msix_cap msix;
83c64f7ff0SSasha Levin 	u8		empty[136]; /* Rest of PCI config space */
84c64f7ff0SSasha Levin 	u32		bar_size[6];
85aa73be70SMatt Evans } __attribute__((packed));
8676f9c841SCyrill Gorcunov 
8760742802SPekka Enberg void pci__init(void);
883fdf659dSSasha Levin void pci__register(struct pci_device_header *dev, u8 dev_num);
89*d0297a59SMatt Evans struct pci_device_header *pci__find_dev(u8 dev_num);
9095d13a52SSasha Levin u32 pci_get_io_space_block(u32 size);
91*d0297a59SMatt Evans void pci__config_wr(struct kvm *kvm, union pci_config_address addr, void *data, int size);
92*d0297a59SMatt Evans void pci__config_rd(struct kvm *kvm, union pci_config_address addr, void *data, int size);
9360742802SPekka Enberg 
9460742802SPekka Enberg #endif /* KVM__PCI_H */
95