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