1*75750e4dSPeter Maydell /* 2*75750e4dSPeter Maydell * ARM IoTKit system control element 3*75750e4dSPeter Maydell * 4*75750e4dSPeter Maydell * Copyright (c) 2018 Linaro Limited 5*75750e4dSPeter Maydell * Written by Peter Maydell 6*75750e4dSPeter Maydell * 7*75750e4dSPeter Maydell * This program is free software; you can redistribute it and/or modify 8*75750e4dSPeter Maydell * it under the terms of the GNU General Public License version 2 or 9*75750e4dSPeter Maydell * (at your option) any later version. 10*75750e4dSPeter Maydell */ 11*75750e4dSPeter Maydell 12*75750e4dSPeter Maydell /* 13*75750e4dSPeter Maydell * This is a model of the "system control element" which is part of the 14*75750e4dSPeter Maydell * Arm IoTKit and documented in 15*75750e4dSPeter Maydell * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html 16*75750e4dSPeter Maydell * Specifically, it implements the "system control register" blocks. 17*75750e4dSPeter Maydell */ 18*75750e4dSPeter Maydell 19*75750e4dSPeter Maydell #include "qemu/osdep.h" 20*75750e4dSPeter Maydell #include "qemu/log.h" 21*75750e4dSPeter Maydell #include "trace.h" 22*75750e4dSPeter Maydell #include "qapi/error.h" 23*75750e4dSPeter Maydell #include "sysemu/sysemu.h" 24*75750e4dSPeter Maydell #include "hw/sysbus.h" 25*75750e4dSPeter Maydell #include "hw/registerfields.h" 26*75750e4dSPeter Maydell #include "hw/misc/iotkit-sysctl.h" 27*75750e4dSPeter Maydell 28*75750e4dSPeter Maydell REG32(SECDBGSTAT, 0x0) 29*75750e4dSPeter Maydell REG32(SECDBGSET, 0x4) 30*75750e4dSPeter Maydell REG32(SECDBGCLR, 0x8) 31*75750e4dSPeter Maydell REG32(RESET_SYNDROME, 0x100) 32*75750e4dSPeter Maydell REG32(RESET_MASK, 0x104) 33*75750e4dSPeter Maydell REG32(SWRESET, 0x108) 34*75750e4dSPeter Maydell FIELD(SWRESET, SWRESETREQ, 9, 1) 35*75750e4dSPeter Maydell REG32(GRETREG, 0x10c) 36*75750e4dSPeter Maydell REG32(INITSVRTOR0, 0x110) 37*75750e4dSPeter Maydell REG32(CPUWAIT, 0x118) 38*75750e4dSPeter Maydell REG32(BUSWAIT, 0x11c) 39*75750e4dSPeter Maydell REG32(WICCTRL, 0x120) 40*75750e4dSPeter Maydell REG32(PID4, 0xfd0) 41*75750e4dSPeter Maydell REG32(PID5, 0xfd4) 42*75750e4dSPeter Maydell REG32(PID6, 0xfd8) 43*75750e4dSPeter Maydell REG32(PID7, 0xfdc) 44*75750e4dSPeter Maydell REG32(PID0, 0xfe0) 45*75750e4dSPeter Maydell REG32(PID1, 0xfe4) 46*75750e4dSPeter Maydell REG32(PID2, 0xfe8) 47*75750e4dSPeter Maydell REG32(PID3, 0xfec) 48*75750e4dSPeter Maydell REG32(CID0, 0xff0) 49*75750e4dSPeter Maydell REG32(CID1, 0xff4) 50*75750e4dSPeter Maydell REG32(CID2, 0xff8) 51*75750e4dSPeter Maydell REG32(CID3, 0xffc) 52*75750e4dSPeter Maydell 53*75750e4dSPeter Maydell /* PID/CID values */ 54*75750e4dSPeter Maydell static const int sysctl_id[] = { 55*75750e4dSPeter Maydell 0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */ 56*75750e4dSPeter Maydell 0x54, 0xb8, 0x0b, 0x00, /* PID0..PID3 */ 57*75750e4dSPeter Maydell 0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */ 58*75750e4dSPeter Maydell }; 59*75750e4dSPeter Maydell 60*75750e4dSPeter Maydell static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset, 61*75750e4dSPeter Maydell unsigned size) 62*75750e4dSPeter Maydell { 63*75750e4dSPeter Maydell IoTKitSysCtl *s = IOTKIT_SYSCTL(opaque); 64*75750e4dSPeter Maydell uint64_t r; 65*75750e4dSPeter Maydell 66*75750e4dSPeter Maydell switch (offset) { 67*75750e4dSPeter Maydell case A_SECDBGSTAT: 68*75750e4dSPeter Maydell r = s->secure_debug; 69*75750e4dSPeter Maydell break; 70*75750e4dSPeter Maydell case A_RESET_SYNDROME: 71*75750e4dSPeter Maydell r = s->reset_syndrome; 72*75750e4dSPeter Maydell break; 73*75750e4dSPeter Maydell case A_RESET_MASK: 74*75750e4dSPeter Maydell r = s->reset_mask; 75*75750e4dSPeter Maydell break; 76*75750e4dSPeter Maydell case A_GRETREG: 77*75750e4dSPeter Maydell r = s->gretreg; 78*75750e4dSPeter Maydell break; 79*75750e4dSPeter Maydell case A_INITSVRTOR0: 80*75750e4dSPeter Maydell r = s->initsvrtor0; 81*75750e4dSPeter Maydell break; 82*75750e4dSPeter Maydell case A_CPUWAIT: 83*75750e4dSPeter Maydell r = s->cpuwait; 84*75750e4dSPeter Maydell break; 85*75750e4dSPeter Maydell case A_BUSWAIT: 86*75750e4dSPeter Maydell /* In IoTKit BUSWAIT is reserved, R/O, zero */ 87*75750e4dSPeter Maydell r = 0; 88*75750e4dSPeter Maydell break; 89*75750e4dSPeter Maydell case A_WICCTRL: 90*75750e4dSPeter Maydell r = s->wicctrl; 91*75750e4dSPeter Maydell break; 92*75750e4dSPeter Maydell case A_PID4 ... A_CID3: 93*75750e4dSPeter Maydell r = sysctl_id[(offset - A_PID4) / 4]; 94*75750e4dSPeter Maydell break; 95*75750e4dSPeter Maydell case A_SECDBGSET: 96*75750e4dSPeter Maydell case A_SECDBGCLR: 97*75750e4dSPeter Maydell case A_SWRESET: 98*75750e4dSPeter Maydell qemu_log_mask(LOG_GUEST_ERROR, 99*75750e4dSPeter Maydell "IoTKit SysCtl read: read of WO offset %x\n", 100*75750e4dSPeter Maydell (int)offset); 101*75750e4dSPeter Maydell r = 0; 102*75750e4dSPeter Maydell break; 103*75750e4dSPeter Maydell default: 104*75750e4dSPeter Maydell qemu_log_mask(LOG_GUEST_ERROR, 105*75750e4dSPeter Maydell "IoTKit SysCtl read: bad offset %x\n", (int)offset); 106*75750e4dSPeter Maydell r = 0; 107*75750e4dSPeter Maydell break; 108*75750e4dSPeter Maydell } 109*75750e4dSPeter Maydell trace_iotkit_sysctl_read(offset, r, size); 110*75750e4dSPeter Maydell return r; 111*75750e4dSPeter Maydell } 112*75750e4dSPeter Maydell 113*75750e4dSPeter Maydell static void iotkit_sysctl_write(void *opaque, hwaddr offset, 114*75750e4dSPeter Maydell uint64_t value, unsigned size) 115*75750e4dSPeter Maydell { 116*75750e4dSPeter Maydell IoTKitSysCtl *s = IOTKIT_SYSCTL(opaque); 117*75750e4dSPeter Maydell 118*75750e4dSPeter Maydell trace_iotkit_sysctl_write(offset, value, size); 119*75750e4dSPeter Maydell 120*75750e4dSPeter Maydell /* 121*75750e4dSPeter Maydell * Most of the state here has to do with control of reset and 122*75750e4dSPeter Maydell * similar kinds of power up -- for instance the guest can ask 123*75750e4dSPeter Maydell * what the reason for the last reset was, or forbid reset for 124*75750e4dSPeter Maydell * some causes (like the non-secure watchdog). Most of this is 125*75750e4dSPeter Maydell * not relevant to QEMU, which doesn't really model anything other 126*75750e4dSPeter Maydell * than a full power-on reset. 127*75750e4dSPeter Maydell * We just model the registers as reads-as-written. 128*75750e4dSPeter Maydell */ 129*75750e4dSPeter Maydell 130*75750e4dSPeter Maydell switch (offset) { 131*75750e4dSPeter Maydell case A_RESET_SYNDROME: 132*75750e4dSPeter Maydell qemu_log_mask(LOG_UNIMP, 133*75750e4dSPeter Maydell "IoTKit SysCtl RESET_SYNDROME unimplemented\n"); 134*75750e4dSPeter Maydell s->reset_syndrome = value; 135*75750e4dSPeter Maydell break; 136*75750e4dSPeter Maydell case A_RESET_MASK: 137*75750e4dSPeter Maydell qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl RESET_MASK unimplemented\n"); 138*75750e4dSPeter Maydell s->reset_mask = value; 139*75750e4dSPeter Maydell break; 140*75750e4dSPeter Maydell case A_GRETREG: 141*75750e4dSPeter Maydell /* 142*75750e4dSPeter Maydell * General retention register, which is only reset by a power-on 143*75750e4dSPeter Maydell * reset. Technically this implementation is complete, since 144*75750e4dSPeter Maydell * QEMU only supports power-on resets... 145*75750e4dSPeter Maydell */ 146*75750e4dSPeter Maydell s->gretreg = value; 147*75750e4dSPeter Maydell break; 148*75750e4dSPeter Maydell case A_INITSVRTOR0: 149*75750e4dSPeter Maydell qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl INITSVRTOR0 unimplemented\n"); 150*75750e4dSPeter Maydell s->initsvrtor0 = value; 151*75750e4dSPeter Maydell break; 152*75750e4dSPeter Maydell case A_CPUWAIT: 153*75750e4dSPeter Maydell qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl CPUWAIT unimplemented\n"); 154*75750e4dSPeter Maydell s->cpuwait = value; 155*75750e4dSPeter Maydell break; 156*75750e4dSPeter Maydell case A_WICCTRL: 157*75750e4dSPeter Maydell qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl WICCTRL unimplemented\n"); 158*75750e4dSPeter Maydell s->wicctrl = value; 159*75750e4dSPeter Maydell break; 160*75750e4dSPeter Maydell case A_SECDBGSET: 161*75750e4dSPeter Maydell /* write-1-to-set */ 162*75750e4dSPeter Maydell qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SECDBGSET unimplemented\n"); 163*75750e4dSPeter Maydell s->secure_debug |= value; 164*75750e4dSPeter Maydell break; 165*75750e4dSPeter Maydell case A_SECDBGCLR: 166*75750e4dSPeter Maydell /* write-1-to-clear */ 167*75750e4dSPeter Maydell s->secure_debug &= ~value; 168*75750e4dSPeter Maydell break; 169*75750e4dSPeter Maydell case A_SWRESET: 170*75750e4dSPeter Maydell /* One w/o bit to request a reset; all other bits reserved */ 171*75750e4dSPeter Maydell if (value & R_SWRESET_SWRESETREQ_MASK) { 172*75750e4dSPeter Maydell qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); 173*75750e4dSPeter Maydell } 174*75750e4dSPeter Maydell break; 175*75750e4dSPeter Maydell case A_BUSWAIT: /* In IoTKit BUSWAIT is reserved, R/O, zero */ 176*75750e4dSPeter Maydell case A_SECDBGSTAT: 177*75750e4dSPeter Maydell case A_PID4 ... A_CID3: 178*75750e4dSPeter Maydell qemu_log_mask(LOG_GUEST_ERROR, 179*75750e4dSPeter Maydell "IoTKit SysCtl write: write of RO offset %x\n", 180*75750e4dSPeter Maydell (int)offset); 181*75750e4dSPeter Maydell break; 182*75750e4dSPeter Maydell default: 183*75750e4dSPeter Maydell qemu_log_mask(LOG_GUEST_ERROR, 184*75750e4dSPeter Maydell "IoTKit SysCtl write: bad offset %x\n", (int)offset); 185*75750e4dSPeter Maydell break; 186*75750e4dSPeter Maydell } 187*75750e4dSPeter Maydell } 188*75750e4dSPeter Maydell 189*75750e4dSPeter Maydell static const MemoryRegionOps iotkit_sysctl_ops = { 190*75750e4dSPeter Maydell .read = iotkit_sysctl_read, 191*75750e4dSPeter Maydell .write = iotkit_sysctl_write, 192*75750e4dSPeter Maydell .endianness = DEVICE_LITTLE_ENDIAN, 193*75750e4dSPeter Maydell /* byte/halfword accesses are just zero-padded on reads and writes */ 194*75750e4dSPeter Maydell .impl.min_access_size = 4, 195*75750e4dSPeter Maydell .impl.max_access_size = 4, 196*75750e4dSPeter Maydell .valid.min_access_size = 1, 197*75750e4dSPeter Maydell .valid.max_access_size = 4, 198*75750e4dSPeter Maydell }; 199*75750e4dSPeter Maydell 200*75750e4dSPeter Maydell static void iotkit_sysctl_reset(DeviceState *dev) 201*75750e4dSPeter Maydell { 202*75750e4dSPeter Maydell IoTKitSysCtl *s = IOTKIT_SYSCTL(dev); 203*75750e4dSPeter Maydell 204*75750e4dSPeter Maydell trace_iotkit_sysctl_reset(); 205*75750e4dSPeter Maydell s->secure_debug = 0; 206*75750e4dSPeter Maydell s->reset_syndrome = 1; 207*75750e4dSPeter Maydell s->reset_mask = 0; 208*75750e4dSPeter Maydell s->gretreg = 0; 209*75750e4dSPeter Maydell s->initsvrtor0 = 0x10000000; 210*75750e4dSPeter Maydell s->cpuwait = 0; 211*75750e4dSPeter Maydell s->wicctrl = 0; 212*75750e4dSPeter Maydell } 213*75750e4dSPeter Maydell 214*75750e4dSPeter Maydell static void iotkit_sysctl_init(Object *obj) 215*75750e4dSPeter Maydell { 216*75750e4dSPeter Maydell SysBusDevice *sbd = SYS_BUS_DEVICE(obj); 217*75750e4dSPeter Maydell IoTKitSysCtl *s = IOTKIT_SYSCTL(obj); 218*75750e4dSPeter Maydell 219*75750e4dSPeter Maydell memory_region_init_io(&s->iomem, obj, &iotkit_sysctl_ops, 220*75750e4dSPeter Maydell s, "iotkit-sysctl", 0x1000); 221*75750e4dSPeter Maydell sysbus_init_mmio(sbd, &s->iomem); 222*75750e4dSPeter Maydell } 223*75750e4dSPeter Maydell 224*75750e4dSPeter Maydell static const VMStateDescription iotkit_sysctl_vmstate = { 225*75750e4dSPeter Maydell .name = "iotkit-sysctl", 226*75750e4dSPeter Maydell .version_id = 1, 227*75750e4dSPeter Maydell .minimum_version_id = 1, 228*75750e4dSPeter Maydell .fields = (VMStateField[]) { 229*75750e4dSPeter Maydell VMSTATE_UINT32(secure_debug, IoTKitSysCtl), 230*75750e4dSPeter Maydell VMSTATE_UINT32(reset_syndrome, IoTKitSysCtl), 231*75750e4dSPeter Maydell VMSTATE_UINT32(reset_mask, IoTKitSysCtl), 232*75750e4dSPeter Maydell VMSTATE_UINT32(gretreg, IoTKitSysCtl), 233*75750e4dSPeter Maydell VMSTATE_UINT32(initsvrtor0, IoTKitSysCtl), 234*75750e4dSPeter Maydell VMSTATE_UINT32(cpuwait, IoTKitSysCtl), 235*75750e4dSPeter Maydell VMSTATE_UINT32(wicctrl, IoTKitSysCtl), 236*75750e4dSPeter Maydell VMSTATE_END_OF_LIST() 237*75750e4dSPeter Maydell } 238*75750e4dSPeter Maydell }; 239*75750e4dSPeter Maydell 240*75750e4dSPeter Maydell static void iotkit_sysctl_class_init(ObjectClass *klass, void *data) 241*75750e4dSPeter Maydell { 242*75750e4dSPeter Maydell DeviceClass *dc = DEVICE_CLASS(klass); 243*75750e4dSPeter Maydell 244*75750e4dSPeter Maydell dc->vmsd = &iotkit_sysctl_vmstate; 245*75750e4dSPeter Maydell dc->reset = iotkit_sysctl_reset; 246*75750e4dSPeter Maydell } 247*75750e4dSPeter Maydell 248*75750e4dSPeter Maydell static const TypeInfo iotkit_sysctl_info = { 249*75750e4dSPeter Maydell .name = TYPE_IOTKIT_SYSCTL, 250*75750e4dSPeter Maydell .parent = TYPE_SYS_BUS_DEVICE, 251*75750e4dSPeter Maydell .instance_size = sizeof(IoTKitSysCtl), 252*75750e4dSPeter Maydell .instance_init = iotkit_sysctl_init, 253*75750e4dSPeter Maydell .class_init = iotkit_sysctl_class_init, 254*75750e4dSPeter Maydell }; 255*75750e4dSPeter Maydell 256*75750e4dSPeter Maydell static void iotkit_sysctl_register_types(void) 257*75750e4dSPeter Maydell { 258*75750e4dSPeter Maydell type_register_static(&iotkit_sysctl_info); 259*75750e4dSPeter Maydell } 260*75750e4dSPeter Maydell 261*75750e4dSPeter Maydell type_init(iotkit_sysctl_register_types); 262