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) 48246dbeb7SPeter Maydell FIELD(INITSVTOR0, LOCK, 0, 1) 49246dbeb7SPeter Maydell FIELD(INITSVTOR0, VTOR, 7, 25) 5004836414SPeter Maydell REG32(INITSVTOR1, 0x114) 5175750e4dSPeter Maydell REG32(CPUWAIT, 0x118) 5204836414SPeter Maydell REG32(NMI_ENABLE, 0x11c) /* BUSWAIT in IoTKit */ 5375750e4dSPeter Maydell REG32(WICCTRL, 0x120) 5404836414SPeter Maydell REG32(EWCTRL, 0x124) 552672a6caSPeter Maydell REG32(PWRCTRL, 0x1fc) 562672a6caSPeter Maydell FIELD(PWRCTRL, PPU_ACCESS_UNLOCK, 0, 1) 572672a6caSPeter Maydell FIELD(PWRCTRL, PPU_ACCESS_FILTER, 1, 1) 5804836414SPeter Maydell REG32(PDCM_PD_SYS_SENSE, 0x200) 59c5ffe6c8SPeter Maydell REG32(PDCM_PD_CPU0_SENSE, 0x204) 6004836414SPeter Maydell REG32(PDCM_PD_SRAM0_SENSE, 0x20c) 6104836414SPeter Maydell REG32(PDCM_PD_SRAM1_SENSE, 0x210) 62c5ffe6c8SPeter Maydell REG32(PDCM_PD_SRAM2_SENSE, 0x214) /* PDCM_PD_VMR0_SENSE on SSE300 */ 63c5ffe6c8SPeter Maydell REG32(PDCM_PD_SRAM3_SENSE, 0x218) /* PDCM_PD_VMR1_SENSE on SSE300 */ 6475750e4dSPeter Maydell REG32(PID4, 0xfd0) 6575750e4dSPeter Maydell REG32(PID5, 0xfd4) 6675750e4dSPeter Maydell REG32(PID6, 0xfd8) 6775750e4dSPeter Maydell REG32(PID7, 0xfdc) 6875750e4dSPeter Maydell REG32(PID0, 0xfe0) 6975750e4dSPeter Maydell REG32(PID1, 0xfe4) 7075750e4dSPeter Maydell REG32(PID2, 0xfe8) 7175750e4dSPeter Maydell REG32(PID3, 0xfec) 7275750e4dSPeter Maydell REG32(CID0, 0xff0) 7375750e4dSPeter Maydell REG32(CID1, 0xff4) 7475750e4dSPeter Maydell REG32(CID2, 0xff8) 7575750e4dSPeter Maydell REG32(CID3, 0xffc) 7675750e4dSPeter Maydell 7775750e4dSPeter Maydell /* PID/CID values */ 78*6069bbc9SPeter Maydell static const int iotkit_sysctl_id[] = { 7975750e4dSPeter Maydell 0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */ 8075750e4dSPeter Maydell 0x54, 0xb8, 0x0b, 0x00, /* PID0..PID3 */ 8175750e4dSPeter Maydell 0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */ 8275750e4dSPeter Maydell }; 8375750e4dSPeter Maydell 84*6069bbc9SPeter Maydell /* Also used by the SSE300 */ 85*6069bbc9SPeter Maydell static const int sse200_sysctl_id[] = { 86*6069bbc9SPeter Maydell 0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */ 87*6069bbc9SPeter Maydell 0x54, 0xb8, 0x1b, 0x00, /* PID0..PID3 */ 88*6069bbc9SPeter Maydell 0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */ 89*6069bbc9SPeter Maydell }; 90*6069bbc9SPeter Maydell 910f862986SPeter Maydell /* 920f862986SPeter Maydell * Set the initial secure vector table offset address for the core. 930f862986SPeter Maydell * This will take effect when the CPU next resets. 940f862986SPeter Maydell */ 950f862986SPeter Maydell static void set_init_vtor(uint64_t cpuid, uint32_t vtor) 960f862986SPeter Maydell { 970f862986SPeter Maydell Object *cpuobj = OBJECT(arm_get_cpu_by_id(cpuid)); 980f862986SPeter Maydell 990f862986SPeter Maydell if (cpuobj) { 100efba1595SDaniel P. Berrangé if (object_property_find(cpuobj, "init-svtor")) { 1015325cc34SMarkus Armbruster object_property_set_uint(cpuobj, "init-svtor", vtor, &error_abort); 1020f862986SPeter Maydell } 1030f862986SPeter Maydell } 1040f862986SPeter Maydell } 1050f862986SPeter Maydell 10675750e4dSPeter Maydell static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset, 10775750e4dSPeter Maydell unsigned size) 10875750e4dSPeter Maydell { 10975750e4dSPeter Maydell IoTKitSysCtl *s = IOTKIT_SYSCTL(opaque); 11075750e4dSPeter Maydell uint64_t r; 11175750e4dSPeter Maydell 11275750e4dSPeter Maydell switch (offset) { 11375750e4dSPeter Maydell case A_SECDBGSTAT: 11475750e4dSPeter Maydell r = s->secure_debug; 11575750e4dSPeter Maydell break; 11604836414SPeter Maydell case A_SCSECCTRL: 1171cbd6fe4SPeter Maydell switch (s->sse_version) { 1181cbd6fe4SPeter Maydell case ARMSSE_IOTKIT: 11904836414SPeter Maydell goto bad_offset; 1201cbd6fe4SPeter Maydell case ARMSSE_SSE200: 12131b0c6b1SPeter Maydell case ARMSSE_SSE300: 12204836414SPeter Maydell r = s->scsecctrl; 12304836414SPeter Maydell break; 1241cbd6fe4SPeter Maydell default: 1251cbd6fe4SPeter Maydell g_assert_not_reached(); 12604836414SPeter Maydell } 1271cbd6fe4SPeter Maydell break; 1281cbd6fe4SPeter Maydell case A_FCLK_DIV: 1291cbd6fe4SPeter Maydell switch (s->sse_version) { 1301cbd6fe4SPeter Maydell case ARMSSE_IOTKIT: 1311cbd6fe4SPeter Maydell goto bad_offset; 1321cbd6fe4SPeter Maydell case ARMSSE_SSE200: 13331b0c6b1SPeter Maydell case ARMSSE_SSE300: 13404836414SPeter Maydell r = s->fclk_div; 13504836414SPeter Maydell break; 1361cbd6fe4SPeter Maydell default: 1371cbd6fe4SPeter Maydell g_assert_not_reached(); 13804836414SPeter Maydell } 1391cbd6fe4SPeter Maydell break; 1401cbd6fe4SPeter Maydell case A_SYSCLK_DIV: 1411cbd6fe4SPeter Maydell switch (s->sse_version) { 1421cbd6fe4SPeter Maydell case ARMSSE_IOTKIT: 1431cbd6fe4SPeter Maydell goto bad_offset; 1441cbd6fe4SPeter Maydell case ARMSSE_SSE200: 14531b0c6b1SPeter Maydell case ARMSSE_SSE300: 14604836414SPeter Maydell r = s->sysclk_div; 14704836414SPeter Maydell break; 1481cbd6fe4SPeter Maydell default: 1491cbd6fe4SPeter Maydell g_assert_not_reached(); 15004836414SPeter Maydell } 1511cbd6fe4SPeter Maydell break; 1521cbd6fe4SPeter Maydell case A_CLOCK_FORCE: 1531cbd6fe4SPeter Maydell switch (s->sse_version) { 1541cbd6fe4SPeter Maydell case ARMSSE_IOTKIT: 1551cbd6fe4SPeter Maydell goto bad_offset; 1561cbd6fe4SPeter Maydell case ARMSSE_SSE200: 15731b0c6b1SPeter Maydell case ARMSSE_SSE300: 15804836414SPeter Maydell r = s->clock_force; 15904836414SPeter Maydell break; 1601cbd6fe4SPeter Maydell default: 1611cbd6fe4SPeter Maydell g_assert_not_reached(); 1621cbd6fe4SPeter Maydell } 1631cbd6fe4SPeter Maydell break; 16475750e4dSPeter Maydell case A_RESET_SYNDROME: 16575750e4dSPeter Maydell r = s->reset_syndrome; 16675750e4dSPeter Maydell break; 16775750e4dSPeter Maydell case A_RESET_MASK: 16875750e4dSPeter Maydell r = s->reset_mask; 16975750e4dSPeter Maydell break; 17075750e4dSPeter Maydell case A_GRETREG: 17175750e4dSPeter Maydell r = s->gretreg; 17275750e4dSPeter Maydell break; 173394e10d2SPeter Maydell case A_INITSVTOR0: 174394e10d2SPeter Maydell r = s->initsvtor0; 17575750e4dSPeter Maydell break; 17604836414SPeter Maydell case A_INITSVTOR1: 1771cbd6fe4SPeter Maydell switch (s->sse_version) { 1781cbd6fe4SPeter Maydell case ARMSSE_IOTKIT: 17904836414SPeter Maydell goto bad_offset; 1801cbd6fe4SPeter Maydell case ARMSSE_SSE200: 18104836414SPeter Maydell r = s->initsvtor1; 18204836414SPeter Maydell break; 183246dbeb7SPeter Maydell case ARMSSE_SSE300: 184246dbeb7SPeter Maydell goto bad_offset; 1851cbd6fe4SPeter Maydell default: 1861cbd6fe4SPeter Maydell g_assert_not_reached(); 1871cbd6fe4SPeter Maydell } 1881cbd6fe4SPeter Maydell break; 18975750e4dSPeter Maydell case A_CPUWAIT: 19092ecf2d5SPeter Maydell switch (s->sse_version) { 19192ecf2d5SPeter Maydell case ARMSSE_IOTKIT: 19292ecf2d5SPeter Maydell case ARMSSE_SSE200: 19375750e4dSPeter Maydell r = s->cpuwait; 19475750e4dSPeter Maydell break; 19592ecf2d5SPeter Maydell case ARMSSE_SSE300: 19692ecf2d5SPeter Maydell /* In SSE300 this is reserved (for INITSVTOR2) */ 19792ecf2d5SPeter Maydell goto bad_offset; 19892ecf2d5SPeter Maydell default: 19992ecf2d5SPeter Maydell g_assert_not_reached(); 20092ecf2d5SPeter Maydell } 20192ecf2d5SPeter Maydell break; 20204836414SPeter Maydell case A_NMI_ENABLE: 2031cbd6fe4SPeter Maydell switch (s->sse_version) { 2041cbd6fe4SPeter Maydell case ARMSSE_IOTKIT: 2051cbd6fe4SPeter Maydell /* In IoTKit this is named BUSWAIT but marked reserved, R/O, zero */ 20675750e4dSPeter Maydell r = 0; 20775750e4dSPeter Maydell break; 2081cbd6fe4SPeter Maydell case ARMSSE_SSE200: 20904836414SPeter Maydell r = s->nmi_enable; 21004836414SPeter Maydell break; 21192ecf2d5SPeter Maydell case ARMSSE_SSE300: 21292ecf2d5SPeter Maydell /* In SSE300 this is reserved (for INITSVTOR3) */ 21392ecf2d5SPeter Maydell goto bad_offset; 2141cbd6fe4SPeter Maydell default: 2151cbd6fe4SPeter Maydell g_assert_not_reached(); 2161cbd6fe4SPeter Maydell } 2171cbd6fe4SPeter Maydell break; 21875750e4dSPeter Maydell case A_WICCTRL: 21992ecf2d5SPeter Maydell switch (s->sse_version) { 22092ecf2d5SPeter Maydell case ARMSSE_IOTKIT: 22192ecf2d5SPeter Maydell case ARMSSE_SSE200: 22275750e4dSPeter Maydell r = s->wicctrl; 22375750e4dSPeter Maydell break; 22492ecf2d5SPeter Maydell case ARMSSE_SSE300: 22592ecf2d5SPeter Maydell /* In SSE300 this offset is CPUWAIT */ 22692ecf2d5SPeter Maydell r = s->cpuwait; 22792ecf2d5SPeter Maydell break; 22892ecf2d5SPeter Maydell default: 22992ecf2d5SPeter Maydell g_assert_not_reached(); 23092ecf2d5SPeter Maydell } 23192ecf2d5SPeter Maydell break; 23204836414SPeter Maydell case A_EWCTRL: 2331cbd6fe4SPeter Maydell switch (s->sse_version) { 2341cbd6fe4SPeter Maydell case ARMSSE_IOTKIT: 23504836414SPeter Maydell goto bad_offset; 2361cbd6fe4SPeter Maydell case ARMSSE_SSE200: 23704836414SPeter Maydell r = s->ewctrl; 23804836414SPeter Maydell break; 23992ecf2d5SPeter Maydell case ARMSSE_SSE300: 24092ecf2d5SPeter Maydell /* In SSE300 this offset is is NMI_ENABLE */ 24192ecf2d5SPeter Maydell r = s->nmi_enable; 24292ecf2d5SPeter Maydell break; 2431cbd6fe4SPeter Maydell default: 2441cbd6fe4SPeter Maydell g_assert_not_reached(); 24504836414SPeter Maydell } 2461cbd6fe4SPeter Maydell break; 2472672a6caSPeter Maydell case A_PWRCTRL: 2482672a6caSPeter Maydell switch (s->sse_version) { 2492672a6caSPeter Maydell case ARMSSE_IOTKIT: 2502672a6caSPeter Maydell case ARMSSE_SSE200: 2512672a6caSPeter Maydell goto bad_offset; 2522672a6caSPeter Maydell case ARMSSE_SSE300: 2532672a6caSPeter Maydell r = s->pwrctrl; 2542672a6caSPeter Maydell break; 2552672a6caSPeter Maydell default: 2562672a6caSPeter Maydell g_assert_not_reached(); 2572672a6caSPeter Maydell } 2582672a6caSPeter Maydell break; 2591cbd6fe4SPeter Maydell case A_PDCM_PD_SYS_SENSE: 2601cbd6fe4SPeter Maydell switch (s->sse_version) { 2611cbd6fe4SPeter Maydell case ARMSSE_IOTKIT: 2621cbd6fe4SPeter Maydell goto bad_offset; 2631cbd6fe4SPeter Maydell case ARMSSE_SSE200: 26431b0c6b1SPeter Maydell case ARMSSE_SSE300: 26504836414SPeter Maydell r = s->pdcm_pd_sys_sense; 26604836414SPeter Maydell break; 2671cbd6fe4SPeter Maydell default: 2681cbd6fe4SPeter Maydell g_assert_not_reached(); 26904836414SPeter Maydell } 2701cbd6fe4SPeter Maydell break; 271c5ffe6c8SPeter Maydell case A_PDCM_PD_CPU0_SENSE: 272c5ffe6c8SPeter Maydell switch (s->sse_version) { 273c5ffe6c8SPeter Maydell case ARMSSE_IOTKIT: 274c5ffe6c8SPeter Maydell case ARMSSE_SSE200: 275c5ffe6c8SPeter Maydell goto bad_offset; 276c5ffe6c8SPeter Maydell case ARMSSE_SSE300: 277c5ffe6c8SPeter Maydell r = s->pdcm_pd_cpu0_sense; 278c5ffe6c8SPeter Maydell break; 279c5ffe6c8SPeter Maydell default: 280c5ffe6c8SPeter Maydell g_assert_not_reached(); 281c5ffe6c8SPeter Maydell } 282c5ffe6c8SPeter Maydell break; 2831cbd6fe4SPeter Maydell case A_PDCM_PD_SRAM0_SENSE: 2841cbd6fe4SPeter Maydell switch (s->sse_version) { 2851cbd6fe4SPeter Maydell case ARMSSE_IOTKIT: 2861cbd6fe4SPeter Maydell goto bad_offset; 2871cbd6fe4SPeter Maydell case ARMSSE_SSE200: 28804836414SPeter Maydell r = s->pdcm_pd_sram0_sense; 28904836414SPeter Maydell break; 290c5ffe6c8SPeter Maydell case ARMSSE_SSE300: 291c5ffe6c8SPeter Maydell goto bad_offset; 2921cbd6fe4SPeter Maydell default: 2931cbd6fe4SPeter Maydell g_assert_not_reached(); 29404836414SPeter Maydell } 2951cbd6fe4SPeter Maydell break; 2961cbd6fe4SPeter Maydell case A_PDCM_PD_SRAM1_SENSE: 2971cbd6fe4SPeter Maydell switch (s->sse_version) { 2981cbd6fe4SPeter Maydell case ARMSSE_IOTKIT: 2991cbd6fe4SPeter Maydell goto bad_offset; 3001cbd6fe4SPeter Maydell case ARMSSE_SSE200: 30104836414SPeter Maydell r = s->pdcm_pd_sram1_sense; 30204836414SPeter Maydell break; 303c5ffe6c8SPeter Maydell case ARMSSE_SSE300: 304c5ffe6c8SPeter Maydell goto bad_offset; 3051cbd6fe4SPeter Maydell default: 3061cbd6fe4SPeter Maydell g_assert_not_reached(); 30704836414SPeter Maydell } 3081cbd6fe4SPeter Maydell break; 3091cbd6fe4SPeter Maydell case A_PDCM_PD_SRAM2_SENSE: 3101cbd6fe4SPeter Maydell switch (s->sse_version) { 3111cbd6fe4SPeter Maydell case ARMSSE_IOTKIT: 3121cbd6fe4SPeter Maydell goto bad_offset; 3131cbd6fe4SPeter Maydell case ARMSSE_SSE200: 31404836414SPeter Maydell r = s->pdcm_pd_sram2_sense; 31504836414SPeter Maydell break; 316c5ffe6c8SPeter Maydell case ARMSSE_SSE300: 317c5ffe6c8SPeter Maydell r = s->pdcm_pd_vmr0_sense; 318c5ffe6c8SPeter Maydell break; 3191cbd6fe4SPeter Maydell default: 3201cbd6fe4SPeter Maydell g_assert_not_reached(); 32104836414SPeter Maydell } 3221cbd6fe4SPeter Maydell break; 3231cbd6fe4SPeter Maydell case A_PDCM_PD_SRAM3_SENSE: 3241cbd6fe4SPeter Maydell switch (s->sse_version) { 3251cbd6fe4SPeter Maydell case ARMSSE_IOTKIT: 3261cbd6fe4SPeter Maydell goto bad_offset; 3271cbd6fe4SPeter Maydell case ARMSSE_SSE200: 32804836414SPeter Maydell r = s->pdcm_pd_sram3_sense; 32904836414SPeter Maydell break; 330c5ffe6c8SPeter Maydell case ARMSSE_SSE300: 331c5ffe6c8SPeter Maydell r = s->pdcm_pd_vmr1_sense; 332c5ffe6c8SPeter Maydell break; 3331cbd6fe4SPeter Maydell default: 3341cbd6fe4SPeter Maydell g_assert_not_reached(); 3351cbd6fe4SPeter Maydell } 3361cbd6fe4SPeter Maydell break; 33775750e4dSPeter Maydell case A_PID4 ... A_CID3: 338*6069bbc9SPeter Maydell switch (s->sse_version) { 339*6069bbc9SPeter Maydell case ARMSSE_IOTKIT: 340*6069bbc9SPeter Maydell r = iotkit_sysctl_id[(offset - A_PID4) / 4]; 341*6069bbc9SPeter Maydell break; 342*6069bbc9SPeter Maydell case ARMSSE_SSE200: 343*6069bbc9SPeter Maydell case ARMSSE_SSE300: 344*6069bbc9SPeter Maydell r = sse200_sysctl_id[(offset - A_PID4) / 4]; 345*6069bbc9SPeter Maydell break; 346*6069bbc9SPeter Maydell default: 347*6069bbc9SPeter Maydell g_assert_not_reached(); 348*6069bbc9SPeter Maydell } 34975750e4dSPeter Maydell break; 35075750e4dSPeter Maydell case A_SECDBGSET: 35175750e4dSPeter Maydell case A_SECDBGCLR: 35275750e4dSPeter Maydell case A_SWRESET: 35375750e4dSPeter Maydell qemu_log_mask(LOG_GUEST_ERROR, 35475750e4dSPeter Maydell "IoTKit SysCtl read: read of WO offset %x\n", 35575750e4dSPeter Maydell (int)offset); 35675750e4dSPeter Maydell r = 0; 35775750e4dSPeter Maydell break; 35875750e4dSPeter Maydell default: 35904836414SPeter Maydell bad_offset: 36075750e4dSPeter Maydell qemu_log_mask(LOG_GUEST_ERROR, 36175750e4dSPeter Maydell "IoTKit SysCtl read: bad offset %x\n", (int)offset); 36275750e4dSPeter Maydell r = 0; 36375750e4dSPeter Maydell break; 36475750e4dSPeter Maydell } 36575750e4dSPeter Maydell trace_iotkit_sysctl_read(offset, r, size); 36675750e4dSPeter Maydell return r; 36775750e4dSPeter Maydell } 36875750e4dSPeter Maydell 36992ecf2d5SPeter Maydell static void cpuwait_write(IoTKitSysCtl *s, uint32_t value) 37092ecf2d5SPeter Maydell { 37192ecf2d5SPeter Maydell int num_cpus = (s->sse_version == ARMSSE_SSE300) ? 1 : 2; 37292ecf2d5SPeter Maydell int i; 37392ecf2d5SPeter Maydell 37492ecf2d5SPeter Maydell for (i = 0; i < num_cpus; i++) { 37592ecf2d5SPeter Maydell uint32_t mask = 1 << i; 37692ecf2d5SPeter Maydell if ((s->cpuwait & mask) && !(value & mask)) { 37792ecf2d5SPeter Maydell /* Powering up CPU 0 */ 37892ecf2d5SPeter Maydell arm_set_cpu_on_and_reset(i); 37992ecf2d5SPeter Maydell } 38092ecf2d5SPeter Maydell } 38192ecf2d5SPeter Maydell s->cpuwait = value; 38292ecf2d5SPeter Maydell } 38392ecf2d5SPeter Maydell 38475750e4dSPeter Maydell static void iotkit_sysctl_write(void *opaque, hwaddr offset, 38575750e4dSPeter Maydell uint64_t value, unsigned size) 38675750e4dSPeter Maydell { 38775750e4dSPeter Maydell IoTKitSysCtl *s = IOTKIT_SYSCTL(opaque); 38875750e4dSPeter Maydell 38975750e4dSPeter Maydell trace_iotkit_sysctl_write(offset, value, size); 39075750e4dSPeter Maydell 39175750e4dSPeter Maydell /* 39275750e4dSPeter Maydell * Most of the state here has to do with control of reset and 39375750e4dSPeter Maydell * similar kinds of power up -- for instance the guest can ask 39475750e4dSPeter Maydell * what the reason for the last reset was, or forbid reset for 39575750e4dSPeter Maydell * some causes (like the non-secure watchdog). Most of this is 39675750e4dSPeter Maydell * not relevant to QEMU, which doesn't really model anything other 39775750e4dSPeter Maydell * than a full power-on reset. 39875750e4dSPeter Maydell * We just model the registers as reads-as-written. 39975750e4dSPeter Maydell */ 40075750e4dSPeter Maydell 40175750e4dSPeter Maydell switch (offset) { 40275750e4dSPeter Maydell case A_RESET_SYNDROME: 40375750e4dSPeter Maydell qemu_log_mask(LOG_UNIMP, 40475750e4dSPeter Maydell "IoTKit SysCtl RESET_SYNDROME unimplemented\n"); 40575750e4dSPeter Maydell s->reset_syndrome = value; 40675750e4dSPeter Maydell break; 40775750e4dSPeter Maydell case A_RESET_MASK: 40875750e4dSPeter Maydell qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl RESET_MASK unimplemented\n"); 40975750e4dSPeter Maydell s->reset_mask = value; 41075750e4dSPeter Maydell break; 41175750e4dSPeter Maydell case A_GRETREG: 41275750e4dSPeter Maydell /* 41375750e4dSPeter Maydell * General retention register, which is only reset by a power-on 41475750e4dSPeter Maydell * reset. Technically this implementation is complete, since 41575750e4dSPeter Maydell * QEMU only supports power-on resets... 41675750e4dSPeter Maydell */ 41775750e4dSPeter Maydell s->gretreg = value; 41875750e4dSPeter Maydell break; 419394e10d2SPeter Maydell case A_INITSVTOR0: 420246dbeb7SPeter Maydell switch (s->sse_version) { 421246dbeb7SPeter Maydell case ARMSSE_SSE300: 422246dbeb7SPeter Maydell /* SSE300 has a LOCK bit which prevents further writes when set */ 423246dbeb7SPeter Maydell if (s->initsvtor0 & R_INITSVTOR0_LOCK_MASK) { 424246dbeb7SPeter Maydell qemu_log_mask(LOG_GUEST_ERROR, 425246dbeb7SPeter Maydell "IoTKit INITSVTOR0 write when register locked\n"); 426246dbeb7SPeter Maydell break; 427246dbeb7SPeter Maydell } 428246dbeb7SPeter Maydell s->initsvtor0 = value; 429246dbeb7SPeter Maydell set_init_vtor(0, s->initsvtor0 & R_INITSVTOR0_VTOR_MASK); 430246dbeb7SPeter Maydell break; 431246dbeb7SPeter Maydell case ARMSSE_IOTKIT: 432246dbeb7SPeter Maydell case ARMSSE_SSE200: 433394e10d2SPeter Maydell s->initsvtor0 = value; 4340f862986SPeter Maydell set_init_vtor(0, s->initsvtor0); 43575750e4dSPeter Maydell break; 436246dbeb7SPeter Maydell default: 437246dbeb7SPeter Maydell g_assert_not_reached(); 438246dbeb7SPeter Maydell } 439246dbeb7SPeter Maydell break; 44075750e4dSPeter Maydell case A_CPUWAIT: 44192ecf2d5SPeter Maydell switch (s->sse_version) { 44292ecf2d5SPeter Maydell case ARMSSE_IOTKIT: 44392ecf2d5SPeter Maydell case ARMSSE_SSE200: 44492ecf2d5SPeter Maydell cpuwait_write(s, value); 44592ecf2d5SPeter Maydell break; 44692ecf2d5SPeter Maydell case ARMSSE_SSE300: 44792ecf2d5SPeter Maydell /* In SSE300 this is reserved (for INITSVTOR2) */ 44892ecf2d5SPeter Maydell goto bad_offset; 44992ecf2d5SPeter Maydell default: 45092ecf2d5SPeter Maydell g_assert_not_reached(); 4510f862986SPeter Maydell } 45275750e4dSPeter Maydell break; 45375750e4dSPeter Maydell case A_WICCTRL: 45492ecf2d5SPeter Maydell switch (s->sse_version) { 45592ecf2d5SPeter Maydell case ARMSSE_IOTKIT: 45692ecf2d5SPeter Maydell case ARMSSE_SSE200: 45775750e4dSPeter Maydell qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl WICCTRL unimplemented\n"); 45875750e4dSPeter Maydell s->wicctrl = value; 45975750e4dSPeter Maydell break; 46092ecf2d5SPeter Maydell case ARMSSE_SSE300: 46192ecf2d5SPeter Maydell /* In SSE300 this offset is CPUWAIT */ 46292ecf2d5SPeter Maydell cpuwait_write(s, value); 46392ecf2d5SPeter Maydell break; 46492ecf2d5SPeter Maydell default: 46592ecf2d5SPeter Maydell g_assert_not_reached(); 46692ecf2d5SPeter Maydell } 46792ecf2d5SPeter Maydell break; 46875750e4dSPeter Maydell case A_SECDBGSET: 46975750e4dSPeter Maydell /* write-1-to-set */ 47075750e4dSPeter Maydell qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SECDBGSET unimplemented\n"); 47175750e4dSPeter Maydell s->secure_debug |= value; 47275750e4dSPeter Maydell break; 47375750e4dSPeter Maydell case A_SECDBGCLR: 47475750e4dSPeter Maydell /* write-1-to-clear */ 47575750e4dSPeter Maydell s->secure_debug &= ~value; 47675750e4dSPeter Maydell break; 47775750e4dSPeter Maydell case A_SWRESET: 47875750e4dSPeter Maydell /* One w/o bit to request a reset; all other bits reserved */ 47975750e4dSPeter Maydell if (value & R_SWRESET_SWRESETREQ_MASK) { 48075750e4dSPeter Maydell qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); 48175750e4dSPeter Maydell } 48275750e4dSPeter Maydell break; 48304836414SPeter Maydell case A_SCSECCTRL: 4841cbd6fe4SPeter Maydell switch (s->sse_version) { 4851cbd6fe4SPeter Maydell case ARMSSE_IOTKIT: 48604836414SPeter Maydell goto bad_offset; 4871cbd6fe4SPeter Maydell case ARMSSE_SSE200: 48831b0c6b1SPeter Maydell case ARMSSE_SSE300: 48904836414SPeter Maydell qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SCSECCTRL unimplemented\n"); 49004836414SPeter Maydell s->scsecctrl = value; 49104836414SPeter Maydell break; 4921cbd6fe4SPeter Maydell default: 4931cbd6fe4SPeter Maydell g_assert_not_reached(); 49404836414SPeter Maydell } 4951cbd6fe4SPeter Maydell break; 4961cbd6fe4SPeter Maydell case A_FCLK_DIV: 4971cbd6fe4SPeter Maydell switch (s->sse_version) { 4981cbd6fe4SPeter Maydell case ARMSSE_IOTKIT: 4991cbd6fe4SPeter Maydell goto bad_offset; 5001cbd6fe4SPeter Maydell case ARMSSE_SSE200: 50131b0c6b1SPeter Maydell case ARMSSE_SSE300: 50204836414SPeter Maydell qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl FCLK_DIV unimplemented\n"); 50304836414SPeter Maydell s->fclk_div = value; 50404836414SPeter Maydell break; 5051cbd6fe4SPeter Maydell default: 5061cbd6fe4SPeter Maydell g_assert_not_reached(); 50704836414SPeter Maydell } 5081cbd6fe4SPeter Maydell break; 5091cbd6fe4SPeter Maydell case A_SYSCLK_DIV: 5101cbd6fe4SPeter Maydell switch (s->sse_version) { 5111cbd6fe4SPeter Maydell case ARMSSE_IOTKIT: 5121cbd6fe4SPeter Maydell goto bad_offset; 5131cbd6fe4SPeter Maydell case ARMSSE_SSE200: 51431b0c6b1SPeter Maydell case ARMSSE_SSE300: 51504836414SPeter Maydell qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SYSCLK_DIV unimplemented\n"); 51604836414SPeter Maydell s->sysclk_div = value; 51704836414SPeter Maydell break; 5181cbd6fe4SPeter Maydell default: 5191cbd6fe4SPeter Maydell g_assert_not_reached(); 52004836414SPeter Maydell } 5211cbd6fe4SPeter Maydell break; 5221cbd6fe4SPeter Maydell case A_CLOCK_FORCE: 5231cbd6fe4SPeter Maydell switch (s->sse_version) { 5241cbd6fe4SPeter Maydell case ARMSSE_IOTKIT: 5251cbd6fe4SPeter Maydell goto bad_offset; 5261cbd6fe4SPeter Maydell case ARMSSE_SSE200: 52731b0c6b1SPeter Maydell case ARMSSE_SSE300: 52804836414SPeter Maydell qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl CLOCK_FORCE unimplemented\n"); 52904836414SPeter Maydell s->clock_force = value; 53004836414SPeter Maydell break; 5311cbd6fe4SPeter Maydell default: 5321cbd6fe4SPeter Maydell g_assert_not_reached(); 53304836414SPeter Maydell } 5341cbd6fe4SPeter Maydell break; 5351cbd6fe4SPeter Maydell case A_INITSVTOR1: 5361cbd6fe4SPeter Maydell switch (s->sse_version) { 5371cbd6fe4SPeter Maydell case ARMSSE_IOTKIT: 5381cbd6fe4SPeter Maydell goto bad_offset; 5391cbd6fe4SPeter Maydell case ARMSSE_SSE200: 54004836414SPeter Maydell s->initsvtor1 = value; 5410f862986SPeter Maydell set_init_vtor(1, s->initsvtor1); 54204836414SPeter Maydell break; 543246dbeb7SPeter Maydell case ARMSSE_SSE300: 544246dbeb7SPeter Maydell goto bad_offset; 5451cbd6fe4SPeter Maydell default: 5461cbd6fe4SPeter Maydell g_assert_not_reached(); 54704836414SPeter Maydell } 5481cbd6fe4SPeter Maydell break; 5491cbd6fe4SPeter Maydell case A_EWCTRL: 5501cbd6fe4SPeter Maydell switch (s->sse_version) { 5511cbd6fe4SPeter Maydell case ARMSSE_IOTKIT: 5521cbd6fe4SPeter Maydell goto bad_offset; 5531cbd6fe4SPeter Maydell case ARMSSE_SSE200: 55404836414SPeter Maydell qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl EWCTRL unimplemented\n"); 55504836414SPeter Maydell s->ewctrl = value; 55604836414SPeter Maydell break; 55792ecf2d5SPeter Maydell case ARMSSE_SSE300: 55892ecf2d5SPeter Maydell /* In SSE300 this offset is is NMI_ENABLE */ 55992ecf2d5SPeter Maydell qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl NMI_ENABLE unimplemented\n"); 56092ecf2d5SPeter Maydell s->nmi_enable = value; 56192ecf2d5SPeter Maydell break; 5621cbd6fe4SPeter Maydell default: 5631cbd6fe4SPeter Maydell g_assert_not_reached(); 56404836414SPeter Maydell } 5651cbd6fe4SPeter Maydell break; 5662672a6caSPeter Maydell case A_PWRCTRL: 5672672a6caSPeter Maydell switch (s->sse_version) { 5682672a6caSPeter Maydell case ARMSSE_IOTKIT: 5692672a6caSPeter Maydell case ARMSSE_SSE200: 5702672a6caSPeter Maydell goto bad_offset; 5712672a6caSPeter Maydell case ARMSSE_SSE300: 5722672a6caSPeter Maydell if (!(s->pwrctrl & R_PWRCTRL_PPU_ACCESS_UNLOCK_MASK)) { 5732672a6caSPeter Maydell qemu_log_mask(LOG_GUEST_ERROR, 5742672a6caSPeter Maydell "IoTKit PWRCTRL write when register locked\n"); 5752672a6caSPeter Maydell break; 5762672a6caSPeter Maydell } 5772672a6caSPeter Maydell s->pwrctrl = value; 5782672a6caSPeter Maydell break; 5792672a6caSPeter Maydell default: 5802672a6caSPeter Maydell g_assert_not_reached(); 5812672a6caSPeter Maydell } 5822672a6caSPeter Maydell break; 5831cbd6fe4SPeter Maydell case A_PDCM_PD_SYS_SENSE: 5841cbd6fe4SPeter Maydell switch (s->sse_version) { 5851cbd6fe4SPeter Maydell case ARMSSE_IOTKIT: 5861cbd6fe4SPeter Maydell goto bad_offset; 5871cbd6fe4SPeter Maydell case ARMSSE_SSE200: 58831b0c6b1SPeter Maydell case ARMSSE_SSE300: 58904836414SPeter Maydell qemu_log_mask(LOG_UNIMP, 59004836414SPeter Maydell "IoTKit SysCtl PDCM_PD_SYS_SENSE unimplemented\n"); 59104836414SPeter Maydell s->pdcm_pd_sys_sense = value; 59204836414SPeter Maydell break; 5931cbd6fe4SPeter Maydell default: 5941cbd6fe4SPeter Maydell g_assert_not_reached(); 59504836414SPeter Maydell } 5961cbd6fe4SPeter Maydell break; 597c5ffe6c8SPeter Maydell case A_PDCM_PD_CPU0_SENSE: 598c5ffe6c8SPeter Maydell switch (s->sse_version) { 599c5ffe6c8SPeter Maydell case ARMSSE_IOTKIT: 600c5ffe6c8SPeter Maydell case ARMSSE_SSE200: 601c5ffe6c8SPeter Maydell goto bad_offset; 602c5ffe6c8SPeter Maydell case ARMSSE_SSE300: 603c5ffe6c8SPeter Maydell qemu_log_mask(LOG_UNIMP, 604c5ffe6c8SPeter Maydell "IoTKit SysCtl PDCM_PD_CPU0_SENSE unimplemented\n"); 605c5ffe6c8SPeter Maydell s->pdcm_pd_cpu0_sense = value; 606c5ffe6c8SPeter Maydell break; 607c5ffe6c8SPeter Maydell default: 608c5ffe6c8SPeter Maydell g_assert_not_reached(); 609c5ffe6c8SPeter Maydell } 610c5ffe6c8SPeter Maydell break; 6111cbd6fe4SPeter Maydell case A_PDCM_PD_SRAM0_SENSE: 6121cbd6fe4SPeter Maydell switch (s->sse_version) { 6131cbd6fe4SPeter Maydell case ARMSSE_IOTKIT: 6141cbd6fe4SPeter Maydell goto bad_offset; 6151cbd6fe4SPeter Maydell case ARMSSE_SSE200: 61604836414SPeter Maydell qemu_log_mask(LOG_UNIMP, 61704836414SPeter Maydell "IoTKit SysCtl PDCM_PD_SRAM0_SENSE unimplemented\n"); 61804836414SPeter Maydell s->pdcm_pd_sram0_sense = value; 61904836414SPeter Maydell break; 620c5ffe6c8SPeter Maydell case ARMSSE_SSE300: 621c5ffe6c8SPeter Maydell goto bad_offset; 6221cbd6fe4SPeter Maydell default: 6231cbd6fe4SPeter Maydell g_assert_not_reached(); 62404836414SPeter Maydell } 6251cbd6fe4SPeter Maydell break; 6261cbd6fe4SPeter Maydell case A_PDCM_PD_SRAM1_SENSE: 6271cbd6fe4SPeter Maydell switch (s->sse_version) { 6281cbd6fe4SPeter Maydell case ARMSSE_IOTKIT: 6291cbd6fe4SPeter Maydell goto bad_offset; 6301cbd6fe4SPeter Maydell case ARMSSE_SSE200: 63104836414SPeter Maydell qemu_log_mask(LOG_UNIMP, 63204836414SPeter Maydell "IoTKit SysCtl PDCM_PD_SRAM1_SENSE unimplemented\n"); 63304836414SPeter Maydell s->pdcm_pd_sram1_sense = value; 63404836414SPeter Maydell break; 635c5ffe6c8SPeter Maydell case ARMSSE_SSE300: 636c5ffe6c8SPeter Maydell goto bad_offset; 6371cbd6fe4SPeter Maydell default: 6381cbd6fe4SPeter Maydell g_assert_not_reached(); 63904836414SPeter Maydell } 6401cbd6fe4SPeter Maydell break; 6411cbd6fe4SPeter Maydell case A_PDCM_PD_SRAM2_SENSE: 6421cbd6fe4SPeter Maydell switch (s->sse_version) { 6431cbd6fe4SPeter Maydell case ARMSSE_IOTKIT: 6441cbd6fe4SPeter Maydell goto bad_offset; 6451cbd6fe4SPeter Maydell case ARMSSE_SSE200: 64604836414SPeter Maydell qemu_log_mask(LOG_UNIMP, 64704836414SPeter Maydell "IoTKit SysCtl PDCM_PD_SRAM2_SENSE unimplemented\n"); 64804836414SPeter Maydell s->pdcm_pd_sram2_sense = value; 64904836414SPeter Maydell break; 650c5ffe6c8SPeter Maydell case ARMSSE_SSE300: 651c5ffe6c8SPeter Maydell qemu_log_mask(LOG_UNIMP, 652c5ffe6c8SPeter Maydell "IoTKit SysCtl PDCM_PD_VMR0_SENSE unimplemented\n"); 653c5ffe6c8SPeter Maydell s->pdcm_pd_vmr0_sense = value; 654c5ffe6c8SPeter Maydell break; 6551cbd6fe4SPeter Maydell default: 6561cbd6fe4SPeter Maydell g_assert_not_reached(); 65704836414SPeter Maydell } 6581cbd6fe4SPeter Maydell break; 6591cbd6fe4SPeter Maydell case A_PDCM_PD_SRAM3_SENSE: 6601cbd6fe4SPeter Maydell switch (s->sse_version) { 6611cbd6fe4SPeter Maydell case ARMSSE_IOTKIT: 6621cbd6fe4SPeter Maydell goto bad_offset; 6631cbd6fe4SPeter Maydell case ARMSSE_SSE200: 66404836414SPeter Maydell qemu_log_mask(LOG_UNIMP, 66504836414SPeter Maydell "IoTKit SysCtl PDCM_PD_SRAM3_SENSE unimplemented\n"); 66604836414SPeter Maydell s->pdcm_pd_sram3_sense = value; 66704836414SPeter Maydell break; 668c5ffe6c8SPeter Maydell case ARMSSE_SSE300: 669c5ffe6c8SPeter Maydell qemu_log_mask(LOG_UNIMP, 670c5ffe6c8SPeter Maydell "IoTKit SysCtl PDCM_PD_VMR1_SENSE unimplemented\n"); 671c5ffe6c8SPeter Maydell s->pdcm_pd_vmr1_sense = value; 672c5ffe6c8SPeter Maydell break; 6731cbd6fe4SPeter Maydell default: 6741cbd6fe4SPeter Maydell g_assert_not_reached(); 6751cbd6fe4SPeter Maydell } 6761cbd6fe4SPeter Maydell break; 67704836414SPeter Maydell case A_NMI_ENABLE: 67804836414SPeter Maydell /* In IoTKit this is BUSWAIT: reserved, R/O, zero */ 6791cbd6fe4SPeter Maydell switch (s->sse_version) { 6801cbd6fe4SPeter Maydell case ARMSSE_IOTKIT: 68104836414SPeter Maydell goto ro_offset; 6821cbd6fe4SPeter Maydell case ARMSSE_SSE200: 68304836414SPeter Maydell qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl NMI_ENABLE unimplemented\n"); 68404836414SPeter Maydell s->nmi_enable = value; 68504836414SPeter Maydell break; 68692ecf2d5SPeter Maydell case ARMSSE_SSE300: 68792ecf2d5SPeter Maydell /* In SSE300 this is reserved (for INITSVTOR3) */ 68892ecf2d5SPeter Maydell goto bad_offset; 6891cbd6fe4SPeter Maydell default: 6901cbd6fe4SPeter Maydell g_assert_not_reached(); 6911cbd6fe4SPeter Maydell } 6921cbd6fe4SPeter Maydell break; 69375750e4dSPeter Maydell case A_SECDBGSTAT: 69475750e4dSPeter Maydell case A_PID4 ... A_CID3: 69504836414SPeter Maydell ro_offset: 69675750e4dSPeter Maydell qemu_log_mask(LOG_GUEST_ERROR, 69775750e4dSPeter Maydell "IoTKit SysCtl write: write of RO offset %x\n", 69875750e4dSPeter Maydell (int)offset); 69975750e4dSPeter Maydell break; 70075750e4dSPeter Maydell default: 70104836414SPeter Maydell bad_offset: 70275750e4dSPeter Maydell qemu_log_mask(LOG_GUEST_ERROR, 70375750e4dSPeter Maydell "IoTKit SysCtl write: bad offset %x\n", (int)offset); 70475750e4dSPeter Maydell break; 70575750e4dSPeter Maydell } 70675750e4dSPeter Maydell } 70775750e4dSPeter Maydell 70875750e4dSPeter Maydell static const MemoryRegionOps iotkit_sysctl_ops = { 70975750e4dSPeter Maydell .read = iotkit_sysctl_read, 71075750e4dSPeter Maydell .write = iotkit_sysctl_write, 71175750e4dSPeter Maydell .endianness = DEVICE_LITTLE_ENDIAN, 71275750e4dSPeter Maydell /* byte/halfword accesses are just zero-padded on reads and writes */ 71375750e4dSPeter Maydell .impl.min_access_size = 4, 71475750e4dSPeter Maydell .impl.max_access_size = 4, 71575750e4dSPeter Maydell .valid.min_access_size = 1, 71675750e4dSPeter Maydell .valid.max_access_size = 4, 71775750e4dSPeter Maydell }; 71875750e4dSPeter Maydell 71975750e4dSPeter Maydell static void iotkit_sysctl_reset(DeviceState *dev) 72075750e4dSPeter Maydell { 72175750e4dSPeter Maydell IoTKitSysCtl *s = IOTKIT_SYSCTL(dev); 72275750e4dSPeter Maydell 72375750e4dSPeter Maydell trace_iotkit_sysctl_reset(); 72475750e4dSPeter Maydell s->secure_debug = 0; 72575750e4dSPeter Maydell s->reset_syndrome = 1; 72675750e4dSPeter Maydell s->reset_mask = 0; 72775750e4dSPeter Maydell s->gretreg = 0; 728aab7a378SPeter Maydell s->initsvtor0 = s->initsvtor0_rst; 729aab7a378SPeter Maydell s->initsvtor1 = s->initsvtor1_rst; 730aab7a378SPeter Maydell s->cpuwait = s->cpuwait_rst; 73175750e4dSPeter Maydell s->wicctrl = 0; 73204836414SPeter Maydell s->scsecctrl = 0; 73304836414SPeter Maydell s->fclk_div = 0; 73404836414SPeter Maydell s->sysclk_div = 0; 73504836414SPeter Maydell s->clock_force = 0; 73604836414SPeter Maydell s->nmi_enable = 0; 73704836414SPeter Maydell s->ewctrl = 0; 7382672a6caSPeter Maydell s->pwrctrl = 0x3; 73904836414SPeter Maydell s->pdcm_pd_sys_sense = 0x7f; 74004836414SPeter Maydell s->pdcm_pd_sram0_sense = 0; 74104836414SPeter Maydell s->pdcm_pd_sram1_sense = 0; 74204836414SPeter Maydell s->pdcm_pd_sram2_sense = 0; 74304836414SPeter Maydell s->pdcm_pd_sram3_sense = 0; 744c5ffe6c8SPeter Maydell s->pdcm_pd_cpu0_sense = 0; 745c5ffe6c8SPeter Maydell s->pdcm_pd_vmr0_sense = 0; 746c5ffe6c8SPeter Maydell s->pdcm_pd_vmr1_sense = 0; 74775750e4dSPeter Maydell } 74875750e4dSPeter Maydell 74975750e4dSPeter Maydell static void iotkit_sysctl_init(Object *obj) 75075750e4dSPeter Maydell { 75175750e4dSPeter Maydell SysBusDevice *sbd = SYS_BUS_DEVICE(obj); 75275750e4dSPeter Maydell IoTKitSysCtl *s = IOTKIT_SYSCTL(obj); 75375750e4dSPeter Maydell 75475750e4dSPeter Maydell memory_region_init_io(&s->iomem, obj, &iotkit_sysctl_ops, 75575750e4dSPeter Maydell s, "iotkit-sysctl", 0x1000); 75675750e4dSPeter Maydell sysbus_init_mmio(sbd, &s->iomem); 75775750e4dSPeter Maydell } 75875750e4dSPeter Maydell 75904836414SPeter Maydell static void iotkit_sysctl_realize(DeviceState *dev, Error **errp) 76004836414SPeter Maydell { 76104836414SPeter Maydell IoTKitSysCtl *s = IOTKIT_SYSCTL(dev); 76204836414SPeter Maydell 763419a7f80SPeter Maydell if (!armsse_version_valid(s->sse_version)) { 764419a7f80SPeter Maydell error_setg(errp, "invalid sse-version value %d", s->sse_version); 765419a7f80SPeter Maydell return; 76604836414SPeter Maydell } 76704836414SPeter Maydell } 76804836414SPeter Maydell 7692672a6caSPeter Maydell static bool sse300_needed(void *opaque) 7702672a6caSPeter Maydell { 7712672a6caSPeter Maydell IoTKitSysCtl *s = IOTKIT_SYSCTL(opaque); 7722672a6caSPeter Maydell 7732672a6caSPeter Maydell return s->sse_version == ARMSSE_SSE300; 7742672a6caSPeter Maydell } 7752672a6caSPeter Maydell 7762672a6caSPeter Maydell static const VMStateDescription iotkit_sysctl_sse300_vmstate = { 7772672a6caSPeter Maydell .name = "iotkit-sysctl/sse-300", 7782672a6caSPeter Maydell .version_id = 1, 7792672a6caSPeter Maydell .minimum_version_id = 1, 7802672a6caSPeter Maydell .needed = sse300_needed, 7812672a6caSPeter Maydell .fields = (VMStateField[]) { 7822672a6caSPeter Maydell VMSTATE_UINT32(pwrctrl, IoTKitSysCtl), 783c5ffe6c8SPeter Maydell VMSTATE_UINT32(pdcm_pd_cpu0_sense, IoTKitSysCtl), 784c5ffe6c8SPeter Maydell VMSTATE_UINT32(pdcm_pd_vmr0_sense, IoTKitSysCtl), 785c5ffe6c8SPeter Maydell VMSTATE_UINT32(pdcm_pd_vmr1_sense, IoTKitSysCtl), 7862672a6caSPeter Maydell VMSTATE_END_OF_LIST() 7872672a6caSPeter Maydell } 7882672a6caSPeter Maydell }; 7892672a6caSPeter Maydell 79004836414SPeter Maydell static bool sse200_needed(void *opaque) 79104836414SPeter Maydell { 79204836414SPeter Maydell IoTKitSysCtl *s = IOTKIT_SYSCTL(opaque); 79304836414SPeter Maydell 79431b0c6b1SPeter Maydell return s->sse_version != ARMSSE_IOTKIT; 79504836414SPeter Maydell } 79604836414SPeter Maydell 79704836414SPeter Maydell static const VMStateDescription iotkit_sysctl_sse200_vmstate = { 79804836414SPeter Maydell .name = "iotkit-sysctl/sse-200", 79904836414SPeter Maydell .version_id = 1, 80004836414SPeter Maydell .minimum_version_id = 1, 80104836414SPeter Maydell .needed = sse200_needed, 80204836414SPeter Maydell .fields = (VMStateField[]) { 80304836414SPeter Maydell VMSTATE_UINT32(scsecctrl, IoTKitSysCtl), 80404836414SPeter Maydell VMSTATE_UINT32(fclk_div, IoTKitSysCtl), 80504836414SPeter Maydell VMSTATE_UINT32(sysclk_div, IoTKitSysCtl), 80604836414SPeter Maydell VMSTATE_UINT32(clock_force, IoTKitSysCtl), 80704836414SPeter Maydell VMSTATE_UINT32(initsvtor1, IoTKitSysCtl), 80804836414SPeter Maydell VMSTATE_UINT32(nmi_enable, IoTKitSysCtl), 80904836414SPeter Maydell VMSTATE_UINT32(pdcm_pd_sys_sense, IoTKitSysCtl), 81004836414SPeter Maydell VMSTATE_UINT32(pdcm_pd_sram0_sense, IoTKitSysCtl), 81104836414SPeter Maydell VMSTATE_UINT32(pdcm_pd_sram1_sense, IoTKitSysCtl), 81204836414SPeter Maydell VMSTATE_UINT32(pdcm_pd_sram2_sense, IoTKitSysCtl), 81304836414SPeter Maydell VMSTATE_UINT32(pdcm_pd_sram3_sense, IoTKitSysCtl), 81404836414SPeter Maydell VMSTATE_END_OF_LIST() 81504836414SPeter Maydell } 81604836414SPeter Maydell }; 81704836414SPeter Maydell 81875750e4dSPeter Maydell static const VMStateDescription iotkit_sysctl_vmstate = { 81975750e4dSPeter Maydell .name = "iotkit-sysctl", 82075750e4dSPeter Maydell .version_id = 1, 82175750e4dSPeter Maydell .minimum_version_id = 1, 82275750e4dSPeter Maydell .fields = (VMStateField[]) { 82375750e4dSPeter Maydell VMSTATE_UINT32(secure_debug, IoTKitSysCtl), 82475750e4dSPeter Maydell VMSTATE_UINT32(reset_syndrome, IoTKitSysCtl), 82575750e4dSPeter Maydell VMSTATE_UINT32(reset_mask, IoTKitSysCtl), 82675750e4dSPeter Maydell VMSTATE_UINT32(gretreg, IoTKitSysCtl), 827394e10d2SPeter Maydell VMSTATE_UINT32(initsvtor0, IoTKitSysCtl), 82875750e4dSPeter Maydell VMSTATE_UINT32(cpuwait, IoTKitSysCtl), 82975750e4dSPeter Maydell VMSTATE_UINT32(wicctrl, IoTKitSysCtl), 83075750e4dSPeter Maydell VMSTATE_END_OF_LIST() 83104836414SPeter Maydell }, 83204836414SPeter Maydell .subsections = (const VMStateDescription*[]) { 83304836414SPeter Maydell &iotkit_sysctl_sse200_vmstate, 8342672a6caSPeter Maydell &iotkit_sysctl_sse300_vmstate, 83504836414SPeter Maydell NULL 83675750e4dSPeter Maydell } 83775750e4dSPeter Maydell }; 83875750e4dSPeter Maydell 83904836414SPeter Maydell static Property iotkit_sysctl_props[] = { 840419a7f80SPeter Maydell DEFINE_PROP_UINT32("sse-version", IoTKitSysCtl, sse_version, 0), 841aab7a378SPeter Maydell DEFINE_PROP_UINT32("CPUWAIT_RST", IoTKitSysCtl, cpuwait_rst, 0), 842aab7a378SPeter Maydell DEFINE_PROP_UINT32("INITSVTOR0_RST", IoTKitSysCtl, initsvtor0_rst, 843aab7a378SPeter Maydell 0x10000000), 844aab7a378SPeter Maydell DEFINE_PROP_UINT32("INITSVTOR1_RST", IoTKitSysCtl, initsvtor1_rst, 845aab7a378SPeter Maydell 0x10000000), 84604836414SPeter Maydell DEFINE_PROP_END_OF_LIST() 84704836414SPeter Maydell }; 84804836414SPeter Maydell 84975750e4dSPeter Maydell static void iotkit_sysctl_class_init(ObjectClass *klass, void *data) 85075750e4dSPeter Maydell { 85175750e4dSPeter Maydell DeviceClass *dc = DEVICE_CLASS(klass); 85275750e4dSPeter Maydell 85375750e4dSPeter Maydell dc->vmsd = &iotkit_sysctl_vmstate; 85475750e4dSPeter Maydell dc->reset = iotkit_sysctl_reset; 8554f67d30bSMarc-André Lureau device_class_set_props(dc, iotkit_sysctl_props); 85604836414SPeter Maydell dc->realize = iotkit_sysctl_realize; 85775750e4dSPeter Maydell } 85875750e4dSPeter Maydell 85975750e4dSPeter Maydell static const TypeInfo iotkit_sysctl_info = { 86075750e4dSPeter Maydell .name = TYPE_IOTKIT_SYSCTL, 86175750e4dSPeter Maydell .parent = TYPE_SYS_BUS_DEVICE, 86275750e4dSPeter Maydell .instance_size = sizeof(IoTKitSysCtl), 86375750e4dSPeter Maydell .instance_init = iotkit_sysctl_init, 86475750e4dSPeter Maydell .class_init = iotkit_sysctl_class_init, 86575750e4dSPeter Maydell }; 86675750e4dSPeter Maydell 86775750e4dSPeter Maydell static void iotkit_sysctl_register_types(void) 86875750e4dSPeter Maydell { 86975750e4dSPeter Maydell type_register_static(&iotkit_sysctl_info); 87075750e4dSPeter Maydell } 87175750e4dSPeter Maydell 87275750e4dSPeter Maydell type_init(iotkit_sysctl_register_types); 873