1 /* 2 * ASPEED PCIe Host Controller 3 * 4 * Copyright (C) 2025 ASPEED Technology Inc. 5 * Copyright (c) 2022 Cédric Le Goater <clg@kaod.org> 6 * 7 * Jamin Lin <jamin_lin@aspeedtech.com> 8 * 9 * SPDX-License-Identifier: GPL-2.0-or-later 10 * 11 * This file is based on Cédric Le Goater's patch: 12 * "pci: Add Aspeed host bridge (WIP)" 13 * https://github.com/legoater/qemu/commit/d1b97b0c7844219d847122410dc189854f9d26df 14 * 15 * Modifications have been made to support the Aspeed AST2600 and AST2700 16 * platforms. 17 */ 18 19 #include "qemu/osdep.h" 20 #include "qemu/log.h" 21 #include "qapi/error.h" 22 #include "hw/qdev-properties.h" 23 #include "hw/registerfields.h" 24 #include "hw/irq.h" 25 #include "hw/pci/pci_host.h" 26 #include "hw/pci-host/aspeed_pcie.h" 27 #include "hw/pci/msi.h" 28 #include "trace.h" 29 30 /* 31 * PCIe Root 32 */ 33 34 static void aspeed_pcie_root_class_init(ObjectClass *klass, const void *data) 35 { 36 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); 37 DeviceClass *dc = DEVICE_CLASS(klass); 38 39 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); 40 dc->desc = "ASPEED PCIe Host Bridge"; 41 k->vendor_id = PCI_VENDOR_ID_ASPEED; 42 k->device_id = 0x1150; 43 k->class_id = PCI_CLASS_BRIDGE_HOST; 44 k->revision = 0; 45 46 /* 47 * PCI-facing part of the host bridge, 48 * not usable without the host-facing part 49 */ 50 dc->user_creatable = false; 51 } 52 53 static const TypeInfo aspeed_pcie_root_info = { 54 .name = TYPE_ASPEED_PCIE_ROOT, 55 .parent = TYPE_PCI_DEVICE, 56 .instance_size = sizeof(AspeedPCIERootState), 57 .class_init = aspeed_pcie_root_class_init, 58 .interfaces = (const InterfaceInfo[]) { 59 { INTERFACE_CONVENTIONAL_PCI_DEVICE }, 60 { }, 61 }, 62 }; 63 64 /* 65 * PCIe Root Complex (RC) 66 */ 67 68 #define ASPEED_PCIE_CFG_RC_MAX_MSI 64 69 70 static void aspeed_pcie_rc_set_irq(void *opaque, int irq, int level) 71 { 72 AspeedPCIERcState *rc = (AspeedPCIERcState *) opaque; 73 AspeedPCIECfgState *cfg = 74 container_of(rc, AspeedPCIECfgState, rc); 75 AspeedPCIECfgClass *apc = ASPEED_PCIE_CFG_GET_CLASS(cfg); 76 const AspeedPCIERcRegs *rc_regs; 77 bool intx; 78 79 assert(irq < PCI_NUM_PINS); 80 81 rc_regs = &apc->reg_map->rc; 82 83 if (level) { 84 cfg->regs[rc_regs->int_sts_reg] |= BIT(irq); 85 } else { 86 cfg->regs[rc_regs->int_sts_reg] &= ~BIT(irq); 87 } 88 89 intx = !!(cfg->regs[rc_regs->int_sts_reg] & cfg->regs[rc_regs->int_en_reg]); 90 trace_aspeed_pcie_rc_intx_set_irq(cfg->id, irq, intx); 91 qemu_set_irq(rc->irq, intx); 92 } 93 94 static int aspeed_pcie_rc_map_irq(PCIDevice *pci_dev, int irq_num) 95 { 96 return irq_num % PCI_NUM_PINS; 97 } 98 99 static void aspeed_pcie_rc_msi_notify(AspeedPCIERcState *rc, uint64_t data) 100 { 101 AspeedPCIECfgState *cfg = 102 container_of(rc, AspeedPCIECfgState, rc); 103 AspeedPCIECfgClass *apc = ASPEED_PCIE_CFG_GET_CLASS(cfg); 104 const AspeedPCIERcRegs *rc_regs; 105 uint32_t reg; 106 107 /* Written data is the HW IRQ number */ 108 assert(data < ASPEED_PCIE_CFG_RC_MAX_MSI); 109 110 rc_regs = &apc->reg_map->rc; 111 112 reg = (data < 32) ? rc_regs->msi_sts0_reg : rc_regs->msi_sts1_reg; 113 cfg->regs[reg] |= BIT(data % 32); 114 115 trace_aspeed_pcie_rc_msi_set_irq(cfg->id, data, 1); 116 qemu_set_irq(rc->irq, 1); 117 } 118 119 static void aspeed_pcie_rc_msi_write(void *opaque, hwaddr addr, uint64_t data, 120 unsigned int size) 121 { 122 AspeedPCIERcState *rc = ASPEED_PCIE_RC(opaque); 123 AspeedPCIECfgState *cfg = 124 container_of(rc, AspeedPCIECfgState, rc); 125 126 trace_aspeed_pcie_rc_msi_notify(cfg->id, addr + rc->msi_addr, data); 127 aspeed_pcie_rc_msi_notify(rc, data); 128 } 129 130 static const MemoryRegionOps aspeed_pcie_rc_msi_ops = { 131 .write = aspeed_pcie_rc_msi_write, 132 .read = NULL, 133 .endianness = DEVICE_LITTLE_ENDIAN, 134 .valid = { 135 .min_access_size = 4, 136 .max_access_size = 4, 137 }, 138 .impl = { 139 .min_access_size = 4, 140 .max_access_size = 4, 141 }, 142 }; 143 144 static AddressSpace *aspeed_pcie_rc_get_as(PCIBus *bus, void *opaque, int devfn) 145 { 146 AspeedPCIERcState *rc = ASPEED_PCIE_RC(opaque); 147 return &rc->iommu_as; 148 } 149 150 static const PCIIOMMUOps aspeed_pcie_rc_iommu_ops = { 151 .get_address_space = aspeed_pcie_rc_get_as, 152 }; 153 154 static void aspeed_pcie_rc_realize(DeviceState *dev, Error **errp) 155 { 156 PCIExpressHost *pex = PCIE_HOST_BRIDGE(dev); 157 AspeedPCIERcState *rc = ASPEED_PCIE_RC(dev); 158 AspeedPCIECfgState *cfg = 159 container_of(rc, AspeedPCIECfgState, rc); 160 PCIHostState *pci = PCI_HOST_BRIDGE(dev); 161 SysBusDevice *sbd = SYS_BUS_DEVICE(dev); 162 g_autofree char *name; 163 164 /* PCI configuration space */ 165 pcie_host_mmcfg_init(pex, PCIE_MMCFG_SIZE_MAX); 166 sysbus_init_mmio(sbd, &pex->mmio); 167 168 /* MMIO and IO region */ 169 memory_region_init(&rc->mmio, OBJECT(rc), "mmio", UINT64_MAX); 170 memory_region_init(&rc->io, OBJECT(rc), "io", 0x10000); 171 172 name = g_strdup_printf("pcie.%d.mmio_window", cfg->id); 173 memory_region_init_io(&rc->mmio_window, OBJECT(rc), &unassigned_io_ops, 174 OBJECT(rc), name, UINT64_MAX); 175 name = g_strdup_printf("pcie.%d.ioport_window", cfg->id); 176 memory_region_init_io(&rc->io_window, OBJECT(rc), &unassigned_io_ops, 177 OBJECT(rc), name, 0x10000); 178 179 memory_region_add_subregion(&rc->mmio_window, 0, &rc->mmio); 180 memory_region_add_subregion(&rc->io_window, 0, &rc->io); 181 sysbus_init_mmio(sbd, &rc->mmio_window); 182 sysbus_init_mmio(sbd, &rc->io_window); 183 184 sysbus_init_irq(sbd, &rc->irq); 185 pci->bus = pci_register_root_bus(dev, NULL, aspeed_pcie_rc_set_irq, 186 aspeed_pcie_rc_map_irq, rc, &rc->mmio, 187 &rc->io, 0, 4, TYPE_PCIE_BUS); 188 pci->bus->flags |= PCI_BUS_EXTENDED_CONFIG_SPACE; 189 190 /* 191 * PCIe memory view setup 192 * 193 * Background: 194 * - On AST2700, all Root Complexes use the same MSI address. This MSI 195 * address is not normal system RAM - it is a PCI system memory address. 196 * If we map the MSI/MSI-X window into real system memory, a write from 197 * one EP can be seen by all RCs and wrongly trigger interrupts on them. 198 * 199 * Design: 200 * - MSI/MSI-X here is just a placeholder address so RC and EP can talk. 201 * We make a separate MMIO space (iommu_root) for the MSI window so the 202 * writes stay local to each RC. 203 * 204 * DMA: 205 * - EPs still need access to real system memory for DMA. We add a DRAM 206 * alias in the PCI space so DMA works as expected. 207 */ 208 name = g_strdup_printf("pcie.%d.iommu_root", cfg->id); 209 memory_region_init(&rc->iommu_root, OBJECT(rc), name, UINT64_MAX); 210 address_space_init(&rc->iommu_as, &rc->iommu_root, name); 211 /* setup MSI */ 212 memory_region_init_io(&rc->msi_window, OBJECT(rc), 213 &aspeed_pcie_rc_msi_ops, rc, 214 "msi_window", 4); 215 memory_region_add_subregion(&rc->iommu_root, rc->msi_addr, 216 &rc->msi_window); 217 /* setup DRAM for DMA */ 218 assert(rc->dram_mr != NULL); 219 name = g_strdup_printf("pcie.%d.dram_alias", cfg->id); 220 memory_region_init_alias(&rc->dram_alias, OBJECT(rc), name, rc->dram_mr, 221 0, memory_region_size(rc->dram_mr)); 222 memory_region_add_subregion(&rc->iommu_root, rc->dram_base, 223 &rc->dram_alias); 224 pci_setup_iommu(pci->bus, &aspeed_pcie_rc_iommu_ops, rc); 225 226 qdev_realize(DEVICE(&rc->root), BUS(pci->bus), &error_fatal); 227 } 228 229 static const char *aspeed_pcie_rc_root_bus_path(PCIHostState *host_bridge, 230 PCIBus *rootbus) 231 { 232 AspeedPCIERcState *s = ASPEED_PCIE_RC(host_bridge); 233 234 snprintf(s->name, sizeof(s->name), "0000:%02x", s->bus_nr); 235 236 return s->name; 237 } 238 239 static void aspeed_pcie_rc_instance_init(Object *obj) 240 { 241 AspeedPCIERcState *s = ASPEED_PCIE_RC(obj); 242 AspeedPCIERootState *root = &s->root; 243 244 object_initialize_child(obj, "root", root, TYPE_ASPEED_PCIE_ROOT); 245 qdev_prop_set_int32(DEVICE(root), "addr", PCI_DEVFN(0, 0)); 246 qdev_prop_set_bit(DEVICE(root), "multifunction", false); 247 } 248 249 static const Property aspeed_pcie_rc_props[] = { 250 DEFINE_PROP_UINT32("bus-nr", AspeedPCIERcState, bus_nr, 0), 251 DEFINE_PROP_UINT32("msi-addr", AspeedPCIERcState, msi_addr, 0), 252 DEFINE_PROP_UINT64("dram-base", AspeedPCIERcState, dram_base, 0), 253 DEFINE_PROP_LINK("dram", AspeedPCIERcState, dram_mr, TYPE_MEMORY_REGION, 254 MemoryRegion *), 255 }; 256 257 static void aspeed_pcie_rc_class_init(ObjectClass *klass, const void *data) 258 { 259 PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_CLASS(klass); 260 DeviceClass *dc = DEVICE_CLASS(klass); 261 262 dc->desc = "ASPEED PCIe RC"; 263 dc->realize = aspeed_pcie_rc_realize; 264 dc->fw_name = "pci"; 265 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); 266 267 hc->root_bus_path = aspeed_pcie_rc_root_bus_path; 268 device_class_set_props(dc, aspeed_pcie_rc_props); 269 270 msi_nonbroken = true; 271 } 272 273 static const TypeInfo aspeed_pcie_rc_info = { 274 .name = TYPE_ASPEED_PCIE_RC, 275 .parent = TYPE_PCIE_HOST_BRIDGE, 276 .instance_size = sizeof(AspeedPCIERcState), 277 .instance_init = aspeed_pcie_rc_instance_init, 278 .class_init = aspeed_pcie_rc_class_init, 279 }; 280 281 /* 282 * PCIe Config 283 * 284 * AHB to PCIe Bus Bridge (H2X) 285 * 286 * On the AST2600: 287 * NOTE: rc_l is not supported by this model. 288 * - Registers 0x00 - 0x7F are shared by both PCIe0 (rc_l) and PCIe1 (rc_h). 289 * - Registers 0x80 - 0xBF are specific to PCIe0. 290 * - Registers 0xC0 - 0xFF are specific to PCIe1. 291 * 292 * On the AST2700: 293 * - The register range 0x00 - 0xFF is assigned to a single PCIe configuration. 294 * - There are three PCIe Root Complexes (RCs), each with its own dedicated H2X 295 * register set of size 0x100 (covering offsets 0x00 to 0xFF). 296 */ 297 298 /* AST2600 */ 299 REG32(H2X_CTRL, 0x00) 300 FIELD(H2X_CTRL, CLEAR_RX, 4, 1) 301 REG32(H2X_TX_CLEAR, 0x08) 302 FIELD(H2X_TX_CLEAR, IDLE, 0, 1) 303 REG32(H2X_RDATA, 0x0C) 304 REG32(H2X_TX_DESC0, 0x10) 305 REG32(H2X_TX_DESC1, 0x14) 306 REG32(H2X_TX_DESC2, 0x18) 307 REG32(H2X_TX_DESC3, 0x1C) 308 REG32(H2X_TX_DATA, 0x20) 309 REG32(H2X_TX_STS, 0x24) 310 FIELD(H2X_TX_STS, IDLE, 31, 1) 311 FIELD(H2X_TX_STS, RC_L_TX_COMP, 24, 1) 312 FIELD(H2X_TX_STS, RC_H_TX_COMP, 25, 1) 313 FIELD(H2X_TX_STS, TRIG, 0, 1) 314 REG32(H2X_RC_H_CTRL, 0xC0) 315 REG32(H2X_RC_H_INT_EN, 0xC4) 316 REG32(H2X_RC_H_INT_STS, 0xC8) 317 SHARED_FIELD(H2X_RC_INT_INTDONE, 4, 1) 318 SHARED_FIELD(H2X_RC_INT_INTX, 0, 4) 319 REG32(H2X_RC_H_RDATA, 0xCC) 320 REG32(H2X_RC_H_MSI_EN0, 0xE0) 321 REG32(H2X_RC_H_MSI_EN1, 0xE4) 322 REG32(H2X_RC_H_MSI_STS0, 0xE8) 323 REG32(H2X_RC_H_MSI_STS1, 0xEC) 324 325 /* AST2700 */ 326 REG32(H2X_CFGE_INT_STS, 0x08) 327 FIELD(H2X_CFGE_INT_STS, TX_IDEL, 0, 1) 328 FIELD(H2X_CFGE_INT_STS, RX_BUSY, 1, 1) 329 REG32(H2X_CFGI_TLP, 0x20) 330 FIELD(H2X_CFGI_TLP, ADDR, 0, 16) 331 FIELD(H2X_CFGI_TLP, BEN, 16, 4) 332 FIELD(H2X_CFGI_TLP, WR, 20, 1) 333 REG32(H2X_CFGI_WDATA, 0x24) 334 REG32(H2X_CFGI_CTRL, 0x28) 335 FIELD(H2X_CFGI_CTRL, FIRE, 0, 1) 336 REG32(H2X_CFGI_RDATA, 0x2C) 337 REG32(H2X_CFGE_TLP1, 0x30) 338 REG32(H2X_CFGE_TLPN, 0x34) 339 REG32(H2X_CFGE_CTRL, 0x38) 340 FIELD(H2X_CFGE_CTRL, FIRE, 0, 1) 341 REG32(H2X_CFGE_RDATA, 0x3C) 342 REG32(H2X_INT_EN, 0x40) 343 REG32(H2X_INT_STS, 0x48) 344 FIELD(H2X_INT_STS, INTX, 0, 4) 345 REG32(H2X_MSI_EN0, 0x50) 346 REG32(H2X_MSI_EN1, 0x54) 347 REG32(H2X_MSI_STS0, 0x58) 348 REG32(H2X_MSI_STS1, 0x5C) 349 350 #define TLP_FMTTYPE_CFGRD0 0x04 /* Configuration Read Type 0 */ 351 #define TLP_FMTTYPE_CFGWR0 0x44 /* Configuration Write Type 0 */ 352 #define TLP_FMTTYPE_CFGRD1 0x05 /* Configuration Read Type 1 */ 353 #define TLP_FMTTYPE_CFGWR1 0x45 /* Configuration Write Type 1 */ 354 355 #define PCIE_CFG_FMTTYPE_MASK(x) (((x) >> 24) & 0xff) 356 #define PCIE_CFG_BYTE_EN(x) ((x) & 0xf) 357 358 static const AspeedPCIERegMap aspeed_regmap = { 359 .rc = { 360 .int_en_reg = R_H2X_RC_H_INT_EN, 361 .int_sts_reg = R_H2X_RC_H_INT_STS, 362 .msi_sts0_reg = R_H2X_RC_H_MSI_STS0, 363 .msi_sts1_reg = R_H2X_RC_H_MSI_STS1, 364 }, 365 }; 366 367 static const AspeedPCIERegMap aspeed_2700_regmap = { 368 .rc = { 369 .int_en_reg = R_H2X_INT_EN, 370 .int_sts_reg = R_H2X_INT_STS, 371 .msi_sts0_reg = R_H2X_MSI_STS0, 372 .msi_sts1_reg = R_H2X_MSI_STS1, 373 }, 374 }; 375 376 static uint64_t aspeed_pcie_cfg_read(void *opaque, hwaddr addr, 377 unsigned int size) 378 { 379 AspeedPCIECfgState *s = ASPEED_PCIE_CFG(opaque); 380 uint32_t reg = addr >> 2; 381 uint32_t value = 0; 382 383 value = s->regs[reg]; 384 385 trace_aspeed_pcie_cfg_read(s->id, addr, value); 386 387 return value; 388 } 389 390 static void aspeed_pcie_cfg_translate_write(uint8_t byte_en, uint32_t *addr, 391 uint64_t *val, int *len) 392 { 393 uint64_t packed_val = 0; 394 int first_bit = -1; 395 int index = 0; 396 int i; 397 398 *len = ctpop8(byte_en); 399 400 if (*len == 0 || *len > 4) { 401 goto err; 402 } 403 404 /* Special case: full 4-byte write must be 4-byte aligned */ 405 if (byte_en == 0x0f) { 406 if (*addr % 4 != 0) { 407 goto err; 408 } 409 *val = *val & 0xffffffff; 410 return; 411 } 412 413 for (i = 0; i < 4; i++) { 414 if (byte_en & (1 << i)) { 415 if (first_bit < 0) { 416 first_bit = i; 417 } 418 packed_val |= ((*val >> (i * 8)) & 0xff) << (index * 8); 419 index++; 420 } 421 } 422 423 *addr += first_bit; 424 *val = packed_val; 425 426 return; 427 428 err: 429 qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid byte enable: 0x%x\n", 430 __func__, byte_en); 431 } 432 433 static void aspeed_pcie_cfg_readwrite(AspeedPCIECfgState *s, 434 const AspeedPCIECfgTxDesc *desc) 435 { 436 AspeedPCIERcState *rc = &s->rc; 437 PCIHostState *pci; 438 uint32_t cfg_addr; 439 PCIDevice *pdev; 440 uint32_t offset; 441 uint8_t byte_en; 442 bool is_write; 443 uint8_t devfn; 444 uint64_t val; 445 uint8_t bus; 446 int len; 447 448 val = ~0; 449 is_write = !!(desc->desc0 & BIT(30)); 450 cfg_addr = desc->desc2; 451 452 bus = (cfg_addr >> 24) & 0xff; 453 devfn = (cfg_addr >> 16) & 0xff; 454 offset = cfg_addr & 0xffc; 455 456 pci = PCI_HOST_BRIDGE(rc); 457 458 /* 459 * On the AST2600, the RC_H bus number ranges from 0x80 to 0xFF, and its 460 * root port uses bus number 0x80 instead of the standard 0x00. To locate 461 * the device at root port 0, remap bus number 0x80 to 0x00 so that the 462 * PCI subsystem can correctly discover the devices. 463 */ 464 if (bus == rc->bus_nr) { 465 bus = 0; 466 } 467 468 pdev = pci_find_device(pci->bus, bus, devfn); 469 if (!pdev) { 470 s->regs[desc->rdata_reg] = ~0; 471 goto out; 472 } 473 474 switch (PCIE_CFG_FMTTYPE_MASK(desc->desc0)) { 475 case TLP_FMTTYPE_CFGWR0: 476 case TLP_FMTTYPE_CFGWR1: 477 byte_en = PCIE_CFG_BYTE_EN(desc->desc1); 478 val = desc->wdata; 479 aspeed_pcie_cfg_translate_write(byte_en, &offset, &val, &len); 480 pci_host_config_write_common(pdev, offset, pci_config_size(pdev), 481 val, len); 482 break; 483 case TLP_FMTTYPE_CFGRD0: 484 case TLP_FMTTYPE_CFGRD1: 485 val = pci_host_config_read_common(pdev, offset, 486 pci_config_size(pdev), 4); 487 s->regs[desc->rdata_reg] = val; 488 break; 489 default: 490 qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid CFG type. DESC0=0x%x\n", 491 __func__, desc->desc0); 492 } 493 494 out: 495 trace_aspeed_pcie_cfg_rw(s->id, is_write ? "write" : "read", bus, devfn, 496 cfg_addr, val); 497 } 498 499 static void aspeed_pcie_cfg_write(void *opaque, hwaddr addr, uint64_t data, 500 unsigned int size) 501 { 502 AspeedPCIECfgState *s = ASPEED_PCIE_CFG(opaque); 503 AspeedPCIECfgClass *apc = ASPEED_PCIE_CFG_GET_CLASS(s); 504 AspeedPCIECfgTxDesc desc; 505 uint32_t reg = addr >> 2; 506 uint32_t rc_reg; 507 508 trace_aspeed_pcie_cfg_write(s->id, addr, data); 509 510 switch (reg) { 511 case R_H2X_CTRL: 512 if (data & R_H2X_CTRL_CLEAR_RX_MASK) { 513 s->regs[R_H2X_RDATA] = ~0; 514 } 515 break; 516 case R_H2X_TX_CLEAR: 517 if (data & R_H2X_TX_CLEAR_IDLE_MASK) { 518 s->regs[R_H2X_TX_STS] &= ~R_H2X_TX_STS_IDLE_MASK; 519 } 520 break; 521 case R_H2X_TX_STS: 522 if (data & R_H2X_TX_STS_TRIG_MASK) { 523 desc.desc0 = s->regs[R_H2X_TX_DESC0]; 524 desc.desc1 = s->regs[R_H2X_TX_DESC1]; 525 desc.desc2 = s->regs[R_H2X_TX_DESC2]; 526 desc.desc3 = s->regs[R_H2X_TX_DESC3]; 527 desc.wdata = s->regs[R_H2X_TX_DATA]; 528 desc.rdata_reg = R_H2X_RC_H_RDATA; 529 aspeed_pcie_cfg_readwrite(s, &desc); 530 rc_reg = apc->reg_map->rc.int_sts_reg; 531 s->regs[rc_reg] |= H2X_RC_INT_INTDONE_MASK; 532 s->regs[R_H2X_TX_STS] |= 533 BIT(R_H2X_TX_STS_RC_H_TX_COMP_SHIFT); 534 s->regs[R_H2X_TX_STS] |= R_H2X_TX_STS_IDLE_MASK; 535 } 536 break; 537 /* preserve INTx status */ 538 case R_H2X_RC_H_INT_STS: 539 if (data & H2X_RC_INT_INTDONE_MASK) { 540 s->regs[R_H2X_TX_STS] &= ~R_H2X_TX_STS_RC_H_TX_COMP_MASK; 541 } 542 s->regs[reg] &= ~data | H2X_RC_INT_INTX_MASK; 543 break; 544 /* 545 * These status registers are used for notify sources ISR are executed. 546 * If one source ISR is executed, it will clear one bit. 547 * If it clear all bits, it means to initialize this register status 548 * rather than sources ISR are executed. 549 */ 550 case R_H2X_RC_H_MSI_STS0: 551 case R_H2X_RC_H_MSI_STS1: 552 if (data == 0) { 553 return ; 554 } 555 556 s->regs[reg] &= ~data; 557 if (data == 0xffffffff) { 558 return; 559 } 560 561 if (!s->regs[R_H2X_RC_H_MSI_STS0] && 562 !s->regs[R_H2X_RC_H_MSI_STS1]) { 563 trace_aspeed_pcie_rc_msi_clear_irq(s->id, 0); 564 qemu_set_irq(s->rc.irq, 0); 565 } 566 break; 567 default: 568 s->regs[reg] = data; 569 break; 570 } 571 } 572 573 static const MemoryRegionOps aspeed_pcie_cfg_ops = { 574 .read = aspeed_pcie_cfg_read, 575 .write = aspeed_pcie_cfg_write, 576 .endianness = DEVICE_LITTLE_ENDIAN, 577 .valid = { 578 .min_access_size = 1, 579 .max_access_size = 4, 580 }, 581 }; 582 583 static void aspeed_pcie_cfg_instance_init(Object *obj) 584 { 585 AspeedPCIECfgState *s = ASPEED_PCIE_CFG(obj); 586 587 object_initialize_child(obj, "rc", &s->rc, TYPE_ASPEED_PCIE_RC); 588 object_property_add_alias(obj, "dram", OBJECT(&s->rc), "dram"); 589 object_property_add_alias(obj, "dram-base", OBJECT(&s->rc), "dram-base"); 590 591 return; 592 } 593 594 static void aspeed_pcie_cfg_reset(DeviceState *dev) 595 { 596 AspeedPCIECfgState *s = ASPEED_PCIE_CFG(dev); 597 AspeedPCIECfgClass *apc = ASPEED_PCIE_CFG_GET_CLASS(s); 598 599 memset(s->regs, 0, apc->nr_regs << 2); 600 memset(s->tlpn_fifo, 0, sizeof(s->tlpn_fifo)); 601 s->tlpn_idx = 0; 602 } 603 604 static void aspeed_pcie_cfg_realize(DeviceState *dev, Error **errp) 605 { 606 SysBusDevice *sbd = SYS_BUS_DEVICE(dev); 607 AspeedPCIECfgState *s = ASPEED_PCIE_CFG(dev); 608 AspeedPCIECfgClass *apc = ASPEED_PCIE_CFG_GET_CLASS(s); 609 g_autofree char *name; 610 611 s->regs = g_new(uint32_t, apc->nr_regs); 612 name = g_strdup_printf(TYPE_ASPEED_PCIE_CFG ".regs.%d", s->id); 613 memory_region_init_io(&s->mmio, OBJECT(s), apc->reg_ops, s, name, 614 apc->nr_regs << 2); 615 sysbus_init_mmio(sbd, &s->mmio); 616 617 object_property_set_int(OBJECT(&s->rc), "bus-nr", 618 apc->rc_bus_nr, 619 &error_abort); 620 object_property_set_int(OBJECT(&s->rc), "msi-addr", 621 apc->rc_msi_addr, 622 &error_abort); 623 if (!sysbus_realize(SYS_BUS_DEVICE(&s->rc), errp)) { 624 return; 625 } 626 } 627 628 static void aspeed_pcie_cfg_unrealize(DeviceState *dev) 629 { 630 AspeedPCIECfgState *s = ASPEED_PCIE_CFG(dev); 631 632 g_free(s->regs); 633 s->regs = NULL; 634 } 635 636 static const Property aspeed_pcie_cfg_props[] = { 637 DEFINE_PROP_UINT32("id", AspeedPCIECfgState, id, 0), 638 }; 639 640 static void aspeed_pcie_cfg_class_init(ObjectClass *klass, const void *data) 641 { 642 DeviceClass *dc = DEVICE_CLASS(klass); 643 AspeedPCIECfgClass *apc = ASPEED_PCIE_CFG_CLASS(klass); 644 645 dc->desc = "ASPEED PCIe Config"; 646 dc->realize = aspeed_pcie_cfg_realize; 647 dc->unrealize = aspeed_pcie_cfg_unrealize; 648 device_class_set_legacy_reset(dc, aspeed_pcie_cfg_reset); 649 device_class_set_props(dc, aspeed_pcie_cfg_props); 650 651 apc->reg_ops = &aspeed_pcie_cfg_ops; 652 apc->reg_map = &aspeed_regmap; 653 apc->nr_regs = 0x100 >> 2; 654 apc->rc_msi_addr = 0x1e77005C; 655 apc->rc_bus_nr = 0x80; 656 } 657 658 static const TypeInfo aspeed_pcie_cfg_info = { 659 .name = TYPE_ASPEED_PCIE_CFG, 660 .parent = TYPE_SYS_BUS_DEVICE, 661 .instance_init = aspeed_pcie_cfg_instance_init, 662 .instance_size = sizeof(AspeedPCIECfgState), 663 .class_init = aspeed_pcie_cfg_class_init, 664 .class_size = sizeof(AspeedPCIECfgClass), 665 }; 666 667 static void aspeed_2700_pcie_cfg_write(void *opaque, hwaddr addr, 668 uint64_t data, unsigned int size) 669 { 670 AspeedPCIECfgState *s = ASPEED_PCIE_CFG(opaque); 671 AspeedPCIECfgTxDesc desc; 672 uint32_t reg = addr >> 2; 673 674 trace_aspeed_pcie_cfg_write(s->id, addr, data); 675 676 switch (reg) { 677 case R_H2X_CFGE_INT_STS: 678 if (data & R_H2X_CFGE_INT_STS_TX_IDEL_MASK) { 679 s->regs[R_H2X_CFGE_INT_STS] &= ~R_H2X_CFGE_INT_STS_TX_IDEL_MASK; 680 } 681 682 if (data & R_H2X_CFGE_INT_STS_RX_BUSY_MASK) { 683 s->regs[R_H2X_CFGE_INT_STS] &= ~R_H2X_CFGE_INT_STS_RX_BUSY_MASK; 684 } 685 break; 686 case R_H2X_CFGI_CTRL: 687 if (data & R_H2X_CFGI_CTRL_FIRE_MASK) { 688 /* 689 * Internal access to bridge 690 * Type and BDF are 0 691 */ 692 desc.desc0 = 0x04000001 | 693 (ARRAY_FIELD_EX32(s->regs, H2X_CFGI_TLP, WR) << 30); 694 desc.desc1 = 0x00401000 | 695 ARRAY_FIELD_EX32(s->regs, H2X_CFGI_TLP, BEN); 696 desc.desc2 = 0x00000000 | 697 ARRAY_FIELD_EX32(s->regs, H2X_CFGI_TLP, ADDR); 698 desc.wdata = s->regs[R_H2X_CFGI_WDATA]; 699 desc.rdata_reg = R_H2X_CFGI_RDATA; 700 aspeed_pcie_cfg_readwrite(s, &desc); 701 } 702 break; 703 case R_H2X_CFGE_TLPN: 704 s->tlpn_fifo[s->tlpn_idx] = data; 705 s->tlpn_idx = (s->tlpn_idx + 1) % ARRAY_SIZE(s->tlpn_fifo); 706 break; 707 case R_H2X_CFGE_CTRL: 708 if (data & R_H2X_CFGE_CTRL_FIRE_MASK) { 709 desc.desc0 = s->regs[R_H2X_CFGE_TLP1]; 710 desc.desc1 = s->tlpn_fifo[0]; 711 desc.desc2 = s->tlpn_fifo[1]; 712 desc.wdata = s->tlpn_fifo[2]; 713 desc.rdata_reg = R_H2X_CFGE_RDATA; 714 aspeed_pcie_cfg_readwrite(s, &desc); 715 s->regs[R_H2X_CFGE_INT_STS] |= R_H2X_CFGE_INT_STS_TX_IDEL_MASK; 716 s->regs[R_H2X_CFGE_INT_STS] |= R_H2X_CFGE_INT_STS_RX_BUSY_MASK; 717 s->tlpn_idx = 0; 718 } 719 break; 720 721 case R_H2X_INT_STS: 722 s->regs[reg] &= ~data | R_H2X_INT_STS_INTX_MASK; 723 break; 724 /* 725 * These status registers are used for notify sources ISR are executed. 726 * If one source ISR is executed, it will clear one bit. 727 * If it clear all bits, it means to initialize this register status 728 * rather than sources ISR are executed. 729 */ 730 case R_H2X_MSI_STS0: 731 case R_H2X_MSI_STS1: 732 if (data == 0) { 733 return ; 734 } 735 736 s->regs[reg] &= ~data; 737 if (data == 0xffffffff) { 738 return; 739 } 740 741 if (!s->regs[R_H2X_MSI_STS0] && 742 !s->regs[R_H2X_MSI_STS1]) { 743 trace_aspeed_pcie_rc_msi_clear_irq(s->id, 0); 744 qemu_set_irq(s->rc.irq, 0); 745 } 746 break; 747 default: 748 s->regs[reg] = data; 749 break; 750 } 751 } 752 753 static const MemoryRegionOps aspeed_2700_pcie_cfg_ops = { 754 .read = aspeed_pcie_cfg_read, 755 .write = aspeed_2700_pcie_cfg_write, 756 .endianness = DEVICE_LITTLE_ENDIAN, 757 .valid = { 758 .min_access_size = 1, 759 .max_access_size = 4, 760 }, 761 }; 762 763 static void aspeed_2700_pcie_cfg_class_init(ObjectClass *klass, 764 const void *data) 765 { 766 DeviceClass *dc = DEVICE_CLASS(klass); 767 AspeedPCIECfgClass *apc = ASPEED_PCIE_CFG_CLASS(klass); 768 769 dc->desc = "ASPEED 2700 PCIe Config"; 770 apc->reg_ops = &aspeed_2700_pcie_cfg_ops; 771 apc->reg_map = &aspeed_2700_regmap; 772 apc->nr_regs = 0x100 >> 2; 773 apc->rc_msi_addr = 0x000000F0; 774 apc->rc_bus_nr = 0; 775 } 776 777 static const TypeInfo aspeed_2700_pcie_cfg_info = { 778 .name = TYPE_ASPEED_2700_PCIE_CFG, 779 .parent = TYPE_ASPEED_PCIE_CFG, 780 .class_init = aspeed_2700_pcie_cfg_class_init, 781 }; 782 783 /* 784 * PCIe PHY 785 * 786 * PCIe Host Controller (PCIEH) 787 */ 788 789 /* AST2600 */ 790 REG32(PEHR_ID, 0x00) 791 FIELD(PEHR_ID, DEV, 16, 16) 792 REG32(PEHR_CLASS_CODE, 0x04) 793 REG32(PEHR_DATALINK, 0x10) 794 REG32(PEHR_PROTECT, 0x7C) 795 FIELD(PEHR_PROTECT, LOCK, 0, 8) 796 REG32(PEHR_LINK, 0xC0) 797 FIELD(PEHR_LINK, STS, 5, 1) 798 799 /* AST2700 */ 800 REG32(PEHR_2700_LINK_GEN2, 0x344) 801 FIELD(PEHR_2700_LINK_GEN2, STS, 18, 1) 802 REG32(PEHR_2700_LINK_GEN4, 0x358) 803 FIELD(PEHR_2700_LINK_GEN4, STS, 8, 1) 804 805 #define ASPEED_PCIE_PHY_UNLOCK 0xA8 806 807 static uint64_t aspeed_pcie_phy_read(void *opaque, hwaddr addr, 808 unsigned int size) 809 { 810 AspeedPCIEPhyState *s = ASPEED_PCIE_PHY(opaque); 811 uint32_t reg = addr >> 2; 812 uint32_t value = 0; 813 814 value = s->regs[reg]; 815 816 trace_aspeed_pcie_phy_read(s->id, addr, value); 817 818 return value; 819 } 820 821 static void aspeed_pcie_phy_write(void *opaque, hwaddr addr, uint64_t data, 822 unsigned int size) 823 { 824 AspeedPCIEPhyState *s = ASPEED_PCIE_PHY(opaque); 825 uint32_t reg = addr >> 2; 826 827 trace_aspeed_pcie_phy_write(s->id, addr, data); 828 829 switch (reg) { 830 case R_PEHR_PROTECT: 831 data &= R_PEHR_PROTECT_LOCK_MASK; 832 s->regs[reg] = !!(data == ASPEED_PCIE_PHY_UNLOCK); 833 break; 834 default: 835 s->regs[reg] = data; 836 break; 837 } 838 } 839 840 static const MemoryRegionOps aspeed_pcie_phy_ops = { 841 .read = aspeed_pcie_phy_read, 842 .write = aspeed_pcie_phy_write, 843 .endianness = DEVICE_LITTLE_ENDIAN, 844 .valid = { 845 .min_access_size = 1, 846 .max_access_size = 4, 847 }, 848 }; 849 850 static void aspeed_pcie_phy_reset(DeviceState *dev) 851 { 852 AspeedPCIEPhyState *s = ASPEED_PCIE_PHY(dev); 853 AspeedPCIEPhyClass *apc = ASPEED_PCIE_PHY_GET_CLASS(s); 854 855 memset(s->regs, 0, apc->nr_regs << 2); 856 857 s->regs[R_PEHR_ID] = 858 (0x1150 << R_PEHR_ID_DEV_SHIFT) | PCI_VENDOR_ID_ASPEED; 859 s->regs[R_PEHR_CLASS_CODE] = 0x06040006; 860 s->regs[R_PEHR_DATALINK] = 0xD7040022; 861 s->regs[R_PEHR_LINK] = R_PEHR_LINK_STS_MASK; 862 } 863 864 static void aspeed_pcie_phy_realize(DeviceState *dev, Error **errp) 865 { 866 AspeedPCIEPhyState *s = ASPEED_PCIE_PHY(dev); 867 AspeedPCIEPhyClass *apc = ASPEED_PCIE_PHY_GET_CLASS(s); 868 SysBusDevice *sbd = SYS_BUS_DEVICE(dev); 869 g_autofree char *name; 870 871 s->regs = g_new(uint32_t, apc->nr_regs); 872 name = g_strdup_printf(TYPE_ASPEED_PCIE_PHY ".regs.%d", s->id); 873 memory_region_init_io(&s->mmio, OBJECT(s), &aspeed_pcie_phy_ops, s, name, 874 apc->nr_regs << 2); 875 sysbus_init_mmio(sbd, &s->mmio); 876 } 877 878 static void aspeed_pcie_phy_unrealize(DeviceState *dev) 879 { 880 AspeedPCIEPhyState *s = ASPEED_PCIE_PHY(dev); 881 882 g_free(s->regs); 883 s->regs = NULL; 884 } 885 886 static const Property aspeed_pcie_phy_props[] = { 887 DEFINE_PROP_UINT32("id", AspeedPCIEPhyState, id, 0), 888 }; 889 890 static void aspeed_pcie_phy_class_init(ObjectClass *klass, const void *data) 891 { 892 DeviceClass *dc = DEVICE_CLASS(klass); 893 AspeedPCIEPhyClass *apc = ASPEED_PCIE_PHY_CLASS(klass); 894 895 dc->desc = "ASPEED PCIe Phy"; 896 dc->realize = aspeed_pcie_phy_realize; 897 dc->unrealize = aspeed_pcie_phy_unrealize; 898 device_class_set_legacy_reset(dc, aspeed_pcie_phy_reset); 899 device_class_set_props(dc, aspeed_pcie_phy_props); 900 901 apc->nr_regs = 0x100 >> 2; 902 } 903 904 static const TypeInfo aspeed_pcie_phy_info = { 905 .name = TYPE_ASPEED_PCIE_PHY, 906 .parent = TYPE_SYS_BUS_DEVICE, 907 .instance_size = sizeof(AspeedPCIEPhyState), 908 .class_init = aspeed_pcie_phy_class_init, 909 .class_size = sizeof(AspeedPCIEPhyClass), 910 }; 911 912 static void aspeed_2700_pcie_phy_reset(DeviceState *dev) 913 { 914 AspeedPCIEPhyState *s = ASPEED_PCIE_PHY(dev); 915 AspeedPCIEPhyClass *apc = ASPEED_PCIE_PHY_GET_CLASS(s); 916 917 memset(s->regs, 0, apc->nr_regs << 2); 918 919 s->regs[R_PEHR_ID] = 920 (0x1150 << R_PEHR_ID_DEV_SHIFT) | PCI_VENDOR_ID_ASPEED; 921 s->regs[R_PEHR_CLASS_CODE] = 0x06040011; 922 s->regs[R_PEHR_2700_LINK_GEN2] = R_PEHR_2700_LINK_GEN2_STS_MASK; 923 s->regs[R_PEHR_2700_LINK_GEN4] = R_PEHR_2700_LINK_GEN4_STS_MASK; 924 } 925 926 static void aspeed_2700_pcie_phy_class_init(ObjectClass *klass, 927 const void *data) 928 { 929 DeviceClass *dc = DEVICE_CLASS(klass); 930 AspeedPCIEPhyClass *apc = ASPEED_PCIE_PHY_CLASS(klass); 931 932 dc->desc = "ASPEED AST2700 PCIe Phy"; 933 device_class_set_legacy_reset(dc, aspeed_2700_pcie_phy_reset); 934 935 apc->nr_regs = 0x800 >> 2; 936 } 937 938 static const TypeInfo aspeed_2700_pcie_phy_info = { 939 .name = TYPE_ASPEED_2700_PCIE_PHY, 940 .parent = TYPE_ASPEED_PCIE_PHY, 941 .class_init = aspeed_2700_pcie_phy_class_init, 942 }; 943 944 static void aspeed_pcie_register_types(void) 945 { 946 type_register_static(&aspeed_pcie_root_info); 947 type_register_static(&aspeed_pcie_rc_info); 948 type_register_static(&aspeed_pcie_cfg_info); 949 type_register_static(&aspeed_2700_pcie_cfg_info); 950 type_register_static(&aspeed_pcie_phy_info); 951 type_register_static(&aspeed_2700_pcie_phy_info); 952 } 953 954 type_init(aspeed_pcie_register_types); 955 956