xref: /openbmc/qemu/hw/pci-host/aspeed_pcie.c (revision 8d40a557)
1 /*
2  * Aspeed PCIe host controller
3  *
4  * Copyright (c) 2022 Cédric Le Goater <clg@kaod.org>
5  *
6  * This code is licensed under the GPL version 2 or later.  See
7  * the COPYING file in the top-level directory.
8  */
9 
10 #include "qemu/osdep.h"
11 #include "qemu/module.h"
12 #include "qemu/units.h"
13 #include "qemu/log.h"
14 #include "qapi/error.h"
15 #include "hw/qdev-properties.h"
16 #include "hw/irq.h"
17 #include "hw/pci-host/aspeed_pcie.h"
18 #include "hw/pci/msi.h"
19 
20 #include "trace.h"
21 
22 #define TO_REG(offset) ((offset) >> 2)
23 
24 #define PCI_VENDOR_ID_ASPEED       0x1A03
25 #define PCI_DEVICE_ID_AST2600_RC   0x1150
26 
27 /*
28  * RC
29  */
30 
31 #define ASPEED_PCIE_RC_CTRL             0x00
32 #define ASPEED_PCIE_RC_CTRL_RCL            BIT(0)
33 #define ASPEED_PCIE_RC_CTRL_RCL_RX         BIT(1)
34 #define ASPEED_PCIE_RC_CTRL_RX_WAIT_FW     BIT(2)
35 #define ASPEED_PCIE_RC_CTRL_RX_UNLOCK      BIT(4)
36 #define ASPEED_PCIE_RC_CTRL_RX_MSI         BIT(6)
37 #define ASPEED_PCIE_RC_CTRL_RX_MSI_SELECT  BIT(7)
38 #define ASPEED_PCIE_RC_CTRL_RX_LINEAR      BIT(8)
39 #define ASPEED_PCIE_RC_CTRL_RX_DMA         BIT(9)
40 #define ASPEED_PCIE_RC_CTRL_RX_TAG_MASK    0x00ff0000
41 
42 #define ASPEED_PCIE_RC_INT_ENABLE       0x04
43 #define   ASPEED_PCIE_RC_INT_ENABLE_INTA   BIT(0)
44 #define   ASPEED_PCIE_RC_INT_ENABLE_INTB   BIT(1)
45 #define   ASPEED_PCIE_RC_INT_ENABLE_INTC   BIT(2)
46 #define   ASPEED_PCIE_RC_INT_ENABLE_INTD   BIT(3)
47 #define   ASPEED_PCIE_RC_INT_ENABLE_RX     BIT(4)
48 #define ASPEED_PCIE_RC_INT_STATUS       0x08
49 #define   ASPEED_PCIE_RC_INT_STATUS_INTA   BIT(0)
50 #define   ASPEED_PCIE_RC_INT_STATUS_INTB   BIT(1)
51 #define   ASPEED_PCIE_RC_INT_STATUS_INTC   BIT(2)
52 #define   ASPEED_PCIE_RC_INT_STATUS_INTD   BIT(3)
53 #define   ASPEED_PCIE_RC_INT_STATUS_INTX_MASK 0xf
54 #define   ASPEED_PCIE_RC_INT_STATUS_RX     BIT(4)
55 
56 #define ASPEED_PCIE_RC_RX_DATA  0x0C
57 #define ASPEED_PCIE_RC_RX_DW0   0x10
58 #define ASPEED_PCIE_RC_RX_DW1   0x14
59 #define ASPEED_PCIE_RC_RX_DW2   0x18
60 #define ASPEED_PCIE_RC_RX_DW3   0x1C
61 #define ASPEED_PCIE_RC_MSI_ENABLE0      0x20
62 #define ASPEED_PCIE_RC_MSI_ENABLE1      0x24
63 #define ASPEED_PCIE_RC_MSI_STATUS0      0x28
64 #define ASPEED_PCIE_RC_MSI_STATUS1      0x2C
65 #define ASPEED_PCIE_RC_TX_TAG           0x3C
66 
aspeed_pcie_rc_update_irq(AspeedPCIERc * s)67 static void aspeed_pcie_rc_update_irq(AspeedPCIERc *s)
68 {
69     bool intx = !!(s->regs[TO_REG(ASPEED_PCIE_RC_INT_STATUS)] &
70                    s->regs[TO_REG(ASPEED_PCIE_RC_INT_ENABLE)]);
71     bool msi0 = !!(s->regs[TO_REG(ASPEED_PCIE_RC_MSI_STATUS0)] &
72                    s->regs[TO_REG(ASPEED_PCIE_RC_MSI_ENABLE0)]);
73     bool msi1 = !!(s->regs[TO_REG(ASPEED_PCIE_RC_MSI_STATUS1)] &
74                    s->regs[TO_REG(ASPEED_PCIE_RC_MSI_ENABLE1)]);
75     bool level = intx || msi0 || msi1;
76 
77     qemu_set_irq(s->irq, level);
78 }
79 
aspeed_pcie_rc_read(void * opaque,hwaddr addr,unsigned int size)80 static uint64_t aspeed_pcie_rc_read(void *opaque, hwaddr addr,
81                                      unsigned int size)
82 {
83     AspeedPCIERc *s = ASPEED_PCIE_RC(opaque);
84     uint64_t val = 0;
85 
86     switch (addr) {
87     case ASPEED_PCIE_RC_CTRL:
88     case ASPEED_PCIE_RC_INT_ENABLE:
89     case ASPEED_PCIE_RC_INT_STATUS:
90     case ASPEED_PCIE_RC_RX_DATA:
91     case ASPEED_PCIE_RC_RX_DW0:
92     case ASPEED_PCIE_RC_RX_DW1:
93     case ASPEED_PCIE_RC_RX_DW2:
94     case ASPEED_PCIE_RC_RX_DW3:
95     case ASPEED_PCIE_RC_MSI_ENABLE0:
96     case ASPEED_PCIE_RC_MSI_ENABLE1:
97     case ASPEED_PCIE_RC_MSI_STATUS0:
98     case ASPEED_PCIE_RC_MSI_STATUS1:
99     case ASPEED_PCIE_RC_TX_TAG:
100         val = s->regs[TO_REG(addr)];
101         break;
102 
103     default:
104         qemu_log_mask(LOG_GUEST_ERROR,
105                       "%s: Out-of-bounds read at offset 0x%" HWADDR_PRIx "\n",
106                       __func__, addr);
107         break;
108     }
109 
110     trace_aspeed_pcie_rc_read(addr, val);
111     return val;
112 }
113 
aspeed_pcie_rc_write(void * opaque,hwaddr addr,uint64_t data,unsigned int size)114 static void aspeed_pcie_rc_write(void *opaque, hwaddr addr, uint64_t data,
115                                   unsigned int size)
116 {
117     AspeedPCIERc *s = ASPEED_PCIE_RC(opaque);
118 
119     trace_aspeed_pcie_rc_write(addr, data);
120 
121     switch (addr) {
122     case ASPEED_PCIE_RC_CTRL:  /* TODO: unlock/lock RX */
123     case ASPEED_PCIE_RC_INT_ENABLE:
124     case ASPEED_PCIE_RC_MSI_ENABLE0:
125     case ASPEED_PCIE_RC_MSI_ENABLE1:
126     case ASPEED_PCIE_RC_TX_TAG:
127         s->regs[TO_REG(addr)] = data;
128         break;
129     case ASPEED_PCIE_RC_MSI_STATUS0:
130     case ASPEED_PCIE_RC_MSI_STATUS1:
131         s->regs[TO_REG(addr)] &= ~data;
132         break;
133     case ASPEED_PCIE_RC_INT_STATUS:  /* preserve INTx status*/
134         s->regs[TO_REG(addr)] &= ~data | ASPEED_PCIE_RC_INT_STATUS_INTX_MASK;
135         break;
136     default:
137         qemu_log_mask(LOG_GUEST_ERROR,
138                       "%s: Out-of-bounds read at offset 0x%" HWADDR_PRIx "\n",
139                       __func__, addr);
140         break;
141     }
142 }
143 
144 static const MemoryRegionOps aspeed_pcie_rc_ops = {
145     .read = aspeed_pcie_rc_read,
146     .write = aspeed_pcie_rc_write,
147     .endianness = DEVICE_LITTLE_ENDIAN,
148     .valid = {
149         .min_access_size = 1,
150         .max_access_size = 4,
151     },
152 };
153 
aspeed_pcie_rc_set_irq(void * opaque,int irq,int level)154 static void aspeed_pcie_rc_set_irq(void *opaque, int irq, int level)
155 {
156     AspeedPCIERc *s = (AspeedPCIERc *) opaque;
157 
158     assert(irq < PCI_NUM_PINS);
159 
160     if (level) {
161         s->regs[TO_REG(ASPEED_PCIE_RC_INT_STATUS)] |= BIT(irq);
162     } else {
163         s->regs[TO_REG(ASPEED_PCIE_RC_INT_STATUS)] &= ~BIT(irq);
164     }
165 
166     aspeed_pcie_rc_update_irq(s);
167 }
168 
aspeed_pcie_rc_map_irq(PCIDevice * pci_dev,int irq_num)169 static int aspeed_pcie_rc_map_irq(PCIDevice *pci_dev, int irq_num)
170 {
171     return irq_num % PCI_NUM_PINS;
172 }
173 
aspeed_pcie_rc_realize(DeviceState * dev,Error ** errp)174 static void aspeed_pcie_rc_realize(DeviceState *dev, Error **errp)
175 {
176     PCIHostState *pci = PCI_HOST_BRIDGE(dev);
177     AspeedPCIERc *s = ASPEED_PCIE_RC(dev);
178     SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
179     PCIExpressHost *pex = PCIE_HOST_BRIDGE(dev);
180 
181     memory_region_init_io(&s->reg_rc_mmio, OBJECT(s), &aspeed_pcie_rc_ops, s,
182                           TYPE_ASPEED_PCIE_RC ".regs", 0x40);
183 
184     /* PCI configuration space */
185     pcie_host_mmcfg_init(pex, PCIE_MMCFG_SIZE_MAX / 2);
186     sysbus_init_mmio(sbd, &pex->mmio);
187 
188     /* MMIO and IO region */
189     memory_region_init(&s->mmio, OBJECT(s), "mmio", UINT64_MAX);
190     memory_region_init(&s->io, OBJECT(s), "io", 0x10000);
191 
192     memory_region_init_io(&s->mmio_window, OBJECT(s), &unassigned_io_ops,
193                           OBJECT(s), "mmio_window", UINT64_MAX);
194     memory_region_init_io(&s->io_window, OBJECT(s), &unassigned_io_ops,
195                           OBJECT(s), "ioport_window", 64 * 1024);
196 
197     memory_region_add_subregion(&s->mmio_window, 0, &s->mmio);
198     memory_region_add_subregion(&s->io_window, 0, &s->io);
199     sysbus_init_mmio(sbd, &s->mmio_window);
200     sysbus_init_mmio(sbd, &s->io_window);
201 
202     sysbus_init_irq(sbd, &s->irq);
203 
204     pci->bus = pci_register_root_bus(dev, dev->id, aspeed_pcie_rc_set_irq,
205                                      aspeed_pcie_rc_map_irq, s, &s->mmio,
206                                      &s->io, 0, 4, TYPE_PCIE_BUS);
207     pci->bus->flags |= PCI_BUS_EXTENDED_CONFIG_SPACE;
208 
209     qdev_realize(DEVICE(&s->root), BUS(pci->bus), &error_fatal);
210 }
211 
aspeed_pcie_rc_reset(DeviceState * dev)212 static void aspeed_pcie_rc_reset(DeviceState *dev)
213 {
214     AspeedPCIERc *s = ASPEED_PCIE_RC(dev);
215 
216     memset(s->regs, 0, sizeof(s->regs));
217 }
218 
aspeed_pcie_rc_root_bus_path(PCIHostState * host_bridge,PCIBus * rootbus)219 static const char *aspeed_pcie_rc_root_bus_path(PCIHostState *host_bridge,
220                                                   PCIBus *rootbus)
221 {
222     AspeedPCIERc *s = ASPEED_PCIE_RC(host_bridge);
223 
224     snprintf(s->name, sizeof(s->name), "0000:%02x", s->bus_nr);
225     return s->name;
226 }
227 
aspeed_pcie_rc_init(Object * obj)228 static void aspeed_pcie_rc_init(Object *obj)
229 {
230     AspeedPCIERc *s = ASPEED_PCIE_RC(obj);
231     AspeedPCIERoot *root = &s->root;
232 
233     object_initialize_child(obj, "root", root, TYPE_ASPEED_PCIE_ROOT);
234     qdev_prop_set_int32(DEVICE(root), "addr", PCI_DEVFN(0, 0));
235     qdev_prop_set_bit(DEVICE(root), "multifunction", false);
236 }
237 
238 static Property aspeed_pcie_rc_props[] = {
239     DEFINE_PROP_UINT32("bus-nr", AspeedPCIERc, bus_nr, 0),
240     DEFINE_PROP_END_OF_LIST(),
241 };
242 
aspeed_pcie_rc_class_init(ObjectClass * klass,void * data)243 static void aspeed_pcie_rc_class_init(ObjectClass *klass, void *data)
244 {
245     DeviceClass *dc = DEVICE_CLASS(klass);
246     PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_CLASS(klass);
247 
248     hc->root_bus_path = aspeed_pcie_rc_root_bus_path;
249     device_class_set_legacy_reset(dc, aspeed_pcie_rc_reset);
250     dc->realize = aspeed_pcie_rc_realize;
251     set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
252     dc->fw_name = "pci";
253     device_class_set_props(dc, aspeed_pcie_rc_props);
254 
255     msi_nonbroken = true;
256 }
257 
258 static const TypeInfo aspeed_pcie_rc_info = {
259     .name       = TYPE_ASPEED_PCIE_RC,
260     .parent     = TYPE_PCIE_HOST_BRIDGE,
261     .instance_size = sizeof(AspeedPCIERc),
262     .instance_init = aspeed_pcie_rc_init,
263     .class_init = aspeed_pcie_rc_class_init,
264 };
265 
aspeed_pcie_root_class_init(ObjectClass * klass,void * data)266 static void aspeed_pcie_root_class_init(ObjectClass *klass, void *data)
267 {
268     DeviceClass *dc = DEVICE_CLASS(klass);
269     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
270 
271     set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
272     dc->desc = "Aspeed PCIe Host Bridge";
273 
274     k->vendor_id = PCI_VENDOR_ID_ASPEED;
275     k->device_id = PCI_DEVICE_ID_AST2600_RC;
276     k->revision = 0;
277     k->class_id = PCI_CLASS_BRIDGE_HOST;
278 
279     /* */
280     dc->user_creatable = false;
281 }
282 
283 static const TypeInfo aspeed_pcie_root_info = {
284     .name = TYPE_ASPEED_PCIE_ROOT,
285     .parent =  TYPE_PCI_DEVICE,
286     .instance_size = sizeof(AspeedPCIERoot),
287     .class_init = aspeed_pcie_root_class_init,
288     .interfaces = (InterfaceInfo[]) {
289         { INTERFACE_CONVENTIONAL_PCI_DEVICE },
290         { }
291     },
292 };
293 
294 /*
295  * AHB to PCIe bridge (PCIECFG)
296  */
297 
298 #define ASPEED_PCIE_CFG_CTRL        0x00
299 #define   ASPEED_PCIE_CFG_CTRL_ENABLE      BIT(0)
300 #define   ASPEED_PCIE_CFG_CTRL_CLEAR_RX     BIT(4)
301 #define ASPEED_PCIE_CFG_EN_IRQ      0x04
302 #define ASPEED_PCIE_CFG_TX_CLEAR    0x08
303 #define ASPEED_PCIE_CFG_RX_DATA     0x0C
304 #define ASPEED_PCIE_CFG_TX_DW0      0x10
305 #define ASPEED_PCIE_CFG_TX_DW1      0x14
306 #define ASPEED_PCIE_CFG_TX_DW2      0x18
307 #define ASPEED_PCIE_CFG_TX_DW3      0x1C
308 #define ASPEED_PCIE_CFG_TX_DATA             0x20
309 #define ASPEED_PCIE_CFG_TX_STATUS           0x24
310 #define   ASPEED_PCIE_CFG_TX_STATUS_IDLE         BIT(31)
311 #define   ASPEED_PCIE_CFG_TX_STATUS_RC_H_RX_DONE BIT(27)
312 #define   ASPEED_PCIE_CFG_TX_STATUS_RC_L_RX_DONE BIT(26)
313 #define   ASPEED_PCIE_CFG_TX_STATUS_RC_H_TX_DONE BIT(25)
314 #define   ASPEED_PCIE_CFG_TX_STATUS_RC_L_TX_DONE BIT(24)
315 #define   ASPEED_PCIE_CFG_TX_STATUS_TRIG         BIT(0)
316 #define ASPEED_PCIE_CFG_MSI0        0x58
317 #define ASPEED_PCIE_CFG_MSI1        0x5C
318 #define ASPEED_PCIE_CFG_REG60       0x60
319 #define ASPEED_PCIE_CFG_REG64       0x64
320 #define ASPEED_PCIE_CFG_REG68       0x68
321 
322 #define ASPEED_PCIE_CFG_RC_MAX_MSI 64
323 
aspeed_pcie_cfg_read(void * opaque,hwaddr addr,unsigned int size)324 static uint64_t aspeed_pcie_cfg_read(void *opaque, hwaddr addr,
325                                      unsigned int size)
326 {
327     AspeedPCIECfg *s = ASPEED_PCIE_CFG(opaque);
328     uint64_t val = 0;
329 
330     switch (addr) {
331     case ASPEED_PCIE_CFG_CTRL:
332     case ASPEED_PCIE_CFG_EN_IRQ:
333     case ASPEED_PCIE_CFG_TX_CLEAR:
334     case ASPEED_PCIE_CFG_RX_DATA:
335     case ASPEED_PCIE_CFG_TX_DW0:
336     case ASPEED_PCIE_CFG_TX_DW1:
337     case ASPEED_PCIE_CFG_TX_DW2:
338     case ASPEED_PCIE_CFG_TX_DW3:
339     case ASPEED_PCIE_CFG_TX_STATUS:
340     case ASPEED_PCIE_CFG_REG60:
341     case ASPEED_PCIE_CFG_REG64:
342     case ASPEED_PCIE_CFG_REG68:
343         val = s->regs[TO_REG(addr)];
344         break;
345     case ASPEED_PCIE_CFG_MSI0:
346     case ASPEED_PCIE_CFG_MSI1:
347         printf("%s: 0x%" HWADDR_PRIx "\n", __func__, addr);
348         val = s->regs[TO_REG(addr)];
349         break;
350     default:
351         qemu_log_mask(LOG_GUEST_ERROR,
352                       "%s: Out-of-bounds read at offset 0x%" HWADDR_PRIx "\n",
353                       __func__, addr);
354         break;
355     }
356 
357     trace_aspeed_pcie_cfg_read(addr, val);
358     return val;
359 }
360 
361 #define TLP_FMTTYPE_CFGRD0      0x04 /* Configuration Read  Type 0 */
362 #define TLP_FMTTYPE_CFGWR0      0x44 /* Configuration Write Type 0 */
363 #define TLP_FMTTYPE_CFGRD1      0x05 /* Configuration Read  Type 1 */
364 #define TLP_FMTTYPE_CFGWR1      0x45 /* Configuration Write Type 1 */
365 
366 #define PCIE_CFG_FMTTYPE_MASK(dw0) (((dw0) >> 24) & 0xff)
367 #define PCIE_CFG_BYTE_EN(dw1) ((dw1) & 0xf)
368 
369 #define PCIE_MMCFG_ADDR(bus, devfn, offset)                             \
370     ((((bus) & PCIE_MMCFG_BUS_MASK) << PCIE_MMCFG_BUS_BIT) |            \
371      (((devfn) & PCIE_MMCFG_DEVFN_MASK) << PCIE_MMCFG_DEVFN_BIT) |      \
372      ((offset) & PCIE_MMCFG_CONFOFFSET_MASK))
373 
374 /* TODO : find a better way to deduce len/addr/val from byte enable */
aspeed_pcie_cfg_translate_write(AspeedPCIECfg * s,uint32_t * addr,uint64_t * val,int * len)375 static void aspeed_pcie_cfg_translate_write(AspeedPCIECfg *s, uint32_t *addr,
376                                             uint64_t *val, int *len)
377 {
378     uint8_t byte_en = PCIE_CFG_BYTE_EN(s->regs[TO_REG(ASPEED_PCIE_CFG_TX_DW1)]);
379 
380     *len = ctpop8(byte_en);
381 
382     switch (byte_en) {
383     case 0x1:
384     case 0x3:
385     case 0xf:
386         break;
387     case 0x4:
388         *addr += 2;
389         *val = (*val >> (2 * 8)) & MAKE_64BIT_MASK(0, *len * 8);
390         break;
391     case 0x2:
392     case 0xc:
393         *addr += *len;
394         *val = (*val >> (*len * 8)) & MAKE_64BIT_MASK(0, *len * 8);
395         break;
396     default:
397         qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid byte enable: %d\n",
398                       __func__, byte_en);
399         g_assert_not_reached();
400     }
401 }
402 
aspeed_pcie_cfg_readwrite(AspeedPCIECfg * s)403 static void aspeed_pcie_cfg_readwrite(AspeedPCIECfg *s)
404 {
405     bool is_write = !!(s->regs[TO_REG(ASPEED_PCIE_CFG_TX_DW0)] & (1ul << 30));
406     uint32_t cfg_addr = s->regs[TO_REG(ASPEED_PCIE_CFG_TX_DW2)];
407     uint8_t bus = (cfg_addr >> 24) & 0xff;
408     uint8_t devfn  = (cfg_addr >> 16) & 0xff;
409     uint32_t offset = cfg_addr & 0xffc;
410     uint8_t rc_index = !!(bus & 0x80);
411     AspeedPCIERc *rc = &s->rcs[rc_index];
412 
413     uint64_t val = ~0;
414     int len;
415 
416     PCIHostState *pci = PCI_HOST_BRIDGE(rc);
417     PCIDevice *pdev;
418 
419     /* HACK: rework host bridge */
420     if (bus == 0x80) {
421         bus = 0;
422     }
423 
424     pdev = pci_find_device(pci->bus, bus, devfn);
425     if (!pdev) {
426         rc->regs[TO_REG(ASPEED_PCIE_RC_RX_DATA)] = ~0;
427         goto out;
428     }
429 
430     switch (PCIE_CFG_FMTTYPE_MASK(s->regs[TO_REG(ASPEED_PCIE_CFG_TX_DW0)])) {
431     case TLP_FMTTYPE_CFGWR0:
432     case TLP_FMTTYPE_CFGWR1:
433         val = s->regs[TO_REG(ASPEED_PCIE_CFG_TX_DATA)];
434         aspeed_pcie_cfg_translate_write(s, &offset, &val, &len);
435 
436         pci_host_config_write_common(pdev, offset, pci_config_size(pdev),
437                                      val, len);
438         break;
439 
440     case TLP_FMTTYPE_CFGRD0:
441     case TLP_FMTTYPE_CFGRD1:
442         val = pci_host_config_read_common(pdev, offset,
443                                           pci_config_size(pdev), 4);
444         rc->regs[TO_REG(ASPEED_PCIE_RC_RX_DATA)] = val;
445         break;
446     default:
447         qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid CFG type. DW0=0x%x\n",
448                       __func__, s->regs[TO_REG(ASPEED_PCIE_CFG_TX_DW0)]);
449     }
450 
451 out:
452     rc->regs[TO_REG(ASPEED_PCIE_RC_INT_STATUS)] |=
453         ASPEED_PCIE_RC_INT_STATUS_RX;
454 
455     s->regs[TO_REG(ASPEED_PCIE_CFG_TX_STATUS)] |= BIT(24 + rc_index);
456     s->regs[TO_REG(ASPEED_PCIE_CFG_TX_STATUS)] |=
457         ASPEED_PCIE_CFG_TX_STATUS_IDLE;
458 
459     trace_aspeed_pcie_cfg_rw(is_write ?  "write" : "read", bus, devfn,
460                              cfg_addr, val);
461 }
462 
aspeed_pcie_cfg_msi_notify(AspeedPCIECfg * s,hwaddr addr,uint64_t data)463 static void aspeed_pcie_cfg_msi_notify(AspeedPCIECfg *s, hwaddr addr,
464                                        uint64_t data)
465 {
466     bool rc_index = !!(addr == ASPEED_PCIE_CFG_MSI1);
467     AspeedPCIERc *rc = &s->rcs[rc_index];
468     int reg;
469 
470     trace_aspeed_pcie_cfg_msi_notify(addr, data);
471 
472     /* Written data is the HW IRQ number */
473     if (data >= ASPEED_PCIE_CFG_RC_MAX_MSI) {
474         qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid MSI vector %"PRIx64"\n",
475                       __func__, data);
476         return;
477     }
478 
479     /* TODO: what is ASPEED_PCIE_RC_CTRL_RX_MSI_SELECT ? */
480     if (!(rc->regs[TO_REG(ASPEED_PCIE_RC_CTRL)] &
481           ASPEED_PCIE_RC_CTRL_RX_MSI)) {
482         qemu_log_mask(LOG_GUEST_ERROR, "%s: MSI are not enabled\n", __func__);
483         return;
484     }
485 
486     reg = data < 32 ? ASPEED_PCIE_RC_MSI_STATUS0 : ASPEED_PCIE_RC_MSI_STATUS1;
487 
488     rc->regs[TO_REG(reg)] |= BIT(data % 32);
489     aspeed_pcie_rc_update_irq(rc);
490 }
491 
aspeed_pcie_cfg_write(void * opaque,hwaddr addr,uint64_t data,unsigned int size)492 static void aspeed_pcie_cfg_write(void *opaque, hwaddr addr, uint64_t data,
493                               unsigned int size)
494 {
495     AspeedPCIECfg *s = ASPEED_PCIE_CFG(opaque);
496 
497     trace_aspeed_pcie_cfg_write(addr, data);
498 
499     /* TODO: test ASPEED_PCIE_CFG_CTRL_ENABLE */
500 
501     switch (addr) {
502     case ASPEED_PCIE_CFG_EN_IRQ:
503     case ASPEED_PCIE_CFG_TX_DW0:
504     case ASPEED_PCIE_CFG_TX_DW1:
505     case ASPEED_PCIE_CFG_TX_DW2:
506     case ASPEED_PCIE_CFG_TX_DW3:
507     case ASPEED_PCIE_CFG_TX_DATA:
508     case ASPEED_PCIE_CFG_REG60:
509     case ASPEED_PCIE_CFG_REG64:
510     case ASPEED_PCIE_CFG_REG68:
511         s->regs[TO_REG(addr)] = data;
512         break;
513     case ASPEED_PCIE_CFG_MSI0:
514     case ASPEED_PCIE_CFG_MSI1:
515         aspeed_pcie_cfg_msi_notify(s, addr, data);
516         break;
517     case ASPEED_PCIE_CFG_CTRL:
518         if (data & ASPEED_PCIE_CFG_CTRL_CLEAR_RX) {
519             s->regs[TO_REG(ASPEED_PCIE_CFG_RX_DATA)] = ~0;
520         }
521         break;
522 
523     case ASPEED_PCIE_CFG_TX_CLEAR:
524         if (data == 0x1) {
525             s->regs[TO_REG(ASPEED_PCIE_CFG_TX_STATUS)] &=
526                 ~ASPEED_PCIE_CFG_TX_STATUS_IDLE;
527         }
528         break;
529     case ASPEED_PCIE_CFG_TX_STATUS:
530         if (data & ASPEED_PCIE_CFG_TX_STATUS_TRIG) {
531             aspeed_pcie_cfg_readwrite(s);
532         }
533         break;
534     default:
535         qemu_log_mask(LOG_GUEST_ERROR,
536                       "%s: Out-of-bounds read at offset 0x%" HWADDR_PRIx "\n",
537                       __func__, addr);
538         break;
539     }
540 }
541 
542 static const MemoryRegionOps aspeed_pcie_cfg_ops = {
543     .read = aspeed_pcie_cfg_read,
544     .write = aspeed_pcie_cfg_write,
545     .endianness = DEVICE_LITTLE_ENDIAN,
546     .valid = {
547         .min_access_size = 1,
548         .max_access_size = 4,
549     },
550 };
551 
aspeed_pcie_cfg_reset(DeviceState * dev)552 static void aspeed_pcie_cfg_reset(DeviceState *dev)
553 {
554     AspeedPCIECfg *s = ASPEED_PCIE_CFG(dev);
555 
556     memset(s->regs, 0, sizeof(s->regs));
557 }
558 
aspeed_pcie_cfg_instance_init(Object * obj)559 static void aspeed_pcie_cfg_instance_init(Object *obj)
560 {
561     AspeedPCIECfg *s = ASPEED_PCIE_CFG(obj);
562     int i;
563 
564     for (i = 0; i < ARRAY_SIZE(s->rcs); i++) {
565         object_initialize_child(obj, "rcs[*]", &s->rcs[i],
566                                 TYPE_ASPEED_PCIE_RC);
567     }
568 }
569 
aspeed_pcie_cfg_realize(DeviceState * dev,Error ** errp)570 static void aspeed_pcie_cfg_realize(DeviceState *dev, Error **errp)
571 {
572     AspeedPCIECfg *s = ASPEED_PCIE_CFG(dev);
573     SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
574     int nr_rcs = ARRAY_SIZE(s->rcs);
575     int i;
576 
577     memory_region_init(&s->reg_mmio_container, OBJECT(s),
578                        TYPE_ASPEED_PCIE_CFG ".container", 0x100);
579     sysbus_init_mmio(sbd, &s->reg_mmio_container);
580 
581     memory_region_init_io(&s->reg_cfg_mmio, OBJECT(s), &aspeed_pcie_cfg_ops, s,
582                           TYPE_ASPEED_PCIE_CFG ".regs", 0x80);
583     memory_region_add_subregion(&s->reg_mmio_container, 0x0, &s->reg_cfg_mmio);
584 
585     for (i = 0; i < nr_rcs; i++) {
586         object_property_set_int(OBJECT(&s->rcs[i]), "bus-nr",
587                                 i * PCI_BUS_MAX / nr_rcs, &error_abort);
588         if (!sysbus_realize(SYS_BUS_DEVICE(&s->rcs[i]), errp)) {
589             return;
590         }
591 
592         /* RC registers */
593         memory_region_add_subregion(&s->reg_mmio_container, 0x80 + i * 0x40,
594                                     &s->rcs[i].reg_rc_mmio);
595     }
596 }
597 
598 static Property aspeed_pcie_cfg_props[] = {
599     DEFINE_PROP_END_OF_LIST(),
600 };
601 
aspeed_pcie_cfg_class_init(ObjectClass * klass,void * data)602 static void aspeed_pcie_cfg_class_init(ObjectClass *klass, void *data)
603 {
604     DeviceClass *dc = DEVICE_CLASS(klass);
605 
606     dc->realize = aspeed_pcie_cfg_realize;
607     device_class_set_legacy_reset(dc, aspeed_pcie_cfg_reset);
608     device_class_set_props(dc, aspeed_pcie_cfg_props);
609 }
610 
611 static const TypeInfo aspeed_pcie_cfg_info = {
612     .name       = TYPE_ASPEED_PCIE_CFG,
613     .parent     = TYPE_SYS_BUS_DEVICE,
614     .instance_size = sizeof(AspeedPCIECfg),
615     .instance_init = aspeed_pcie_cfg_instance_init,
616     .class_init = aspeed_pcie_cfg_class_init,
617 };
618 
619 
620 /*
621  * PHY
622  */
623 
624 #define ASPEED_PCIE_PHY_DEVID           0x00
625 #define ASPEED_PCIE_PHY_CLASS_CODE      0x04
626 #define   ASPEED_PCIE_PHY_CLASS_CODE_A3   0x6
627 #define ASPEED_PCIE_PHY_DATALINK        0x10
628 #define ASPEED_PCIE_PHY_HOTPLUG         0x14
629 #define ASPEED_PCIE_PHY_CTRL1           0x30
630 #define   ASPEED_PCIE_PHY_CTRL1_ROOTPORT  (BIT(5) | BIT(4))
631 #define   ASPEED_PCIE_PHY_CTRL1_ENABLE     BIT(1)
632 #define ASPEED_PCIE_PHY_PROTECT         0x7C
633 #define ASPEED_PCIE_PHY_LINK            0xC0
634 #define   ASPEED_PCIE_PHY_LINK_STATUS     BIT(5)
635 #define ASPEED_PCIE_PHY_BDF             0xC4
636 #define ASPEED_PCIE_PHY_LINK_STS        0xD0
637 
aspeed_pcie_phy_read(void * opaque,hwaddr addr,unsigned int size)638 static uint64_t aspeed_pcie_phy_read(void *opaque, hwaddr addr,
639                                      unsigned int size)
640 {
641     AspeedPCIEPhy *s = ASPEED_PCIE_PHY(opaque);
642     uint64_t val = 0;
643 
644     switch (addr) {
645     case ASPEED_PCIE_PHY_DEVID:
646     case ASPEED_PCIE_PHY_CLASS_CODE:
647     case ASPEED_PCIE_PHY_DATALINK:
648     case ASPEED_PCIE_PHY_CTRL1:
649     case ASPEED_PCIE_PHY_PROTECT:
650     case ASPEED_PCIE_PHY_LINK:
651     case ASPEED_PCIE_PHY_BDF:
652     case ASPEED_PCIE_PHY_LINK_STS:
653         val = s->regs[TO_REG(addr)];
654         break;
655     default:
656         qemu_log_mask(LOG_GUEST_ERROR,
657                       "%s: Out-of-bounds read at offset 0x%" HWADDR_PRIx "\n",
658                       __func__, addr);
659         break;
660     }
661 
662     trace_aspeed_pcie_phy_read(addr, val);
663     return val;
664 }
665 
aspeed_pcie_phy_write(void * opaque,hwaddr addr,uint64_t data,unsigned int size)666 static void aspeed_pcie_phy_write(void *opaque, hwaddr addr, uint64_t data,
667                               unsigned int size)
668 {
669     AspeedPCIEPhy *s = ASPEED_PCIE_PHY(opaque);
670 
671     trace_aspeed_pcie_phy_write(addr, data);
672 
673     /* TODO: test protect */
674 
675     switch (addr) {
676     case ASPEED_PCIE_PHY_PROTECT:
677         data &= 0xff;
678         s->regs[TO_REG(addr)] = !!(data == 0xA8);
679         break;
680 
681     case ASPEED_PCIE_PHY_DEVID:
682     case ASPEED_PCIE_PHY_CLASS_CODE:
683     case ASPEED_PCIE_PHY_DATALINK:
684     case ASPEED_PCIE_PHY_CTRL1: /* 0x30 == root port, else bridge */
685         s->regs[TO_REG(addr)] = data;
686         break;
687     default:
688         qemu_log_mask(LOG_GUEST_ERROR,
689                       "%s: Out-of-bounds read at offset 0x%" HWADDR_PRIx "\n",
690                       __func__, addr);
691         break;
692     }
693 }
694 
695 static const MemoryRegionOps aspeed_pcie_phy_ops = {
696     .read = aspeed_pcie_phy_read,
697     .write = aspeed_pcie_phy_write,
698     .endianness = DEVICE_LITTLE_ENDIAN,
699     .valid = {
700         .min_access_size = 1,
701         .max_access_size = 4,
702     },
703 };
704 
aspeed_pcie_phy_reset(DeviceState * dev)705 static void aspeed_pcie_phy_reset(DeviceState *dev)
706 {
707     AspeedPCIEPhy *s = ASPEED_PCIE_PHY(dev);
708 
709     memset(s->regs, 0, sizeof(s->regs));
710 
711     s->regs[TO_REG(ASPEED_PCIE_PHY_DEVID)] =
712         (PCI_DEVICE_ID_AST2600_RC << 16) | PCI_VENDOR_ID_ASPEED;
713     s->regs[TO_REG(ASPEED_PCIE_PHY_CLASS_CODE)] =
714         0x06040000 | ASPEED_PCIE_PHY_CLASS_CODE_A3;
715     s->regs[TO_REG(ASPEED_PCIE_PHY_DATALINK)] = 0xD7040022;
716     s->regs[TO_REG(ASPEED_PCIE_PHY_LINK)] = ASPEED_PCIE_PHY_LINK_STATUS;
717     s->regs[TO_REG(ASPEED_PCIE_PHY_BDF)] = 0x0; /* TODO: BUS+DEV */
718 }
719 
aspeed_pcie_phy_realize(DeviceState * dev,Error ** errp)720 static void aspeed_pcie_phy_realize(DeviceState *dev, Error **errp)
721 {
722     AspeedPCIEPhy *s = ASPEED_PCIE_PHY(dev);
723     SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
724 
725     memory_region_init_io(&s->mmio, OBJECT(s), &aspeed_pcie_phy_ops, s,
726                           TYPE_ASPEED_PCIE_PHY, 0x200);
727     sysbus_init_mmio(sbd, &s->mmio);
728 }
729 
730 static Property aspeed_pcie_phy_props[] = {
731     DEFINE_PROP_END_OF_LIST(),
732 };
733 
aspeed_pcie_phy_class_init(ObjectClass * klass,void * data)734 static void aspeed_pcie_phy_class_init(ObjectClass *klass, void *data)
735 {
736     DeviceClass *dc = DEVICE_CLASS(klass);
737 
738     dc->realize = aspeed_pcie_phy_realize;
739     device_class_set_legacy_reset(dc, aspeed_pcie_phy_reset);
740     device_class_set_props(dc, aspeed_pcie_phy_props);
741 }
742 
743 static const TypeInfo aspeed_pcie_phy_info = {
744     .name       = TYPE_ASPEED_PCIE_PHY,
745     .parent     = TYPE_SYS_BUS_DEVICE,
746     .instance_size = sizeof(AspeedPCIEPhy),
747     .class_init = aspeed_pcie_phy_class_init,
748 };
749 
aspeed_pcie_register(void)750 static void aspeed_pcie_register(void)
751 {
752     type_register_static(&aspeed_pcie_root_info);
753     type_register_static(&aspeed_pcie_rc_info);
754     type_register_static(&aspeed_pcie_phy_info);
755     type_register_static(&aspeed_pcie_cfg_info);
756 }
757 
758 type_init(aspeed_pcie_register)
759