1 /* 2 * SPAPR PHB emulation, RTAS interface to PCI config space, device tree nodes 3 * for enumerated devices. 4 * 5 * Borrowed heavily from QEMU's spapr_pci.c, 6 * Copyright (c) 2011 Alexey Kardashevskiy, IBM Corporation. 7 * Copyright (c) 2011 David Gibson, IBM Corporation. 8 * 9 * Modifications copyright 2011 Matt Evans <matt@ozlabs.org>, IBM Corporation. 10 * 11 * This program is free software; you can redistribute it and/or modify it 12 * under the terms of the GNU General Public License version 2 as published 13 * by the Free Software Foundation. 14 */ 15 16 #include "spapr.h" 17 #include "spapr_pci.h" 18 #include "kvm/devices.h" 19 #include "kvm/fdt.h" 20 #include "kvm/util.h" 21 #include "kvm/of_pci.h" 22 #include "kvm/pci.h" 23 24 #include <linux/pci_regs.h> 25 #include <linux/byteorder.h> 26 27 28 /* #define DEBUG_PHB yes */ 29 #ifdef DEBUG_PHB 30 #define phb_dprintf(fmt, ...) \ 31 do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0) 32 #else 33 #define phb_dprintf(fmt, ...) \ 34 do { } while (0) 35 #endif 36 37 static const uint32_t bars[] = { 38 PCI_BASE_ADDRESS_0, PCI_BASE_ADDRESS_1, 39 PCI_BASE_ADDRESS_2, PCI_BASE_ADDRESS_3, 40 PCI_BASE_ADDRESS_4, PCI_BASE_ADDRESS_5 41 /*, PCI_ROM_ADDRESS*/ 42 }; 43 44 #define PCI_NUM_REGIONS 7 45 46 static struct spapr_phb phb; 47 48 static void rtas_ibm_read_pci_config(struct kvm_cpu *vcpu, 49 uint32_t token, uint32_t nargs, 50 target_ulong args, 51 uint32_t nret, target_ulong rets) 52 { 53 uint32_t val = 0; 54 uint64_t buid = ((uint64_t)rtas_ld(vcpu->kvm, args, 1) << 32) | rtas_ld(vcpu->kvm, args, 2); 55 union pci_config_address addr = { .w = rtas_ld(vcpu->kvm, args, 0) }; 56 struct pci_device_header *dev = pci__find_dev(addr.device_number); 57 uint32_t size = rtas_ld(vcpu->kvm, args, 3); 58 59 if (buid != phb.buid || !dev || (size > 4)) { 60 phb_dprintf("- cfgRd buid 0x%lx cfg addr 0x%x size %d not found\n", 61 buid, addr.w, size); 62 63 rtas_st(vcpu->kvm, rets, 0, -1); 64 return; 65 } 66 pci__config_rd(vcpu->kvm, addr, &val, size); 67 /* It appears this wants a byteswapped result... */ 68 switch (size) { 69 case 4: 70 val = le32_to_cpu(val); 71 break; 72 case 2: 73 val = le16_to_cpu(val>>16); 74 break; 75 case 1: 76 val = val >> 24; 77 break; 78 } 79 phb_dprintf("- cfgRd buid 0x%lx addr 0x%x (/%d): b%d,d%d,f%d,r0x%x, val 0x%x\n", 80 buid, addr.w, size, addr.bus_number, addr.device_number, addr.function_number, 81 addr.register_number, val); 82 83 rtas_st(vcpu->kvm, rets, 0, 0); 84 rtas_st(vcpu->kvm, rets, 1, val); 85 } 86 87 static void rtas_read_pci_config(struct kvm_cpu *vcpu, 88 uint32_t token, uint32_t nargs, 89 target_ulong args, 90 uint32_t nret, target_ulong rets) 91 { 92 uint32_t val; 93 union pci_config_address addr = { .w = rtas_ld(vcpu->kvm, args, 0) }; 94 struct pci_device_header *dev = pci__find_dev(addr.device_number); 95 uint32_t size = rtas_ld(vcpu->kvm, args, 1); 96 97 if (!dev || (size > 4)) { 98 rtas_st(vcpu->kvm, rets, 0, -1); 99 return; 100 } 101 pci__config_rd(vcpu->kvm, addr, &val, size); 102 switch (size) { 103 case 4: 104 val = le32_to_cpu(val); 105 break; 106 case 2: 107 val = le16_to_cpu(val>>16); /* We're yuck-endian. */ 108 break; 109 case 1: 110 val = val >> 24; 111 break; 112 } 113 phb_dprintf("- cfgRd addr 0x%x size %d, val 0x%x\n", addr.w, size, val); 114 rtas_st(vcpu->kvm, rets, 0, 0); 115 rtas_st(vcpu->kvm, rets, 1, val); 116 } 117 118 static void rtas_ibm_write_pci_config(struct kvm_cpu *vcpu, 119 uint32_t token, uint32_t nargs, 120 target_ulong args, 121 uint32_t nret, target_ulong rets) 122 { 123 uint64_t buid = ((uint64_t)rtas_ld(vcpu->kvm, args, 1) << 32) | rtas_ld(vcpu->kvm, args, 2); 124 union pci_config_address addr = { .w = rtas_ld(vcpu->kvm, args, 0) }; 125 struct pci_device_header *dev = pci__find_dev(addr.device_number); 126 uint32_t size = rtas_ld(vcpu->kvm, args, 3); 127 uint32_t val = rtas_ld(vcpu->kvm, args, 4); 128 129 if (buid != phb.buid || !dev || (size > 4)) { 130 phb_dprintf("- cfgWr buid 0x%lx cfg addr 0x%x/%d error (val 0x%x)\n", 131 buid, addr.w, size, val); 132 133 rtas_st(vcpu->kvm, rets, 0, -1); 134 return; 135 } 136 phb_dprintf("- cfgWr buid 0x%lx addr 0x%x (/%d): b%d,d%d,f%d,r0x%x, val 0x%x\n", 137 buid, addr.w, size, addr.bus_number, addr.device_number, addr.function_number, 138 addr.register_number, val); 139 switch (size) { 140 case 4: 141 val = le32_to_cpu(val); 142 break; 143 case 2: 144 val = le16_to_cpu(val) << 16; 145 break; 146 case 1: 147 val = val >> 24; 148 break; 149 } 150 pci__config_wr(vcpu->kvm, addr, &val, size); 151 rtas_st(vcpu->kvm, rets, 0, 0); 152 } 153 154 static void rtas_write_pci_config(struct kvm_cpu *vcpu, 155 uint32_t token, uint32_t nargs, 156 target_ulong args, 157 uint32_t nret, target_ulong rets) 158 { 159 union pci_config_address addr = { .w = rtas_ld(vcpu->kvm, args, 0) }; 160 struct pci_device_header *dev = pci__find_dev(addr.device_number); 161 uint32_t size = rtas_ld(vcpu->kvm, args, 1); 162 uint32_t val = rtas_ld(vcpu->kvm, args, 2); 163 164 if (!dev || (size > 4)) { 165 rtas_st(vcpu->kvm, rets, 0, -1); 166 return; 167 } 168 169 phb_dprintf("- cfgWr addr 0x%x (/%d): b%d,d%d,f%d,r0x%x, val 0x%x\n", 170 addr.w, size, addr.bus_number, addr.device_number, addr.function_number, 171 addr.register_number, val); 172 switch (size) { 173 case 4: 174 val = le32_to_cpu(val); 175 break; 176 case 2: 177 val = le16_to_cpu(val) << 16; 178 break; 179 case 1: 180 val = val >> 24; 181 break; 182 } 183 pci__config_wr(vcpu->kvm, addr, &val, size); 184 rtas_st(vcpu->kvm, rets, 0, 0); 185 } 186 187 void spapr_create_phb(struct kvm *kvm, 188 const char *busname, uint64_t buid, 189 uint64_t mem_win_addr, uint64_t mem_win_size, 190 uint64_t io_win_addr, uint64_t io_win_size) 191 { 192 /* 193 * Since kvmtool doesn't really have any concept of buses etc., 194 * there's nothing to register here. Just register RTAS. 195 */ 196 spapr_rtas_register("read-pci-config", rtas_read_pci_config); 197 spapr_rtas_register("write-pci-config", rtas_write_pci_config); 198 spapr_rtas_register("ibm,read-pci-config", rtas_ibm_read_pci_config); 199 spapr_rtas_register("ibm,write-pci-config", rtas_ibm_write_pci_config); 200 201 phb.buid = buid; 202 phb.mem_addr = mem_win_addr; 203 phb.mem_size = mem_win_size; 204 phb.io_addr = io_win_addr; 205 phb.io_size = io_win_size; 206 207 kvm->arch.phb = &phb; 208 } 209 210 static uint32_t bar_to_ss(unsigned long bar) 211 { 212 if ((bar & PCI_BASE_ADDRESS_SPACE) == 213 PCI_BASE_ADDRESS_SPACE_IO) 214 return OF_PCI_SS_IO; 215 else if (bar & PCI_BASE_ADDRESS_MEM_TYPE_64) 216 return OF_PCI_SS_M64; 217 else 218 return OF_PCI_SS_M32; 219 } 220 221 static unsigned long bar_to_addr(unsigned long bar) 222 { 223 if ((bar & PCI_BASE_ADDRESS_SPACE) == 224 PCI_BASE_ADDRESS_SPACE_IO) 225 return bar & PCI_BASE_ADDRESS_IO_MASK; 226 else 227 return bar & PCI_BASE_ADDRESS_MEM_MASK; 228 } 229 230 int spapr_populate_pci_devices(struct kvm *kvm, 231 uint32_t xics_phandle, 232 void *fdt) 233 { 234 int bus_off, node_off = 0, devid, fn, i, n, devices; 235 struct device_header *dev_hdr; 236 char nodename[256]; 237 struct of_pci_unit64_address { 238 u32 phys_hi; 239 u64 addr; 240 u64 size; 241 } __attribute((packed)) reg[PCI_NUM_REGIONS + 1], assigned_addresses[PCI_NUM_REGIONS]; 242 uint32_t bus_range[] = { cpu_to_be32(0), cpu_to_be32(0xff) }; 243 struct of_pci_ranges_entry ranges[] = { 244 { 245 { 246 cpu_to_be32(of_pci_b_ss(1)), 247 cpu_to_be32(0), 248 cpu_to_be32(0), 249 }, 250 cpu_to_be64(phb.io_addr), 251 cpu_to_be64(phb.io_size), 252 }, 253 { 254 { 255 cpu_to_be32(of_pci_b_ss(2)), 256 cpu_to_be32(0), 257 cpu_to_be32(0), 258 }, 259 cpu_to_be64(phb.mem_addr), 260 cpu_to_be64(phb.mem_size), 261 }, 262 }; 263 uint64_t bus_reg[] = { cpu_to_be64(phb.buid), 0 }; 264 uint32_t interrupt_map_mask[] = { 265 cpu_to_be32(of_pci_b_ddddd(-1)|of_pci_b_fff(-1)), 0x0, 0x0, 0x0}; 266 uint32_t interrupt_map[SPAPR_PCI_NUM_LSI][7]; 267 268 /* Start populating the FDT */ 269 sprintf(nodename, "pci@%" PRIx64, phb.buid); 270 bus_off = fdt_add_subnode(fdt, 0, nodename); 271 if (bus_off < 0) { 272 die("error making bus subnode, %s\n", fdt_strerror(bus_off)); 273 return bus_off; 274 } 275 276 /* Write PHB properties */ 277 _FDT(fdt_setprop_string(fdt, bus_off, "device_type", "pci")); 278 _FDT(fdt_setprop_string(fdt, bus_off, "compatible", "IBM,Logical_PHB")); 279 _FDT(fdt_setprop_cell(fdt, bus_off, "#address-cells", 0x3)); 280 _FDT(fdt_setprop_cell(fdt, bus_off, "#size-cells", 0x2)); 281 _FDT(fdt_setprop_cell(fdt, bus_off, "#interrupt-cells", 0x1)); 282 _FDT(fdt_setprop(fdt, bus_off, "used-by-rtas", NULL, 0)); 283 _FDT(fdt_setprop(fdt, bus_off, "bus-range", &bus_range, sizeof(bus_range))); 284 _FDT(fdt_setprop(fdt, bus_off, "ranges", &ranges, sizeof(ranges))); 285 _FDT(fdt_setprop(fdt, bus_off, "reg", &bus_reg, sizeof(bus_reg))); 286 _FDT(fdt_setprop(fdt, bus_off, "interrupt-map-mask", 287 &interrupt_map_mask, sizeof(interrupt_map_mask))); 288 289 /* Populate PCI devices and allocate IRQs */ 290 devices = 0; 291 dev_hdr = device__first_dev(DEVICE_BUS_PCI); 292 while (dev_hdr) { 293 uint32_t *irqmap = interrupt_map[devices]; 294 struct pci_device_header *hdr = dev_hdr->data; 295 296 if (!hdr) 297 continue; 298 299 devid = dev_hdr->dev_num; 300 fn = 0; /* kvmtool doesn't yet do multifunction devices */ 301 302 sprintf(nodename, "pci@%u,%u", devid, fn); 303 304 /* Allocate interrupt from the map */ 305 if (devid > SPAPR_PCI_NUM_LSI) { 306 die("Unexpected behaviour in spapr_populate_pci_devices," 307 "wrong devid %u\n", devid); 308 } 309 irqmap[0] = cpu_to_be32(of_pci_b_ddddd(devid)|of_pci_b_fff(fn)); 310 irqmap[1] = 0; 311 irqmap[2] = 0; 312 irqmap[3] = 0; 313 irqmap[4] = cpu_to_be32(xics_phandle); 314 /* 315 * This is nasty; the PCI devs are set up such that their own 316 * header's irq_line indicates the direct XICS IRQ number to 317 * use. There REALLY needs to be a hierarchical system in place 318 * to 'raise' an IRQ on the bridge which indexes/looks up which 319 * XICS IRQ to fire. 320 */ 321 irqmap[5] = cpu_to_be32(hdr->irq_line); 322 irqmap[6] = cpu_to_be32(0x8); 323 324 /* Add node to FDT */ 325 node_off = fdt_add_subnode(fdt, bus_off, nodename); 326 if (node_off < 0) { 327 die("error making node subnode, %s\n", fdt_strerror(bus_off)); 328 return node_off; 329 } 330 331 _FDT(fdt_setprop_cell(fdt, node_off, "vendor-id", 332 le16_to_cpu(hdr->vendor_id))); 333 _FDT(fdt_setprop_cell(fdt, node_off, "device-id", 334 le16_to_cpu(hdr->device_id))); 335 _FDT(fdt_setprop_cell(fdt, node_off, "revision-id", 336 hdr->revision_id)); 337 _FDT(fdt_setprop_cell(fdt, node_off, "class-code", 338 hdr->class[0] | (hdr->class[1] << 8) | (hdr->class[2] << 16))); 339 _FDT(fdt_setprop_cell(fdt, node_off, "subsystem-id", 340 le16_to_cpu(hdr->subsys_id))); 341 _FDT(fdt_setprop_cell(fdt, node_off, "subsystem-vendor-id", 342 le16_to_cpu(hdr->subsys_vendor_id))); 343 344 /* Config space region comes first */ 345 reg[0].phys_hi = cpu_to_be32( 346 of_pci_b_n(0) | 347 of_pci_b_p(0) | 348 of_pci_b_t(0) | 349 of_pci_b_ss(OF_PCI_SS_CONFIG) | 350 of_pci_b_bbbbbbbb(0) | 351 of_pci_b_ddddd(devid) | 352 of_pci_b_fff(fn)); 353 reg[0].addr = 0; 354 reg[0].size = 0; 355 356 n = 0; 357 /* Six BARs, no ROM supported, addresses are 32bit */ 358 for (i = 0; i < 6; ++i) { 359 if (0 == hdr->bar[i]) { 360 continue; 361 } 362 363 reg[n+1].phys_hi = cpu_to_be32( 364 of_pci_b_n(0) | 365 of_pci_b_p(0) | 366 of_pci_b_t(0) | 367 of_pci_b_ss(bar_to_ss(le32_to_cpu(hdr->bar[i]))) | 368 of_pci_b_bbbbbbbb(0) | 369 of_pci_b_ddddd(devid) | 370 of_pci_b_fff(fn) | 371 of_pci_b_rrrrrrrr(bars[i])); 372 reg[n+1].size = cpu_to_be64(hdr->bar_size[i]); 373 reg[n+1].addr = 0; 374 375 assigned_addresses[n].phys_hi = cpu_to_be32( 376 of_pci_b_n(1) | 377 of_pci_b_p(0) | 378 of_pci_b_t(0) | 379 of_pci_b_ss(bar_to_ss(le32_to_cpu(hdr->bar[i]))) | 380 of_pci_b_bbbbbbbb(0) | 381 of_pci_b_ddddd(devid) | 382 of_pci_b_fff(fn) | 383 of_pci_b_rrrrrrrr(bars[i])); 384 385 /* 386 * Writing zeroes to assigned_addresses causes the guest kernel to 387 * reassign BARs 388 */ 389 assigned_addresses[n].addr = cpu_to_be64(bar_to_addr(le32_to_cpu(hdr->bar[i]))); 390 assigned_addresses[n].size = reg[n+1].size; 391 392 ++n; 393 } 394 _FDT(fdt_setprop(fdt, node_off, "reg", reg, sizeof(reg[0])*(n+1))); 395 _FDT(fdt_setprop(fdt, node_off, "assigned-addresses", 396 assigned_addresses, 397 sizeof(assigned_addresses[0])*(n))); 398 _FDT(fdt_setprop_cell(fdt, node_off, "interrupts", 399 hdr->irq_pin)); 400 401 /* We don't set ibm,dma-window property as we don't have an IOMMU. */ 402 403 ++devices; 404 dev_hdr = device__next_dev(dev_hdr); 405 } 406 407 /* Write interrupt map */ 408 _FDT(fdt_setprop(fdt, bus_off, "interrupt-map", &interrupt_map, 409 devices * sizeof(interrupt_map[0]))); 410 411 return 0; 412 } 413