xref: /openbmc/qemu/hw/pci-host/mv64361.c (revision 8c6631e6)
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/hw.h"
15 #include "hw/sysbus.h"
16 #include "hw/pci/pci_device.h"
17 #include "hw/pci/pci_host.h"
18 #include "hw/irq.h"
19 #include "hw/intc/i8259.h"
20 #include "hw/qdev-properties.h"
21 #include "exec/address-spaces.h"
22 #include "qemu/log.h"
23 #include "qemu/error-report.h"
24 #include "trace.h"
25 #include "hw/pci-host/mv64361.h"
26 #include "mv643xx.h"
27 
28 #define TYPE_MV64361_PCI_BRIDGE "mv64361-pcibridge"
29 
30 static void mv64361_pcibridge_class_init(ObjectClass *klass, void *data)
31 {
32     DeviceClass *dc = DEVICE_CLASS(klass);
33     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
34 
35     k->vendor_id = PCI_VENDOR_ID_MARVELL;
36     k->device_id = PCI_DEVICE_ID_MARVELL_MV6436X;
37     k->class_id = PCI_CLASS_BRIDGE_HOST;
38     /*
39      * PCI-facing part of the host bridge,
40      * not usable without the host-facing part
41      */
42     dc->user_creatable = false;
43 }
44 
45 static const TypeInfo mv64361_pcibridge_info = {
46     .name          = TYPE_MV64361_PCI_BRIDGE,
47     .parent        = TYPE_PCI_DEVICE,
48     .instance_size = sizeof(PCIDevice),
49     .class_init    = mv64361_pcibridge_class_init,
50     .interfaces = (InterfaceInfo[]) {
51         { INTERFACE_CONVENTIONAL_PCI_DEVICE },
52         { },
53     },
54 };
55 
56 
57 #define TYPE_MV64361_PCI "mv64361-pcihost"
58 OBJECT_DECLARE_SIMPLE_TYPE(MV64361PCIState, MV64361_PCI)
59 
60 struct MV64361PCIState {
61     PCIHostState parent_obj;
62 
63     uint8_t index;
64     MemoryRegion io;
65     MemoryRegion mem;
66     qemu_irq irq[PCI_NUM_PINS];
67 
68     uint32_t io_base;
69     uint32_t io_size;
70     uint32_t mem_base[4];
71     uint32_t mem_size[4];
72     uint64_t remap[5];
73 };
74 
75 static void mv64361_pcihost_set_irq(void *opaque, int n, int level)
76 {
77     MV64361PCIState *s = opaque;
78     qemu_set_irq(s->irq[n], level);
79 }
80 
81 static void mv64361_pcihost_realize(DeviceState *dev, Error **errp)
82 {
83     MV64361PCIState *s = MV64361_PCI(dev);
84     PCIHostState *h = PCI_HOST_BRIDGE(dev);
85     char *name;
86 
87     name = g_strdup_printf("pci%d-io", s->index);
88     memory_region_init(&s->io, OBJECT(dev), name, 0x10000);
89     g_free(name);
90     name = g_strdup_printf("pci%d-mem", s->index);
91     memory_region_init(&s->mem, OBJECT(dev), name, 1ULL << 32);
92     g_free(name);
93     name = g_strdup_printf("pci.%d", s->index);
94     h->bus = pci_register_root_bus(dev, name, mv64361_pcihost_set_irq,
95                                    pci_swizzle_map_irq_fn, dev,
96                                    &s->mem, &s->io, 0, 4, TYPE_PCI_BUS);
97     g_free(name);
98     pci_create_simple(h->bus, 0, TYPE_MV64361_PCI_BRIDGE);
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_CUNIT_ARBITER_CONTROL_REG:
546         ret = 0x11ff0000 | (s->gpp_int_level << 10);
547         break;
548     case MV64340_GPP_IO_CONTROL:
549         ret = s->gpp_io;
550         break;
551     case MV64340_GPP_LEVEL_CONTROL:
552         ret = s->gpp_level;
553         break;
554     case MV64340_GPP_VALUE:
555         ret = s->gpp_value;
556         break;
557     case MV64340_GPP_VALUE_SET:
558     case MV64340_GPP_VALUE_CLEAR:
559         ret = 0;
560         break;
561     case MV64340_GPP_INTERRUPT_CAUSE:
562         ret = s->gpp_int_cr;
563         break;
564     case MV64340_GPP_INTERRUPT_MASK0:
565     case MV64340_GPP_INTERRUPT_MASK1:
566         ret = s->gpp_int_mask;
567         break;
568     default:
569         qemu_log_mask(LOG_UNIMP, "%s: Unimplemented register read 0x%"
570                       HWADDR_PRIx "\n", __func__, addr);
571         break;
572     }
573     if (addr != MV64340_PCI_1_INTERRUPT_ACKNOWLEDGE_VIRTUAL_REG) {
574         trace_mv64361_reg_read(addr, ret);
575     }
576     return ret;
577 }
578 
579 static void warn_swap_bit(uint64_t val)
580 {
581     if ((val & 0x3000000ULL) >> 24 != 1) {
582         qemu_log_mask(LOG_UNIMP, "%s: Data swap not implemented", __func__);
583     }
584 }
585 
586 static void mv64361_set_pci_mem_remap(MV64361State *s, int bus, int idx,
587                                       uint64_t val, bool high)
588 {
589     if (high) {
590         s->pci[bus].remap[idx] = val;
591     } else {
592         s->pci[bus].remap[idx] &= 0xffffffff00000000ULL;
593         s->pci[bus].remap[idx] |= (val & 0xffffULL) << 16;
594     }
595 }
596 
597 static void mv64361_write(void *opaque, hwaddr addr, uint64_t val,
598                           unsigned int size)
599 {
600     MV64361State *s = MV64361(opaque);
601 
602     trace_mv64361_reg_write(addr, val);
603     switch (addr) {
604     case MV64340_CPU_CONFIG:
605         s->cpu_conf = val & 0xe4e3bffULL;
606         s->cpu_conf |= BIT(23);
607         break;
608     case MV64340_PCI_0_IO_BASE_ADDR:
609         s->pci[0].io_base = val & 0x30fffffULL;
610         warn_swap_bit(val);
611         if (!(s->cpu_conf & BIT(27))) {
612             s->pci[0].remap[4] = (val & 0xffffULL) << 16;
613         }
614         break;
615     case MV64340_PCI_0_IO_SIZE:
616         s->pci[0].io_size = val & 0xffffULL;
617         break;
618     case MV64340_PCI_0_IO_ADDR_REMAP:
619         s->pci[0].remap[4] = (val & 0xffffULL) << 16;
620         break;
621     case MV64340_PCI_0_MEMORY0_BASE_ADDR:
622         s->pci[0].mem_base[0] = val & 0x70fffffULL;
623         warn_swap_bit(val);
624         if (!(s->cpu_conf & BIT(27))) {
625             mv64361_set_pci_mem_remap(s, 0, 0, val, false);
626         }
627         break;
628     case MV64340_PCI_0_MEMORY0_SIZE:
629         s->pci[0].mem_size[0] = val & 0xffffULL;
630         break;
631     case MV64340_PCI_0_MEMORY0_LOW_ADDR_REMAP:
632     case MV64340_PCI_0_MEMORY0_HIGH_ADDR_REMAP:
633         mv64361_set_pci_mem_remap(s, 0, 0, val,
634             (addr == MV64340_PCI_0_MEMORY0_HIGH_ADDR_REMAP));
635         break;
636     case MV64340_PCI_0_MEMORY1_BASE_ADDR:
637         s->pci[0].mem_base[1] = val & 0x70fffffULL;
638         warn_swap_bit(val);
639         if (!(s->cpu_conf & BIT(27))) {
640             mv64361_set_pci_mem_remap(s, 0, 1, val, false);
641         }
642         break;
643     case MV64340_PCI_0_MEMORY1_SIZE:
644         s->pci[0].mem_size[1] = val & 0xffffULL;
645         break;
646     case MV64340_PCI_0_MEMORY1_LOW_ADDR_REMAP:
647     case MV64340_PCI_0_MEMORY1_HIGH_ADDR_REMAP:
648         mv64361_set_pci_mem_remap(s, 0, 1, val,
649             (addr == MV64340_PCI_0_MEMORY1_HIGH_ADDR_REMAP));
650         break;
651     case MV64340_PCI_0_MEMORY2_BASE_ADDR:
652         s->pci[0].mem_base[2] = val & 0x70fffffULL;
653         warn_swap_bit(val);
654         if (!(s->cpu_conf & BIT(27))) {
655             mv64361_set_pci_mem_remap(s, 0, 2, val, false);
656         }
657         break;
658     case MV64340_PCI_0_MEMORY2_SIZE:
659         s->pci[0].mem_size[2] = val & 0xffffULL;
660         break;
661     case MV64340_PCI_0_MEMORY2_LOW_ADDR_REMAP:
662     case MV64340_PCI_0_MEMORY2_HIGH_ADDR_REMAP:
663         mv64361_set_pci_mem_remap(s, 0, 2, val,
664             (addr == MV64340_PCI_0_MEMORY2_HIGH_ADDR_REMAP));
665         break;
666     case MV64340_PCI_0_MEMORY3_BASE_ADDR:
667         s->pci[0].mem_base[3] = val & 0x70fffffULL;
668         warn_swap_bit(val);
669         if (!(s->cpu_conf & BIT(27))) {
670             mv64361_set_pci_mem_remap(s, 0, 3, val, false);
671         }
672         break;
673     case MV64340_PCI_0_MEMORY3_SIZE:
674         s->pci[0].mem_size[3] = val & 0xffffULL;
675         break;
676     case MV64340_PCI_0_MEMORY3_LOW_ADDR_REMAP:
677     case MV64340_PCI_0_MEMORY3_HIGH_ADDR_REMAP:
678         mv64361_set_pci_mem_remap(s, 0, 3, val,
679             (addr == MV64340_PCI_0_MEMORY3_HIGH_ADDR_REMAP));
680         break;
681     case MV64340_PCI_1_IO_BASE_ADDR:
682         s->pci[1].io_base = val & 0x30fffffULL;
683         warn_swap_bit(val);
684         if (!(s->cpu_conf & BIT(27))) {
685             s->pci[1].remap[4] = (val & 0xffffULL) << 16;
686         }
687         break;
688     case MV64340_PCI_1_IO_SIZE:
689         s->pci[1].io_size = val & 0xffffULL;
690         break;
691     case MV64340_PCI_1_MEMORY0_BASE_ADDR:
692         s->pci[1].mem_base[0] = val & 0x70fffffULL;
693         warn_swap_bit(val);
694         if (!(s->cpu_conf & BIT(27))) {
695             mv64361_set_pci_mem_remap(s, 1, 0, val, false);
696         }
697         break;
698     case MV64340_PCI_1_MEMORY0_SIZE:
699         s->pci[1].mem_size[0] = val & 0xffffULL;
700         break;
701     case MV64340_PCI_1_MEMORY0_LOW_ADDR_REMAP:
702     case MV64340_PCI_1_MEMORY0_HIGH_ADDR_REMAP:
703         mv64361_set_pci_mem_remap(s, 1, 0, val,
704             (addr == MV64340_PCI_1_MEMORY0_HIGH_ADDR_REMAP));
705         break;
706     case MV64340_PCI_1_MEMORY1_BASE_ADDR:
707         s->pci[1].mem_base[1] = val & 0x70fffffULL;
708         warn_swap_bit(val);
709         if (!(s->cpu_conf & BIT(27))) {
710             mv64361_set_pci_mem_remap(s, 1, 1, val, false);
711         }
712         break;
713     case MV64340_PCI_1_MEMORY1_SIZE:
714         s->pci[1].mem_size[1] = val & 0xffffULL;
715         break;
716     case MV64340_PCI_1_MEMORY1_LOW_ADDR_REMAP:
717     case MV64340_PCI_1_MEMORY1_HIGH_ADDR_REMAP:
718         mv64361_set_pci_mem_remap(s, 1, 1, val,
719             (addr == MV64340_PCI_1_MEMORY1_HIGH_ADDR_REMAP));
720         break;
721     case MV64340_PCI_1_MEMORY2_BASE_ADDR:
722         s->pci[1].mem_base[2] = val & 0x70fffffULL;
723         warn_swap_bit(val);
724         if (!(s->cpu_conf & BIT(27))) {
725             mv64361_set_pci_mem_remap(s, 1, 2, val, false);
726         }
727         break;
728     case MV64340_PCI_1_MEMORY2_SIZE:
729         s->pci[1].mem_size[2] = val & 0xffffULL;
730         break;
731     case MV64340_PCI_1_MEMORY2_LOW_ADDR_REMAP:
732     case MV64340_PCI_1_MEMORY2_HIGH_ADDR_REMAP:
733         mv64361_set_pci_mem_remap(s, 1, 2, val,
734             (addr == MV64340_PCI_1_MEMORY2_HIGH_ADDR_REMAP));
735         break;
736     case MV64340_PCI_1_MEMORY3_BASE_ADDR:
737         s->pci[1].mem_base[3] = val & 0x70fffffULL;
738         warn_swap_bit(val);
739         if (!(s->cpu_conf & BIT(27))) {
740             mv64361_set_pci_mem_remap(s, 1, 3, val, false);
741         }
742         break;
743     case MV64340_PCI_1_MEMORY3_SIZE:
744         s->pci[1].mem_size[3] = val & 0xffffULL;
745         break;
746     case MV64340_PCI_1_MEMORY3_LOW_ADDR_REMAP:
747     case MV64340_PCI_1_MEMORY3_HIGH_ADDR_REMAP:
748         mv64361_set_pci_mem_remap(s, 1, 3, val,
749             (addr == MV64340_PCI_1_MEMORY3_HIGH_ADDR_REMAP));
750         break;
751     case MV64340_INTERNAL_SPACE_BASE_ADDR:
752         s->regs_base = val & 0xfffffULL;
753         break;
754     case MV64340_BASE_ADDR_ENABLE:
755         set_mem_windows(s, val);
756         break;
757     case MV64340_PCI_0_CONFIG_ADDR:
758         pci_host_conf_le_ops.write(PCI_HOST_BRIDGE(&s->pci[0]), 0, val, size);
759         break;
760     case MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG ...
761          MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG + 3:
762         pci_host_data_le_ops.write(PCI_HOST_BRIDGE(&s->pci[0]),
763             addr - MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG, val, size);
764         break;
765     case MV64340_PCI_1_CONFIG_ADDR:
766         pci_host_conf_le_ops.write(PCI_HOST_BRIDGE(&s->pci[1]), 0, val, size);
767         break;
768     case MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG ...
769          MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG + 3:
770         pci_host_data_le_ops.write(PCI_HOST_BRIDGE(&s->pci[1]),
771             addr - MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG, val, size);
772         break;
773     case MV64340_CPU_INTERRUPT0_MASK_LOW:
774         s->cpu0_int_mask &= 0xffffffff00000000ULL;
775         s->cpu0_int_mask |= val & 0xffffffffULL;
776         break;
777     case MV64340_CPU_INTERRUPT0_MASK_HIGH:
778         s->cpu0_int_mask &= 0xffffffffULL;
779         s->cpu0_int_mask |= val << 32;
780         break;
781     case MV64340_CUNIT_ARBITER_CONTROL_REG:
782         s->gpp_int_level = !!(val & BIT(10));
783         break;
784     case MV64340_GPP_IO_CONTROL:
785         s->gpp_io = val;
786         break;
787     case MV64340_GPP_LEVEL_CONTROL:
788         s->gpp_level = val;
789         break;
790     case MV64340_GPP_VALUE:
791         s->gpp_value &= ~s->gpp_io;
792         s->gpp_value |= val & s->gpp_io;
793         break;
794     case MV64340_GPP_VALUE_SET:
795         s->gpp_value |= val & s->gpp_io;
796         break;
797     case MV64340_GPP_VALUE_CLEAR:
798         s->gpp_value &= ~(val & s->gpp_io);
799         break;
800     case MV64340_GPP_INTERRUPT_CAUSE:
801         if (!s->gpp_int_level && val != s->gpp_int_cr) {
802             int i;
803             uint32_t ch = s->gpp_int_cr ^ val;
804             s->gpp_int_cr = val;
805             for (i = 0; i < 4; i++) {
806                 if ((ch & 0xff << i) && !(val & 0xff << i)) {
807                     mv64361_update_irq(opaque, MV64361_IRQ_P0_GPP0_7 + i, 0);
808                 }
809             }
810         } else {
811             s->gpp_int_cr = val;
812         }
813         break;
814     case MV64340_GPP_INTERRUPT_MASK0:
815     case MV64340_GPP_INTERRUPT_MASK1:
816         s->gpp_int_mask = val;
817         break;
818     default:
819         qemu_log_mask(LOG_UNIMP, "%s: Unimplemented register write 0x%"
820                       HWADDR_PRIx " = %"PRIx64"\n", __func__, addr, val);
821         break;
822     }
823 }
824 
825 static const MemoryRegionOps mv64361_ops = {
826     .read = mv64361_read,
827     .write = mv64361_write,
828     .valid.min_access_size = 1,
829     .valid.max_access_size = 4,
830     .endianness = DEVICE_LITTLE_ENDIAN,
831 };
832 
833 static void mv64361_gpp_irq(void *opaque, int n, int level)
834 {
835     MV64361State *s = opaque;
836     uint32_t mask = BIT(n);
837     uint32_t val = s->gpp_value & ~mask;
838 
839     if (s->gpp_level & mask) {
840         level = !level;
841     }
842     val |= level << n;
843     if (val > s->gpp_value) {
844         s->gpp_value = val;
845         s->gpp_int_cr |= mask;
846         if (s->gpp_int_mask & mask) {
847             mv64361_update_irq(opaque, MV64361_IRQ_P0_GPP0_7 + n / 8, 1);
848         }
849     } else if (val < s->gpp_value) {
850         int b = n / 8;
851         s->gpp_value = val;
852         if (s->gpp_int_level && !(val & 0xff << b)) {
853             mv64361_update_irq(opaque, MV64361_IRQ_P0_GPP0_7 + b, 0);
854         }
855     }
856 }
857 
858 static void mv64361_realize(DeviceState *dev, Error **errp)
859 {
860     MV64361State *s = MV64361(dev);
861     int i;
862 
863     s->base_addr_enable = 0x1fffff;
864     memory_region_init_io(&s->regs, OBJECT(s), &mv64361_ops, s,
865                           TYPE_MV64361, 0x10000);
866     sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->regs);
867     for (i = 0; i < 2; i++) {
868         g_autofree char *name = g_strdup_printf("pcihost%d", i);
869         object_initialize_child(OBJECT(dev), name, &s->pci[i],
870                                 TYPE_MV64361_PCI);
871         DeviceState *pci = DEVICE(&s->pci[i]);
872         qdev_prop_set_uint8(pci, "index", i);
873         sysbus_realize_and_unref(SYS_BUS_DEVICE(pci), &error_fatal);
874     }
875     sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->cpu_irq);
876     qdev_init_gpio_in_named(dev, mv64361_gpp_irq, "gpp", 32);
877     /* FIXME: PCI IRQ connections may be board specific */
878     for (i = 0; i < PCI_NUM_PINS; i++) {
879         s->pci[1].irq[i] = qdev_get_gpio_in_named(dev, "gpp", 12 + i);
880     }
881 }
882 
883 static void mv64361_reset(DeviceState *dev)
884 {
885     MV64361State *s = MV64361(dev);
886     int i, j;
887 
888     /*
889      * These values may be board specific
890      * Real chip supports init from an eprom but that's not modelled
891      */
892     set_mem_windows(s, 0x1fffff);
893     s->cpu_conf = 0x28000ff;
894     s->regs_base = 0x100f100;
895     s->pci[0].io_base = 0x100f800;
896     s->pci[0].io_size = 0xff;
897     s->pci[0].mem_base[0] = 0x100c000;
898     s->pci[0].mem_size[0] = 0x1fff;
899     s->pci[0].mem_base[1] = 0x100f900;
900     s->pci[0].mem_size[1] = 0xff;
901     s->pci[0].mem_base[2] = 0x100f400;
902     s->pci[0].mem_size[2] = 0x1ff;
903     s->pci[0].mem_base[3] = 0x100f600;
904     s->pci[0].mem_size[3] = 0x1ff;
905     s->pci[1].io_base = 0x100fe00;
906     s->pci[1].io_size = 0xff;
907     s->pci[1].mem_base[0] = 0x1008000;
908     s->pci[1].mem_size[0] = 0x3fff;
909     s->pci[1].mem_base[1] = 0x100fd00;
910     s->pci[1].mem_size[1] = 0xff;
911     s->pci[1].mem_base[2] = 0x1002600;
912     s->pci[1].mem_size[2] = 0x1ff;
913     s->pci[1].mem_base[3] = 0x100ff80;
914     s->pci[1].mem_size[3] = 0x7f;
915     for (i = 0; i < 2; i++) {
916         for (j = 0; j < 4; j++) {
917             s->pci[i].remap[j] = s->pci[i].mem_base[j] << 16;
918         }
919     }
920     s->pci[0].remap[1] = 0;
921     s->pci[1].remap[1] = 0;
922     set_mem_windows(s, 0xfbfff);
923 }
924 
925 static void mv64361_class_init(ObjectClass *klass, void *data)
926 {
927     DeviceClass *dc = DEVICE_CLASS(klass);
928 
929     dc->realize = mv64361_realize;
930     dc->reset = mv64361_reset;
931 }
932 
933 static const TypeInfo mv64361_type_info = {
934     .name = TYPE_MV64361,
935     .parent = TYPE_SYS_BUS_DEVICE,
936     .instance_size = sizeof(MV64361State),
937     .class_init = mv64361_class_init,
938 };
939 
940 static void mv64361_register_types(void)
941 {
942     type_register_static(&mv64361_type_info);
943 }
944 
945 type_init(mv64361_register_types)
946