xref: /openbmc/qemu/hw/pci-host/aspeed_pcie.c (revision 68ef48e0af7aa90525cb98241a83cad907862f47)
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