xref: /qemu/hw/misc/iotkit-secctl.c (revision b3717c23e1c02b4f03cc4998cf41885a9db2eb03)
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 
95*b3717c23SPeter Maydell /* The register sets for the various PPCs (AHB internal, APB internal,
96*b3717c23SPeter Maydell  * AHB expansion, APB expansion) are all set up so that they are
97*b3717c23SPeter Maydell  * in 16-aligned blocks so offsets 0xN0, 0xN4, 0xN8, 0xNC are PPCs
98*b3717c23SPeter Maydell  * 0, 1, 2, 3 of that type, so we can convert a register address offset
99*b3717c23SPeter Maydell  * into an an index into a PPC array easily.
100*b3717c23SPeter Maydell  */
101*b3717c23SPeter Maydell static inline int offset_to_ppc_idx(uint32_t offset)
102*b3717c23SPeter Maydell {
103*b3717c23SPeter Maydell     return extract32(offset, 2, 2);
104*b3717c23SPeter Maydell }
105*b3717c23SPeter Maydell 
106*b3717c23SPeter Maydell typedef void PerPPCFunction(IoTKitSecCtlPPC *ppc);
107*b3717c23SPeter Maydell 
108*b3717c23SPeter Maydell static void foreach_ppc(IoTKitSecCtl *s, PerPPCFunction *fn)
109*b3717c23SPeter Maydell {
110*b3717c23SPeter Maydell     int i;
111*b3717c23SPeter Maydell 
112*b3717c23SPeter Maydell     for (i = 0; i < IOTS_NUM_APB_PPC; i++) {
113*b3717c23SPeter Maydell         fn(&s->apb[i]);
114*b3717c23SPeter Maydell     }
115*b3717c23SPeter Maydell     for (i = 0; i < IOTS_NUM_APB_EXP_PPC; i++) {
116*b3717c23SPeter Maydell         fn(&s->apbexp[i]);
117*b3717c23SPeter Maydell     }
118*b3717c23SPeter Maydell     for (i = 0; i < IOTS_NUM_AHB_EXP_PPC; i++) {
119*b3717c23SPeter Maydell         fn(&s->ahbexp[i]);
120*b3717c23SPeter Maydell     }
121*b3717c23SPeter Maydell }
122*b3717c23SPeter 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;
129*b3717c23SPeter 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:
137*b3717c23SPeter Maydell         r = s->secrespcfg;
138*b3717c23SPeter Maydell         break;
139de343bb6SPeter Maydell     case A_SECPPCINTSTAT:
140*b3717c23SPeter Maydell         r = s->secppcintstat;
141*b3717c23SPeter Maydell         break;
142de343bb6SPeter Maydell     case A_SECPPCINTEN:
143*b3717c23SPeter Maydell         r = s->secppcinten;
144*b3717c23SPeter Maydell         break;
145de343bb6SPeter Maydell     case A_AHBNSPPCEXP0:
146de343bb6SPeter Maydell     case A_AHBNSPPCEXP1:
147de343bb6SPeter Maydell     case A_AHBNSPPCEXP2:
148de343bb6SPeter Maydell     case A_AHBNSPPCEXP3:
149*b3717c23SPeter Maydell         r = s->ahbexp[offset_to_ppc_idx(offset)].ns;
150*b3717c23SPeter Maydell         break;
151de343bb6SPeter Maydell     case A_APBNSPPC0:
152de343bb6SPeter Maydell     case A_APBNSPPC1:
153*b3717c23SPeter Maydell         r = s->apb[offset_to_ppc_idx(offset)].ns;
154*b3717c23SPeter Maydell         break;
155de343bb6SPeter Maydell     case A_APBNSPPCEXP0:
156de343bb6SPeter Maydell     case A_APBNSPPCEXP1:
157de343bb6SPeter Maydell     case A_APBNSPPCEXP2:
158de343bb6SPeter Maydell     case A_APBNSPPCEXP3:
159*b3717c23SPeter Maydell         r = s->apbexp[offset_to_ppc_idx(offset)].ns;
160*b3717c23SPeter Maydell         break;
161de343bb6SPeter Maydell     case A_AHBSPPPCEXP0:
162de343bb6SPeter Maydell     case A_AHBSPPPCEXP1:
163de343bb6SPeter Maydell     case A_AHBSPPPCEXP2:
164de343bb6SPeter Maydell     case A_AHBSPPPCEXP3:
165*b3717c23SPeter Maydell         r = s->apbexp[offset_to_ppc_idx(offset)].sp;
166*b3717c23SPeter Maydell         break;
167de343bb6SPeter Maydell     case A_APBSPPPC0:
168de343bb6SPeter Maydell     case A_APBSPPPC1:
169*b3717c23SPeter Maydell         r = s->apb[offset_to_ppc_idx(offset)].sp;
170*b3717c23SPeter Maydell         break;
171de343bb6SPeter Maydell     case A_APBSPPPCEXP0:
172de343bb6SPeter Maydell     case A_APBSPPPCEXP1:
173de343bb6SPeter Maydell     case A_APBSPPPCEXP2:
174de343bb6SPeter Maydell     case A_APBSPPPCEXP3:
175*b3717c23SPeter Maydell         r = s->apbexp[offset_to_ppc_idx(offset)].sp;
176*b3717c23SPeter Maydell         break;
177*b3717c23SPeter Maydell     case A_NSCCFG:
178*b3717c23SPeter Maydell     case A_SECMPCINTSTATUS:
179*b3717c23SPeter Maydell     case A_SECMSCINTSTAT:
180*b3717c23SPeter Maydell     case A_SECMSCINTEN:
181*b3717c23SPeter Maydell     case A_BRGINTSTAT:
182*b3717c23SPeter Maydell     case A_BRGINTEN:
183de343bb6SPeter Maydell     case A_NSMSCEXP:
184de343bb6SPeter Maydell         qemu_log_mask(LOG_UNIMP,
185de343bb6SPeter Maydell                       "IoTKit SecCtl S block read: "
186de343bb6SPeter Maydell                       "unimplemented offset 0x%x\n", offset);
187de343bb6SPeter Maydell         r = 0;
188de343bb6SPeter Maydell         break;
189de343bb6SPeter Maydell     case A_PID4:
190de343bb6SPeter Maydell     case A_PID5:
191de343bb6SPeter Maydell     case A_PID6:
192de343bb6SPeter Maydell     case A_PID7:
193de343bb6SPeter Maydell     case A_PID0:
194de343bb6SPeter Maydell     case A_PID1:
195de343bb6SPeter Maydell     case A_PID2:
196de343bb6SPeter Maydell     case A_PID3:
197de343bb6SPeter Maydell     case A_CID0:
198de343bb6SPeter Maydell     case A_CID1:
199de343bb6SPeter Maydell     case A_CID2:
200de343bb6SPeter Maydell     case A_CID3:
201de343bb6SPeter Maydell         r = iotkit_secctl_s_idregs[(offset - A_PID4) / 4];
202de343bb6SPeter Maydell         break;
203de343bb6SPeter Maydell     case A_SECPPCINTCLR:
204de343bb6SPeter Maydell     case A_SECMSCINTCLR:
205de343bb6SPeter Maydell     case A_BRGINTCLR:
206de343bb6SPeter Maydell         qemu_log_mask(LOG_GUEST_ERROR,
207de343bb6SPeter Maydell                       "IotKit SecCtl S block read: write-only offset 0x%x\n",
208de343bb6SPeter Maydell                       offset);
209de343bb6SPeter Maydell         r = 0;
210de343bb6SPeter Maydell         break;
211de343bb6SPeter Maydell     default:
212de343bb6SPeter Maydell         qemu_log_mask(LOG_GUEST_ERROR,
213de343bb6SPeter Maydell                       "IotKit SecCtl S block read: bad offset 0x%x\n", offset);
214de343bb6SPeter Maydell         r = 0;
215de343bb6SPeter Maydell         break;
216de343bb6SPeter Maydell     }
217de343bb6SPeter Maydell 
218de343bb6SPeter Maydell     if (size != 4) {
219de343bb6SPeter Maydell         /* None of our registers are access-sensitive, so just pull the right
220de343bb6SPeter Maydell          * byte out of the word read result.
221de343bb6SPeter Maydell          */
222de343bb6SPeter Maydell         r = extract32(r, (addr & 3) * 8, size * 8);
223de343bb6SPeter Maydell     }
224de343bb6SPeter Maydell 
225de343bb6SPeter Maydell     trace_iotkit_secctl_s_read(offset, r, size);
226de343bb6SPeter Maydell     *pdata = r;
227de343bb6SPeter Maydell     return MEMTX_OK;
228de343bb6SPeter Maydell }
229de343bb6SPeter Maydell 
230*b3717c23SPeter Maydell static void iotkit_secctl_update_ppc_ap(IoTKitSecCtlPPC *ppc)
231*b3717c23SPeter Maydell {
232*b3717c23SPeter Maydell     int i;
233*b3717c23SPeter Maydell 
234*b3717c23SPeter Maydell     for (i = 0; i < ppc->numports; i++) {
235*b3717c23SPeter Maydell         bool v;
236*b3717c23SPeter Maydell 
237*b3717c23SPeter Maydell         if (extract32(ppc->ns, i, 1)) {
238*b3717c23SPeter Maydell             v = extract32(ppc->nsp, i, 1);
239*b3717c23SPeter Maydell         } else {
240*b3717c23SPeter Maydell             v = extract32(ppc->sp, i, 1);
241*b3717c23SPeter Maydell         }
242*b3717c23SPeter Maydell         qemu_set_irq(ppc->ap[i], v);
243*b3717c23SPeter Maydell     }
244*b3717c23SPeter Maydell }
245*b3717c23SPeter Maydell 
246*b3717c23SPeter Maydell static void iotkit_secctl_ppc_ns_write(IoTKitSecCtlPPC *ppc, uint32_t value)
247*b3717c23SPeter Maydell {
248*b3717c23SPeter Maydell     int i;
249*b3717c23SPeter Maydell 
250*b3717c23SPeter Maydell     ppc->ns = value & MAKE_64BIT_MASK(0, ppc->numports);
251*b3717c23SPeter Maydell     for (i = 0; i < ppc->numports; i++) {
252*b3717c23SPeter Maydell         qemu_set_irq(ppc->nonsec[i], extract32(ppc->ns, i, 1));
253*b3717c23SPeter Maydell     }
254*b3717c23SPeter Maydell     iotkit_secctl_update_ppc_ap(ppc);
255*b3717c23SPeter Maydell }
256*b3717c23SPeter Maydell 
257*b3717c23SPeter Maydell static void iotkit_secctl_ppc_sp_write(IoTKitSecCtlPPC *ppc, uint32_t value)
258*b3717c23SPeter Maydell {
259*b3717c23SPeter Maydell     ppc->sp = value & MAKE_64BIT_MASK(0, ppc->numports);
260*b3717c23SPeter Maydell     iotkit_secctl_update_ppc_ap(ppc);
261*b3717c23SPeter Maydell }
262*b3717c23SPeter Maydell 
263*b3717c23SPeter Maydell static void iotkit_secctl_ppc_nsp_write(IoTKitSecCtlPPC *ppc, uint32_t value)
264*b3717c23SPeter Maydell {
265*b3717c23SPeter Maydell     ppc->nsp = value & MAKE_64BIT_MASK(0, ppc->numports);
266*b3717c23SPeter Maydell     iotkit_secctl_update_ppc_ap(ppc);
267*b3717c23SPeter Maydell }
268*b3717c23SPeter Maydell 
269*b3717c23SPeter Maydell static void iotkit_secctl_ppc_update_irq_clear(IoTKitSecCtlPPC *ppc)
270*b3717c23SPeter Maydell {
271*b3717c23SPeter Maydell     uint32_t value = ppc->parent->secppcintstat;
272*b3717c23SPeter Maydell 
273*b3717c23SPeter Maydell     qemu_set_irq(ppc->irq_clear, extract32(value, ppc->irq_bit_offset, 1));
274*b3717c23SPeter Maydell }
275*b3717c23SPeter Maydell 
276*b3717c23SPeter Maydell static void iotkit_secctl_ppc_update_irq_enable(IoTKitSecCtlPPC *ppc)
277*b3717c23SPeter Maydell {
278*b3717c23SPeter Maydell     uint32_t value = ppc->parent->secppcinten;
279*b3717c23SPeter Maydell 
280*b3717c23SPeter Maydell     qemu_set_irq(ppc->irq_enable, extract32(value, ppc->irq_bit_offset, 1));
281*b3717c23SPeter Maydell }
282*b3717c23SPeter Maydell 
283de343bb6SPeter Maydell static MemTxResult iotkit_secctl_s_write(void *opaque, hwaddr addr,
284de343bb6SPeter Maydell                                          uint64_t value,
285de343bb6SPeter Maydell                                          unsigned size, MemTxAttrs attrs)
286de343bb6SPeter Maydell {
287*b3717c23SPeter Maydell     IoTKitSecCtl *s = IOTKIT_SECCTL(opaque);
288de343bb6SPeter Maydell     uint32_t offset = addr;
289*b3717c23SPeter Maydell     IoTKitSecCtlPPC *ppc;
290de343bb6SPeter Maydell 
291de343bb6SPeter Maydell     trace_iotkit_secctl_s_write(offset, value, size);
292de343bb6SPeter Maydell 
293de343bb6SPeter Maydell     if (size != 4) {
294de343bb6SPeter Maydell         /* Byte and halfword writes are ignored */
295de343bb6SPeter Maydell         qemu_log_mask(LOG_GUEST_ERROR,
296de343bb6SPeter Maydell                       "IotKit SecCtl S block write: bad size, ignored\n");
297de343bb6SPeter Maydell         return MEMTX_OK;
298de343bb6SPeter Maydell     }
299de343bb6SPeter Maydell 
300de343bb6SPeter Maydell     switch (offset) {
301de343bb6SPeter Maydell     case A_SECRESPCFG:
302*b3717c23SPeter Maydell         value &= 1;
303*b3717c23SPeter Maydell         s->secrespcfg = value;
304*b3717c23SPeter Maydell         qemu_set_irq(s->sec_resp_cfg, s->secrespcfg);
305*b3717c23SPeter Maydell         break;
306de343bb6SPeter Maydell     case A_SECPPCINTCLR:
307*b3717c23SPeter Maydell         value &= 0x00f000f3;
308*b3717c23SPeter Maydell         foreach_ppc(s, iotkit_secctl_ppc_update_irq_clear);
309*b3717c23SPeter Maydell         break;
310de343bb6SPeter Maydell     case A_SECPPCINTEN:
311*b3717c23SPeter Maydell         s->secppcinten = value & 0x00f000f3;
312*b3717c23SPeter Maydell         foreach_ppc(s, iotkit_secctl_ppc_update_irq_enable);
313*b3717c23SPeter Maydell         break;
314de343bb6SPeter Maydell     case A_AHBNSPPCEXP0:
315de343bb6SPeter Maydell     case A_AHBNSPPCEXP1:
316de343bb6SPeter Maydell     case A_AHBNSPPCEXP2:
317de343bb6SPeter Maydell     case A_AHBNSPPCEXP3:
318*b3717c23SPeter Maydell         ppc = &s->ahbexp[offset_to_ppc_idx(offset)];
319*b3717c23SPeter Maydell         iotkit_secctl_ppc_ns_write(ppc, value);
320*b3717c23SPeter Maydell         break;
321de343bb6SPeter Maydell     case A_APBNSPPC0:
322de343bb6SPeter Maydell     case A_APBNSPPC1:
323*b3717c23SPeter Maydell         ppc = &s->apb[offset_to_ppc_idx(offset)];
324*b3717c23SPeter Maydell         iotkit_secctl_ppc_ns_write(ppc, value);
325*b3717c23SPeter Maydell         break;
326de343bb6SPeter Maydell     case A_APBNSPPCEXP0:
327de343bb6SPeter Maydell     case A_APBNSPPCEXP1:
328de343bb6SPeter Maydell     case A_APBNSPPCEXP2:
329de343bb6SPeter Maydell     case A_APBNSPPCEXP3:
330*b3717c23SPeter Maydell         ppc = &s->apbexp[offset_to_ppc_idx(offset)];
331*b3717c23SPeter Maydell         iotkit_secctl_ppc_ns_write(ppc, value);
332*b3717c23SPeter Maydell         break;
333de343bb6SPeter Maydell     case A_AHBSPPPCEXP0:
334de343bb6SPeter Maydell     case A_AHBSPPPCEXP1:
335de343bb6SPeter Maydell     case A_AHBSPPPCEXP2:
336de343bb6SPeter Maydell     case A_AHBSPPPCEXP3:
337*b3717c23SPeter Maydell         ppc = &s->ahbexp[offset_to_ppc_idx(offset)];
338*b3717c23SPeter Maydell         iotkit_secctl_ppc_sp_write(ppc, value);
339*b3717c23SPeter Maydell         break;
340de343bb6SPeter Maydell     case A_APBSPPPC0:
341de343bb6SPeter Maydell     case A_APBSPPPC1:
342*b3717c23SPeter Maydell         ppc = &s->apb[offset_to_ppc_idx(offset)];
343*b3717c23SPeter Maydell         iotkit_secctl_ppc_sp_write(ppc, value);
344*b3717c23SPeter Maydell         break;
345de343bb6SPeter Maydell     case A_APBSPPPCEXP0:
346de343bb6SPeter Maydell     case A_APBSPPPCEXP1:
347de343bb6SPeter Maydell     case A_APBSPPPCEXP2:
348de343bb6SPeter Maydell     case A_APBSPPPCEXP3:
349*b3717c23SPeter Maydell         ppc = &s->apbexp[offset_to_ppc_idx(offset)];
350*b3717c23SPeter Maydell         iotkit_secctl_ppc_sp_write(ppc, value);
351*b3717c23SPeter Maydell         break;
352*b3717c23SPeter Maydell     case A_NSCCFG:
353*b3717c23SPeter Maydell     case A_SECMSCINTCLR:
354*b3717c23SPeter Maydell     case A_SECMSCINTEN:
355*b3717c23SPeter Maydell     case A_BRGINTCLR:
356*b3717c23SPeter Maydell     case A_BRGINTEN:
357de343bb6SPeter Maydell         qemu_log_mask(LOG_UNIMP,
358de343bb6SPeter Maydell                       "IoTKit SecCtl S block write: "
359de343bb6SPeter Maydell                       "unimplemented offset 0x%x\n", offset);
360de343bb6SPeter Maydell         break;
361de343bb6SPeter Maydell     case A_SECMPCINTSTATUS:
362de343bb6SPeter Maydell     case A_SECPPCINTSTAT:
363de343bb6SPeter Maydell     case A_SECMSCINTSTAT:
364de343bb6SPeter Maydell     case A_BRGINTSTAT:
365de343bb6SPeter Maydell     case A_AHBNSPPC0:
366de343bb6SPeter Maydell     case A_AHBSPPPC0:
367de343bb6SPeter Maydell     case A_NSMSCEXP:
368de343bb6SPeter Maydell     case A_PID4:
369de343bb6SPeter Maydell     case A_PID5:
370de343bb6SPeter Maydell     case A_PID6:
371de343bb6SPeter Maydell     case A_PID7:
372de343bb6SPeter Maydell     case A_PID0:
373de343bb6SPeter Maydell     case A_PID1:
374de343bb6SPeter Maydell     case A_PID2:
375de343bb6SPeter Maydell     case A_PID3:
376de343bb6SPeter Maydell     case A_CID0:
377de343bb6SPeter Maydell     case A_CID1:
378de343bb6SPeter Maydell     case A_CID2:
379de343bb6SPeter Maydell     case A_CID3:
380de343bb6SPeter Maydell         qemu_log_mask(LOG_GUEST_ERROR,
381de343bb6SPeter Maydell                       "IoTKit SecCtl S block write: "
382de343bb6SPeter Maydell                       "read-only offset 0x%x\n", offset);
383de343bb6SPeter Maydell         break;
384de343bb6SPeter Maydell     default:
385de343bb6SPeter Maydell         qemu_log_mask(LOG_GUEST_ERROR,
386de343bb6SPeter Maydell                       "IotKit SecCtl S block write: bad offset 0x%x\n",
387de343bb6SPeter Maydell                       offset);
388de343bb6SPeter Maydell         break;
389de343bb6SPeter Maydell     }
390de343bb6SPeter Maydell 
391de343bb6SPeter Maydell     return MEMTX_OK;
392de343bb6SPeter Maydell }
393de343bb6SPeter Maydell 
394de343bb6SPeter Maydell static MemTxResult iotkit_secctl_ns_read(void *opaque, hwaddr addr,
395de343bb6SPeter Maydell                                          uint64_t *pdata,
396de343bb6SPeter Maydell                                          unsigned size, MemTxAttrs attrs)
397de343bb6SPeter Maydell {
398*b3717c23SPeter Maydell     IoTKitSecCtl *s = IOTKIT_SECCTL(opaque);
399de343bb6SPeter Maydell     uint64_t r;
400de343bb6SPeter Maydell     uint32_t offset = addr & ~0x3;
401de343bb6SPeter Maydell 
402de343bb6SPeter Maydell     switch (offset) {
403de343bb6SPeter Maydell     case A_AHBNSPPPC0:
404de343bb6SPeter Maydell         r = 0;
405de343bb6SPeter Maydell         break;
406de343bb6SPeter Maydell     case A_AHBNSPPPCEXP0:
407de343bb6SPeter Maydell     case A_AHBNSPPPCEXP1:
408de343bb6SPeter Maydell     case A_AHBNSPPPCEXP2:
409de343bb6SPeter Maydell     case A_AHBNSPPPCEXP3:
410*b3717c23SPeter Maydell         r = s->ahbexp[offset_to_ppc_idx(offset)].nsp;
411*b3717c23SPeter Maydell         break;
412de343bb6SPeter Maydell     case A_APBNSPPPC0:
413de343bb6SPeter Maydell     case A_APBNSPPPC1:
414*b3717c23SPeter Maydell         r = s->apb[offset_to_ppc_idx(offset)].nsp;
415*b3717c23SPeter Maydell         break;
416de343bb6SPeter Maydell     case A_APBNSPPPCEXP0:
417de343bb6SPeter Maydell     case A_APBNSPPPCEXP1:
418de343bb6SPeter Maydell     case A_APBNSPPPCEXP2:
419de343bb6SPeter Maydell     case A_APBNSPPPCEXP3:
420*b3717c23SPeter Maydell         r = s->apbexp[offset_to_ppc_idx(offset)].nsp;
421de343bb6SPeter Maydell         break;
422de343bb6SPeter Maydell     case A_PID4:
423de343bb6SPeter Maydell     case A_PID5:
424de343bb6SPeter Maydell     case A_PID6:
425de343bb6SPeter Maydell     case A_PID7:
426de343bb6SPeter Maydell     case A_PID0:
427de343bb6SPeter Maydell     case A_PID1:
428de343bb6SPeter Maydell     case A_PID2:
429de343bb6SPeter Maydell     case A_PID3:
430de343bb6SPeter Maydell     case A_CID0:
431de343bb6SPeter Maydell     case A_CID1:
432de343bb6SPeter Maydell     case A_CID2:
433de343bb6SPeter Maydell     case A_CID3:
434de343bb6SPeter Maydell         r = iotkit_secctl_ns_idregs[(offset - A_PID4) / 4];
435de343bb6SPeter Maydell         break;
436de343bb6SPeter Maydell     default:
437de343bb6SPeter Maydell         qemu_log_mask(LOG_GUEST_ERROR,
438de343bb6SPeter Maydell                       "IotKit SecCtl NS block write: bad offset 0x%x\n",
439de343bb6SPeter Maydell                       offset);
440de343bb6SPeter Maydell         r = 0;
441de343bb6SPeter Maydell         break;
442de343bb6SPeter Maydell     }
443de343bb6SPeter Maydell 
444de343bb6SPeter Maydell     if (size != 4) {
445de343bb6SPeter Maydell         /* None of our registers are access-sensitive, so just pull the right
446de343bb6SPeter Maydell          * byte out of the word read result.
447de343bb6SPeter Maydell          */
448de343bb6SPeter Maydell         r = extract32(r, (addr & 3) * 8, size * 8);
449de343bb6SPeter Maydell     }
450de343bb6SPeter Maydell 
451de343bb6SPeter Maydell     trace_iotkit_secctl_ns_read(offset, r, size);
452de343bb6SPeter Maydell     *pdata = r;
453de343bb6SPeter Maydell     return MEMTX_OK;
454de343bb6SPeter Maydell }
455de343bb6SPeter Maydell 
456de343bb6SPeter Maydell static MemTxResult iotkit_secctl_ns_write(void *opaque, hwaddr addr,
457de343bb6SPeter Maydell                                           uint64_t value,
458de343bb6SPeter Maydell                                           unsigned size, MemTxAttrs attrs)
459de343bb6SPeter Maydell {
460*b3717c23SPeter Maydell     IoTKitSecCtl *s = IOTKIT_SECCTL(opaque);
461de343bb6SPeter Maydell     uint32_t offset = addr;
462*b3717c23SPeter Maydell     IoTKitSecCtlPPC *ppc;
463de343bb6SPeter Maydell 
464de343bb6SPeter Maydell     trace_iotkit_secctl_ns_write(offset, value, size);
465de343bb6SPeter Maydell 
466de343bb6SPeter Maydell     if (size != 4) {
467de343bb6SPeter Maydell         /* Byte and halfword writes are ignored */
468de343bb6SPeter Maydell         qemu_log_mask(LOG_GUEST_ERROR,
469de343bb6SPeter Maydell                       "IotKit SecCtl NS block write: bad size, ignored\n");
470de343bb6SPeter Maydell         return MEMTX_OK;
471de343bb6SPeter Maydell     }
472de343bb6SPeter Maydell 
473de343bb6SPeter Maydell     switch (offset) {
474de343bb6SPeter Maydell     case A_AHBNSPPPCEXP0:
475de343bb6SPeter Maydell     case A_AHBNSPPPCEXP1:
476de343bb6SPeter Maydell     case A_AHBNSPPPCEXP2:
477de343bb6SPeter Maydell     case A_AHBNSPPPCEXP3:
478*b3717c23SPeter Maydell         ppc = &s->ahbexp[offset_to_ppc_idx(offset)];
479*b3717c23SPeter Maydell         iotkit_secctl_ppc_nsp_write(ppc, value);
480*b3717c23SPeter Maydell         break;
481de343bb6SPeter Maydell     case A_APBNSPPPC0:
482de343bb6SPeter Maydell     case A_APBNSPPPC1:
483*b3717c23SPeter Maydell         ppc = &s->apb[offset_to_ppc_idx(offset)];
484*b3717c23SPeter Maydell         iotkit_secctl_ppc_nsp_write(ppc, value);
485*b3717c23SPeter Maydell         break;
486de343bb6SPeter Maydell     case A_APBNSPPPCEXP0:
487de343bb6SPeter Maydell     case A_APBNSPPPCEXP1:
488de343bb6SPeter Maydell     case A_APBNSPPPCEXP2:
489de343bb6SPeter Maydell     case A_APBNSPPPCEXP3:
490*b3717c23SPeter Maydell         ppc = &s->apbexp[offset_to_ppc_idx(offset)];
491*b3717c23SPeter Maydell         iotkit_secctl_ppc_nsp_write(ppc, value);
492de343bb6SPeter Maydell         break;
493de343bb6SPeter Maydell     case A_AHBNSPPPC0:
494de343bb6SPeter Maydell     case A_PID4:
495de343bb6SPeter Maydell     case A_PID5:
496de343bb6SPeter Maydell     case A_PID6:
497de343bb6SPeter Maydell     case A_PID7:
498de343bb6SPeter Maydell     case A_PID0:
499de343bb6SPeter Maydell     case A_PID1:
500de343bb6SPeter Maydell     case A_PID2:
501de343bb6SPeter Maydell     case A_PID3:
502de343bb6SPeter Maydell     case A_CID0:
503de343bb6SPeter Maydell     case A_CID1:
504de343bb6SPeter Maydell     case A_CID2:
505de343bb6SPeter Maydell     case A_CID3:
506de343bb6SPeter Maydell         qemu_log_mask(LOG_GUEST_ERROR,
507de343bb6SPeter Maydell                       "IoTKit SecCtl NS block write: "
508de343bb6SPeter Maydell                       "read-only offset 0x%x\n", offset);
509de343bb6SPeter Maydell         break;
510de343bb6SPeter Maydell     default:
511de343bb6SPeter Maydell         qemu_log_mask(LOG_GUEST_ERROR,
512de343bb6SPeter Maydell                       "IotKit SecCtl NS block write: bad offset 0x%x\n",
513de343bb6SPeter Maydell                       offset);
514de343bb6SPeter Maydell         break;
515de343bb6SPeter Maydell     }
516de343bb6SPeter Maydell 
517de343bb6SPeter Maydell     return MEMTX_OK;
518de343bb6SPeter Maydell }
519de343bb6SPeter Maydell 
520de343bb6SPeter Maydell static const MemoryRegionOps iotkit_secctl_s_ops = {
521de343bb6SPeter Maydell     .read_with_attrs = iotkit_secctl_s_read,
522de343bb6SPeter Maydell     .write_with_attrs = iotkit_secctl_s_write,
523de343bb6SPeter Maydell     .endianness = DEVICE_LITTLE_ENDIAN,
524de343bb6SPeter Maydell     .valid.min_access_size = 1,
525de343bb6SPeter Maydell     .valid.max_access_size = 4,
526de343bb6SPeter Maydell     .impl.min_access_size = 1,
527de343bb6SPeter Maydell     .impl.max_access_size = 4,
528de343bb6SPeter Maydell };
529de343bb6SPeter Maydell 
530de343bb6SPeter Maydell static const MemoryRegionOps iotkit_secctl_ns_ops = {
531de343bb6SPeter Maydell     .read_with_attrs = iotkit_secctl_ns_read,
532de343bb6SPeter Maydell     .write_with_attrs = iotkit_secctl_ns_write,
533de343bb6SPeter Maydell     .endianness = DEVICE_LITTLE_ENDIAN,
534de343bb6SPeter Maydell     .valid.min_access_size = 1,
535de343bb6SPeter Maydell     .valid.max_access_size = 4,
536de343bb6SPeter Maydell     .impl.min_access_size = 1,
537de343bb6SPeter Maydell     .impl.max_access_size = 4,
538de343bb6SPeter Maydell };
539de343bb6SPeter Maydell 
540*b3717c23SPeter Maydell static void iotkit_secctl_reset_ppc(IoTKitSecCtlPPC *ppc)
541*b3717c23SPeter Maydell {
542*b3717c23SPeter Maydell     ppc->ns = 0;
543*b3717c23SPeter Maydell     ppc->sp = 0;
544*b3717c23SPeter Maydell     ppc->nsp = 0;
545*b3717c23SPeter Maydell }
546*b3717c23SPeter Maydell 
547de343bb6SPeter Maydell static void iotkit_secctl_reset(DeviceState *dev)
548de343bb6SPeter Maydell {
549*b3717c23SPeter Maydell     IoTKitSecCtl *s = IOTKIT_SECCTL(dev);
550de343bb6SPeter Maydell 
551*b3717c23SPeter Maydell     s->secppcintstat = 0;
552*b3717c23SPeter Maydell     s->secppcinten = 0;
553*b3717c23SPeter Maydell     s->secrespcfg = 0;
554*b3717c23SPeter Maydell 
555*b3717c23SPeter Maydell     foreach_ppc(s, iotkit_secctl_reset_ppc);
556*b3717c23SPeter Maydell }
557*b3717c23SPeter Maydell 
558*b3717c23SPeter Maydell static void iotkit_secctl_ppc_irqstatus(void *opaque, int n, int level)
559*b3717c23SPeter Maydell {
560*b3717c23SPeter Maydell     IoTKitSecCtlPPC *ppc = opaque;
561*b3717c23SPeter Maydell     IoTKitSecCtl *s = IOTKIT_SECCTL(ppc->parent);
562*b3717c23SPeter Maydell     int irqbit = ppc->irq_bit_offset + n;
563*b3717c23SPeter Maydell 
564*b3717c23SPeter Maydell     s->secppcintstat = deposit32(s->secppcintstat, irqbit, 1, level);
565*b3717c23SPeter Maydell }
566*b3717c23SPeter Maydell 
567*b3717c23SPeter Maydell static void iotkit_secctl_init_ppc(IoTKitSecCtl *s,
568*b3717c23SPeter Maydell                                    IoTKitSecCtlPPC *ppc,
569*b3717c23SPeter Maydell                                    const char *name,
570*b3717c23SPeter Maydell                                    int numports,
571*b3717c23SPeter Maydell                                    int irq_bit_offset)
572*b3717c23SPeter Maydell {
573*b3717c23SPeter Maydell     char *gpioname;
574*b3717c23SPeter Maydell     DeviceState *dev = DEVICE(s);
575*b3717c23SPeter Maydell 
576*b3717c23SPeter Maydell     ppc->numports = numports;
577*b3717c23SPeter Maydell     ppc->irq_bit_offset = irq_bit_offset;
578*b3717c23SPeter Maydell     ppc->parent = s;
579*b3717c23SPeter Maydell 
580*b3717c23SPeter Maydell     gpioname = g_strdup_printf("%s_nonsec", name);
581*b3717c23SPeter Maydell     qdev_init_gpio_out_named(dev, ppc->nonsec, gpioname, numports);
582*b3717c23SPeter Maydell     g_free(gpioname);
583*b3717c23SPeter Maydell     gpioname = g_strdup_printf("%s_ap", name);
584*b3717c23SPeter Maydell     qdev_init_gpio_out_named(dev, ppc->ap, gpioname, numports);
585*b3717c23SPeter Maydell     g_free(gpioname);
586*b3717c23SPeter Maydell     gpioname = g_strdup_printf("%s_irq_enable", name);
587*b3717c23SPeter Maydell     qdev_init_gpio_out_named(dev, &ppc->irq_enable, gpioname, 1);
588*b3717c23SPeter Maydell     g_free(gpioname);
589*b3717c23SPeter Maydell     gpioname = g_strdup_printf("%s_irq_clear", name);
590*b3717c23SPeter Maydell     qdev_init_gpio_out_named(dev, &ppc->irq_clear, gpioname, 1);
591*b3717c23SPeter Maydell     g_free(gpioname);
592*b3717c23SPeter Maydell     gpioname = g_strdup_printf("%s_irq_status", name);
593*b3717c23SPeter Maydell     qdev_init_gpio_in_named_with_opaque(dev, iotkit_secctl_ppc_irqstatus,
594*b3717c23SPeter Maydell                                         ppc, gpioname, 1);
595*b3717c23SPeter Maydell     g_free(gpioname);
596de343bb6SPeter Maydell }
597de343bb6SPeter Maydell 
598de343bb6SPeter Maydell static void iotkit_secctl_init(Object *obj)
599de343bb6SPeter Maydell {
600de343bb6SPeter Maydell     IoTKitSecCtl *s = IOTKIT_SECCTL(obj);
601de343bb6SPeter Maydell     SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
602*b3717c23SPeter Maydell     DeviceState *dev = DEVICE(obj);
603*b3717c23SPeter Maydell     int i;
604*b3717c23SPeter Maydell 
605*b3717c23SPeter Maydell     iotkit_secctl_init_ppc(s, &s->apb[0], "apb_ppc0",
606*b3717c23SPeter Maydell                            IOTS_APB_PPC0_NUM_PORTS, 0);
607*b3717c23SPeter Maydell     iotkit_secctl_init_ppc(s, &s->apb[1], "apb_ppc1",
608*b3717c23SPeter Maydell                            IOTS_APB_PPC1_NUM_PORTS, 1);
609*b3717c23SPeter Maydell 
610*b3717c23SPeter Maydell     for (i = 0; i < IOTS_NUM_APB_EXP_PPC; i++) {
611*b3717c23SPeter Maydell         IoTKitSecCtlPPC *ppc = &s->apbexp[i];
612*b3717c23SPeter Maydell         char *ppcname = g_strdup_printf("apb_ppcexp%d", i);
613*b3717c23SPeter Maydell         iotkit_secctl_init_ppc(s, ppc, ppcname, IOTS_PPC_NUM_PORTS, 4 + i);
614*b3717c23SPeter Maydell         g_free(ppcname);
615*b3717c23SPeter Maydell     }
616*b3717c23SPeter Maydell     for (i = 0; i < IOTS_NUM_AHB_EXP_PPC; i++) {
617*b3717c23SPeter Maydell         IoTKitSecCtlPPC *ppc = &s->ahbexp[i];
618*b3717c23SPeter Maydell         char *ppcname = g_strdup_printf("ahb_ppcexp%d", i);
619*b3717c23SPeter Maydell         iotkit_secctl_init_ppc(s, ppc, ppcname, IOTS_PPC_NUM_PORTS, 20 + i);
620*b3717c23SPeter Maydell         g_free(ppcname);
621*b3717c23SPeter Maydell     }
622*b3717c23SPeter Maydell 
623*b3717c23SPeter Maydell     qdev_init_gpio_out_named(dev, &s->sec_resp_cfg, "sec_resp_cfg", 1);
624de343bb6SPeter Maydell 
625de343bb6SPeter Maydell     memory_region_init_io(&s->s_regs, obj, &iotkit_secctl_s_ops,
626de343bb6SPeter Maydell                           s, "iotkit-secctl-s-regs", 0x1000);
627de343bb6SPeter Maydell     memory_region_init_io(&s->ns_regs, obj, &iotkit_secctl_ns_ops,
628de343bb6SPeter Maydell                           s, "iotkit-secctl-ns-regs", 0x1000);
629de343bb6SPeter Maydell     sysbus_init_mmio(sbd, &s->s_regs);
630de343bb6SPeter Maydell     sysbus_init_mmio(sbd, &s->ns_regs);
631de343bb6SPeter Maydell }
632de343bb6SPeter Maydell 
633*b3717c23SPeter Maydell static const VMStateDescription iotkit_secctl_ppc_vmstate = {
634*b3717c23SPeter Maydell     .name = "iotkit-secctl-ppc",
635*b3717c23SPeter Maydell     .version_id = 1,
636*b3717c23SPeter Maydell     .minimum_version_id = 1,
637*b3717c23SPeter Maydell     .fields = (VMStateField[]) {
638*b3717c23SPeter Maydell         VMSTATE_UINT32(ns, IoTKitSecCtlPPC),
639*b3717c23SPeter Maydell         VMSTATE_UINT32(sp, IoTKitSecCtlPPC),
640*b3717c23SPeter Maydell         VMSTATE_UINT32(nsp, IoTKitSecCtlPPC),
641*b3717c23SPeter Maydell         VMSTATE_END_OF_LIST()
642*b3717c23SPeter Maydell     }
643*b3717c23SPeter Maydell };
644*b3717c23SPeter Maydell 
645de343bb6SPeter Maydell static const VMStateDescription iotkit_secctl_vmstate = {
646de343bb6SPeter Maydell     .name = "iotkit-secctl",
647de343bb6SPeter Maydell     .version_id = 1,
648de343bb6SPeter Maydell     .minimum_version_id = 1,
649de343bb6SPeter Maydell     .fields = (VMStateField[]) {
650*b3717c23SPeter Maydell         VMSTATE_UINT32(secppcintstat, IoTKitSecCtl),
651*b3717c23SPeter Maydell         VMSTATE_UINT32(secppcinten, IoTKitSecCtl),
652*b3717c23SPeter Maydell         VMSTATE_UINT32(secrespcfg, IoTKitSecCtl),
653*b3717c23SPeter Maydell         VMSTATE_STRUCT_ARRAY(apb, IoTKitSecCtl, IOTS_NUM_APB_PPC, 1,
654*b3717c23SPeter Maydell                              iotkit_secctl_ppc_vmstate, IoTKitSecCtlPPC),
655*b3717c23SPeter Maydell         VMSTATE_STRUCT_ARRAY(apbexp, IoTKitSecCtl, IOTS_NUM_APB_EXP_PPC, 1,
656*b3717c23SPeter Maydell                              iotkit_secctl_ppc_vmstate, IoTKitSecCtlPPC),
657*b3717c23SPeter Maydell         VMSTATE_STRUCT_ARRAY(ahbexp, IoTKitSecCtl, IOTS_NUM_AHB_EXP_PPC, 1,
658*b3717c23SPeter Maydell                              iotkit_secctl_ppc_vmstate, IoTKitSecCtlPPC),
659de343bb6SPeter Maydell         VMSTATE_END_OF_LIST()
660de343bb6SPeter Maydell     }
661de343bb6SPeter Maydell };
662de343bb6SPeter Maydell 
663de343bb6SPeter Maydell static void iotkit_secctl_class_init(ObjectClass *klass, void *data)
664de343bb6SPeter Maydell {
665de343bb6SPeter Maydell     DeviceClass *dc = DEVICE_CLASS(klass);
666de343bb6SPeter Maydell 
667de343bb6SPeter Maydell     dc->vmsd = &iotkit_secctl_vmstate;
668de343bb6SPeter Maydell     dc->reset = iotkit_secctl_reset;
669de343bb6SPeter Maydell }
670de343bb6SPeter Maydell 
671de343bb6SPeter Maydell static const TypeInfo iotkit_secctl_info = {
672de343bb6SPeter Maydell     .name = TYPE_IOTKIT_SECCTL,
673de343bb6SPeter Maydell     .parent = TYPE_SYS_BUS_DEVICE,
674de343bb6SPeter Maydell     .instance_size = sizeof(IoTKitSecCtl),
675de343bb6SPeter Maydell     .instance_init = iotkit_secctl_init,
676de343bb6SPeter Maydell     .class_init = iotkit_secctl_class_init,
677de343bb6SPeter Maydell };
678de343bb6SPeter Maydell 
679de343bb6SPeter Maydell static void iotkit_secctl_register_types(void)
680de343bb6SPeter Maydell {
681de343bb6SPeter Maydell     type_register_static(&iotkit_secctl_info);
682de343bb6SPeter Maydell }
683de343bb6SPeter Maydell 
684de343bb6SPeter Maydell type_init(iotkit_secctl_register_types);
685