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