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