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 "qemu/module.h"
  20#include "qapi/error.h"
  21
  22static uint64_t unimp_read(void *opaque, hwaddr offset, unsigned size)
  23{
  24    UnimplementedDeviceState *s = UNIMPLEMENTED_DEVICE(opaque);
  25
  26    qemu_log_mask(LOG_UNIMP, "%s: unimplemented device read "
  27                  "(size %d, offset 0x%" HWADDR_PRIx ")\n",
  28                  s->name, size, offset);
  29    return 0;
  30}
  31
  32static void unimp_write(void *opaque, hwaddr offset,
  33                        uint64_t value, unsigned size)
  34{
  35    UnimplementedDeviceState *s = UNIMPLEMENTED_DEVICE(opaque);
  36
  37    qemu_log_mask(LOG_UNIMP, "%s: unimplemented device write "
  38                  "(size %d, value 0x%" PRIx64
  39                  ", offset 0x%" HWADDR_PRIx ")\n",
  40                  s->name, size, value, offset);
  41}
  42
  43static const MemoryRegionOps unimp_ops = {
  44    .read = unimp_read,
  45    .write = unimp_write,
  46    .impl.min_access_size = 1,
  47    .impl.max_access_size = 8,
  48    .valid.min_access_size = 1,
  49    .valid.max_access_size = 8,
  50    .endianness = DEVICE_NATIVE_ENDIAN,
  51};
  52
  53static void unimp_realize(DeviceState *dev, Error **errp)
  54{
  55    UnimplementedDeviceState *s = UNIMPLEMENTED_DEVICE(dev);
  56
  57    if (s->size == 0) {
  58        error_setg(errp, "property 'size' not specified or zero");
  59        return;
  60    }
  61
  62    if (s->name == NULL) {
  63        error_setg(errp, "property 'name' not specified");
  64        return;
  65    }
  66
  67    memory_region_init_io(&s->iomem, OBJECT(s), &unimp_ops, s,
  68                          s->name, s->size);
  69    sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem);
  70}
  71
  72static Property unimp_properties[] = {
  73    DEFINE_PROP_UINT64("size", UnimplementedDeviceState, size, 0),
  74    DEFINE_PROP_STRING("name", UnimplementedDeviceState, name),
  75    DEFINE_PROP_END_OF_LIST(),
  76};
  77
  78static void unimp_class_init(ObjectClass *klass, void *data)
  79{
  80    DeviceClass *dc = DEVICE_CLASS(klass);
  81
  82    dc->realize = unimp_realize;
  83    dc->props = unimp_properties;
  84}
  85
  86static const TypeInfo unimp_info = {
  87    .name = TYPE_UNIMPLEMENTED_DEVICE,
  88    .parent = TYPE_SYS_BUS_DEVICE,
  89    .instance_size = sizeof(UnimplementedDeviceState),
  90    .class_init = unimp_class_init,
  91};
  92
  93static void unimp_register_types(void)
  94{
  95    type_register_static(&unimp_info);
  96}
  97
  98type_init(unimp_register_types)
  99