xics/spapr: Rename xics_kvm_init()
[qemu/ar7.git] / hw / misc / iotkit-secctl.c
blob58fd94b14fe6b1260db45a97f3a3789537a04338
1 /*
2 * Arm IoT Kit security controller
4 * Copyright (c) 2018 Linaro Limited
5 * Written by Peter Maydell
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 or
9 * (at your option) any later version.
12 #include "qemu/osdep.h"
13 #include "qemu/log.h"
14 #include "qemu/module.h"
15 #include "qapi/error.h"
16 #include "trace.h"
17 #include "hw/sysbus.h"
18 #include "hw/registerfields.h"
19 #include "hw/misc/iotkit-secctl.h"
21 /* Registers in the secure privilege control block */
22 REG32(SECRESPCFG, 0x10)
23 REG32(NSCCFG, 0x14)
24 REG32(SECMPCINTSTATUS, 0x1c)
25 REG32(SECPPCINTSTAT, 0x20)
26 REG32(SECPPCINTCLR, 0x24)
27 REG32(SECPPCINTEN, 0x28)
28 REG32(SECMSCINTSTAT, 0x30)
29 REG32(SECMSCINTCLR, 0x34)
30 REG32(SECMSCINTEN, 0x38)
31 REG32(BRGINTSTAT, 0x40)
32 REG32(BRGINTCLR, 0x44)
33 REG32(BRGINTEN, 0x48)
34 REG32(AHBNSPPC0, 0x50)
35 REG32(AHBNSPPCEXP0, 0x60)
36 REG32(AHBNSPPCEXP1, 0x64)
37 REG32(AHBNSPPCEXP2, 0x68)
38 REG32(AHBNSPPCEXP3, 0x6c)
39 REG32(APBNSPPC0, 0x70)
40 REG32(APBNSPPC1, 0x74)
41 REG32(APBNSPPCEXP0, 0x80)
42 REG32(APBNSPPCEXP1, 0x84)
43 REG32(APBNSPPCEXP2, 0x88)
44 REG32(APBNSPPCEXP3, 0x8c)
45 REG32(AHBSPPPC0, 0x90)
46 REG32(AHBSPPPCEXP0, 0xa0)
47 REG32(AHBSPPPCEXP1, 0xa4)
48 REG32(AHBSPPPCEXP2, 0xa8)
49 REG32(AHBSPPPCEXP3, 0xac)
50 REG32(APBSPPPC0, 0xb0)
51 REG32(APBSPPPC1, 0xb4)
52 REG32(APBSPPPCEXP0, 0xc0)
53 REG32(APBSPPPCEXP1, 0xc4)
54 REG32(APBSPPPCEXP2, 0xc8)
55 REG32(APBSPPPCEXP3, 0xcc)
56 REG32(NSMSCEXP, 0xd0)
57 REG32(PID4, 0xfd0)
58 REG32(PID5, 0xfd4)
59 REG32(PID6, 0xfd8)
60 REG32(PID7, 0xfdc)
61 REG32(PID0, 0xfe0)
62 REG32(PID1, 0xfe4)
63 REG32(PID2, 0xfe8)
64 REG32(PID3, 0xfec)
65 REG32(CID0, 0xff0)
66 REG32(CID1, 0xff4)
67 REG32(CID2, 0xff8)
68 REG32(CID3, 0xffc)
70 /* Registers in the non-secure privilege control block */
71 REG32(AHBNSPPPC0, 0x90)
72 REG32(AHBNSPPPCEXP0, 0xa0)
73 REG32(AHBNSPPPCEXP1, 0xa4)
74 REG32(AHBNSPPPCEXP2, 0xa8)
75 REG32(AHBNSPPPCEXP3, 0xac)
76 REG32(APBNSPPPC0, 0xb0)
77 REG32(APBNSPPPC1, 0xb4)
78 REG32(APBNSPPPCEXP0, 0xc0)
79 REG32(APBNSPPPCEXP1, 0xc4)
80 REG32(APBNSPPPCEXP2, 0xc8)
81 REG32(APBNSPPPCEXP3, 0xcc)
82 /* PID and CID registers are also present in the NS block */
84 static const uint8_t iotkit_secctl_s_idregs[] = {
85 0x04, 0x00, 0x00, 0x00,
86 0x52, 0xb8, 0x0b, 0x00,
87 0x0d, 0xf0, 0x05, 0xb1,
90 static const uint8_t iotkit_secctl_ns_idregs[] = {
91 0x04, 0x00, 0x00, 0x00,
92 0x53, 0xb8, 0x0b, 0x00,
93 0x0d, 0xf0, 0x05, 0xb1,
96 /* The register sets for the various PPCs (AHB internal, APB internal,
97 * AHB expansion, APB expansion) are all set up so that they are
98 * in 16-aligned blocks so offsets 0xN0, 0xN4, 0xN8, 0xNC are PPCs
99 * 0, 1, 2, 3 of that type, so we can convert a register address offset
100 * into an an index into a PPC array easily.
102 static inline int offset_to_ppc_idx(uint32_t offset)
104 return extract32(offset, 2, 2);
107 typedef void PerPPCFunction(IoTKitSecCtlPPC *ppc);
109 static void foreach_ppc(IoTKitSecCtl *s, PerPPCFunction *fn)
111 int i;
113 for (i = 0; i < IOTS_NUM_APB_PPC; i++) {
114 fn(&s->apb[i]);
116 for (i = 0; i < IOTS_NUM_APB_EXP_PPC; i++) {
117 fn(&s->apbexp[i]);
119 for (i = 0; i < IOTS_NUM_AHB_EXP_PPC; i++) {
120 fn(&s->ahbexp[i]);
124 static MemTxResult iotkit_secctl_s_read(void *opaque, hwaddr addr,
125 uint64_t *pdata,
126 unsigned size, MemTxAttrs attrs)
128 uint64_t r;
129 uint32_t offset = addr & ~0x3;
130 IoTKitSecCtl *s = IOTKIT_SECCTL(opaque);
132 switch (offset) {
133 case A_AHBNSPPC0:
134 case A_AHBSPPPC0:
135 r = 0;
136 break;
137 case A_SECRESPCFG:
138 r = s->secrespcfg;
139 break;
140 case A_NSCCFG:
141 r = s->nsccfg;
142 break;
143 case A_SECMPCINTSTATUS:
144 r = s->mpcintstatus;
145 break;
146 case A_SECPPCINTSTAT:
147 r = s->secppcintstat;
148 break;
149 case A_SECPPCINTEN:
150 r = s->secppcinten;
151 break;
152 case A_BRGINTSTAT:
153 /* QEMU's bus fabric can never report errors as it doesn't buffer
154 * writes, so we never report bridge interrupts.
156 r = 0;
157 break;
158 case A_BRGINTEN:
159 r = s->brginten;
160 break;
161 case A_AHBNSPPCEXP0:
162 case A_AHBNSPPCEXP1:
163 case A_AHBNSPPCEXP2:
164 case A_AHBNSPPCEXP3:
165 r = s->ahbexp[offset_to_ppc_idx(offset)].ns;
166 break;
167 case A_APBNSPPC0:
168 case A_APBNSPPC1:
169 r = s->apb[offset_to_ppc_idx(offset)].ns;
170 break;
171 case A_APBNSPPCEXP0:
172 case A_APBNSPPCEXP1:
173 case A_APBNSPPCEXP2:
174 case A_APBNSPPCEXP3:
175 r = s->apbexp[offset_to_ppc_idx(offset)].ns;
176 break;
177 case A_AHBSPPPCEXP0:
178 case A_AHBSPPPCEXP1:
179 case A_AHBSPPPCEXP2:
180 case A_AHBSPPPCEXP3:
181 r = s->apbexp[offset_to_ppc_idx(offset)].sp;
182 break;
183 case A_APBSPPPC0:
184 case A_APBSPPPC1:
185 r = s->apb[offset_to_ppc_idx(offset)].sp;
186 break;
187 case A_APBSPPPCEXP0:
188 case A_APBSPPPCEXP1:
189 case A_APBSPPPCEXP2:
190 case A_APBSPPPCEXP3:
191 r = s->apbexp[offset_to_ppc_idx(offset)].sp;
192 break;
193 case A_SECMSCINTSTAT:
194 r = s->secmscintstat;
195 break;
196 case A_SECMSCINTEN:
197 r = s->secmscinten;
198 break;
199 case A_NSMSCEXP:
200 r = s->nsmscexp;
201 break;
202 case A_PID4:
203 case A_PID5:
204 case A_PID6:
205 case A_PID7:
206 case A_PID0:
207 case A_PID1:
208 case A_PID2:
209 case A_PID3:
210 case A_CID0:
211 case A_CID1:
212 case A_CID2:
213 case A_CID3:
214 r = iotkit_secctl_s_idregs[(offset - A_PID4) / 4];
215 break;
216 case A_SECPPCINTCLR:
217 case A_SECMSCINTCLR:
218 case A_BRGINTCLR:
219 qemu_log_mask(LOG_GUEST_ERROR,
220 "IotKit SecCtl S block read: write-only offset 0x%x\n",
221 offset);
222 r = 0;
223 break;
224 default:
225 qemu_log_mask(LOG_GUEST_ERROR,
226 "IotKit SecCtl S block read: bad offset 0x%x\n", offset);
227 r = 0;
228 break;
231 if (size != 4) {
232 /* None of our registers are access-sensitive, so just pull the right
233 * byte out of the word read result.
235 r = extract32(r, (addr & 3) * 8, size * 8);
238 trace_iotkit_secctl_s_read(offset, r, size);
239 *pdata = r;
240 return MEMTX_OK;
243 static void iotkit_secctl_update_ppc_ap(IoTKitSecCtlPPC *ppc)
245 int i;
247 for (i = 0; i < ppc->numports; i++) {
248 bool v;
250 if (extract32(ppc->ns, i, 1)) {
251 v = extract32(ppc->nsp, i, 1);
252 } else {
253 v = extract32(ppc->sp, i, 1);
255 qemu_set_irq(ppc->ap[i], v);
259 static void iotkit_secctl_ppc_ns_write(IoTKitSecCtlPPC *ppc, uint32_t value)
261 int i;
263 ppc->ns = value & MAKE_64BIT_MASK(0, ppc->numports);
264 for (i = 0; i < ppc->numports; i++) {
265 qemu_set_irq(ppc->nonsec[i], extract32(ppc->ns, i, 1));
267 iotkit_secctl_update_ppc_ap(ppc);
270 static void iotkit_secctl_ppc_sp_write(IoTKitSecCtlPPC *ppc, uint32_t value)
272 ppc->sp = value & MAKE_64BIT_MASK(0, ppc->numports);
273 iotkit_secctl_update_ppc_ap(ppc);
276 static void iotkit_secctl_ppc_nsp_write(IoTKitSecCtlPPC *ppc, uint32_t value)
278 ppc->nsp = value & MAKE_64BIT_MASK(0, ppc->numports);
279 iotkit_secctl_update_ppc_ap(ppc);
282 static void iotkit_secctl_ppc_update_irq_clear(IoTKitSecCtlPPC *ppc)
284 uint32_t value = ppc->parent->secppcintstat;
286 qemu_set_irq(ppc->irq_clear, extract32(value, ppc->irq_bit_offset, 1));
289 static void iotkit_secctl_ppc_update_irq_enable(IoTKitSecCtlPPC *ppc)
291 uint32_t value = ppc->parent->secppcinten;
293 qemu_set_irq(ppc->irq_enable, extract32(value, ppc->irq_bit_offset, 1));
296 static void iotkit_secctl_update_mscexp_irqs(qemu_irq *msc_irqs, uint32_t value)
298 int i;
300 for (i = 0; i < IOTS_NUM_EXP_MSC; i++) {
301 qemu_set_irq(msc_irqs[i], extract32(value, i + 16, 1));
305 static void iotkit_secctl_update_msc_irq(IoTKitSecCtl *s)
307 /* Update the combined MSC IRQ, based on S_MSCEXP_STATUS and S_MSCEXP_EN */
308 bool level = s->secmscintstat & s->secmscinten;
310 qemu_set_irq(s->msc_irq, level);
313 static MemTxResult iotkit_secctl_s_write(void *opaque, hwaddr addr,
314 uint64_t value,
315 unsigned size, MemTxAttrs attrs)
317 IoTKitSecCtl *s = IOTKIT_SECCTL(opaque);
318 uint32_t offset = addr;
319 IoTKitSecCtlPPC *ppc;
321 trace_iotkit_secctl_s_write(offset, value, size);
323 if (size != 4) {
324 /* Byte and halfword writes are ignored */
325 qemu_log_mask(LOG_GUEST_ERROR,
326 "IotKit SecCtl S block write: bad size, ignored\n");
327 return MEMTX_OK;
330 switch (offset) {
331 case A_NSCCFG:
332 s->nsccfg = value & 3;
333 qemu_set_irq(s->nsc_cfg_irq, s->nsccfg);
334 break;
335 case A_SECRESPCFG:
336 value &= 1;
337 s->secrespcfg = value;
338 qemu_set_irq(s->sec_resp_cfg, s->secrespcfg);
339 break;
340 case A_SECPPCINTCLR:
341 value &= 0x00f000f3;
342 foreach_ppc(s, iotkit_secctl_ppc_update_irq_clear);
343 break;
344 case A_SECPPCINTEN:
345 s->secppcinten = value & 0x00f000f3;
346 foreach_ppc(s, iotkit_secctl_ppc_update_irq_enable);
347 break;
348 case A_BRGINTCLR:
349 break;
350 case A_BRGINTEN:
351 s->brginten = value & 0xffff0000;
352 break;
353 case A_AHBNSPPCEXP0:
354 case A_AHBNSPPCEXP1:
355 case A_AHBNSPPCEXP2:
356 case A_AHBNSPPCEXP3:
357 ppc = &s->ahbexp[offset_to_ppc_idx(offset)];
358 iotkit_secctl_ppc_ns_write(ppc, value);
359 break;
360 case A_APBNSPPC0:
361 case A_APBNSPPC1:
362 ppc = &s->apb[offset_to_ppc_idx(offset)];
363 iotkit_secctl_ppc_ns_write(ppc, value);
364 break;
365 case A_APBNSPPCEXP0:
366 case A_APBNSPPCEXP1:
367 case A_APBNSPPCEXP2:
368 case A_APBNSPPCEXP3:
369 ppc = &s->apbexp[offset_to_ppc_idx(offset)];
370 iotkit_secctl_ppc_ns_write(ppc, value);
371 break;
372 case A_AHBSPPPCEXP0:
373 case A_AHBSPPPCEXP1:
374 case A_AHBSPPPCEXP2:
375 case A_AHBSPPPCEXP3:
376 ppc = &s->ahbexp[offset_to_ppc_idx(offset)];
377 iotkit_secctl_ppc_sp_write(ppc, value);
378 break;
379 case A_APBSPPPC0:
380 case A_APBSPPPC1:
381 ppc = &s->apb[offset_to_ppc_idx(offset)];
382 iotkit_secctl_ppc_sp_write(ppc, value);
383 break;
384 case A_APBSPPPCEXP0:
385 case A_APBSPPPCEXP1:
386 case A_APBSPPPCEXP2:
387 case A_APBSPPPCEXP3:
388 ppc = &s->apbexp[offset_to_ppc_idx(offset)];
389 iotkit_secctl_ppc_sp_write(ppc, value);
390 break;
391 case A_SECMSCINTCLR:
392 iotkit_secctl_update_mscexp_irqs(s->mscexp_clear, value);
393 break;
394 case A_SECMSCINTEN:
395 s->secmscinten = value;
396 iotkit_secctl_update_msc_irq(s);
397 break;
398 case A_NSMSCEXP:
399 s->nsmscexp = value;
400 iotkit_secctl_update_mscexp_irqs(s->mscexp_ns, value);
401 break;
402 case A_SECMPCINTSTATUS:
403 case A_SECPPCINTSTAT:
404 case A_SECMSCINTSTAT:
405 case A_BRGINTSTAT:
406 case A_AHBNSPPC0:
407 case A_AHBSPPPC0:
408 case A_PID4:
409 case A_PID5:
410 case A_PID6:
411 case A_PID7:
412 case A_PID0:
413 case A_PID1:
414 case A_PID2:
415 case A_PID3:
416 case A_CID0:
417 case A_CID1:
418 case A_CID2:
419 case A_CID3:
420 qemu_log_mask(LOG_GUEST_ERROR,
421 "IoTKit SecCtl S block write: "
422 "read-only offset 0x%x\n", offset);
423 break;
424 default:
425 qemu_log_mask(LOG_GUEST_ERROR,
426 "IotKit SecCtl S block write: bad offset 0x%x\n",
427 offset);
428 break;
431 return MEMTX_OK;
434 static MemTxResult iotkit_secctl_ns_read(void *opaque, hwaddr addr,
435 uint64_t *pdata,
436 unsigned size, MemTxAttrs attrs)
438 IoTKitSecCtl *s = IOTKIT_SECCTL(opaque);
439 uint64_t r;
440 uint32_t offset = addr & ~0x3;
442 switch (offset) {
443 case A_AHBNSPPPC0:
444 r = 0;
445 break;
446 case A_AHBNSPPPCEXP0:
447 case A_AHBNSPPPCEXP1:
448 case A_AHBNSPPPCEXP2:
449 case A_AHBNSPPPCEXP3:
450 r = s->ahbexp[offset_to_ppc_idx(offset)].nsp;
451 break;
452 case A_APBNSPPPC0:
453 case A_APBNSPPPC1:
454 r = s->apb[offset_to_ppc_idx(offset)].nsp;
455 break;
456 case A_APBNSPPPCEXP0:
457 case A_APBNSPPPCEXP1:
458 case A_APBNSPPPCEXP2:
459 case A_APBNSPPPCEXP3:
460 r = s->apbexp[offset_to_ppc_idx(offset)].nsp;
461 break;
462 case A_PID4:
463 case A_PID5:
464 case A_PID6:
465 case A_PID7:
466 case A_PID0:
467 case A_PID1:
468 case A_PID2:
469 case A_PID3:
470 case A_CID0:
471 case A_CID1:
472 case A_CID2:
473 case A_CID3:
474 r = iotkit_secctl_ns_idregs[(offset - A_PID4) / 4];
475 break;
476 default:
477 qemu_log_mask(LOG_GUEST_ERROR,
478 "IotKit SecCtl NS block write: bad offset 0x%x\n",
479 offset);
480 r = 0;
481 break;
484 if (size != 4) {
485 /* None of our registers are access-sensitive, so just pull the right
486 * byte out of the word read result.
488 r = extract32(r, (addr & 3) * 8, size * 8);
491 trace_iotkit_secctl_ns_read(offset, r, size);
492 *pdata = r;
493 return MEMTX_OK;
496 static MemTxResult iotkit_secctl_ns_write(void *opaque, hwaddr addr,
497 uint64_t value,
498 unsigned size, MemTxAttrs attrs)
500 IoTKitSecCtl *s = IOTKIT_SECCTL(opaque);
501 uint32_t offset = addr;
502 IoTKitSecCtlPPC *ppc;
504 trace_iotkit_secctl_ns_write(offset, value, size);
506 if (size != 4) {
507 /* Byte and halfword writes are ignored */
508 qemu_log_mask(LOG_GUEST_ERROR,
509 "IotKit SecCtl NS block write: bad size, ignored\n");
510 return MEMTX_OK;
513 switch (offset) {
514 case A_AHBNSPPPCEXP0:
515 case A_AHBNSPPPCEXP1:
516 case A_AHBNSPPPCEXP2:
517 case A_AHBNSPPPCEXP3:
518 ppc = &s->ahbexp[offset_to_ppc_idx(offset)];
519 iotkit_secctl_ppc_nsp_write(ppc, value);
520 break;
521 case A_APBNSPPPC0:
522 case A_APBNSPPPC1:
523 ppc = &s->apb[offset_to_ppc_idx(offset)];
524 iotkit_secctl_ppc_nsp_write(ppc, value);
525 break;
526 case A_APBNSPPPCEXP0:
527 case A_APBNSPPPCEXP1:
528 case A_APBNSPPPCEXP2:
529 case A_APBNSPPPCEXP3:
530 ppc = &s->apbexp[offset_to_ppc_idx(offset)];
531 iotkit_secctl_ppc_nsp_write(ppc, value);
532 break;
533 case A_AHBNSPPPC0:
534 case A_PID4:
535 case A_PID5:
536 case A_PID6:
537 case A_PID7:
538 case A_PID0:
539 case A_PID1:
540 case A_PID2:
541 case A_PID3:
542 case A_CID0:
543 case A_CID1:
544 case A_CID2:
545 case A_CID3:
546 qemu_log_mask(LOG_GUEST_ERROR,
547 "IoTKit SecCtl NS block write: "
548 "read-only offset 0x%x\n", offset);
549 break;
550 default:
551 qemu_log_mask(LOG_GUEST_ERROR,
552 "IotKit SecCtl NS block write: bad offset 0x%x\n",
553 offset);
554 break;
557 return MEMTX_OK;
560 static const MemoryRegionOps iotkit_secctl_s_ops = {
561 .read_with_attrs = iotkit_secctl_s_read,
562 .write_with_attrs = iotkit_secctl_s_write,
563 .endianness = DEVICE_LITTLE_ENDIAN,
564 .valid.min_access_size = 1,
565 .valid.max_access_size = 4,
566 .impl.min_access_size = 1,
567 .impl.max_access_size = 4,
570 static const MemoryRegionOps iotkit_secctl_ns_ops = {
571 .read_with_attrs = iotkit_secctl_ns_read,
572 .write_with_attrs = iotkit_secctl_ns_write,
573 .endianness = DEVICE_LITTLE_ENDIAN,
574 .valid.min_access_size = 1,
575 .valid.max_access_size = 4,
576 .impl.min_access_size = 1,
577 .impl.max_access_size = 4,
580 static void iotkit_secctl_reset_ppc(IoTKitSecCtlPPC *ppc)
582 ppc->ns = 0;
583 ppc->sp = 0;
584 ppc->nsp = 0;
587 static void iotkit_secctl_reset(DeviceState *dev)
589 IoTKitSecCtl *s = IOTKIT_SECCTL(dev);
591 s->secppcintstat = 0;
592 s->secppcinten = 0;
593 s->secrespcfg = 0;
594 s->nsccfg = 0;
595 s->brginten = 0;
597 foreach_ppc(s, iotkit_secctl_reset_ppc);
600 static void iotkit_secctl_mpc_status(void *opaque, int n, int level)
602 IoTKitSecCtl *s = IOTKIT_SECCTL(opaque);
604 s->mpcintstatus = deposit32(s->mpcintstatus, n, 1, !!level);
607 static void iotkit_secctl_mpcexp_status(void *opaque, int n, int level)
609 IoTKitSecCtl *s = IOTKIT_SECCTL(opaque);
611 s->mpcintstatus = deposit32(s->mpcintstatus, n + 16, 1, !!level);
614 static void iotkit_secctl_mscexp_status(void *opaque, int n, int level)
616 IoTKitSecCtl *s = IOTKIT_SECCTL(opaque);
618 s->secmscintstat = deposit32(s->secmscintstat, n + 16, 1, !!level);
619 iotkit_secctl_update_msc_irq(s);
622 static void iotkit_secctl_ppc_irqstatus(void *opaque, int n, int level)
624 IoTKitSecCtlPPC *ppc = opaque;
625 IoTKitSecCtl *s = IOTKIT_SECCTL(ppc->parent);
626 int irqbit = ppc->irq_bit_offset + n;
628 s->secppcintstat = deposit32(s->secppcintstat, irqbit, 1, level);
631 static void iotkit_secctl_init_ppc(IoTKitSecCtl *s,
632 IoTKitSecCtlPPC *ppc,
633 const char *name,
634 int numports,
635 int irq_bit_offset)
637 char *gpioname;
638 DeviceState *dev = DEVICE(s);
640 ppc->numports = numports;
641 ppc->irq_bit_offset = irq_bit_offset;
642 ppc->parent = s;
644 gpioname = g_strdup_printf("%s_nonsec", name);
645 qdev_init_gpio_out_named(dev, ppc->nonsec, gpioname, numports);
646 g_free(gpioname);
647 gpioname = g_strdup_printf("%s_ap", name);
648 qdev_init_gpio_out_named(dev, ppc->ap, gpioname, numports);
649 g_free(gpioname);
650 gpioname = g_strdup_printf("%s_irq_enable", name);
651 qdev_init_gpio_out_named(dev, &ppc->irq_enable, gpioname, 1);
652 g_free(gpioname);
653 gpioname = g_strdup_printf("%s_irq_clear", name);
654 qdev_init_gpio_out_named(dev, &ppc->irq_clear, gpioname, 1);
655 g_free(gpioname);
656 gpioname = g_strdup_printf("%s_irq_status", name);
657 qdev_init_gpio_in_named_with_opaque(dev, iotkit_secctl_ppc_irqstatus,
658 ppc, gpioname, 1);
659 g_free(gpioname);
662 static void iotkit_secctl_init(Object *obj)
664 IoTKitSecCtl *s = IOTKIT_SECCTL(obj);
665 SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
666 DeviceState *dev = DEVICE(obj);
667 int i;
669 iotkit_secctl_init_ppc(s, &s->apb[0], "apb_ppc0",
670 IOTS_APB_PPC0_NUM_PORTS, 0);
671 iotkit_secctl_init_ppc(s, &s->apb[1], "apb_ppc1",
672 IOTS_APB_PPC1_NUM_PORTS, 1);
674 for (i = 0; i < IOTS_NUM_APB_EXP_PPC; i++) {
675 IoTKitSecCtlPPC *ppc = &s->apbexp[i];
676 char *ppcname = g_strdup_printf("apb_ppcexp%d", i);
677 iotkit_secctl_init_ppc(s, ppc, ppcname, IOTS_PPC_NUM_PORTS, 4 + i);
678 g_free(ppcname);
680 for (i = 0; i < IOTS_NUM_AHB_EXP_PPC; i++) {
681 IoTKitSecCtlPPC *ppc = &s->ahbexp[i];
682 char *ppcname = g_strdup_printf("ahb_ppcexp%d", i);
683 iotkit_secctl_init_ppc(s, ppc, ppcname, IOTS_PPC_NUM_PORTS, 20 + i);
684 g_free(ppcname);
687 qdev_init_gpio_out_named(dev, &s->sec_resp_cfg, "sec_resp_cfg", 1);
688 qdev_init_gpio_out_named(dev, &s->nsc_cfg_irq, "nsc_cfg", 1);
690 qdev_init_gpio_in_named(dev, iotkit_secctl_mpc_status, "mpc_status",
691 IOTS_NUM_MPC);
692 qdev_init_gpio_in_named(dev, iotkit_secctl_mpcexp_status,
693 "mpcexp_status", IOTS_NUM_EXP_MPC);
695 qdev_init_gpio_in_named(dev, iotkit_secctl_mscexp_status,
696 "mscexp_status", IOTS_NUM_EXP_MSC);
697 qdev_init_gpio_out_named(dev, s->mscexp_clear, "mscexp_clear",
698 IOTS_NUM_EXP_MSC);
699 qdev_init_gpio_out_named(dev, s->mscexp_ns, "mscexp_ns",
700 IOTS_NUM_EXP_MSC);
701 qdev_init_gpio_out_named(dev, &s->msc_irq, "msc_irq", 1);
703 memory_region_init_io(&s->s_regs, obj, &iotkit_secctl_s_ops,
704 s, "iotkit-secctl-s-regs", 0x1000);
705 memory_region_init_io(&s->ns_regs, obj, &iotkit_secctl_ns_ops,
706 s, "iotkit-secctl-ns-regs", 0x1000);
707 sysbus_init_mmio(sbd, &s->s_regs);
708 sysbus_init_mmio(sbd, &s->ns_regs);
711 static const VMStateDescription iotkit_secctl_ppc_vmstate = {
712 .name = "iotkit-secctl-ppc",
713 .version_id = 1,
714 .minimum_version_id = 1,
715 .fields = (VMStateField[]) {
716 VMSTATE_UINT32(ns, IoTKitSecCtlPPC),
717 VMSTATE_UINT32(sp, IoTKitSecCtlPPC),
718 VMSTATE_UINT32(nsp, IoTKitSecCtlPPC),
719 VMSTATE_END_OF_LIST()
723 static const VMStateDescription iotkit_secctl_mpcintstatus_vmstate = {
724 .name = "iotkit-secctl-mpcintstatus",
725 .version_id = 1,
726 .minimum_version_id = 1,
727 .fields = (VMStateField[]) {
728 VMSTATE_UINT32(mpcintstatus, IoTKitSecCtl),
729 VMSTATE_END_OF_LIST()
733 static bool needed_always(void *opaque)
735 return true;
738 static const VMStateDescription iotkit_secctl_msc_vmstate = {
739 .name = "iotkit-secctl/msc",
740 .version_id = 1,
741 .minimum_version_id = 1,
742 .needed = needed_always,
743 .fields = (VMStateField[]) {
744 VMSTATE_UINT32(secmscintstat, IoTKitSecCtl),
745 VMSTATE_UINT32(secmscinten, IoTKitSecCtl),
746 VMSTATE_UINT32(nsmscexp, IoTKitSecCtl),
747 VMSTATE_END_OF_LIST()
751 static const VMStateDescription iotkit_secctl_vmstate = {
752 .name = "iotkit-secctl",
753 .version_id = 1,
754 .minimum_version_id = 1,
755 .fields = (VMStateField[]) {
756 VMSTATE_UINT32(secppcintstat, IoTKitSecCtl),
757 VMSTATE_UINT32(secppcinten, IoTKitSecCtl),
758 VMSTATE_UINT32(secrespcfg, IoTKitSecCtl),
759 VMSTATE_UINT32(nsccfg, IoTKitSecCtl),
760 VMSTATE_UINT32(brginten, IoTKitSecCtl),
761 VMSTATE_STRUCT_ARRAY(apb, IoTKitSecCtl, IOTS_NUM_APB_PPC, 1,
762 iotkit_secctl_ppc_vmstate, IoTKitSecCtlPPC),
763 VMSTATE_STRUCT_ARRAY(apbexp, IoTKitSecCtl, IOTS_NUM_APB_EXP_PPC, 1,
764 iotkit_secctl_ppc_vmstate, IoTKitSecCtlPPC),
765 VMSTATE_STRUCT_ARRAY(ahbexp, IoTKitSecCtl, IOTS_NUM_AHB_EXP_PPC, 1,
766 iotkit_secctl_ppc_vmstate, IoTKitSecCtlPPC),
767 VMSTATE_END_OF_LIST()
769 .subsections = (const VMStateDescription*[]) {
770 &iotkit_secctl_mpcintstatus_vmstate,
771 &iotkit_secctl_msc_vmstate,
772 NULL
776 static void iotkit_secctl_class_init(ObjectClass *klass, void *data)
778 DeviceClass *dc = DEVICE_CLASS(klass);
780 dc->vmsd = &iotkit_secctl_vmstate;
781 dc->reset = iotkit_secctl_reset;
784 static const TypeInfo iotkit_secctl_info = {
785 .name = TYPE_IOTKIT_SECCTL,
786 .parent = TYPE_SYS_BUS_DEVICE,
787 .instance_size = sizeof(IoTKitSecCtl),
788 .instance_init = iotkit_secctl_init,
789 .class_init = iotkit_secctl_class_init,
792 static void iotkit_secctl_register_types(void)
794 type_register_static(&iotkit_secctl_info);
797 type_init(iotkit_secctl_register_types);