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