123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150 |
- /*
- * SPDX-License-Identifer: GPL-2.0-or-later
- *
- * Virt system Controller
- */
- #include "qemu/osdep.h"
- #include "hw/qdev-properties.h"
- #include "hw/sysbus.h"
- #include "migration/vmstate.h"
- #include "qemu/log.h"
- #include "trace.h"
- #include "sysemu/runstate.h"
- #include "hw/misc/virt_ctrl.h"
- enum {
- REG_FEATURES = 0x00,
- REG_CMD = 0x04,
- };
- #define FEAT_POWER_CTRL 0x00000001
- enum {
- CMD_NOOP,
- CMD_RESET,
- CMD_HALT,
- CMD_PANIC,
- };
- static uint64_t virt_ctrl_read(void *opaque, hwaddr addr, unsigned size)
- {
- VirtCtrlState *s = opaque;
- uint64_t value = 0;
- switch (addr) {
- case REG_FEATURES:
- value = FEAT_POWER_CTRL;
- break;
- default:
- qemu_log_mask(LOG_UNIMP,
- "%s: unimplemented register read 0x%02"HWADDR_PRIx"\n",
- __func__, addr);
- break;
- }
- trace_virt_ctrl_write(s, addr, size, value);
- return value;
- }
- static void virt_ctrl_write(void *opaque, hwaddr addr, uint64_t value,
- unsigned size)
- {
- VirtCtrlState *s = opaque;
- trace_virt_ctrl_write(s, addr, size, value);
- switch (addr) {
- case REG_CMD:
- switch (value) {
- case CMD_NOOP:
- break;
- case CMD_RESET:
- qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
- break;
- case CMD_HALT:
- qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
- break;
- case CMD_PANIC:
- qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_PANIC);
- break;
- }
- break;
- default:
- qemu_log_mask(LOG_UNIMP,
- "%s: unimplemented register write 0x%02"HWADDR_PRIx"\n",
- __func__, addr);
- break;
- }
- }
- static const MemoryRegionOps virt_ctrl_ops = {
- .read = virt_ctrl_read,
- .write = virt_ctrl_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
- .valid.max_access_size = 4,
- .impl.max_access_size = 4,
- };
- static void virt_ctrl_reset(DeviceState *dev)
- {
- VirtCtrlState *s = VIRT_CTRL(dev);
- trace_virt_ctrl_reset(s);
- }
- static void virt_ctrl_realize(DeviceState *dev, Error **errp)
- {
- VirtCtrlState *s = VIRT_CTRL(dev);
- trace_virt_ctrl_instance_init(s);
- memory_region_init_io(&s->iomem, OBJECT(s), &virt_ctrl_ops, s,
- "virt-ctrl", 0x100);
- }
- static const VMStateDescription vmstate_virt_ctrl = {
- .name = "virt-ctrl",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32(irq_enabled, VirtCtrlState),
- VMSTATE_END_OF_LIST()
- }
- };
- static void virt_ctrl_instance_init(Object *obj)
- {
- SysBusDevice *dev = SYS_BUS_DEVICE(obj);
- VirtCtrlState *s = VIRT_CTRL(obj);
- trace_virt_ctrl_instance_init(s);
- sysbus_init_mmio(dev, &s->iomem);
- sysbus_init_irq(dev, &s->irq);
- }
- static void virt_ctrl_class_init(ObjectClass *oc, void *data)
- {
- DeviceClass *dc = DEVICE_CLASS(oc);
- dc->reset = virt_ctrl_reset;
- dc->realize = virt_ctrl_realize;
- dc->vmsd = &vmstate_virt_ctrl;
- }
- static const TypeInfo virt_ctrl_info = {
- .name = TYPE_VIRT_CTRL,
- .parent = TYPE_SYS_BUS_DEVICE,
- .class_init = virt_ctrl_class_init,
- .instance_init = virt_ctrl_instance_init,
- .instance_size = sizeof(VirtCtrlState),
- };
- static void virt_ctrl_register_types(void)
- {
- type_register_static(&virt_ctrl_info);
- }
- type_init(virt_ctrl_register_types)
|