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_ETH_PHY_ADDR
:
547 case MV64340_ETH_SMI
:
550 case MV64340_CUNIT_ARBITER_CONTROL_REG
:
551 ret
= 0x11ff0000 | (s
->gpp_int_level
<< 10);
553 case MV64340_GPP_IO_CONTROL
:
556 case MV64340_GPP_LEVEL_CONTROL
:
559 case MV64340_GPP_VALUE
:
562 case MV64340_GPP_VALUE_SET
:
563 case MV64340_GPP_VALUE_CLEAR
:
566 case MV64340_GPP_INTERRUPT_CAUSE
:
569 case MV64340_GPP_INTERRUPT_MASK0
:
570 case MV64340_GPP_INTERRUPT_MASK1
:
571 ret
= s
->gpp_int_mask
;
574 qemu_log_mask(LOG_UNIMP
, "%s: Unimplemented register read 0x%"
575 HWADDR_PRIx
"\n", __func__
, addr
);
578 if (addr
!= MV64340_PCI_1_INTERRUPT_ACKNOWLEDGE_VIRTUAL_REG
) {
579 trace_mv64361_reg_read(addr
, ret
);
584 static void warn_swap_bit(uint64_t val
)
586 if ((val
& 0x3000000ULL
) >> 24 != 1) {
587 qemu_log_mask(LOG_UNIMP
, "%s: Data swap not implemented", __func__
);
591 static void mv64361_set_pci_mem_remap(MV64361State
*s
, int bus
, int idx
,
592 uint64_t val
, bool high
)
595 s
->pci
[bus
].remap
[idx
] = val
;
597 s
->pci
[bus
].remap
[idx
] &= 0xffffffff00000000ULL
;
598 s
->pci
[bus
].remap
[idx
] |= (val
& 0xffffULL
) << 16;
602 static void mv64361_write(void *opaque
, hwaddr addr
, uint64_t val
,
605 MV64361State
*s
= MV64361(opaque
);
607 trace_mv64361_reg_write(addr
, val
);
609 case MV64340_CPU_CONFIG
:
610 s
->cpu_conf
= val
& 0xe4e3bffULL
;
611 s
->cpu_conf
|= BIT(23);
613 case MV64340_PCI_0_IO_BASE_ADDR
:
614 s
->pci
[0].io_base
= val
& 0x30fffffULL
;
616 if (!(s
->cpu_conf
& BIT(27))) {
617 s
->pci
[0].remap
[4] = (val
& 0xffffULL
) << 16;
620 case MV64340_PCI_0_IO_SIZE
:
621 s
->pci
[0].io_size
= val
& 0xffffULL
;
623 case MV64340_PCI_0_IO_ADDR_REMAP
:
624 s
->pci
[0].remap
[4] = (val
& 0xffffULL
) << 16;
626 case MV64340_PCI_0_MEMORY0_BASE_ADDR
:
627 s
->pci
[0].mem_base
[0] = val
& 0x70fffffULL
;
629 if (!(s
->cpu_conf
& BIT(27))) {
630 mv64361_set_pci_mem_remap(s
, 0, 0, val
, false);
633 case MV64340_PCI_0_MEMORY0_SIZE
:
634 s
->pci
[0].mem_size
[0] = val
& 0xffffULL
;
636 case MV64340_PCI_0_MEMORY0_LOW_ADDR_REMAP
:
637 case MV64340_PCI_0_MEMORY0_HIGH_ADDR_REMAP
:
638 mv64361_set_pci_mem_remap(s
, 0, 0, val
,
639 (addr
== MV64340_PCI_0_MEMORY0_HIGH_ADDR_REMAP
));
641 case MV64340_PCI_0_MEMORY1_BASE_ADDR
:
642 s
->pci
[0].mem_base
[1] = val
& 0x70fffffULL
;
644 if (!(s
->cpu_conf
& BIT(27))) {
645 mv64361_set_pci_mem_remap(s
, 0, 1, val
, false);
648 case MV64340_PCI_0_MEMORY1_SIZE
:
649 s
->pci
[0].mem_size
[1] = val
& 0xffffULL
;
651 case MV64340_PCI_0_MEMORY1_LOW_ADDR_REMAP
:
652 case MV64340_PCI_0_MEMORY1_HIGH_ADDR_REMAP
:
653 mv64361_set_pci_mem_remap(s
, 0, 1, val
,
654 (addr
== MV64340_PCI_0_MEMORY1_HIGH_ADDR_REMAP
));
656 case MV64340_PCI_0_MEMORY2_BASE_ADDR
:
657 s
->pci
[0].mem_base
[2] = val
& 0x70fffffULL
;
659 if (!(s
->cpu_conf
& BIT(27))) {
660 mv64361_set_pci_mem_remap(s
, 0, 2, val
, false);
663 case MV64340_PCI_0_MEMORY2_SIZE
:
664 s
->pci
[0].mem_size
[2] = val
& 0xffffULL
;
666 case MV64340_PCI_0_MEMORY2_LOW_ADDR_REMAP
:
667 case MV64340_PCI_0_MEMORY2_HIGH_ADDR_REMAP
:
668 mv64361_set_pci_mem_remap(s
, 0, 2, val
,
669 (addr
== MV64340_PCI_0_MEMORY2_HIGH_ADDR_REMAP
));
671 case MV64340_PCI_0_MEMORY3_BASE_ADDR
:
672 s
->pci
[0].mem_base
[3] = val
& 0x70fffffULL
;
674 if (!(s
->cpu_conf
& BIT(27))) {
675 mv64361_set_pci_mem_remap(s
, 0, 3, val
, false);
678 case MV64340_PCI_0_MEMORY3_SIZE
:
679 s
->pci
[0].mem_size
[3] = val
& 0xffffULL
;
681 case MV64340_PCI_0_MEMORY3_LOW_ADDR_REMAP
:
682 case MV64340_PCI_0_MEMORY3_HIGH_ADDR_REMAP
:
683 mv64361_set_pci_mem_remap(s
, 0, 3, val
,
684 (addr
== MV64340_PCI_0_MEMORY3_HIGH_ADDR_REMAP
));
686 case MV64340_PCI_1_IO_BASE_ADDR
:
687 s
->pci
[1].io_base
= val
& 0x30fffffULL
;
689 if (!(s
->cpu_conf
& BIT(27))) {
690 s
->pci
[1].remap
[4] = (val
& 0xffffULL
) << 16;
693 case MV64340_PCI_1_IO_SIZE
:
694 s
->pci
[1].io_size
= val
& 0xffffULL
;
696 case MV64340_PCI_1_MEMORY0_BASE_ADDR
:
697 s
->pci
[1].mem_base
[0] = val
& 0x70fffffULL
;
699 if (!(s
->cpu_conf
& BIT(27))) {
700 mv64361_set_pci_mem_remap(s
, 1, 0, val
, false);
703 case MV64340_PCI_1_MEMORY0_SIZE
:
704 s
->pci
[1].mem_size
[0] = val
& 0xffffULL
;
706 case MV64340_PCI_1_MEMORY0_LOW_ADDR_REMAP
:
707 case MV64340_PCI_1_MEMORY0_HIGH_ADDR_REMAP
:
708 mv64361_set_pci_mem_remap(s
, 1, 0, val
,
709 (addr
== MV64340_PCI_1_MEMORY0_HIGH_ADDR_REMAP
));
711 case MV64340_PCI_1_MEMORY1_BASE_ADDR
:
712 s
->pci
[1].mem_base
[1] = val
& 0x70fffffULL
;
714 if (!(s
->cpu_conf
& BIT(27))) {
715 mv64361_set_pci_mem_remap(s
, 1, 1, val
, false);
718 case MV64340_PCI_1_MEMORY1_SIZE
:
719 s
->pci
[1].mem_size
[1] = val
& 0xffffULL
;
721 case MV64340_PCI_1_MEMORY1_LOW_ADDR_REMAP
:
722 case MV64340_PCI_1_MEMORY1_HIGH_ADDR_REMAP
:
723 mv64361_set_pci_mem_remap(s
, 1, 1, val
,
724 (addr
== MV64340_PCI_1_MEMORY1_HIGH_ADDR_REMAP
));
726 case MV64340_PCI_1_MEMORY2_BASE_ADDR
:
727 s
->pci
[1].mem_base
[2] = val
& 0x70fffffULL
;
729 if (!(s
->cpu_conf
& BIT(27))) {
730 mv64361_set_pci_mem_remap(s
, 1, 2, val
, false);
733 case MV64340_PCI_1_MEMORY2_SIZE
:
734 s
->pci
[1].mem_size
[2] = val
& 0xffffULL
;
736 case MV64340_PCI_1_MEMORY2_LOW_ADDR_REMAP
:
737 case MV64340_PCI_1_MEMORY2_HIGH_ADDR_REMAP
:
738 mv64361_set_pci_mem_remap(s
, 1, 2, val
,
739 (addr
== MV64340_PCI_1_MEMORY2_HIGH_ADDR_REMAP
));
741 case MV64340_PCI_1_MEMORY3_BASE_ADDR
:
742 s
->pci
[1].mem_base
[3] = val
& 0x70fffffULL
;
744 if (!(s
->cpu_conf
& BIT(27))) {
745 mv64361_set_pci_mem_remap(s
, 1, 3, val
, false);
748 case MV64340_PCI_1_MEMORY3_SIZE
:
749 s
->pci
[1].mem_size
[3] = val
& 0xffffULL
;
751 case MV64340_PCI_1_MEMORY3_LOW_ADDR_REMAP
:
752 case MV64340_PCI_1_MEMORY3_HIGH_ADDR_REMAP
:
753 mv64361_set_pci_mem_remap(s
, 1, 3, val
,
754 (addr
== MV64340_PCI_1_MEMORY3_HIGH_ADDR_REMAP
));
756 case MV64340_INTERNAL_SPACE_BASE_ADDR
:
757 s
->regs_base
= val
& 0xfffffULL
;
759 case MV64340_BASE_ADDR_ENABLE
:
760 set_mem_windows(s
, val
);
762 case MV64340_PCI_0_CONFIG_ADDR
:
763 pci_host_conf_le_ops
.write(PCI_HOST_BRIDGE(&s
->pci
[0]), 0, val
, size
);
765 case MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG
...
766 MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG
+ 3:
767 pci_host_data_le_ops
.write(PCI_HOST_BRIDGE(&s
->pci
[0]),
768 addr
- MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG
, val
, size
);
770 case MV64340_PCI_1_CONFIG_ADDR
:
771 pci_host_conf_le_ops
.write(PCI_HOST_BRIDGE(&s
->pci
[1]), 0, val
, size
);
773 case MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG
...
774 MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG
+ 3:
775 pci_host_data_le_ops
.write(PCI_HOST_BRIDGE(&s
->pci
[1]),
776 addr
- MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG
, val
, size
);
778 case MV64340_CPU_INTERRUPT0_MASK_LOW
:
779 s
->cpu0_int_mask
&= 0xffffffff00000000ULL
;
780 s
->cpu0_int_mask
|= val
& 0xffffffffULL
;
782 case MV64340_CPU_INTERRUPT0_MASK_HIGH
:
783 s
->cpu0_int_mask
&= 0xffffffffULL
;
784 s
->cpu0_int_mask
|= val
<< 32;
786 case MV64340_CUNIT_ARBITER_CONTROL_REG
:
787 s
->gpp_int_level
= !!(val
& BIT(10));
789 case MV64340_GPP_IO_CONTROL
:
792 case MV64340_GPP_LEVEL_CONTROL
:
795 case MV64340_GPP_VALUE
:
796 s
->gpp_value
&= ~s
->gpp_io
;
797 s
->gpp_value
|= val
& s
->gpp_io
;
799 case MV64340_GPP_VALUE_SET
:
800 s
->gpp_value
|= val
& s
->gpp_io
;
802 case MV64340_GPP_VALUE_CLEAR
:
803 s
->gpp_value
&= ~(val
& s
->gpp_io
);
805 case MV64340_GPP_INTERRUPT_CAUSE
:
806 if (!s
->gpp_int_level
&& val
!= s
->gpp_int_cr
) {
808 uint32_t ch
= s
->gpp_int_cr
^ val
;
810 for (i
= 0; i
< 4; i
++) {
811 if ((ch
& 0xff << i
) && !(val
& 0xff << i
)) {
812 mv64361_update_irq(opaque
, MV64361_IRQ_P0_GPP0_7
+ i
, 0);
819 case MV64340_GPP_INTERRUPT_MASK0
:
820 case MV64340_GPP_INTERRUPT_MASK1
:
821 s
->gpp_int_mask
= val
;
824 qemu_log_mask(LOG_UNIMP
, "%s: Unimplemented register write 0x%"
825 HWADDR_PRIx
" = %"PRIx64
"\n", __func__
, addr
, val
);
830 static const MemoryRegionOps mv64361_ops
= {
831 .read
= mv64361_read
,
832 .write
= mv64361_write
,
833 .valid
.min_access_size
= 1,
834 .valid
.max_access_size
= 4,
835 .endianness
= DEVICE_LITTLE_ENDIAN
,
838 static void mv64361_gpp_irq(void *opaque
, int n
, int level
)
840 MV64361State
*s
= opaque
;
841 uint32_t mask
= BIT(n
);
842 uint32_t val
= s
->gpp_value
& ~mask
;
844 if (s
->gpp_level
& mask
) {
848 if (val
> s
->gpp_value
) {
850 s
->gpp_int_cr
|= mask
;
851 if (s
->gpp_int_mask
& mask
) {
852 mv64361_update_irq(opaque
, MV64361_IRQ_P0_GPP0_7
+ n
/ 8, 1);
854 } else if (val
< s
->gpp_value
) {
857 if (s
->gpp_int_level
&& !(val
& 0xff << b
)) {
858 mv64361_update_irq(opaque
, MV64361_IRQ_P0_GPP0_7
+ b
, 0);
863 static void mv64361_realize(DeviceState
*dev
, Error
**errp
)
865 MV64361State
*s
= MV64361(dev
);
868 s
->base_addr_enable
= 0x1fffff;
869 memory_region_init_io(&s
->regs
, OBJECT(s
), &mv64361_ops
, s
,
870 TYPE_MV64361
, 0x10000);
871 sysbus_init_mmio(SYS_BUS_DEVICE(dev
), &s
->regs
);
872 for (i
= 0; i
< 2; i
++) {
873 g_autofree
char *name
= g_strdup_printf("pcihost%d", i
);
874 object_initialize_child(OBJECT(dev
), name
, &s
->pci
[i
],
876 DeviceState
*pci
= DEVICE(&s
->pci
[i
]);
877 qdev_prop_set_uint8(pci
, "index", i
);
878 sysbus_realize_and_unref(SYS_BUS_DEVICE(pci
), &error_fatal
);
880 sysbus_init_irq(SYS_BUS_DEVICE(dev
), &s
->cpu_irq
);
881 qdev_init_gpio_in_named(dev
, mv64361_gpp_irq
, "gpp", 32);
884 static void mv64361_reset(DeviceState
*dev
)
886 MV64361State
*s
= MV64361(dev
);
890 * These values may be board specific
891 * Real chip supports init from an eprom but that's not modelled
893 set_mem_windows(s
, 0x1fffff);
894 s
->cpu_conf
= 0x28000ff;
895 s
->regs_base
= 0x100f100;
896 s
->pci
[0].io_base
= 0x100f800;
897 s
->pci
[0].io_size
= 0xff;
898 s
->pci
[0].mem_base
[0] = 0x100c000;
899 s
->pci
[0].mem_size
[0] = 0x1fff;
900 s
->pci
[0].mem_base
[1] = 0x100f900;
901 s
->pci
[0].mem_size
[1] = 0xff;
902 s
->pci
[0].mem_base
[2] = 0x100f400;
903 s
->pci
[0].mem_size
[2] = 0x1ff;
904 s
->pci
[0].mem_base
[3] = 0x100f600;
905 s
->pci
[0].mem_size
[3] = 0x1ff;
906 s
->pci
[1].io_base
= 0x100fe00;
907 s
->pci
[1].io_size
= 0xff;
908 s
->pci
[1].mem_base
[0] = 0x1008000;
909 s
->pci
[1].mem_size
[0] = 0x3fff;
910 s
->pci
[1].mem_base
[1] = 0x100fd00;
911 s
->pci
[1].mem_size
[1] = 0xff;
912 s
->pci
[1].mem_base
[2] = 0x1002600;
913 s
->pci
[1].mem_size
[2] = 0x1ff;
914 s
->pci
[1].mem_base
[3] = 0x100ff80;
915 s
->pci
[1].mem_size
[3] = 0x7f;
916 for (i
= 0; i
< 2; i
++) {
917 for (j
= 0; j
< 4; j
++) {
918 s
->pci
[i
].remap
[j
] = s
->pci
[i
].mem_base
[j
] << 16;
921 s
->pci
[0].remap
[1] = 0;
922 s
->pci
[1].remap
[1] = 0;
923 set_mem_windows(s
, 0xfbfff);
926 static void mv64361_class_init(ObjectClass
*klass
, void *data
)
928 DeviceClass
*dc
= DEVICE_CLASS(klass
);
930 dc
->realize
= mv64361_realize
;
931 dc
->reset
= mv64361_reset
;
934 static const TypeInfo mv64361_type_info
= {
935 .name
= TYPE_MV64361
,
936 .parent
= TYPE_SYS_BUS_DEVICE
,
937 .instance_size
= sizeof(MV64361State
),
938 .class_init
= mv64361_class_init
,
941 static void mv64361_register_types(void)
943 type_register_static(&mv64361_type_info
);
946 type_init(mv64361_register_types
)