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