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