1 #include "kvm/pci.h" 2 #include "kvm/ioport.h" 3 #include "kvm/util.h" 4 #include "kvm/kvm.h" 5 6 #include <assert.h> 7 8 #define PCI_BAR_OFFSET(b) (offsetof(struct pci_device_header, bar[b])) 9 10 static struct pci_device_header *pci_devices[PCI_MAX_DEVICES]; 11 12 static union pci_config_address pci_config_address; 13 14 /* This is within our PCI gap - in an unused area */ 15 static u32 io_space_blocks = KVM_32BIT_GAP_START + 0x1000000; 16 17 u32 pci_get_io_space_block(u32 size) 18 { 19 u32 block = io_space_blocks; 20 io_space_blocks += size; 21 22 return block; 23 } 24 25 static void *pci_config_address_ptr(u16 port) 26 { 27 unsigned long offset; 28 void *base; 29 30 offset = port - PCI_CONFIG_ADDRESS; 31 base = &pci_config_address; 32 33 return base + offset; 34 } 35 36 static bool pci_config_address_out(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size) 37 { 38 void *p = pci_config_address_ptr(port); 39 40 memcpy(p, data, size); 41 42 return true; 43 } 44 45 static bool pci_config_address_in(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size) 46 { 47 void *p = pci_config_address_ptr(port); 48 49 memcpy(data, p, size); 50 51 return true; 52 } 53 54 static struct ioport_operations pci_config_address_ops = { 55 .io_in = pci_config_address_in, 56 .io_out = pci_config_address_out, 57 }; 58 59 static bool pci_device_exists(u8 bus_number, u8 device_number, u8 function_number) 60 { 61 struct pci_device_header *dev; 62 63 if (pci_config_address.bus_number != bus_number) 64 return false; 65 66 if (pci_config_address.function_number != function_number) 67 return false; 68 69 if (device_number >= PCI_MAX_DEVICES) 70 return false; 71 72 dev = pci_devices[device_number]; 73 74 return dev != NULL; 75 } 76 77 static bool pci_config_data_out(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size) 78 { 79 unsigned long start; 80 u8 dev_num; 81 82 /* 83 * If someone accesses PCI configuration space offsets that are not 84 * aligned to 4 bytes, it uses ioports to signify that. 85 */ 86 start = port - PCI_CONFIG_DATA; 87 88 dev_num = pci_config_address.device_number; 89 90 if (pci_device_exists(0, dev_num, 0)) { 91 unsigned long offset; 92 93 offset = start + (pci_config_address.register_number << 2); 94 if (offset < sizeof(struct pci_device_header)) { 95 void *p = pci_devices[dev_num]; 96 u8 bar = (offset - PCI_BAR_OFFSET(0)) / (sizeof(u32)); 97 u32 sz = PCI_IO_SIZE; 98 99 if (bar < 6 && pci_devices[dev_num]->bar_size[bar]) 100 sz = pci_devices[dev_num]->bar_size[bar]; 101 102 /* 103 * If the kernel masks the BAR it would expect to find the 104 * size of the BAR there next time it reads from it. 105 * When the kernel got the size it would write the address 106 * back. 107 */ 108 if (*(u32 *)(p + offset)) { 109 /* See if kernel tries to mask one of the BARs */ 110 if ((offset >= PCI_BAR_OFFSET(0)) && 111 (offset <= PCI_BAR_OFFSET(6)) && 112 (ioport__read32(data) == 0xFFFFFFFF)) 113 memcpy(p + offset, &sz, sizeof(sz)); 114 else 115 memcpy(p + offset, data, size); 116 } 117 } 118 } 119 120 return true; 121 } 122 123 static bool pci_config_data_in(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size) 124 { 125 unsigned long start; 126 u8 dev_num; 127 128 /* 129 * If someone accesses PCI configuration space offsets that are not 130 * aligned to 4 bytes, it uses ioports to signify that. 131 */ 132 start = port - PCI_CONFIG_DATA; 133 134 dev_num = pci_config_address.device_number; 135 136 if (pci_device_exists(0, dev_num, 0)) { 137 unsigned long offset; 138 139 offset = start + (pci_config_address.register_number << 2); 140 if (offset < sizeof(struct pci_device_header)) { 141 void *p = pci_devices[dev_num]; 142 143 memcpy(data, p + offset, size); 144 } else 145 memset(data, 0x00, size); 146 } else 147 memset(data, 0xff, size); 148 149 return true; 150 } 151 152 static struct ioport_operations pci_config_data_ops = { 153 .io_in = pci_config_data_in, 154 .io_out = pci_config_data_out, 155 }; 156 157 void pci__register(struct pci_device_header *dev, u8 dev_num) 158 { 159 assert(dev_num < PCI_MAX_DEVICES); 160 161 pci_devices[dev_num] = dev; 162 } 163 164 void pci__init(void) 165 { 166 ioport__register(PCI_CONFIG_DATA + 0, &pci_config_data_ops, 4, NULL); 167 ioport__register(PCI_CONFIG_ADDRESS + 0, &pci_config_address_ops, 4, NULL); 168 } 169