qemu/hw/misc/unimp.c
<<
>>
Prefs
   1/* "Unimplemented" device
   2 *
   3 * This is a dummy device which accepts and logs all accesses.
   4 * It's useful for stubbing out regions of an SoC or board
   5 * map which correspond to devices that have not yet been
   6 * implemented. This is often sufficient to placate initial
   7 * guest device driver probing such that the system will
   8 * come up.
   9 *
  10 * Copyright Linaro Limited, 2017
  11 * Written by Peter Maydell
  12 */
  13
  14#include "qemu/osdep.h"
  15#include "hw/hw.h"
  16#include "hw/sysbus.h"
  17#include "hw/misc/unimp.h"
  18#include "qemu/log.h"
  19#include "qapi/error.h"
  20
  21static uint64_t unimp_read(void *opaque, hwaddr offset, unsigned size)
  22{
  23    UnimplementedDeviceState *s = UNIMPLEMENTED_DEVICE(opaque);
  24
  25    qemu_log_mask(LOG_UNIMP, "%s: unimplemented device read "
  26                  "(size %d, offset 0x%" HWADDR_PRIx ")\n",
  27                  s->name, size, offset);
  28    return 0;
  29}
  30
  31static void unimp_write(void *opaque, hwaddr offset,
  32                        uint64_t value, unsigned size)
  33{
  34    UnimplementedDeviceState *s = UNIMPLEMENTED_DEVICE(opaque);
  35
  36    qemu_log_mask(LOG_UNIMP, "%s: unimplemented device write "
  37                  "(size %d, value 0x%" PRIx64
  38                  ", offset 0x%" HWADDR_PRIx ")\n",
  39                  s->name, size, value, offset);
  40}
  41
  42static const MemoryRegionOps unimp_ops = {
  43    .read = unimp_read,
  44    .write = unimp_write,
  45    .impl.min_access_size = 1,
  46    .impl.max_access_size = 8,
  47    .valid.min_access_size = 1,
  48    .valid.max_access_size = 8,
  49    .endianness = DEVICE_NATIVE_ENDIAN,
  50};
  51
  52static void unimp_realize(DeviceState *dev, Error **errp)
  53{
  54    UnimplementedDeviceState *s = UNIMPLEMENTED_DEVICE(dev);
  55
  56    if (s->size == 0) {
  57        error_setg(errp, "property 'size' not specified or zero");
  58        return;
  59    }
  60
  61    if (s->name == NULL) {
  62        error_setg(errp, "property 'name' not specified");
  63        return;
  64    }
  65
  66    memory_region_init_io(&s->iomem, OBJECT(s), &unimp_ops, s,
  67                          s->name, s->size);
  68    sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem);
  69}
  70
  71static Property unimp_properties[] = {
  72    DEFINE_PROP_UINT64("size", UnimplementedDeviceState, size, 0),
  73    DEFINE_PROP_STRING("name", UnimplementedDeviceState, name),
  74    DEFINE_PROP_END_OF_LIST(),
  75};
  76
  77static void unimp_class_init(ObjectClass *klass, void *data)
  78{
  79    DeviceClass *dc = DEVICE_CLASS(klass);
  80
  81    dc->realize = unimp_realize;
  82    dc->props = unimp_properties;
  83}
  84
  85static const TypeInfo unimp_info = {
  86    .name = TYPE_UNIMPLEMENTED_DEVICE,
  87    .parent = TYPE_SYS_BUS_DEVICE,
  88    .instance_size = sizeof(UnimplementedDeviceState),
  89    .class_init = unimp_class_init,
  90};
  91
  92static void unimp_register_types(void)
  93{
  94    type_register_static(&unimp_info);
  95}
  96
  97type_init(unimp_register_types)
  98