25
#include "qemu/osdep.h"
28
#include "migration/vmstate.h"
29
#include "qemu/module.h"
30
#include "sysemu/runstate.h"
32
#include "qom/object.h"
42
#define TYPE_SLAVIO_MISC "slavio_misc"
43
OBJECT_DECLARE_SIMPLE_TYPE(MiscState, SLAVIO_MISC)
46
SysBusDevice parent_obj;
48
MemoryRegion cfg_iomem;
49
MemoryRegion diag_iomem;
50
MemoryRegion mdm_iomem;
51
MemoryRegion led_iomem;
52
MemoryRegion sysctrl_iomem;
53
MemoryRegion aux1_iomem;
54
MemoryRegion aux2_iomem;
66
typedef struct APCState APCState;
67
DECLARE_INSTANCE_CHECKER(APCState, APC,
71
SysBusDevice parent_obj;
83
#define AUX2_PWROFF 0x01
84
#define AUX2_PWRINTCLR 0x02
85
#define AUX2_PWRFAIL 0x20
87
#define CFG_PWRINTEN 0x08
90
#define SYS_RESETSTAT 0x02
92
static void slavio_misc_update_irq(void *opaque)
94
MiscState *s = opaque;
96
if ((s->aux2 & AUX2_PWRFAIL) && (s->config & CFG_PWRINTEN)) {
97
trace_slavio_misc_update_irq_raise();
98
qemu_irq_raise(s->irq);
100
trace_slavio_misc_update_irq_lower();
101
qemu_irq_lower(s->irq);
105
static void slavio_misc_reset(DeviceState *d)
107
MiscState *s = SLAVIO_MISC(d);
110
s->config = s->aux1 = s->aux2 = s->mctrl = 0;
113
static void slavio_set_power_fail(void *opaque, int irq, int power_failing)
115
MiscState *s = opaque;
117
trace_slavio_set_power_fail(power_failing, s->config);
118
if (power_failing && (s->config & CFG_PWRINTEN)) {
119
s->aux2 |= AUX2_PWRFAIL;
121
s->aux2 &= ~AUX2_PWRFAIL;
123
slavio_misc_update_irq(s);
126
static void slavio_cfg_mem_writeb(void *opaque, hwaddr addr,
127
uint64_t val, unsigned size)
129
MiscState *s = opaque;
131
trace_slavio_cfg_mem_writeb(val & 0xff);
132
s->config = val & 0xff;
133
slavio_misc_update_irq(s);
136
static uint64_t slavio_cfg_mem_readb(void *opaque, hwaddr addr,
139
MiscState *s = opaque;
143
trace_slavio_cfg_mem_readb(ret);
147
static const MemoryRegionOps slavio_cfg_mem_ops = {
148
.read = slavio_cfg_mem_readb,
149
.write = slavio_cfg_mem_writeb,
150
.endianness = DEVICE_NATIVE_ENDIAN,
152
.min_access_size = 1,
153
.max_access_size = 1,
157
static void slavio_diag_mem_writeb(void *opaque, hwaddr addr,
158
uint64_t val, unsigned size)
160
MiscState *s = opaque;
162
trace_slavio_diag_mem_writeb(val & 0xff);
163
s->diag = val & 0xff;
166
static uint64_t slavio_diag_mem_readb(void *opaque, hwaddr addr,
169
MiscState *s = opaque;
173
trace_slavio_diag_mem_readb(ret);
177
static const MemoryRegionOps slavio_diag_mem_ops = {
178
.read = slavio_diag_mem_readb,
179
.write = slavio_diag_mem_writeb,
180
.endianness = DEVICE_NATIVE_ENDIAN,
182
.min_access_size = 1,
183
.max_access_size = 1,
187
static void slavio_mdm_mem_writeb(void *opaque, hwaddr addr,
188
uint64_t val, unsigned size)
190
MiscState *s = opaque;
192
trace_slavio_mdm_mem_writeb(val & 0xff);
193
s->mctrl = val & 0xff;
196
static uint64_t slavio_mdm_mem_readb(void *opaque, hwaddr addr,
199
MiscState *s = opaque;
203
trace_slavio_mdm_mem_readb(ret);
207
static const MemoryRegionOps slavio_mdm_mem_ops = {
208
.read = slavio_mdm_mem_readb,
209
.write = slavio_mdm_mem_writeb,
210
.endianness = DEVICE_NATIVE_ENDIAN,
212
.min_access_size = 1,
213
.max_access_size = 1,
217
static void slavio_aux1_mem_writeb(void *opaque, hwaddr addr,
218
uint64_t val, unsigned size)
220
MiscState *s = opaque;
222
trace_slavio_aux1_mem_writeb(val & 0xff);
226
qemu_irq_raise(s->fdc_tc);
227
qemu_irq_lower(s->fdc_tc);
231
s->aux1 = val & 0xff;
234
static uint64_t slavio_aux1_mem_readb(void *opaque, hwaddr addr,
237
MiscState *s = opaque;
241
trace_slavio_aux1_mem_readb(ret);
245
static const MemoryRegionOps slavio_aux1_mem_ops = {
246
.read = slavio_aux1_mem_readb,
247
.write = slavio_aux1_mem_writeb,
248
.endianness = DEVICE_NATIVE_ENDIAN,
250
.min_access_size = 1,
251
.max_access_size = 1,
255
static void slavio_aux2_mem_writeb(void *opaque, hwaddr addr,
256
uint64_t val, unsigned size)
258
MiscState *s = opaque;
260
val &= AUX2_PWRINTCLR | AUX2_PWROFF;
261
trace_slavio_aux2_mem_writeb(val & 0xff);
262
val |= s->aux2 & AUX2_PWRFAIL;
263
if (val & AUX2_PWRINTCLR)
266
if (val & AUX2_PWROFF)
267
qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
268
slavio_misc_update_irq(s);
271
static uint64_t slavio_aux2_mem_readb(void *opaque, hwaddr addr,
274
MiscState *s = opaque;
278
trace_slavio_aux2_mem_readb(ret);
282
static const MemoryRegionOps slavio_aux2_mem_ops = {
283
.read = slavio_aux2_mem_readb,
284
.write = slavio_aux2_mem_writeb,
285
.endianness = DEVICE_NATIVE_ENDIAN,
287
.min_access_size = 1,
288
.max_access_size = 1,
292
static void apc_mem_writeb(void *opaque, hwaddr addr,
293
uint64_t val, unsigned size)
295
APCState *s = opaque;
297
trace_apc_mem_writeb(val & 0xff);
298
qemu_irq_raise(s->cpu_halt);
301
static uint64_t apc_mem_readb(void *opaque, hwaddr addr,
306
trace_apc_mem_readb(ret);
310
static const MemoryRegionOps apc_mem_ops = {
311
.read = apc_mem_readb,
312
.write = apc_mem_writeb,
313
.endianness = DEVICE_NATIVE_ENDIAN,
315
.min_access_size = 1,
316
.max_access_size = 1,
320
static uint64_t slavio_sysctrl_mem_readl(void *opaque, hwaddr addr,
323
MiscState *s = opaque;
333
trace_slavio_sysctrl_mem_readl(ret);
337
static void slavio_sysctrl_mem_writel(void *opaque, hwaddr addr,
338
uint64_t val, unsigned size)
340
MiscState *s = opaque;
342
trace_slavio_sysctrl_mem_writel(val);
345
if (val & SYS_RESET) {
346
s->sysctrl = SYS_RESETSTAT;
347
qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
355
static const MemoryRegionOps slavio_sysctrl_mem_ops = {
356
.read = slavio_sysctrl_mem_readl,
357
.write = slavio_sysctrl_mem_writel,
358
.endianness = DEVICE_NATIVE_ENDIAN,
360
.min_access_size = 4,
361
.max_access_size = 4,
365
static uint64_t slavio_led_mem_readw(void *opaque, hwaddr addr,
368
MiscState *s = opaque;
378
trace_slavio_led_mem_readw(ret);
382
static void slavio_led_mem_writew(void *opaque, hwaddr addr,
383
uint64_t val, unsigned size)
385
MiscState *s = opaque;
387
trace_slavio_led_mem_writew(val & 0xffff);
397
static const MemoryRegionOps slavio_led_mem_ops = {
398
.read = slavio_led_mem_readw,
399
.write = slavio_led_mem_writew,
400
.endianness = DEVICE_NATIVE_ENDIAN,
402
.min_access_size = 2,
403
.max_access_size = 2,
407
static const VMStateDescription vmstate_misc = {
408
.name ="slavio_misc",
410
.minimum_version_id = 1,
411
.fields = (const VMStateField[]) {
412
VMSTATE_UINT32(dummy, MiscState),
413
VMSTATE_UINT8(config, MiscState),
414
VMSTATE_UINT8(aux1, MiscState),
415
VMSTATE_UINT8(aux2, MiscState),
416
VMSTATE_UINT8(diag, MiscState),
417
VMSTATE_UINT8(mctrl, MiscState),
418
VMSTATE_UINT8(sysctrl, MiscState),
419
VMSTATE_END_OF_LIST()
423
static void apc_init(Object *obj)
425
APCState *s = APC(obj);
426
SysBusDevice *dev = SYS_BUS_DEVICE(obj);
428
sysbus_init_irq(dev, &s->cpu_halt);
431
memory_region_init_io(&s->iomem, obj, &apc_mem_ops, s,
433
sysbus_init_mmio(dev, &s->iomem);
436
static void slavio_misc_init(Object *obj)
438
DeviceState *dev = DEVICE(obj);
439
MiscState *s = SLAVIO_MISC(obj);
440
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
442
sysbus_init_irq(sbd, &s->irq);
443
sysbus_init_irq(sbd, &s->fdc_tc);
447
memory_region_init_io(&s->cfg_iomem, obj, &slavio_cfg_mem_ops, s,
448
"configuration", MISC_SIZE);
449
sysbus_init_mmio(sbd, &s->cfg_iomem);
452
memory_region_init_io(&s->diag_iomem, obj, &slavio_diag_mem_ops, s,
453
"diagnostic", MISC_SIZE);
454
sysbus_init_mmio(sbd, &s->diag_iomem);
457
memory_region_init_io(&s->mdm_iomem, obj, &slavio_mdm_mem_ops, s,
459
sysbus_init_mmio(sbd, &s->mdm_iomem);
463
memory_region_init_io(&s->led_iomem, obj, &slavio_led_mem_ops, s,
465
sysbus_init_mmio(sbd, &s->led_iomem);
469
memory_region_init_io(&s->sysctrl_iomem, obj, &slavio_sysctrl_mem_ops, s,
470
"system-control", SYSCTRL_SIZE);
471
sysbus_init_mmio(sbd, &s->sysctrl_iomem);
474
memory_region_init_io(&s->aux1_iomem, obj, &slavio_aux1_mem_ops, s,
475
"misc-system-functions", MISC_SIZE);
476
sysbus_init_mmio(sbd, &s->aux1_iomem);
479
memory_region_init_io(&s->aux2_iomem, obj, &slavio_aux2_mem_ops, s,
480
"software-powerdown-control", MISC_SIZE);
481
sysbus_init_mmio(sbd, &s->aux2_iomem);
483
qdev_init_gpio_in(dev, slavio_set_power_fail, 1);
486
static void slavio_misc_class_init(ObjectClass *klass, void *data)
488
DeviceClass *dc = DEVICE_CLASS(klass);
490
dc->reset = slavio_misc_reset;
491
dc->vmsd = &vmstate_misc;
494
static const TypeInfo slavio_misc_info = {
495
.name = TYPE_SLAVIO_MISC,
496
.parent = TYPE_SYS_BUS_DEVICE,
497
.instance_size = sizeof(MiscState),
498
.instance_init = slavio_misc_init,
499
.class_init = slavio_misc_class_init,
502
static const TypeInfo apc_info = {
504
.parent = TYPE_SYS_BUS_DEVICE,
505
.instance_size = sizeof(MiscState),
506
.instance_init = apc_init,
509
static void slavio_misc_register_types(void)
511
type_register_static(&slavio_misc_info);
512
type_register_static(&apc_info);
515
type_init(slavio_misc_register_types)