1c667a25bSPeter Maydell /* 2c667a25bSPeter Maydell * ARM IoTKit system information block 3c667a25bSPeter Maydell * 4c667a25bSPeter Maydell * Copyright (c) 2018 Linaro Limited 5c667a25bSPeter Maydell * Written by Peter Maydell 6c667a25bSPeter Maydell * 7c667a25bSPeter Maydell * This program is free software; you can redistribute it and/or modify 8c667a25bSPeter Maydell * it under the terms of the GNU General Public License version 2 or 9c667a25bSPeter Maydell * (at your option) any later version. 10c667a25bSPeter Maydell */ 11c667a25bSPeter Maydell 12c667a25bSPeter Maydell /* 13c667a25bSPeter Maydell * This is a model of the "system information block" which is part of the 14c667a25bSPeter Maydell * Arm IoTKit and documented in 1550b52b18SPeter Maydell * https://developer.arm.com/documentation/ecm0601256/latest 16c667a25bSPeter Maydell * It consists of 2 read-only version/config registers, plus the 17c667a25bSPeter Maydell * usual ID registers. 18c667a25bSPeter Maydell */ 19c667a25bSPeter Maydell 20c667a25bSPeter Maydell #include "qemu/osdep.h" 21c667a25bSPeter Maydell #include "qemu/log.h" 220b8fa32fSMarkus Armbruster #include "qemu/module.h" 23c667a25bSPeter Maydell #include "trace.h" 24c667a25bSPeter Maydell #include "qapi/error.h" 25c667a25bSPeter Maydell #include "hw/sysbus.h" 26c667a25bSPeter Maydell #include "hw/registerfields.h" 27c667a25bSPeter Maydell #include "hw/misc/iotkit-sysinfo.h" 28a27bd6c7SMarkus Armbruster #include "hw/qdev-properties.h" 29*40766453SPeter Maydell #include "hw/arm/armsse-version.h" 30c667a25bSPeter Maydell 31c667a25bSPeter Maydell REG32(SYS_VERSION, 0x0) 32c667a25bSPeter Maydell REG32(SYS_CONFIG, 0x4) 33c667a25bSPeter Maydell REG32(PID4, 0xfd0) 34c667a25bSPeter Maydell REG32(PID5, 0xfd4) 35c667a25bSPeter Maydell REG32(PID6, 0xfd8) 36c667a25bSPeter Maydell REG32(PID7, 0xfdc) 37c667a25bSPeter Maydell REG32(PID0, 0xfe0) 38c667a25bSPeter Maydell REG32(PID1, 0xfe4) 39c667a25bSPeter Maydell REG32(PID2, 0xfe8) 40c667a25bSPeter Maydell REG32(PID3, 0xfec) 41c667a25bSPeter Maydell REG32(CID0, 0xff0) 42c667a25bSPeter Maydell REG32(CID1, 0xff4) 43c667a25bSPeter Maydell REG32(CID2, 0xff8) 44c667a25bSPeter Maydell REG32(CID3, 0xffc) 45c667a25bSPeter Maydell 46c667a25bSPeter Maydell /* PID/CID values */ 47c667a25bSPeter Maydell static const int sysinfo_id[] = { 48c667a25bSPeter Maydell 0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */ 49c667a25bSPeter Maydell 0x58, 0xb8, 0x0b, 0x00, /* PID0..PID3 */ 50c667a25bSPeter Maydell 0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */ 51c667a25bSPeter Maydell }; 52c667a25bSPeter Maydell 53*40766453SPeter Maydell static const int sysinfo_sse300_id[] = { 54*40766453SPeter Maydell 0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */ 55*40766453SPeter Maydell 0x58, 0xb8, 0x1b, 0x00, /* PID0..PID3 */ 56*40766453SPeter Maydell 0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */ 57*40766453SPeter Maydell }; 58*40766453SPeter Maydell 59c667a25bSPeter Maydell static uint64_t iotkit_sysinfo_read(void *opaque, hwaddr offset, 60c667a25bSPeter Maydell unsigned size) 61c667a25bSPeter Maydell { 62dde0c491SPeter Maydell IoTKitSysInfo *s = IOTKIT_SYSINFO(opaque); 63c667a25bSPeter Maydell uint64_t r; 64c667a25bSPeter Maydell 65c667a25bSPeter Maydell switch (offset) { 66c667a25bSPeter Maydell case A_SYS_VERSION: 67dde0c491SPeter Maydell r = s->sys_version; 68c667a25bSPeter Maydell break; 69c667a25bSPeter Maydell 70c667a25bSPeter Maydell case A_SYS_CONFIG: 71dde0c491SPeter Maydell r = s->sys_config; 72c667a25bSPeter Maydell break; 73c667a25bSPeter Maydell case A_PID4 ... A_CID3: 74*40766453SPeter Maydell switch (s->sse_version) { 75*40766453SPeter Maydell case ARMSSE_SSE300: 76*40766453SPeter Maydell r = sysinfo_sse300_id[(offset - A_PID4) / 4]; 77*40766453SPeter Maydell break; 78*40766453SPeter Maydell default: 79c667a25bSPeter Maydell r = sysinfo_id[(offset - A_PID4) / 4]; 80c667a25bSPeter Maydell break; 81*40766453SPeter Maydell } 82*40766453SPeter Maydell break; 83c667a25bSPeter Maydell default: 84c667a25bSPeter Maydell qemu_log_mask(LOG_GUEST_ERROR, 85c667a25bSPeter Maydell "IoTKit SysInfo read: bad offset %x\n", (int)offset); 86c667a25bSPeter Maydell r = 0; 87c667a25bSPeter Maydell break; 88c667a25bSPeter Maydell } 89c667a25bSPeter Maydell trace_iotkit_sysinfo_read(offset, r, size); 90c667a25bSPeter Maydell return r; 91c667a25bSPeter Maydell } 92c667a25bSPeter Maydell 93c667a25bSPeter Maydell static void iotkit_sysinfo_write(void *opaque, hwaddr offset, 94c667a25bSPeter Maydell uint64_t value, unsigned size) 95c667a25bSPeter Maydell { 96c667a25bSPeter Maydell trace_iotkit_sysinfo_write(offset, value, size); 97c667a25bSPeter Maydell 98c667a25bSPeter Maydell qemu_log_mask(LOG_GUEST_ERROR, 99c667a25bSPeter Maydell "IoTKit SysInfo: write to RO offset 0x%x\n", (int)offset); 100c667a25bSPeter Maydell } 101c667a25bSPeter Maydell 102c667a25bSPeter Maydell static const MemoryRegionOps iotkit_sysinfo_ops = { 103c667a25bSPeter Maydell .read = iotkit_sysinfo_read, 104c667a25bSPeter Maydell .write = iotkit_sysinfo_write, 105c667a25bSPeter Maydell .endianness = DEVICE_LITTLE_ENDIAN, 106c667a25bSPeter Maydell /* byte/halfword accesses are just zero-padded on reads and writes */ 107c667a25bSPeter Maydell .impl.min_access_size = 4, 108c667a25bSPeter Maydell .impl.max_access_size = 4, 109c667a25bSPeter Maydell .valid.min_access_size = 1, 110c667a25bSPeter Maydell .valid.max_access_size = 4, 111c667a25bSPeter Maydell }; 112c667a25bSPeter Maydell 113dde0c491SPeter Maydell static Property iotkit_sysinfo_props[] = { 114dde0c491SPeter Maydell DEFINE_PROP_UINT32("SYS_VERSION", IoTKitSysInfo, sys_version, 0), 115dde0c491SPeter Maydell DEFINE_PROP_UINT32("SYS_CONFIG", IoTKitSysInfo, sys_config, 0), 116*40766453SPeter Maydell DEFINE_PROP_UINT32("sse-version", IoTKitSysInfo, sse_version, 0), 117dde0c491SPeter Maydell DEFINE_PROP_END_OF_LIST() 118dde0c491SPeter Maydell }; 119dde0c491SPeter Maydell 120c667a25bSPeter Maydell static void iotkit_sysinfo_init(Object *obj) 121c667a25bSPeter Maydell { 122c667a25bSPeter Maydell SysBusDevice *sbd = SYS_BUS_DEVICE(obj); 123c667a25bSPeter Maydell IoTKitSysInfo *s = IOTKIT_SYSINFO(obj); 124c667a25bSPeter Maydell 125c667a25bSPeter Maydell memory_region_init_io(&s->iomem, obj, &iotkit_sysinfo_ops, 126c667a25bSPeter Maydell s, "iotkit-sysinfo", 0x1000); 127c667a25bSPeter Maydell sysbus_init_mmio(sbd, &s->iomem); 128c667a25bSPeter Maydell } 129c667a25bSPeter Maydell 130*40766453SPeter Maydell static void iotkit_sysinfo_realize(DeviceState *dev, Error **errp) 131*40766453SPeter Maydell { 132*40766453SPeter Maydell IoTKitSysInfo *s = IOTKIT_SYSINFO(dev); 133*40766453SPeter Maydell 134*40766453SPeter Maydell if (!armsse_version_valid(s->sse_version)) { 135*40766453SPeter Maydell error_setg(errp, "invalid sse-version value %d", s->sse_version); 136*40766453SPeter Maydell return; 137*40766453SPeter Maydell } 138*40766453SPeter Maydell } 139*40766453SPeter Maydell 140c667a25bSPeter Maydell static void iotkit_sysinfo_class_init(ObjectClass *klass, void *data) 141c667a25bSPeter Maydell { 142dde0c491SPeter Maydell DeviceClass *dc = DEVICE_CLASS(klass); 143dde0c491SPeter Maydell 144c667a25bSPeter Maydell /* 145c667a25bSPeter Maydell * This device has no guest-modifiable state and so it 146c667a25bSPeter Maydell * does not need a reset function or VMState. 147c667a25bSPeter Maydell */ 148*40766453SPeter Maydell dc->realize = iotkit_sysinfo_realize; 1494f67d30bSMarc-André Lureau device_class_set_props(dc, iotkit_sysinfo_props); 150c667a25bSPeter Maydell } 151c667a25bSPeter Maydell 152c667a25bSPeter Maydell static const TypeInfo iotkit_sysinfo_info = { 153c667a25bSPeter Maydell .name = TYPE_IOTKIT_SYSINFO, 154c667a25bSPeter Maydell .parent = TYPE_SYS_BUS_DEVICE, 155c667a25bSPeter Maydell .instance_size = sizeof(IoTKitSysInfo), 156c667a25bSPeter Maydell .instance_init = iotkit_sysinfo_init, 157c667a25bSPeter Maydell .class_init = iotkit_sysinfo_class_init, 158c667a25bSPeter Maydell }; 159c667a25bSPeter Maydell 160c667a25bSPeter Maydell static void iotkit_sysinfo_register_types(void) 161c667a25bSPeter Maydell { 162c667a25bSPeter Maydell type_register_static(&iotkit_sysinfo_info); 163c667a25bSPeter Maydell } 164c667a25bSPeter Maydell 165c667a25bSPeter Maydell type_init(iotkit_sysinfo_register_types); 166