2 * Marvell Discovery II MV64361 System Controller for
3 * QEMU PowerPC CHRP (Genesi/bPlan Pegasos II) hardware System Emulator
5 * Copyright (c) 2018-2020 BALATON Zoltan
7 * This work is licensed under the GNU GPL license version 2 or later.
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"
18 #include "hw/intc/i8259.h"
19 #include "hw/qdev-properties.h"
20 #include "exec/address-spaces.h"
22 #include "qemu/error-report.h"
24 #include "hw/pci-host/mv64361.h"
27 #define TYPE_MV64361_PCI_BRIDGE "mv64361-pcibridge"
29 static void mv64361_pcibridge_class_init(ObjectClass
*klass
, void *data
)
31 DeviceClass
*dc
= DEVICE_CLASS(klass
);
32 PCIDeviceClass
*k
= PCI_DEVICE_CLASS(klass
);
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
;
38 * PCI-facing part of the host bridge,
39 * not usable without the host-facing part
41 dc
->user_creatable
= false;
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
},
56 #define TYPE_MV64361_PCI "mv64361-pcihost"
57 OBJECT_DECLARE_SIMPLE_TYPE(MV64361PCIState
, MV64361_PCI
)
59 struct MV64361PCIState
{
60 PCIHostState parent_obj
;
65 qemu_irq irq
[PCI_NUM_PINS
];
74 static void mv64361_pcihost_set_irq(void *opaque
, int n
, int level
)
76 MV64361PCIState
*s
= opaque
;
77 qemu_set_irq(s
->irq
[n
], level
);
80 static void mv64361_pcihost_realize(DeviceState
*dev
, Error
**errp
)
82 MV64361PCIState
*s
= MV64361_PCI(dev
);
83 PCIHostState
*h
= PCI_HOST_BRIDGE(dev
);
86 name
= g_strdup_printf("pci%d-io", s
->index
);
87 memory_region_init(&s
->io
, OBJECT(dev
), name
, 0x10000);
89 name
= g_strdup_printf("pci%d-mem", s
->index
);
90 memory_region_init(&s
->mem
, OBJECT(dev
), name
, 1ULL << 32);
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
);
97 pci_create_simple(h
->bus
, 0, TYPE_MV64361_PCI_BRIDGE
);
100 static Property mv64361_pcihost_props
[] = {
101 DEFINE_PROP_UINT8("index", MV64361PCIState
, index
, 0),
102 DEFINE_PROP_END_OF_LIST()
105 static void mv64361_pcihost_class_init(ObjectClass
*klass
, void *data
)
107 DeviceClass
*dc
= DEVICE_CLASS(klass
);
109 dc
->realize
= mv64361_pcihost_realize
;
110 device_class_set_props(dc
, mv64361_pcihost_props
);
111 set_bit(DEVICE_CATEGORY_BRIDGE
, dc
->categories
);
114 static const TypeInfo mv64361_pcihost_info
= {
115 .name
= TYPE_MV64361_PCI
,
116 .parent
= TYPE_PCI_HOST_BRIDGE
,
117 .instance_size
= sizeof(MV64361PCIState
),
118 .class_init
= mv64361_pcihost_class_init
,
121 static void mv64361_pci_register_types(void)
123 type_register_static(&mv64361_pcihost_info
);
124 type_register_static(&mv64361_pcibridge_info
);
127 type_init(mv64361_pci_register_types
)
130 OBJECT_DECLARE_SIMPLE_TYPE(MV64361State
, MV64361
)
132 struct MV64361State
{
133 SysBusDevice parent_obj
;
136 MV64361PCIState pci
[2];
137 MemoryRegion cpu_win
[19];
140 /* registers state */
143 uint32_t base_addr_enable
;
144 uint64_t main_int_cr
;
145 uint64_t cpu0_int_mask
;
150 uint32_t gpp_int_mask
;
154 enum mv64361_irq_cause
{
155 MV64361_IRQ_DEVERR
= 1,
156 MV64361_IRQ_DMAERR
= 2,
157 MV64361_IRQ_CPUERR
= 3,
158 MV64361_IRQ_IDMA0
= 4,
159 MV64361_IRQ_IDMA1
= 5,
160 MV64361_IRQ_IDMA2
= 6,
161 MV64361_IRQ_IDMA3
= 7,
162 MV64361_IRQ_TIMER0
= 8,
163 MV64361_IRQ_TIMER1
= 9,
164 MV64361_IRQ_TIMER2
= 10,
165 MV64361_IRQ_TIMER3
= 11,
166 MV64361_IRQ_PCI0
= 12,
167 MV64361_IRQ_SRAMERR
= 13,
168 MV64361_IRQ_GBEERR
= 14,
169 MV64361_IRQ_CERR
= 15,
170 MV64361_IRQ_PCI1
= 16,
171 MV64361_IRQ_DRAMERR
= 17,
172 MV64361_IRQ_WDNMI
= 18,
173 MV64361_IRQ_WDE
= 19,
174 MV64361_IRQ_PCI0IN
= 20,
175 MV64361_IRQ_PCI0OUT
= 21,
176 MV64361_IRQ_PCI1IN
= 22,
177 MV64361_IRQ_PCI1OUT
= 23,
178 MV64361_IRQ_P1_GPP0_7
= 24,
179 MV64361_IRQ_P1_GPP8_15
= 25,
180 MV64361_IRQ_P1_GPP16_23
= 26,
181 MV64361_IRQ_P1_GPP24_31
= 27,
182 MV64361_IRQ_P1_CPU_DB
= 28,
183 /* 29-31: reserved */
184 MV64361_IRQ_GBE0
= 32,
185 MV64361_IRQ_GBE1
= 33,
186 MV64361_IRQ_GBE2
= 34,
188 MV64361_IRQ_SDMA0
= 36,
189 MV64361_IRQ_TWSI
= 37,
190 MV64361_IRQ_SDMA1
= 38,
191 MV64361_IRQ_BRG
= 39,
192 MV64361_IRQ_MPSC0
= 40,
193 MV64361_IRQ_MPSC1
= 41,
194 MV64361_IRQ_G0RX
= 42,
195 MV64361_IRQ_G0TX
= 43,
196 MV64361_IRQ_G0MISC
= 44,
197 MV64361_IRQ_G1RX
= 45,
198 MV64361_IRQ_G1TX
= 46,
199 MV64361_IRQ_G1MISC
= 47,
200 MV64361_IRQ_G2RX
= 48,
201 MV64361_IRQ_G2TX
= 49,
202 MV64361_IRQ_G2MISC
= 50,
203 /* 51-55: reserved */
204 MV64361_IRQ_P0_GPP0_7
= 56,
205 MV64361_IRQ_P0_GPP8_15
= 57,
206 MV64361_IRQ_P0_GPP16_23
= 58,
207 MV64361_IRQ_P0_GPP24_31
= 59,
208 MV64361_IRQ_P0_CPU_DB
= 60,
209 /* 61-63: reserved */
212 PCIBus
*mv64361_get_pci_bus(DeviceState
*dev
, int n
)
214 MV64361State
*mv
= MV64361(dev
);
215 return PCI_HOST_BRIDGE(&mv
->pci
[n
])->bus
;
218 static void unmap_region(MemoryRegion
*mr
)
220 if (memory_region_is_mapped(mr
)) {
221 memory_region_del_subregion(get_system_memory(), mr
);
222 object_unparent(OBJECT(mr
));
226 static void map_pci_region(MemoryRegion
*mr
, MemoryRegion
*parent
,
227 struct Object
*owner
, const char *name
,
228 hwaddr poffs
, uint64_t size
, hwaddr moffs
)
230 memory_region_init_alias(mr
, owner
, name
, parent
, poffs
, size
);
231 memory_region_add_subregion(get_system_memory(), moffs
, mr
);
232 trace_mv64361_region_map(name
, poffs
, size
, moffs
);
235 static void set_mem_windows(MV64361State
*s
, uint32_t val
)
243 for (mask
= 1, i
= 0; i
< 21; i
++, mask
<<= 1) {
244 if ((val
& mask
) != (s
->base_addr_enable
& mask
)) {
245 trace_mv64361_region_enable(!(val
& mask
) ? "enable" : "disable", i
);
247 * 0-3 are SDRAM chip selects but we map all RAM directly
248 * 4-7 are device chip selects (not sure what those are)
249 * 8 is Boot device (ROM) chip select but we map that directly too
256 map_pci_region(mr
, &p
->io
, OBJECT(s
), "pci0-io-win",
257 p
->remap
[4], (p
->io_size
+ 1) << 16,
258 (p
->io_base
& 0xfffff) << 16);
260 } else if (i
== 10) {
265 map_pci_region(mr
, &p
->mem
, OBJECT(s
), "pci0-mem0-win",
266 p
->remap
[0], (p
->mem_size
[0] + 1) << 16,
267 (p
->mem_base
[0] & 0xfffff) << 16);
269 } else if (i
== 11) {
274 map_pci_region(mr
, &p
->mem
, OBJECT(s
), "pci0-mem1-win",
275 p
->remap
[1], (p
->mem_size
[1] + 1) << 16,
276 (p
->mem_base
[1] & 0xfffff) << 16);
278 } else if (i
== 12) {
283 map_pci_region(mr
, &p
->mem
, OBJECT(s
), "pci0-mem2-win",
284 p
->remap
[2], (p
->mem_size
[2] + 1) << 16,
285 (p
->mem_base
[2] & 0xfffff) << 16);
287 } else if (i
== 13) {
292 map_pci_region(mr
, &p
->mem
, OBJECT(s
), "pci0-mem3-win",
293 p
->remap
[3], (p
->mem_size
[3] + 1) << 16,
294 (p
->mem_base
[3] & 0xfffff) << 16);
296 } else if (i
== 14) {
301 map_pci_region(mr
, &p
->io
, OBJECT(s
), "pci1-io-win",
302 p
->remap
[4], (p
->io_size
+ 1) << 16,
303 (p
->io_base
& 0xfffff) << 16);
305 } else if (i
== 15) {
310 map_pci_region(mr
, &p
->mem
, OBJECT(s
), "pci1-mem0-win",
311 p
->remap
[0], (p
->mem_size
[0] + 1) << 16,
312 (p
->mem_base
[0] & 0xfffff) << 16);
314 } else if (i
== 16) {
319 map_pci_region(mr
, &p
->mem
, OBJECT(s
), "pci1-mem1-win",
320 p
->remap
[1], (p
->mem_size
[1] + 1) << 16,
321 (p
->mem_base
[1] & 0xfffff) << 16);
323 } else if (i
== 17) {
328 map_pci_region(mr
, &p
->mem
, OBJECT(s
), "pci1-mem2-win",
329 p
->remap
[2], (p
->mem_size
[2] + 1) << 16,
330 (p
->mem_base
[2] & 0xfffff) << 16);
332 } else if (i
== 18) {
337 map_pci_region(mr
, &p
->mem
, OBJECT(s
), "pci1-mem3-win",
338 p
->remap
[3], (p
->mem_size
[3] + 1) << 16,
339 (p
->mem_base
[3] & 0xfffff) << 16);
341 /* 19 is integrated SRAM */
342 } else if (i
== 20) {
346 memory_region_add_subregion(get_system_memory(),
347 (s
->regs_base
& 0xfffff) << 16, mr
);
352 s
->base_addr_enable
= val
;
355 static void mv64361_update_irq(void *opaque
, int n
, int level
)
357 MV64361State
*s
= opaque
;
358 uint64_t val
= s
->main_int_cr
;
365 if ((s
->main_int_cr
& s
->cpu0_int_mask
) != (val
& s
->cpu0_int_mask
)) {
366 qemu_set_irq(s
->cpu_irq
, level
);
368 s
->main_int_cr
= val
;
371 static uint64_t mv64361_read(void *opaque
, hwaddr addr
, unsigned int size
)
373 MV64361State
*s
= MV64361(opaque
);
377 case MV64340_CPU_CONFIG
:
380 case MV64340_PCI_0_IO_BASE_ADDR
:
381 ret
= s
->pci
[0].io_base
;
383 case MV64340_PCI_0_IO_SIZE
:
384 ret
= s
->pci
[0].io_size
;
386 case MV64340_PCI_0_IO_ADDR_REMAP
:
387 ret
= s
->pci
[0].remap
[4] >> 16;
389 case MV64340_PCI_0_MEMORY0_BASE_ADDR
:
390 ret
= s
->pci
[0].mem_base
[0];
392 case MV64340_PCI_0_MEMORY0_SIZE
:
393 ret
= s
->pci
[0].mem_size
[0];
395 case MV64340_PCI_0_MEMORY0_LOW_ADDR_REMAP
:
396 ret
= (s
->pci
[0].remap
[0] & 0xffff0000) >> 16;
398 case MV64340_PCI_0_MEMORY0_HIGH_ADDR_REMAP
:
399 ret
= s
->pci
[0].remap
[0] >> 32;
401 case MV64340_PCI_0_MEMORY1_BASE_ADDR
:
402 ret
= s
->pci
[0].mem_base
[1];
404 case MV64340_PCI_0_MEMORY1_SIZE
:
405 ret
= s
->pci
[0].mem_size
[1];
407 case MV64340_PCI_0_MEMORY1_LOW_ADDR_REMAP
:
408 ret
= (s
->pci
[0].remap
[1] & 0xffff0000) >> 16;
410 case MV64340_PCI_0_MEMORY1_HIGH_ADDR_REMAP
:
411 ret
= s
->pci
[0].remap
[1] >> 32;
413 case MV64340_PCI_0_MEMORY2_BASE_ADDR
:
414 ret
= s
->pci
[0].mem_base
[2];
416 case MV64340_PCI_0_MEMORY2_SIZE
:
417 ret
= s
->pci
[0].mem_size
[2];
419 case MV64340_PCI_0_MEMORY2_LOW_ADDR_REMAP
:
420 ret
= (s
->pci
[0].remap
[2] & 0xffff0000) >> 16;
422 case MV64340_PCI_0_MEMORY2_HIGH_ADDR_REMAP
:
423 ret
= s
->pci
[0].remap
[2] >> 32;
425 case MV64340_PCI_0_MEMORY3_BASE_ADDR
:
426 ret
= s
->pci
[0].mem_base
[3];
428 case MV64340_PCI_0_MEMORY3_SIZE
:
429 ret
= s
->pci
[0].mem_size
[3];
431 case MV64340_PCI_0_MEMORY3_LOW_ADDR_REMAP
:
432 ret
= (s
->pci
[0].remap
[3] & 0xffff0000) >> 16;
434 case MV64340_PCI_0_MEMORY3_HIGH_ADDR_REMAP
:
435 ret
= s
->pci
[0].remap
[3] >> 32;
437 case MV64340_PCI_1_IO_BASE_ADDR
:
438 ret
= s
->pci
[1].io_base
;
440 case MV64340_PCI_1_IO_SIZE
:
441 ret
= s
->pci
[1].io_size
;
443 case MV64340_PCI_1_IO_ADDR_REMAP
:
444 ret
= s
->pci
[1].remap
[4] >> 16;
446 case MV64340_PCI_1_MEMORY0_BASE_ADDR
:
447 ret
= s
->pci
[1].mem_base
[0];
449 case MV64340_PCI_1_MEMORY0_SIZE
:
450 ret
= s
->pci
[1].mem_size
[0];
452 case MV64340_PCI_1_MEMORY0_LOW_ADDR_REMAP
:
453 ret
= (s
->pci
[1].remap
[0] & 0xffff0000) >> 16;
455 case MV64340_PCI_1_MEMORY0_HIGH_ADDR_REMAP
:
456 ret
= s
->pci
[1].remap
[0] >> 32;
458 case MV64340_PCI_1_MEMORY1_BASE_ADDR
:
459 ret
= s
->pci
[1].mem_base
[1];
461 case MV64340_PCI_1_MEMORY1_SIZE
:
462 ret
= s
->pci
[1].mem_size
[1];
464 case MV64340_PCI_1_MEMORY1_LOW_ADDR_REMAP
:
465 ret
= (s
->pci
[1].remap
[1] & 0xffff0000) >> 16;
467 case MV64340_PCI_1_MEMORY1_HIGH_ADDR_REMAP
:
468 ret
= s
->pci
[1].remap
[1] >> 32;
470 case MV64340_PCI_1_MEMORY2_BASE_ADDR
:
471 ret
= s
->pci
[1].mem_base
[2];
473 case MV64340_PCI_1_MEMORY2_SIZE
:
474 ret
= s
->pci
[1].mem_size
[2];
476 case MV64340_PCI_1_MEMORY2_LOW_ADDR_REMAP
:
477 ret
= (s
->pci
[1].remap
[2] & 0xffff0000) >> 16;
479 case MV64340_PCI_1_MEMORY2_HIGH_ADDR_REMAP
:
480 ret
= s
->pci
[1].remap
[2] >> 32;
482 case MV64340_PCI_1_MEMORY3_BASE_ADDR
:
483 ret
= s
->pci
[1].mem_base
[3];
485 case MV64340_PCI_1_MEMORY3_SIZE
:
486 ret
= s
->pci
[1].mem_size
[3];
488 case MV64340_PCI_1_MEMORY3_LOW_ADDR_REMAP
:
489 ret
= (s
->pci
[1].remap
[3] & 0xffff0000) >> 16;
491 case MV64340_PCI_1_MEMORY3_HIGH_ADDR_REMAP
:
492 ret
= s
->pci
[1].remap
[3] >> 32;
494 case MV64340_INTERNAL_SPACE_BASE_ADDR
:
497 case MV64340_BASE_ADDR_ENABLE
:
498 ret
= s
->base_addr_enable
;
500 case MV64340_PCI_0_CONFIG_ADDR
:
501 ret
= pci_host_conf_le_ops
.read(PCI_HOST_BRIDGE(&s
->pci
[0]), 0, size
);
503 case MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG
...
504 MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG
+ 3:
505 ret
= pci_host_data_le_ops
.read(PCI_HOST_BRIDGE(&s
->pci
[0]),
506 addr
- MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG
, size
);
508 case MV64340_PCI_1_CONFIG_ADDR
:
509 ret
= pci_host_conf_le_ops
.read(PCI_HOST_BRIDGE(&s
->pci
[1]), 0, size
);
511 case MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG
...
512 MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG
+ 3:
513 ret
= pci_host_data_le_ops
.read(PCI_HOST_BRIDGE(&s
->pci
[1]),
514 addr
- MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG
, size
);
516 case MV64340_PCI_1_INTERRUPT_ACKNOWLEDGE_VIRTUAL_REG
:
517 /* FIXME: Should this be sent via the PCI bus somehow? */
518 if (s
->gpp_int_level
&& (s
->gpp_value
& BIT(31))) {
519 ret
= pic_read_irq(isa_pic
);
522 case MV64340_MAIN_INTERRUPT_CAUSE_LOW
:
523 ret
= s
->main_int_cr
;
525 case MV64340_MAIN_INTERRUPT_CAUSE_HIGH
:
526 ret
= s
->main_int_cr
>> 32;
528 case MV64340_CPU_INTERRUPT0_MASK_LOW
:
529 ret
= s
->cpu0_int_mask
;
531 case MV64340_CPU_INTERRUPT0_MASK_HIGH
:
532 ret
= s
->cpu0_int_mask
>> 32;
534 case MV64340_CPU_INTERRUPT0_SELECT_CAUSE
:
535 ret
= s
->main_int_cr
;
536 if (s
->main_int_cr
& s
->cpu0_int_mask
) {
537 if (!(s
->main_int_cr
& s
->cpu0_int_mask
& 0xffffffff)) {
538 ret
= s
->main_int_cr
>> 32 | BIT(30);
539 } else if ((s
->main_int_cr
& s
->cpu0_int_mask
) >> 32) {
544 case MV64340_CUNIT_ARBITER_CONTROL_REG
:
545 ret
= 0x11ff0000 | (s
->gpp_int_level
<< 10);
547 case MV64340_GPP_IO_CONTROL
:
550 case MV64340_GPP_LEVEL_CONTROL
:
553 case MV64340_GPP_VALUE
:
556 case MV64340_GPP_VALUE_SET
:
557 case MV64340_GPP_VALUE_CLEAR
:
560 case MV64340_GPP_INTERRUPT_CAUSE
:
563 case MV64340_GPP_INTERRUPT_MASK0
:
564 case MV64340_GPP_INTERRUPT_MASK1
:
565 ret
= s
->gpp_int_mask
;
568 qemu_log_mask(LOG_UNIMP
, "%s: Unimplemented register read 0x%"
569 HWADDR_PRIx
"\n", __func__
, addr
);
572 if (addr
!= MV64340_PCI_1_INTERRUPT_ACKNOWLEDGE_VIRTUAL_REG
) {
573 trace_mv64361_reg_read(addr
, ret
);
578 static void warn_swap_bit(uint64_t val
)
580 if ((val
& 0x3000000ULL
) >> 24 != 1) {
581 qemu_log_mask(LOG_UNIMP
, "%s: Data swap not implemented", __func__
);
585 static void mv64361_set_pci_mem_remap(MV64361State
*s
, int bus
, int idx
,
586 uint64_t val
, bool high
)
589 s
->pci
[bus
].remap
[idx
] = val
;
591 s
->pci
[bus
].remap
[idx
] &= 0xffffffff00000000ULL
;
592 s
->pci
[bus
].remap
[idx
] |= (val
& 0xffffULL
) << 16;
596 static void mv64361_write(void *opaque
, hwaddr addr
, uint64_t val
,
599 MV64361State
*s
= MV64361(opaque
);
601 trace_mv64361_reg_write(addr
, val
);
603 case MV64340_CPU_CONFIG
:
604 s
->cpu_conf
= val
& 0xe4e3bffULL
;
605 s
->cpu_conf
|= BIT(23);
607 case MV64340_PCI_0_IO_BASE_ADDR
:
608 s
->pci
[0].io_base
= val
& 0x30fffffULL
;
610 if (!(s
->cpu_conf
& BIT(27))) {
611 s
->pci
[0].remap
[4] = (val
& 0xffffULL
) << 16;
614 case MV64340_PCI_0_IO_SIZE
:
615 s
->pci
[0].io_size
= val
& 0xffffULL
;
617 case MV64340_PCI_0_IO_ADDR_REMAP
:
618 s
->pci
[0].remap
[4] = (val
& 0xffffULL
) << 16;
620 case MV64340_PCI_0_MEMORY0_BASE_ADDR
:
621 s
->pci
[0].mem_base
[0] = val
& 0x70fffffULL
;
623 if (!(s
->cpu_conf
& BIT(27))) {
624 mv64361_set_pci_mem_remap(s
, 0, 0, val
, false);
627 case MV64340_PCI_0_MEMORY0_SIZE
:
628 s
->pci
[0].mem_size
[0] = val
& 0xffffULL
;
630 case MV64340_PCI_0_MEMORY0_LOW_ADDR_REMAP
:
631 case MV64340_PCI_0_MEMORY0_HIGH_ADDR_REMAP
:
632 mv64361_set_pci_mem_remap(s
, 0, 0, val
,
633 (addr
== MV64340_PCI_0_MEMORY0_HIGH_ADDR_REMAP
));
635 case MV64340_PCI_0_MEMORY1_BASE_ADDR
:
636 s
->pci
[0].mem_base
[1] = val
& 0x70fffffULL
;
638 if (!(s
->cpu_conf
& BIT(27))) {
639 mv64361_set_pci_mem_remap(s
, 0, 1, val
, false);
642 case MV64340_PCI_0_MEMORY1_SIZE
:
643 s
->pci
[0].mem_size
[1] = val
& 0xffffULL
;
645 case MV64340_PCI_0_MEMORY1_LOW_ADDR_REMAP
:
646 case MV64340_PCI_0_MEMORY1_HIGH_ADDR_REMAP
:
647 mv64361_set_pci_mem_remap(s
, 0, 1, val
,
648 (addr
== MV64340_PCI_0_MEMORY1_HIGH_ADDR_REMAP
));
650 case MV64340_PCI_0_MEMORY2_BASE_ADDR
:
651 s
->pci
[0].mem_base
[2] = val
& 0x70fffffULL
;
653 if (!(s
->cpu_conf
& BIT(27))) {
654 mv64361_set_pci_mem_remap(s
, 0, 2, val
, false);
657 case MV64340_PCI_0_MEMORY2_SIZE
:
658 s
->pci
[0].mem_size
[2] = val
& 0xffffULL
;
660 case MV64340_PCI_0_MEMORY2_LOW_ADDR_REMAP
:
661 case MV64340_PCI_0_MEMORY2_HIGH_ADDR_REMAP
:
662 mv64361_set_pci_mem_remap(s
, 0, 2, val
,
663 (addr
== MV64340_PCI_0_MEMORY2_HIGH_ADDR_REMAP
));
665 case MV64340_PCI_0_MEMORY3_BASE_ADDR
:
666 s
->pci
[0].mem_base
[3] = val
& 0x70fffffULL
;
668 if (!(s
->cpu_conf
& BIT(27))) {
669 mv64361_set_pci_mem_remap(s
, 0, 3, val
, false);
672 case MV64340_PCI_0_MEMORY3_SIZE
:
673 s
->pci
[0].mem_size
[3] = val
& 0xffffULL
;
675 case MV64340_PCI_0_MEMORY3_LOW_ADDR_REMAP
:
676 case MV64340_PCI_0_MEMORY3_HIGH_ADDR_REMAP
:
677 mv64361_set_pci_mem_remap(s
, 0, 3, val
,
678 (addr
== MV64340_PCI_0_MEMORY3_HIGH_ADDR_REMAP
));
680 case MV64340_PCI_1_IO_BASE_ADDR
:
681 s
->pci
[1].io_base
= val
& 0x30fffffULL
;
683 if (!(s
->cpu_conf
& BIT(27))) {
684 s
->pci
[1].remap
[4] = (val
& 0xffffULL
) << 16;
687 case MV64340_PCI_1_IO_SIZE
:
688 s
->pci
[1].io_size
= val
& 0xffffULL
;
690 case MV64340_PCI_1_MEMORY0_BASE_ADDR
:
691 s
->pci
[1].mem_base
[0] = val
& 0x70fffffULL
;
693 if (!(s
->cpu_conf
& BIT(27))) {
694 mv64361_set_pci_mem_remap(s
, 1, 0, val
, false);
697 case MV64340_PCI_1_MEMORY0_SIZE
:
698 s
->pci
[1].mem_size
[0] = val
& 0xffffULL
;
700 case MV64340_PCI_1_MEMORY0_LOW_ADDR_REMAP
:
701 case MV64340_PCI_1_MEMORY0_HIGH_ADDR_REMAP
:
702 mv64361_set_pci_mem_remap(s
, 1, 0, val
,
703 (addr
== MV64340_PCI_1_MEMORY0_HIGH_ADDR_REMAP
));
705 case MV64340_PCI_1_MEMORY1_BASE_ADDR
:
706 s
->pci
[1].mem_base
[1] = val
& 0x70fffffULL
;
708 if (!(s
->cpu_conf
& BIT(27))) {
709 mv64361_set_pci_mem_remap(s
, 1, 1, val
, false);
712 case MV64340_PCI_1_MEMORY1_SIZE
:
713 s
->pci
[1].mem_size
[1] = val
& 0xffffULL
;
715 case MV64340_PCI_1_MEMORY1_LOW_ADDR_REMAP
:
716 case MV64340_PCI_1_MEMORY1_HIGH_ADDR_REMAP
:
717 mv64361_set_pci_mem_remap(s
, 1, 1, val
,
718 (addr
== MV64340_PCI_1_MEMORY1_HIGH_ADDR_REMAP
));
720 case MV64340_PCI_1_MEMORY2_BASE_ADDR
:
721 s
->pci
[1].mem_base
[2] = val
& 0x70fffffULL
;
723 if (!(s
->cpu_conf
& BIT(27))) {
724 mv64361_set_pci_mem_remap(s
, 1, 2, val
, false);
727 case MV64340_PCI_1_MEMORY2_SIZE
:
728 s
->pci
[1].mem_size
[2] = val
& 0xffffULL
;
730 case MV64340_PCI_1_MEMORY2_LOW_ADDR_REMAP
:
731 case MV64340_PCI_1_MEMORY2_HIGH_ADDR_REMAP
:
732 mv64361_set_pci_mem_remap(s
, 1, 2, val
,
733 (addr
== MV64340_PCI_1_MEMORY2_HIGH_ADDR_REMAP
));
735 case MV64340_PCI_1_MEMORY3_BASE_ADDR
:
736 s
->pci
[1].mem_base
[3] = val
& 0x70fffffULL
;
738 if (!(s
->cpu_conf
& BIT(27))) {
739 mv64361_set_pci_mem_remap(s
, 1, 3, val
, false);
742 case MV64340_PCI_1_MEMORY3_SIZE
:
743 s
->pci
[1].mem_size
[3] = val
& 0xffffULL
;
745 case MV64340_PCI_1_MEMORY3_LOW_ADDR_REMAP
:
746 case MV64340_PCI_1_MEMORY3_HIGH_ADDR_REMAP
:
747 mv64361_set_pci_mem_remap(s
, 1, 3, val
,
748 (addr
== MV64340_PCI_1_MEMORY3_HIGH_ADDR_REMAP
));
750 case MV64340_INTERNAL_SPACE_BASE_ADDR
:
751 s
->regs_base
= val
& 0xfffffULL
;
753 case MV64340_BASE_ADDR_ENABLE
:
754 set_mem_windows(s
, val
);
756 case MV64340_PCI_0_CONFIG_ADDR
:
757 pci_host_conf_le_ops
.write(PCI_HOST_BRIDGE(&s
->pci
[0]), 0, val
, size
);
759 case MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG
...
760 MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG
+ 3:
761 pci_host_data_le_ops
.write(PCI_HOST_BRIDGE(&s
->pci
[0]),
762 addr
- MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG
, val
, size
);
764 case MV64340_PCI_1_CONFIG_ADDR
:
765 pci_host_conf_le_ops
.write(PCI_HOST_BRIDGE(&s
->pci
[1]), 0, val
, size
);
767 case MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG
...
768 MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG
+ 3:
769 pci_host_data_le_ops
.write(PCI_HOST_BRIDGE(&s
->pci
[1]),
770 addr
- MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG
, val
, size
);
772 case MV64340_CPU_INTERRUPT0_MASK_LOW
:
773 s
->cpu0_int_mask
&= 0xffffffff00000000ULL
;
774 s
->cpu0_int_mask
|= val
& 0xffffffffULL
;
776 case MV64340_CPU_INTERRUPT0_MASK_HIGH
:
777 s
->cpu0_int_mask
&= 0xffffffffULL
;
778 s
->cpu0_int_mask
|= val
<< 32;
780 case MV64340_CUNIT_ARBITER_CONTROL_REG
:
781 s
->gpp_int_level
= !!(val
& BIT(10));
783 case MV64340_GPP_IO_CONTROL
:
786 case MV64340_GPP_LEVEL_CONTROL
:
789 case MV64340_GPP_VALUE
:
790 s
->gpp_value
&= ~s
->gpp_io
;
791 s
->gpp_value
|= val
& s
->gpp_io
;
793 case MV64340_GPP_VALUE_SET
:
794 s
->gpp_value
|= val
& s
->gpp_io
;
796 case MV64340_GPP_VALUE_CLEAR
:
797 s
->gpp_value
&= ~(val
& s
->gpp_io
);
799 case MV64340_GPP_INTERRUPT_CAUSE
:
800 if (!s
->gpp_int_level
&& val
!= s
->gpp_int_cr
) {
802 uint32_t ch
= s
->gpp_int_cr
^ val
;
804 for (i
= 0; i
< 4; i
++) {
805 if ((ch
& 0xff << i
) && !(val
& 0xff << i
)) {
806 mv64361_update_irq(opaque
, MV64361_IRQ_P0_GPP0_7
+ i
, 0);
813 case MV64340_GPP_INTERRUPT_MASK0
:
814 case MV64340_GPP_INTERRUPT_MASK1
:
815 s
->gpp_int_mask
= val
;
818 qemu_log_mask(LOG_UNIMP
, "%s: Unimplemented register write 0x%"
819 HWADDR_PRIx
" = %"PRIx64
"\n", __func__
, addr
, val
);
824 static const MemoryRegionOps mv64361_ops
= {
825 .read
= mv64361_read
,
826 .write
= mv64361_write
,
827 .valid
.min_access_size
= 1,
828 .valid
.max_access_size
= 4,
829 .endianness
= DEVICE_LITTLE_ENDIAN
,
832 static void mv64361_gpp_irq(void *opaque
, int n
, int level
)
834 MV64361State
*s
= opaque
;
835 uint32_t mask
= BIT(n
);
836 uint32_t val
= s
->gpp_value
& ~mask
;
838 if (s
->gpp_level
& mask
) {
842 if (val
> s
->gpp_value
) {
844 s
->gpp_int_cr
|= mask
;
845 if (s
->gpp_int_mask
& mask
) {
846 mv64361_update_irq(opaque
, MV64361_IRQ_P0_GPP0_7
+ n
/ 8, 1);
848 } else if (val
< s
->gpp_value
) {
851 if (s
->gpp_int_level
&& !(val
& 0xff << b
)) {
852 mv64361_update_irq(opaque
, MV64361_IRQ_P0_GPP0_7
+ b
, 0);
857 static void mv64361_realize(DeviceState
*dev
, Error
**errp
)
859 MV64361State
*s
= MV64361(dev
);
862 s
->base_addr_enable
= 0x1fffff;
863 memory_region_init_io(&s
->regs
, OBJECT(s
), &mv64361_ops
, s
,
864 TYPE_MV64361
, 0x10000);
865 sysbus_init_mmio(SYS_BUS_DEVICE(dev
), &s
->regs
);
866 for (i
= 0; i
< 2; i
++) {
867 g_autofree
char *name
= g_strdup_printf("pcihost%d", i
);
868 object_initialize_child(OBJECT(dev
), name
, &s
->pci
[i
],
870 DeviceState
*pci
= DEVICE(&s
->pci
[i
]);
871 qdev_prop_set_uint8(pci
, "index", i
);
872 sysbus_realize_and_unref(SYS_BUS_DEVICE(pci
), &error_fatal
);
874 sysbus_init_irq(SYS_BUS_DEVICE(dev
), &s
->cpu_irq
);
875 qdev_init_gpio_in_named(dev
, mv64361_gpp_irq
, "gpp", 32);
878 static void mv64361_reset(DeviceState
*dev
)
880 MV64361State
*s
= MV64361(dev
);
884 * These values may be board specific
885 * Real chip supports init from an eprom but that's not modelled
887 set_mem_windows(s
, 0x1fffff);
888 s
->cpu_conf
= 0x28000ff;
889 s
->regs_base
= 0x100f100;
890 s
->pci
[0].io_base
= 0x100f800;
891 s
->pci
[0].io_size
= 0xff;
892 s
->pci
[0].mem_base
[0] = 0x100c000;
893 s
->pci
[0].mem_size
[0] = 0x1fff;
894 s
->pci
[0].mem_base
[1] = 0x100f900;
895 s
->pci
[0].mem_size
[1] = 0xff;
896 s
->pci
[0].mem_base
[2] = 0x100f400;
897 s
->pci
[0].mem_size
[2] = 0x1ff;
898 s
->pci
[0].mem_base
[3] = 0x100f600;
899 s
->pci
[0].mem_size
[3] = 0x1ff;
900 s
->pci
[1].io_base
= 0x100fe00;
901 s
->pci
[1].io_size
= 0xff;
902 s
->pci
[1].mem_base
[0] = 0x1008000;
903 s
->pci
[1].mem_size
[0] = 0x3fff;
904 s
->pci
[1].mem_base
[1] = 0x100fd00;
905 s
->pci
[1].mem_size
[1] = 0xff;
906 s
->pci
[1].mem_base
[2] = 0x1002600;
907 s
->pci
[1].mem_size
[2] = 0x1ff;
908 s
->pci
[1].mem_base
[3] = 0x100ff80;
909 s
->pci
[1].mem_size
[3] = 0x7f;
910 for (i
= 0; i
< 2; i
++) {
911 for (j
= 0; j
< 4; j
++) {
912 s
->pci
[i
].remap
[j
] = s
->pci
[i
].mem_base
[j
] << 16;
915 s
->pci
[0].remap
[1] = 0;
916 s
->pci
[1].remap
[1] = 0;
917 set_mem_windows(s
, 0xfbfff);
920 static void mv64361_class_init(ObjectClass
*klass
, void *data
)
922 DeviceClass
*dc
= DEVICE_CLASS(klass
);
924 dc
->realize
= mv64361_realize
;
925 dc
->reset
= mv64361_reset
;
928 static const TypeInfo mv64361_type_info
= {
929 .name
= TYPE_MV64361
,
930 .parent
= TYPE_SYS_BUS_DEVICE
,
931 .instance_size
= sizeof(MV64361State
),
932 .class_init
= mv64361_class_init
,
935 static void mv64361_register_types(void)
937 type_register_static(&mv64361_type_info
);
940 type_init(mv64361_register_types
)