1de343bb6SPeter Maydell /* 2de343bb6SPeter Maydell * Arm IoT Kit security controller 3de343bb6SPeter Maydell * 4de343bb6SPeter Maydell * Copyright (c) 2018 Linaro Limited 5de343bb6SPeter Maydell * Written by Peter Maydell 6de343bb6SPeter Maydell * 7de343bb6SPeter Maydell * This program is free software; you can redistribute it and/or modify 8de343bb6SPeter Maydell * it under the terms of the GNU General Public License version 2 or 9de343bb6SPeter Maydell * (at your option) any later version. 10de343bb6SPeter Maydell */ 11de343bb6SPeter Maydell 12de343bb6SPeter Maydell #include "qemu/osdep.h" 13de343bb6SPeter Maydell #include "qemu/log.h" 14de343bb6SPeter Maydell #include "qapi/error.h" 15de343bb6SPeter Maydell #include "trace.h" 16de343bb6SPeter Maydell #include "hw/sysbus.h" 17de343bb6SPeter Maydell #include "hw/registerfields.h" 18de343bb6SPeter Maydell #include "hw/misc/iotkit-secctl.h" 19de343bb6SPeter Maydell 20de343bb6SPeter Maydell /* Registers in the secure privilege control block */ 21de343bb6SPeter Maydell REG32(SECRESPCFG, 0x10) 22de343bb6SPeter Maydell REG32(NSCCFG, 0x14) 23de343bb6SPeter Maydell REG32(SECMPCINTSTATUS, 0x1c) 24de343bb6SPeter Maydell REG32(SECPPCINTSTAT, 0x20) 25de343bb6SPeter Maydell REG32(SECPPCINTCLR, 0x24) 26de343bb6SPeter Maydell REG32(SECPPCINTEN, 0x28) 27de343bb6SPeter Maydell REG32(SECMSCINTSTAT, 0x30) 28de343bb6SPeter Maydell REG32(SECMSCINTCLR, 0x34) 29de343bb6SPeter Maydell REG32(SECMSCINTEN, 0x38) 30de343bb6SPeter Maydell REG32(BRGINTSTAT, 0x40) 31de343bb6SPeter Maydell REG32(BRGINTCLR, 0x44) 32de343bb6SPeter Maydell REG32(BRGINTEN, 0x48) 33de343bb6SPeter Maydell REG32(AHBNSPPC0, 0x50) 34de343bb6SPeter Maydell REG32(AHBNSPPCEXP0, 0x60) 35de343bb6SPeter Maydell REG32(AHBNSPPCEXP1, 0x64) 36de343bb6SPeter Maydell REG32(AHBNSPPCEXP2, 0x68) 37de343bb6SPeter Maydell REG32(AHBNSPPCEXP3, 0x6c) 38de343bb6SPeter Maydell REG32(APBNSPPC0, 0x70) 39de343bb6SPeter Maydell REG32(APBNSPPC1, 0x74) 40de343bb6SPeter Maydell REG32(APBNSPPCEXP0, 0x80) 41de343bb6SPeter Maydell REG32(APBNSPPCEXP1, 0x84) 42de343bb6SPeter Maydell REG32(APBNSPPCEXP2, 0x88) 43de343bb6SPeter Maydell REG32(APBNSPPCEXP3, 0x8c) 44de343bb6SPeter Maydell REG32(AHBSPPPC0, 0x90) 45de343bb6SPeter Maydell REG32(AHBSPPPCEXP0, 0xa0) 46de343bb6SPeter Maydell REG32(AHBSPPPCEXP1, 0xa4) 47de343bb6SPeter Maydell REG32(AHBSPPPCEXP2, 0xa8) 48de343bb6SPeter Maydell REG32(AHBSPPPCEXP3, 0xac) 49de343bb6SPeter Maydell REG32(APBSPPPC0, 0xb0) 50de343bb6SPeter Maydell REG32(APBSPPPC1, 0xb4) 51de343bb6SPeter Maydell REG32(APBSPPPCEXP0, 0xc0) 52de343bb6SPeter Maydell REG32(APBSPPPCEXP1, 0xc4) 53de343bb6SPeter Maydell REG32(APBSPPPCEXP2, 0xc8) 54de343bb6SPeter Maydell REG32(APBSPPPCEXP3, 0xcc) 55de343bb6SPeter Maydell REG32(NSMSCEXP, 0xd0) 56de343bb6SPeter Maydell REG32(PID4, 0xfd0) 57de343bb6SPeter Maydell REG32(PID5, 0xfd4) 58de343bb6SPeter Maydell REG32(PID6, 0xfd8) 59de343bb6SPeter Maydell REG32(PID7, 0xfdc) 60de343bb6SPeter Maydell REG32(PID0, 0xfe0) 61de343bb6SPeter Maydell REG32(PID1, 0xfe4) 62de343bb6SPeter Maydell REG32(PID2, 0xfe8) 63de343bb6SPeter Maydell REG32(PID3, 0xfec) 64de343bb6SPeter Maydell REG32(CID0, 0xff0) 65de343bb6SPeter Maydell REG32(CID1, 0xff4) 66de343bb6SPeter Maydell REG32(CID2, 0xff8) 67de343bb6SPeter Maydell REG32(CID3, 0xffc) 68de343bb6SPeter Maydell 69de343bb6SPeter Maydell /* Registers in the non-secure privilege control block */ 70de343bb6SPeter Maydell REG32(AHBNSPPPC0, 0x90) 71de343bb6SPeter Maydell REG32(AHBNSPPPCEXP0, 0xa0) 72de343bb6SPeter Maydell REG32(AHBNSPPPCEXP1, 0xa4) 73de343bb6SPeter Maydell REG32(AHBNSPPPCEXP2, 0xa8) 74de343bb6SPeter Maydell REG32(AHBNSPPPCEXP3, 0xac) 75de343bb6SPeter Maydell REG32(APBNSPPPC0, 0xb0) 76de343bb6SPeter Maydell REG32(APBNSPPPC1, 0xb4) 77de343bb6SPeter Maydell REG32(APBNSPPPCEXP0, 0xc0) 78de343bb6SPeter Maydell REG32(APBNSPPPCEXP1, 0xc4) 79de343bb6SPeter Maydell REG32(APBNSPPPCEXP2, 0xc8) 80de343bb6SPeter Maydell REG32(APBNSPPPCEXP3, 0xcc) 81de343bb6SPeter Maydell /* PID and CID registers are also present in the NS block */ 82de343bb6SPeter Maydell 83de343bb6SPeter Maydell static const uint8_t iotkit_secctl_s_idregs[] = { 84de343bb6SPeter Maydell 0x04, 0x00, 0x00, 0x00, 85de343bb6SPeter Maydell 0x52, 0xb8, 0x0b, 0x00, 86de343bb6SPeter Maydell 0x0d, 0xf0, 0x05, 0xb1, 87de343bb6SPeter Maydell }; 88de343bb6SPeter Maydell 89de343bb6SPeter Maydell static const uint8_t iotkit_secctl_ns_idregs[] = { 90de343bb6SPeter Maydell 0x04, 0x00, 0x00, 0x00, 91de343bb6SPeter Maydell 0x53, 0xb8, 0x0b, 0x00, 92de343bb6SPeter Maydell 0x0d, 0xf0, 0x05, 0xb1, 93de343bb6SPeter Maydell }; 94de343bb6SPeter Maydell 95b3717c23SPeter Maydell /* The register sets for the various PPCs (AHB internal, APB internal, 96b3717c23SPeter Maydell * AHB expansion, APB expansion) are all set up so that they are 97b3717c23SPeter Maydell * in 16-aligned blocks so offsets 0xN0, 0xN4, 0xN8, 0xNC are PPCs 98b3717c23SPeter Maydell * 0, 1, 2, 3 of that type, so we can convert a register address offset 99b3717c23SPeter Maydell * into an an index into a PPC array easily. 100b3717c23SPeter Maydell */ 101b3717c23SPeter Maydell static inline int offset_to_ppc_idx(uint32_t offset) 102b3717c23SPeter Maydell { 103b3717c23SPeter Maydell return extract32(offset, 2, 2); 104b3717c23SPeter Maydell } 105b3717c23SPeter Maydell 106b3717c23SPeter Maydell typedef void PerPPCFunction(IoTKitSecCtlPPC *ppc); 107b3717c23SPeter Maydell 108b3717c23SPeter Maydell static void foreach_ppc(IoTKitSecCtl *s, PerPPCFunction *fn) 109b3717c23SPeter Maydell { 110b3717c23SPeter Maydell int i; 111b3717c23SPeter Maydell 112b3717c23SPeter Maydell for (i = 0; i < IOTS_NUM_APB_PPC; i++) { 113b3717c23SPeter Maydell fn(&s->apb[i]); 114b3717c23SPeter Maydell } 115b3717c23SPeter Maydell for (i = 0; i < IOTS_NUM_APB_EXP_PPC; i++) { 116b3717c23SPeter Maydell fn(&s->apbexp[i]); 117b3717c23SPeter Maydell } 118b3717c23SPeter Maydell for (i = 0; i < IOTS_NUM_AHB_EXP_PPC; i++) { 119b3717c23SPeter Maydell fn(&s->ahbexp[i]); 120b3717c23SPeter Maydell } 121b3717c23SPeter Maydell } 122b3717c23SPeter Maydell 123de343bb6SPeter Maydell static MemTxResult iotkit_secctl_s_read(void *opaque, hwaddr addr, 124de343bb6SPeter Maydell uint64_t *pdata, 125de343bb6SPeter Maydell unsigned size, MemTxAttrs attrs) 126de343bb6SPeter Maydell { 127de343bb6SPeter Maydell uint64_t r; 128de343bb6SPeter Maydell uint32_t offset = addr & ~0x3; 129b3717c23SPeter Maydell IoTKitSecCtl *s = IOTKIT_SECCTL(opaque); 130de343bb6SPeter Maydell 131de343bb6SPeter Maydell switch (offset) { 132de343bb6SPeter Maydell case A_AHBNSPPC0: 133de343bb6SPeter Maydell case A_AHBSPPPC0: 134de343bb6SPeter Maydell r = 0; 135de343bb6SPeter Maydell break; 136de343bb6SPeter Maydell case A_SECRESPCFG: 137b3717c23SPeter Maydell r = s->secrespcfg; 138b3717c23SPeter Maydell break; 139b1ce38e1SPeter Maydell case A_NSCCFG: 140b1ce38e1SPeter Maydell r = s->nsccfg; 141b1ce38e1SPeter Maydell break; 1423fd3cb2fSPeter Maydell case A_SECMPCINTSTATUS: 1433fd3cb2fSPeter Maydell r = s->mpcintstatus; 1443fd3cb2fSPeter Maydell break; 145de343bb6SPeter Maydell case A_SECPPCINTSTAT: 146b3717c23SPeter Maydell r = s->secppcintstat; 147b3717c23SPeter Maydell break; 148de343bb6SPeter Maydell case A_SECPPCINTEN: 149b3717c23SPeter Maydell r = s->secppcinten; 150b3717c23SPeter Maydell break; 151b1ce38e1SPeter Maydell case A_BRGINTSTAT: 152b1ce38e1SPeter Maydell /* QEMU's bus fabric can never report errors as it doesn't buffer 153b1ce38e1SPeter Maydell * writes, so we never report bridge interrupts. 154b1ce38e1SPeter Maydell */ 155b1ce38e1SPeter Maydell r = 0; 156b1ce38e1SPeter Maydell break; 157b1ce38e1SPeter Maydell case A_BRGINTEN: 158b1ce38e1SPeter Maydell r = s->brginten; 159b1ce38e1SPeter Maydell break; 160de343bb6SPeter Maydell case A_AHBNSPPCEXP0: 161de343bb6SPeter Maydell case A_AHBNSPPCEXP1: 162de343bb6SPeter Maydell case A_AHBNSPPCEXP2: 163de343bb6SPeter Maydell case A_AHBNSPPCEXP3: 164b3717c23SPeter Maydell r = s->ahbexp[offset_to_ppc_idx(offset)].ns; 165b3717c23SPeter Maydell break; 166de343bb6SPeter Maydell case A_APBNSPPC0: 167de343bb6SPeter Maydell case A_APBNSPPC1: 168b3717c23SPeter Maydell r = s->apb[offset_to_ppc_idx(offset)].ns; 169b3717c23SPeter Maydell break; 170de343bb6SPeter Maydell case A_APBNSPPCEXP0: 171de343bb6SPeter Maydell case A_APBNSPPCEXP1: 172de343bb6SPeter Maydell case A_APBNSPPCEXP2: 173de343bb6SPeter Maydell case A_APBNSPPCEXP3: 174b3717c23SPeter Maydell r = s->apbexp[offset_to_ppc_idx(offset)].ns; 175b3717c23SPeter Maydell break; 176de343bb6SPeter Maydell case A_AHBSPPPCEXP0: 177de343bb6SPeter Maydell case A_AHBSPPPCEXP1: 178de343bb6SPeter Maydell case A_AHBSPPPCEXP2: 179de343bb6SPeter Maydell case A_AHBSPPPCEXP3: 180b3717c23SPeter Maydell r = s->apbexp[offset_to_ppc_idx(offset)].sp; 181b3717c23SPeter Maydell break; 182de343bb6SPeter Maydell case A_APBSPPPC0: 183de343bb6SPeter Maydell case A_APBSPPPC1: 184b3717c23SPeter Maydell r = s->apb[offset_to_ppc_idx(offset)].sp; 185b3717c23SPeter Maydell break; 186de343bb6SPeter Maydell case A_APBSPPPCEXP0: 187de343bb6SPeter Maydell case A_APBSPPPCEXP1: 188de343bb6SPeter Maydell case A_APBSPPPCEXP2: 189de343bb6SPeter Maydell case A_APBSPPPCEXP3: 190b3717c23SPeter Maydell r = s->apbexp[offset_to_ppc_idx(offset)].sp; 191b3717c23SPeter Maydell break; 192b3717c23SPeter Maydell case A_SECMSCINTSTAT: 19381a75debSPeter Maydell r = s->secmscintstat; 19481a75debSPeter Maydell break; 195b3717c23SPeter Maydell case A_SECMSCINTEN: 19681a75debSPeter Maydell r = s->secmscinten; 19781a75debSPeter Maydell break; 198de343bb6SPeter Maydell case A_NSMSCEXP: 19981a75debSPeter Maydell r = s->nsmscexp; 200de343bb6SPeter Maydell break; 201de343bb6SPeter Maydell case A_PID4: 202de343bb6SPeter Maydell case A_PID5: 203de343bb6SPeter Maydell case A_PID6: 204de343bb6SPeter Maydell case A_PID7: 205de343bb6SPeter Maydell case A_PID0: 206de343bb6SPeter Maydell case A_PID1: 207de343bb6SPeter Maydell case A_PID2: 208de343bb6SPeter Maydell case A_PID3: 209de343bb6SPeter Maydell case A_CID0: 210de343bb6SPeter Maydell case A_CID1: 211de343bb6SPeter Maydell case A_CID2: 212de343bb6SPeter Maydell case A_CID3: 213de343bb6SPeter Maydell r = iotkit_secctl_s_idregs[(offset - A_PID4) / 4]; 214de343bb6SPeter Maydell break; 215de343bb6SPeter Maydell case A_SECPPCINTCLR: 216de343bb6SPeter Maydell case A_SECMSCINTCLR: 217de343bb6SPeter Maydell case A_BRGINTCLR: 218de343bb6SPeter Maydell qemu_log_mask(LOG_GUEST_ERROR, 219de343bb6SPeter Maydell "IotKit SecCtl S block read: write-only offset 0x%x\n", 220de343bb6SPeter Maydell offset); 221de343bb6SPeter Maydell r = 0; 222de343bb6SPeter Maydell break; 223de343bb6SPeter Maydell default: 224de343bb6SPeter Maydell qemu_log_mask(LOG_GUEST_ERROR, 225de343bb6SPeter Maydell "IotKit SecCtl S block read: bad offset 0x%x\n", offset); 226de343bb6SPeter Maydell r = 0; 227de343bb6SPeter Maydell break; 228de343bb6SPeter Maydell } 229de343bb6SPeter Maydell 230de343bb6SPeter Maydell if (size != 4) { 231de343bb6SPeter Maydell /* None of our registers are access-sensitive, so just pull the right 232de343bb6SPeter Maydell * byte out of the word read result. 233de343bb6SPeter Maydell */ 234de343bb6SPeter Maydell r = extract32(r, (addr & 3) * 8, size * 8); 235de343bb6SPeter Maydell } 236de343bb6SPeter Maydell 237de343bb6SPeter Maydell trace_iotkit_secctl_s_read(offset, r, size); 238de343bb6SPeter Maydell *pdata = r; 239de343bb6SPeter Maydell return MEMTX_OK; 240de343bb6SPeter Maydell } 241de343bb6SPeter Maydell 242b3717c23SPeter Maydell static void iotkit_secctl_update_ppc_ap(IoTKitSecCtlPPC *ppc) 243b3717c23SPeter Maydell { 244b3717c23SPeter Maydell int i; 245b3717c23SPeter Maydell 246b3717c23SPeter Maydell for (i = 0; i < ppc->numports; i++) { 247b3717c23SPeter Maydell bool v; 248b3717c23SPeter Maydell 249b3717c23SPeter Maydell if (extract32(ppc->ns, i, 1)) { 250b3717c23SPeter Maydell v = extract32(ppc->nsp, i, 1); 251b3717c23SPeter Maydell } else { 252b3717c23SPeter Maydell v = extract32(ppc->sp, i, 1); 253b3717c23SPeter Maydell } 254b3717c23SPeter Maydell qemu_set_irq(ppc->ap[i], v); 255b3717c23SPeter Maydell } 256b3717c23SPeter Maydell } 257b3717c23SPeter Maydell 258b3717c23SPeter Maydell static void iotkit_secctl_ppc_ns_write(IoTKitSecCtlPPC *ppc, uint32_t value) 259b3717c23SPeter Maydell { 260b3717c23SPeter Maydell int i; 261b3717c23SPeter Maydell 262b3717c23SPeter Maydell ppc->ns = value & MAKE_64BIT_MASK(0, ppc->numports); 263b3717c23SPeter Maydell for (i = 0; i < ppc->numports; i++) { 264b3717c23SPeter Maydell qemu_set_irq(ppc->nonsec[i], extract32(ppc->ns, i, 1)); 265b3717c23SPeter Maydell } 266b3717c23SPeter Maydell iotkit_secctl_update_ppc_ap(ppc); 267b3717c23SPeter Maydell } 268b3717c23SPeter Maydell 269b3717c23SPeter Maydell static void iotkit_secctl_ppc_sp_write(IoTKitSecCtlPPC *ppc, uint32_t value) 270b3717c23SPeter Maydell { 271b3717c23SPeter Maydell ppc->sp = value & MAKE_64BIT_MASK(0, ppc->numports); 272b3717c23SPeter Maydell iotkit_secctl_update_ppc_ap(ppc); 273b3717c23SPeter Maydell } 274b3717c23SPeter Maydell 275b3717c23SPeter Maydell static void iotkit_secctl_ppc_nsp_write(IoTKitSecCtlPPC *ppc, uint32_t value) 276b3717c23SPeter Maydell { 277b3717c23SPeter Maydell ppc->nsp = value & MAKE_64BIT_MASK(0, ppc->numports); 278b3717c23SPeter Maydell iotkit_secctl_update_ppc_ap(ppc); 279b3717c23SPeter Maydell } 280b3717c23SPeter Maydell 281b3717c23SPeter Maydell static void iotkit_secctl_ppc_update_irq_clear(IoTKitSecCtlPPC *ppc) 282b3717c23SPeter Maydell { 283b3717c23SPeter Maydell uint32_t value = ppc->parent->secppcintstat; 284b3717c23SPeter Maydell 285b3717c23SPeter Maydell qemu_set_irq(ppc->irq_clear, extract32(value, ppc->irq_bit_offset, 1)); 286b3717c23SPeter Maydell } 287b3717c23SPeter Maydell 288b3717c23SPeter Maydell static void iotkit_secctl_ppc_update_irq_enable(IoTKitSecCtlPPC *ppc) 289b3717c23SPeter Maydell { 290b3717c23SPeter Maydell uint32_t value = ppc->parent->secppcinten; 291b3717c23SPeter Maydell 292b3717c23SPeter Maydell qemu_set_irq(ppc->irq_enable, extract32(value, ppc->irq_bit_offset, 1)); 293b3717c23SPeter Maydell } 294b3717c23SPeter Maydell 29581a75debSPeter Maydell static void iotkit_secctl_update_mscexp_irqs(qemu_irq *msc_irqs, uint32_t value) 29681a75debSPeter Maydell { 29781a75debSPeter Maydell int i; 29881a75debSPeter Maydell 29981a75debSPeter Maydell for (i = 0; i < IOTS_NUM_EXP_MSC; i++) { 30081a75debSPeter Maydell qemu_set_irq(msc_irqs[i], extract32(value, i + 16, 1)); 30181a75debSPeter Maydell } 30281a75debSPeter Maydell } 30381a75debSPeter Maydell 30481a75debSPeter Maydell static void iotkit_secctl_update_msc_irq(IoTKitSecCtl *s) 30581a75debSPeter Maydell { 30681a75debSPeter Maydell /* Update the combined MSC IRQ, based on S_MSCEXP_STATUS and S_MSCEXP_EN */ 30781a75debSPeter Maydell bool level = s->secmscintstat & s->secmscinten; 30881a75debSPeter Maydell 30981a75debSPeter Maydell qemu_set_irq(s->msc_irq, level); 31081a75debSPeter Maydell } 31181a75debSPeter Maydell 312de343bb6SPeter Maydell static MemTxResult iotkit_secctl_s_write(void *opaque, hwaddr addr, 313de343bb6SPeter Maydell uint64_t value, 314de343bb6SPeter Maydell unsigned size, MemTxAttrs attrs) 315de343bb6SPeter Maydell { 316b3717c23SPeter Maydell IoTKitSecCtl *s = IOTKIT_SECCTL(opaque); 317de343bb6SPeter Maydell uint32_t offset = addr; 318b3717c23SPeter Maydell IoTKitSecCtlPPC *ppc; 319de343bb6SPeter Maydell 320de343bb6SPeter Maydell trace_iotkit_secctl_s_write(offset, value, size); 321de343bb6SPeter Maydell 322de343bb6SPeter Maydell if (size != 4) { 323de343bb6SPeter Maydell /* Byte and halfword writes are ignored */ 324de343bb6SPeter Maydell qemu_log_mask(LOG_GUEST_ERROR, 325de343bb6SPeter Maydell "IotKit SecCtl S block write: bad size, ignored\n"); 326de343bb6SPeter Maydell return MEMTX_OK; 327de343bb6SPeter Maydell } 328de343bb6SPeter Maydell 329de343bb6SPeter Maydell switch (offset) { 330b1ce38e1SPeter Maydell case A_NSCCFG: 331b1ce38e1SPeter Maydell s->nsccfg = value & 3; 332b1ce38e1SPeter Maydell qemu_set_irq(s->nsc_cfg_irq, s->nsccfg); 333b1ce38e1SPeter Maydell break; 334de343bb6SPeter Maydell case A_SECRESPCFG: 335b3717c23SPeter Maydell value &= 1; 336b3717c23SPeter Maydell s->secrespcfg = value; 337b3717c23SPeter Maydell qemu_set_irq(s->sec_resp_cfg, s->secrespcfg); 338b3717c23SPeter Maydell break; 339de343bb6SPeter Maydell case A_SECPPCINTCLR: 340b3717c23SPeter Maydell value &= 0x00f000f3; 341b3717c23SPeter Maydell foreach_ppc(s, iotkit_secctl_ppc_update_irq_clear); 342b3717c23SPeter Maydell break; 343de343bb6SPeter Maydell case A_SECPPCINTEN: 344b3717c23SPeter Maydell s->secppcinten = value & 0x00f000f3; 345b3717c23SPeter Maydell foreach_ppc(s, iotkit_secctl_ppc_update_irq_enable); 346b3717c23SPeter Maydell break; 347b1ce38e1SPeter Maydell case A_BRGINTCLR: 348b1ce38e1SPeter Maydell break; 349b1ce38e1SPeter Maydell case A_BRGINTEN: 350b1ce38e1SPeter Maydell s->brginten = value & 0xffff0000; 351b1ce38e1SPeter Maydell break; 352de343bb6SPeter Maydell case A_AHBNSPPCEXP0: 353de343bb6SPeter Maydell case A_AHBNSPPCEXP1: 354de343bb6SPeter Maydell case A_AHBNSPPCEXP2: 355de343bb6SPeter Maydell case A_AHBNSPPCEXP3: 356b3717c23SPeter Maydell ppc = &s->ahbexp[offset_to_ppc_idx(offset)]; 357b3717c23SPeter Maydell iotkit_secctl_ppc_ns_write(ppc, value); 358b3717c23SPeter Maydell break; 359de343bb6SPeter Maydell case A_APBNSPPC0: 360de343bb6SPeter Maydell case A_APBNSPPC1: 361b3717c23SPeter Maydell ppc = &s->apb[offset_to_ppc_idx(offset)]; 362b3717c23SPeter Maydell iotkit_secctl_ppc_ns_write(ppc, value); 363b3717c23SPeter Maydell break; 364de343bb6SPeter Maydell case A_APBNSPPCEXP0: 365de343bb6SPeter Maydell case A_APBNSPPCEXP1: 366de343bb6SPeter Maydell case A_APBNSPPCEXP2: 367de343bb6SPeter Maydell case A_APBNSPPCEXP3: 368b3717c23SPeter Maydell ppc = &s->apbexp[offset_to_ppc_idx(offset)]; 369b3717c23SPeter Maydell iotkit_secctl_ppc_ns_write(ppc, value); 370b3717c23SPeter Maydell break; 371de343bb6SPeter Maydell case A_AHBSPPPCEXP0: 372de343bb6SPeter Maydell case A_AHBSPPPCEXP1: 373de343bb6SPeter Maydell case A_AHBSPPPCEXP2: 374de343bb6SPeter Maydell case A_AHBSPPPCEXP3: 375b3717c23SPeter Maydell ppc = &s->ahbexp[offset_to_ppc_idx(offset)]; 376b3717c23SPeter Maydell iotkit_secctl_ppc_sp_write(ppc, value); 377b3717c23SPeter Maydell break; 378de343bb6SPeter Maydell case A_APBSPPPC0: 379de343bb6SPeter Maydell case A_APBSPPPC1: 380b3717c23SPeter Maydell ppc = &s->apb[offset_to_ppc_idx(offset)]; 381b3717c23SPeter Maydell iotkit_secctl_ppc_sp_write(ppc, value); 382b3717c23SPeter Maydell break; 383de343bb6SPeter Maydell case A_APBSPPPCEXP0: 384de343bb6SPeter Maydell case A_APBSPPPCEXP1: 385de343bb6SPeter Maydell case A_APBSPPPCEXP2: 386de343bb6SPeter Maydell case A_APBSPPPCEXP3: 387b3717c23SPeter Maydell ppc = &s->apbexp[offset_to_ppc_idx(offset)]; 388b3717c23SPeter Maydell iotkit_secctl_ppc_sp_write(ppc, value); 389b3717c23SPeter Maydell break; 390b3717c23SPeter Maydell case A_SECMSCINTCLR: 39181a75debSPeter Maydell iotkit_secctl_update_mscexp_irqs(s->mscexp_clear, value); 39281a75debSPeter Maydell break; 393b3717c23SPeter Maydell case A_SECMSCINTEN: 39481a75debSPeter Maydell s->secmscinten = value; 39581a75debSPeter Maydell iotkit_secctl_update_msc_irq(s); 39681a75debSPeter Maydell break; 39781a75debSPeter Maydell case A_NSMSCEXP: 39881a75debSPeter Maydell s->nsmscexp = value; 39981a75debSPeter Maydell iotkit_secctl_update_mscexp_irqs(s->mscexp_ns, value); 400de343bb6SPeter Maydell break; 401de343bb6SPeter Maydell case A_SECMPCINTSTATUS: 402de343bb6SPeter Maydell case A_SECPPCINTSTAT: 403de343bb6SPeter Maydell case A_SECMSCINTSTAT: 404de343bb6SPeter Maydell case A_BRGINTSTAT: 405de343bb6SPeter Maydell case A_AHBNSPPC0: 406de343bb6SPeter Maydell case A_AHBSPPPC0: 407de343bb6SPeter Maydell case A_PID4: 408de343bb6SPeter Maydell case A_PID5: 409de343bb6SPeter Maydell case A_PID6: 410de343bb6SPeter Maydell case A_PID7: 411de343bb6SPeter Maydell case A_PID0: 412de343bb6SPeter Maydell case A_PID1: 413de343bb6SPeter Maydell case A_PID2: 414de343bb6SPeter Maydell case A_PID3: 415de343bb6SPeter Maydell case A_CID0: 416de343bb6SPeter Maydell case A_CID1: 417de343bb6SPeter Maydell case A_CID2: 418de343bb6SPeter Maydell case A_CID3: 419de343bb6SPeter Maydell qemu_log_mask(LOG_GUEST_ERROR, 420de343bb6SPeter Maydell "IoTKit SecCtl S block write: " 421de343bb6SPeter Maydell "read-only offset 0x%x\n", offset); 422de343bb6SPeter Maydell break; 423de343bb6SPeter Maydell default: 424de343bb6SPeter Maydell qemu_log_mask(LOG_GUEST_ERROR, 425de343bb6SPeter Maydell "IotKit SecCtl S block write: bad offset 0x%x\n", 426de343bb6SPeter Maydell offset); 427de343bb6SPeter Maydell break; 428de343bb6SPeter Maydell } 429de343bb6SPeter Maydell 430de343bb6SPeter Maydell return MEMTX_OK; 431de343bb6SPeter Maydell } 432de343bb6SPeter Maydell 433de343bb6SPeter Maydell static MemTxResult iotkit_secctl_ns_read(void *opaque, hwaddr addr, 434de343bb6SPeter Maydell uint64_t *pdata, 435de343bb6SPeter Maydell unsigned size, MemTxAttrs attrs) 436de343bb6SPeter Maydell { 437b3717c23SPeter Maydell IoTKitSecCtl *s = IOTKIT_SECCTL(opaque); 438de343bb6SPeter Maydell uint64_t r; 439de343bb6SPeter Maydell uint32_t offset = addr & ~0x3; 440de343bb6SPeter Maydell 441de343bb6SPeter Maydell switch (offset) { 442de343bb6SPeter Maydell case A_AHBNSPPPC0: 443de343bb6SPeter Maydell r = 0; 444de343bb6SPeter Maydell break; 445de343bb6SPeter Maydell case A_AHBNSPPPCEXP0: 446de343bb6SPeter Maydell case A_AHBNSPPPCEXP1: 447de343bb6SPeter Maydell case A_AHBNSPPPCEXP2: 448de343bb6SPeter Maydell case A_AHBNSPPPCEXP3: 449b3717c23SPeter Maydell r = s->ahbexp[offset_to_ppc_idx(offset)].nsp; 450b3717c23SPeter Maydell break; 451de343bb6SPeter Maydell case A_APBNSPPPC0: 452de343bb6SPeter Maydell case A_APBNSPPPC1: 453b3717c23SPeter Maydell r = s->apb[offset_to_ppc_idx(offset)].nsp; 454b3717c23SPeter Maydell break; 455de343bb6SPeter Maydell case A_APBNSPPPCEXP0: 456de343bb6SPeter Maydell case A_APBNSPPPCEXP1: 457de343bb6SPeter Maydell case A_APBNSPPPCEXP2: 458de343bb6SPeter Maydell case A_APBNSPPPCEXP3: 459b3717c23SPeter Maydell r = s->apbexp[offset_to_ppc_idx(offset)].nsp; 460de343bb6SPeter Maydell break; 461de343bb6SPeter Maydell case A_PID4: 462de343bb6SPeter Maydell case A_PID5: 463de343bb6SPeter Maydell case A_PID6: 464de343bb6SPeter Maydell case A_PID7: 465de343bb6SPeter Maydell case A_PID0: 466de343bb6SPeter Maydell case A_PID1: 467de343bb6SPeter Maydell case A_PID2: 468de343bb6SPeter Maydell case A_PID3: 469de343bb6SPeter Maydell case A_CID0: 470de343bb6SPeter Maydell case A_CID1: 471de343bb6SPeter Maydell case A_CID2: 472de343bb6SPeter Maydell case A_CID3: 473de343bb6SPeter Maydell r = iotkit_secctl_ns_idregs[(offset - A_PID4) / 4]; 474de343bb6SPeter Maydell break; 475de343bb6SPeter Maydell default: 476de343bb6SPeter Maydell qemu_log_mask(LOG_GUEST_ERROR, 477de343bb6SPeter Maydell "IotKit SecCtl NS block write: bad offset 0x%x\n", 478de343bb6SPeter Maydell offset); 479de343bb6SPeter Maydell r = 0; 480de343bb6SPeter Maydell break; 481de343bb6SPeter Maydell } 482de343bb6SPeter Maydell 483de343bb6SPeter Maydell if (size != 4) { 484de343bb6SPeter Maydell /* None of our registers are access-sensitive, so just pull the right 485de343bb6SPeter Maydell * byte out of the word read result. 486de343bb6SPeter Maydell */ 487de343bb6SPeter Maydell r = extract32(r, (addr & 3) * 8, size * 8); 488de343bb6SPeter Maydell } 489de343bb6SPeter Maydell 490de343bb6SPeter Maydell trace_iotkit_secctl_ns_read(offset, r, size); 491de343bb6SPeter Maydell *pdata = r; 492de343bb6SPeter Maydell return MEMTX_OK; 493de343bb6SPeter Maydell } 494de343bb6SPeter Maydell 495de343bb6SPeter Maydell static MemTxResult iotkit_secctl_ns_write(void *opaque, hwaddr addr, 496de343bb6SPeter Maydell uint64_t value, 497de343bb6SPeter Maydell unsigned size, MemTxAttrs attrs) 498de343bb6SPeter Maydell { 499b3717c23SPeter Maydell IoTKitSecCtl *s = IOTKIT_SECCTL(opaque); 500de343bb6SPeter Maydell uint32_t offset = addr; 501b3717c23SPeter Maydell IoTKitSecCtlPPC *ppc; 502de343bb6SPeter Maydell 503de343bb6SPeter Maydell trace_iotkit_secctl_ns_write(offset, value, size); 504de343bb6SPeter Maydell 505de343bb6SPeter Maydell if (size != 4) { 506de343bb6SPeter Maydell /* Byte and halfword writes are ignored */ 507de343bb6SPeter Maydell qemu_log_mask(LOG_GUEST_ERROR, 508de343bb6SPeter Maydell "IotKit SecCtl NS block write: bad size, ignored\n"); 509de343bb6SPeter Maydell return MEMTX_OK; 510de343bb6SPeter Maydell } 511de343bb6SPeter Maydell 512de343bb6SPeter Maydell switch (offset) { 513de343bb6SPeter Maydell case A_AHBNSPPPCEXP0: 514de343bb6SPeter Maydell case A_AHBNSPPPCEXP1: 515de343bb6SPeter Maydell case A_AHBNSPPPCEXP2: 516de343bb6SPeter Maydell case A_AHBNSPPPCEXP3: 517b3717c23SPeter Maydell ppc = &s->ahbexp[offset_to_ppc_idx(offset)]; 518b3717c23SPeter Maydell iotkit_secctl_ppc_nsp_write(ppc, value); 519b3717c23SPeter Maydell break; 520de343bb6SPeter Maydell case A_APBNSPPPC0: 521de343bb6SPeter Maydell case A_APBNSPPPC1: 522b3717c23SPeter Maydell ppc = &s->apb[offset_to_ppc_idx(offset)]; 523b3717c23SPeter Maydell iotkit_secctl_ppc_nsp_write(ppc, value); 524b3717c23SPeter Maydell break; 525de343bb6SPeter Maydell case A_APBNSPPPCEXP0: 526de343bb6SPeter Maydell case A_APBNSPPPCEXP1: 527de343bb6SPeter Maydell case A_APBNSPPPCEXP2: 528de343bb6SPeter Maydell case A_APBNSPPPCEXP3: 529b3717c23SPeter Maydell ppc = &s->apbexp[offset_to_ppc_idx(offset)]; 530b3717c23SPeter Maydell iotkit_secctl_ppc_nsp_write(ppc, value); 531de343bb6SPeter Maydell break; 532de343bb6SPeter Maydell case A_AHBNSPPPC0: 533de343bb6SPeter Maydell case A_PID4: 534de343bb6SPeter Maydell case A_PID5: 535de343bb6SPeter Maydell case A_PID6: 536de343bb6SPeter Maydell case A_PID7: 537de343bb6SPeter Maydell case A_PID0: 538de343bb6SPeter Maydell case A_PID1: 539de343bb6SPeter Maydell case A_PID2: 540de343bb6SPeter Maydell case A_PID3: 541de343bb6SPeter Maydell case A_CID0: 542de343bb6SPeter Maydell case A_CID1: 543de343bb6SPeter Maydell case A_CID2: 544de343bb6SPeter Maydell case A_CID3: 545de343bb6SPeter Maydell qemu_log_mask(LOG_GUEST_ERROR, 546de343bb6SPeter Maydell "IoTKit SecCtl NS block write: " 547de343bb6SPeter Maydell "read-only offset 0x%x\n", offset); 548de343bb6SPeter Maydell break; 549de343bb6SPeter Maydell default: 550de343bb6SPeter Maydell qemu_log_mask(LOG_GUEST_ERROR, 551de343bb6SPeter Maydell "IotKit SecCtl NS block write: bad offset 0x%x\n", 552de343bb6SPeter Maydell offset); 553de343bb6SPeter Maydell break; 554de343bb6SPeter Maydell } 555de343bb6SPeter Maydell 556de343bb6SPeter Maydell return MEMTX_OK; 557de343bb6SPeter Maydell } 558de343bb6SPeter Maydell 559de343bb6SPeter Maydell static const MemoryRegionOps iotkit_secctl_s_ops = { 560de343bb6SPeter Maydell .read_with_attrs = iotkit_secctl_s_read, 561de343bb6SPeter Maydell .write_with_attrs = iotkit_secctl_s_write, 562de343bb6SPeter Maydell .endianness = DEVICE_LITTLE_ENDIAN, 563de343bb6SPeter Maydell .valid.min_access_size = 1, 564de343bb6SPeter Maydell .valid.max_access_size = 4, 565de343bb6SPeter Maydell .impl.min_access_size = 1, 566de343bb6SPeter Maydell .impl.max_access_size = 4, 567de343bb6SPeter Maydell }; 568de343bb6SPeter Maydell 569de343bb6SPeter Maydell static const MemoryRegionOps iotkit_secctl_ns_ops = { 570de343bb6SPeter Maydell .read_with_attrs = iotkit_secctl_ns_read, 571de343bb6SPeter Maydell .write_with_attrs = iotkit_secctl_ns_write, 572de343bb6SPeter Maydell .endianness = DEVICE_LITTLE_ENDIAN, 573de343bb6SPeter Maydell .valid.min_access_size = 1, 574de343bb6SPeter Maydell .valid.max_access_size = 4, 575de343bb6SPeter Maydell .impl.min_access_size = 1, 576de343bb6SPeter Maydell .impl.max_access_size = 4, 577de343bb6SPeter Maydell }; 578de343bb6SPeter Maydell 579b3717c23SPeter Maydell static void iotkit_secctl_reset_ppc(IoTKitSecCtlPPC *ppc) 580b3717c23SPeter Maydell { 581b3717c23SPeter Maydell ppc->ns = 0; 582b3717c23SPeter Maydell ppc->sp = 0; 583b3717c23SPeter Maydell ppc->nsp = 0; 584b3717c23SPeter Maydell } 585b3717c23SPeter Maydell 586de343bb6SPeter Maydell static void iotkit_secctl_reset(DeviceState *dev) 587de343bb6SPeter Maydell { 588b3717c23SPeter Maydell IoTKitSecCtl *s = IOTKIT_SECCTL(dev); 589de343bb6SPeter Maydell 590b3717c23SPeter Maydell s->secppcintstat = 0; 591b3717c23SPeter Maydell s->secppcinten = 0; 592b3717c23SPeter Maydell s->secrespcfg = 0; 593b1ce38e1SPeter Maydell s->nsccfg = 0; 594b1ce38e1SPeter Maydell s->brginten = 0; 595b3717c23SPeter Maydell 596b3717c23SPeter Maydell foreach_ppc(s, iotkit_secctl_reset_ppc); 597b3717c23SPeter Maydell } 598b3717c23SPeter Maydell 5993fd3cb2fSPeter Maydell static void iotkit_secctl_mpc_status(void *opaque, int n, int level) 6003fd3cb2fSPeter Maydell { 6013fd3cb2fSPeter Maydell IoTKitSecCtl *s = IOTKIT_SECCTL(opaque); 6023fd3cb2fSPeter Maydell 603*0a78d7ebSPeter Maydell s->mpcintstatus = deposit32(s->mpcintstatus, n, 1, !!level); 6043fd3cb2fSPeter Maydell } 6053fd3cb2fSPeter Maydell 6063fd3cb2fSPeter Maydell static void iotkit_secctl_mpcexp_status(void *opaque, int n, int level) 6073fd3cb2fSPeter Maydell { 6083fd3cb2fSPeter Maydell IoTKitSecCtl *s = IOTKIT_SECCTL(opaque); 6093fd3cb2fSPeter Maydell 6103fd3cb2fSPeter Maydell s->mpcintstatus = deposit32(s->mpcintstatus, n + 16, 1, !!level); 6113fd3cb2fSPeter Maydell } 6123fd3cb2fSPeter Maydell 61381a75debSPeter Maydell static void iotkit_secctl_mscexp_status(void *opaque, int n, int level) 61481a75debSPeter Maydell { 61581a75debSPeter Maydell IoTKitSecCtl *s = IOTKIT_SECCTL(opaque); 61681a75debSPeter Maydell 61781a75debSPeter Maydell s->secmscintstat = deposit32(s->secmscintstat, n + 16, 1, !!level); 61881a75debSPeter Maydell iotkit_secctl_update_msc_irq(s); 61981a75debSPeter Maydell } 62081a75debSPeter Maydell 621b3717c23SPeter Maydell static void iotkit_secctl_ppc_irqstatus(void *opaque, int n, int level) 622b3717c23SPeter Maydell { 623b3717c23SPeter Maydell IoTKitSecCtlPPC *ppc = opaque; 624b3717c23SPeter Maydell IoTKitSecCtl *s = IOTKIT_SECCTL(ppc->parent); 625b3717c23SPeter Maydell int irqbit = ppc->irq_bit_offset + n; 626b3717c23SPeter Maydell 627b3717c23SPeter Maydell s->secppcintstat = deposit32(s->secppcintstat, irqbit, 1, level); 628b3717c23SPeter Maydell } 629b3717c23SPeter Maydell 630b3717c23SPeter Maydell static void iotkit_secctl_init_ppc(IoTKitSecCtl *s, 631b3717c23SPeter Maydell IoTKitSecCtlPPC *ppc, 632b3717c23SPeter Maydell const char *name, 633b3717c23SPeter Maydell int numports, 634b3717c23SPeter Maydell int irq_bit_offset) 635b3717c23SPeter Maydell { 636b3717c23SPeter Maydell char *gpioname; 637b3717c23SPeter Maydell DeviceState *dev = DEVICE(s); 638b3717c23SPeter Maydell 639b3717c23SPeter Maydell ppc->numports = numports; 640b3717c23SPeter Maydell ppc->irq_bit_offset = irq_bit_offset; 641b3717c23SPeter Maydell ppc->parent = s; 642b3717c23SPeter Maydell 643b3717c23SPeter Maydell gpioname = g_strdup_printf("%s_nonsec", name); 644b3717c23SPeter Maydell qdev_init_gpio_out_named(dev, ppc->nonsec, gpioname, numports); 645b3717c23SPeter Maydell g_free(gpioname); 646b3717c23SPeter Maydell gpioname = g_strdup_printf("%s_ap", name); 647b3717c23SPeter Maydell qdev_init_gpio_out_named(dev, ppc->ap, gpioname, numports); 648b3717c23SPeter Maydell g_free(gpioname); 649b3717c23SPeter Maydell gpioname = g_strdup_printf("%s_irq_enable", name); 650b3717c23SPeter Maydell qdev_init_gpio_out_named(dev, &ppc->irq_enable, gpioname, 1); 651b3717c23SPeter Maydell g_free(gpioname); 652b3717c23SPeter Maydell gpioname = g_strdup_printf("%s_irq_clear", name); 653b3717c23SPeter Maydell qdev_init_gpio_out_named(dev, &ppc->irq_clear, gpioname, 1); 654b3717c23SPeter Maydell g_free(gpioname); 655b3717c23SPeter Maydell gpioname = g_strdup_printf("%s_irq_status", name); 656b3717c23SPeter Maydell qdev_init_gpio_in_named_with_opaque(dev, iotkit_secctl_ppc_irqstatus, 657b3717c23SPeter Maydell ppc, gpioname, 1); 658b3717c23SPeter Maydell g_free(gpioname); 659de343bb6SPeter Maydell } 660de343bb6SPeter Maydell 661de343bb6SPeter Maydell static void iotkit_secctl_init(Object *obj) 662de343bb6SPeter Maydell { 663de343bb6SPeter Maydell IoTKitSecCtl *s = IOTKIT_SECCTL(obj); 664de343bb6SPeter Maydell SysBusDevice *sbd = SYS_BUS_DEVICE(obj); 665b3717c23SPeter Maydell DeviceState *dev = DEVICE(obj); 666b3717c23SPeter Maydell int i; 667b3717c23SPeter Maydell 668b3717c23SPeter Maydell iotkit_secctl_init_ppc(s, &s->apb[0], "apb_ppc0", 669b3717c23SPeter Maydell IOTS_APB_PPC0_NUM_PORTS, 0); 670b3717c23SPeter Maydell iotkit_secctl_init_ppc(s, &s->apb[1], "apb_ppc1", 671b3717c23SPeter Maydell IOTS_APB_PPC1_NUM_PORTS, 1); 672b3717c23SPeter Maydell 673b3717c23SPeter Maydell for (i = 0; i < IOTS_NUM_APB_EXP_PPC; i++) { 674b3717c23SPeter Maydell IoTKitSecCtlPPC *ppc = &s->apbexp[i]; 675b3717c23SPeter Maydell char *ppcname = g_strdup_printf("apb_ppcexp%d", i); 676b3717c23SPeter Maydell iotkit_secctl_init_ppc(s, ppc, ppcname, IOTS_PPC_NUM_PORTS, 4 + i); 677b3717c23SPeter Maydell g_free(ppcname); 678b3717c23SPeter Maydell } 679b3717c23SPeter Maydell for (i = 0; i < IOTS_NUM_AHB_EXP_PPC; i++) { 680b3717c23SPeter Maydell IoTKitSecCtlPPC *ppc = &s->ahbexp[i]; 681b3717c23SPeter Maydell char *ppcname = g_strdup_printf("ahb_ppcexp%d", i); 682b3717c23SPeter Maydell iotkit_secctl_init_ppc(s, ppc, ppcname, IOTS_PPC_NUM_PORTS, 20 + i); 683b3717c23SPeter Maydell g_free(ppcname); 684b3717c23SPeter Maydell } 685b3717c23SPeter Maydell 686b3717c23SPeter Maydell qdev_init_gpio_out_named(dev, &s->sec_resp_cfg, "sec_resp_cfg", 1); 687b1ce38e1SPeter Maydell qdev_init_gpio_out_named(dev, &s->nsc_cfg_irq, "nsc_cfg", 1); 688de343bb6SPeter Maydell 689*0a78d7ebSPeter Maydell qdev_init_gpio_in_named(dev, iotkit_secctl_mpc_status, "mpc_status", 690*0a78d7ebSPeter Maydell IOTS_NUM_MPC); 6913fd3cb2fSPeter Maydell qdev_init_gpio_in_named(dev, iotkit_secctl_mpcexp_status, 6923fd3cb2fSPeter Maydell "mpcexp_status", IOTS_NUM_EXP_MPC); 6933fd3cb2fSPeter Maydell 69481a75debSPeter Maydell qdev_init_gpio_in_named(dev, iotkit_secctl_mscexp_status, 69581a75debSPeter Maydell "mscexp_status", IOTS_NUM_EXP_MSC); 69681a75debSPeter Maydell qdev_init_gpio_out_named(dev, s->mscexp_clear, "mscexp_clear", 69781a75debSPeter Maydell IOTS_NUM_EXP_MSC); 69881a75debSPeter Maydell qdev_init_gpio_out_named(dev, s->mscexp_ns, "mscexp_ns", 69981a75debSPeter Maydell IOTS_NUM_EXP_MSC); 70081a75debSPeter Maydell qdev_init_gpio_out_named(dev, &s->msc_irq, "msc_irq", 1); 70181a75debSPeter Maydell 702de343bb6SPeter Maydell memory_region_init_io(&s->s_regs, obj, &iotkit_secctl_s_ops, 703de343bb6SPeter Maydell s, "iotkit-secctl-s-regs", 0x1000); 704de343bb6SPeter Maydell memory_region_init_io(&s->ns_regs, obj, &iotkit_secctl_ns_ops, 705de343bb6SPeter Maydell s, "iotkit-secctl-ns-regs", 0x1000); 706de343bb6SPeter Maydell sysbus_init_mmio(sbd, &s->s_regs); 707de343bb6SPeter Maydell sysbus_init_mmio(sbd, &s->ns_regs); 708de343bb6SPeter Maydell } 709de343bb6SPeter Maydell 710b3717c23SPeter Maydell static const VMStateDescription iotkit_secctl_ppc_vmstate = { 711b3717c23SPeter Maydell .name = "iotkit-secctl-ppc", 712b3717c23SPeter Maydell .version_id = 1, 713b3717c23SPeter Maydell .minimum_version_id = 1, 714b3717c23SPeter Maydell .fields = (VMStateField[]) { 715b3717c23SPeter Maydell VMSTATE_UINT32(ns, IoTKitSecCtlPPC), 716b3717c23SPeter Maydell VMSTATE_UINT32(sp, IoTKitSecCtlPPC), 717b3717c23SPeter Maydell VMSTATE_UINT32(nsp, IoTKitSecCtlPPC), 718b3717c23SPeter Maydell VMSTATE_END_OF_LIST() 719b3717c23SPeter Maydell } 720b3717c23SPeter Maydell }; 721b3717c23SPeter Maydell 7223fd3cb2fSPeter Maydell static const VMStateDescription iotkit_secctl_mpcintstatus_vmstate = { 7233fd3cb2fSPeter Maydell .name = "iotkit-secctl-mpcintstatus", 7243fd3cb2fSPeter Maydell .version_id = 1, 7253fd3cb2fSPeter Maydell .minimum_version_id = 1, 7263fd3cb2fSPeter Maydell .fields = (VMStateField[]) { 7273fd3cb2fSPeter Maydell VMSTATE_UINT32(mpcintstatus, IoTKitSecCtl), 7283fd3cb2fSPeter Maydell VMSTATE_END_OF_LIST() 7293fd3cb2fSPeter Maydell } 7303fd3cb2fSPeter Maydell }; 7313fd3cb2fSPeter Maydell 73281a75debSPeter Maydell static bool needed_always(void *opaque) 73381a75debSPeter Maydell { 73481a75debSPeter Maydell return true; 73581a75debSPeter Maydell } 73681a75debSPeter Maydell 73781a75debSPeter Maydell static const VMStateDescription iotkit_secctl_msc_vmstate = { 73881a75debSPeter Maydell .name = "iotkit-secctl/msc", 73981a75debSPeter Maydell .version_id = 1, 74081a75debSPeter Maydell .minimum_version_id = 1, 74181a75debSPeter Maydell .needed = needed_always, 74281a75debSPeter Maydell .fields = (VMStateField[]) { 74381a75debSPeter Maydell VMSTATE_UINT32(secmscintstat, IoTKitSecCtl), 74481a75debSPeter Maydell VMSTATE_UINT32(secmscinten, IoTKitSecCtl), 74581a75debSPeter Maydell VMSTATE_UINT32(nsmscexp, IoTKitSecCtl), 74681a75debSPeter Maydell VMSTATE_END_OF_LIST() 74781a75debSPeter Maydell } 74881a75debSPeter Maydell }; 74981a75debSPeter Maydell 750de343bb6SPeter Maydell static const VMStateDescription iotkit_secctl_vmstate = { 751de343bb6SPeter Maydell .name = "iotkit-secctl", 752de343bb6SPeter Maydell .version_id = 1, 753de343bb6SPeter Maydell .minimum_version_id = 1, 754de343bb6SPeter Maydell .fields = (VMStateField[]) { 755b3717c23SPeter Maydell VMSTATE_UINT32(secppcintstat, IoTKitSecCtl), 756b3717c23SPeter Maydell VMSTATE_UINT32(secppcinten, IoTKitSecCtl), 757b3717c23SPeter Maydell VMSTATE_UINT32(secrespcfg, IoTKitSecCtl), 758b1ce38e1SPeter Maydell VMSTATE_UINT32(nsccfg, IoTKitSecCtl), 759b1ce38e1SPeter Maydell VMSTATE_UINT32(brginten, IoTKitSecCtl), 760b3717c23SPeter Maydell VMSTATE_STRUCT_ARRAY(apb, IoTKitSecCtl, IOTS_NUM_APB_PPC, 1, 761b3717c23SPeter Maydell iotkit_secctl_ppc_vmstate, IoTKitSecCtlPPC), 762b3717c23SPeter Maydell VMSTATE_STRUCT_ARRAY(apbexp, IoTKitSecCtl, IOTS_NUM_APB_EXP_PPC, 1, 763b3717c23SPeter Maydell iotkit_secctl_ppc_vmstate, IoTKitSecCtlPPC), 764b3717c23SPeter Maydell VMSTATE_STRUCT_ARRAY(ahbexp, IoTKitSecCtl, IOTS_NUM_AHB_EXP_PPC, 1, 765b3717c23SPeter Maydell iotkit_secctl_ppc_vmstate, IoTKitSecCtlPPC), 766de343bb6SPeter Maydell VMSTATE_END_OF_LIST() 7673fd3cb2fSPeter Maydell }, 7683fd3cb2fSPeter Maydell .subsections = (const VMStateDescription*[]) { 7693fd3cb2fSPeter Maydell &iotkit_secctl_mpcintstatus_vmstate, 77081a75debSPeter Maydell &iotkit_secctl_msc_vmstate, 7713fd3cb2fSPeter Maydell NULL 7723fd3cb2fSPeter Maydell }, 773de343bb6SPeter Maydell }; 774de343bb6SPeter Maydell 775de343bb6SPeter Maydell static void iotkit_secctl_class_init(ObjectClass *klass, void *data) 776de343bb6SPeter Maydell { 777de343bb6SPeter Maydell DeviceClass *dc = DEVICE_CLASS(klass); 778de343bb6SPeter Maydell 779de343bb6SPeter Maydell dc->vmsd = &iotkit_secctl_vmstate; 780de343bb6SPeter Maydell dc->reset = iotkit_secctl_reset; 781de343bb6SPeter Maydell } 782de343bb6SPeter Maydell 783de343bb6SPeter Maydell static const TypeInfo iotkit_secctl_info = { 784de343bb6SPeter Maydell .name = TYPE_IOTKIT_SECCTL, 785de343bb6SPeter Maydell .parent = TYPE_SYS_BUS_DEVICE, 786de343bb6SPeter Maydell .instance_size = sizeof(IoTKitSecCtl), 787de343bb6SPeter Maydell .instance_init = iotkit_secctl_init, 788de343bb6SPeter Maydell .class_init = iotkit_secctl_class_init, 789de343bb6SPeter Maydell }; 790de343bb6SPeter Maydell 791de343bb6SPeter Maydell static void iotkit_secctl_register_types(void) 792de343bb6SPeter Maydell { 793de343bb6SPeter Maydell type_register_static(&iotkit_secctl_info); 794de343bb6SPeter Maydell } 795de343bb6SPeter Maydell 796de343bb6SPeter Maydell type_init(iotkit_secctl_register_types); 797