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; 142*3fd3cb2fSPeter Maydell case A_SECMPCINTSTATUS: 143*3fd3cb2fSPeter Maydell r = s->mpcintstatus; 144*3fd3cb2fSPeter 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: 193b3717c23SPeter Maydell case A_SECMSCINTEN: 194de343bb6SPeter Maydell case A_NSMSCEXP: 195de343bb6SPeter Maydell qemu_log_mask(LOG_UNIMP, 196de343bb6SPeter Maydell "IoTKit SecCtl S block read: " 197de343bb6SPeter Maydell "unimplemented offset 0x%x\n", offset); 198de343bb6SPeter Maydell r = 0; 199de343bb6SPeter Maydell break; 200de343bb6SPeter Maydell case A_PID4: 201de343bb6SPeter Maydell case A_PID5: 202de343bb6SPeter Maydell case A_PID6: 203de343bb6SPeter Maydell case A_PID7: 204de343bb6SPeter Maydell case A_PID0: 205de343bb6SPeter Maydell case A_PID1: 206de343bb6SPeter Maydell case A_PID2: 207de343bb6SPeter Maydell case A_PID3: 208de343bb6SPeter Maydell case A_CID0: 209de343bb6SPeter Maydell case A_CID1: 210de343bb6SPeter Maydell case A_CID2: 211de343bb6SPeter Maydell case A_CID3: 212de343bb6SPeter Maydell r = iotkit_secctl_s_idregs[(offset - A_PID4) / 4]; 213de343bb6SPeter Maydell break; 214de343bb6SPeter Maydell case A_SECPPCINTCLR: 215de343bb6SPeter Maydell case A_SECMSCINTCLR: 216de343bb6SPeter Maydell case A_BRGINTCLR: 217de343bb6SPeter Maydell qemu_log_mask(LOG_GUEST_ERROR, 218de343bb6SPeter Maydell "IotKit SecCtl S block read: write-only offset 0x%x\n", 219de343bb6SPeter Maydell offset); 220de343bb6SPeter Maydell r = 0; 221de343bb6SPeter Maydell break; 222de343bb6SPeter Maydell default: 223de343bb6SPeter Maydell qemu_log_mask(LOG_GUEST_ERROR, 224de343bb6SPeter Maydell "IotKit SecCtl S block read: bad offset 0x%x\n", offset); 225de343bb6SPeter Maydell r = 0; 226de343bb6SPeter Maydell break; 227de343bb6SPeter Maydell } 228de343bb6SPeter Maydell 229de343bb6SPeter Maydell if (size != 4) { 230de343bb6SPeter Maydell /* None of our registers are access-sensitive, so just pull the right 231de343bb6SPeter Maydell * byte out of the word read result. 232de343bb6SPeter Maydell */ 233de343bb6SPeter Maydell r = extract32(r, (addr & 3) * 8, size * 8); 234de343bb6SPeter Maydell } 235de343bb6SPeter Maydell 236de343bb6SPeter Maydell trace_iotkit_secctl_s_read(offset, r, size); 237de343bb6SPeter Maydell *pdata = r; 238de343bb6SPeter Maydell return MEMTX_OK; 239de343bb6SPeter Maydell } 240de343bb6SPeter Maydell 241b3717c23SPeter Maydell static void iotkit_secctl_update_ppc_ap(IoTKitSecCtlPPC *ppc) 242b3717c23SPeter Maydell { 243b3717c23SPeter Maydell int i; 244b3717c23SPeter Maydell 245b3717c23SPeter Maydell for (i = 0; i < ppc->numports; i++) { 246b3717c23SPeter Maydell bool v; 247b3717c23SPeter Maydell 248b3717c23SPeter Maydell if (extract32(ppc->ns, i, 1)) { 249b3717c23SPeter Maydell v = extract32(ppc->nsp, i, 1); 250b3717c23SPeter Maydell } else { 251b3717c23SPeter Maydell v = extract32(ppc->sp, i, 1); 252b3717c23SPeter Maydell } 253b3717c23SPeter Maydell qemu_set_irq(ppc->ap[i], v); 254b3717c23SPeter Maydell } 255b3717c23SPeter Maydell } 256b3717c23SPeter Maydell 257b3717c23SPeter Maydell static void iotkit_secctl_ppc_ns_write(IoTKitSecCtlPPC *ppc, uint32_t value) 258b3717c23SPeter Maydell { 259b3717c23SPeter Maydell int i; 260b3717c23SPeter Maydell 261b3717c23SPeter Maydell ppc->ns = value & MAKE_64BIT_MASK(0, ppc->numports); 262b3717c23SPeter Maydell for (i = 0; i < ppc->numports; i++) { 263b3717c23SPeter Maydell qemu_set_irq(ppc->nonsec[i], extract32(ppc->ns, i, 1)); 264b3717c23SPeter Maydell } 265b3717c23SPeter Maydell iotkit_secctl_update_ppc_ap(ppc); 266b3717c23SPeter Maydell } 267b3717c23SPeter Maydell 268b3717c23SPeter Maydell static void iotkit_secctl_ppc_sp_write(IoTKitSecCtlPPC *ppc, uint32_t value) 269b3717c23SPeter Maydell { 270b3717c23SPeter Maydell ppc->sp = value & MAKE_64BIT_MASK(0, ppc->numports); 271b3717c23SPeter Maydell iotkit_secctl_update_ppc_ap(ppc); 272b3717c23SPeter Maydell } 273b3717c23SPeter Maydell 274b3717c23SPeter Maydell static void iotkit_secctl_ppc_nsp_write(IoTKitSecCtlPPC *ppc, uint32_t value) 275b3717c23SPeter Maydell { 276b3717c23SPeter Maydell ppc->nsp = value & MAKE_64BIT_MASK(0, ppc->numports); 277b3717c23SPeter Maydell iotkit_secctl_update_ppc_ap(ppc); 278b3717c23SPeter Maydell } 279b3717c23SPeter Maydell 280b3717c23SPeter Maydell static void iotkit_secctl_ppc_update_irq_clear(IoTKitSecCtlPPC *ppc) 281b3717c23SPeter Maydell { 282b3717c23SPeter Maydell uint32_t value = ppc->parent->secppcintstat; 283b3717c23SPeter Maydell 284b3717c23SPeter Maydell qemu_set_irq(ppc->irq_clear, extract32(value, ppc->irq_bit_offset, 1)); 285b3717c23SPeter Maydell } 286b3717c23SPeter Maydell 287b3717c23SPeter Maydell static void iotkit_secctl_ppc_update_irq_enable(IoTKitSecCtlPPC *ppc) 288b3717c23SPeter Maydell { 289b3717c23SPeter Maydell uint32_t value = ppc->parent->secppcinten; 290b3717c23SPeter Maydell 291b3717c23SPeter Maydell qemu_set_irq(ppc->irq_enable, extract32(value, ppc->irq_bit_offset, 1)); 292b3717c23SPeter Maydell } 293b3717c23SPeter Maydell 294de343bb6SPeter Maydell static MemTxResult iotkit_secctl_s_write(void *opaque, hwaddr addr, 295de343bb6SPeter Maydell uint64_t value, 296de343bb6SPeter Maydell unsigned size, MemTxAttrs attrs) 297de343bb6SPeter Maydell { 298b3717c23SPeter Maydell IoTKitSecCtl *s = IOTKIT_SECCTL(opaque); 299de343bb6SPeter Maydell uint32_t offset = addr; 300b3717c23SPeter Maydell IoTKitSecCtlPPC *ppc; 301de343bb6SPeter Maydell 302de343bb6SPeter Maydell trace_iotkit_secctl_s_write(offset, value, size); 303de343bb6SPeter Maydell 304de343bb6SPeter Maydell if (size != 4) { 305de343bb6SPeter Maydell /* Byte and halfword writes are ignored */ 306de343bb6SPeter Maydell qemu_log_mask(LOG_GUEST_ERROR, 307de343bb6SPeter Maydell "IotKit SecCtl S block write: bad size, ignored\n"); 308de343bb6SPeter Maydell return MEMTX_OK; 309de343bb6SPeter Maydell } 310de343bb6SPeter Maydell 311de343bb6SPeter Maydell switch (offset) { 312b1ce38e1SPeter Maydell case A_NSCCFG: 313b1ce38e1SPeter Maydell s->nsccfg = value & 3; 314b1ce38e1SPeter Maydell qemu_set_irq(s->nsc_cfg_irq, s->nsccfg); 315b1ce38e1SPeter Maydell break; 316de343bb6SPeter Maydell case A_SECRESPCFG: 317b3717c23SPeter Maydell value &= 1; 318b3717c23SPeter Maydell s->secrespcfg = value; 319b3717c23SPeter Maydell qemu_set_irq(s->sec_resp_cfg, s->secrespcfg); 320b3717c23SPeter Maydell break; 321de343bb6SPeter Maydell case A_SECPPCINTCLR: 322b3717c23SPeter Maydell value &= 0x00f000f3; 323b3717c23SPeter Maydell foreach_ppc(s, iotkit_secctl_ppc_update_irq_clear); 324b3717c23SPeter Maydell break; 325de343bb6SPeter Maydell case A_SECPPCINTEN: 326b3717c23SPeter Maydell s->secppcinten = value & 0x00f000f3; 327b3717c23SPeter Maydell foreach_ppc(s, iotkit_secctl_ppc_update_irq_enable); 328b3717c23SPeter Maydell break; 329b1ce38e1SPeter Maydell case A_BRGINTCLR: 330b1ce38e1SPeter Maydell break; 331b1ce38e1SPeter Maydell case A_BRGINTEN: 332b1ce38e1SPeter Maydell s->brginten = value & 0xffff0000; 333b1ce38e1SPeter Maydell break; 334de343bb6SPeter Maydell case A_AHBNSPPCEXP0: 335de343bb6SPeter Maydell case A_AHBNSPPCEXP1: 336de343bb6SPeter Maydell case A_AHBNSPPCEXP2: 337de343bb6SPeter Maydell case A_AHBNSPPCEXP3: 338b3717c23SPeter Maydell ppc = &s->ahbexp[offset_to_ppc_idx(offset)]; 339b3717c23SPeter Maydell iotkit_secctl_ppc_ns_write(ppc, value); 340b3717c23SPeter Maydell break; 341de343bb6SPeter Maydell case A_APBNSPPC0: 342de343bb6SPeter Maydell case A_APBNSPPC1: 343b3717c23SPeter Maydell ppc = &s->apb[offset_to_ppc_idx(offset)]; 344b3717c23SPeter Maydell iotkit_secctl_ppc_ns_write(ppc, value); 345b3717c23SPeter Maydell break; 346de343bb6SPeter Maydell case A_APBNSPPCEXP0: 347de343bb6SPeter Maydell case A_APBNSPPCEXP1: 348de343bb6SPeter Maydell case A_APBNSPPCEXP2: 349de343bb6SPeter Maydell case A_APBNSPPCEXP3: 350b3717c23SPeter Maydell ppc = &s->apbexp[offset_to_ppc_idx(offset)]; 351b3717c23SPeter Maydell iotkit_secctl_ppc_ns_write(ppc, value); 352b3717c23SPeter Maydell break; 353de343bb6SPeter Maydell case A_AHBSPPPCEXP0: 354de343bb6SPeter Maydell case A_AHBSPPPCEXP1: 355de343bb6SPeter Maydell case A_AHBSPPPCEXP2: 356de343bb6SPeter Maydell case A_AHBSPPPCEXP3: 357b3717c23SPeter Maydell ppc = &s->ahbexp[offset_to_ppc_idx(offset)]; 358b3717c23SPeter Maydell iotkit_secctl_ppc_sp_write(ppc, value); 359b3717c23SPeter Maydell break; 360de343bb6SPeter Maydell case A_APBSPPPC0: 361de343bb6SPeter Maydell case A_APBSPPPC1: 362b3717c23SPeter Maydell ppc = &s->apb[offset_to_ppc_idx(offset)]; 363b3717c23SPeter Maydell iotkit_secctl_ppc_sp_write(ppc, value); 364b3717c23SPeter Maydell break; 365de343bb6SPeter Maydell case A_APBSPPPCEXP0: 366de343bb6SPeter Maydell case A_APBSPPPCEXP1: 367de343bb6SPeter Maydell case A_APBSPPPCEXP2: 368de343bb6SPeter Maydell case A_APBSPPPCEXP3: 369b3717c23SPeter Maydell ppc = &s->apbexp[offset_to_ppc_idx(offset)]; 370b3717c23SPeter Maydell iotkit_secctl_ppc_sp_write(ppc, value); 371b3717c23SPeter Maydell break; 372b3717c23SPeter Maydell case A_SECMSCINTCLR: 373b3717c23SPeter Maydell case A_SECMSCINTEN: 374de343bb6SPeter Maydell qemu_log_mask(LOG_UNIMP, 375de343bb6SPeter Maydell "IoTKit SecCtl S block write: " 376de343bb6SPeter Maydell "unimplemented offset 0x%x\n", offset); 377de343bb6SPeter Maydell break; 378de343bb6SPeter Maydell case A_SECMPCINTSTATUS: 379de343bb6SPeter Maydell case A_SECPPCINTSTAT: 380de343bb6SPeter Maydell case A_SECMSCINTSTAT: 381de343bb6SPeter Maydell case A_BRGINTSTAT: 382de343bb6SPeter Maydell case A_AHBNSPPC0: 383de343bb6SPeter Maydell case A_AHBSPPPC0: 384de343bb6SPeter Maydell case A_NSMSCEXP: 385de343bb6SPeter Maydell case A_PID4: 386de343bb6SPeter Maydell case A_PID5: 387de343bb6SPeter Maydell case A_PID6: 388de343bb6SPeter Maydell case A_PID7: 389de343bb6SPeter Maydell case A_PID0: 390de343bb6SPeter Maydell case A_PID1: 391de343bb6SPeter Maydell case A_PID2: 392de343bb6SPeter Maydell case A_PID3: 393de343bb6SPeter Maydell case A_CID0: 394de343bb6SPeter Maydell case A_CID1: 395de343bb6SPeter Maydell case A_CID2: 396de343bb6SPeter Maydell case A_CID3: 397de343bb6SPeter Maydell qemu_log_mask(LOG_GUEST_ERROR, 398de343bb6SPeter Maydell "IoTKit SecCtl S block write: " 399de343bb6SPeter Maydell "read-only offset 0x%x\n", offset); 400de343bb6SPeter Maydell break; 401de343bb6SPeter Maydell default: 402de343bb6SPeter Maydell qemu_log_mask(LOG_GUEST_ERROR, 403de343bb6SPeter Maydell "IotKit SecCtl S block write: bad offset 0x%x\n", 404de343bb6SPeter Maydell offset); 405de343bb6SPeter Maydell break; 406de343bb6SPeter Maydell } 407de343bb6SPeter Maydell 408de343bb6SPeter Maydell return MEMTX_OK; 409de343bb6SPeter Maydell } 410de343bb6SPeter Maydell 411de343bb6SPeter Maydell static MemTxResult iotkit_secctl_ns_read(void *opaque, hwaddr addr, 412de343bb6SPeter Maydell uint64_t *pdata, 413de343bb6SPeter Maydell unsigned size, MemTxAttrs attrs) 414de343bb6SPeter Maydell { 415b3717c23SPeter Maydell IoTKitSecCtl *s = IOTKIT_SECCTL(opaque); 416de343bb6SPeter Maydell uint64_t r; 417de343bb6SPeter Maydell uint32_t offset = addr & ~0x3; 418de343bb6SPeter Maydell 419de343bb6SPeter Maydell switch (offset) { 420de343bb6SPeter Maydell case A_AHBNSPPPC0: 421de343bb6SPeter Maydell r = 0; 422de343bb6SPeter Maydell break; 423de343bb6SPeter Maydell case A_AHBNSPPPCEXP0: 424de343bb6SPeter Maydell case A_AHBNSPPPCEXP1: 425de343bb6SPeter Maydell case A_AHBNSPPPCEXP2: 426de343bb6SPeter Maydell case A_AHBNSPPPCEXP3: 427b3717c23SPeter Maydell r = s->ahbexp[offset_to_ppc_idx(offset)].nsp; 428b3717c23SPeter Maydell break; 429de343bb6SPeter Maydell case A_APBNSPPPC0: 430de343bb6SPeter Maydell case A_APBNSPPPC1: 431b3717c23SPeter Maydell r = s->apb[offset_to_ppc_idx(offset)].nsp; 432b3717c23SPeter Maydell break; 433de343bb6SPeter Maydell case A_APBNSPPPCEXP0: 434de343bb6SPeter Maydell case A_APBNSPPPCEXP1: 435de343bb6SPeter Maydell case A_APBNSPPPCEXP2: 436de343bb6SPeter Maydell case A_APBNSPPPCEXP3: 437b3717c23SPeter Maydell r = s->apbexp[offset_to_ppc_idx(offset)].nsp; 438de343bb6SPeter Maydell break; 439de343bb6SPeter Maydell case A_PID4: 440de343bb6SPeter Maydell case A_PID5: 441de343bb6SPeter Maydell case A_PID6: 442de343bb6SPeter Maydell case A_PID7: 443de343bb6SPeter Maydell case A_PID0: 444de343bb6SPeter Maydell case A_PID1: 445de343bb6SPeter Maydell case A_PID2: 446de343bb6SPeter Maydell case A_PID3: 447de343bb6SPeter Maydell case A_CID0: 448de343bb6SPeter Maydell case A_CID1: 449de343bb6SPeter Maydell case A_CID2: 450de343bb6SPeter Maydell case A_CID3: 451de343bb6SPeter Maydell r = iotkit_secctl_ns_idregs[(offset - A_PID4) / 4]; 452de343bb6SPeter Maydell break; 453de343bb6SPeter Maydell default: 454de343bb6SPeter Maydell qemu_log_mask(LOG_GUEST_ERROR, 455de343bb6SPeter Maydell "IotKit SecCtl NS block write: bad offset 0x%x\n", 456de343bb6SPeter Maydell offset); 457de343bb6SPeter Maydell r = 0; 458de343bb6SPeter Maydell break; 459de343bb6SPeter Maydell } 460de343bb6SPeter Maydell 461de343bb6SPeter Maydell if (size != 4) { 462de343bb6SPeter Maydell /* None of our registers are access-sensitive, so just pull the right 463de343bb6SPeter Maydell * byte out of the word read result. 464de343bb6SPeter Maydell */ 465de343bb6SPeter Maydell r = extract32(r, (addr & 3) * 8, size * 8); 466de343bb6SPeter Maydell } 467de343bb6SPeter Maydell 468de343bb6SPeter Maydell trace_iotkit_secctl_ns_read(offset, r, size); 469de343bb6SPeter Maydell *pdata = r; 470de343bb6SPeter Maydell return MEMTX_OK; 471de343bb6SPeter Maydell } 472de343bb6SPeter Maydell 473de343bb6SPeter Maydell static MemTxResult iotkit_secctl_ns_write(void *opaque, hwaddr addr, 474de343bb6SPeter Maydell uint64_t value, 475de343bb6SPeter Maydell unsigned size, MemTxAttrs attrs) 476de343bb6SPeter Maydell { 477b3717c23SPeter Maydell IoTKitSecCtl *s = IOTKIT_SECCTL(opaque); 478de343bb6SPeter Maydell uint32_t offset = addr; 479b3717c23SPeter Maydell IoTKitSecCtlPPC *ppc; 480de343bb6SPeter Maydell 481de343bb6SPeter Maydell trace_iotkit_secctl_ns_write(offset, value, size); 482de343bb6SPeter Maydell 483de343bb6SPeter Maydell if (size != 4) { 484de343bb6SPeter Maydell /* Byte and halfword writes are ignored */ 485de343bb6SPeter Maydell qemu_log_mask(LOG_GUEST_ERROR, 486de343bb6SPeter Maydell "IotKit SecCtl NS block write: bad size, ignored\n"); 487de343bb6SPeter Maydell return MEMTX_OK; 488de343bb6SPeter Maydell } 489de343bb6SPeter Maydell 490de343bb6SPeter Maydell switch (offset) { 491de343bb6SPeter Maydell case A_AHBNSPPPCEXP0: 492de343bb6SPeter Maydell case A_AHBNSPPPCEXP1: 493de343bb6SPeter Maydell case A_AHBNSPPPCEXP2: 494de343bb6SPeter Maydell case A_AHBNSPPPCEXP3: 495b3717c23SPeter Maydell ppc = &s->ahbexp[offset_to_ppc_idx(offset)]; 496b3717c23SPeter Maydell iotkit_secctl_ppc_nsp_write(ppc, value); 497b3717c23SPeter Maydell break; 498de343bb6SPeter Maydell case A_APBNSPPPC0: 499de343bb6SPeter Maydell case A_APBNSPPPC1: 500b3717c23SPeter Maydell ppc = &s->apb[offset_to_ppc_idx(offset)]; 501b3717c23SPeter Maydell iotkit_secctl_ppc_nsp_write(ppc, value); 502b3717c23SPeter Maydell break; 503de343bb6SPeter Maydell case A_APBNSPPPCEXP0: 504de343bb6SPeter Maydell case A_APBNSPPPCEXP1: 505de343bb6SPeter Maydell case A_APBNSPPPCEXP2: 506de343bb6SPeter Maydell case A_APBNSPPPCEXP3: 507b3717c23SPeter Maydell ppc = &s->apbexp[offset_to_ppc_idx(offset)]; 508b3717c23SPeter Maydell iotkit_secctl_ppc_nsp_write(ppc, value); 509de343bb6SPeter Maydell break; 510de343bb6SPeter Maydell case A_AHBNSPPPC0: 511de343bb6SPeter Maydell case A_PID4: 512de343bb6SPeter Maydell case A_PID5: 513de343bb6SPeter Maydell case A_PID6: 514de343bb6SPeter Maydell case A_PID7: 515de343bb6SPeter Maydell case A_PID0: 516de343bb6SPeter Maydell case A_PID1: 517de343bb6SPeter Maydell case A_PID2: 518de343bb6SPeter Maydell case A_PID3: 519de343bb6SPeter Maydell case A_CID0: 520de343bb6SPeter Maydell case A_CID1: 521de343bb6SPeter Maydell case A_CID2: 522de343bb6SPeter Maydell case A_CID3: 523de343bb6SPeter Maydell qemu_log_mask(LOG_GUEST_ERROR, 524de343bb6SPeter Maydell "IoTKit SecCtl NS block write: " 525de343bb6SPeter Maydell "read-only offset 0x%x\n", offset); 526de343bb6SPeter Maydell break; 527de343bb6SPeter Maydell default: 528de343bb6SPeter Maydell qemu_log_mask(LOG_GUEST_ERROR, 529de343bb6SPeter Maydell "IotKit SecCtl NS block write: bad offset 0x%x\n", 530de343bb6SPeter Maydell offset); 531de343bb6SPeter Maydell break; 532de343bb6SPeter Maydell } 533de343bb6SPeter Maydell 534de343bb6SPeter Maydell return MEMTX_OK; 535de343bb6SPeter Maydell } 536de343bb6SPeter Maydell 537de343bb6SPeter Maydell static const MemoryRegionOps iotkit_secctl_s_ops = { 538de343bb6SPeter Maydell .read_with_attrs = iotkit_secctl_s_read, 539de343bb6SPeter Maydell .write_with_attrs = iotkit_secctl_s_write, 540de343bb6SPeter Maydell .endianness = DEVICE_LITTLE_ENDIAN, 541de343bb6SPeter Maydell .valid.min_access_size = 1, 542de343bb6SPeter Maydell .valid.max_access_size = 4, 543de343bb6SPeter Maydell .impl.min_access_size = 1, 544de343bb6SPeter Maydell .impl.max_access_size = 4, 545de343bb6SPeter Maydell }; 546de343bb6SPeter Maydell 547de343bb6SPeter Maydell static const MemoryRegionOps iotkit_secctl_ns_ops = { 548de343bb6SPeter Maydell .read_with_attrs = iotkit_secctl_ns_read, 549de343bb6SPeter Maydell .write_with_attrs = iotkit_secctl_ns_write, 550de343bb6SPeter Maydell .endianness = DEVICE_LITTLE_ENDIAN, 551de343bb6SPeter Maydell .valid.min_access_size = 1, 552de343bb6SPeter Maydell .valid.max_access_size = 4, 553de343bb6SPeter Maydell .impl.min_access_size = 1, 554de343bb6SPeter Maydell .impl.max_access_size = 4, 555de343bb6SPeter Maydell }; 556de343bb6SPeter Maydell 557b3717c23SPeter Maydell static void iotkit_secctl_reset_ppc(IoTKitSecCtlPPC *ppc) 558b3717c23SPeter Maydell { 559b3717c23SPeter Maydell ppc->ns = 0; 560b3717c23SPeter Maydell ppc->sp = 0; 561b3717c23SPeter Maydell ppc->nsp = 0; 562b3717c23SPeter Maydell } 563b3717c23SPeter Maydell 564de343bb6SPeter Maydell static void iotkit_secctl_reset(DeviceState *dev) 565de343bb6SPeter Maydell { 566b3717c23SPeter Maydell IoTKitSecCtl *s = IOTKIT_SECCTL(dev); 567de343bb6SPeter Maydell 568b3717c23SPeter Maydell s->secppcintstat = 0; 569b3717c23SPeter Maydell s->secppcinten = 0; 570b3717c23SPeter Maydell s->secrespcfg = 0; 571b1ce38e1SPeter Maydell s->nsccfg = 0; 572b1ce38e1SPeter Maydell s->brginten = 0; 573b3717c23SPeter Maydell 574b3717c23SPeter Maydell foreach_ppc(s, iotkit_secctl_reset_ppc); 575b3717c23SPeter Maydell } 576b3717c23SPeter Maydell 577*3fd3cb2fSPeter Maydell static void iotkit_secctl_mpc_status(void *opaque, int n, int level) 578*3fd3cb2fSPeter Maydell { 579*3fd3cb2fSPeter Maydell IoTKitSecCtl *s = IOTKIT_SECCTL(opaque); 580*3fd3cb2fSPeter Maydell 581*3fd3cb2fSPeter Maydell s->mpcintstatus = deposit32(s->mpcintstatus, 0, 1, !!level); 582*3fd3cb2fSPeter Maydell } 583*3fd3cb2fSPeter Maydell 584*3fd3cb2fSPeter Maydell static void iotkit_secctl_mpcexp_status(void *opaque, int n, int level) 585*3fd3cb2fSPeter Maydell { 586*3fd3cb2fSPeter Maydell IoTKitSecCtl *s = IOTKIT_SECCTL(opaque); 587*3fd3cb2fSPeter Maydell 588*3fd3cb2fSPeter Maydell s->mpcintstatus = deposit32(s->mpcintstatus, n + 16, 1, !!level); 589*3fd3cb2fSPeter Maydell } 590*3fd3cb2fSPeter Maydell 591b3717c23SPeter Maydell static void iotkit_secctl_ppc_irqstatus(void *opaque, int n, int level) 592b3717c23SPeter Maydell { 593b3717c23SPeter Maydell IoTKitSecCtlPPC *ppc = opaque; 594b3717c23SPeter Maydell IoTKitSecCtl *s = IOTKIT_SECCTL(ppc->parent); 595b3717c23SPeter Maydell int irqbit = ppc->irq_bit_offset + n; 596b3717c23SPeter Maydell 597b3717c23SPeter Maydell s->secppcintstat = deposit32(s->secppcintstat, irqbit, 1, level); 598b3717c23SPeter Maydell } 599b3717c23SPeter Maydell 600b3717c23SPeter Maydell static void iotkit_secctl_init_ppc(IoTKitSecCtl *s, 601b3717c23SPeter Maydell IoTKitSecCtlPPC *ppc, 602b3717c23SPeter Maydell const char *name, 603b3717c23SPeter Maydell int numports, 604b3717c23SPeter Maydell int irq_bit_offset) 605b3717c23SPeter Maydell { 606b3717c23SPeter Maydell char *gpioname; 607b3717c23SPeter Maydell DeviceState *dev = DEVICE(s); 608b3717c23SPeter Maydell 609b3717c23SPeter Maydell ppc->numports = numports; 610b3717c23SPeter Maydell ppc->irq_bit_offset = irq_bit_offset; 611b3717c23SPeter Maydell ppc->parent = s; 612b3717c23SPeter Maydell 613b3717c23SPeter Maydell gpioname = g_strdup_printf("%s_nonsec", name); 614b3717c23SPeter Maydell qdev_init_gpio_out_named(dev, ppc->nonsec, gpioname, numports); 615b3717c23SPeter Maydell g_free(gpioname); 616b3717c23SPeter Maydell gpioname = g_strdup_printf("%s_ap", name); 617b3717c23SPeter Maydell qdev_init_gpio_out_named(dev, ppc->ap, gpioname, numports); 618b3717c23SPeter Maydell g_free(gpioname); 619b3717c23SPeter Maydell gpioname = g_strdup_printf("%s_irq_enable", name); 620b3717c23SPeter Maydell qdev_init_gpio_out_named(dev, &ppc->irq_enable, gpioname, 1); 621b3717c23SPeter Maydell g_free(gpioname); 622b3717c23SPeter Maydell gpioname = g_strdup_printf("%s_irq_clear", name); 623b3717c23SPeter Maydell qdev_init_gpio_out_named(dev, &ppc->irq_clear, gpioname, 1); 624b3717c23SPeter Maydell g_free(gpioname); 625b3717c23SPeter Maydell gpioname = g_strdup_printf("%s_irq_status", name); 626b3717c23SPeter Maydell qdev_init_gpio_in_named_with_opaque(dev, iotkit_secctl_ppc_irqstatus, 627b3717c23SPeter Maydell ppc, gpioname, 1); 628b3717c23SPeter Maydell g_free(gpioname); 629de343bb6SPeter Maydell } 630de343bb6SPeter Maydell 631de343bb6SPeter Maydell static void iotkit_secctl_init(Object *obj) 632de343bb6SPeter Maydell { 633de343bb6SPeter Maydell IoTKitSecCtl *s = IOTKIT_SECCTL(obj); 634de343bb6SPeter Maydell SysBusDevice *sbd = SYS_BUS_DEVICE(obj); 635b3717c23SPeter Maydell DeviceState *dev = DEVICE(obj); 636b3717c23SPeter Maydell int i; 637b3717c23SPeter Maydell 638b3717c23SPeter Maydell iotkit_secctl_init_ppc(s, &s->apb[0], "apb_ppc0", 639b3717c23SPeter Maydell IOTS_APB_PPC0_NUM_PORTS, 0); 640b3717c23SPeter Maydell iotkit_secctl_init_ppc(s, &s->apb[1], "apb_ppc1", 641b3717c23SPeter Maydell IOTS_APB_PPC1_NUM_PORTS, 1); 642b3717c23SPeter Maydell 643b3717c23SPeter Maydell for (i = 0; i < IOTS_NUM_APB_EXP_PPC; i++) { 644b3717c23SPeter Maydell IoTKitSecCtlPPC *ppc = &s->apbexp[i]; 645b3717c23SPeter Maydell char *ppcname = g_strdup_printf("apb_ppcexp%d", i); 646b3717c23SPeter Maydell iotkit_secctl_init_ppc(s, ppc, ppcname, IOTS_PPC_NUM_PORTS, 4 + i); 647b3717c23SPeter Maydell g_free(ppcname); 648b3717c23SPeter Maydell } 649b3717c23SPeter Maydell for (i = 0; i < IOTS_NUM_AHB_EXP_PPC; i++) { 650b3717c23SPeter Maydell IoTKitSecCtlPPC *ppc = &s->ahbexp[i]; 651b3717c23SPeter Maydell char *ppcname = g_strdup_printf("ahb_ppcexp%d", i); 652b3717c23SPeter Maydell iotkit_secctl_init_ppc(s, ppc, ppcname, IOTS_PPC_NUM_PORTS, 20 + i); 653b3717c23SPeter Maydell g_free(ppcname); 654b3717c23SPeter Maydell } 655b3717c23SPeter Maydell 656b3717c23SPeter Maydell qdev_init_gpio_out_named(dev, &s->sec_resp_cfg, "sec_resp_cfg", 1); 657b1ce38e1SPeter Maydell qdev_init_gpio_out_named(dev, &s->nsc_cfg_irq, "nsc_cfg", 1); 658de343bb6SPeter Maydell 659*3fd3cb2fSPeter Maydell qdev_init_gpio_in_named(dev, iotkit_secctl_mpc_status, "mpc_status", 1); 660*3fd3cb2fSPeter Maydell qdev_init_gpio_in_named(dev, iotkit_secctl_mpcexp_status, 661*3fd3cb2fSPeter Maydell "mpcexp_status", IOTS_NUM_EXP_MPC); 662*3fd3cb2fSPeter Maydell 663de343bb6SPeter Maydell memory_region_init_io(&s->s_regs, obj, &iotkit_secctl_s_ops, 664de343bb6SPeter Maydell s, "iotkit-secctl-s-regs", 0x1000); 665de343bb6SPeter Maydell memory_region_init_io(&s->ns_regs, obj, &iotkit_secctl_ns_ops, 666de343bb6SPeter Maydell s, "iotkit-secctl-ns-regs", 0x1000); 667de343bb6SPeter Maydell sysbus_init_mmio(sbd, &s->s_regs); 668de343bb6SPeter Maydell sysbus_init_mmio(sbd, &s->ns_regs); 669de343bb6SPeter Maydell } 670de343bb6SPeter Maydell 671b3717c23SPeter Maydell static const VMStateDescription iotkit_secctl_ppc_vmstate = { 672b3717c23SPeter Maydell .name = "iotkit-secctl-ppc", 673b3717c23SPeter Maydell .version_id = 1, 674b3717c23SPeter Maydell .minimum_version_id = 1, 675b3717c23SPeter Maydell .fields = (VMStateField[]) { 676b3717c23SPeter Maydell VMSTATE_UINT32(ns, IoTKitSecCtlPPC), 677b3717c23SPeter Maydell VMSTATE_UINT32(sp, IoTKitSecCtlPPC), 678b3717c23SPeter Maydell VMSTATE_UINT32(nsp, IoTKitSecCtlPPC), 679b3717c23SPeter Maydell VMSTATE_END_OF_LIST() 680b3717c23SPeter Maydell } 681b3717c23SPeter Maydell }; 682b3717c23SPeter Maydell 683*3fd3cb2fSPeter Maydell static const VMStateDescription iotkit_secctl_mpcintstatus_vmstate = { 684*3fd3cb2fSPeter Maydell .name = "iotkit-secctl-mpcintstatus", 685*3fd3cb2fSPeter Maydell .version_id = 1, 686*3fd3cb2fSPeter Maydell .minimum_version_id = 1, 687*3fd3cb2fSPeter Maydell .fields = (VMStateField[]) { 688*3fd3cb2fSPeter Maydell VMSTATE_UINT32(mpcintstatus, IoTKitSecCtl), 689*3fd3cb2fSPeter Maydell VMSTATE_END_OF_LIST() 690*3fd3cb2fSPeter Maydell } 691*3fd3cb2fSPeter Maydell }; 692*3fd3cb2fSPeter Maydell 693de343bb6SPeter Maydell static const VMStateDescription iotkit_secctl_vmstate = { 694de343bb6SPeter Maydell .name = "iotkit-secctl", 695de343bb6SPeter Maydell .version_id = 1, 696de343bb6SPeter Maydell .minimum_version_id = 1, 697de343bb6SPeter Maydell .fields = (VMStateField[]) { 698b3717c23SPeter Maydell VMSTATE_UINT32(secppcintstat, IoTKitSecCtl), 699b3717c23SPeter Maydell VMSTATE_UINT32(secppcinten, IoTKitSecCtl), 700b3717c23SPeter Maydell VMSTATE_UINT32(secrespcfg, IoTKitSecCtl), 701b1ce38e1SPeter Maydell VMSTATE_UINT32(nsccfg, IoTKitSecCtl), 702b1ce38e1SPeter Maydell VMSTATE_UINT32(brginten, IoTKitSecCtl), 703b3717c23SPeter Maydell VMSTATE_STRUCT_ARRAY(apb, IoTKitSecCtl, IOTS_NUM_APB_PPC, 1, 704b3717c23SPeter Maydell iotkit_secctl_ppc_vmstate, IoTKitSecCtlPPC), 705b3717c23SPeter Maydell VMSTATE_STRUCT_ARRAY(apbexp, IoTKitSecCtl, IOTS_NUM_APB_EXP_PPC, 1, 706b3717c23SPeter Maydell iotkit_secctl_ppc_vmstate, IoTKitSecCtlPPC), 707b3717c23SPeter Maydell VMSTATE_STRUCT_ARRAY(ahbexp, IoTKitSecCtl, IOTS_NUM_AHB_EXP_PPC, 1, 708b3717c23SPeter Maydell iotkit_secctl_ppc_vmstate, IoTKitSecCtlPPC), 709de343bb6SPeter Maydell VMSTATE_END_OF_LIST() 710*3fd3cb2fSPeter Maydell }, 711*3fd3cb2fSPeter Maydell .subsections = (const VMStateDescription*[]) { 712*3fd3cb2fSPeter Maydell &iotkit_secctl_mpcintstatus_vmstate, 713*3fd3cb2fSPeter Maydell NULL 714*3fd3cb2fSPeter Maydell }, 715de343bb6SPeter Maydell }; 716de343bb6SPeter Maydell 717de343bb6SPeter Maydell static void iotkit_secctl_class_init(ObjectClass *klass, void *data) 718de343bb6SPeter Maydell { 719de343bb6SPeter Maydell DeviceClass *dc = DEVICE_CLASS(klass); 720de343bb6SPeter Maydell 721de343bb6SPeter Maydell dc->vmsd = &iotkit_secctl_vmstate; 722de343bb6SPeter Maydell dc->reset = iotkit_secctl_reset; 723de343bb6SPeter Maydell } 724de343bb6SPeter Maydell 725de343bb6SPeter Maydell static const TypeInfo iotkit_secctl_info = { 726de343bb6SPeter Maydell .name = TYPE_IOTKIT_SECCTL, 727de343bb6SPeter Maydell .parent = TYPE_SYS_BUS_DEVICE, 728de343bb6SPeter Maydell .instance_size = sizeof(IoTKitSecCtl), 729de343bb6SPeter Maydell .instance_init = iotkit_secctl_init, 730de343bb6SPeter Maydell .class_init = iotkit_secctl_class_init, 731de343bb6SPeter Maydell }; 732de343bb6SPeter Maydell 733de343bb6SPeter Maydell static void iotkit_secctl_register_types(void) 734de343bb6SPeter Maydell { 735de343bb6SPeter Maydell type_register_static(&iotkit_secctl_info); 736de343bb6SPeter Maydell } 737de343bb6SPeter Maydell 738de343bb6SPeter Maydell type_init(iotkit_secctl_register_types); 739