xref: /qemu/hw/misc/iotkit-secctl.c (revision 06b40d250ecfa1633209c2e431a7a38acfd03a98)
1de343bb6SPeter Maydell /*
2de343bb6SPeter Maydell  * Arm IoT Kit security controller
3de343bb6SPeter Maydell  *
4de343bb6SPeter Maydell  * Copyright (c) 2018 Linaro Limited
5de343bb6SPeter Maydell  * Written by Peter Maydell
6de343bb6SPeter Maydell  *
7de343bb6SPeter Maydell  * This program is free software; you can redistribute it and/or modify
8de343bb6SPeter Maydell  * it under the terms of the GNU General Public License version 2 or
9de343bb6SPeter Maydell  * (at your option) any later version.
10de343bb6SPeter Maydell  */
11de343bb6SPeter Maydell 
12de343bb6SPeter Maydell #include "qemu/osdep.h"
13de343bb6SPeter Maydell #include "qemu/log.h"
140b8fa32fSMarkus Armbruster #include "qemu/module.h"
15de343bb6SPeter Maydell #include "qapi/error.h"
16de343bb6SPeter Maydell #include "trace.h"
17de343bb6SPeter Maydell #include "hw/sysbus.h"
18d6454270SMarkus Armbruster #include "migration/vmstate.h"
19de343bb6SPeter Maydell #include "hw/registerfields.h"
2064552b6bSMarkus Armbruster #include "hw/irq.h"
21de343bb6SPeter Maydell #include "hw/misc/iotkit-secctl.h"
220eb6b0adSPeter Maydell #include "hw/arm/armsse-version.h"
230eb6b0adSPeter Maydell #include "hw/qdev-properties.h"
24de343bb6SPeter Maydell 
25de343bb6SPeter Maydell /* Registers in the secure privilege control block */
26de343bb6SPeter Maydell REG32(SECRESPCFG, 0x10)
27de343bb6SPeter Maydell REG32(NSCCFG, 0x14)
28de343bb6SPeter Maydell REG32(SECMPCINTSTATUS, 0x1c)
29de343bb6SPeter Maydell REG32(SECPPCINTSTAT, 0x20)
30de343bb6SPeter Maydell REG32(SECPPCINTCLR, 0x24)
31de343bb6SPeter Maydell REG32(SECPPCINTEN, 0x28)
32de343bb6SPeter Maydell REG32(SECMSCINTSTAT, 0x30)
33de343bb6SPeter Maydell REG32(SECMSCINTCLR, 0x34)
34de343bb6SPeter Maydell REG32(SECMSCINTEN, 0x38)
35de343bb6SPeter Maydell REG32(BRGINTSTAT, 0x40)
36de343bb6SPeter Maydell REG32(BRGINTCLR, 0x44)
37de343bb6SPeter Maydell REG32(BRGINTEN, 0x48)
38de343bb6SPeter Maydell REG32(AHBNSPPC0, 0x50)
39de343bb6SPeter Maydell REG32(AHBNSPPCEXP0, 0x60)
40de343bb6SPeter Maydell REG32(AHBNSPPCEXP1, 0x64)
41de343bb6SPeter Maydell REG32(AHBNSPPCEXP2, 0x68)
42de343bb6SPeter Maydell REG32(AHBNSPPCEXP3, 0x6c)
43de343bb6SPeter Maydell REG32(APBNSPPC0, 0x70)
44de343bb6SPeter Maydell REG32(APBNSPPC1, 0x74)
45de343bb6SPeter Maydell REG32(APBNSPPCEXP0, 0x80)
46de343bb6SPeter Maydell REG32(APBNSPPCEXP1, 0x84)
47de343bb6SPeter Maydell REG32(APBNSPPCEXP2, 0x88)
48de343bb6SPeter Maydell REG32(APBNSPPCEXP3, 0x8c)
49de343bb6SPeter Maydell REG32(AHBSPPPC0, 0x90)
50de343bb6SPeter Maydell REG32(AHBSPPPCEXP0, 0xa0)
51de343bb6SPeter Maydell REG32(AHBSPPPCEXP1, 0xa4)
52de343bb6SPeter Maydell REG32(AHBSPPPCEXP2, 0xa8)
53de343bb6SPeter Maydell REG32(AHBSPPPCEXP3, 0xac)
54de343bb6SPeter Maydell REG32(APBSPPPC0, 0xb0)
55de343bb6SPeter Maydell REG32(APBSPPPC1, 0xb4)
56de343bb6SPeter Maydell REG32(APBSPPPCEXP0, 0xc0)
57de343bb6SPeter Maydell REG32(APBSPPPCEXP1, 0xc4)
58de343bb6SPeter Maydell REG32(APBSPPPCEXP2, 0xc8)
59de343bb6SPeter Maydell REG32(APBSPPPCEXP3, 0xcc)
60de343bb6SPeter Maydell REG32(NSMSCEXP, 0xd0)
61de343bb6SPeter Maydell REG32(PID4, 0xfd0)
62de343bb6SPeter Maydell REG32(PID5, 0xfd4)
63de343bb6SPeter Maydell REG32(PID6, 0xfd8)
64de343bb6SPeter Maydell REG32(PID7, 0xfdc)
65de343bb6SPeter Maydell REG32(PID0, 0xfe0)
66de343bb6SPeter Maydell REG32(PID1, 0xfe4)
67de343bb6SPeter Maydell REG32(PID2, 0xfe8)
68de343bb6SPeter Maydell REG32(PID3, 0xfec)
69de343bb6SPeter Maydell REG32(CID0, 0xff0)
70de343bb6SPeter Maydell REG32(CID1, 0xff4)
71de343bb6SPeter Maydell REG32(CID2, 0xff8)
72de343bb6SPeter Maydell REG32(CID3, 0xffc)
73de343bb6SPeter Maydell 
74de343bb6SPeter Maydell /* Registers in the non-secure privilege control block */
75de343bb6SPeter Maydell REG32(AHBNSPPPC0, 0x90)
76de343bb6SPeter Maydell REG32(AHBNSPPPCEXP0, 0xa0)
77de343bb6SPeter Maydell REG32(AHBNSPPPCEXP1, 0xa4)
78de343bb6SPeter Maydell REG32(AHBNSPPPCEXP2, 0xa8)
79de343bb6SPeter Maydell REG32(AHBNSPPPCEXP3, 0xac)
80de343bb6SPeter Maydell REG32(APBNSPPPC0, 0xb0)
81de343bb6SPeter Maydell REG32(APBNSPPPC1, 0xb4)
82de343bb6SPeter Maydell REG32(APBNSPPPCEXP0, 0xc0)
83de343bb6SPeter Maydell REG32(APBNSPPPCEXP1, 0xc4)
84de343bb6SPeter Maydell REG32(APBNSPPPCEXP2, 0xc8)
85de343bb6SPeter Maydell REG32(APBNSPPPCEXP3, 0xcc)
86de343bb6SPeter Maydell /* PID and CID registers are also present in the NS block */
87de343bb6SPeter Maydell 
88de343bb6SPeter Maydell static const uint8_t iotkit_secctl_s_idregs[] = {
89de343bb6SPeter Maydell     0x04, 0x00, 0x00, 0x00,
90de343bb6SPeter Maydell     0x52, 0xb8, 0x0b, 0x00,
91de343bb6SPeter Maydell     0x0d, 0xf0, 0x05, 0xb1,
92de343bb6SPeter Maydell };
93de343bb6SPeter Maydell 
94de343bb6SPeter Maydell static const uint8_t iotkit_secctl_ns_idregs[] = {
95de343bb6SPeter Maydell     0x04, 0x00, 0x00, 0x00,
96de343bb6SPeter Maydell     0x53, 0xb8, 0x0b, 0x00,
97de343bb6SPeter Maydell     0x0d, 0xf0, 0x05, 0xb1,
98de343bb6SPeter Maydell };
99de343bb6SPeter Maydell 
1000eb6b0adSPeter Maydell static const uint8_t iotkit_secctl_s_sse300_idregs[] = {
1010eb6b0adSPeter Maydell     0x04, 0x00, 0x00, 0x00,
1020eb6b0adSPeter Maydell     0x52, 0xb8, 0x2b, 0x00,
1030eb6b0adSPeter Maydell     0x0d, 0xf0, 0x05, 0xb1,
1040eb6b0adSPeter Maydell };
1050eb6b0adSPeter Maydell 
1060eb6b0adSPeter Maydell static const uint8_t iotkit_secctl_ns_sse300_idregs[] = {
1070eb6b0adSPeter Maydell     0x04, 0x00, 0x00, 0x00,
1080eb6b0adSPeter Maydell     0x53, 0xb8, 0x2b, 0x00,
1090eb6b0adSPeter Maydell     0x0d, 0xf0, 0x05, 0xb1,
1100eb6b0adSPeter Maydell };
1110eb6b0adSPeter Maydell 
1120eb6b0adSPeter Maydell 
113b3717c23SPeter Maydell /* The register sets for the various PPCs (AHB internal, APB internal,
114b3717c23SPeter Maydell  * AHB expansion, APB expansion) are all set up so that they are
115b3717c23SPeter Maydell  * in 16-aligned blocks so offsets 0xN0, 0xN4, 0xN8, 0xNC are PPCs
116b3717c23SPeter Maydell  * 0, 1, 2, 3 of that type, so we can convert a register address offset
1177a21bee2SDaniel P. Berrangé  * into an index into a PPC array easily.
118b3717c23SPeter Maydell  */
offset_to_ppc_idx(uint32_t offset)119b3717c23SPeter Maydell static inline int offset_to_ppc_idx(uint32_t offset)
120b3717c23SPeter Maydell {
121b3717c23SPeter Maydell     return extract32(offset, 2, 2);
122b3717c23SPeter Maydell }
123b3717c23SPeter Maydell 
124b3717c23SPeter Maydell typedef void PerPPCFunction(IoTKitSecCtlPPC *ppc);
125b3717c23SPeter Maydell 
foreach_ppc(IoTKitSecCtl * s,PerPPCFunction * fn)126b3717c23SPeter Maydell static void foreach_ppc(IoTKitSecCtl *s, PerPPCFunction *fn)
127b3717c23SPeter Maydell {
128b3717c23SPeter Maydell     int i;
129b3717c23SPeter Maydell 
130b3717c23SPeter Maydell     for (i = 0; i < IOTS_NUM_APB_PPC; i++) {
131b3717c23SPeter Maydell         fn(&s->apb[i]);
132b3717c23SPeter Maydell     }
133b3717c23SPeter Maydell     for (i = 0; i < IOTS_NUM_APB_EXP_PPC; i++) {
134b3717c23SPeter Maydell         fn(&s->apbexp[i]);
135b3717c23SPeter Maydell     }
136b3717c23SPeter Maydell     for (i = 0; i < IOTS_NUM_AHB_EXP_PPC; i++) {
137b3717c23SPeter Maydell         fn(&s->ahbexp[i]);
138b3717c23SPeter Maydell     }
139b3717c23SPeter Maydell }
140b3717c23SPeter Maydell 
iotkit_secctl_s_read(void * opaque,hwaddr addr,uint64_t * pdata,unsigned size,MemTxAttrs attrs)141de343bb6SPeter Maydell static MemTxResult iotkit_secctl_s_read(void *opaque, hwaddr addr,
142de343bb6SPeter Maydell                                         uint64_t *pdata,
143de343bb6SPeter Maydell                                         unsigned size, MemTxAttrs attrs)
144de343bb6SPeter Maydell {
145de343bb6SPeter Maydell     uint64_t r;
146de343bb6SPeter Maydell     uint32_t offset = addr & ~0x3;
147b3717c23SPeter Maydell     IoTKitSecCtl *s = IOTKIT_SECCTL(opaque);
148de343bb6SPeter Maydell 
149de343bb6SPeter Maydell     switch (offset) {
150de343bb6SPeter Maydell     case A_AHBNSPPC0:
151de343bb6SPeter Maydell     case A_AHBSPPPC0:
152de343bb6SPeter Maydell         r = 0;
153de343bb6SPeter Maydell         break;
154de343bb6SPeter Maydell     case A_SECRESPCFG:
155b3717c23SPeter Maydell         r = s->secrespcfg;
156b3717c23SPeter Maydell         break;
157b1ce38e1SPeter Maydell     case A_NSCCFG:
158b1ce38e1SPeter Maydell         r = s->nsccfg;
159b1ce38e1SPeter Maydell         break;
1603fd3cb2fSPeter Maydell     case A_SECMPCINTSTATUS:
1613fd3cb2fSPeter Maydell         r = s->mpcintstatus;
1623fd3cb2fSPeter Maydell         break;
163de343bb6SPeter Maydell     case A_SECPPCINTSTAT:
164b3717c23SPeter Maydell         r = s->secppcintstat;
165b3717c23SPeter Maydell         break;
166de343bb6SPeter Maydell     case A_SECPPCINTEN:
167b3717c23SPeter Maydell         r = s->secppcinten;
168b3717c23SPeter Maydell         break;
169b1ce38e1SPeter Maydell     case A_BRGINTSTAT:
170b1ce38e1SPeter Maydell         /* QEMU's bus fabric can never report errors as it doesn't buffer
171b1ce38e1SPeter Maydell          * writes, so we never report bridge interrupts.
172b1ce38e1SPeter Maydell          */
173b1ce38e1SPeter Maydell         r = 0;
174b1ce38e1SPeter Maydell         break;
175b1ce38e1SPeter Maydell     case A_BRGINTEN:
176b1ce38e1SPeter Maydell         r = s->brginten;
177b1ce38e1SPeter Maydell         break;
178de343bb6SPeter Maydell     case A_AHBNSPPCEXP0:
179de343bb6SPeter Maydell     case A_AHBNSPPCEXP1:
180de343bb6SPeter Maydell     case A_AHBNSPPCEXP2:
181de343bb6SPeter Maydell     case A_AHBNSPPCEXP3:
182b3717c23SPeter Maydell         r = s->ahbexp[offset_to_ppc_idx(offset)].ns;
183b3717c23SPeter Maydell         break;
184de343bb6SPeter Maydell     case A_APBNSPPC0:
185de343bb6SPeter Maydell     case A_APBNSPPC1:
186b3717c23SPeter Maydell         r = s->apb[offset_to_ppc_idx(offset)].ns;
187b3717c23SPeter Maydell         break;
188de343bb6SPeter Maydell     case A_APBNSPPCEXP0:
189de343bb6SPeter Maydell     case A_APBNSPPCEXP1:
190de343bb6SPeter Maydell     case A_APBNSPPCEXP2:
191de343bb6SPeter Maydell     case A_APBNSPPCEXP3:
192b3717c23SPeter Maydell         r = s->apbexp[offset_to_ppc_idx(offset)].ns;
193b3717c23SPeter Maydell         break;
194de343bb6SPeter Maydell     case A_AHBSPPPCEXP0:
195de343bb6SPeter Maydell     case A_AHBSPPPCEXP1:
196de343bb6SPeter Maydell     case A_AHBSPPPCEXP2:
197de343bb6SPeter Maydell     case A_AHBSPPPCEXP3:
198b3717c23SPeter Maydell         r = s->apbexp[offset_to_ppc_idx(offset)].sp;
199b3717c23SPeter Maydell         break;
200de343bb6SPeter Maydell     case A_APBSPPPC0:
201de343bb6SPeter Maydell     case A_APBSPPPC1:
202b3717c23SPeter Maydell         r = s->apb[offset_to_ppc_idx(offset)].sp;
203b3717c23SPeter Maydell         break;
204de343bb6SPeter Maydell     case A_APBSPPPCEXP0:
205de343bb6SPeter Maydell     case A_APBSPPPCEXP1:
206de343bb6SPeter Maydell     case A_APBSPPPCEXP2:
207de343bb6SPeter Maydell     case A_APBSPPPCEXP3:
208b3717c23SPeter Maydell         r = s->apbexp[offset_to_ppc_idx(offset)].sp;
209b3717c23SPeter Maydell         break;
210b3717c23SPeter Maydell     case A_SECMSCINTSTAT:
21181a75debSPeter Maydell         r = s->secmscintstat;
21281a75debSPeter Maydell         break;
213b3717c23SPeter Maydell     case A_SECMSCINTEN:
21481a75debSPeter Maydell         r = s->secmscinten;
21581a75debSPeter Maydell         break;
216de343bb6SPeter Maydell     case A_NSMSCEXP:
21781a75debSPeter Maydell         r = s->nsmscexp;
218de343bb6SPeter Maydell         break;
219de343bb6SPeter Maydell     case A_PID4:
220de343bb6SPeter Maydell     case A_PID5:
221de343bb6SPeter Maydell     case A_PID6:
222de343bb6SPeter Maydell     case A_PID7:
223de343bb6SPeter Maydell     case A_PID0:
224de343bb6SPeter Maydell     case A_PID1:
225de343bb6SPeter Maydell     case A_PID2:
226de343bb6SPeter Maydell     case A_PID3:
227de343bb6SPeter Maydell     case A_CID0:
228de343bb6SPeter Maydell     case A_CID1:
229de343bb6SPeter Maydell     case A_CID2:
230de343bb6SPeter Maydell     case A_CID3:
2310eb6b0adSPeter Maydell         switch (s->sse_version) {
2320eb6b0adSPeter Maydell         case ARMSSE_SSE300:
2330eb6b0adSPeter Maydell             r = iotkit_secctl_s_sse300_idregs[(offset - A_PID4) / 4];
2340eb6b0adSPeter Maydell             break;
2350eb6b0adSPeter Maydell         default:
236de343bb6SPeter Maydell             r = iotkit_secctl_s_idregs[(offset - A_PID4) / 4];
237de343bb6SPeter Maydell             break;
2380eb6b0adSPeter Maydell         }
2390eb6b0adSPeter Maydell         break;
240de343bb6SPeter Maydell     case A_SECPPCINTCLR:
241de343bb6SPeter Maydell     case A_SECMSCINTCLR:
242de343bb6SPeter Maydell     case A_BRGINTCLR:
243de343bb6SPeter Maydell         qemu_log_mask(LOG_GUEST_ERROR,
244de343bb6SPeter Maydell                       "IotKit SecCtl S block read: write-only offset 0x%x\n",
245de343bb6SPeter Maydell                       offset);
246de343bb6SPeter Maydell         r = 0;
247de343bb6SPeter Maydell         break;
248de343bb6SPeter Maydell     default:
249de343bb6SPeter Maydell         qemu_log_mask(LOG_GUEST_ERROR,
250de343bb6SPeter Maydell                       "IotKit SecCtl S block read: bad offset 0x%x\n", offset);
251de343bb6SPeter Maydell         r = 0;
252de343bb6SPeter Maydell         break;
253de343bb6SPeter Maydell     }
254de343bb6SPeter Maydell 
255de343bb6SPeter Maydell     if (size != 4) {
256de343bb6SPeter Maydell         /* None of our registers are access-sensitive, so just pull the right
257de343bb6SPeter Maydell          * byte out of the word read result.
258de343bb6SPeter Maydell          */
259de343bb6SPeter Maydell         r = extract32(r, (addr & 3) * 8, size * 8);
260de343bb6SPeter Maydell     }
261de343bb6SPeter Maydell 
262de343bb6SPeter Maydell     trace_iotkit_secctl_s_read(offset, r, size);
263de343bb6SPeter Maydell     *pdata = r;
264de343bb6SPeter Maydell     return MEMTX_OK;
265de343bb6SPeter Maydell }
266de343bb6SPeter Maydell 
iotkit_secctl_update_ppc_ap(IoTKitSecCtlPPC * ppc)267b3717c23SPeter Maydell static void iotkit_secctl_update_ppc_ap(IoTKitSecCtlPPC *ppc)
268b3717c23SPeter Maydell {
269b3717c23SPeter Maydell     int i;
270b3717c23SPeter Maydell 
271b3717c23SPeter Maydell     for (i = 0; i < ppc->numports; i++) {
272b3717c23SPeter Maydell         bool v;
273b3717c23SPeter Maydell 
274b3717c23SPeter Maydell         if (extract32(ppc->ns, i, 1)) {
275b3717c23SPeter Maydell             v = extract32(ppc->nsp, i, 1);
276b3717c23SPeter Maydell         } else {
277b3717c23SPeter Maydell             v = extract32(ppc->sp, i, 1);
278b3717c23SPeter Maydell         }
279b3717c23SPeter Maydell         qemu_set_irq(ppc->ap[i], v);
280b3717c23SPeter Maydell     }
281b3717c23SPeter Maydell }
282b3717c23SPeter Maydell 
iotkit_secctl_ppc_ns_write(IoTKitSecCtlPPC * ppc,uint32_t value)283b3717c23SPeter Maydell static void iotkit_secctl_ppc_ns_write(IoTKitSecCtlPPC *ppc, uint32_t value)
284b3717c23SPeter Maydell {
285b3717c23SPeter Maydell     int i;
286b3717c23SPeter Maydell 
287b3717c23SPeter Maydell     ppc->ns = value & MAKE_64BIT_MASK(0, ppc->numports);
288b3717c23SPeter Maydell     for (i = 0; i < ppc->numports; i++) {
289b3717c23SPeter Maydell         qemu_set_irq(ppc->nonsec[i], extract32(ppc->ns, i, 1));
290b3717c23SPeter Maydell     }
291b3717c23SPeter Maydell     iotkit_secctl_update_ppc_ap(ppc);
292b3717c23SPeter Maydell }
293b3717c23SPeter Maydell 
iotkit_secctl_ppc_sp_write(IoTKitSecCtlPPC * ppc,uint32_t value)294b3717c23SPeter Maydell static void iotkit_secctl_ppc_sp_write(IoTKitSecCtlPPC *ppc, uint32_t value)
295b3717c23SPeter Maydell {
296b3717c23SPeter Maydell     ppc->sp = value & MAKE_64BIT_MASK(0, ppc->numports);
297b3717c23SPeter Maydell     iotkit_secctl_update_ppc_ap(ppc);
298b3717c23SPeter Maydell }
299b3717c23SPeter Maydell 
iotkit_secctl_ppc_nsp_write(IoTKitSecCtlPPC * ppc,uint32_t value)300b3717c23SPeter Maydell static void iotkit_secctl_ppc_nsp_write(IoTKitSecCtlPPC *ppc, uint32_t value)
301b3717c23SPeter Maydell {
302b3717c23SPeter Maydell     ppc->nsp = value & MAKE_64BIT_MASK(0, ppc->numports);
303b3717c23SPeter Maydell     iotkit_secctl_update_ppc_ap(ppc);
304b3717c23SPeter Maydell }
305b3717c23SPeter Maydell 
iotkit_secctl_ppc_update_irq_clear(IoTKitSecCtlPPC * ppc)306b3717c23SPeter Maydell static void iotkit_secctl_ppc_update_irq_clear(IoTKitSecCtlPPC *ppc)
307b3717c23SPeter Maydell {
308b3717c23SPeter Maydell     uint32_t value = ppc->parent->secppcintstat;
309b3717c23SPeter Maydell 
310b3717c23SPeter Maydell     qemu_set_irq(ppc->irq_clear, extract32(value, ppc->irq_bit_offset, 1));
311b3717c23SPeter Maydell }
312b3717c23SPeter Maydell 
iotkit_secctl_ppc_update_irq_enable(IoTKitSecCtlPPC * ppc)313b3717c23SPeter Maydell static void iotkit_secctl_ppc_update_irq_enable(IoTKitSecCtlPPC *ppc)
314b3717c23SPeter Maydell {
315b3717c23SPeter Maydell     uint32_t value = ppc->parent->secppcinten;
316b3717c23SPeter Maydell 
317b3717c23SPeter Maydell     qemu_set_irq(ppc->irq_enable, extract32(value, ppc->irq_bit_offset, 1));
318b3717c23SPeter Maydell }
319b3717c23SPeter Maydell 
iotkit_secctl_update_mscexp_irqs(qemu_irq * msc_irqs,uint32_t value)32081a75debSPeter Maydell static void iotkit_secctl_update_mscexp_irqs(qemu_irq *msc_irqs, uint32_t value)
32181a75debSPeter Maydell {
32281a75debSPeter Maydell     int i;
32381a75debSPeter Maydell 
32481a75debSPeter Maydell     for (i = 0; i < IOTS_NUM_EXP_MSC; i++) {
32581a75debSPeter Maydell         qemu_set_irq(msc_irqs[i], extract32(value, i + 16, 1));
32681a75debSPeter Maydell     }
32781a75debSPeter Maydell }
32881a75debSPeter Maydell 
iotkit_secctl_update_msc_irq(IoTKitSecCtl * s)32981a75debSPeter Maydell static void iotkit_secctl_update_msc_irq(IoTKitSecCtl *s)
33081a75debSPeter Maydell {
33181a75debSPeter Maydell     /* Update the combined MSC IRQ, based on S_MSCEXP_STATUS and S_MSCEXP_EN */
33281a75debSPeter Maydell     bool level = s->secmscintstat & s->secmscinten;
33381a75debSPeter Maydell 
33481a75debSPeter Maydell     qemu_set_irq(s->msc_irq, level);
33581a75debSPeter Maydell }
33681a75debSPeter Maydell 
iotkit_secctl_s_write(void * opaque,hwaddr addr,uint64_t value,unsigned size,MemTxAttrs attrs)337de343bb6SPeter Maydell static MemTxResult iotkit_secctl_s_write(void *opaque, hwaddr addr,
338de343bb6SPeter Maydell                                          uint64_t value,
339de343bb6SPeter Maydell                                          unsigned size, MemTxAttrs attrs)
340de343bb6SPeter Maydell {
341b3717c23SPeter Maydell     IoTKitSecCtl *s = IOTKIT_SECCTL(opaque);
342de343bb6SPeter Maydell     uint32_t offset = addr;
343b3717c23SPeter Maydell     IoTKitSecCtlPPC *ppc;
344de343bb6SPeter Maydell 
345de343bb6SPeter Maydell     trace_iotkit_secctl_s_write(offset, value, size);
346de343bb6SPeter Maydell 
347de343bb6SPeter Maydell     if (size != 4) {
348de343bb6SPeter Maydell         /* Byte and halfword writes are ignored */
349de343bb6SPeter Maydell         qemu_log_mask(LOG_GUEST_ERROR,
350de343bb6SPeter Maydell                       "IotKit SecCtl S block write: bad size, ignored\n");
351de343bb6SPeter Maydell         return MEMTX_OK;
352de343bb6SPeter Maydell     }
353de343bb6SPeter Maydell 
354de343bb6SPeter Maydell     switch (offset) {
355b1ce38e1SPeter Maydell     case A_NSCCFG:
356b1ce38e1SPeter Maydell         s->nsccfg = value & 3;
357b1ce38e1SPeter Maydell         qemu_set_irq(s->nsc_cfg_irq, s->nsccfg);
358b1ce38e1SPeter Maydell         break;
359de343bb6SPeter Maydell     case A_SECRESPCFG:
360b3717c23SPeter Maydell         value &= 1;
361b3717c23SPeter Maydell         s->secrespcfg = value;
362b3717c23SPeter Maydell         qemu_set_irq(s->sec_resp_cfg, s->secrespcfg);
363b3717c23SPeter Maydell         break;
364de343bb6SPeter Maydell     case A_SECPPCINTCLR:
3659df7401bSPhilippe Mathieu-Daudé         s->secppcintstat &= ~(value & 0x00f000f3);
366b3717c23SPeter Maydell         foreach_ppc(s, iotkit_secctl_ppc_update_irq_clear);
367b3717c23SPeter Maydell         break;
368de343bb6SPeter Maydell     case A_SECPPCINTEN:
369b3717c23SPeter Maydell         s->secppcinten = value & 0x00f000f3;
370b3717c23SPeter Maydell         foreach_ppc(s, iotkit_secctl_ppc_update_irq_enable);
371b3717c23SPeter Maydell         break;
372b1ce38e1SPeter Maydell     case A_BRGINTCLR:
373b1ce38e1SPeter Maydell         break;
374b1ce38e1SPeter Maydell     case A_BRGINTEN:
375b1ce38e1SPeter Maydell         s->brginten = value & 0xffff0000;
376b1ce38e1SPeter Maydell         break;
377de343bb6SPeter Maydell     case A_AHBNSPPCEXP0:
378de343bb6SPeter Maydell     case A_AHBNSPPCEXP1:
379de343bb6SPeter Maydell     case A_AHBNSPPCEXP2:
380de343bb6SPeter Maydell     case A_AHBNSPPCEXP3:
381b3717c23SPeter Maydell         ppc = &s->ahbexp[offset_to_ppc_idx(offset)];
382b3717c23SPeter Maydell         iotkit_secctl_ppc_ns_write(ppc, value);
383b3717c23SPeter Maydell         break;
384de343bb6SPeter Maydell     case A_APBNSPPC0:
385de343bb6SPeter Maydell     case A_APBNSPPC1:
386b3717c23SPeter Maydell         ppc = &s->apb[offset_to_ppc_idx(offset)];
387b3717c23SPeter Maydell         iotkit_secctl_ppc_ns_write(ppc, value);
388b3717c23SPeter Maydell         break;
389de343bb6SPeter Maydell     case A_APBNSPPCEXP0:
390de343bb6SPeter Maydell     case A_APBNSPPCEXP1:
391de343bb6SPeter Maydell     case A_APBNSPPCEXP2:
392de343bb6SPeter Maydell     case A_APBNSPPCEXP3:
393b3717c23SPeter Maydell         ppc = &s->apbexp[offset_to_ppc_idx(offset)];
394b3717c23SPeter Maydell         iotkit_secctl_ppc_ns_write(ppc, value);
395b3717c23SPeter Maydell         break;
396de343bb6SPeter Maydell     case A_AHBSPPPCEXP0:
397de343bb6SPeter Maydell     case A_AHBSPPPCEXP1:
398de343bb6SPeter Maydell     case A_AHBSPPPCEXP2:
399de343bb6SPeter Maydell     case A_AHBSPPPCEXP3:
400b3717c23SPeter Maydell         ppc = &s->ahbexp[offset_to_ppc_idx(offset)];
401b3717c23SPeter Maydell         iotkit_secctl_ppc_sp_write(ppc, value);
402b3717c23SPeter Maydell         break;
403de343bb6SPeter Maydell     case A_APBSPPPC0:
404de343bb6SPeter Maydell     case A_APBSPPPC1:
405b3717c23SPeter Maydell         ppc = &s->apb[offset_to_ppc_idx(offset)];
406b3717c23SPeter Maydell         iotkit_secctl_ppc_sp_write(ppc, value);
407b3717c23SPeter Maydell         break;
408de343bb6SPeter Maydell     case A_APBSPPPCEXP0:
409de343bb6SPeter Maydell     case A_APBSPPPCEXP1:
410de343bb6SPeter Maydell     case A_APBSPPPCEXP2:
411de343bb6SPeter Maydell     case A_APBSPPPCEXP3:
412b3717c23SPeter Maydell         ppc = &s->apbexp[offset_to_ppc_idx(offset)];
413b3717c23SPeter Maydell         iotkit_secctl_ppc_sp_write(ppc, value);
414b3717c23SPeter Maydell         break;
415b3717c23SPeter Maydell     case A_SECMSCINTCLR:
41681a75debSPeter Maydell         iotkit_secctl_update_mscexp_irqs(s->mscexp_clear, value);
41781a75debSPeter Maydell         break;
418b3717c23SPeter Maydell     case A_SECMSCINTEN:
41981a75debSPeter Maydell         s->secmscinten = value;
42081a75debSPeter Maydell         iotkit_secctl_update_msc_irq(s);
42181a75debSPeter Maydell         break;
42281a75debSPeter Maydell     case A_NSMSCEXP:
42381a75debSPeter Maydell         s->nsmscexp = value;
42481a75debSPeter Maydell         iotkit_secctl_update_mscexp_irqs(s->mscexp_ns, value);
425de343bb6SPeter Maydell         break;
426de343bb6SPeter Maydell     case A_SECMPCINTSTATUS:
427de343bb6SPeter Maydell     case A_SECPPCINTSTAT:
428de343bb6SPeter Maydell     case A_SECMSCINTSTAT:
429de343bb6SPeter Maydell     case A_BRGINTSTAT:
430de343bb6SPeter Maydell     case A_AHBNSPPC0:
431de343bb6SPeter Maydell     case A_AHBSPPPC0:
432de343bb6SPeter Maydell     case A_PID4:
433de343bb6SPeter Maydell     case A_PID5:
434de343bb6SPeter Maydell     case A_PID6:
435de343bb6SPeter Maydell     case A_PID7:
436de343bb6SPeter Maydell     case A_PID0:
437de343bb6SPeter Maydell     case A_PID1:
438de343bb6SPeter Maydell     case A_PID2:
439de343bb6SPeter Maydell     case A_PID3:
440de343bb6SPeter Maydell     case A_CID0:
441de343bb6SPeter Maydell     case A_CID1:
442de343bb6SPeter Maydell     case A_CID2:
443de343bb6SPeter Maydell     case A_CID3:
444de343bb6SPeter Maydell         qemu_log_mask(LOG_GUEST_ERROR,
445de343bb6SPeter Maydell                       "IoTKit SecCtl S block write: "
446de343bb6SPeter Maydell                       "read-only offset 0x%x\n", offset);
447de343bb6SPeter Maydell         break;
448de343bb6SPeter Maydell     default:
449de343bb6SPeter Maydell         qemu_log_mask(LOG_GUEST_ERROR,
450de343bb6SPeter Maydell                       "IotKit SecCtl S block write: bad offset 0x%x\n",
451de343bb6SPeter Maydell                       offset);
452de343bb6SPeter Maydell         break;
453de343bb6SPeter Maydell     }
454de343bb6SPeter Maydell 
455de343bb6SPeter Maydell     return MEMTX_OK;
456de343bb6SPeter Maydell }
457de343bb6SPeter Maydell 
iotkit_secctl_ns_read(void * opaque,hwaddr addr,uint64_t * pdata,unsigned size,MemTxAttrs attrs)458de343bb6SPeter Maydell static MemTxResult iotkit_secctl_ns_read(void *opaque, hwaddr addr,
459de343bb6SPeter Maydell                                          uint64_t *pdata,
460de343bb6SPeter Maydell                                          unsigned size, MemTxAttrs attrs)
461de343bb6SPeter Maydell {
462b3717c23SPeter Maydell     IoTKitSecCtl *s = IOTKIT_SECCTL(opaque);
463de343bb6SPeter Maydell     uint64_t r;
464de343bb6SPeter Maydell     uint32_t offset = addr & ~0x3;
465de343bb6SPeter Maydell 
466de343bb6SPeter Maydell     switch (offset) {
467de343bb6SPeter Maydell     case A_AHBNSPPPC0:
468de343bb6SPeter Maydell         r = 0;
469de343bb6SPeter Maydell         break;
470de343bb6SPeter Maydell     case A_AHBNSPPPCEXP0:
471de343bb6SPeter Maydell     case A_AHBNSPPPCEXP1:
472de343bb6SPeter Maydell     case A_AHBNSPPPCEXP2:
473de343bb6SPeter Maydell     case A_AHBNSPPPCEXP3:
474b3717c23SPeter Maydell         r = s->ahbexp[offset_to_ppc_idx(offset)].nsp;
475b3717c23SPeter Maydell         break;
476de343bb6SPeter Maydell     case A_APBNSPPPC0:
477de343bb6SPeter Maydell     case A_APBNSPPPC1:
478b3717c23SPeter Maydell         r = s->apb[offset_to_ppc_idx(offset)].nsp;
479b3717c23SPeter Maydell         break;
480de343bb6SPeter Maydell     case A_APBNSPPPCEXP0:
481de343bb6SPeter Maydell     case A_APBNSPPPCEXP1:
482de343bb6SPeter Maydell     case A_APBNSPPPCEXP2:
483de343bb6SPeter Maydell     case A_APBNSPPPCEXP3:
484b3717c23SPeter Maydell         r = s->apbexp[offset_to_ppc_idx(offset)].nsp;
485de343bb6SPeter Maydell         break;
486de343bb6SPeter Maydell     case A_PID4:
487de343bb6SPeter Maydell     case A_PID5:
488de343bb6SPeter Maydell     case A_PID6:
489de343bb6SPeter Maydell     case A_PID7:
490de343bb6SPeter Maydell     case A_PID0:
491de343bb6SPeter Maydell     case A_PID1:
492de343bb6SPeter Maydell     case A_PID2:
493de343bb6SPeter Maydell     case A_PID3:
494de343bb6SPeter Maydell     case A_CID0:
495de343bb6SPeter Maydell     case A_CID1:
496de343bb6SPeter Maydell     case A_CID2:
497de343bb6SPeter Maydell     case A_CID3:
4980eb6b0adSPeter Maydell         switch (s->sse_version) {
4990eb6b0adSPeter Maydell         case ARMSSE_SSE300:
5000eb6b0adSPeter Maydell             r = iotkit_secctl_ns_sse300_idregs[(offset - A_PID4) / 4];
5010eb6b0adSPeter Maydell             break;
5020eb6b0adSPeter Maydell         default:
503de343bb6SPeter Maydell             r = iotkit_secctl_ns_idregs[(offset - A_PID4) / 4];
504de343bb6SPeter Maydell             break;
5050eb6b0adSPeter Maydell         }
5060eb6b0adSPeter Maydell         break;
507de343bb6SPeter Maydell     default:
508de343bb6SPeter Maydell         qemu_log_mask(LOG_GUEST_ERROR,
509de343bb6SPeter Maydell                       "IotKit SecCtl NS block write: bad offset 0x%x\n",
510de343bb6SPeter Maydell                       offset);
511de343bb6SPeter Maydell         r = 0;
512de343bb6SPeter Maydell         break;
513de343bb6SPeter Maydell     }
514de343bb6SPeter Maydell 
515de343bb6SPeter Maydell     if (size != 4) {
516de343bb6SPeter Maydell         /* None of our registers are access-sensitive, so just pull the right
517de343bb6SPeter Maydell          * byte out of the word read result.
518de343bb6SPeter Maydell          */
519de343bb6SPeter Maydell         r = extract32(r, (addr & 3) * 8, size * 8);
520de343bb6SPeter Maydell     }
521de343bb6SPeter Maydell 
522de343bb6SPeter Maydell     trace_iotkit_secctl_ns_read(offset, r, size);
523de343bb6SPeter Maydell     *pdata = r;
524de343bb6SPeter Maydell     return MEMTX_OK;
525de343bb6SPeter Maydell }
526de343bb6SPeter Maydell 
iotkit_secctl_ns_write(void * opaque,hwaddr addr,uint64_t value,unsigned size,MemTxAttrs attrs)527de343bb6SPeter Maydell static MemTxResult iotkit_secctl_ns_write(void *opaque, hwaddr addr,
528de343bb6SPeter Maydell                                           uint64_t value,
529de343bb6SPeter Maydell                                           unsigned size, MemTxAttrs attrs)
530de343bb6SPeter Maydell {
531b3717c23SPeter Maydell     IoTKitSecCtl *s = IOTKIT_SECCTL(opaque);
532de343bb6SPeter Maydell     uint32_t offset = addr;
533b3717c23SPeter Maydell     IoTKitSecCtlPPC *ppc;
534de343bb6SPeter Maydell 
535de343bb6SPeter Maydell     trace_iotkit_secctl_ns_write(offset, value, size);
536de343bb6SPeter Maydell 
537de343bb6SPeter Maydell     if (size != 4) {
538de343bb6SPeter Maydell         /* Byte and halfword writes are ignored */
539de343bb6SPeter Maydell         qemu_log_mask(LOG_GUEST_ERROR,
540de343bb6SPeter Maydell                       "IotKit SecCtl NS block write: bad size, ignored\n");
541de343bb6SPeter Maydell         return MEMTX_OK;
542de343bb6SPeter Maydell     }
543de343bb6SPeter Maydell 
544de343bb6SPeter Maydell     switch (offset) {
545de343bb6SPeter Maydell     case A_AHBNSPPPCEXP0:
546de343bb6SPeter Maydell     case A_AHBNSPPPCEXP1:
547de343bb6SPeter Maydell     case A_AHBNSPPPCEXP2:
548de343bb6SPeter Maydell     case A_AHBNSPPPCEXP3:
549b3717c23SPeter Maydell         ppc = &s->ahbexp[offset_to_ppc_idx(offset)];
550b3717c23SPeter Maydell         iotkit_secctl_ppc_nsp_write(ppc, value);
551b3717c23SPeter Maydell         break;
552de343bb6SPeter Maydell     case A_APBNSPPPC0:
553de343bb6SPeter Maydell     case A_APBNSPPPC1:
554b3717c23SPeter Maydell         ppc = &s->apb[offset_to_ppc_idx(offset)];
555b3717c23SPeter Maydell         iotkit_secctl_ppc_nsp_write(ppc, value);
556b3717c23SPeter Maydell         break;
557de343bb6SPeter Maydell     case A_APBNSPPPCEXP0:
558de343bb6SPeter Maydell     case A_APBNSPPPCEXP1:
559de343bb6SPeter Maydell     case A_APBNSPPPCEXP2:
560de343bb6SPeter Maydell     case A_APBNSPPPCEXP3:
561b3717c23SPeter Maydell         ppc = &s->apbexp[offset_to_ppc_idx(offset)];
562b3717c23SPeter Maydell         iotkit_secctl_ppc_nsp_write(ppc, value);
563de343bb6SPeter Maydell         break;
564de343bb6SPeter Maydell     case A_AHBNSPPPC0:
565de343bb6SPeter Maydell     case A_PID4:
566de343bb6SPeter Maydell     case A_PID5:
567de343bb6SPeter Maydell     case A_PID6:
568de343bb6SPeter Maydell     case A_PID7:
569de343bb6SPeter Maydell     case A_PID0:
570de343bb6SPeter Maydell     case A_PID1:
571de343bb6SPeter Maydell     case A_PID2:
572de343bb6SPeter Maydell     case A_PID3:
573de343bb6SPeter Maydell     case A_CID0:
574de343bb6SPeter Maydell     case A_CID1:
575de343bb6SPeter Maydell     case A_CID2:
576de343bb6SPeter Maydell     case A_CID3:
577de343bb6SPeter Maydell         qemu_log_mask(LOG_GUEST_ERROR,
578de343bb6SPeter Maydell                       "IoTKit SecCtl NS block write: "
579de343bb6SPeter Maydell                       "read-only offset 0x%x\n", offset);
580de343bb6SPeter Maydell         break;
581de343bb6SPeter Maydell     default:
582de343bb6SPeter Maydell         qemu_log_mask(LOG_GUEST_ERROR,
583de343bb6SPeter Maydell                       "IotKit SecCtl NS block write: bad offset 0x%x\n",
584de343bb6SPeter Maydell                       offset);
585de343bb6SPeter Maydell         break;
586de343bb6SPeter Maydell     }
587de343bb6SPeter Maydell 
588de343bb6SPeter Maydell     return MEMTX_OK;
589de343bb6SPeter Maydell }
590de343bb6SPeter Maydell 
591de343bb6SPeter Maydell static const MemoryRegionOps iotkit_secctl_s_ops = {
592de343bb6SPeter Maydell     .read_with_attrs = iotkit_secctl_s_read,
593de343bb6SPeter Maydell     .write_with_attrs = iotkit_secctl_s_write,
594de343bb6SPeter Maydell     .endianness = DEVICE_LITTLE_ENDIAN,
595de343bb6SPeter Maydell     .valid.min_access_size = 1,
596de343bb6SPeter Maydell     .valid.max_access_size = 4,
597de343bb6SPeter Maydell     .impl.min_access_size = 1,
598de343bb6SPeter Maydell     .impl.max_access_size = 4,
599de343bb6SPeter Maydell };
600de343bb6SPeter Maydell 
601de343bb6SPeter Maydell static const MemoryRegionOps iotkit_secctl_ns_ops = {
602de343bb6SPeter Maydell     .read_with_attrs = iotkit_secctl_ns_read,
603de343bb6SPeter Maydell     .write_with_attrs = iotkit_secctl_ns_write,
604de343bb6SPeter Maydell     .endianness = DEVICE_LITTLE_ENDIAN,
605de343bb6SPeter Maydell     .valid.min_access_size = 1,
606de343bb6SPeter Maydell     .valid.max_access_size = 4,
607de343bb6SPeter Maydell     .impl.min_access_size = 1,
608de343bb6SPeter Maydell     .impl.max_access_size = 4,
609de343bb6SPeter Maydell };
610de343bb6SPeter Maydell 
iotkit_secctl_reset_ppc(IoTKitSecCtlPPC * ppc)611b3717c23SPeter Maydell static void iotkit_secctl_reset_ppc(IoTKitSecCtlPPC *ppc)
612b3717c23SPeter Maydell {
613b3717c23SPeter Maydell     ppc->ns = 0;
614b3717c23SPeter Maydell     ppc->sp = 0;
615b3717c23SPeter Maydell     ppc->nsp = 0;
616b3717c23SPeter Maydell }
617b3717c23SPeter Maydell 
iotkit_secctl_reset(DeviceState * dev)618de343bb6SPeter Maydell static void iotkit_secctl_reset(DeviceState *dev)
619de343bb6SPeter Maydell {
620b3717c23SPeter Maydell     IoTKitSecCtl *s = IOTKIT_SECCTL(dev);
621de343bb6SPeter Maydell 
622b3717c23SPeter Maydell     s->secppcintstat = 0;
623b3717c23SPeter Maydell     s->secppcinten = 0;
624b3717c23SPeter Maydell     s->secrespcfg = 0;
625b1ce38e1SPeter Maydell     s->nsccfg = 0;
626b1ce38e1SPeter Maydell     s->brginten = 0;
627b3717c23SPeter Maydell 
628b3717c23SPeter Maydell     foreach_ppc(s, iotkit_secctl_reset_ppc);
629b3717c23SPeter Maydell }
630b3717c23SPeter Maydell 
iotkit_secctl_mpc_status(void * opaque,int n,int level)6313fd3cb2fSPeter Maydell static void iotkit_secctl_mpc_status(void *opaque, int n, int level)
6323fd3cb2fSPeter Maydell {
6333fd3cb2fSPeter Maydell     IoTKitSecCtl *s = IOTKIT_SECCTL(opaque);
6343fd3cb2fSPeter Maydell 
6350a78d7ebSPeter Maydell     s->mpcintstatus = deposit32(s->mpcintstatus, n, 1, !!level);
6363fd3cb2fSPeter Maydell }
6373fd3cb2fSPeter Maydell 
iotkit_secctl_mpcexp_status(void * opaque,int n,int level)6383fd3cb2fSPeter Maydell static void iotkit_secctl_mpcexp_status(void *opaque, int n, int level)
6393fd3cb2fSPeter Maydell {
6403fd3cb2fSPeter Maydell     IoTKitSecCtl *s = IOTKIT_SECCTL(opaque);
6413fd3cb2fSPeter Maydell 
6423fd3cb2fSPeter Maydell     s->mpcintstatus = deposit32(s->mpcintstatus, n + 16, 1, !!level);
6433fd3cb2fSPeter Maydell }
6443fd3cb2fSPeter Maydell 
iotkit_secctl_mscexp_status(void * opaque,int n,int level)64581a75debSPeter Maydell static void iotkit_secctl_mscexp_status(void *opaque, int n, int level)
64681a75debSPeter Maydell {
64781a75debSPeter Maydell     IoTKitSecCtl *s = IOTKIT_SECCTL(opaque);
64881a75debSPeter Maydell 
64981a75debSPeter Maydell     s->secmscintstat = deposit32(s->secmscintstat, n + 16, 1, !!level);
65081a75debSPeter Maydell     iotkit_secctl_update_msc_irq(s);
65181a75debSPeter Maydell }
65281a75debSPeter Maydell 
iotkit_secctl_ppc_irqstatus(void * opaque,int n,int level)653b3717c23SPeter Maydell static void iotkit_secctl_ppc_irqstatus(void *opaque, int n, int level)
654b3717c23SPeter Maydell {
655b3717c23SPeter Maydell     IoTKitSecCtlPPC *ppc = opaque;
656b3717c23SPeter Maydell     IoTKitSecCtl *s = IOTKIT_SECCTL(ppc->parent);
657b3717c23SPeter Maydell     int irqbit = ppc->irq_bit_offset + n;
658b3717c23SPeter Maydell 
659b3717c23SPeter Maydell     s->secppcintstat = deposit32(s->secppcintstat, irqbit, 1, level);
660b3717c23SPeter Maydell }
661b3717c23SPeter Maydell 
iotkit_secctl_init_ppc(IoTKitSecCtl * s,IoTKitSecCtlPPC * ppc,const char * name,int numports,int irq_bit_offset)662b3717c23SPeter Maydell static void iotkit_secctl_init_ppc(IoTKitSecCtl *s,
663b3717c23SPeter Maydell                                    IoTKitSecCtlPPC *ppc,
664b3717c23SPeter Maydell                                    const char *name,
665b3717c23SPeter Maydell                                    int numports,
666b3717c23SPeter Maydell                                    int irq_bit_offset)
667b3717c23SPeter Maydell {
668b3717c23SPeter Maydell     char *gpioname;
669b3717c23SPeter Maydell     DeviceState *dev = DEVICE(s);
670b3717c23SPeter Maydell 
671b3717c23SPeter Maydell     ppc->numports = numports;
672b3717c23SPeter Maydell     ppc->irq_bit_offset = irq_bit_offset;
673b3717c23SPeter Maydell     ppc->parent = s;
674b3717c23SPeter Maydell 
675b3717c23SPeter Maydell     gpioname = g_strdup_printf("%s_nonsec", name);
676b3717c23SPeter Maydell     qdev_init_gpio_out_named(dev, ppc->nonsec, gpioname, numports);
677b3717c23SPeter Maydell     g_free(gpioname);
678b3717c23SPeter Maydell     gpioname = g_strdup_printf("%s_ap", name);
679b3717c23SPeter Maydell     qdev_init_gpio_out_named(dev, ppc->ap, gpioname, numports);
680b3717c23SPeter Maydell     g_free(gpioname);
681b3717c23SPeter Maydell     gpioname = g_strdup_printf("%s_irq_enable", name);
682b3717c23SPeter Maydell     qdev_init_gpio_out_named(dev, &ppc->irq_enable, gpioname, 1);
683b3717c23SPeter Maydell     g_free(gpioname);
684b3717c23SPeter Maydell     gpioname = g_strdup_printf("%s_irq_clear", name);
685b3717c23SPeter Maydell     qdev_init_gpio_out_named(dev, &ppc->irq_clear, gpioname, 1);
686b3717c23SPeter Maydell     g_free(gpioname);
687b3717c23SPeter Maydell     gpioname = g_strdup_printf("%s_irq_status", name);
688b3717c23SPeter Maydell     qdev_init_gpio_in_named_with_opaque(dev, iotkit_secctl_ppc_irqstatus,
689b3717c23SPeter Maydell                                         ppc, gpioname, 1);
690b3717c23SPeter Maydell     g_free(gpioname);
691de343bb6SPeter Maydell }
692de343bb6SPeter Maydell 
iotkit_secctl_init(Object * obj)693de343bb6SPeter Maydell static void iotkit_secctl_init(Object *obj)
694de343bb6SPeter Maydell {
695de343bb6SPeter Maydell     IoTKitSecCtl *s = IOTKIT_SECCTL(obj);
696de343bb6SPeter Maydell     SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
697b3717c23SPeter Maydell     DeviceState *dev = DEVICE(obj);
698b3717c23SPeter Maydell     int i;
699b3717c23SPeter Maydell 
700b3717c23SPeter Maydell     iotkit_secctl_init_ppc(s, &s->apb[0], "apb_ppc0",
701b3717c23SPeter Maydell                            IOTS_APB_PPC0_NUM_PORTS, 0);
702b3717c23SPeter Maydell     iotkit_secctl_init_ppc(s, &s->apb[1], "apb_ppc1",
703b3717c23SPeter Maydell                            IOTS_APB_PPC1_NUM_PORTS, 1);
704b3717c23SPeter Maydell 
705b3717c23SPeter Maydell     for (i = 0; i < IOTS_NUM_APB_EXP_PPC; i++) {
706b3717c23SPeter Maydell         IoTKitSecCtlPPC *ppc = &s->apbexp[i];
707b3717c23SPeter Maydell         char *ppcname = g_strdup_printf("apb_ppcexp%d", i);
708b3717c23SPeter Maydell         iotkit_secctl_init_ppc(s, ppc, ppcname, IOTS_PPC_NUM_PORTS, 4 + i);
709b3717c23SPeter Maydell         g_free(ppcname);
710b3717c23SPeter Maydell     }
711b3717c23SPeter Maydell     for (i = 0; i < IOTS_NUM_AHB_EXP_PPC; i++) {
712b3717c23SPeter Maydell         IoTKitSecCtlPPC *ppc = &s->ahbexp[i];
713b3717c23SPeter Maydell         char *ppcname = g_strdup_printf("ahb_ppcexp%d", i);
714b3717c23SPeter Maydell         iotkit_secctl_init_ppc(s, ppc, ppcname, IOTS_PPC_NUM_PORTS, 20 + i);
715b3717c23SPeter Maydell         g_free(ppcname);
716b3717c23SPeter Maydell     }
717b3717c23SPeter Maydell 
718b3717c23SPeter Maydell     qdev_init_gpio_out_named(dev, &s->sec_resp_cfg, "sec_resp_cfg", 1);
719b1ce38e1SPeter Maydell     qdev_init_gpio_out_named(dev, &s->nsc_cfg_irq, "nsc_cfg", 1);
720de343bb6SPeter Maydell 
7210a78d7ebSPeter Maydell     qdev_init_gpio_in_named(dev, iotkit_secctl_mpc_status, "mpc_status",
7220a78d7ebSPeter Maydell                             IOTS_NUM_MPC);
7233fd3cb2fSPeter Maydell     qdev_init_gpio_in_named(dev, iotkit_secctl_mpcexp_status,
7243fd3cb2fSPeter Maydell                             "mpcexp_status", IOTS_NUM_EXP_MPC);
7253fd3cb2fSPeter Maydell 
72681a75debSPeter Maydell     qdev_init_gpio_in_named(dev, iotkit_secctl_mscexp_status,
72781a75debSPeter Maydell                             "mscexp_status", IOTS_NUM_EXP_MSC);
72881a75debSPeter Maydell     qdev_init_gpio_out_named(dev, s->mscexp_clear, "mscexp_clear",
72981a75debSPeter Maydell                              IOTS_NUM_EXP_MSC);
73081a75debSPeter Maydell     qdev_init_gpio_out_named(dev, s->mscexp_ns, "mscexp_ns",
73181a75debSPeter Maydell                              IOTS_NUM_EXP_MSC);
73281a75debSPeter Maydell     qdev_init_gpio_out_named(dev, &s->msc_irq, "msc_irq", 1);
73381a75debSPeter Maydell 
734de343bb6SPeter Maydell     memory_region_init_io(&s->s_regs, obj, &iotkit_secctl_s_ops,
735de343bb6SPeter Maydell                           s, "iotkit-secctl-s-regs", 0x1000);
736de343bb6SPeter Maydell     memory_region_init_io(&s->ns_regs, obj, &iotkit_secctl_ns_ops,
737de343bb6SPeter Maydell                           s, "iotkit-secctl-ns-regs", 0x1000);
738de343bb6SPeter Maydell     sysbus_init_mmio(sbd, &s->s_regs);
739de343bb6SPeter Maydell     sysbus_init_mmio(sbd, &s->ns_regs);
740de343bb6SPeter Maydell }
741de343bb6SPeter Maydell 
iotkit_secctl_realize(DeviceState * dev,Error ** errp)7420eb6b0adSPeter Maydell static void iotkit_secctl_realize(DeviceState *dev, Error **errp)
7430eb6b0adSPeter Maydell {
7440eb6b0adSPeter Maydell     IoTKitSecCtl *s = IOTKIT_SECCTL(dev);
7450eb6b0adSPeter Maydell 
7460eb6b0adSPeter Maydell     if (!armsse_version_valid(s->sse_version)) {
7470eb6b0adSPeter Maydell         error_setg(errp, "invalid sse-version value %d", s->sse_version);
7480eb6b0adSPeter Maydell         return;
7490eb6b0adSPeter Maydell     }
7500eb6b0adSPeter Maydell }
7510eb6b0adSPeter Maydell 
752b3717c23SPeter Maydell static const VMStateDescription iotkit_secctl_ppc_vmstate = {
753b3717c23SPeter Maydell     .name = "iotkit-secctl-ppc",
754b3717c23SPeter Maydell     .version_id = 1,
755b3717c23SPeter Maydell     .minimum_version_id = 1,
756e4ea952fSRichard Henderson     .fields = (const VMStateField[]) {
757b3717c23SPeter Maydell         VMSTATE_UINT32(ns, IoTKitSecCtlPPC),
758b3717c23SPeter Maydell         VMSTATE_UINT32(sp, IoTKitSecCtlPPC),
759b3717c23SPeter Maydell         VMSTATE_UINT32(nsp, IoTKitSecCtlPPC),
760b3717c23SPeter Maydell         VMSTATE_END_OF_LIST()
761b3717c23SPeter Maydell     }
762b3717c23SPeter Maydell };
763b3717c23SPeter Maydell 
7643fd3cb2fSPeter Maydell static const VMStateDescription iotkit_secctl_mpcintstatus_vmstate = {
7653fd3cb2fSPeter Maydell     .name = "iotkit-secctl-mpcintstatus",
7663fd3cb2fSPeter Maydell     .version_id = 1,
7673fd3cb2fSPeter Maydell     .minimum_version_id = 1,
768e4ea952fSRichard Henderson     .fields = (const VMStateField[]) {
7693fd3cb2fSPeter Maydell         VMSTATE_UINT32(mpcintstatus, IoTKitSecCtl),
7703fd3cb2fSPeter Maydell         VMSTATE_END_OF_LIST()
7713fd3cb2fSPeter Maydell     }
7723fd3cb2fSPeter Maydell };
7733fd3cb2fSPeter Maydell 
needed_always(void * opaque)77481a75debSPeter Maydell static bool needed_always(void *opaque)
77581a75debSPeter Maydell {
77681a75debSPeter Maydell     return true;
77781a75debSPeter Maydell }
77881a75debSPeter Maydell 
77981a75debSPeter Maydell static const VMStateDescription iotkit_secctl_msc_vmstate = {
78081a75debSPeter Maydell     .name = "iotkit-secctl/msc",
78181a75debSPeter Maydell     .version_id = 1,
78281a75debSPeter Maydell     .minimum_version_id = 1,
78381a75debSPeter Maydell     .needed = needed_always,
784e4ea952fSRichard Henderson     .fields = (const VMStateField[]) {
78581a75debSPeter Maydell         VMSTATE_UINT32(secmscintstat, IoTKitSecCtl),
78681a75debSPeter Maydell         VMSTATE_UINT32(secmscinten, IoTKitSecCtl),
78781a75debSPeter Maydell         VMSTATE_UINT32(nsmscexp, IoTKitSecCtl),
78881a75debSPeter Maydell         VMSTATE_END_OF_LIST()
78981a75debSPeter Maydell     }
79081a75debSPeter Maydell };
79181a75debSPeter Maydell 
792de343bb6SPeter Maydell static const VMStateDescription iotkit_secctl_vmstate = {
793de343bb6SPeter Maydell     .name = "iotkit-secctl",
794de343bb6SPeter Maydell     .version_id = 1,
795de343bb6SPeter Maydell     .minimum_version_id = 1,
796e4ea952fSRichard Henderson     .fields = (const VMStateField[]) {
797b3717c23SPeter Maydell         VMSTATE_UINT32(secppcintstat, IoTKitSecCtl),
798b3717c23SPeter Maydell         VMSTATE_UINT32(secppcinten, IoTKitSecCtl),
799b3717c23SPeter Maydell         VMSTATE_UINT32(secrespcfg, IoTKitSecCtl),
800b1ce38e1SPeter Maydell         VMSTATE_UINT32(nsccfg, IoTKitSecCtl),
801b1ce38e1SPeter Maydell         VMSTATE_UINT32(brginten, IoTKitSecCtl),
802b3717c23SPeter Maydell         VMSTATE_STRUCT_ARRAY(apb, IoTKitSecCtl, IOTS_NUM_APB_PPC, 1,
803b3717c23SPeter Maydell                              iotkit_secctl_ppc_vmstate, IoTKitSecCtlPPC),
804b3717c23SPeter Maydell         VMSTATE_STRUCT_ARRAY(apbexp, IoTKitSecCtl, IOTS_NUM_APB_EXP_PPC, 1,
805b3717c23SPeter Maydell                              iotkit_secctl_ppc_vmstate, IoTKitSecCtlPPC),
806b3717c23SPeter Maydell         VMSTATE_STRUCT_ARRAY(ahbexp, IoTKitSecCtl, IOTS_NUM_AHB_EXP_PPC, 1,
807b3717c23SPeter Maydell                              iotkit_secctl_ppc_vmstate, IoTKitSecCtlPPC),
808de343bb6SPeter Maydell         VMSTATE_END_OF_LIST()
8093fd3cb2fSPeter Maydell     },
810e4ea952fSRichard Henderson     .subsections = (const VMStateDescription * const []) {
8113fd3cb2fSPeter Maydell         &iotkit_secctl_mpcintstatus_vmstate,
81281a75debSPeter Maydell         &iotkit_secctl_msc_vmstate,
8133fd3cb2fSPeter Maydell         NULL
8143fd3cb2fSPeter Maydell     },
815de343bb6SPeter Maydell };
816de343bb6SPeter Maydell 
81730029973SRichard Henderson static const Property iotkit_secctl_props[] = {
8180eb6b0adSPeter Maydell     DEFINE_PROP_UINT32("sse-version", IoTKitSecCtl, sse_version, 0),
8190eb6b0adSPeter Maydell };
8200eb6b0adSPeter Maydell 
iotkit_secctl_class_init(ObjectClass * klass,const void * data)821*12d1a768SPhilippe Mathieu-Daudé static void iotkit_secctl_class_init(ObjectClass *klass, const void *data)
822de343bb6SPeter Maydell {
823de343bb6SPeter Maydell     DeviceClass *dc = DEVICE_CLASS(klass);
824de343bb6SPeter Maydell 
825de343bb6SPeter Maydell     dc->vmsd = &iotkit_secctl_vmstate;
826e3d08143SPeter Maydell     device_class_set_legacy_reset(dc, iotkit_secctl_reset);
8270eb6b0adSPeter Maydell     dc->realize = iotkit_secctl_realize;
8280eb6b0adSPeter Maydell     device_class_set_props(dc, iotkit_secctl_props);
829de343bb6SPeter Maydell }
830de343bb6SPeter Maydell 
831de343bb6SPeter Maydell static const TypeInfo iotkit_secctl_info = {
832de343bb6SPeter Maydell     .name = TYPE_IOTKIT_SECCTL,
833de343bb6SPeter Maydell     .parent = TYPE_SYS_BUS_DEVICE,
834de343bb6SPeter Maydell     .instance_size = sizeof(IoTKitSecCtl),
835de343bb6SPeter Maydell     .instance_init = iotkit_secctl_init,
836de343bb6SPeter Maydell     .class_init = iotkit_secctl_class_init,
837de343bb6SPeter Maydell };
838de343bb6SPeter Maydell 
iotkit_secctl_register_types(void)839de343bb6SPeter Maydell static void iotkit_secctl_register_types(void)
840de343bb6SPeter Maydell {
841de343bb6SPeter Maydell     type_register_static(&iotkit_secctl_info);
842de343bb6SPeter Maydell }
843de343bb6SPeter Maydell 
844de343bb6SPeter Maydell type_init(iotkit_secctl_register_types);
845