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
aspeed_pcie_root_class_init(ObjectClass * klass,const void * data)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
aspeed_pcie_rc_set_irq(void * opaque,int irq,int level)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
aspeed_pcie_rc_map_irq(PCIDevice * pci_dev,int irq_num)94 static int aspeed_pcie_rc_map_irq(PCIDevice *pci_dev, int irq_num)
95 {
96 return irq_num % PCI_NUM_PINS;
97 }
98
aspeed_pcie_rc_msi_notify(AspeedPCIERcState * rc,uint64_t data)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
aspeed_pcie_rc_msi_write(void * opaque,hwaddr addr,uint64_t data,unsigned int size)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
aspeed_pcie_rc_get_as(PCIBus * bus,void * opaque,int devfn)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
aspeed_pcie_rc_realize(DeviceState * dev,Error ** errp)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
aspeed_pcie_rc_root_bus_path(PCIHostState * host_bridge,PCIBus * rootbus)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
aspeed_pcie_rc_instance_init(Object * obj)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
aspeed_pcie_rc_class_init(ObjectClass * klass,const void * data)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
aspeed_pcie_cfg_read(void * opaque,hwaddr addr,unsigned int size)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
aspeed_pcie_cfg_translate_write(uint8_t byte_en,uint32_t * addr,uint64_t * val,int * len)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
aspeed_pcie_cfg_readwrite(AspeedPCIECfgState * s,const AspeedPCIECfgTxDesc * desc)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
aspeed_pcie_cfg_write(void * opaque,hwaddr addr,uint64_t data,unsigned int size)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
aspeed_pcie_cfg_instance_init(Object * obj)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
aspeed_pcie_cfg_reset(DeviceState * dev)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
aspeed_pcie_cfg_realize(DeviceState * dev,Error ** errp)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
aspeed_pcie_cfg_unrealize(DeviceState * dev)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
aspeed_pcie_cfg_class_init(ObjectClass * klass,const void * data)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
aspeed_2700_pcie_cfg_write(void * opaque,hwaddr addr,uint64_t data,unsigned int size)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
aspeed_2700_pcie_cfg_class_init(ObjectClass * klass,const void * data)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
aspeed_pcie_phy_read(void * opaque,hwaddr addr,unsigned int size)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
aspeed_pcie_phy_write(void * opaque,hwaddr addr,uint64_t data,unsigned int size)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
aspeed_pcie_phy_reset(DeviceState * dev)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
aspeed_pcie_phy_realize(DeviceState * dev,Error ** errp)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
aspeed_pcie_phy_unrealize(DeviceState * dev)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
aspeed_pcie_phy_class_init(ObjectClass * klass,const void * data)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
aspeed_2700_pcie_phy_reset(DeviceState * dev)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
aspeed_2700_pcie_phy_class_init(ObjectClass * klass,const void * data)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
aspeed_pcie_register_types(void)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