hw/misc/iotkit-secctl: Add handling for PPCs
[qemu.git] / hw / misc / iotkit-secctl.c
blob1093f2910fdaab32ea04054430b25e29218e49f7
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 "qapi/error.h"
15 #include "trace.h"
16 #include "hw/sysbus.h"
17 #include "hw/registerfields.h"
18 #include "hw/misc/iotkit-secctl.h"
20 /* Registers in the secure privilege control block */
21 REG32(SECRESPCFG, 0x10)
22 REG32(NSCCFG, 0x14)
23 REG32(SECMPCINTSTATUS, 0x1c)
24 REG32(SECPPCINTSTAT, 0x20)
25 REG32(SECPPCINTCLR, 0x24)
26 REG32(SECPPCINTEN, 0x28)
27 REG32(SECMSCINTSTAT, 0x30)
28 REG32(SECMSCINTCLR, 0x34)
29 REG32(SECMSCINTEN, 0x38)
30 REG32(BRGINTSTAT, 0x40)
31 REG32(BRGINTCLR, 0x44)
32 REG32(BRGINTEN, 0x48)
33 REG32(AHBNSPPC0, 0x50)
34 REG32(AHBNSPPCEXP0, 0x60)
35 REG32(AHBNSPPCEXP1, 0x64)
36 REG32(AHBNSPPCEXP2, 0x68)
37 REG32(AHBNSPPCEXP3, 0x6c)
38 REG32(APBNSPPC0, 0x70)
39 REG32(APBNSPPC1, 0x74)
40 REG32(APBNSPPCEXP0, 0x80)
41 REG32(APBNSPPCEXP1, 0x84)
42 REG32(APBNSPPCEXP2, 0x88)
43 REG32(APBNSPPCEXP3, 0x8c)
44 REG32(AHBSPPPC0, 0x90)
45 REG32(AHBSPPPCEXP0, 0xa0)
46 REG32(AHBSPPPCEXP1, 0xa4)
47 REG32(AHBSPPPCEXP2, 0xa8)
48 REG32(AHBSPPPCEXP3, 0xac)
49 REG32(APBSPPPC0, 0xb0)
50 REG32(APBSPPPC1, 0xb4)
51 REG32(APBSPPPCEXP0, 0xc0)
52 REG32(APBSPPPCEXP1, 0xc4)
53 REG32(APBSPPPCEXP2, 0xc8)
54 REG32(APBSPPPCEXP3, 0xcc)
55 REG32(NSMSCEXP, 0xd0)
56 REG32(PID4, 0xfd0)
57 REG32(PID5, 0xfd4)
58 REG32(PID6, 0xfd8)
59 REG32(PID7, 0xfdc)
60 REG32(PID0, 0xfe0)
61 REG32(PID1, 0xfe4)
62 REG32(PID2, 0xfe8)
63 REG32(PID3, 0xfec)
64 REG32(CID0, 0xff0)
65 REG32(CID1, 0xff4)
66 REG32(CID2, 0xff8)
67 REG32(CID3, 0xffc)
69 /* Registers in the non-secure privilege control block */
70 REG32(AHBNSPPPC0, 0x90)
71 REG32(AHBNSPPPCEXP0, 0xa0)
72 REG32(AHBNSPPPCEXP1, 0xa4)
73 REG32(AHBNSPPPCEXP2, 0xa8)
74 REG32(AHBNSPPPCEXP3, 0xac)
75 REG32(APBNSPPPC0, 0xb0)
76 REG32(APBNSPPPC1, 0xb4)
77 REG32(APBNSPPPCEXP0, 0xc0)
78 REG32(APBNSPPPCEXP1, 0xc4)
79 REG32(APBNSPPPCEXP2, 0xc8)
80 REG32(APBNSPPPCEXP3, 0xcc)
81 /* PID and CID registers are also present in the NS block */
83 static const uint8_t iotkit_secctl_s_idregs[] = {
84 0x04, 0x00, 0x00, 0x00,
85 0x52, 0xb8, 0x0b, 0x00,
86 0x0d, 0xf0, 0x05, 0xb1,
89 static const uint8_t iotkit_secctl_ns_idregs[] = {
90 0x04, 0x00, 0x00, 0x00,
91 0x53, 0xb8, 0x0b, 0x00,
92 0x0d, 0xf0, 0x05, 0xb1,
95 /* The register sets for the various PPCs (AHB internal, APB internal,
96 * AHB expansion, APB expansion) are all set up so that they are
97 * in 16-aligned blocks so offsets 0xN0, 0xN4, 0xN8, 0xNC are PPCs
98 * 0, 1, 2, 3 of that type, so we can convert a register address offset
99 * into an an index into a PPC array easily.
101 static inline int offset_to_ppc_idx(uint32_t offset)
103 return extract32(offset, 2, 2);
106 typedef void PerPPCFunction(IoTKitSecCtlPPC *ppc);
108 static void foreach_ppc(IoTKitSecCtl *s, PerPPCFunction *fn)
110 int i;
112 for (i = 0; i < IOTS_NUM_APB_PPC; i++) {
113 fn(&s->apb[i]);
115 for (i = 0; i < IOTS_NUM_APB_EXP_PPC; i++) {
116 fn(&s->apbexp[i]);
118 for (i = 0; i < IOTS_NUM_AHB_EXP_PPC; i++) {
119 fn(&s->ahbexp[i]);
123 static MemTxResult iotkit_secctl_s_read(void *opaque, hwaddr addr,
124 uint64_t *pdata,
125 unsigned size, MemTxAttrs attrs)
127 uint64_t r;
128 uint32_t offset = addr & ~0x3;
129 IoTKitSecCtl *s = IOTKIT_SECCTL(opaque);
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_SECPPCINTSTAT:
140 r = s->secppcintstat;
141 break;
142 case A_SECPPCINTEN:
143 r = s->secppcinten;
144 break;
145 case A_AHBNSPPCEXP0:
146 case A_AHBNSPPCEXP1:
147 case A_AHBNSPPCEXP2:
148 case A_AHBNSPPCEXP3:
149 r = s->ahbexp[offset_to_ppc_idx(offset)].ns;
150 break;
151 case A_APBNSPPC0:
152 case A_APBNSPPC1:
153 r = s->apb[offset_to_ppc_idx(offset)].ns;
154 break;
155 case A_APBNSPPCEXP0:
156 case A_APBNSPPCEXP1:
157 case A_APBNSPPCEXP2:
158 case A_APBNSPPCEXP3:
159 r = s->apbexp[offset_to_ppc_idx(offset)].ns;
160 break;
161 case A_AHBSPPPCEXP0:
162 case A_AHBSPPPCEXP1:
163 case A_AHBSPPPCEXP2:
164 case A_AHBSPPPCEXP3:
165 r = s->apbexp[offset_to_ppc_idx(offset)].sp;
166 break;
167 case A_APBSPPPC0:
168 case A_APBSPPPC1:
169 r = s->apb[offset_to_ppc_idx(offset)].sp;
170 break;
171 case A_APBSPPPCEXP0:
172 case A_APBSPPPCEXP1:
173 case A_APBSPPPCEXP2:
174 case A_APBSPPPCEXP3:
175 r = s->apbexp[offset_to_ppc_idx(offset)].sp;
176 break;
177 case A_NSCCFG:
178 case A_SECMPCINTSTATUS:
179 case A_SECMSCINTSTAT:
180 case A_SECMSCINTEN:
181 case A_BRGINTSTAT:
182 case A_BRGINTEN:
183 case A_NSMSCEXP:
184 qemu_log_mask(LOG_UNIMP,
185 "IoTKit SecCtl S block read: "
186 "unimplemented offset 0x%x\n", offset);
187 r = 0;
188 break;
189 case A_PID4:
190 case A_PID5:
191 case A_PID6:
192 case A_PID7:
193 case A_PID0:
194 case A_PID1:
195 case A_PID2:
196 case A_PID3:
197 case A_CID0:
198 case A_CID1:
199 case A_CID2:
200 case A_CID3:
201 r = iotkit_secctl_s_idregs[(offset - A_PID4) / 4];
202 break;
203 case A_SECPPCINTCLR:
204 case A_SECMSCINTCLR:
205 case A_BRGINTCLR:
206 qemu_log_mask(LOG_GUEST_ERROR,
207 "IotKit SecCtl S block read: write-only offset 0x%x\n",
208 offset);
209 r = 0;
210 break;
211 default:
212 qemu_log_mask(LOG_GUEST_ERROR,
213 "IotKit SecCtl S block read: bad offset 0x%x\n", offset);
214 r = 0;
215 break;
218 if (size != 4) {
219 /* None of our registers are access-sensitive, so just pull the right
220 * byte out of the word read result.
222 r = extract32(r, (addr & 3) * 8, size * 8);
225 trace_iotkit_secctl_s_read(offset, r, size);
226 *pdata = r;
227 return MEMTX_OK;
230 static void iotkit_secctl_update_ppc_ap(IoTKitSecCtlPPC *ppc)
232 int i;
234 for (i = 0; i < ppc->numports; i++) {
235 bool v;
237 if (extract32(ppc->ns, i, 1)) {
238 v = extract32(ppc->nsp, i, 1);
239 } else {
240 v = extract32(ppc->sp, i, 1);
242 qemu_set_irq(ppc->ap[i], v);
246 static void iotkit_secctl_ppc_ns_write(IoTKitSecCtlPPC *ppc, uint32_t value)
248 int i;
250 ppc->ns = value & MAKE_64BIT_MASK(0, ppc->numports);
251 for (i = 0; i < ppc->numports; i++) {
252 qemu_set_irq(ppc->nonsec[i], extract32(ppc->ns, i, 1));
254 iotkit_secctl_update_ppc_ap(ppc);
257 static void iotkit_secctl_ppc_sp_write(IoTKitSecCtlPPC *ppc, uint32_t value)
259 ppc->sp = value & MAKE_64BIT_MASK(0, ppc->numports);
260 iotkit_secctl_update_ppc_ap(ppc);
263 static void iotkit_secctl_ppc_nsp_write(IoTKitSecCtlPPC *ppc, uint32_t value)
265 ppc->nsp = value & MAKE_64BIT_MASK(0, ppc->numports);
266 iotkit_secctl_update_ppc_ap(ppc);
269 static void iotkit_secctl_ppc_update_irq_clear(IoTKitSecCtlPPC *ppc)
271 uint32_t value = ppc->parent->secppcintstat;
273 qemu_set_irq(ppc->irq_clear, extract32(value, ppc->irq_bit_offset, 1));
276 static void iotkit_secctl_ppc_update_irq_enable(IoTKitSecCtlPPC *ppc)
278 uint32_t value = ppc->parent->secppcinten;
280 qemu_set_irq(ppc->irq_enable, extract32(value, ppc->irq_bit_offset, 1));
283 static MemTxResult iotkit_secctl_s_write(void *opaque, hwaddr addr,
284 uint64_t value,
285 unsigned size, MemTxAttrs attrs)
287 IoTKitSecCtl *s = IOTKIT_SECCTL(opaque);
288 uint32_t offset = addr;
289 IoTKitSecCtlPPC *ppc;
291 trace_iotkit_secctl_s_write(offset, value, size);
293 if (size != 4) {
294 /* Byte and halfword writes are ignored */
295 qemu_log_mask(LOG_GUEST_ERROR,
296 "IotKit SecCtl S block write: bad size, ignored\n");
297 return MEMTX_OK;
300 switch (offset) {
301 case A_SECRESPCFG:
302 value &= 1;
303 s->secrespcfg = value;
304 qemu_set_irq(s->sec_resp_cfg, s->secrespcfg);
305 break;
306 case A_SECPPCINTCLR:
307 value &= 0x00f000f3;
308 foreach_ppc(s, iotkit_secctl_ppc_update_irq_clear);
309 break;
310 case A_SECPPCINTEN:
311 s->secppcinten = value & 0x00f000f3;
312 foreach_ppc(s, iotkit_secctl_ppc_update_irq_enable);
313 break;
314 case A_AHBNSPPCEXP0:
315 case A_AHBNSPPCEXP1:
316 case A_AHBNSPPCEXP2:
317 case A_AHBNSPPCEXP3:
318 ppc = &s->ahbexp[offset_to_ppc_idx(offset)];
319 iotkit_secctl_ppc_ns_write(ppc, value);
320 break;
321 case A_APBNSPPC0:
322 case A_APBNSPPC1:
323 ppc = &s->apb[offset_to_ppc_idx(offset)];
324 iotkit_secctl_ppc_ns_write(ppc, value);
325 break;
326 case A_APBNSPPCEXP0:
327 case A_APBNSPPCEXP1:
328 case A_APBNSPPCEXP2:
329 case A_APBNSPPCEXP3:
330 ppc = &s->apbexp[offset_to_ppc_idx(offset)];
331 iotkit_secctl_ppc_ns_write(ppc, value);
332 break;
333 case A_AHBSPPPCEXP0:
334 case A_AHBSPPPCEXP1:
335 case A_AHBSPPPCEXP2:
336 case A_AHBSPPPCEXP3:
337 ppc = &s->ahbexp[offset_to_ppc_idx(offset)];
338 iotkit_secctl_ppc_sp_write(ppc, value);
339 break;
340 case A_APBSPPPC0:
341 case A_APBSPPPC1:
342 ppc = &s->apb[offset_to_ppc_idx(offset)];
343 iotkit_secctl_ppc_sp_write(ppc, value);
344 break;
345 case A_APBSPPPCEXP0:
346 case A_APBSPPPCEXP1:
347 case A_APBSPPPCEXP2:
348 case A_APBSPPPCEXP3:
349 ppc = &s->apbexp[offset_to_ppc_idx(offset)];
350 iotkit_secctl_ppc_sp_write(ppc, value);
351 break;
352 case A_NSCCFG:
353 case A_SECMSCINTCLR:
354 case A_SECMSCINTEN:
355 case A_BRGINTCLR:
356 case A_BRGINTEN:
357 qemu_log_mask(LOG_UNIMP,
358 "IoTKit SecCtl S block write: "
359 "unimplemented offset 0x%x\n", offset);
360 break;
361 case A_SECMPCINTSTATUS:
362 case A_SECPPCINTSTAT:
363 case A_SECMSCINTSTAT:
364 case A_BRGINTSTAT:
365 case A_AHBNSPPC0:
366 case A_AHBSPPPC0:
367 case A_NSMSCEXP:
368 case A_PID4:
369 case A_PID5:
370 case A_PID6:
371 case A_PID7:
372 case A_PID0:
373 case A_PID1:
374 case A_PID2:
375 case A_PID3:
376 case A_CID0:
377 case A_CID1:
378 case A_CID2:
379 case A_CID3:
380 qemu_log_mask(LOG_GUEST_ERROR,
381 "IoTKit SecCtl S block write: "
382 "read-only offset 0x%x\n", offset);
383 break;
384 default:
385 qemu_log_mask(LOG_GUEST_ERROR,
386 "IotKit SecCtl S block write: bad offset 0x%x\n",
387 offset);
388 break;
391 return MEMTX_OK;
394 static MemTxResult iotkit_secctl_ns_read(void *opaque, hwaddr addr,
395 uint64_t *pdata,
396 unsigned size, MemTxAttrs attrs)
398 IoTKitSecCtl *s = IOTKIT_SECCTL(opaque);
399 uint64_t r;
400 uint32_t offset = addr & ~0x3;
402 switch (offset) {
403 case A_AHBNSPPPC0:
404 r = 0;
405 break;
406 case A_AHBNSPPPCEXP0:
407 case A_AHBNSPPPCEXP1:
408 case A_AHBNSPPPCEXP2:
409 case A_AHBNSPPPCEXP3:
410 r = s->ahbexp[offset_to_ppc_idx(offset)].nsp;
411 break;
412 case A_APBNSPPPC0:
413 case A_APBNSPPPC1:
414 r = s->apb[offset_to_ppc_idx(offset)].nsp;
415 break;
416 case A_APBNSPPPCEXP0:
417 case A_APBNSPPPCEXP1:
418 case A_APBNSPPPCEXP2:
419 case A_APBNSPPPCEXP3:
420 r = s->apbexp[offset_to_ppc_idx(offset)].nsp;
421 break;
422 case A_PID4:
423 case A_PID5:
424 case A_PID6:
425 case A_PID7:
426 case A_PID0:
427 case A_PID1:
428 case A_PID2:
429 case A_PID3:
430 case A_CID0:
431 case A_CID1:
432 case A_CID2:
433 case A_CID3:
434 r = iotkit_secctl_ns_idregs[(offset - A_PID4) / 4];
435 break;
436 default:
437 qemu_log_mask(LOG_GUEST_ERROR,
438 "IotKit SecCtl NS block write: bad offset 0x%x\n",
439 offset);
440 r = 0;
441 break;
444 if (size != 4) {
445 /* None of our registers are access-sensitive, so just pull the right
446 * byte out of the word read result.
448 r = extract32(r, (addr & 3) * 8, size * 8);
451 trace_iotkit_secctl_ns_read(offset, r, size);
452 *pdata = r;
453 return MEMTX_OK;
456 static MemTxResult iotkit_secctl_ns_write(void *opaque, hwaddr addr,
457 uint64_t value,
458 unsigned size, MemTxAttrs attrs)
460 IoTKitSecCtl *s = IOTKIT_SECCTL(opaque);
461 uint32_t offset = addr;
462 IoTKitSecCtlPPC *ppc;
464 trace_iotkit_secctl_ns_write(offset, value, size);
466 if (size != 4) {
467 /* Byte and halfword writes are ignored */
468 qemu_log_mask(LOG_GUEST_ERROR,
469 "IotKit SecCtl NS block write: bad size, ignored\n");
470 return MEMTX_OK;
473 switch (offset) {
474 case A_AHBNSPPPCEXP0:
475 case A_AHBNSPPPCEXP1:
476 case A_AHBNSPPPCEXP2:
477 case A_AHBNSPPPCEXP3:
478 ppc = &s->ahbexp[offset_to_ppc_idx(offset)];
479 iotkit_secctl_ppc_nsp_write(ppc, value);
480 break;
481 case A_APBNSPPPC0:
482 case A_APBNSPPPC1:
483 ppc = &s->apb[offset_to_ppc_idx(offset)];
484 iotkit_secctl_ppc_nsp_write(ppc, value);
485 break;
486 case A_APBNSPPPCEXP0:
487 case A_APBNSPPPCEXP1:
488 case A_APBNSPPPCEXP2:
489 case A_APBNSPPPCEXP3:
490 ppc = &s->apbexp[offset_to_ppc_idx(offset)];
491 iotkit_secctl_ppc_nsp_write(ppc, value);
492 break;
493 case A_AHBNSPPPC0:
494 case A_PID4:
495 case A_PID5:
496 case A_PID6:
497 case A_PID7:
498 case A_PID0:
499 case A_PID1:
500 case A_PID2:
501 case A_PID3:
502 case A_CID0:
503 case A_CID1:
504 case A_CID2:
505 case A_CID3:
506 qemu_log_mask(LOG_GUEST_ERROR,
507 "IoTKit SecCtl NS block write: "
508 "read-only offset 0x%x\n", offset);
509 break;
510 default:
511 qemu_log_mask(LOG_GUEST_ERROR,
512 "IotKit SecCtl NS block write: bad offset 0x%x\n",
513 offset);
514 break;
517 return MEMTX_OK;
520 static const MemoryRegionOps iotkit_secctl_s_ops = {
521 .read_with_attrs = iotkit_secctl_s_read,
522 .write_with_attrs = iotkit_secctl_s_write,
523 .endianness = DEVICE_LITTLE_ENDIAN,
524 .valid.min_access_size = 1,
525 .valid.max_access_size = 4,
526 .impl.min_access_size = 1,
527 .impl.max_access_size = 4,
530 static const MemoryRegionOps iotkit_secctl_ns_ops = {
531 .read_with_attrs = iotkit_secctl_ns_read,
532 .write_with_attrs = iotkit_secctl_ns_write,
533 .endianness = DEVICE_LITTLE_ENDIAN,
534 .valid.min_access_size = 1,
535 .valid.max_access_size = 4,
536 .impl.min_access_size = 1,
537 .impl.max_access_size = 4,
540 static void iotkit_secctl_reset_ppc(IoTKitSecCtlPPC *ppc)
542 ppc->ns = 0;
543 ppc->sp = 0;
544 ppc->nsp = 0;
547 static void iotkit_secctl_reset(DeviceState *dev)
549 IoTKitSecCtl *s = IOTKIT_SECCTL(dev);
551 s->secppcintstat = 0;
552 s->secppcinten = 0;
553 s->secrespcfg = 0;
555 foreach_ppc(s, iotkit_secctl_reset_ppc);
558 static void iotkit_secctl_ppc_irqstatus(void *opaque, int n, int level)
560 IoTKitSecCtlPPC *ppc = opaque;
561 IoTKitSecCtl *s = IOTKIT_SECCTL(ppc->parent);
562 int irqbit = ppc->irq_bit_offset + n;
564 s->secppcintstat = deposit32(s->secppcintstat, irqbit, 1, level);
567 static void iotkit_secctl_init_ppc(IoTKitSecCtl *s,
568 IoTKitSecCtlPPC *ppc,
569 const char *name,
570 int numports,
571 int irq_bit_offset)
573 char *gpioname;
574 DeviceState *dev = DEVICE(s);
576 ppc->numports = numports;
577 ppc->irq_bit_offset = irq_bit_offset;
578 ppc->parent = s;
580 gpioname = g_strdup_printf("%s_nonsec", name);
581 qdev_init_gpio_out_named(dev, ppc->nonsec, gpioname, numports);
582 g_free(gpioname);
583 gpioname = g_strdup_printf("%s_ap", name);
584 qdev_init_gpio_out_named(dev, ppc->ap, gpioname, numports);
585 g_free(gpioname);
586 gpioname = g_strdup_printf("%s_irq_enable", name);
587 qdev_init_gpio_out_named(dev, &ppc->irq_enable, gpioname, 1);
588 g_free(gpioname);
589 gpioname = g_strdup_printf("%s_irq_clear", name);
590 qdev_init_gpio_out_named(dev, &ppc->irq_clear, gpioname, 1);
591 g_free(gpioname);
592 gpioname = g_strdup_printf("%s_irq_status", name);
593 qdev_init_gpio_in_named_with_opaque(dev, iotkit_secctl_ppc_irqstatus,
594 ppc, gpioname, 1);
595 g_free(gpioname);
598 static void iotkit_secctl_init(Object *obj)
600 IoTKitSecCtl *s = IOTKIT_SECCTL(obj);
601 SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
602 DeviceState *dev = DEVICE(obj);
603 int i;
605 iotkit_secctl_init_ppc(s, &s->apb[0], "apb_ppc0",
606 IOTS_APB_PPC0_NUM_PORTS, 0);
607 iotkit_secctl_init_ppc(s, &s->apb[1], "apb_ppc1",
608 IOTS_APB_PPC1_NUM_PORTS, 1);
610 for (i = 0; i < IOTS_NUM_APB_EXP_PPC; i++) {
611 IoTKitSecCtlPPC *ppc = &s->apbexp[i];
612 char *ppcname = g_strdup_printf("apb_ppcexp%d", i);
613 iotkit_secctl_init_ppc(s, ppc, ppcname, IOTS_PPC_NUM_PORTS, 4 + i);
614 g_free(ppcname);
616 for (i = 0; i < IOTS_NUM_AHB_EXP_PPC; i++) {
617 IoTKitSecCtlPPC *ppc = &s->ahbexp[i];
618 char *ppcname = g_strdup_printf("ahb_ppcexp%d", i);
619 iotkit_secctl_init_ppc(s, ppc, ppcname, IOTS_PPC_NUM_PORTS, 20 + i);
620 g_free(ppcname);
623 qdev_init_gpio_out_named(dev, &s->sec_resp_cfg, "sec_resp_cfg", 1);
625 memory_region_init_io(&s->s_regs, obj, &iotkit_secctl_s_ops,
626 s, "iotkit-secctl-s-regs", 0x1000);
627 memory_region_init_io(&s->ns_regs, obj, &iotkit_secctl_ns_ops,
628 s, "iotkit-secctl-ns-regs", 0x1000);
629 sysbus_init_mmio(sbd, &s->s_regs);
630 sysbus_init_mmio(sbd, &s->ns_regs);
633 static const VMStateDescription iotkit_secctl_ppc_vmstate = {
634 .name = "iotkit-secctl-ppc",
635 .version_id = 1,
636 .minimum_version_id = 1,
637 .fields = (VMStateField[]) {
638 VMSTATE_UINT32(ns, IoTKitSecCtlPPC),
639 VMSTATE_UINT32(sp, IoTKitSecCtlPPC),
640 VMSTATE_UINT32(nsp, IoTKitSecCtlPPC),
641 VMSTATE_END_OF_LIST()
645 static const VMStateDescription iotkit_secctl_vmstate = {
646 .name = "iotkit-secctl",
647 .version_id = 1,
648 .minimum_version_id = 1,
649 .fields = (VMStateField[]) {
650 VMSTATE_UINT32(secppcintstat, IoTKitSecCtl),
651 VMSTATE_UINT32(secppcinten, IoTKitSecCtl),
652 VMSTATE_UINT32(secrespcfg, IoTKitSecCtl),
653 VMSTATE_STRUCT_ARRAY(apb, IoTKitSecCtl, IOTS_NUM_APB_PPC, 1,
654 iotkit_secctl_ppc_vmstate, IoTKitSecCtlPPC),
655 VMSTATE_STRUCT_ARRAY(apbexp, IoTKitSecCtl, IOTS_NUM_APB_EXP_PPC, 1,
656 iotkit_secctl_ppc_vmstate, IoTKitSecCtlPPC),
657 VMSTATE_STRUCT_ARRAY(ahbexp, IoTKitSecCtl, IOTS_NUM_AHB_EXP_PPC, 1,
658 iotkit_secctl_ppc_vmstate, IoTKitSecCtlPPC),
659 VMSTATE_END_OF_LIST()
663 static void iotkit_secctl_class_init(ObjectClass *klass, void *data)
665 DeviceClass *dc = DEVICE_CLASS(klass);
667 dc->vmsd = &iotkit_secctl_vmstate;
668 dc->reset = iotkit_secctl_reset;
671 static const TypeInfo iotkit_secctl_info = {
672 .name = TYPE_IOTKIT_SECCTL,
673 .parent = TYPE_SYS_BUS_DEVICE,
674 .instance_size = sizeof(IoTKitSecCtl),
675 .instance_init = iotkit_secctl_init,
676 .class_init = iotkit_secctl_class_init,
679 static void iotkit_secctl_register_types(void)
681 type_register_static(&iotkit_secctl_info);
684 type_init(iotkit_secctl_register_types);