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> 7aa73be70SMatt Evans #include <endian.h> 876f9c841SCyrill Gorcunov 9b5981636SWill Deacon #include "kvm/devices.h" 10f7c17d7cSPekka Enberg #include "kvm/msi.h" 11ff01b5dbSJean-Philippe Brucker #include "kvm/fdt.h" 12d0297a59SMatt Evans 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 22b403f2f7SWill Deacon #define PCI_CFG_SIZE (1ULL << 24) 23305b72ceSCyrill Gorcunov 24*6078a454SJean-Philippe Brucker struct kvm; 25*6078a454SJean-Philippe Brucker 26aa73be70SMatt Evans union pci_config_address { 27aa73be70SMatt Evans struct { 28aa73be70SMatt Evans #if __BYTE_ORDER == __LITTLE_ENDIAN 29d0297a59SMatt Evans unsigned reg_offset : 2; /* 1 .. 0 */ 304402a581SPekka Enberg unsigned register_number : 6; /* 7 .. 2 */ 314402a581SPekka Enberg unsigned function_number : 3; /* 10 .. 8 */ 324402a581SPekka Enberg unsigned device_number : 5; /* 15 .. 11 */ 334402a581SPekka Enberg unsigned bus_number : 8; /* 23 .. 16 */ 344402a581SPekka Enberg unsigned reserved : 7; /* 30 .. 24 */ 354402a581SPekka Enberg unsigned enable_bit : 1; /* 31 */ 36aa73be70SMatt Evans #else 37aa73be70SMatt Evans unsigned enable_bit : 1; /* 31 */ 38aa73be70SMatt Evans unsigned reserved : 7; /* 30 .. 24 */ 39aa73be70SMatt Evans unsigned bus_number : 8; /* 23 .. 16 */ 40aa73be70SMatt Evans unsigned device_number : 5; /* 15 .. 11 */ 41aa73be70SMatt Evans unsigned function_number : 3; /* 10 .. 8 */ 42aa73be70SMatt Evans unsigned register_number : 6; /* 7 .. 2 */ 43d0297a59SMatt Evans unsigned reg_offset : 2; /* 1 .. 0 */ 44aa73be70SMatt Evans #endif 45aa73be70SMatt Evans }; 46aa73be70SMatt Evans u32 w; 474402a581SPekka Enberg }; 484402a581SPekka Enberg 49bc485053SSasha Levin struct msix_table { 501de74957SSasha Levin struct msi_msg msg; 51bc485053SSasha Levin u32 ctrl; 52bc485053SSasha Levin }; 53bc485053SSasha Levin 54bc485053SSasha Levin struct msix_cap { 55bc485053SSasha Levin u8 cap; 56bc485053SSasha Levin u8 next; 5706f48103SSasha Levin u16 ctrl; 58bc485053SSasha Levin u32 table_offset; 5906f48103SSasha Levin u32 pba_offset; 60bc485053SSasha Levin }; 61bc485053SSasha Levin 621a51c93dSJean-Philippe Brucker struct pci_cap_hdr { 631a51c93dSJean-Philippe Brucker u8 type; 641a51c93dSJean-Philippe Brucker u8 next; 651a51c93dSJean-Philippe Brucker }; 661a51c93dSJean-Philippe Brucker 67023fdaaeSJean-Philippe Brucker #define PCI_BAR_OFFSET(b) (offsetof(struct pci_device_header, bar[b])) 68023fdaaeSJean-Philippe Brucker #define PCI_DEV_CFG_SIZE 256 69023fdaaeSJean-Philippe Brucker #define PCI_DEV_CFG_MASK (PCI_DEV_CFG_SIZE - 1) 70023fdaaeSJean-Philippe Brucker 71023fdaaeSJean-Philippe Brucker struct pci_device_header; 72023fdaaeSJean-Philippe Brucker 73023fdaaeSJean-Philippe Brucker struct pci_config_operations { 74023fdaaeSJean-Philippe Brucker void (*write)(struct kvm *kvm, struct pci_device_header *pci_hdr, 75023fdaaeSJean-Philippe Brucker u8 offset, void *data, int sz); 76023fdaaeSJean-Philippe Brucker void (*read)(struct kvm *kvm, struct pci_device_header *pci_hdr, 77023fdaaeSJean-Philippe Brucker u8 offset, void *data, int sz); 78023fdaaeSJean-Philippe Brucker }; 79023fdaaeSJean-Philippe Brucker 8076f9c841SCyrill Gorcunov struct pci_device_header { 81023fdaaeSJean-Philippe Brucker /* Configuration space, as seen by the guest */ 82023fdaaeSJean-Philippe Brucker union { 83023fdaaeSJean-Philippe Brucker struct { 843fdf659dSSasha Levin u16 vendor_id; 853fdf659dSSasha Levin u16 device_id; 863fdf659dSSasha Levin u16 command; 873fdf659dSSasha Levin u16 status; 88aa73be70SMatt Evans u8 revision_id; 89aa73be70SMatt Evans u8 class[3]; 903fdf659dSSasha Levin u8 cacheline_size; 913fdf659dSSasha Levin u8 latency_timer; 923fdf659dSSasha Levin u8 header_type; 933fdf659dSSasha Levin u8 bist; 943fdf659dSSasha Levin u32 bar[6]; 953fdf659dSSasha Levin u32 card_bus; 963fdf659dSSasha Levin u16 subsys_vendor_id; 973fdf659dSSasha Levin u16 subsys_id; 983fdf659dSSasha Levin u32 exp_rom_bar; 99aa73be70SMatt Evans u8 capabilities; 100aa73be70SMatt Evans u8 reserved1[3]; 1013fdf659dSSasha Levin u32 reserved2; 1023fdf659dSSasha Levin u8 irq_line; 1033fdf659dSSasha Levin u8 irq_pin; 1043fdf659dSSasha Levin u8 min_gnt; 1053fdf659dSSasha Levin u8 max_lat; 106bc485053SSasha Levin struct msix_cap msix; 107aa73be70SMatt Evans } __attribute__((packed)); 108023fdaaeSJean-Philippe Brucker /* Pad to PCI config space size */ 109023fdaaeSJean-Philippe Brucker u8 __pad[PCI_DEV_CFG_SIZE]; 110023fdaaeSJean-Philippe Brucker }; 111023fdaaeSJean-Philippe Brucker 112023fdaaeSJean-Philippe Brucker /* Private to lkvm */ 113023fdaaeSJean-Philippe Brucker u32 bar_size[6]; 114023fdaaeSJean-Philippe Brucker struct pci_config_operations cfg_ops; 115ff01b5dbSJean-Philippe Brucker /* 116ff01b5dbSJean-Philippe Brucker * PCI INTx# are level-triggered, but virtual device often feature 117ff01b5dbSJean-Philippe Brucker * edge-triggered INTx# for convenience. 118ff01b5dbSJean-Philippe Brucker */ 119ff01b5dbSJean-Philippe Brucker enum irq_type irq_type; 120023fdaaeSJean-Philippe Brucker }; 12176f9c841SCyrill Gorcunov 1221a51c93dSJean-Philippe Brucker #define PCI_CAP(pci_hdr, pos) ((void *)(pci_hdr) + (pos)) 1231a51c93dSJean-Philippe Brucker 1241a51c93dSJean-Philippe Brucker #define pci_for_each_cap(pos, cap, hdr) \ 1251a51c93dSJean-Philippe Brucker for ((pos) = (hdr)->capabilities & ~3; \ 1261a51c93dSJean-Philippe Brucker (cap) = PCI_CAP(hdr, pos), (pos) != 0; \ 1271a51c93dSJean-Philippe Brucker (pos) = ((struct pci_cap_hdr *)(cap))->next & ~3) 1281a51c93dSJean-Philippe Brucker 1296d987703SSasha Levin int pci__init(struct kvm *kvm); 1306d987703SSasha Levin int pci__exit(struct kvm *kvm); 131d0297a59SMatt Evans struct pci_device_header *pci__find_dev(u8 dev_num); 13295d13a52SSasha Levin u32 pci_get_io_space_block(u32 size); 133b5981636SWill Deacon void pci__assign_irq(struct device_header *dev_hdr); 134d0297a59SMatt Evans void pci__config_wr(struct kvm *kvm, union pci_config_address addr, void *data, int size); 135d0297a59SMatt Evans void pci__config_rd(struct kvm *kvm, union pci_config_address addr, void *data, int size); 13660742802SPekka Enberg 1371a51c93dSJean-Philippe Brucker void *pci_find_cap(struct pci_device_header *hdr, u8 cap_type); 1381a51c93dSJean-Philippe Brucker 13960742802SPekka Enberg #endif /* KVM__PCI_H */ 140