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