qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

unimp.c (2881B)


      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/sysbus.h"
     16 #include "hw/misc/unimp.h"
     17 #include "qemu/log.h"
     18 #include "qemu/module.h"
     19 #include "qapi/error.h"
     20 
     21 static 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%0*" HWADDR_PRIx ")\n",
     27                   s->name, size, s->offset_fmt_width, offset);
     28     return 0;
     29 }
     30 
     31 static 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, offset 0x%0*" HWADDR_PRIx
     38                   ", value 0x%0*" PRIx64 ")\n",
     39                   s->name, size, s->offset_fmt_width, offset, size << 1, value);
     40 }
     41 
     42 static 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 
     52 static 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     s->offset_fmt_width = DIV_ROUND_UP(64 - clz64(s->size - 1), 4);
     67 
     68     memory_region_init_io(&s->iomem, OBJECT(s), &unimp_ops, s,
     69                           s->name, s->size);
     70     sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem);
     71 }
     72 
     73 static Property unimp_properties[] = {
     74     DEFINE_PROP_UINT64("size", UnimplementedDeviceState, size, 0),
     75     DEFINE_PROP_STRING("name", UnimplementedDeviceState, name),
     76     DEFINE_PROP_END_OF_LIST(),
     77 };
     78 
     79 static void unimp_class_init(ObjectClass *klass, void *data)
     80 {
     81     DeviceClass *dc = DEVICE_CLASS(klass);
     82 
     83     dc->realize = unimp_realize;
     84     device_class_set_props(dc, unimp_properties);
     85 }
     86 
     87 static const TypeInfo unimp_info = {
     88     .name = TYPE_UNIMPLEMENTED_DEVICE,
     89     .parent = TYPE_SYS_BUS_DEVICE,
     90     .instance_size = sizeof(UnimplementedDeviceState),
     91     .class_init = unimp_class_init,
     92 };
     93 
     94 static void unimp_register_types(void)
     95 {
     96     type_register_static(&unimp_info);
     97 }
     98 
     99 type_init(unimp_register_types)