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 24 typedef struct { 25 SysBusDevice parent_obj; 26 MemoryRegion iomem; 27 char *name; 28 uint64_t size; 29 } UnimplementedDeviceState; 30 31 static 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 41 static 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 52 static 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 62 static 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 81 static 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 87 static 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 95 static 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 102 static void unimp_register_types(void) 103 { 104 type_register_static(&unimp_info); 105 } 106 107 type_init(unimp_register_types) 108