175750e4dSPeter Maydell /* 275750e4dSPeter Maydell * ARM IoTKit system control element 375750e4dSPeter Maydell * 475750e4dSPeter Maydell * Copyright (c) 2018 Linaro Limited 575750e4dSPeter Maydell * Written by Peter Maydell 675750e4dSPeter Maydell * 775750e4dSPeter Maydell * This program is free software; you can redistribute it and/or modify 875750e4dSPeter Maydell * it under the terms of the GNU General Public License version 2 or 975750e4dSPeter Maydell * (at your option) any later version. 1075750e4dSPeter Maydell */ 1175750e4dSPeter Maydell 1275750e4dSPeter Maydell /* 1375750e4dSPeter Maydell * This is a model of the "system control element" which is part of the 1475750e4dSPeter Maydell * Arm IoTKit and documented in 1550b52b18SPeter Maydell * https://developer.arm.com/documentation/ecm0601256/latest 1675750e4dSPeter Maydell * Specifically, it implements the "system control register" blocks. 1775750e4dSPeter Maydell */ 1875750e4dSPeter Maydell 1975750e4dSPeter Maydell #include "qemu/osdep.h" 2004836414SPeter Maydell #include "qemu/bitops.h" 2175750e4dSPeter Maydell #include "qemu/log.h" 220b8fa32fSMarkus Armbruster #include "qemu/module.h" 2354d31236SMarkus Armbruster #include "sysemu/runstate.h" 2475750e4dSPeter Maydell #include "trace.h" 2575750e4dSPeter Maydell #include "qapi/error.h" 2675750e4dSPeter Maydell #include "hw/sysbus.h" 27d6454270SMarkus Armbruster #include "migration/vmstate.h" 2875750e4dSPeter Maydell #include "hw/registerfields.h" 2975750e4dSPeter Maydell #include "hw/misc/iotkit-sysctl.h" 30a27bd6c7SMarkus Armbruster #include "hw/qdev-properties.h" 31419a7f80SPeter Maydell #include "hw/arm/armsse-version.h" 320f862986SPeter Maydell #include "target/arm/arm-powerctl.h" 330f862986SPeter Maydell #include "target/arm/cpu.h" 3475750e4dSPeter Maydell 3575750e4dSPeter Maydell REG32(SECDBGSTAT, 0x0) 3675750e4dSPeter Maydell REG32(SECDBGSET, 0x4) 3775750e4dSPeter Maydell REG32(SECDBGCLR, 0x8) 3804836414SPeter Maydell REG32(SCSECCTRL, 0xc) 3904836414SPeter Maydell REG32(FCLK_DIV, 0x10) 4004836414SPeter Maydell REG32(SYSCLK_DIV, 0x14) 4104836414SPeter Maydell REG32(CLOCK_FORCE, 0x18) 4275750e4dSPeter Maydell REG32(RESET_SYNDROME, 0x100) 4375750e4dSPeter Maydell REG32(RESET_MASK, 0x104) 4475750e4dSPeter Maydell REG32(SWRESET, 0x108) 4575750e4dSPeter Maydell FIELD(SWRESET, SWRESETREQ, 9, 1) 4675750e4dSPeter Maydell REG32(GRETREG, 0x10c) 47394e10d2SPeter Maydell REG32(INITSVTOR0, 0x110) 4804836414SPeter Maydell REG32(INITSVTOR1, 0x114) 4975750e4dSPeter Maydell REG32(CPUWAIT, 0x118) 5004836414SPeter Maydell REG32(NMI_ENABLE, 0x11c) /* BUSWAIT in IoTKit */ 5175750e4dSPeter Maydell REG32(WICCTRL, 0x120) 5204836414SPeter Maydell REG32(EWCTRL, 0x124) 5304836414SPeter Maydell REG32(PDCM_PD_SYS_SENSE, 0x200) 5404836414SPeter Maydell REG32(PDCM_PD_SRAM0_SENSE, 0x20c) 5504836414SPeter Maydell REG32(PDCM_PD_SRAM1_SENSE, 0x210) 5604836414SPeter Maydell REG32(PDCM_PD_SRAM2_SENSE, 0x214) 5704836414SPeter Maydell REG32(PDCM_PD_SRAM3_SENSE, 0x218) 5875750e4dSPeter Maydell REG32(PID4, 0xfd0) 5975750e4dSPeter Maydell REG32(PID5, 0xfd4) 6075750e4dSPeter Maydell REG32(PID6, 0xfd8) 6175750e4dSPeter Maydell REG32(PID7, 0xfdc) 6275750e4dSPeter Maydell REG32(PID0, 0xfe0) 6375750e4dSPeter Maydell REG32(PID1, 0xfe4) 6475750e4dSPeter Maydell REG32(PID2, 0xfe8) 6575750e4dSPeter Maydell REG32(PID3, 0xfec) 6675750e4dSPeter Maydell REG32(CID0, 0xff0) 6775750e4dSPeter Maydell REG32(CID1, 0xff4) 6875750e4dSPeter Maydell REG32(CID2, 0xff8) 6975750e4dSPeter Maydell REG32(CID3, 0xffc) 7075750e4dSPeter Maydell 7175750e4dSPeter Maydell /* PID/CID values */ 7275750e4dSPeter Maydell static const int sysctl_id[] = { 7375750e4dSPeter Maydell 0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */ 7475750e4dSPeter Maydell 0x54, 0xb8, 0x0b, 0x00, /* PID0..PID3 */ 7575750e4dSPeter Maydell 0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */ 7675750e4dSPeter Maydell }; 7775750e4dSPeter Maydell 780f862986SPeter Maydell /* 790f862986SPeter Maydell * Set the initial secure vector table offset address for the core. 800f862986SPeter Maydell * This will take effect when the CPU next resets. 810f862986SPeter Maydell */ 820f862986SPeter Maydell static void set_init_vtor(uint64_t cpuid, uint32_t vtor) 830f862986SPeter Maydell { 840f862986SPeter Maydell Object *cpuobj = OBJECT(arm_get_cpu_by_id(cpuid)); 850f862986SPeter Maydell 860f862986SPeter Maydell if (cpuobj) { 87efba1595SDaniel P. Berrangé if (object_property_find(cpuobj, "init-svtor")) { 885325cc34SMarkus Armbruster object_property_set_uint(cpuobj, "init-svtor", vtor, &error_abort); 890f862986SPeter Maydell } 900f862986SPeter Maydell } 910f862986SPeter Maydell } 920f862986SPeter Maydell 9375750e4dSPeter Maydell static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset, 9475750e4dSPeter Maydell unsigned size) 9575750e4dSPeter Maydell { 9675750e4dSPeter Maydell IoTKitSysCtl *s = IOTKIT_SYSCTL(opaque); 9775750e4dSPeter Maydell uint64_t r; 9875750e4dSPeter Maydell 9975750e4dSPeter Maydell switch (offset) { 10075750e4dSPeter Maydell case A_SECDBGSTAT: 10175750e4dSPeter Maydell r = s->secure_debug; 10275750e4dSPeter Maydell break; 10304836414SPeter Maydell case A_SCSECCTRL: 1041cbd6fe4SPeter Maydell switch (s->sse_version) { 1051cbd6fe4SPeter Maydell case ARMSSE_IOTKIT: 10604836414SPeter Maydell goto bad_offset; 1071cbd6fe4SPeter Maydell case ARMSSE_SSE200: 10831b0c6b1SPeter Maydell case ARMSSE_SSE300: 10904836414SPeter Maydell r = s->scsecctrl; 11004836414SPeter Maydell break; 1111cbd6fe4SPeter Maydell default: 1121cbd6fe4SPeter Maydell g_assert_not_reached(); 11304836414SPeter Maydell } 1141cbd6fe4SPeter Maydell break; 1151cbd6fe4SPeter Maydell case A_FCLK_DIV: 1161cbd6fe4SPeter Maydell switch (s->sse_version) { 1171cbd6fe4SPeter Maydell case ARMSSE_IOTKIT: 1181cbd6fe4SPeter Maydell goto bad_offset; 1191cbd6fe4SPeter Maydell case ARMSSE_SSE200: 12031b0c6b1SPeter Maydell case ARMSSE_SSE300: 12104836414SPeter Maydell r = s->fclk_div; 12204836414SPeter Maydell break; 1231cbd6fe4SPeter Maydell default: 1241cbd6fe4SPeter Maydell g_assert_not_reached(); 12504836414SPeter Maydell } 1261cbd6fe4SPeter Maydell break; 1271cbd6fe4SPeter Maydell case A_SYSCLK_DIV: 1281cbd6fe4SPeter Maydell switch (s->sse_version) { 1291cbd6fe4SPeter Maydell case ARMSSE_IOTKIT: 1301cbd6fe4SPeter Maydell goto bad_offset; 1311cbd6fe4SPeter Maydell case ARMSSE_SSE200: 13231b0c6b1SPeter Maydell case ARMSSE_SSE300: 13304836414SPeter Maydell r = s->sysclk_div; 13404836414SPeter Maydell break; 1351cbd6fe4SPeter Maydell default: 1361cbd6fe4SPeter Maydell g_assert_not_reached(); 13704836414SPeter Maydell } 1381cbd6fe4SPeter Maydell break; 1391cbd6fe4SPeter Maydell case A_CLOCK_FORCE: 1401cbd6fe4SPeter Maydell switch (s->sse_version) { 1411cbd6fe4SPeter Maydell case ARMSSE_IOTKIT: 1421cbd6fe4SPeter Maydell goto bad_offset; 1431cbd6fe4SPeter Maydell case ARMSSE_SSE200: 14431b0c6b1SPeter Maydell case ARMSSE_SSE300: 14504836414SPeter Maydell r = s->clock_force; 14604836414SPeter Maydell break; 1471cbd6fe4SPeter Maydell default: 1481cbd6fe4SPeter Maydell g_assert_not_reached(); 1491cbd6fe4SPeter Maydell } 1501cbd6fe4SPeter Maydell break; 15175750e4dSPeter Maydell case A_RESET_SYNDROME: 15275750e4dSPeter Maydell r = s->reset_syndrome; 15375750e4dSPeter Maydell break; 15475750e4dSPeter Maydell case A_RESET_MASK: 15575750e4dSPeter Maydell r = s->reset_mask; 15675750e4dSPeter Maydell break; 15775750e4dSPeter Maydell case A_GRETREG: 15875750e4dSPeter Maydell r = s->gretreg; 15975750e4dSPeter Maydell break; 160394e10d2SPeter Maydell case A_INITSVTOR0: 161394e10d2SPeter Maydell r = s->initsvtor0; 16275750e4dSPeter Maydell break; 16304836414SPeter Maydell case A_INITSVTOR1: 1641cbd6fe4SPeter Maydell switch (s->sse_version) { 1651cbd6fe4SPeter Maydell case ARMSSE_IOTKIT: 16604836414SPeter Maydell goto bad_offset; 1671cbd6fe4SPeter Maydell case ARMSSE_SSE200: 16804836414SPeter Maydell r = s->initsvtor1; 16904836414SPeter Maydell break; 1701cbd6fe4SPeter Maydell default: 1711cbd6fe4SPeter Maydell g_assert_not_reached(); 1721cbd6fe4SPeter Maydell } 1731cbd6fe4SPeter Maydell break; 17475750e4dSPeter Maydell case A_CPUWAIT: 175*92ecf2d5SPeter Maydell switch (s->sse_version) { 176*92ecf2d5SPeter Maydell case ARMSSE_IOTKIT: 177*92ecf2d5SPeter Maydell case ARMSSE_SSE200: 17875750e4dSPeter Maydell r = s->cpuwait; 17975750e4dSPeter Maydell break; 180*92ecf2d5SPeter Maydell case ARMSSE_SSE300: 181*92ecf2d5SPeter Maydell /* In SSE300 this is reserved (for INITSVTOR2) */ 182*92ecf2d5SPeter Maydell goto bad_offset; 183*92ecf2d5SPeter Maydell default: 184*92ecf2d5SPeter Maydell g_assert_not_reached(); 185*92ecf2d5SPeter Maydell } 186*92ecf2d5SPeter Maydell break; 18704836414SPeter Maydell case A_NMI_ENABLE: 1881cbd6fe4SPeter Maydell switch (s->sse_version) { 1891cbd6fe4SPeter Maydell case ARMSSE_IOTKIT: 1901cbd6fe4SPeter Maydell /* In IoTKit this is named BUSWAIT but marked reserved, R/O, zero */ 19175750e4dSPeter Maydell r = 0; 19275750e4dSPeter Maydell break; 1931cbd6fe4SPeter Maydell case ARMSSE_SSE200: 19404836414SPeter Maydell r = s->nmi_enable; 19504836414SPeter Maydell break; 196*92ecf2d5SPeter Maydell case ARMSSE_SSE300: 197*92ecf2d5SPeter Maydell /* In SSE300 this is reserved (for INITSVTOR3) */ 198*92ecf2d5SPeter Maydell goto bad_offset; 1991cbd6fe4SPeter Maydell default: 2001cbd6fe4SPeter Maydell g_assert_not_reached(); 2011cbd6fe4SPeter Maydell } 2021cbd6fe4SPeter Maydell break; 20375750e4dSPeter Maydell case A_WICCTRL: 204*92ecf2d5SPeter Maydell switch (s->sse_version) { 205*92ecf2d5SPeter Maydell case ARMSSE_IOTKIT: 206*92ecf2d5SPeter Maydell case ARMSSE_SSE200: 20775750e4dSPeter Maydell r = s->wicctrl; 20875750e4dSPeter Maydell break; 209*92ecf2d5SPeter Maydell case ARMSSE_SSE300: 210*92ecf2d5SPeter Maydell /* In SSE300 this offset is CPUWAIT */ 211*92ecf2d5SPeter Maydell r = s->cpuwait; 212*92ecf2d5SPeter Maydell break; 213*92ecf2d5SPeter Maydell default: 214*92ecf2d5SPeter Maydell g_assert_not_reached(); 215*92ecf2d5SPeter Maydell } 216*92ecf2d5SPeter Maydell break; 21704836414SPeter Maydell case A_EWCTRL: 2181cbd6fe4SPeter Maydell switch (s->sse_version) { 2191cbd6fe4SPeter Maydell case ARMSSE_IOTKIT: 22004836414SPeter Maydell goto bad_offset; 2211cbd6fe4SPeter Maydell case ARMSSE_SSE200: 22204836414SPeter Maydell r = s->ewctrl; 22304836414SPeter Maydell break; 224*92ecf2d5SPeter Maydell case ARMSSE_SSE300: 225*92ecf2d5SPeter Maydell /* In SSE300 this offset is is NMI_ENABLE */ 226*92ecf2d5SPeter Maydell r = s->nmi_enable; 227*92ecf2d5SPeter Maydell break; 2281cbd6fe4SPeter Maydell default: 2291cbd6fe4SPeter Maydell g_assert_not_reached(); 23004836414SPeter Maydell } 2311cbd6fe4SPeter Maydell break; 2321cbd6fe4SPeter Maydell case A_PDCM_PD_SYS_SENSE: 2331cbd6fe4SPeter Maydell switch (s->sse_version) { 2341cbd6fe4SPeter Maydell case ARMSSE_IOTKIT: 2351cbd6fe4SPeter Maydell goto bad_offset; 2361cbd6fe4SPeter Maydell case ARMSSE_SSE200: 23731b0c6b1SPeter Maydell case ARMSSE_SSE300: 23804836414SPeter Maydell r = s->pdcm_pd_sys_sense; 23904836414SPeter Maydell break; 2401cbd6fe4SPeter Maydell default: 2411cbd6fe4SPeter Maydell g_assert_not_reached(); 24204836414SPeter Maydell } 2431cbd6fe4SPeter Maydell break; 2441cbd6fe4SPeter Maydell case A_PDCM_PD_SRAM0_SENSE: 2451cbd6fe4SPeter Maydell switch (s->sse_version) { 2461cbd6fe4SPeter Maydell case ARMSSE_IOTKIT: 2471cbd6fe4SPeter Maydell goto bad_offset; 2481cbd6fe4SPeter Maydell case ARMSSE_SSE200: 24904836414SPeter Maydell r = s->pdcm_pd_sram0_sense; 25004836414SPeter Maydell break; 2511cbd6fe4SPeter Maydell default: 2521cbd6fe4SPeter Maydell g_assert_not_reached(); 25304836414SPeter Maydell } 2541cbd6fe4SPeter Maydell break; 2551cbd6fe4SPeter Maydell case A_PDCM_PD_SRAM1_SENSE: 2561cbd6fe4SPeter Maydell switch (s->sse_version) { 2571cbd6fe4SPeter Maydell case ARMSSE_IOTKIT: 2581cbd6fe4SPeter Maydell goto bad_offset; 2591cbd6fe4SPeter Maydell case ARMSSE_SSE200: 26004836414SPeter Maydell r = s->pdcm_pd_sram1_sense; 26104836414SPeter Maydell break; 2621cbd6fe4SPeter Maydell default: 2631cbd6fe4SPeter Maydell g_assert_not_reached(); 26404836414SPeter Maydell } 2651cbd6fe4SPeter Maydell break; 2661cbd6fe4SPeter Maydell case A_PDCM_PD_SRAM2_SENSE: 2671cbd6fe4SPeter Maydell switch (s->sse_version) { 2681cbd6fe4SPeter Maydell case ARMSSE_IOTKIT: 2691cbd6fe4SPeter Maydell goto bad_offset; 2701cbd6fe4SPeter Maydell case ARMSSE_SSE200: 27104836414SPeter Maydell r = s->pdcm_pd_sram2_sense; 27204836414SPeter Maydell break; 2731cbd6fe4SPeter Maydell default: 2741cbd6fe4SPeter Maydell g_assert_not_reached(); 27504836414SPeter Maydell } 2761cbd6fe4SPeter Maydell break; 2771cbd6fe4SPeter Maydell case A_PDCM_PD_SRAM3_SENSE: 2781cbd6fe4SPeter Maydell switch (s->sse_version) { 2791cbd6fe4SPeter Maydell case ARMSSE_IOTKIT: 2801cbd6fe4SPeter Maydell goto bad_offset; 2811cbd6fe4SPeter Maydell case ARMSSE_SSE200: 28204836414SPeter Maydell r = s->pdcm_pd_sram3_sense; 28304836414SPeter Maydell break; 2841cbd6fe4SPeter Maydell default: 2851cbd6fe4SPeter Maydell g_assert_not_reached(); 2861cbd6fe4SPeter Maydell } 2871cbd6fe4SPeter Maydell break; 28875750e4dSPeter Maydell case A_PID4 ... A_CID3: 28975750e4dSPeter Maydell r = sysctl_id[(offset - A_PID4) / 4]; 29075750e4dSPeter Maydell break; 29175750e4dSPeter Maydell case A_SECDBGSET: 29275750e4dSPeter Maydell case A_SECDBGCLR: 29375750e4dSPeter Maydell case A_SWRESET: 29475750e4dSPeter Maydell qemu_log_mask(LOG_GUEST_ERROR, 29575750e4dSPeter Maydell "IoTKit SysCtl read: read of WO offset %x\n", 29675750e4dSPeter Maydell (int)offset); 29775750e4dSPeter Maydell r = 0; 29875750e4dSPeter Maydell break; 29975750e4dSPeter Maydell default: 30004836414SPeter Maydell bad_offset: 30175750e4dSPeter Maydell qemu_log_mask(LOG_GUEST_ERROR, 30275750e4dSPeter Maydell "IoTKit SysCtl read: bad offset %x\n", (int)offset); 30375750e4dSPeter Maydell r = 0; 30475750e4dSPeter Maydell break; 30575750e4dSPeter Maydell } 30675750e4dSPeter Maydell trace_iotkit_sysctl_read(offset, r, size); 30775750e4dSPeter Maydell return r; 30875750e4dSPeter Maydell } 30975750e4dSPeter Maydell 310*92ecf2d5SPeter Maydell static void cpuwait_write(IoTKitSysCtl *s, uint32_t value) 311*92ecf2d5SPeter Maydell { 312*92ecf2d5SPeter Maydell int num_cpus = (s->sse_version == ARMSSE_SSE300) ? 1 : 2; 313*92ecf2d5SPeter Maydell int i; 314*92ecf2d5SPeter Maydell 315*92ecf2d5SPeter Maydell for (i = 0; i < num_cpus; i++) { 316*92ecf2d5SPeter Maydell uint32_t mask = 1 << i; 317*92ecf2d5SPeter Maydell if ((s->cpuwait & mask) && !(value & mask)) { 318*92ecf2d5SPeter Maydell /* Powering up CPU 0 */ 319*92ecf2d5SPeter Maydell arm_set_cpu_on_and_reset(i); 320*92ecf2d5SPeter Maydell } 321*92ecf2d5SPeter Maydell } 322*92ecf2d5SPeter Maydell s->cpuwait = value; 323*92ecf2d5SPeter Maydell } 324*92ecf2d5SPeter Maydell 32575750e4dSPeter Maydell static void iotkit_sysctl_write(void *opaque, hwaddr offset, 32675750e4dSPeter Maydell uint64_t value, unsigned size) 32775750e4dSPeter Maydell { 32875750e4dSPeter Maydell IoTKitSysCtl *s = IOTKIT_SYSCTL(opaque); 32975750e4dSPeter Maydell 33075750e4dSPeter Maydell trace_iotkit_sysctl_write(offset, value, size); 33175750e4dSPeter Maydell 33275750e4dSPeter Maydell /* 33375750e4dSPeter Maydell * Most of the state here has to do with control of reset and 33475750e4dSPeter Maydell * similar kinds of power up -- for instance the guest can ask 33575750e4dSPeter Maydell * what the reason for the last reset was, or forbid reset for 33675750e4dSPeter Maydell * some causes (like the non-secure watchdog). Most of this is 33775750e4dSPeter Maydell * not relevant to QEMU, which doesn't really model anything other 33875750e4dSPeter Maydell * than a full power-on reset. 33975750e4dSPeter Maydell * We just model the registers as reads-as-written. 34075750e4dSPeter Maydell */ 34175750e4dSPeter Maydell 34275750e4dSPeter Maydell switch (offset) { 34375750e4dSPeter Maydell case A_RESET_SYNDROME: 34475750e4dSPeter Maydell qemu_log_mask(LOG_UNIMP, 34575750e4dSPeter Maydell "IoTKit SysCtl RESET_SYNDROME unimplemented\n"); 34675750e4dSPeter Maydell s->reset_syndrome = value; 34775750e4dSPeter Maydell break; 34875750e4dSPeter Maydell case A_RESET_MASK: 34975750e4dSPeter Maydell qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl RESET_MASK unimplemented\n"); 35075750e4dSPeter Maydell s->reset_mask = value; 35175750e4dSPeter Maydell break; 35275750e4dSPeter Maydell case A_GRETREG: 35375750e4dSPeter Maydell /* 35475750e4dSPeter Maydell * General retention register, which is only reset by a power-on 35575750e4dSPeter Maydell * reset. Technically this implementation is complete, since 35675750e4dSPeter Maydell * QEMU only supports power-on resets... 35775750e4dSPeter Maydell */ 35875750e4dSPeter Maydell s->gretreg = value; 35975750e4dSPeter Maydell break; 360394e10d2SPeter Maydell case A_INITSVTOR0: 361394e10d2SPeter Maydell s->initsvtor0 = value; 3620f862986SPeter Maydell set_init_vtor(0, s->initsvtor0); 36375750e4dSPeter Maydell break; 36475750e4dSPeter Maydell case A_CPUWAIT: 365*92ecf2d5SPeter Maydell switch (s->sse_version) { 366*92ecf2d5SPeter Maydell case ARMSSE_IOTKIT: 367*92ecf2d5SPeter Maydell case ARMSSE_SSE200: 368*92ecf2d5SPeter Maydell cpuwait_write(s, value); 369*92ecf2d5SPeter Maydell break; 370*92ecf2d5SPeter Maydell case ARMSSE_SSE300: 371*92ecf2d5SPeter Maydell /* In SSE300 this is reserved (for INITSVTOR2) */ 372*92ecf2d5SPeter Maydell goto bad_offset; 373*92ecf2d5SPeter Maydell default: 374*92ecf2d5SPeter Maydell g_assert_not_reached(); 3750f862986SPeter Maydell } 37675750e4dSPeter Maydell break; 37775750e4dSPeter Maydell case A_WICCTRL: 378*92ecf2d5SPeter Maydell switch (s->sse_version) { 379*92ecf2d5SPeter Maydell case ARMSSE_IOTKIT: 380*92ecf2d5SPeter Maydell case ARMSSE_SSE200: 38175750e4dSPeter Maydell qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl WICCTRL unimplemented\n"); 38275750e4dSPeter Maydell s->wicctrl = value; 38375750e4dSPeter Maydell break; 384*92ecf2d5SPeter Maydell case ARMSSE_SSE300: 385*92ecf2d5SPeter Maydell /* In SSE300 this offset is CPUWAIT */ 386*92ecf2d5SPeter Maydell cpuwait_write(s, value); 387*92ecf2d5SPeter Maydell break; 388*92ecf2d5SPeter Maydell default: 389*92ecf2d5SPeter Maydell g_assert_not_reached(); 390*92ecf2d5SPeter Maydell } 391*92ecf2d5SPeter Maydell break; 39275750e4dSPeter Maydell case A_SECDBGSET: 39375750e4dSPeter Maydell /* write-1-to-set */ 39475750e4dSPeter Maydell qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SECDBGSET unimplemented\n"); 39575750e4dSPeter Maydell s->secure_debug |= value; 39675750e4dSPeter Maydell break; 39775750e4dSPeter Maydell case A_SECDBGCLR: 39875750e4dSPeter Maydell /* write-1-to-clear */ 39975750e4dSPeter Maydell s->secure_debug &= ~value; 40075750e4dSPeter Maydell break; 40175750e4dSPeter Maydell case A_SWRESET: 40275750e4dSPeter Maydell /* One w/o bit to request a reset; all other bits reserved */ 40375750e4dSPeter Maydell if (value & R_SWRESET_SWRESETREQ_MASK) { 40475750e4dSPeter Maydell qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); 40575750e4dSPeter Maydell } 40675750e4dSPeter Maydell break; 40704836414SPeter Maydell case A_SCSECCTRL: 4081cbd6fe4SPeter Maydell switch (s->sse_version) { 4091cbd6fe4SPeter Maydell case ARMSSE_IOTKIT: 41004836414SPeter Maydell goto bad_offset; 4111cbd6fe4SPeter Maydell case ARMSSE_SSE200: 41231b0c6b1SPeter Maydell case ARMSSE_SSE300: 41304836414SPeter Maydell qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SCSECCTRL unimplemented\n"); 41404836414SPeter Maydell s->scsecctrl = value; 41504836414SPeter Maydell break; 4161cbd6fe4SPeter Maydell default: 4171cbd6fe4SPeter Maydell g_assert_not_reached(); 41804836414SPeter Maydell } 4191cbd6fe4SPeter Maydell break; 4201cbd6fe4SPeter Maydell case A_FCLK_DIV: 4211cbd6fe4SPeter Maydell switch (s->sse_version) { 4221cbd6fe4SPeter Maydell case ARMSSE_IOTKIT: 4231cbd6fe4SPeter Maydell goto bad_offset; 4241cbd6fe4SPeter Maydell case ARMSSE_SSE200: 42531b0c6b1SPeter Maydell case ARMSSE_SSE300: 42604836414SPeter Maydell qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl FCLK_DIV unimplemented\n"); 42704836414SPeter Maydell s->fclk_div = value; 42804836414SPeter Maydell break; 4291cbd6fe4SPeter Maydell default: 4301cbd6fe4SPeter Maydell g_assert_not_reached(); 43104836414SPeter Maydell } 4321cbd6fe4SPeter Maydell break; 4331cbd6fe4SPeter Maydell case A_SYSCLK_DIV: 4341cbd6fe4SPeter Maydell switch (s->sse_version) { 4351cbd6fe4SPeter Maydell case ARMSSE_IOTKIT: 4361cbd6fe4SPeter Maydell goto bad_offset; 4371cbd6fe4SPeter Maydell case ARMSSE_SSE200: 43831b0c6b1SPeter Maydell case ARMSSE_SSE300: 43904836414SPeter Maydell qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SYSCLK_DIV unimplemented\n"); 44004836414SPeter Maydell s->sysclk_div = value; 44104836414SPeter Maydell break; 4421cbd6fe4SPeter Maydell default: 4431cbd6fe4SPeter Maydell g_assert_not_reached(); 44404836414SPeter Maydell } 4451cbd6fe4SPeter Maydell break; 4461cbd6fe4SPeter Maydell case A_CLOCK_FORCE: 4471cbd6fe4SPeter Maydell switch (s->sse_version) { 4481cbd6fe4SPeter Maydell case ARMSSE_IOTKIT: 4491cbd6fe4SPeter Maydell goto bad_offset; 4501cbd6fe4SPeter Maydell case ARMSSE_SSE200: 45131b0c6b1SPeter Maydell case ARMSSE_SSE300: 45204836414SPeter Maydell qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl CLOCK_FORCE unimplemented\n"); 45304836414SPeter Maydell s->clock_force = value; 45404836414SPeter Maydell break; 4551cbd6fe4SPeter Maydell default: 4561cbd6fe4SPeter Maydell g_assert_not_reached(); 45704836414SPeter Maydell } 4581cbd6fe4SPeter Maydell break; 4591cbd6fe4SPeter Maydell case A_INITSVTOR1: 4601cbd6fe4SPeter Maydell switch (s->sse_version) { 4611cbd6fe4SPeter Maydell case ARMSSE_IOTKIT: 4621cbd6fe4SPeter Maydell goto bad_offset; 4631cbd6fe4SPeter Maydell case ARMSSE_SSE200: 46404836414SPeter Maydell s->initsvtor1 = value; 4650f862986SPeter Maydell set_init_vtor(1, s->initsvtor1); 46604836414SPeter Maydell break; 4671cbd6fe4SPeter Maydell default: 4681cbd6fe4SPeter Maydell g_assert_not_reached(); 46904836414SPeter Maydell } 4701cbd6fe4SPeter Maydell break; 4711cbd6fe4SPeter Maydell case A_EWCTRL: 4721cbd6fe4SPeter Maydell switch (s->sse_version) { 4731cbd6fe4SPeter Maydell case ARMSSE_IOTKIT: 4741cbd6fe4SPeter Maydell goto bad_offset; 4751cbd6fe4SPeter Maydell case ARMSSE_SSE200: 47604836414SPeter Maydell qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl EWCTRL unimplemented\n"); 47704836414SPeter Maydell s->ewctrl = value; 47804836414SPeter Maydell break; 479*92ecf2d5SPeter Maydell case ARMSSE_SSE300: 480*92ecf2d5SPeter Maydell /* In SSE300 this offset is is NMI_ENABLE */ 481*92ecf2d5SPeter Maydell qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl NMI_ENABLE unimplemented\n"); 482*92ecf2d5SPeter Maydell s->nmi_enable = value; 483*92ecf2d5SPeter Maydell break; 4841cbd6fe4SPeter Maydell default: 4851cbd6fe4SPeter Maydell g_assert_not_reached(); 48604836414SPeter Maydell } 4871cbd6fe4SPeter Maydell break; 4881cbd6fe4SPeter Maydell case A_PDCM_PD_SYS_SENSE: 4891cbd6fe4SPeter Maydell switch (s->sse_version) { 4901cbd6fe4SPeter Maydell case ARMSSE_IOTKIT: 4911cbd6fe4SPeter Maydell goto bad_offset; 4921cbd6fe4SPeter Maydell case ARMSSE_SSE200: 49331b0c6b1SPeter Maydell case ARMSSE_SSE300: 49404836414SPeter Maydell qemu_log_mask(LOG_UNIMP, 49504836414SPeter Maydell "IoTKit SysCtl PDCM_PD_SYS_SENSE unimplemented\n"); 49604836414SPeter Maydell s->pdcm_pd_sys_sense = value; 49704836414SPeter Maydell break; 4981cbd6fe4SPeter Maydell default: 4991cbd6fe4SPeter Maydell g_assert_not_reached(); 50004836414SPeter Maydell } 5011cbd6fe4SPeter Maydell break; 5021cbd6fe4SPeter Maydell case A_PDCM_PD_SRAM0_SENSE: 5031cbd6fe4SPeter Maydell switch (s->sse_version) { 5041cbd6fe4SPeter Maydell case ARMSSE_IOTKIT: 5051cbd6fe4SPeter Maydell goto bad_offset; 5061cbd6fe4SPeter Maydell case ARMSSE_SSE200: 50704836414SPeter Maydell qemu_log_mask(LOG_UNIMP, 50804836414SPeter Maydell "IoTKit SysCtl PDCM_PD_SRAM0_SENSE unimplemented\n"); 50904836414SPeter Maydell s->pdcm_pd_sram0_sense = value; 51004836414SPeter Maydell break; 5111cbd6fe4SPeter Maydell default: 5121cbd6fe4SPeter Maydell g_assert_not_reached(); 51304836414SPeter Maydell } 5141cbd6fe4SPeter Maydell break; 5151cbd6fe4SPeter Maydell case A_PDCM_PD_SRAM1_SENSE: 5161cbd6fe4SPeter Maydell switch (s->sse_version) { 5171cbd6fe4SPeter Maydell case ARMSSE_IOTKIT: 5181cbd6fe4SPeter Maydell goto bad_offset; 5191cbd6fe4SPeter Maydell case ARMSSE_SSE200: 52004836414SPeter Maydell qemu_log_mask(LOG_UNIMP, 52104836414SPeter Maydell "IoTKit SysCtl PDCM_PD_SRAM1_SENSE unimplemented\n"); 52204836414SPeter Maydell s->pdcm_pd_sram1_sense = value; 52304836414SPeter Maydell break; 5241cbd6fe4SPeter Maydell default: 5251cbd6fe4SPeter Maydell g_assert_not_reached(); 52604836414SPeter Maydell } 5271cbd6fe4SPeter Maydell break; 5281cbd6fe4SPeter Maydell case A_PDCM_PD_SRAM2_SENSE: 5291cbd6fe4SPeter Maydell switch (s->sse_version) { 5301cbd6fe4SPeter Maydell case ARMSSE_IOTKIT: 5311cbd6fe4SPeter Maydell goto bad_offset; 5321cbd6fe4SPeter Maydell case ARMSSE_SSE200: 53304836414SPeter Maydell qemu_log_mask(LOG_UNIMP, 53404836414SPeter Maydell "IoTKit SysCtl PDCM_PD_SRAM2_SENSE unimplemented\n"); 53504836414SPeter Maydell s->pdcm_pd_sram2_sense = value; 53604836414SPeter Maydell break; 5371cbd6fe4SPeter Maydell default: 5381cbd6fe4SPeter Maydell g_assert_not_reached(); 53904836414SPeter Maydell } 5401cbd6fe4SPeter Maydell break; 5411cbd6fe4SPeter Maydell case A_PDCM_PD_SRAM3_SENSE: 5421cbd6fe4SPeter Maydell switch (s->sse_version) { 5431cbd6fe4SPeter Maydell case ARMSSE_IOTKIT: 5441cbd6fe4SPeter Maydell goto bad_offset; 5451cbd6fe4SPeter Maydell case ARMSSE_SSE200: 54604836414SPeter Maydell qemu_log_mask(LOG_UNIMP, 54704836414SPeter Maydell "IoTKit SysCtl PDCM_PD_SRAM3_SENSE unimplemented\n"); 54804836414SPeter Maydell s->pdcm_pd_sram3_sense = value; 54904836414SPeter Maydell break; 5501cbd6fe4SPeter Maydell default: 5511cbd6fe4SPeter Maydell g_assert_not_reached(); 5521cbd6fe4SPeter Maydell } 5531cbd6fe4SPeter Maydell break; 55404836414SPeter Maydell case A_NMI_ENABLE: 55504836414SPeter Maydell /* In IoTKit this is BUSWAIT: reserved, R/O, zero */ 5561cbd6fe4SPeter Maydell switch (s->sse_version) { 5571cbd6fe4SPeter Maydell case ARMSSE_IOTKIT: 55804836414SPeter Maydell goto ro_offset; 5591cbd6fe4SPeter Maydell case ARMSSE_SSE200: 56004836414SPeter Maydell qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl NMI_ENABLE unimplemented\n"); 56104836414SPeter Maydell s->nmi_enable = value; 56204836414SPeter Maydell break; 563*92ecf2d5SPeter Maydell case ARMSSE_SSE300: 564*92ecf2d5SPeter Maydell /* In SSE300 this is reserved (for INITSVTOR3) */ 565*92ecf2d5SPeter Maydell goto bad_offset; 5661cbd6fe4SPeter Maydell default: 5671cbd6fe4SPeter Maydell g_assert_not_reached(); 5681cbd6fe4SPeter Maydell } 5691cbd6fe4SPeter Maydell break; 57075750e4dSPeter Maydell case A_SECDBGSTAT: 57175750e4dSPeter Maydell case A_PID4 ... A_CID3: 57204836414SPeter Maydell ro_offset: 57375750e4dSPeter Maydell qemu_log_mask(LOG_GUEST_ERROR, 57475750e4dSPeter Maydell "IoTKit SysCtl write: write of RO offset %x\n", 57575750e4dSPeter Maydell (int)offset); 57675750e4dSPeter Maydell break; 57775750e4dSPeter Maydell default: 57804836414SPeter Maydell bad_offset: 57975750e4dSPeter Maydell qemu_log_mask(LOG_GUEST_ERROR, 58075750e4dSPeter Maydell "IoTKit SysCtl write: bad offset %x\n", (int)offset); 58175750e4dSPeter Maydell break; 58275750e4dSPeter Maydell } 58375750e4dSPeter Maydell } 58475750e4dSPeter Maydell 58575750e4dSPeter Maydell static const MemoryRegionOps iotkit_sysctl_ops = { 58675750e4dSPeter Maydell .read = iotkit_sysctl_read, 58775750e4dSPeter Maydell .write = iotkit_sysctl_write, 58875750e4dSPeter Maydell .endianness = DEVICE_LITTLE_ENDIAN, 58975750e4dSPeter Maydell /* byte/halfword accesses are just zero-padded on reads and writes */ 59075750e4dSPeter Maydell .impl.min_access_size = 4, 59175750e4dSPeter Maydell .impl.max_access_size = 4, 59275750e4dSPeter Maydell .valid.min_access_size = 1, 59375750e4dSPeter Maydell .valid.max_access_size = 4, 59475750e4dSPeter Maydell }; 59575750e4dSPeter Maydell 59675750e4dSPeter Maydell static void iotkit_sysctl_reset(DeviceState *dev) 59775750e4dSPeter Maydell { 59875750e4dSPeter Maydell IoTKitSysCtl *s = IOTKIT_SYSCTL(dev); 59975750e4dSPeter Maydell 60075750e4dSPeter Maydell trace_iotkit_sysctl_reset(); 60175750e4dSPeter Maydell s->secure_debug = 0; 60275750e4dSPeter Maydell s->reset_syndrome = 1; 60375750e4dSPeter Maydell s->reset_mask = 0; 60475750e4dSPeter Maydell s->gretreg = 0; 605aab7a378SPeter Maydell s->initsvtor0 = s->initsvtor0_rst; 606aab7a378SPeter Maydell s->initsvtor1 = s->initsvtor1_rst; 607aab7a378SPeter Maydell s->cpuwait = s->cpuwait_rst; 60875750e4dSPeter Maydell s->wicctrl = 0; 60904836414SPeter Maydell s->scsecctrl = 0; 61004836414SPeter Maydell s->fclk_div = 0; 61104836414SPeter Maydell s->sysclk_div = 0; 61204836414SPeter Maydell s->clock_force = 0; 61304836414SPeter Maydell s->nmi_enable = 0; 61404836414SPeter Maydell s->ewctrl = 0; 61504836414SPeter Maydell s->pdcm_pd_sys_sense = 0x7f; 61604836414SPeter Maydell s->pdcm_pd_sram0_sense = 0; 61704836414SPeter Maydell s->pdcm_pd_sram1_sense = 0; 61804836414SPeter Maydell s->pdcm_pd_sram2_sense = 0; 61904836414SPeter Maydell s->pdcm_pd_sram3_sense = 0; 62075750e4dSPeter Maydell } 62175750e4dSPeter Maydell 62275750e4dSPeter Maydell static void iotkit_sysctl_init(Object *obj) 62375750e4dSPeter Maydell { 62475750e4dSPeter Maydell SysBusDevice *sbd = SYS_BUS_DEVICE(obj); 62575750e4dSPeter Maydell IoTKitSysCtl *s = IOTKIT_SYSCTL(obj); 62675750e4dSPeter Maydell 62775750e4dSPeter Maydell memory_region_init_io(&s->iomem, obj, &iotkit_sysctl_ops, 62875750e4dSPeter Maydell s, "iotkit-sysctl", 0x1000); 62975750e4dSPeter Maydell sysbus_init_mmio(sbd, &s->iomem); 63075750e4dSPeter Maydell } 63175750e4dSPeter Maydell 63204836414SPeter Maydell static void iotkit_sysctl_realize(DeviceState *dev, Error **errp) 63304836414SPeter Maydell { 63404836414SPeter Maydell IoTKitSysCtl *s = IOTKIT_SYSCTL(dev); 63504836414SPeter Maydell 636419a7f80SPeter Maydell if (!armsse_version_valid(s->sse_version)) { 637419a7f80SPeter Maydell error_setg(errp, "invalid sse-version value %d", s->sse_version); 638419a7f80SPeter Maydell return; 63904836414SPeter Maydell } 64004836414SPeter Maydell } 64104836414SPeter Maydell 64204836414SPeter Maydell static bool sse200_needed(void *opaque) 64304836414SPeter Maydell { 64404836414SPeter Maydell IoTKitSysCtl *s = IOTKIT_SYSCTL(opaque); 64504836414SPeter Maydell 64631b0c6b1SPeter Maydell return s->sse_version != ARMSSE_IOTKIT; 64704836414SPeter Maydell } 64804836414SPeter Maydell 64904836414SPeter Maydell static const VMStateDescription iotkit_sysctl_sse200_vmstate = { 65004836414SPeter Maydell .name = "iotkit-sysctl/sse-200", 65104836414SPeter Maydell .version_id = 1, 65204836414SPeter Maydell .minimum_version_id = 1, 65304836414SPeter Maydell .needed = sse200_needed, 65404836414SPeter Maydell .fields = (VMStateField[]) { 65504836414SPeter Maydell VMSTATE_UINT32(scsecctrl, IoTKitSysCtl), 65604836414SPeter Maydell VMSTATE_UINT32(fclk_div, IoTKitSysCtl), 65704836414SPeter Maydell VMSTATE_UINT32(sysclk_div, IoTKitSysCtl), 65804836414SPeter Maydell VMSTATE_UINT32(clock_force, IoTKitSysCtl), 65904836414SPeter Maydell VMSTATE_UINT32(initsvtor1, IoTKitSysCtl), 66004836414SPeter Maydell VMSTATE_UINT32(nmi_enable, IoTKitSysCtl), 66104836414SPeter Maydell VMSTATE_UINT32(pdcm_pd_sys_sense, IoTKitSysCtl), 66204836414SPeter Maydell VMSTATE_UINT32(pdcm_pd_sram0_sense, IoTKitSysCtl), 66304836414SPeter Maydell VMSTATE_UINT32(pdcm_pd_sram1_sense, IoTKitSysCtl), 66404836414SPeter Maydell VMSTATE_UINT32(pdcm_pd_sram2_sense, IoTKitSysCtl), 66504836414SPeter Maydell VMSTATE_UINT32(pdcm_pd_sram3_sense, IoTKitSysCtl), 66604836414SPeter Maydell VMSTATE_END_OF_LIST() 66704836414SPeter Maydell } 66804836414SPeter Maydell }; 66904836414SPeter Maydell 67075750e4dSPeter Maydell static const VMStateDescription iotkit_sysctl_vmstate = { 67175750e4dSPeter Maydell .name = "iotkit-sysctl", 67275750e4dSPeter Maydell .version_id = 1, 67375750e4dSPeter Maydell .minimum_version_id = 1, 67475750e4dSPeter Maydell .fields = (VMStateField[]) { 67575750e4dSPeter Maydell VMSTATE_UINT32(secure_debug, IoTKitSysCtl), 67675750e4dSPeter Maydell VMSTATE_UINT32(reset_syndrome, IoTKitSysCtl), 67775750e4dSPeter Maydell VMSTATE_UINT32(reset_mask, IoTKitSysCtl), 67875750e4dSPeter Maydell VMSTATE_UINT32(gretreg, IoTKitSysCtl), 679394e10d2SPeter Maydell VMSTATE_UINT32(initsvtor0, IoTKitSysCtl), 68075750e4dSPeter Maydell VMSTATE_UINT32(cpuwait, IoTKitSysCtl), 68175750e4dSPeter Maydell VMSTATE_UINT32(wicctrl, IoTKitSysCtl), 68275750e4dSPeter Maydell VMSTATE_END_OF_LIST() 68304836414SPeter Maydell }, 68404836414SPeter Maydell .subsections = (const VMStateDescription*[]) { 68504836414SPeter Maydell &iotkit_sysctl_sse200_vmstate, 68604836414SPeter Maydell NULL 68775750e4dSPeter Maydell } 68875750e4dSPeter Maydell }; 68975750e4dSPeter Maydell 69004836414SPeter Maydell static Property iotkit_sysctl_props[] = { 691419a7f80SPeter Maydell DEFINE_PROP_UINT32("sse-version", IoTKitSysCtl, sse_version, 0), 692aab7a378SPeter Maydell DEFINE_PROP_UINT32("CPUWAIT_RST", IoTKitSysCtl, cpuwait_rst, 0), 693aab7a378SPeter Maydell DEFINE_PROP_UINT32("INITSVTOR0_RST", IoTKitSysCtl, initsvtor0_rst, 694aab7a378SPeter Maydell 0x10000000), 695aab7a378SPeter Maydell DEFINE_PROP_UINT32("INITSVTOR1_RST", IoTKitSysCtl, initsvtor1_rst, 696aab7a378SPeter Maydell 0x10000000), 69704836414SPeter Maydell DEFINE_PROP_END_OF_LIST() 69804836414SPeter Maydell }; 69904836414SPeter Maydell 70075750e4dSPeter Maydell static void iotkit_sysctl_class_init(ObjectClass *klass, void *data) 70175750e4dSPeter Maydell { 70275750e4dSPeter Maydell DeviceClass *dc = DEVICE_CLASS(klass); 70375750e4dSPeter Maydell 70475750e4dSPeter Maydell dc->vmsd = &iotkit_sysctl_vmstate; 70575750e4dSPeter Maydell dc->reset = iotkit_sysctl_reset; 7064f67d30bSMarc-André Lureau device_class_set_props(dc, iotkit_sysctl_props); 70704836414SPeter Maydell dc->realize = iotkit_sysctl_realize; 70875750e4dSPeter Maydell } 70975750e4dSPeter Maydell 71075750e4dSPeter Maydell static const TypeInfo iotkit_sysctl_info = { 71175750e4dSPeter Maydell .name = TYPE_IOTKIT_SYSCTL, 71275750e4dSPeter Maydell .parent = TYPE_SYS_BUS_DEVICE, 71375750e4dSPeter Maydell .instance_size = sizeof(IoTKitSysCtl), 71475750e4dSPeter Maydell .instance_init = iotkit_sysctl_init, 71575750e4dSPeter Maydell .class_init = iotkit_sysctl_class_init, 71675750e4dSPeter Maydell }; 71775750e4dSPeter Maydell 71875750e4dSPeter Maydell static void iotkit_sysctl_register_types(void) 71975750e4dSPeter Maydell { 72075750e4dSPeter Maydell type_register_static(&iotkit_sysctl_info); 72175750e4dSPeter Maydell } 72275750e4dSPeter Maydell 72375750e4dSPeter Maydell type_init(iotkit_sysctl_register_types); 724