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