qemu/hw/misc/virt_ctrl.c
<<
>>
Prefs
   1/*
   2 * SPDX-License-Identifier: GPL-2.0-or-later
   3 *
   4 * Virt system Controller
   5 */
   6
   7#include "qemu/osdep.h"
   8#include "hw/qdev-properties.h"
   9#include "hw/sysbus.h"
  10#include "migration/vmstate.h"
  11#include "qemu/log.h"
  12#include "trace.h"
  13#include "sysemu/runstate.h"
  14#include "hw/misc/virt_ctrl.h"
  15
  16enum {
  17    REG_FEATURES = 0x00,
  18    REG_CMD      = 0x04,
  19};
  20
  21#define FEAT_POWER_CTRL 0x00000001
  22
  23enum {
  24    CMD_NOOP,
  25    CMD_RESET,
  26    CMD_HALT,
  27    CMD_PANIC,
  28};
  29
  30static uint64_t virt_ctrl_read(void *opaque, hwaddr addr, unsigned size)
  31{
  32    VirtCtrlState *s = opaque;
  33    uint64_t value = 0;
  34
  35    switch (addr) {
  36    case REG_FEATURES:
  37        value = FEAT_POWER_CTRL;
  38        break;
  39    default:
  40        qemu_log_mask(LOG_UNIMP,
  41                      "%s: unimplemented register read 0x%02"HWADDR_PRIx"\n",
  42                      __func__, addr);
  43        break;
  44    }
  45
  46    trace_virt_ctrl_write(s, addr, size, value);
  47
  48    return value;
  49}
  50
  51static void virt_ctrl_write(void *opaque, hwaddr addr, uint64_t value,
  52                            unsigned size)
  53{
  54    VirtCtrlState *s = opaque;
  55
  56    trace_virt_ctrl_write(s, addr, size, value);
  57
  58    switch (addr) {
  59    case REG_CMD:
  60        switch (value) {
  61        case CMD_NOOP:
  62            break;
  63        case CMD_RESET:
  64            qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
  65            break;
  66        case CMD_HALT:
  67            qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
  68            break;
  69        case CMD_PANIC:
  70            qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_PANIC);
  71            break;
  72        }
  73        break;
  74    default:
  75        qemu_log_mask(LOG_UNIMP,
  76                      "%s: unimplemented register write 0x%02"HWADDR_PRIx"\n",
  77                      __func__, addr);
  78        break;
  79    }
  80}
  81
  82static const MemoryRegionOps virt_ctrl_ops = {
  83    .read = virt_ctrl_read,
  84    .write = virt_ctrl_write,
  85    .endianness = DEVICE_NATIVE_ENDIAN,
  86    .valid.max_access_size = 4,
  87    .impl.max_access_size = 4,
  88};
  89
  90static void virt_ctrl_reset(DeviceState *dev)
  91{
  92    VirtCtrlState *s = VIRT_CTRL(dev);
  93
  94    trace_virt_ctrl_reset(s);
  95}
  96
  97static void virt_ctrl_realize(DeviceState *dev, Error **errp)
  98{
  99    VirtCtrlState *s = VIRT_CTRL(dev);
 100
 101    trace_virt_ctrl_instance_init(s);
 102
 103    memory_region_init_io(&s->iomem, OBJECT(s), &virt_ctrl_ops, s,
 104                          "virt-ctrl", 0x100);
 105}
 106
 107static const VMStateDescription vmstate_virt_ctrl = {
 108    .name = "virt-ctrl",
 109    .version_id = 1,
 110    .minimum_version_id = 1,
 111    .fields = (VMStateField[]) {
 112        VMSTATE_UINT32(irq_enabled, VirtCtrlState),
 113        VMSTATE_END_OF_LIST()
 114    }
 115};
 116
 117static void virt_ctrl_instance_init(Object *obj)
 118{
 119    SysBusDevice *dev = SYS_BUS_DEVICE(obj);
 120    VirtCtrlState *s = VIRT_CTRL(obj);
 121
 122    trace_virt_ctrl_instance_init(s);
 123
 124    sysbus_init_mmio(dev, &s->iomem);
 125    sysbus_init_irq(dev, &s->irq);
 126}
 127
 128static void virt_ctrl_class_init(ObjectClass *oc, void *data)
 129{
 130    DeviceClass *dc = DEVICE_CLASS(oc);
 131
 132    dc->reset = virt_ctrl_reset;
 133    dc->realize = virt_ctrl_realize;
 134    dc->vmsd = &vmstate_virt_ctrl;
 135}
 136
 137static const TypeInfo virt_ctrl_info = {
 138    .name = TYPE_VIRT_CTRL,
 139    .parent = TYPE_SYS_BUS_DEVICE,
 140    .class_init = virt_ctrl_class_init,
 141    .instance_init = virt_ctrl_instance_init,
 142    .instance_size = sizeof(VirtCtrlState),
 143};
 144
 145static void virt_ctrl_register_types(void)
 146{
 147    type_register_static(&virt_ctrl_info);
 148}
 149
 150type_init(virt_ctrl_register_types)
 151