xref: /openbmc/qemu/hw/pci-host/mv64361.c (revision 964d2a0c)
1 /*
2  * Marvell Discovery II MV64361 System Controller for
3  * QEMU PowerPC CHRP (Genesi/bPlan Pegasos II) hardware System Emulator
4  *
5  * Copyright (c) 2018-2020 BALATON Zoltan
6  *
7  * This work is licensed under the GNU GPL license version 2 or later.
8  *
9  */
10 
11 #include "qemu/osdep.h"
12 #include "qemu/units.h"
13 #include "qapi/error.h"
14 #include "hw/sysbus.h"
15 #include "hw/pci/pci_device.h"
16 #include "hw/pci/pci_host.h"
17 #include "hw/irq.h"
18 #include "hw/intc/i8259.h"
19 #include "hw/qdev-properties.h"
20 #include "exec/address-spaces.h"
21 #include "qemu/log.h"
22 #include "qemu/error-report.h"
23 #include "trace.h"
24 #include "hw/pci-host/mv64361.h"
25 #include "mv643xx.h"
26 
27 #define TYPE_MV64361_PCI_BRIDGE "mv64361-pcibridge"
28 
29 static void mv64361_pcibridge_class_init(ObjectClass *klass, void *data)
30 {
31     DeviceClass *dc = DEVICE_CLASS(klass);
32     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
33 
34     k->vendor_id = PCI_VENDOR_ID_MARVELL;
35     k->device_id = PCI_DEVICE_ID_MARVELL_MV6436X;
36     k->class_id = PCI_CLASS_BRIDGE_HOST;
37     /*
38      * PCI-facing part of the host bridge,
39      * not usable without the host-facing part
40      */
41     dc->user_creatable = false;
42 }
43 
44 static const TypeInfo mv64361_pcibridge_info = {
45     .name          = TYPE_MV64361_PCI_BRIDGE,
46     .parent        = TYPE_PCI_DEVICE,
47     .instance_size = sizeof(PCIDevice),
48     .class_init    = mv64361_pcibridge_class_init,
49     .interfaces = (InterfaceInfo[]) {
50         { INTERFACE_CONVENTIONAL_PCI_DEVICE },
51         { },
52     },
53 };
54 
55 
56 #define TYPE_MV64361_PCI "mv64361-pcihost"
57 OBJECT_DECLARE_SIMPLE_TYPE(MV64361PCIState, MV64361_PCI)
58 
59 struct MV64361PCIState {
60     PCIHostState parent_obj;
61 
62     uint8_t index;
63     MemoryRegion io;
64     MemoryRegion mem;
65     qemu_irq irq[PCI_NUM_PINS];
66 
67     uint32_t io_base;
68     uint32_t io_size;
69     uint32_t mem_base[4];
70     uint32_t mem_size[4];
71     uint64_t remap[5];
72 };
73 
74 static void mv64361_pcihost_set_irq(void *opaque, int n, int level)
75 {
76     MV64361PCIState *s = opaque;
77     qemu_set_irq(s->irq[n], level);
78 }
79 
80 static void mv64361_pcihost_realize(DeviceState *dev, Error **errp)
81 {
82     MV64361PCIState *s = MV64361_PCI(dev);
83     PCIHostState *h = PCI_HOST_BRIDGE(dev);
84     char *name;
85 
86     name = g_strdup_printf("pci%d-io", s->index);
87     memory_region_init(&s->io, OBJECT(dev), name, 0x10000);
88     g_free(name);
89     name = g_strdup_printf("pci%d-mem", s->index);
90     memory_region_init(&s->mem, OBJECT(dev), name, 1ULL << 32);
91     g_free(name);
92     name = g_strdup_printf("pci.%d", s->index);
93     h->bus = pci_register_root_bus(dev, name, mv64361_pcihost_set_irq,
94                                    pci_swizzle_map_irq_fn, dev,
95                                    &s->mem, &s->io, 0, 4, TYPE_PCI_BUS);
96     g_free(name);
97     pci_create_simple(h->bus, 0, TYPE_MV64361_PCI_BRIDGE);
98     qdev_init_gpio_out(dev, s->irq, ARRAY_SIZE(s->irq));
99 }
100 
101 static Property mv64361_pcihost_props[] = {
102     DEFINE_PROP_UINT8("index", MV64361PCIState, index, 0),
103     DEFINE_PROP_END_OF_LIST()
104 };
105 
106 static void mv64361_pcihost_class_init(ObjectClass *klass, void *data)
107 {
108     DeviceClass *dc = DEVICE_CLASS(klass);
109 
110     dc->realize = mv64361_pcihost_realize;
111     device_class_set_props(dc, mv64361_pcihost_props);
112     set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
113 }
114 
115 static const TypeInfo mv64361_pcihost_info = {
116        .name          = TYPE_MV64361_PCI,
117        .parent        = TYPE_PCI_HOST_BRIDGE,
118        .instance_size = sizeof(MV64361PCIState),
119        .class_init    = mv64361_pcihost_class_init,
120 };
121 
122 static void mv64361_pci_register_types(void)
123 {
124    type_register_static(&mv64361_pcihost_info);
125    type_register_static(&mv64361_pcibridge_info);
126 }
127 
128 type_init(mv64361_pci_register_types)
129 
130 
131 OBJECT_DECLARE_SIMPLE_TYPE(MV64361State, MV64361)
132 
133 struct MV64361State {
134     SysBusDevice parent_obj;
135 
136     MemoryRegion regs;
137     MV64361PCIState pci[2];
138     MemoryRegion cpu_win[19];
139     qemu_irq cpu_irq;
140 
141     /* registers state */
142     uint32_t cpu_conf;
143     uint32_t regs_base;
144     uint32_t base_addr_enable;
145     uint64_t main_int_cr;
146     uint64_t cpu0_int_mask;
147     uint32_t gpp_io;
148     uint32_t gpp_level;
149     uint32_t gpp_value;
150     uint32_t gpp_int_cr;
151     uint32_t gpp_int_mask;
152     bool gpp_int_level;
153 };
154 
155 enum mv64361_irq_cause {
156     MV64361_IRQ_DEVERR = 1,
157     MV64361_IRQ_DMAERR = 2,
158     MV64361_IRQ_CPUERR = 3,
159     MV64361_IRQ_IDMA0 = 4,
160     MV64361_IRQ_IDMA1 = 5,
161     MV64361_IRQ_IDMA2 = 6,
162     MV64361_IRQ_IDMA3 = 7,
163     MV64361_IRQ_TIMER0 = 8,
164     MV64361_IRQ_TIMER1 = 9,
165     MV64361_IRQ_TIMER2 = 10,
166     MV64361_IRQ_TIMER3 = 11,
167     MV64361_IRQ_PCI0 = 12,
168     MV64361_IRQ_SRAMERR = 13,
169     MV64361_IRQ_GBEERR = 14,
170     MV64361_IRQ_CERR = 15,
171     MV64361_IRQ_PCI1 = 16,
172     MV64361_IRQ_DRAMERR = 17,
173     MV64361_IRQ_WDNMI = 18,
174     MV64361_IRQ_WDE = 19,
175     MV64361_IRQ_PCI0IN = 20,
176     MV64361_IRQ_PCI0OUT = 21,
177     MV64361_IRQ_PCI1IN = 22,
178     MV64361_IRQ_PCI1OUT = 23,
179     MV64361_IRQ_P1_GPP0_7 = 24,
180     MV64361_IRQ_P1_GPP8_15 = 25,
181     MV64361_IRQ_P1_GPP16_23 = 26,
182     MV64361_IRQ_P1_GPP24_31 = 27,
183     MV64361_IRQ_P1_CPU_DB = 28,
184     /* 29-31: reserved */
185     MV64361_IRQ_GBE0 = 32,
186     MV64361_IRQ_GBE1 = 33,
187     MV64361_IRQ_GBE2 = 34,
188     /* 35: reserved */
189     MV64361_IRQ_SDMA0 = 36,
190     MV64361_IRQ_TWSI = 37,
191     MV64361_IRQ_SDMA1 = 38,
192     MV64361_IRQ_BRG = 39,
193     MV64361_IRQ_MPSC0 = 40,
194     MV64361_IRQ_MPSC1 = 41,
195     MV64361_IRQ_G0RX = 42,
196     MV64361_IRQ_G0TX = 43,
197     MV64361_IRQ_G0MISC = 44,
198     MV64361_IRQ_G1RX = 45,
199     MV64361_IRQ_G1TX = 46,
200     MV64361_IRQ_G1MISC = 47,
201     MV64361_IRQ_G2RX = 48,
202     MV64361_IRQ_G2TX = 49,
203     MV64361_IRQ_G2MISC = 50,
204     /* 51-55: reserved */
205     MV64361_IRQ_P0_GPP0_7 = 56,
206     MV64361_IRQ_P0_GPP8_15 = 57,
207     MV64361_IRQ_P0_GPP16_23 = 58,
208     MV64361_IRQ_P0_GPP24_31 = 59,
209     MV64361_IRQ_P0_CPU_DB = 60,
210     /* 61-63: reserved */
211 };
212 
213 PCIBus *mv64361_get_pci_bus(DeviceState *dev, int n)
214 {
215     MV64361State *mv = MV64361(dev);
216     return PCI_HOST_BRIDGE(&mv->pci[n])->bus;
217 }
218 
219 static void unmap_region(MemoryRegion *mr)
220 {
221     if (memory_region_is_mapped(mr)) {
222         memory_region_del_subregion(get_system_memory(), mr);
223         object_unparent(OBJECT(mr));
224     }
225 }
226 
227 static void map_pci_region(MemoryRegion *mr, MemoryRegion *parent,
228                            struct Object *owner, const char *name,
229                            hwaddr poffs, uint64_t size, hwaddr moffs)
230 {
231     memory_region_init_alias(mr, owner, name, parent, poffs, size);
232     memory_region_add_subregion(get_system_memory(), moffs, mr);
233     trace_mv64361_region_map(name, poffs, size, moffs);
234 }
235 
236 static void set_mem_windows(MV64361State *s, uint32_t val)
237 {
238     MV64361PCIState *p;
239     MemoryRegion *mr;
240     uint32_t mask;
241     int i;
242 
243     val &= 0x1fffff;
244     for (mask = 1, i = 0; i < 21; i++, mask <<= 1) {
245         if ((val & mask) != (s->base_addr_enable & mask)) {
246             trace_mv64361_region_enable(!(val & mask) ? "enable" : "disable", i);
247             /*
248              * 0-3 are SDRAM chip selects but we map all RAM directly
249              * 4-7 are device chip selects (not sure what those are)
250              * 8 is Boot device (ROM) chip select but we map that directly too
251              */
252             if (i == 9) {
253                 p = &s->pci[0];
254                 mr = &s->cpu_win[i];
255                 unmap_region(mr);
256                 if (!(val & mask)) {
257                     map_pci_region(mr, &p->io, OBJECT(s), "pci0-io-win",
258                                    p->remap[4], (p->io_size + 1) << 16,
259                                    (p->io_base & 0xfffff) << 16);
260                 }
261             } else if (i == 10) {
262                 p = &s->pci[0];
263                 mr = &s->cpu_win[i];
264                 unmap_region(mr);
265                 if (!(val & mask)) {
266                     map_pci_region(mr, &p->mem, OBJECT(s), "pci0-mem0-win",
267                                    p->remap[0], (p->mem_size[0] + 1) << 16,
268                                    (p->mem_base[0] & 0xfffff) << 16);
269                 }
270             } else if (i == 11) {
271                 p = &s->pci[0];
272                 mr = &s->cpu_win[i];
273                 unmap_region(mr);
274                 if (!(val & mask)) {
275                     map_pci_region(mr, &p->mem, OBJECT(s), "pci0-mem1-win",
276                                    p->remap[1], (p->mem_size[1] + 1) << 16,
277                                    (p->mem_base[1] & 0xfffff) << 16);
278                 }
279             } else if (i == 12) {
280                 p = &s->pci[0];
281                 mr = &s->cpu_win[i];
282                 unmap_region(mr);
283                 if (!(val & mask)) {
284                     map_pci_region(mr, &p->mem, OBJECT(s), "pci0-mem2-win",
285                                    p->remap[2], (p->mem_size[2] + 1) << 16,
286                                    (p->mem_base[2] & 0xfffff) << 16);
287                 }
288             } else if (i == 13) {
289                 p = &s->pci[0];
290                 mr = &s->cpu_win[i];
291                 unmap_region(mr);
292                 if (!(val & mask)) {
293                     map_pci_region(mr, &p->mem, OBJECT(s), "pci0-mem3-win",
294                                    p->remap[3], (p->mem_size[3] + 1) << 16,
295                                    (p->mem_base[3] & 0xfffff) << 16);
296                 }
297             } else if (i == 14) {
298                 p = &s->pci[1];
299                 mr = &s->cpu_win[i];
300                 unmap_region(mr);
301                 if (!(val & mask)) {
302                     map_pci_region(mr, &p->io, OBJECT(s), "pci1-io-win",
303                                    p->remap[4], (p->io_size + 1) << 16,
304                                    (p->io_base & 0xfffff) << 16);
305                 }
306             } else if (i == 15) {
307                 p = &s->pci[1];
308                 mr = &s->cpu_win[i];
309                 unmap_region(mr);
310                 if (!(val & mask)) {
311                     map_pci_region(mr, &p->mem, OBJECT(s), "pci1-mem0-win",
312                                    p->remap[0], (p->mem_size[0] + 1) << 16,
313                                    (p->mem_base[0] & 0xfffff) << 16);
314                 }
315             } else if (i == 16) {
316                 p = &s->pci[1];
317                 mr = &s->cpu_win[i];
318                 unmap_region(mr);
319                 if (!(val & mask)) {
320                     map_pci_region(mr, &p->mem, OBJECT(s), "pci1-mem1-win",
321                                    p->remap[1], (p->mem_size[1] + 1) << 16,
322                                    (p->mem_base[1] & 0xfffff) << 16);
323                 }
324             } else if (i == 17) {
325                 p = &s->pci[1];
326                 mr = &s->cpu_win[i];
327                 unmap_region(mr);
328                 if (!(val & mask)) {
329                     map_pci_region(mr, &p->mem, OBJECT(s), "pci1-mem2-win",
330                                    p->remap[2], (p->mem_size[2] + 1) << 16,
331                                    (p->mem_base[2] & 0xfffff) << 16);
332                 }
333             } else if (i == 18) {
334                 p = &s->pci[1];
335                 mr = &s->cpu_win[i];
336                 unmap_region(mr);
337                 if (!(val & mask)) {
338                     map_pci_region(mr, &p->mem, OBJECT(s), "pci1-mem3-win",
339                                    p->remap[3], (p->mem_size[3] + 1) << 16,
340                                    (p->mem_base[3] & 0xfffff) << 16);
341                 }
342             /* 19 is integrated SRAM */
343             } else if (i == 20) {
344                 mr = &s->regs;
345                 unmap_region(mr);
346                 if (!(val & mask)) {
347                     memory_region_add_subregion(get_system_memory(),
348                         (s->regs_base & 0xfffff) << 16, mr);
349                 }
350             }
351         }
352     }
353     s->base_addr_enable = val;
354 }
355 
356 static void mv64361_update_irq(void *opaque, int n, int level)
357 {
358     MV64361State *s = opaque;
359     uint64_t val = s->main_int_cr;
360 
361     if (level) {
362         val |= BIT_ULL(n);
363     } else {
364         val &= ~BIT_ULL(n);
365     }
366     if ((s->main_int_cr & s->cpu0_int_mask) != (val & s->cpu0_int_mask)) {
367         qemu_set_irq(s->cpu_irq, level);
368     }
369     s->main_int_cr = val;
370 }
371 
372 static uint64_t mv64361_read(void *opaque, hwaddr addr, unsigned int size)
373 {
374     MV64361State *s = MV64361(opaque);
375     uint32_t ret = 0;
376 
377     switch (addr) {
378     case MV64340_CPU_CONFIG:
379         ret = s->cpu_conf;
380         break;
381     case MV64340_PCI_0_IO_BASE_ADDR:
382         ret = s->pci[0].io_base;
383         break;
384     case MV64340_PCI_0_IO_SIZE:
385         ret = s->pci[0].io_size;
386         break;
387     case MV64340_PCI_0_IO_ADDR_REMAP:
388         ret = s->pci[0].remap[4] >> 16;
389         break;
390     case MV64340_PCI_0_MEMORY0_BASE_ADDR:
391         ret = s->pci[0].mem_base[0];
392         break;
393     case MV64340_PCI_0_MEMORY0_SIZE:
394         ret = s->pci[0].mem_size[0];
395         break;
396     case MV64340_PCI_0_MEMORY0_LOW_ADDR_REMAP:
397         ret = (s->pci[0].remap[0] & 0xffff0000) >> 16;
398         break;
399     case MV64340_PCI_0_MEMORY0_HIGH_ADDR_REMAP:
400         ret = s->pci[0].remap[0] >> 32;
401         break;
402     case MV64340_PCI_0_MEMORY1_BASE_ADDR:
403         ret = s->pci[0].mem_base[1];
404         break;
405     case MV64340_PCI_0_MEMORY1_SIZE:
406         ret = s->pci[0].mem_size[1];
407         break;
408     case MV64340_PCI_0_MEMORY1_LOW_ADDR_REMAP:
409         ret = (s->pci[0].remap[1] & 0xffff0000) >> 16;
410         break;
411     case MV64340_PCI_0_MEMORY1_HIGH_ADDR_REMAP:
412         ret = s->pci[0].remap[1] >> 32;
413         break;
414     case MV64340_PCI_0_MEMORY2_BASE_ADDR:
415         ret = s->pci[0].mem_base[2];
416         break;
417     case MV64340_PCI_0_MEMORY2_SIZE:
418         ret = s->pci[0].mem_size[2];
419         break;
420     case MV64340_PCI_0_MEMORY2_LOW_ADDR_REMAP:
421         ret = (s->pci[0].remap[2] & 0xffff0000) >> 16;
422         break;
423     case MV64340_PCI_0_MEMORY2_HIGH_ADDR_REMAP:
424         ret = s->pci[0].remap[2] >> 32;
425         break;
426     case MV64340_PCI_0_MEMORY3_BASE_ADDR:
427         ret = s->pci[0].mem_base[3];
428         break;
429     case MV64340_PCI_0_MEMORY3_SIZE:
430         ret = s->pci[0].mem_size[3];
431         break;
432     case MV64340_PCI_0_MEMORY3_LOW_ADDR_REMAP:
433         ret = (s->pci[0].remap[3] & 0xffff0000) >> 16;
434         break;
435     case MV64340_PCI_0_MEMORY3_HIGH_ADDR_REMAP:
436         ret = s->pci[0].remap[3] >> 32;
437         break;
438     case MV64340_PCI_1_IO_BASE_ADDR:
439         ret = s->pci[1].io_base;
440         break;
441     case MV64340_PCI_1_IO_SIZE:
442         ret = s->pci[1].io_size;
443         break;
444     case MV64340_PCI_1_IO_ADDR_REMAP:
445         ret = s->pci[1].remap[4] >> 16;
446         break;
447     case MV64340_PCI_1_MEMORY0_BASE_ADDR:
448         ret = s->pci[1].mem_base[0];
449         break;
450     case MV64340_PCI_1_MEMORY0_SIZE:
451         ret = s->pci[1].mem_size[0];
452         break;
453     case MV64340_PCI_1_MEMORY0_LOW_ADDR_REMAP:
454         ret = (s->pci[1].remap[0] & 0xffff0000) >> 16;
455         break;
456     case MV64340_PCI_1_MEMORY0_HIGH_ADDR_REMAP:
457         ret = s->pci[1].remap[0] >> 32;
458         break;
459     case MV64340_PCI_1_MEMORY1_BASE_ADDR:
460         ret = s->pci[1].mem_base[1];
461         break;
462     case MV64340_PCI_1_MEMORY1_SIZE:
463         ret = s->pci[1].mem_size[1];
464         break;
465     case MV64340_PCI_1_MEMORY1_LOW_ADDR_REMAP:
466         ret = (s->pci[1].remap[1] & 0xffff0000) >> 16;
467         break;
468     case MV64340_PCI_1_MEMORY1_HIGH_ADDR_REMAP:
469         ret = s->pci[1].remap[1] >> 32;
470         break;
471     case MV64340_PCI_1_MEMORY2_BASE_ADDR:
472         ret = s->pci[1].mem_base[2];
473         break;
474     case MV64340_PCI_1_MEMORY2_SIZE:
475         ret = s->pci[1].mem_size[2];
476         break;
477     case MV64340_PCI_1_MEMORY2_LOW_ADDR_REMAP:
478         ret = (s->pci[1].remap[2] & 0xffff0000) >> 16;
479         break;
480     case MV64340_PCI_1_MEMORY2_HIGH_ADDR_REMAP:
481         ret = s->pci[1].remap[2] >> 32;
482         break;
483     case MV64340_PCI_1_MEMORY3_BASE_ADDR:
484         ret = s->pci[1].mem_base[3];
485         break;
486     case MV64340_PCI_1_MEMORY3_SIZE:
487         ret = s->pci[1].mem_size[3];
488         break;
489     case MV64340_PCI_1_MEMORY3_LOW_ADDR_REMAP:
490         ret = (s->pci[1].remap[3] & 0xffff0000) >> 16;
491         break;
492     case MV64340_PCI_1_MEMORY3_HIGH_ADDR_REMAP:
493         ret = s->pci[1].remap[3] >> 32;
494         break;
495     case MV64340_INTERNAL_SPACE_BASE_ADDR:
496         ret = s->regs_base;
497         break;
498     case MV64340_BASE_ADDR_ENABLE:
499         ret = s->base_addr_enable;
500         break;
501     case MV64340_PCI_0_CONFIG_ADDR:
502         ret = pci_host_conf_le_ops.read(PCI_HOST_BRIDGE(&s->pci[0]), 0, size);
503         break;
504     case MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG ...
505          MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG + 3:
506         ret = pci_host_data_le_ops.read(PCI_HOST_BRIDGE(&s->pci[0]),
507                   addr - MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG, size);
508         break;
509     case MV64340_PCI_1_CONFIG_ADDR:
510         ret = pci_host_conf_le_ops.read(PCI_HOST_BRIDGE(&s->pci[1]), 0, size);
511         break;
512     case MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG ...
513          MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG + 3:
514         ret = pci_host_data_le_ops.read(PCI_HOST_BRIDGE(&s->pci[1]),
515                   addr - MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG, size);
516         break;
517     case MV64340_PCI_1_INTERRUPT_ACKNOWLEDGE_VIRTUAL_REG:
518         /* FIXME: Should this be sent via the PCI bus somehow? */
519         if (s->gpp_int_level && (s->gpp_value & BIT(31))) {
520             ret = pic_read_irq(isa_pic);
521         }
522         break;
523     case MV64340_MAIN_INTERRUPT_CAUSE_LOW:
524         ret = s->main_int_cr;
525         break;
526     case MV64340_MAIN_INTERRUPT_CAUSE_HIGH:
527         ret = s->main_int_cr >> 32;
528         break;
529     case MV64340_CPU_INTERRUPT0_MASK_LOW:
530         ret = s->cpu0_int_mask;
531         break;
532     case MV64340_CPU_INTERRUPT0_MASK_HIGH:
533         ret = s->cpu0_int_mask >> 32;
534         break;
535     case MV64340_CPU_INTERRUPT0_SELECT_CAUSE:
536         ret = s->main_int_cr;
537         if (s->main_int_cr & s->cpu0_int_mask) {
538             if (!(s->main_int_cr & s->cpu0_int_mask & 0xffffffff)) {
539                 ret = s->main_int_cr >> 32 | BIT(30);
540             } else if ((s->main_int_cr & s->cpu0_int_mask) >> 32) {
541                 ret |= BIT(31);
542             }
543         }
544         break;
545     case MV64340_ETH_PHY_ADDR:
546         ret = 0x98;
547         break;
548     case MV64340_ETH_SMI:
549         ret = BIT(27);
550         break;
551     case MV64340_CUNIT_ARBITER_CONTROL_REG:
552         ret = 0x11ff0000 | (s->gpp_int_level << 10);
553         break;
554     case MV64340_GPP_IO_CONTROL:
555         ret = s->gpp_io;
556         break;
557     case MV64340_GPP_LEVEL_CONTROL:
558         ret = s->gpp_level;
559         break;
560     case MV64340_GPP_VALUE:
561         ret = s->gpp_value;
562         break;
563     case MV64340_GPP_VALUE_SET:
564     case MV64340_GPP_VALUE_CLEAR:
565         ret = 0;
566         break;
567     case MV64340_GPP_INTERRUPT_CAUSE:
568         ret = s->gpp_int_cr;
569         break;
570     case MV64340_GPP_INTERRUPT_MASK0:
571     case MV64340_GPP_INTERRUPT_MASK1:
572         ret = s->gpp_int_mask;
573         break;
574     default:
575         qemu_log_mask(LOG_UNIMP, "%s: Unimplemented register read 0x%"
576                       HWADDR_PRIx "\n", __func__, addr);
577         break;
578     }
579     if (addr != MV64340_PCI_1_INTERRUPT_ACKNOWLEDGE_VIRTUAL_REG) {
580         trace_mv64361_reg_read(addr, ret);
581     }
582     return ret;
583 }
584 
585 static void warn_swap_bit(uint64_t val)
586 {
587     if ((val & 0x3000000ULL) >> 24 != 1) {
588         qemu_log_mask(LOG_UNIMP, "%s: Data swap not implemented", __func__);
589     }
590 }
591 
592 static void mv64361_set_pci_mem_remap(MV64361State *s, int bus, int idx,
593                                       uint64_t val, bool high)
594 {
595     if (high) {
596         s->pci[bus].remap[idx] = val;
597     } else {
598         s->pci[bus].remap[idx] &= 0xffffffff00000000ULL;
599         s->pci[bus].remap[idx] |= (val & 0xffffULL) << 16;
600     }
601 }
602 
603 static void mv64361_write(void *opaque, hwaddr addr, uint64_t val,
604                           unsigned int size)
605 {
606     MV64361State *s = MV64361(opaque);
607 
608     trace_mv64361_reg_write(addr, val);
609     switch (addr) {
610     case MV64340_CPU_CONFIG:
611         s->cpu_conf = val & 0xe4e3bffULL;
612         s->cpu_conf |= BIT(23);
613         break;
614     case MV64340_PCI_0_IO_BASE_ADDR:
615         s->pci[0].io_base = val & 0x30fffffULL;
616         warn_swap_bit(val);
617         if (!(s->cpu_conf & BIT(27))) {
618             s->pci[0].remap[4] = (val & 0xffffULL) << 16;
619         }
620         break;
621     case MV64340_PCI_0_IO_SIZE:
622         s->pci[0].io_size = val & 0xffffULL;
623         break;
624     case MV64340_PCI_0_IO_ADDR_REMAP:
625         s->pci[0].remap[4] = (val & 0xffffULL) << 16;
626         break;
627     case MV64340_PCI_0_MEMORY0_BASE_ADDR:
628         s->pci[0].mem_base[0] = val & 0x70fffffULL;
629         warn_swap_bit(val);
630         if (!(s->cpu_conf & BIT(27))) {
631             mv64361_set_pci_mem_remap(s, 0, 0, val, false);
632         }
633         break;
634     case MV64340_PCI_0_MEMORY0_SIZE:
635         s->pci[0].mem_size[0] = val & 0xffffULL;
636         break;
637     case MV64340_PCI_0_MEMORY0_LOW_ADDR_REMAP:
638     case MV64340_PCI_0_MEMORY0_HIGH_ADDR_REMAP:
639         mv64361_set_pci_mem_remap(s, 0, 0, val,
640             (addr == MV64340_PCI_0_MEMORY0_HIGH_ADDR_REMAP));
641         break;
642     case MV64340_PCI_0_MEMORY1_BASE_ADDR:
643         s->pci[0].mem_base[1] = val & 0x70fffffULL;
644         warn_swap_bit(val);
645         if (!(s->cpu_conf & BIT(27))) {
646             mv64361_set_pci_mem_remap(s, 0, 1, val, false);
647         }
648         break;
649     case MV64340_PCI_0_MEMORY1_SIZE:
650         s->pci[0].mem_size[1] = val & 0xffffULL;
651         break;
652     case MV64340_PCI_0_MEMORY1_LOW_ADDR_REMAP:
653     case MV64340_PCI_0_MEMORY1_HIGH_ADDR_REMAP:
654         mv64361_set_pci_mem_remap(s, 0, 1, val,
655             (addr == MV64340_PCI_0_MEMORY1_HIGH_ADDR_REMAP));
656         break;
657     case MV64340_PCI_0_MEMORY2_BASE_ADDR:
658         s->pci[0].mem_base[2] = val & 0x70fffffULL;
659         warn_swap_bit(val);
660         if (!(s->cpu_conf & BIT(27))) {
661             mv64361_set_pci_mem_remap(s, 0, 2, val, false);
662         }
663         break;
664     case MV64340_PCI_0_MEMORY2_SIZE:
665         s->pci[0].mem_size[2] = val & 0xffffULL;
666         break;
667     case MV64340_PCI_0_MEMORY2_LOW_ADDR_REMAP:
668     case MV64340_PCI_0_MEMORY2_HIGH_ADDR_REMAP:
669         mv64361_set_pci_mem_remap(s, 0, 2, val,
670             (addr == MV64340_PCI_0_MEMORY2_HIGH_ADDR_REMAP));
671         break;
672     case MV64340_PCI_0_MEMORY3_BASE_ADDR:
673         s->pci[0].mem_base[3] = val & 0x70fffffULL;
674         warn_swap_bit(val);
675         if (!(s->cpu_conf & BIT(27))) {
676             mv64361_set_pci_mem_remap(s, 0, 3, val, false);
677         }
678         break;
679     case MV64340_PCI_0_MEMORY3_SIZE:
680         s->pci[0].mem_size[3] = val & 0xffffULL;
681         break;
682     case MV64340_PCI_0_MEMORY3_LOW_ADDR_REMAP:
683     case MV64340_PCI_0_MEMORY3_HIGH_ADDR_REMAP:
684         mv64361_set_pci_mem_remap(s, 0, 3, val,
685             (addr == MV64340_PCI_0_MEMORY3_HIGH_ADDR_REMAP));
686         break;
687     case MV64340_PCI_1_IO_BASE_ADDR:
688         s->pci[1].io_base = val & 0x30fffffULL;
689         warn_swap_bit(val);
690         if (!(s->cpu_conf & BIT(27))) {
691             s->pci[1].remap[4] = (val & 0xffffULL) << 16;
692         }
693         break;
694     case MV64340_PCI_1_IO_SIZE:
695         s->pci[1].io_size = val & 0xffffULL;
696         break;
697     case MV64340_PCI_1_MEMORY0_BASE_ADDR:
698         s->pci[1].mem_base[0] = val & 0x70fffffULL;
699         warn_swap_bit(val);
700         if (!(s->cpu_conf & BIT(27))) {
701             mv64361_set_pci_mem_remap(s, 1, 0, val, false);
702         }
703         break;
704     case MV64340_PCI_1_MEMORY0_SIZE:
705         s->pci[1].mem_size[0] = val & 0xffffULL;
706         break;
707     case MV64340_PCI_1_MEMORY0_LOW_ADDR_REMAP:
708     case MV64340_PCI_1_MEMORY0_HIGH_ADDR_REMAP:
709         mv64361_set_pci_mem_remap(s, 1, 0, val,
710             (addr == MV64340_PCI_1_MEMORY0_HIGH_ADDR_REMAP));
711         break;
712     case MV64340_PCI_1_MEMORY1_BASE_ADDR:
713         s->pci[1].mem_base[1] = val & 0x70fffffULL;
714         warn_swap_bit(val);
715         if (!(s->cpu_conf & BIT(27))) {
716             mv64361_set_pci_mem_remap(s, 1, 1, val, false);
717         }
718         break;
719     case MV64340_PCI_1_MEMORY1_SIZE:
720         s->pci[1].mem_size[1] = val & 0xffffULL;
721         break;
722     case MV64340_PCI_1_MEMORY1_LOW_ADDR_REMAP:
723     case MV64340_PCI_1_MEMORY1_HIGH_ADDR_REMAP:
724         mv64361_set_pci_mem_remap(s, 1, 1, val,
725             (addr == MV64340_PCI_1_MEMORY1_HIGH_ADDR_REMAP));
726         break;
727     case MV64340_PCI_1_MEMORY2_BASE_ADDR:
728         s->pci[1].mem_base[2] = val & 0x70fffffULL;
729         warn_swap_bit(val);
730         if (!(s->cpu_conf & BIT(27))) {
731             mv64361_set_pci_mem_remap(s, 1, 2, val, false);
732         }
733         break;
734     case MV64340_PCI_1_MEMORY2_SIZE:
735         s->pci[1].mem_size[2] = val & 0xffffULL;
736         break;
737     case MV64340_PCI_1_MEMORY2_LOW_ADDR_REMAP:
738     case MV64340_PCI_1_MEMORY2_HIGH_ADDR_REMAP:
739         mv64361_set_pci_mem_remap(s, 1, 2, val,
740             (addr == MV64340_PCI_1_MEMORY2_HIGH_ADDR_REMAP));
741         break;
742     case MV64340_PCI_1_MEMORY3_BASE_ADDR:
743         s->pci[1].mem_base[3] = val & 0x70fffffULL;
744         warn_swap_bit(val);
745         if (!(s->cpu_conf & BIT(27))) {
746             mv64361_set_pci_mem_remap(s, 1, 3, val, false);
747         }
748         break;
749     case MV64340_PCI_1_MEMORY3_SIZE:
750         s->pci[1].mem_size[3] = val & 0xffffULL;
751         break;
752     case MV64340_PCI_1_MEMORY3_LOW_ADDR_REMAP:
753     case MV64340_PCI_1_MEMORY3_HIGH_ADDR_REMAP:
754         mv64361_set_pci_mem_remap(s, 1, 3, val,
755             (addr == MV64340_PCI_1_MEMORY3_HIGH_ADDR_REMAP));
756         break;
757     case MV64340_INTERNAL_SPACE_BASE_ADDR:
758         s->regs_base = val & 0xfffffULL;
759         break;
760     case MV64340_BASE_ADDR_ENABLE:
761         set_mem_windows(s, val);
762         break;
763     case MV64340_PCI_0_CONFIG_ADDR:
764         pci_host_conf_le_ops.write(PCI_HOST_BRIDGE(&s->pci[0]), 0, val, size);
765         break;
766     case MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG ...
767          MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG + 3:
768         pci_host_data_le_ops.write(PCI_HOST_BRIDGE(&s->pci[0]),
769             addr - MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG, val, size);
770         break;
771     case MV64340_PCI_1_CONFIG_ADDR:
772         pci_host_conf_le_ops.write(PCI_HOST_BRIDGE(&s->pci[1]), 0, val, size);
773         break;
774     case MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG ...
775          MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG + 3:
776         pci_host_data_le_ops.write(PCI_HOST_BRIDGE(&s->pci[1]),
777             addr - MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG, val, size);
778         break;
779     case MV64340_CPU_INTERRUPT0_MASK_LOW:
780         s->cpu0_int_mask &= 0xffffffff00000000ULL;
781         s->cpu0_int_mask |= val & 0xffffffffULL;
782         break;
783     case MV64340_CPU_INTERRUPT0_MASK_HIGH:
784         s->cpu0_int_mask &= 0xffffffffULL;
785         s->cpu0_int_mask |= val << 32;
786         break;
787     case MV64340_CUNIT_ARBITER_CONTROL_REG:
788         s->gpp_int_level = !!(val & BIT(10));
789         break;
790     case MV64340_GPP_IO_CONTROL:
791         s->gpp_io = val;
792         break;
793     case MV64340_GPP_LEVEL_CONTROL:
794         s->gpp_level = val;
795         break;
796     case MV64340_GPP_VALUE:
797         s->gpp_value &= ~s->gpp_io;
798         s->gpp_value |= val & s->gpp_io;
799         break;
800     case MV64340_GPP_VALUE_SET:
801         s->gpp_value |= val & s->gpp_io;
802         break;
803     case MV64340_GPP_VALUE_CLEAR:
804         s->gpp_value &= ~(val & s->gpp_io);
805         break;
806     case MV64340_GPP_INTERRUPT_CAUSE:
807         if (!s->gpp_int_level && val != s->gpp_int_cr) {
808             int i;
809             uint32_t ch = s->gpp_int_cr ^ val;
810             s->gpp_int_cr = val;
811             for (i = 0; i < 4; i++) {
812                 if ((ch & 0xff << i) && !(val & 0xff << i)) {
813                     mv64361_update_irq(opaque, MV64361_IRQ_P0_GPP0_7 + i, 0);
814                 }
815             }
816         } else {
817             s->gpp_int_cr = val;
818         }
819         break;
820     case MV64340_GPP_INTERRUPT_MASK0:
821     case MV64340_GPP_INTERRUPT_MASK1:
822         s->gpp_int_mask = val;
823         break;
824     default:
825         qemu_log_mask(LOG_UNIMP, "%s: Unimplemented register write 0x%"
826                       HWADDR_PRIx " = %"PRIx64"\n", __func__, addr, val);
827         break;
828     }
829 }
830 
831 static const MemoryRegionOps mv64361_ops = {
832     .read = mv64361_read,
833     .write = mv64361_write,
834     .valid.min_access_size = 1,
835     .valid.max_access_size = 4,
836     .endianness = DEVICE_LITTLE_ENDIAN,
837 };
838 
839 static void mv64361_gpp_irq(void *opaque, int n, int level)
840 {
841     MV64361State *s = opaque;
842     uint32_t mask = BIT(n);
843     uint32_t val = s->gpp_value & ~mask;
844 
845     if (s->gpp_level & mask) {
846         level = !level;
847     }
848     val |= level << n;
849     if (val > s->gpp_value) {
850         s->gpp_value = val;
851         s->gpp_int_cr |= mask;
852         if (s->gpp_int_mask & mask) {
853             mv64361_update_irq(opaque, MV64361_IRQ_P0_GPP0_7 + n / 8, 1);
854         }
855     } else if (val < s->gpp_value) {
856         int b = n / 8;
857         s->gpp_value = val;
858         if (s->gpp_int_level && !(val & 0xff << b)) {
859             mv64361_update_irq(opaque, MV64361_IRQ_P0_GPP0_7 + b, 0);
860         }
861     }
862 }
863 
864 static void mv64361_realize(DeviceState *dev, Error **errp)
865 {
866     MV64361State *s = MV64361(dev);
867     int i;
868 
869     s->base_addr_enable = 0x1fffff;
870     memory_region_init_io(&s->regs, OBJECT(s), &mv64361_ops, s,
871                           TYPE_MV64361, 0x10000);
872     sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->regs);
873     for (i = 0; i < 2; i++) {
874         g_autofree char *name = g_strdup_printf("pcihost%d", i);
875         object_initialize_child(OBJECT(dev), name, &s->pci[i],
876                                 TYPE_MV64361_PCI);
877         DeviceState *pci = DEVICE(&s->pci[i]);
878         qdev_prop_set_uint8(pci, "index", i);
879         sysbus_realize_and_unref(SYS_BUS_DEVICE(pci), &error_fatal);
880     }
881     sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->cpu_irq);
882     qdev_init_gpio_in_named(dev, mv64361_gpp_irq, "gpp", 32);
883 }
884 
885 static void mv64361_reset(DeviceState *dev)
886 {
887     MV64361State *s = MV64361(dev);
888     int i, j;
889 
890     /*
891      * These values may be board specific
892      * Real chip supports init from an eprom but that's not modelled
893      */
894     set_mem_windows(s, 0x1fffff);
895     s->cpu_conf = 0x28000ff;
896     s->regs_base = 0x100f100;
897     s->pci[0].io_base = 0x100f800;
898     s->pci[0].io_size = 0xff;
899     s->pci[0].mem_base[0] = 0x100c000;
900     s->pci[0].mem_size[0] = 0x1fff;
901     s->pci[0].mem_base[1] = 0x100f900;
902     s->pci[0].mem_size[1] = 0xff;
903     s->pci[0].mem_base[2] = 0x100f400;
904     s->pci[0].mem_size[2] = 0x1ff;
905     s->pci[0].mem_base[3] = 0x100f600;
906     s->pci[0].mem_size[3] = 0x1ff;
907     s->pci[1].io_base = 0x100fe00;
908     s->pci[1].io_size = 0xff;
909     s->pci[1].mem_base[0] = 0x1008000;
910     s->pci[1].mem_size[0] = 0x3fff;
911     s->pci[1].mem_base[1] = 0x100fd00;
912     s->pci[1].mem_size[1] = 0xff;
913     s->pci[1].mem_base[2] = 0x1002600;
914     s->pci[1].mem_size[2] = 0x1ff;
915     s->pci[1].mem_base[3] = 0x100ff80;
916     s->pci[1].mem_size[3] = 0x7f;
917     for (i = 0; i < 2; i++) {
918         for (j = 0; j < 4; j++) {
919             s->pci[i].remap[j] = s->pci[i].mem_base[j] << 16;
920         }
921     }
922     s->pci[0].remap[1] = 0;
923     s->pci[1].remap[1] = 0;
924     set_mem_windows(s, 0xfbfff);
925 }
926 
927 static void mv64361_class_init(ObjectClass *klass, void *data)
928 {
929     DeviceClass *dc = DEVICE_CLASS(klass);
930 
931     dc->realize = mv64361_realize;
932     device_class_set_legacy_reset(dc, mv64361_reset);
933 }
934 
935 static const TypeInfo mv64361_type_info = {
936     .name = TYPE_MV64361,
937     .parent = TYPE_SYS_BUS_DEVICE,
938     .instance_size = sizeof(MV64361State),
939     .class_init = mv64361_class_init,
940 };
941 
942 static void mv64361_register_types(void)
943 {
944     type_register_static(&mv64361_type_info);
945 }
946 
947 type_init(mv64361_register_types)
948