2 * Raspberry Pi emulation (c) 2012 Gregory Estrade
3 * This code is licensed under the GNU GPLv2 and later.
6 #include "qemu/osdep.h"
8 #include "hw/misc/bcm2835_mphi.h"
10 static void bcm2835_mphi_update_irq(BCM2835MphiState
*s
)
12 if (s
->mphi_intstat
) {
13 qemu_set_irq(s
->irq
, 1);
15 qemu_set_irq(s
->irq
, 0);
19 static uint64_t bcm2835_mphi_read(void *opaque
, hwaddr offset
,
22 BCM2835MphiState
*s
= (BCM2835MphiState
*)opaque
;
28 case 0x00: /* mphi_base */
31 case 0x28: /* mphi_outdda */
34 case 0x2c: /* mphi_outddb */
37 case 0x4c: /* mphi_ctrl */
40 case 0x50: /* mphi_intstat */
41 res
= s
->mphi_intstat
;
45 qemu_log_mask(LOG_GUEST_ERROR
,
46 "bcm2835_mphi_read: Bad offset %x\n", (int)offset
);
54 static void bcm2835_mphi_write(void *opaque
, hwaddr offset
,
55 uint64_t value
, unsigned size
)
57 BCM2835MphiState
*s
= (BCM2835MphiState
*)opaque
;
63 case 0x00: /* mphi_base */
66 case 0x28: /* mphi_outdda */
67 s
->mphi_outdda
= value
;
69 case 0x2c: /* mphi_outddb */
70 s
->mphi_outddb
= value
;
71 if (value
& (1 << 29)) {
72 /* Enable MPHI interrupt */
73 s
->mphi_intstat
|= (1 << 16);
77 case 0x4c: /* mphi_ctrl */
78 s
->mphi_ctrl
&= ~(1 << 31);
79 s
->mphi_ctrl
|= value
& (1 << 31);
81 s
->mphi_ctrl
&= ~(3 << 16);
82 if (value
& (1 << 16)) {
83 s
->mphi_ctrl
|= (3 << 16);
87 case 0x50: /* mphi_intstat */
88 s
->mphi_intstat
&= ~value
;
93 qemu_log_mask(LOG_GUEST_ERROR
,
94 "bcm2835_mphi_write: Bad offset %x\n", (int)offset
);
99 bcm2835_mphi_update_irq(s
);
103 static const MemoryRegionOps bcm2835_mphi_ops
= {
104 .read
= bcm2835_mphi_read
,
105 .write
= bcm2835_mphi_write
,
106 .endianness
= DEVICE_NATIVE_ENDIAN
,
109 static const VMStateDescription vmstate_bcm2835_mphi
= {
110 .name
= TYPE_BCM2835_MPHI
,
112 .minimum_version_id
= 1,
113 .minimum_version_id_old
= 1,
114 .fields
= (VMStateField
[]) {
115 VMSTATE_END_OF_LIST()
119 static void bcm2835_mphi_init(Object
*obj
)
121 BCM2835MphiState
*s
= BCM2835_MPHI(obj
);
123 memory_region_init_io(&s
->iomem
, obj
, &bcm2835_mphi_ops
, s
,
124 TYPE_BCM2835_MPHI
, 0x1000);
125 sysbus_init_mmio(SYS_BUS_DEVICE(s
), &s
->iomem
);
126 sysbus_init_irq(SYS_BUS_DEVICE(s
), &s
->irq
);
129 static void bcm2835_mphi_realize(DeviceState
*dev
, Error
**errp
)
131 BCM2835MphiState
*s
= BCM2835_MPHI(dev
);
140 static void bcm2835_mphi_class_init(ObjectClass
*klass
, void *data
)
142 DeviceClass
*dc
= DEVICE_CLASS(klass
);
144 dc
->realize
= bcm2835_mphi_realize
;
145 dc
->vmsd
= &vmstate_bcm2835_mphi
;
148 static TypeInfo bcm2835_mphi_info
= {
149 .name
= TYPE_BCM2835_MPHI
,
150 .parent
= TYPE_SYS_BUS_DEVICE
,
151 .instance_size
= sizeof(BCM2835MphiState
),
152 .class_init
= bcm2835_mphi_class_init
,
153 .instance_init
= bcm2835_mphi_init
,
156 static void bcm2835_mphi_register_types(void)
158 type_register_static(&bcm2835_mphi_info
);
161 type_init(bcm2835_mphi_register_types
)