1
2
3
4
5
6
7
8
9
10
11
12#include "qemu/osdep.h"
13#include "qemu/log.h"
14#include "qapi/error.h"
15#include "trace.h"
16#include "hw/sysbus.h"
17#include "hw/registerfields.h"
18#include "hw/misc/iotkit-secctl.h"
19
20
21REG32(SECRESPCFG, 0x10)
22REG32(NSCCFG, 0x14)
23REG32(SECMPCINTSTATUS, 0x1c)
24REG32(SECPPCINTSTAT, 0x20)
25REG32(SECPPCINTCLR, 0x24)
26REG32(SECPPCINTEN, 0x28)
27REG32(SECMSCINTSTAT, 0x30)
28REG32(SECMSCINTCLR, 0x34)
29REG32(SECMSCINTEN, 0x38)
30REG32(BRGINTSTAT, 0x40)
31REG32(BRGINTCLR, 0x44)
32REG32(BRGINTEN, 0x48)
33REG32(AHBNSPPC0, 0x50)
34REG32(AHBNSPPCEXP0, 0x60)
35REG32(AHBNSPPCEXP1, 0x64)
36REG32(AHBNSPPCEXP2, 0x68)
37REG32(AHBNSPPCEXP3, 0x6c)
38REG32(APBNSPPC0, 0x70)
39REG32(APBNSPPC1, 0x74)
40REG32(APBNSPPCEXP0, 0x80)
41REG32(APBNSPPCEXP1, 0x84)
42REG32(APBNSPPCEXP2, 0x88)
43REG32(APBNSPPCEXP3, 0x8c)
44REG32(AHBSPPPC0, 0x90)
45REG32(AHBSPPPCEXP0, 0xa0)
46REG32(AHBSPPPCEXP1, 0xa4)
47REG32(AHBSPPPCEXP2, 0xa8)
48REG32(AHBSPPPCEXP3, 0xac)
49REG32(APBSPPPC0, 0xb0)
50REG32(APBSPPPC1, 0xb4)
51REG32(APBSPPPCEXP0, 0xc0)
52REG32(APBSPPPCEXP1, 0xc4)
53REG32(APBSPPPCEXP2, 0xc8)
54REG32(APBSPPPCEXP3, 0xcc)
55REG32(NSMSCEXP, 0xd0)
56REG32(PID4, 0xfd0)
57REG32(PID5, 0xfd4)
58REG32(PID6, 0xfd8)
59REG32(PID7, 0xfdc)
60REG32(PID0, 0xfe0)
61REG32(PID1, 0xfe4)
62REG32(PID2, 0xfe8)
63REG32(PID3, 0xfec)
64REG32(CID0, 0xff0)
65REG32(CID1, 0xff4)
66REG32(CID2, 0xff8)
67REG32(CID3, 0xffc)
68
69
70REG32(AHBNSPPPC0, 0x90)
71REG32(AHBNSPPPCEXP0, 0xa0)
72REG32(AHBNSPPPCEXP1, 0xa4)
73REG32(AHBNSPPPCEXP2, 0xa8)
74REG32(AHBNSPPPCEXP3, 0xac)
75REG32(APBNSPPPC0, 0xb0)
76REG32(APBNSPPPC1, 0xb4)
77REG32(APBNSPPPCEXP0, 0xc0)
78REG32(APBNSPPPCEXP1, 0xc4)
79REG32(APBNSPPPCEXP2, 0xc8)
80REG32(APBNSPPPCEXP3, 0xcc)
81
82
83static const uint8_t iotkit_secctl_s_idregs[] = {
84 0x04, 0x00, 0x00, 0x00,
85 0x52, 0xb8, 0x0b, 0x00,
86 0x0d, 0xf0, 0x05, 0xb1,
87};
88
89static const uint8_t iotkit_secctl_ns_idregs[] = {
90 0x04, 0x00, 0x00, 0x00,
91 0x53, 0xb8, 0x0b, 0x00,
92 0x0d, 0xf0, 0x05, 0xb1,
93};
94
95
96
97
98
99
100
101static inline int offset_to_ppc_idx(uint32_t offset)
102{
103 return extract32(offset, 2, 2);
104}
105
106typedef void PerPPCFunction(IoTKitSecCtlPPC *ppc);
107
108static void foreach_ppc(IoTKitSecCtl *s, PerPPCFunction *fn)
109{
110 int i;
111
112 for (i = 0; i < IOTS_NUM_APB_PPC; i++) {
113 fn(&s->apb[i]);
114 }
115 for (i = 0; i < IOTS_NUM_APB_EXP_PPC; i++) {
116 fn(&s->apbexp[i]);
117 }
118 for (i = 0; i < IOTS_NUM_AHB_EXP_PPC; i++) {
119 fn(&s->ahbexp[i]);
120 }
121}
122
123static MemTxResult iotkit_secctl_s_read(void *opaque, hwaddr addr,
124 uint64_t *pdata,
125 unsigned size, MemTxAttrs attrs)
126{
127 uint64_t r;
128 uint32_t offset = addr & ~0x3;
129 IoTKitSecCtl *s = IOTKIT_SECCTL(opaque);
130
131 switch (offset) {
132 case A_AHBNSPPC0:
133 case A_AHBSPPPC0:
134 r = 0;
135 break;
136 case A_SECRESPCFG:
137 r = s->secrespcfg;
138 break;
139 case A_NSCCFG:
140 r = s->nsccfg;
141 break;
142 case A_SECMPCINTSTATUS:
143 r = s->mpcintstatus;
144 break;
145 case A_SECPPCINTSTAT:
146 r = s->secppcintstat;
147 break;
148 case A_SECPPCINTEN:
149 r = s->secppcinten;
150 break;
151 case A_BRGINTSTAT:
152
153
154
155 r = 0;
156 break;
157 case A_BRGINTEN:
158 r = s->brginten;
159 break;
160 case A_AHBNSPPCEXP0:
161 case A_AHBNSPPCEXP1:
162 case A_AHBNSPPCEXP2:
163 case A_AHBNSPPCEXP3:
164 r = s->ahbexp[offset_to_ppc_idx(offset)].ns;
165 break;
166 case A_APBNSPPC0:
167 case A_APBNSPPC1:
168 r = s->apb[offset_to_ppc_idx(offset)].ns;
169 break;
170 case A_APBNSPPCEXP0:
171 case A_APBNSPPCEXP1:
172 case A_APBNSPPCEXP2:
173 case A_APBNSPPCEXP3:
174 r = s->apbexp[offset_to_ppc_idx(offset)].ns;
175 break;
176 case A_AHBSPPPCEXP0:
177 case A_AHBSPPPCEXP1:
178 case A_AHBSPPPCEXP2:
179 case A_AHBSPPPCEXP3:
180 r = s->apbexp[offset_to_ppc_idx(offset)].sp;
181 break;
182 case A_APBSPPPC0:
183 case A_APBSPPPC1:
184 r = s->apb[offset_to_ppc_idx(offset)].sp;
185 break;
186 case A_APBSPPPCEXP0:
187 case A_APBSPPPCEXP1:
188 case A_APBSPPPCEXP2:
189 case A_APBSPPPCEXP3:
190 r = s->apbexp[offset_to_ppc_idx(offset)].sp;
191 break;
192 case A_SECMSCINTSTAT:
193 case A_SECMSCINTEN:
194 case A_NSMSCEXP:
195 qemu_log_mask(LOG_UNIMP,
196 "IoTKit SecCtl S block read: "
197 "unimplemented offset 0x%x\n", offset);
198 r = 0;
199 break;
200 case A_PID4:
201 case A_PID5:
202 case A_PID6:
203 case A_PID7:
204 case A_PID0:
205 case A_PID1:
206 case A_PID2:
207 case A_PID3:
208 case A_CID0:
209 case A_CID1:
210 case A_CID2:
211 case A_CID3:
212 r = iotkit_secctl_s_idregs[(offset - A_PID4) / 4];
213 break;
214 case A_SECPPCINTCLR:
215 case A_SECMSCINTCLR:
216 case A_BRGINTCLR:
217 qemu_log_mask(LOG_GUEST_ERROR,
218 "IotKit SecCtl S block read: write-only offset 0x%x\n",
219 offset);
220 r = 0;
221 break;
222 default:
223 qemu_log_mask(LOG_GUEST_ERROR,
224 "IotKit SecCtl S block read: bad offset 0x%x\n", offset);
225 r = 0;
226 break;
227 }
228
229 if (size != 4) {
230
231
232
233 r = extract32(r, (addr & 3) * 8, size * 8);
234 }
235
236 trace_iotkit_secctl_s_read(offset, r, size);
237 *pdata = r;
238 return MEMTX_OK;
239}
240
241static void iotkit_secctl_update_ppc_ap(IoTKitSecCtlPPC *ppc)
242{
243 int i;
244
245 for (i = 0; i < ppc->numports; i++) {
246 bool v;
247
248 if (extract32(ppc->ns, i, 1)) {
249 v = extract32(ppc->nsp, i, 1);
250 } else {
251 v = extract32(ppc->sp, i, 1);
252 }
253 qemu_set_irq(ppc->ap[i], v);
254 }
255}
256
257static void iotkit_secctl_ppc_ns_write(IoTKitSecCtlPPC *ppc, uint32_t value)
258{
259 int i;
260
261 ppc->ns = value & MAKE_64BIT_MASK(0, ppc->numports);
262 for (i = 0; i < ppc->numports; i++) {
263 qemu_set_irq(ppc->nonsec[i], extract32(ppc->ns, i, 1));
264 }
265 iotkit_secctl_update_ppc_ap(ppc);
266}
267
268static void iotkit_secctl_ppc_sp_write(IoTKitSecCtlPPC *ppc, uint32_t value)
269{
270 ppc->sp = value & MAKE_64BIT_MASK(0, ppc->numports);
271 iotkit_secctl_update_ppc_ap(ppc);
272}
273
274static void iotkit_secctl_ppc_nsp_write(IoTKitSecCtlPPC *ppc, uint32_t value)
275{
276 ppc->nsp = value & MAKE_64BIT_MASK(0, ppc->numports);
277 iotkit_secctl_update_ppc_ap(ppc);
278}
279
280static void iotkit_secctl_ppc_update_irq_clear(IoTKitSecCtlPPC *ppc)
281{
282 uint32_t value = ppc->parent->secppcintstat;
283
284 qemu_set_irq(ppc->irq_clear, extract32(value, ppc->irq_bit_offset, 1));
285}
286
287static void iotkit_secctl_ppc_update_irq_enable(IoTKitSecCtlPPC *ppc)
288{
289 uint32_t value = ppc->parent->secppcinten;
290
291 qemu_set_irq(ppc->irq_enable, extract32(value, ppc->irq_bit_offset, 1));
292}
293
294static MemTxResult iotkit_secctl_s_write(void *opaque, hwaddr addr,
295 uint64_t value,
296 unsigned size, MemTxAttrs attrs)
297{
298 IoTKitSecCtl *s = IOTKIT_SECCTL(opaque);
299 uint32_t offset = addr;
300 IoTKitSecCtlPPC *ppc;
301
302 trace_iotkit_secctl_s_write(offset, value, size);
303
304 if (size != 4) {
305
306 qemu_log_mask(LOG_GUEST_ERROR,
307 "IotKit SecCtl S block write: bad size, ignored\n");
308 return MEMTX_OK;
309 }
310
311 switch (offset) {
312 case A_NSCCFG:
313 s->nsccfg = value & 3;
314 qemu_set_irq(s->nsc_cfg_irq, s->nsccfg);
315 break;
316 case A_SECRESPCFG:
317 value &= 1;
318 s->secrespcfg = value;
319 qemu_set_irq(s->sec_resp_cfg, s->secrespcfg);
320 break;
321 case A_SECPPCINTCLR:
322 value &= 0x00f000f3;
323 foreach_ppc(s, iotkit_secctl_ppc_update_irq_clear);
324 break;
325 case A_SECPPCINTEN:
326 s->secppcinten = value & 0x00f000f3;
327 foreach_ppc(s, iotkit_secctl_ppc_update_irq_enable);
328 break;
329 case A_BRGINTCLR:
330 break;
331 case A_BRGINTEN:
332 s->brginten = value & 0xffff0000;
333 break;
334 case A_AHBNSPPCEXP0:
335 case A_AHBNSPPCEXP1:
336 case A_AHBNSPPCEXP2:
337 case A_AHBNSPPCEXP3:
338 ppc = &s->ahbexp[offset_to_ppc_idx(offset)];
339 iotkit_secctl_ppc_ns_write(ppc, value);
340 break;
341 case A_APBNSPPC0:
342 case A_APBNSPPC1:
343 ppc = &s->apb[offset_to_ppc_idx(offset)];
344 iotkit_secctl_ppc_ns_write(ppc, value);
345 break;
346 case A_APBNSPPCEXP0:
347 case A_APBNSPPCEXP1:
348 case A_APBNSPPCEXP2:
349 case A_APBNSPPCEXP3:
350 ppc = &s->apbexp[offset_to_ppc_idx(offset)];
351 iotkit_secctl_ppc_ns_write(ppc, value);
352 break;
353 case A_AHBSPPPCEXP0:
354 case A_AHBSPPPCEXP1:
355 case A_AHBSPPPCEXP2:
356 case A_AHBSPPPCEXP3:
357 ppc = &s->ahbexp[offset_to_ppc_idx(offset)];
358 iotkit_secctl_ppc_sp_write(ppc, value);
359 break;
360 case A_APBSPPPC0:
361 case A_APBSPPPC1:
362 ppc = &s->apb[offset_to_ppc_idx(offset)];
363 iotkit_secctl_ppc_sp_write(ppc, value);
364 break;
365 case A_APBSPPPCEXP0:
366 case A_APBSPPPCEXP1:
367 case A_APBSPPPCEXP2:
368 case A_APBSPPPCEXP3:
369 ppc = &s->apbexp[offset_to_ppc_idx(offset)];
370 iotkit_secctl_ppc_sp_write(ppc, value);
371 break;
372 case A_SECMSCINTCLR:
373 case A_SECMSCINTEN:
374 qemu_log_mask(LOG_UNIMP,
375 "IoTKit SecCtl S block write: "
376 "unimplemented offset 0x%x\n", offset);
377 break;
378 case A_SECMPCINTSTATUS:
379 case A_SECPPCINTSTAT:
380 case A_SECMSCINTSTAT:
381 case A_BRGINTSTAT:
382 case A_AHBNSPPC0:
383 case A_AHBSPPPC0:
384 case A_NSMSCEXP:
385 case A_PID4:
386 case A_PID5:
387 case A_PID6:
388 case A_PID7:
389 case A_PID0:
390 case A_PID1:
391 case A_PID2:
392 case A_PID3:
393 case A_CID0:
394 case A_CID1:
395 case A_CID2:
396 case A_CID3:
397 qemu_log_mask(LOG_GUEST_ERROR,
398 "IoTKit SecCtl S block write: "
399 "read-only offset 0x%x\n", offset);
400 break;
401 default:
402 qemu_log_mask(LOG_GUEST_ERROR,
403 "IotKit SecCtl S block write: bad offset 0x%x\n",
404 offset);
405 break;
406 }
407
408 return MEMTX_OK;
409}
410
411static MemTxResult iotkit_secctl_ns_read(void *opaque, hwaddr addr,
412 uint64_t *pdata,
413 unsigned size, MemTxAttrs attrs)
414{
415 IoTKitSecCtl *s = IOTKIT_SECCTL(opaque);
416 uint64_t r;
417 uint32_t offset = addr & ~0x3;
418
419 switch (offset) {
420 case A_AHBNSPPPC0:
421 r = 0;
422 break;
423 case A_AHBNSPPPCEXP0:
424 case A_AHBNSPPPCEXP1:
425 case A_AHBNSPPPCEXP2:
426 case A_AHBNSPPPCEXP3:
427 r = s->ahbexp[offset_to_ppc_idx(offset)].nsp;
428 break;
429 case A_APBNSPPPC0:
430 case A_APBNSPPPC1:
431 r = s->apb[offset_to_ppc_idx(offset)].nsp;
432 break;
433 case A_APBNSPPPCEXP0:
434 case A_APBNSPPPCEXP1:
435 case A_APBNSPPPCEXP2:
436 case A_APBNSPPPCEXP3:
437 r = s->apbexp[offset_to_ppc_idx(offset)].nsp;
438 break;
439 case A_PID4:
440 case A_PID5:
441 case A_PID6:
442 case A_PID7:
443 case A_PID0:
444 case A_PID1:
445 case A_PID2:
446 case A_PID3:
447 case A_CID0:
448 case A_CID1:
449 case A_CID2:
450 case A_CID3:
451 r = iotkit_secctl_ns_idregs[(offset - A_PID4) / 4];
452 break;
453 default:
454 qemu_log_mask(LOG_GUEST_ERROR,
455 "IotKit SecCtl NS block write: bad offset 0x%x\n",
456 offset);
457 r = 0;
458 break;
459 }
460
461 if (size != 4) {
462
463
464
465 r = extract32(r, (addr & 3) * 8, size * 8);
466 }
467
468 trace_iotkit_secctl_ns_read(offset, r, size);
469 *pdata = r;
470 return MEMTX_OK;
471}
472
473static MemTxResult iotkit_secctl_ns_write(void *opaque, hwaddr addr,
474 uint64_t value,
475 unsigned size, MemTxAttrs attrs)
476{
477 IoTKitSecCtl *s = IOTKIT_SECCTL(opaque);
478 uint32_t offset = addr;
479 IoTKitSecCtlPPC *ppc;
480
481 trace_iotkit_secctl_ns_write(offset, value, size);
482
483 if (size != 4) {
484
485 qemu_log_mask(LOG_GUEST_ERROR,
486 "IotKit SecCtl NS block write: bad size, ignored\n");
487 return MEMTX_OK;
488 }
489
490 switch (offset) {
491 case A_AHBNSPPPCEXP0:
492 case A_AHBNSPPPCEXP1:
493 case A_AHBNSPPPCEXP2:
494 case A_AHBNSPPPCEXP3:
495 ppc = &s->ahbexp[offset_to_ppc_idx(offset)];
496 iotkit_secctl_ppc_nsp_write(ppc, value);
497 break;
498 case A_APBNSPPPC0:
499 case A_APBNSPPPC1:
500 ppc = &s->apb[offset_to_ppc_idx(offset)];
501 iotkit_secctl_ppc_nsp_write(ppc, value);
502 break;
503 case A_APBNSPPPCEXP0:
504 case A_APBNSPPPCEXP1:
505 case A_APBNSPPPCEXP2:
506 case A_APBNSPPPCEXP3:
507 ppc = &s->apbexp[offset_to_ppc_idx(offset)];
508 iotkit_secctl_ppc_nsp_write(ppc, value);
509 break;
510 case A_AHBNSPPPC0:
511 case A_PID4:
512 case A_PID5:
513 case A_PID6:
514 case A_PID7:
515 case A_PID0:
516 case A_PID1:
517 case A_PID2:
518 case A_PID3:
519 case A_CID0:
520 case A_CID1:
521 case A_CID2:
522 case A_CID3:
523 qemu_log_mask(LOG_GUEST_ERROR,
524 "IoTKit SecCtl NS block write: "
525 "read-only offset 0x%x\n", offset);
526 break;
527 default:
528 qemu_log_mask(LOG_GUEST_ERROR,
529 "IotKit SecCtl NS block write: bad offset 0x%x\n",
530 offset);
531 break;
532 }
533
534 return MEMTX_OK;
535}
536
537static const MemoryRegionOps iotkit_secctl_s_ops = {
538 .read_with_attrs = iotkit_secctl_s_read,
539 .write_with_attrs = iotkit_secctl_s_write,
540 .endianness = DEVICE_LITTLE_ENDIAN,
541 .valid.min_access_size = 1,
542 .valid.max_access_size = 4,
543 .impl.min_access_size = 1,
544 .impl.max_access_size = 4,
545};
546
547static const MemoryRegionOps iotkit_secctl_ns_ops = {
548 .read_with_attrs = iotkit_secctl_ns_read,
549 .write_with_attrs = iotkit_secctl_ns_write,
550 .endianness = DEVICE_LITTLE_ENDIAN,
551 .valid.min_access_size = 1,
552 .valid.max_access_size = 4,
553 .impl.min_access_size = 1,
554 .impl.max_access_size = 4,
555};
556
557static void iotkit_secctl_reset_ppc(IoTKitSecCtlPPC *ppc)
558{
559 ppc->ns = 0;
560 ppc->sp = 0;
561 ppc->nsp = 0;
562}
563
564static void iotkit_secctl_reset(DeviceState *dev)
565{
566 IoTKitSecCtl *s = IOTKIT_SECCTL(dev);
567
568 s->secppcintstat = 0;
569 s->secppcinten = 0;
570 s->secrespcfg = 0;
571 s->nsccfg = 0;
572 s->brginten = 0;
573
574 foreach_ppc(s, iotkit_secctl_reset_ppc);
575}
576
577static void iotkit_secctl_mpc_status(void *opaque, int n, int level)
578{
579 IoTKitSecCtl *s = IOTKIT_SECCTL(opaque);
580
581 s->mpcintstatus = deposit32(s->mpcintstatus, 0, 1, !!level);
582}
583
584static void iotkit_secctl_mpcexp_status(void *opaque, int n, int level)
585{
586 IoTKitSecCtl *s = IOTKIT_SECCTL(opaque);
587
588 s->mpcintstatus = deposit32(s->mpcintstatus, n + 16, 1, !!level);
589}
590
591static void iotkit_secctl_ppc_irqstatus(void *opaque, int n, int level)
592{
593 IoTKitSecCtlPPC *ppc = opaque;
594 IoTKitSecCtl *s = IOTKIT_SECCTL(ppc->parent);
595 int irqbit = ppc->irq_bit_offset + n;
596
597 s->secppcintstat = deposit32(s->secppcintstat, irqbit, 1, level);
598}
599
600static void iotkit_secctl_init_ppc(IoTKitSecCtl *s,
601 IoTKitSecCtlPPC *ppc,
602 const char *name,
603 int numports,
604 int irq_bit_offset)
605{
606 char *gpioname;
607 DeviceState *dev = DEVICE(s);
608
609 ppc->numports = numports;
610 ppc->irq_bit_offset = irq_bit_offset;
611 ppc->parent = s;
612
613 gpioname = g_strdup_printf("%s_nonsec", name);
614 qdev_init_gpio_out_named(dev, ppc->nonsec, gpioname, numports);
615 g_free(gpioname);
616 gpioname = g_strdup_printf("%s_ap", name);
617 qdev_init_gpio_out_named(dev, ppc->ap, gpioname, numports);
618 g_free(gpioname);
619 gpioname = g_strdup_printf("%s_irq_enable", name);
620 qdev_init_gpio_out_named(dev, &ppc->irq_enable, gpioname, 1);
621 g_free(gpioname);
622 gpioname = g_strdup_printf("%s_irq_clear", name);
623 qdev_init_gpio_out_named(dev, &ppc->irq_clear, gpioname, 1);
624 g_free(gpioname);
625 gpioname = g_strdup_printf("%s_irq_status", name);
626 qdev_init_gpio_in_named_with_opaque(dev, iotkit_secctl_ppc_irqstatus,
627 ppc, gpioname, 1);
628 g_free(gpioname);
629}
630
631static void iotkit_secctl_init(Object *obj)
632{
633 IoTKitSecCtl *s = IOTKIT_SECCTL(obj);
634 SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
635 DeviceState *dev = DEVICE(obj);
636 int i;
637
638 iotkit_secctl_init_ppc(s, &s->apb[0], "apb_ppc0",
639 IOTS_APB_PPC0_NUM_PORTS, 0);
640 iotkit_secctl_init_ppc(s, &s->apb[1], "apb_ppc1",
641 IOTS_APB_PPC1_NUM_PORTS, 1);
642
643 for (i = 0; i < IOTS_NUM_APB_EXP_PPC; i++) {
644 IoTKitSecCtlPPC *ppc = &s->apbexp[i];
645 char *ppcname = g_strdup_printf("apb_ppcexp%d", i);
646 iotkit_secctl_init_ppc(s, ppc, ppcname, IOTS_PPC_NUM_PORTS, 4 + i);
647 g_free(ppcname);
648 }
649 for (i = 0; i < IOTS_NUM_AHB_EXP_PPC; i++) {
650 IoTKitSecCtlPPC *ppc = &s->ahbexp[i];
651 char *ppcname = g_strdup_printf("ahb_ppcexp%d", i);
652 iotkit_secctl_init_ppc(s, ppc, ppcname, IOTS_PPC_NUM_PORTS, 20 + i);
653 g_free(ppcname);
654 }
655
656 qdev_init_gpio_out_named(dev, &s->sec_resp_cfg, "sec_resp_cfg", 1);
657 qdev_init_gpio_out_named(dev, &s->nsc_cfg_irq, "nsc_cfg", 1);
658
659 qdev_init_gpio_in_named(dev, iotkit_secctl_mpc_status, "mpc_status", 1);
660 qdev_init_gpio_in_named(dev, iotkit_secctl_mpcexp_status,
661 "mpcexp_status", IOTS_NUM_EXP_MPC);
662
663 memory_region_init_io(&s->s_regs, obj, &iotkit_secctl_s_ops,
664 s, "iotkit-secctl-s-regs", 0x1000);
665 memory_region_init_io(&s->ns_regs, obj, &iotkit_secctl_ns_ops,
666 s, "iotkit-secctl-ns-regs", 0x1000);
667 sysbus_init_mmio(sbd, &s->s_regs);
668 sysbus_init_mmio(sbd, &s->ns_regs);
669}
670
671static const VMStateDescription iotkit_secctl_ppc_vmstate = {
672 .name = "iotkit-secctl-ppc",
673 .version_id = 1,
674 .minimum_version_id = 1,
675 .fields = (VMStateField[]) {
676 VMSTATE_UINT32(ns, IoTKitSecCtlPPC),
677 VMSTATE_UINT32(sp, IoTKitSecCtlPPC),
678 VMSTATE_UINT32(nsp, IoTKitSecCtlPPC),
679 VMSTATE_END_OF_LIST()
680 }
681};
682
683static const VMStateDescription iotkit_secctl_mpcintstatus_vmstate = {
684 .name = "iotkit-secctl-mpcintstatus",
685 .version_id = 1,
686 .minimum_version_id = 1,
687 .fields = (VMStateField[]) {
688 VMSTATE_UINT32(mpcintstatus, IoTKitSecCtl),
689 VMSTATE_END_OF_LIST()
690 }
691};
692
693static const VMStateDescription iotkit_secctl_vmstate = {
694 .name = "iotkit-secctl",
695 .version_id = 1,
696 .minimum_version_id = 1,
697 .fields = (VMStateField[]) {
698 VMSTATE_UINT32(secppcintstat, IoTKitSecCtl),
699 VMSTATE_UINT32(secppcinten, IoTKitSecCtl),
700 VMSTATE_UINT32(secrespcfg, IoTKitSecCtl),
701 VMSTATE_UINT32(nsccfg, IoTKitSecCtl),
702 VMSTATE_UINT32(brginten, IoTKitSecCtl),
703 VMSTATE_STRUCT_ARRAY(apb, IoTKitSecCtl, IOTS_NUM_APB_PPC, 1,
704 iotkit_secctl_ppc_vmstate, IoTKitSecCtlPPC),
705 VMSTATE_STRUCT_ARRAY(apbexp, IoTKitSecCtl, IOTS_NUM_APB_EXP_PPC, 1,
706 iotkit_secctl_ppc_vmstate, IoTKitSecCtlPPC),
707 VMSTATE_STRUCT_ARRAY(ahbexp, IoTKitSecCtl, IOTS_NUM_AHB_EXP_PPC, 1,
708 iotkit_secctl_ppc_vmstate, IoTKitSecCtlPPC),
709 VMSTATE_END_OF_LIST()
710 },
711 .subsections = (const VMStateDescription*[]) {
712 &iotkit_secctl_mpcintstatus_vmstate,
713 NULL
714 },
715};
716
717static void iotkit_secctl_class_init(ObjectClass *klass, void *data)
718{
719 DeviceClass *dc = DEVICE_CLASS(klass);
720
721 dc->vmsd = &iotkit_secctl_vmstate;
722 dc->reset = iotkit_secctl_reset;
723}
724
725static const TypeInfo iotkit_secctl_info = {
726 .name = TYPE_IOTKIT_SECCTL,
727 .parent = TYPE_SYS_BUS_DEVICE,
728 .instance_size = sizeof(IoTKitSecCtl),
729 .instance_init = iotkit_secctl_init,
730 .class_init = iotkit_secctl_class_init,
731};
732
733static void iotkit_secctl_register_types(void)
734{
735 type_register_static(&iotkit_secctl_info);
736}
737
738type_init(iotkit_secctl_register_types);
739