11
#include "qemu/osdep.h"
13
#include "qemu/module.h"
14
#include "hw/misc/bcm2835_powermgt.h"
15
#include "migration/vmstate.h"
16
#include "sysemu/runstate.h"
18
#define PASSWORD 0x5a000000
19
#define PASSWORD_MASK 0xff000000
22
#define V_RSTC_RESET 0x20
24
#define V_RSTS_POWEROFF 0x555
27
static uint64_t bcm2835_powermgt_read(void *opaque, hwaddr offset,
30
BCM2835PowerMgtState *s = (BCM2835PowerMgtState *)opaque;
45
qemu_log_mask(LOG_UNIMP,
46
"bcm2835_powermgt_read: Unknown offset 0x%08"HWADDR_PRIx
55
static void bcm2835_powermgt_write(void *opaque, hwaddr offset,
56
uint64_t value, unsigned size)
58
BCM2835PowerMgtState *s = (BCM2835PowerMgtState *)opaque;
60
if ((value & PASSWORD_MASK) != PASSWORD) {
61
qemu_log_mask(LOG_GUEST_ERROR,
62
"bcm2835_powermgt_write: Bad password 0x%"PRIx64
63
" at offset 0x%08"HWADDR_PRIx"\n",
68
value = value & ~PASSWORD_MASK;
73
if (value & V_RSTC_RESET) {
74
if ((s->rsts & 0xfff) == V_RSTS_POWEROFF) {
75
qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
77
qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
82
qemu_log_mask(LOG_UNIMP,
83
"bcm2835_powermgt_write: RSTS\n");
87
qemu_log_mask(LOG_UNIMP,
88
"bcm2835_powermgt_write: WDOG\n");
93
qemu_log_mask(LOG_UNIMP,
94
"bcm2835_powermgt_write: Unknown offset 0x%08"HWADDR_PRIx
100
static const MemoryRegionOps bcm2835_powermgt_ops = {
101
.read = bcm2835_powermgt_read,
102
.write = bcm2835_powermgt_write,
103
.endianness = DEVICE_NATIVE_ENDIAN,
104
.impl.min_access_size = 4,
105
.impl.max_access_size = 4,
108
static const VMStateDescription vmstate_bcm2835_powermgt = {
109
.name = TYPE_BCM2835_POWERMGT,
111
.minimum_version_id = 1,
112
.fields = (const VMStateField[]) {
113
VMSTATE_UINT32(rstc, BCM2835PowerMgtState),
114
VMSTATE_UINT32(rsts, BCM2835PowerMgtState),
115
VMSTATE_UINT32(wdog, BCM2835PowerMgtState),
116
VMSTATE_END_OF_LIST()
120
static void bcm2835_powermgt_init(Object *obj)
122
BCM2835PowerMgtState *s = BCM2835_POWERMGT(obj);
124
memory_region_init_io(&s->iomem, obj, &bcm2835_powermgt_ops, s,
125
TYPE_BCM2835_POWERMGT, 0x200);
126
sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem);
129
static void bcm2835_powermgt_reset(DeviceState *dev)
131
BCM2835PowerMgtState *s = BCM2835_POWERMGT(dev);
134
s->rstc = 0x00000102;
135
s->rsts = 0x00001000;
136
s->wdog = 0x00000000;
139
static void bcm2835_powermgt_class_init(ObjectClass *klass, void *data)
141
DeviceClass *dc = DEVICE_CLASS(klass);
143
dc->reset = bcm2835_powermgt_reset;
144
dc->vmsd = &vmstate_bcm2835_powermgt;
147
static const TypeInfo bcm2835_powermgt_info = {
148
.name = TYPE_BCM2835_POWERMGT,
149
.parent = TYPE_SYS_BUS_DEVICE,
150
.instance_size = sizeof(BCM2835PowerMgtState),
151
.class_init = bcm2835_powermgt_class_init,
152
.instance_init = bcm2835_powermgt_init,
155
static void bcm2835_powermgt_register_types(void)
157
type_register_static(&bcm2835_powermgt_info);
160
type_init(bcm2835_powermgt_register_types)