1 /* 2 * Copyright (c) 2018, Impinj, Inc. 3 * 4 * Designware PCIe IP block emulation 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, see 18 * <http://www.gnu.org/licenses/>. 19 */ 20 21 #include "qemu/osdep.h" 22 #include "qapi/error.h" 23 #include "qemu/log.h" 24 #include "qemu/bitops.h" 25 #include "hw/pci/msi.h" 26 #include "hw/pci/pci_bridge.h" 27 #include "hw/pci/pci_host.h" 28 #include "hw/pci/pcie_port.h" 29 #include "hw/qdev-properties.h" 30 #include "migration/vmstate.h" 31 #include "hw/irq.h" 32 #include "hw/pci-host/designware.h" 33 34 #define DESIGNWARE_PCIE_PORT_LINK_CONTROL 0x710 35 #define DESIGNWARE_PCIE_PHY_DEBUG_R1 0x72C 36 #define DESIGNWARE_PCIE_PHY_DEBUG_R1_XMLH_LINK_UP BIT(4) 37 #define DESIGNWARE_PCIE_LINK_WIDTH_SPEED_CONTROL 0x80C 38 #define DESIGNWARE_PCIE_PORT_LOGIC_SPEED_CHANGE BIT(17) 39 #define DESIGNWARE_PCIE_MSI_ADDR_LO 0x820 40 #define DESIGNWARE_PCIE_MSI_ADDR_HI 0x824 41 #define DESIGNWARE_PCIE_MSI_INTR0_ENABLE 0x828 42 #define DESIGNWARE_PCIE_MSI_INTR0_MASK 0x82C 43 #define DESIGNWARE_PCIE_MSI_INTR0_STATUS 0x830 44 #define DESIGNWARE_PCIE_ATU_VIEWPORT 0x900 45 #define DESIGNWARE_PCIE_ATU_REGION_INBOUND BIT(31) 46 #define DESIGNWARE_PCIE_ATU_CR1 0x904 47 #define DESIGNWARE_PCIE_ATU_TYPE_MEM (0x0 << 0) 48 #define DESIGNWARE_PCIE_ATU_CR2 0x908 49 #define DESIGNWARE_PCIE_ATU_ENABLE BIT(31) 50 #define DESIGNWARE_PCIE_ATU_LOWER_BASE 0x90C 51 #define DESIGNWARE_PCIE_ATU_UPPER_BASE 0x910 52 #define DESIGNWARE_PCIE_ATU_LIMIT 0x914 53 #define DESIGNWARE_PCIE_ATU_LOWER_TARGET 0x918 54 #define DESIGNWARE_PCIE_ATU_BUS(x) (((x) >> 24) & 0xff) 55 #define DESIGNWARE_PCIE_ATU_DEVFN(x) (((x) >> 16) & 0xff) 56 #define DESIGNWARE_PCIE_ATU_UPPER_TARGET 0x91C 57 58 static void designware_pcie_root_bus_class_init(ObjectClass *klass, 59 const void *data) 60 { 61 BusClass *k = BUS_CLASS(klass); 62 63 /* 64 * Designware has only a single root complex. Enforce the limit on the 65 * parent bus 66 */ 67 k->max_dev = 1; 68 } 69 70 static DesignwarePCIEHost * 71 designware_pcie_root_to_host(DesignwarePCIERoot *root) 72 { 73 BusState *bus = qdev_get_parent_bus(DEVICE(root)); 74 return DESIGNWARE_PCIE_HOST(bus->parent); 75 } 76 77 static uint64_t designware_pcie_root_msi_read(void *opaque, hwaddr addr, 78 unsigned size) 79 { 80 /* 81 * Attempts to read from the MSI address are undefined in 82 * the PCI specifications. For this hardware, the datasheet 83 * specifies that a read from the magic address is simply not 84 * intercepted by the MSI controller, and will go out to the 85 * AHB/AXI bus like any other PCI-device-initiated DMA read. 86 * This is not trivial to implement in QEMU, so since 87 * well-behaved guests won't ever ask a PCI device to DMA from 88 * this address we just log the missing functionality. 89 */ 90 qemu_log_mask(LOG_UNIMP, "%s not implemented\n", __func__); 91 return 0; 92 } 93 94 static void designware_pcie_root_msi_write(void *opaque, hwaddr addr, 95 uint64_t val, unsigned len) 96 { 97 DesignwarePCIERoot *root = DESIGNWARE_PCIE_ROOT(opaque); 98 DesignwarePCIEHost *host = designware_pcie_root_to_host(root); 99 100 root->msi.intr[0].status |= BIT(val) & root->msi.intr[0].enable; 101 102 if (root->msi.intr[0].status & ~root->msi.intr[0].mask) { 103 qemu_set_irq(host->pci.msi, 1); 104 } 105 } 106 107 static const MemoryRegionOps designware_pci_host_msi_ops = { 108 .read = designware_pcie_root_msi_read, 109 .write = designware_pcie_root_msi_write, 110 .endianness = DEVICE_LITTLE_ENDIAN, 111 .valid = { 112 .min_access_size = 4, 113 .max_access_size = 4, 114 }, 115 }; 116 117 static void designware_pcie_root_update_msi_mapping(DesignwarePCIERoot *root) 118 119 { 120 MemoryRegion *mem = &root->msi.iomem; 121 const uint64_t base = root->msi.base; 122 const bool enable = root->msi.intr[0].enable; 123 124 memory_region_set_address(mem, base); 125 memory_region_set_enabled(mem, enable); 126 } 127 128 static DesignwarePCIEViewport * 129 designware_pcie_root_get_current_viewport(DesignwarePCIERoot *root) 130 { 131 const unsigned int idx = root->atu_viewport & 0xF; 132 const unsigned int dir = 133 !!(root->atu_viewport & DESIGNWARE_PCIE_ATU_REGION_INBOUND); 134 return &root->viewports[dir][idx]; 135 } 136 137 static uint32_t 138 designware_pcie_root_config_read(PCIDevice *d, uint32_t address, int len) 139 { 140 DesignwarePCIERoot *root = DESIGNWARE_PCIE_ROOT(d); 141 DesignwarePCIEViewport *viewport = 142 designware_pcie_root_get_current_viewport(root); 143 144 uint32_t val; 145 146 switch (address) { 147 case DESIGNWARE_PCIE_PORT_LINK_CONTROL: 148 /* 149 * Linux guest uses this register only to configure number of 150 * PCIE lane (which in our case is irrelevant) and doesn't 151 * really care about the value it reads from this register 152 */ 153 val = 0xDEADBEEF; 154 break; 155 156 case DESIGNWARE_PCIE_LINK_WIDTH_SPEED_CONTROL: 157 /* 158 * To make sure that any code in guest waiting for speed 159 * change does not time out we always report 160 * PORT_LOGIC_SPEED_CHANGE as set 161 */ 162 val = DESIGNWARE_PCIE_PORT_LOGIC_SPEED_CHANGE; 163 break; 164 165 case DESIGNWARE_PCIE_MSI_ADDR_LO: 166 case DESIGNWARE_PCIE_MSI_ADDR_HI: 167 val = extract64(root->msi.base, 168 address == DESIGNWARE_PCIE_MSI_ADDR_LO ? 0 : 32, 32); 169 break; 170 171 case DESIGNWARE_PCIE_MSI_INTR0_ENABLE: 172 val = root->msi.intr[0].enable; 173 break; 174 175 case DESIGNWARE_PCIE_MSI_INTR0_MASK: 176 val = root->msi.intr[0].mask; 177 break; 178 179 case DESIGNWARE_PCIE_MSI_INTR0_STATUS: 180 val = root->msi.intr[0].status; 181 break; 182 183 case DESIGNWARE_PCIE_PHY_DEBUG_R1: 184 val = DESIGNWARE_PCIE_PHY_DEBUG_R1_XMLH_LINK_UP; 185 break; 186 187 case DESIGNWARE_PCIE_ATU_VIEWPORT: 188 val = root->atu_viewport; 189 break; 190 191 case DESIGNWARE_PCIE_ATU_LOWER_BASE: 192 case DESIGNWARE_PCIE_ATU_UPPER_BASE: 193 val = extract64(viewport->base, 194 address == DESIGNWARE_PCIE_ATU_LOWER_BASE ? 0 : 32, 32); 195 break; 196 197 case DESIGNWARE_PCIE_ATU_LOWER_TARGET: 198 case DESIGNWARE_PCIE_ATU_UPPER_TARGET: 199 val = extract64(viewport->target, 200 address == DESIGNWARE_PCIE_ATU_LOWER_TARGET ? 0 : 32, 201 32); 202 break; 203 204 case DESIGNWARE_PCIE_ATU_LIMIT: 205 val = viewport->limit; 206 break; 207 208 case DESIGNWARE_PCIE_ATU_CR1: 209 case DESIGNWARE_PCIE_ATU_CR2: 210 val = viewport->cr[(address - DESIGNWARE_PCIE_ATU_CR1) / 211 sizeof(uint32_t)]; 212 break; 213 214 default: 215 val = pci_default_read_config(d, address, len); 216 break; 217 } 218 219 return val; 220 } 221 222 static uint64_t designware_pcie_root_data_access(void *opaque, hwaddr addr, 223 uint64_t *val, unsigned len) 224 { 225 DesignwarePCIEViewport *viewport = opaque; 226 DesignwarePCIERoot *root = viewport->root; 227 228 const uint8_t busnum = DESIGNWARE_PCIE_ATU_BUS(viewport->target); 229 const uint8_t devfn = DESIGNWARE_PCIE_ATU_DEVFN(viewport->target); 230 PCIBus *pcibus = pci_get_bus(PCI_DEVICE(root)); 231 PCIDevice *pcidev = pci_find_device(pcibus, busnum, devfn); 232 233 if (pcidev) { 234 addr &= pci_config_size(pcidev) - 1; 235 236 if (val) { 237 pci_host_config_write_common(pcidev, addr, 238 pci_config_size(pcidev), 239 *val, len); 240 } else { 241 return pci_host_config_read_common(pcidev, addr, 242 pci_config_size(pcidev), 243 len); 244 } 245 } 246 247 return UINT64_MAX; 248 } 249 250 static uint64_t designware_pcie_root_data_read(void *opaque, hwaddr addr, 251 unsigned len) 252 { 253 return designware_pcie_root_data_access(opaque, addr, NULL, len); 254 } 255 256 static void designware_pcie_root_data_write(void *opaque, hwaddr addr, 257 uint64_t val, unsigned len) 258 { 259 designware_pcie_root_data_access(opaque, addr, &val, len); 260 } 261 262 static const MemoryRegionOps designware_pci_host_conf_ops = { 263 .read = designware_pcie_root_data_read, 264 .write = designware_pcie_root_data_write, 265 .endianness = DEVICE_LITTLE_ENDIAN, 266 .valid = { 267 .min_access_size = 1, 268 .max_access_size = 4, 269 }, 270 }; 271 272 static void designware_pcie_update_viewport(DesignwarePCIERoot *root, 273 DesignwarePCIEViewport *viewport) 274 { 275 const uint64_t target = viewport->target; 276 const uint64_t base = viewport->base; 277 const uint64_t size = (uint64_t)viewport->limit - base + 1; 278 const bool enabled = viewport->cr[1] & DESIGNWARE_PCIE_ATU_ENABLE; 279 280 MemoryRegion *current, *other; 281 282 if (viewport->cr[0] == DESIGNWARE_PCIE_ATU_TYPE_MEM) { 283 current = &viewport->mem; 284 other = &viewport->cfg; 285 memory_region_set_alias_offset(current, target); 286 } else { 287 current = &viewport->cfg; 288 other = &viewport->mem; 289 } 290 291 /* 292 * An outbound viewport can be reconfigure from being MEM to CFG, 293 * to account for that we disable the "other" memory region that 294 * becomes unused due to that fact. 295 */ 296 memory_region_set_enabled(other, false); 297 if (enabled) { 298 memory_region_set_size(current, size); 299 memory_region_set_address(current, base); 300 } 301 memory_region_set_enabled(current, enabled); 302 } 303 304 static void designware_pcie_root_config_write(PCIDevice *d, uint32_t address, 305 uint32_t val, int len) 306 { 307 DesignwarePCIERoot *root = DESIGNWARE_PCIE_ROOT(d); 308 DesignwarePCIEHost *host = designware_pcie_root_to_host(root); 309 DesignwarePCIEViewport *viewport = 310 designware_pcie_root_get_current_viewport(root); 311 312 switch (address) { 313 case DESIGNWARE_PCIE_PORT_LINK_CONTROL: 314 case DESIGNWARE_PCIE_LINK_WIDTH_SPEED_CONTROL: 315 case DESIGNWARE_PCIE_PHY_DEBUG_R1: 316 /* No-op */ 317 break; 318 319 case DESIGNWARE_PCIE_MSI_ADDR_LO: 320 case DESIGNWARE_PCIE_MSI_ADDR_HI: 321 root->msi.base = deposit64(root->msi.base, 322 address == DESIGNWARE_PCIE_MSI_ADDR_LO 323 ? 0 : 32, 32, val); 324 designware_pcie_root_update_msi_mapping(root); 325 break; 326 327 case DESIGNWARE_PCIE_MSI_INTR0_ENABLE: 328 root->msi.intr[0].enable = val; 329 designware_pcie_root_update_msi_mapping(root); 330 break; 331 332 case DESIGNWARE_PCIE_MSI_INTR0_MASK: 333 root->msi.intr[0].mask = val; 334 break; 335 336 case DESIGNWARE_PCIE_MSI_INTR0_STATUS: 337 root->msi.intr[0].status ^= val; 338 if (!root->msi.intr[0].status) { 339 qemu_set_irq(host->pci.msi, 0); 340 } 341 break; 342 343 case DESIGNWARE_PCIE_ATU_VIEWPORT: 344 val &= DESIGNWARE_PCIE_ATU_REGION_INBOUND | 345 (DESIGNWARE_PCIE_NUM_VIEWPORTS - 1); 346 root->atu_viewport = val; 347 break; 348 349 case DESIGNWARE_PCIE_ATU_LOWER_BASE: 350 case DESIGNWARE_PCIE_ATU_UPPER_BASE: 351 viewport->base = deposit64(viewport->base, 352 address == DESIGNWARE_PCIE_ATU_LOWER_BASE 353 ? 0 : 32, 32, val); 354 break; 355 356 case DESIGNWARE_PCIE_ATU_LOWER_TARGET: 357 case DESIGNWARE_PCIE_ATU_UPPER_TARGET: 358 viewport->target = deposit64(viewport->target, 359 address == DESIGNWARE_PCIE_ATU_LOWER_TARGET 360 ? 0 : 32, 32, val); 361 break; 362 363 case DESIGNWARE_PCIE_ATU_LIMIT: 364 viewport->limit = val; 365 break; 366 367 case DESIGNWARE_PCIE_ATU_CR1: 368 viewport->cr[0] = val; 369 break; 370 case DESIGNWARE_PCIE_ATU_CR2: 371 viewport->cr[1] = val; 372 designware_pcie_update_viewport(root, viewport); 373 break; 374 375 default: 376 pci_bridge_write_config(d, address, val, len); 377 break; 378 } 379 } 380 381 static char *designware_pcie_viewport_name(const char *direction, 382 unsigned int i, 383 const char *type) 384 { 385 return g_strdup_printf("PCI %s Viewport %u [%s]", 386 direction, i, type); 387 } 388 389 static void designware_pcie_root_realize(PCIDevice *dev, Error **errp) 390 { 391 DesignwarePCIERoot *root = DESIGNWARE_PCIE_ROOT(dev); 392 DesignwarePCIEHost *host = designware_pcie_root_to_host(root); 393 MemoryRegion *host_mem = get_system_memory(); 394 MemoryRegion *address_space = &host->pci.memory; 395 PCIBridge *br = PCI_BRIDGE(dev); 396 DesignwarePCIEViewport *viewport; 397 /* 398 * Dummy values used for initial configuration of MemoryRegions 399 * that belong to a given viewport 400 */ 401 const hwaddr dummy_offset = 0; 402 const uint64_t dummy_size = 4; 403 size_t i; 404 405 br->bus_name = "dw-pcie"; 406 407 pci_set_word(dev->config + PCI_COMMAND, 408 PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); 409 410 pci_config_set_interrupt_pin(dev->config, 1); 411 pci_bridge_initfn(dev, TYPE_PCIE_BUS); 412 413 pcie_port_init_reg(dev); 414 415 pcie_cap_init(dev, 0x70, PCI_EXP_TYPE_ROOT_PORT, 416 0, &error_fatal); 417 418 msi_nonbroken = true; 419 msi_init(dev, 0x50, 32, true, true, &error_fatal); 420 421 for (i = 0; i < DESIGNWARE_PCIE_NUM_VIEWPORTS; i++) { 422 MemoryRegion *source, *destination, *mem; 423 const char *direction; 424 char *name; 425 426 viewport = &root->viewports[DESIGNWARE_PCIE_VIEWPORT_INBOUND][i]; 427 viewport->inbound = true; 428 viewport->base = 0x0000000000000000ULL; 429 viewport->target = 0x0000000000000000ULL; 430 viewport->limit = UINT32_MAX; 431 viewport->cr[0] = DESIGNWARE_PCIE_ATU_TYPE_MEM; 432 433 source = &host->pci.address_space_root; 434 destination = host_mem; 435 direction = "Inbound"; 436 437 /* 438 * Configure MemoryRegion implementing PCI -> CPU memory 439 * access 440 */ 441 mem = &viewport->mem; 442 name = designware_pcie_viewport_name(direction, i, "MEM"); 443 memory_region_init_alias(mem, OBJECT(root), name, destination, 444 dummy_offset, dummy_size); 445 memory_region_add_subregion_overlap(source, dummy_offset, mem, -1); 446 memory_region_set_enabled(mem, false); 447 g_free(name); 448 449 viewport = &root->viewports[DESIGNWARE_PCIE_VIEWPORT_OUTBOUND][i]; 450 viewport->root = root; 451 viewport->inbound = false; 452 viewport->base = 0x0000000000000000ULL; 453 viewport->target = 0x0000000000000000ULL; 454 viewport->limit = UINT32_MAX; 455 viewport->cr[0] = DESIGNWARE_PCIE_ATU_TYPE_MEM; 456 457 destination = &host->pci.memory; 458 direction = "Outbound"; 459 source = host_mem; 460 461 /* 462 * Configure MemoryRegion implementing CPU -> PCI memory 463 * access 464 */ 465 mem = &viewport->mem; 466 name = designware_pcie_viewport_name(direction, i, "MEM"); 467 memory_region_init_alias(mem, OBJECT(root), name, destination, 468 dummy_offset, dummy_size); 469 memory_region_add_subregion(source, dummy_offset, mem); 470 memory_region_set_enabled(mem, false); 471 g_free(name); 472 473 /* 474 * Configure MemoryRegion implementing access to configuration 475 * space 476 */ 477 mem = &viewport->cfg; 478 name = designware_pcie_viewport_name(direction, i, "CFG"); 479 memory_region_init_io(&viewport->cfg, OBJECT(root), 480 &designware_pci_host_conf_ops, 481 viewport, name, dummy_size); 482 memory_region_add_subregion(source, dummy_offset, mem); 483 memory_region_set_enabled(mem, false); 484 g_free(name); 485 } 486 487 /* 488 * If no inbound iATU windows are configured, HW defaults to 489 * letting inbound TLPs to pass in. We emulate that by explicitly 490 * configuring first inbound window to cover all of target's 491 * address space. 492 * 493 * NOTE: This will not work correctly for the case when first 494 * configured inbound window is window 0 495 */ 496 viewport = &root->viewports[DESIGNWARE_PCIE_VIEWPORT_INBOUND][0]; 497 viewport->cr[1] = DESIGNWARE_PCIE_ATU_ENABLE; 498 designware_pcie_update_viewport(root, viewport); 499 500 memory_region_init_io(&root->msi.iomem, OBJECT(root), 501 &designware_pci_host_msi_ops, 502 root, "pcie-msi", 0x4); 503 /* 504 * We initially place MSI interrupt I/O region at address 0 and 505 * disable it. It'll be later moved to correct offset and enabled 506 * in designware_pcie_root_update_msi_mapping() as a part of 507 * initialization done by guest OS 508 */ 509 memory_region_add_subregion(address_space, dummy_offset, &root->msi.iomem); 510 memory_region_set_enabled(&root->msi.iomem, false); 511 } 512 513 static void designware_pcie_set_irq(void *opaque, int irq_num, int level) 514 { 515 DesignwarePCIEHost *host = DESIGNWARE_PCIE_HOST(opaque); 516 517 qemu_set_irq(host->pci.irqs[irq_num], level); 518 } 519 520 static const char * 521 designware_pcie_host_root_bus_path(PCIHostState *host_bridge, PCIBus *rootbus) 522 { 523 return "0000:00"; 524 } 525 526 static const VMStateDescription vmstate_designware_pcie_msi_bank = { 527 .name = "designware-pcie-msi-bank", 528 .version_id = 1, 529 .minimum_version_id = 1, 530 .fields = (const VMStateField[]) { 531 VMSTATE_UINT32(enable, DesignwarePCIEMSIBank), 532 VMSTATE_UINT32(mask, DesignwarePCIEMSIBank), 533 VMSTATE_UINT32(status, DesignwarePCIEMSIBank), 534 VMSTATE_END_OF_LIST() 535 } 536 }; 537 538 static const VMStateDescription vmstate_designware_pcie_msi = { 539 .name = "designware-pcie-msi", 540 .version_id = 1, 541 .minimum_version_id = 1, 542 .fields = (const VMStateField[]) { 543 VMSTATE_UINT64(base, DesignwarePCIEMSI), 544 VMSTATE_STRUCT_ARRAY(intr, 545 DesignwarePCIEMSI, 546 DESIGNWARE_PCIE_NUM_MSI_BANKS, 547 1, 548 vmstate_designware_pcie_msi_bank, 549 DesignwarePCIEMSIBank), 550 VMSTATE_END_OF_LIST() 551 } 552 }; 553 554 static const VMStateDescription vmstate_designware_pcie_viewport = { 555 .name = "designware-pcie-viewport", 556 .version_id = 1, 557 .minimum_version_id = 1, 558 .fields = (const VMStateField[]) { 559 VMSTATE_UINT64(base, DesignwarePCIEViewport), 560 VMSTATE_UINT64(target, DesignwarePCIEViewport), 561 VMSTATE_UINT32(limit, DesignwarePCIEViewport), 562 VMSTATE_UINT32_ARRAY(cr, DesignwarePCIEViewport, 2), 563 VMSTATE_END_OF_LIST() 564 } 565 }; 566 567 static const VMStateDescription vmstate_designware_pcie_root = { 568 .name = "designware-pcie-root", 569 .version_id = 1, 570 .minimum_version_id = 1, 571 .fields = (const VMStateField[]) { 572 VMSTATE_PCI_DEVICE(parent_obj, PCIBridge), 573 VMSTATE_UINT32(atu_viewport, DesignwarePCIERoot), 574 VMSTATE_STRUCT_2DARRAY(viewports, 575 DesignwarePCIERoot, 576 2, 577 DESIGNWARE_PCIE_NUM_VIEWPORTS, 578 1, 579 vmstate_designware_pcie_viewport, 580 DesignwarePCIEViewport), 581 VMSTATE_STRUCT(msi, 582 DesignwarePCIERoot, 583 1, 584 vmstate_designware_pcie_msi, 585 DesignwarePCIEMSI), 586 VMSTATE_END_OF_LIST() 587 } 588 }; 589 590 static void designware_pcie_root_class_init(ObjectClass *klass, 591 const void *data) 592 { 593 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); 594 DeviceClass *dc = DEVICE_CLASS(klass); 595 596 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); 597 598 k->vendor_id = PCI_VENDOR_ID_SYNOPSYS; 599 k->device_id = 0xABCD; 600 k->revision = 0; 601 k->class_id = PCI_CLASS_BRIDGE_PCI; 602 k->exit = pci_bridge_exitfn; 603 k->realize = designware_pcie_root_realize; 604 k->config_read = designware_pcie_root_config_read; 605 k->config_write = designware_pcie_root_config_write; 606 607 device_class_set_legacy_reset(dc, pci_bridge_reset); 608 /* 609 * PCI-facing part of the host bridge, not usable without the 610 * host-facing part, which can't be device_add'ed, yet. 611 */ 612 dc->user_creatable = false; 613 dc->vmsd = &vmstate_designware_pcie_root; 614 } 615 616 static uint64_t designware_pcie_host_mmio_read(void *opaque, hwaddr addr, 617 unsigned int size) 618 { 619 PCIHostState *pci = PCI_HOST_BRIDGE(opaque); 620 PCIDevice *device = pci_find_device(pci->bus, 0, 0); 621 622 return pci_host_config_read_common(device, 623 addr, 624 pci_config_size(device), 625 size); 626 } 627 628 static void designware_pcie_host_mmio_write(void *opaque, hwaddr addr, 629 uint64_t val, unsigned int size) 630 { 631 PCIHostState *pci = PCI_HOST_BRIDGE(opaque); 632 PCIDevice *device = pci_find_device(pci->bus, 0, 0); 633 634 return pci_host_config_write_common(device, 635 addr, 636 pci_config_size(device), 637 val, size); 638 } 639 640 static const MemoryRegionOps designware_pci_mmio_ops = { 641 .read = designware_pcie_host_mmio_read, 642 .write = designware_pcie_host_mmio_write, 643 .endianness = DEVICE_LITTLE_ENDIAN, 644 .impl = { 645 /* 646 * Our device would not work correctly if the guest was doing 647 * unaligned access. This might not be a limitation on the real 648 * device but in practice there is no reason for a guest to access 649 * this device unaligned. 650 */ 651 .min_access_size = 4, 652 .max_access_size = 4, 653 .unaligned = false, 654 }, 655 }; 656 657 static AddressSpace *designware_pcie_host_set_iommu(PCIBus *bus, void *opaque, 658 int devfn) 659 { 660 DesignwarePCIEHost *s = DESIGNWARE_PCIE_HOST(opaque); 661 662 return &s->pci.address_space; 663 } 664 665 static const PCIIOMMUOps designware_iommu_ops = { 666 .get_address_space = designware_pcie_host_set_iommu, 667 }; 668 669 static void designware_pcie_host_realize(DeviceState *dev, Error **errp) 670 { 671 PCIHostState *pci = PCI_HOST_BRIDGE(dev); 672 DesignwarePCIEHost *s = DESIGNWARE_PCIE_HOST(dev); 673 SysBusDevice *sbd = SYS_BUS_DEVICE(dev); 674 size_t i; 675 676 for (i = 0; i < ARRAY_SIZE(s->pci.irqs); i++) { 677 sysbus_init_irq(sbd, &s->pci.irqs[i]); 678 } 679 sysbus_init_irq(sbd, &s->pci.msi); 680 681 memory_region_init_io(&s->mmio, 682 OBJECT(s), 683 &designware_pci_mmio_ops, 684 s, 685 "pcie.reg", 4 * 1024); 686 sysbus_init_mmio(sbd, &s->mmio); 687 688 memory_region_init(&s->pci.io, OBJECT(s), "pcie-pio", 16); 689 memory_region_init(&s->pci.memory, OBJECT(s), 690 "pcie-bus-memory", 691 UINT64_MAX); 692 693 pci->bus = pci_register_root_bus(dev, "pcie", 694 designware_pcie_set_irq, 695 pci_swizzle_map_irq_fn, 696 s, 697 &s->pci.memory, 698 &s->pci.io, 699 0, 4, 700 TYPE_DESIGNWARE_PCIE_ROOT_BUS); 701 pci->bus->flags |= PCI_BUS_EXTENDED_CONFIG_SPACE; 702 703 memory_region_init(&s->pci.address_space_root, 704 OBJECT(s), 705 "pcie-bus-address-space-root", 706 UINT64_MAX); 707 memory_region_add_subregion(&s->pci.address_space_root, 708 0x0, &s->pci.memory); 709 address_space_init(&s->pci.address_space, 710 &s->pci.address_space_root, 711 "pcie-bus-address-space"); 712 pci_setup_iommu(pci->bus, &designware_iommu_ops, s); 713 714 qdev_realize(DEVICE(&s->root), BUS(pci->bus), &error_fatal); 715 } 716 717 static const VMStateDescription vmstate_designware_pcie_host = { 718 .name = "designware-pcie-host", 719 .version_id = 1, 720 .minimum_version_id = 1, 721 .fields = (const VMStateField[]) { 722 VMSTATE_STRUCT(root, 723 DesignwarePCIEHost, 724 1, 725 vmstate_designware_pcie_root, 726 DesignwarePCIERoot), 727 VMSTATE_END_OF_LIST() 728 } 729 }; 730 731 static void designware_pcie_host_class_init(ObjectClass *klass, 732 const void *data) 733 { 734 DeviceClass *dc = DEVICE_CLASS(klass); 735 PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_CLASS(klass); 736 737 hc->root_bus_path = designware_pcie_host_root_bus_path; 738 dc->realize = designware_pcie_host_realize; 739 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); 740 dc->fw_name = "pci"; 741 dc->vmsd = &vmstate_designware_pcie_host; 742 } 743 744 static void designware_pcie_host_init(Object *obj) 745 { 746 DesignwarePCIEHost *s = DESIGNWARE_PCIE_HOST(obj); 747 DesignwarePCIERoot *root = &s->root; 748 749 object_initialize_child(obj, "root", root, TYPE_DESIGNWARE_PCIE_ROOT); 750 qdev_prop_set_int32(DEVICE(root), "addr", PCI_DEVFN(0, 0)); 751 qdev_prop_set_bit(DEVICE(root), "multifunction", false); 752 } 753 754 static const TypeInfo designware_pcie_types[] = { 755 { 756 .name = TYPE_DESIGNWARE_PCIE_ROOT_BUS, 757 .parent = TYPE_PCIE_BUS, 758 .instance_size = sizeof(DesignwarePCIERootBus), 759 .class_init = designware_pcie_root_bus_class_init, 760 }, { 761 .name = TYPE_DESIGNWARE_PCIE_HOST, 762 .parent = TYPE_PCI_HOST_BRIDGE, 763 .instance_size = sizeof(DesignwarePCIEHost), 764 .instance_init = designware_pcie_host_init, 765 .class_init = designware_pcie_host_class_init, 766 }, { 767 .name = TYPE_DESIGNWARE_PCIE_ROOT, 768 .parent = TYPE_PCI_BRIDGE, 769 .instance_size = sizeof(DesignwarePCIERoot), 770 .class_init = designware_pcie_root_class_init, 771 .interfaces = (const InterfaceInfo[]) { 772 { INTERFACE_PCIE_DEVICE }, 773 { } 774 }, 775 }, 776 }; 777 778 DEFINE_TYPES(designware_pcie_types) 779