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"
14 #include "qemu/module.h"
15 #include "qapi/error.h"
17 #include "hw/sysbus.h"
18 #include "migration/vmstate.h"
19 #include "hw/registerfields.h"
21 #include "hw/misc/iotkit-secctl.h"
22 #include "hw/arm/armsse-version.h"
23 #include "hw/qdev-properties.h"
25 /* Registers in the secure privilege control block */
26 REG32(SECRESPCFG, 0x10)
28 REG32(SECMPCINTSTATUS, 0x1c)
29 REG32(SECPPCINTSTAT, 0x20)
30 REG32(SECPPCINTCLR, 0x24)
31 REG32(SECPPCINTEN, 0x28)
32 REG32(SECMSCINTSTAT, 0x30)
33 REG32(SECMSCINTCLR, 0x34)
34 REG32(SECMSCINTEN, 0x38)
35 REG32(BRGINTSTAT, 0x40)
36 REG32(BRGINTCLR, 0x44)
38 REG32(AHBNSPPC0, 0x50)
39 REG32(AHBNSPPCEXP0, 0x60)
40 REG32(AHBNSPPCEXP1, 0x64)
41 REG32(AHBNSPPCEXP2, 0x68)
42 REG32(AHBNSPPCEXP3, 0x6c)
43 REG32(APBNSPPC0, 0x70)
44 REG32(APBNSPPC1, 0x74)
45 REG32(APBNSPPCEXP0, 0x80)
46 REG32(APBNSPPCEXP1, 0x84)
47 REG32(APBNSPPCEXP2, 0x88)
48 REG32(APBNSPPCEXP3, 0x8c)
49 REG32(AHBSPPPC0, 0x90)
50 REG32(AHBSPPPCEXP0, 0xa0)
51 REG32(AHBSPPPCEXP1, 0xa4)
52 REG32(AHBSPPPCEXP2, 0xa8)
53 REG32(AHBSPPPCEXP3, 0xac)
54 REG32(APBSPPPC0, 0xb0)
55 REG32(APBSPPPC1, 0xb4)
56 REG32(APBSPPPCEXP0, 0xc0)
57 REG32(APBSPPPCEXP1, 0xc4)
58 REG32(APBSPPPCEXP2, 0xc8)
59 REG32(APBSPPPCEXP3, 0xcc)
74 /* Registers in the non-secure privilege control block */
75 REG32(AHBNSPPPC0, 0x90)
76 REG32(AHBNSPPPCEXP0, 0xa0)
77 REG32(AHBNSPPPCEXP1, 0xa4)
78 REG32(AHBNSPPPCEXP2, 0xa8)
79 REG32(AHBNSPPPCEXP3, 0xac)
80 REG32(APBNSPPPC0, 0xb0)
81 REG32(APBNSPPPC1, 0xb4)
82 REG32(APBNSPPPCEXP0, 0xc0)
83 REG32(APBNSPPPCEXP1, 0xc4)
84 REG32(APBNSPPPCEXP2, 0xc8)
85 REG32(APBNSPPPCEXP3, 0xcc)
86 /* PID and CID registers are also present in the NS block */
88 static const uint8_t iotkit_secctl_s_idregs[] = {
89 0x04, 0x00, 0x00, 0x00,
90 0x52, 0xb8, 0x0b, 0x00,
91 0x0d, 0xf0, 0x05, 0xb1,
94 static const uint8_t iotkit_secctl_ns_idregs[] = {
95 0x04, 0x00, 0x00, 0x00,
96 0x53, 0xb8, 0x0b, 0x00,
97 0x0d, 0xf0, 0x05, 0xb1,
100 static const uint8_t iotkit_secctl_s_sse300_idregs[] = {
101 0x04, 0x00, 0x00, 0x00,
102 0x52, 0xb8, 0x2b, 0x00,
103 0x0d, 0xf0, 0x05, 0xb1,
106 static const uint8_t iotkit_secctl_ns_sse300_idregs[] = {
107 0x04, 0x00, 0x00, 0x00,
108 0x53, 0xb8, 0x2b, 0x00,
109 0x0d, 0xf0, 0x05, 0xb1,
113 /* The register sets for the various PPCs (AHB internal, APB internal,
114 * AHB expansion, APB expansion) are all set up so that they are
115 * in 16-aligned blocks so offsets 0xN0, 0xN4, 0xN8, 0xNC are PPCs
116 * 0, 1, 2, 3 of that type, so we can convert a register address offset
117 * into an an index into a PPC array easily.
119 static inline int offset_to_ppc_idx(uint32_t offset)
121 return extract32(offset, 2, 2);
124 typedef void PerPPCFunction(IoTKitSecCtlPPC *ppc);
126 static void foreach_ppc(IoTKitSecCtl *s, PerPPCFunction *fn)
130 for (i = 0; i < IOTS_NUM_APB_PPC; i++) {
133 for (i = 0; i < IOTS_NUM_APB_EXP_PPC; i++) {
136 for (i = 0; i < IOTS_NUM_AHB_EXP_PPC; i++) {
141 static MemTxResult iotkit_secctl_s_read(void *opaque, hwaddr addr,
143 unsigned size, MemTxAttrs attrs)
146 uint32_t offset = addr & ~0x3;
147 IoTKitSecCtl *s = IOTKIT_SECCTL(opaque);
160 case A_SECMPCINTSTATUS:
163 case A_SECPPCINTSTAT:
164 r = s->secppcintstat;
170 /* QEMU's bus fabric can never report errors as it doesn't buffer
171 * writes, so we never report bridge interrupts.
182 r = s->ahbexp[offset_to_ppc_idx(offset)].ns;
186 r = s->apb[offset_to_ppc_idx(offset)].ns;
192 r = s->apbexp[offset_to_ppc_idx(offset)].ns;
198 r = s->apbexp[offset_to_ppc_idx(offset)].sp;
202 r = s->apb[offset_to_ppc_idx(offset)].sp;
208 r = s->apbexp[offset_to_ppc_idx(offset)].sp;
210 case A_SECMSCINTSTAT:
211 r = s->secmscintstat;
231 switch (s->sse_version) {
233 r = iotkit_secctl_s_sse300_idregs[(offset - A_PID4) / 4];
236 r = iotkit_secctl_s_idregs[(offset - A_PID4) / 4];
243 qemu_log_mask(LOG_GUEST_ERROR,
244 "IotKit SecCtl S block read: write-only offset 0x%x\n",
249 qemu_log_mask(LOG_GUEST_ERROR,
250 "IotKit SecCtl S block read: bad offset 0x%x\n", offset);
256 /* None of our registers are access-sensitive, so just pull the right
257 * byte out of the word read result.
259 r = extract32(r, (addr & 3) * 8, size * 8);
262 trace_iotkit_secctl_s_read(offset, r, size);
267 static void iotkit_secctl_update_ppc_ap(IoTKitSecCtlPPC *ppc)
271 for (i = 0; i < ppc->numports; i++) {
274 if (extract32(ppc->ns, i, 1)) {
275 v = extract32(ppc->nsp, i, 1);
277 v = extract32(ppc->sp, i, 1);
279 qemu_set_irq(ppc->ap[i], v);
283 static void iotkit_secctl_ppc_ns_write(IoTKitSecCtlPPC *ppc, uint32_t value)
287 ppc->ns = value & MAKE_64BIT_MASK(0, ppc->numports);
288 for (i = 0; i < ppc->numports; i++) {
289 qemu_set_irq(ppc->nonsec[i], extract32(ppc->ns, i, 1));
291 iotkit_secctl_update_ppc_ap(ppc);
294 static void iotkit_secctl_ppc_sp_write(IoTKitSecCtlPPC *ppc, uint32_t value)
296 ppc->sp = value & MAKE_64BIT_MASK(0, ppc->numports);
297 iotkit_secctl_update_ppc_ap(ppc);
300 static void iotkit_secctl_ppc_nsp_write(IoTKitSecCtlPPC *ppc, uint32_t value)
302 ppc->nsp = value & MAKE_64BIT_MASK(0, ppc->numports);
303 iotkit_secctl_update_ppc_ap(ppc);
306 static void iotkit_secctl_ppc_update_irq_clear(IoTKitSecCtlPPC *ppc)
308 uint32_t value = ppc->parent->secppcintstat;
310 qemu_set_irq(ppc->irq_clear, extract32(value, ppc->irq_bit_offset, 1));
313 static void iotkit_secctl_ppc_update_irq_enable(IoTKitSecCtlPPC *ppc)
315 uint32_t value = ppc->parent->secppcinten;
317 qemu_set_irq(ppc->irq_enable, extract32(value, ppc->irq_bit_offset, 1));
320 static void iotkit_secctl_update_mscexp_irqs(qemu_irq *msc_irqs, uint32_t value)
324 for (i = 0; i < IOTS_NUM_EXP_MSC; i++) {
325 qemu_set_irq(msc_irqs[i], extract32(value, i + 16, 1));
329 static void iotkit_secctl_update_msc_irq(IoTKitSecCtl *s)
331 /* Update the combined MSC IRQ, based on S_MSCEXP_STATUS and S_MSCEXP_EN */
332 bool level = s->secmscintstat & s->secmscinten;
334 qemu_set_irq(s->msc_irq, level);
337 static MemTxResult iotkit_secctl_s_write(void *opaque, hwaddr addr,
339 unsigned size, MemTxAttrs attrs)
341 IoTKitSecCtl *s = IOTKIT_SECCTL(opaque);
342 uint32_t offset = addr;
343 IoTKitSecCtlPPC *ppc;
345 trace_iotkit_secctl_s_write(offset, value, size);
348 /* Byte and halfword writes are ignored */
349 qemu_log_mask(LOG_GUEST_ERROR,
350 "IotKit SecCtl S block write: bad size, ignored\n");
356 s->nsccfg = value & 3;
357 qemu_set_irq(s->nsc_cfg_irq, s->nsccfg);
361 s->secrespcfg = value;
362 qemu_set_irq(s->sec_resp_cfg, s->secrespcfg);
365 s->secppcintstat &= ~(value & 0x00f000f3);
366 foreach_ppc(s, iotkit_secctl_ppc_update_irq_clear);
369 s->secppcinten = value & 0x00f000f3;
370 foreach_ppc(s, iotkit_secctl_ppc_update_irq_enable);
375 s->brginten = value & 0xffff0000;
381 ppc = &s->ahbexp[offset_to_ppc_idx(offset)];
382 iotkit_secctl_ppc_ns_write(ppc, value);
386 ppc = &s->apb[offset_to_ppc_idx(offset)];
387 iotkit_secctl_ppc_ns_write(ppc, value);
393 ppc = &s->apbexp[offset_to_ppc_idx(offset)];
394 iotkit_secctl_ppc_ns_write(ppc, value);
400 ppc = &s->ahbexp[offset_to_ppc_idx(offset)];
401 iotkit_secctl_ppc_sp_write(ppc, value);
405 ppc = &s->apb[offset_to_ppc_idx(offset)];
406 iotkit_secctl_ppc_sp_write(ppc, value);
412 ppc = &s->apbexp[offset_to_ppc_idx(offset)];
413 iotkit_secctl_ppc_sp_write(ppc, value);
416 iotkit_secctl_update_mscexp_irqs(s->mscexp_clear, value);
419 s->secmscinten = value;
420 iotkit_secctl_update_msc_irq(s);
424 iotkit_secctl_update_mscexp_irqs(s->mscexp_ns, value);
426 case A_SECMPCINTSTATUS:
427 case A_SECPPCINTSTAT:
428 case A_SECMSCINTSTAT:
444 qemu_log_mask(LOG_GUEST_ERROR,
445 "IoTKit SecCtl S block write: "
446 "read-only offset 0x%x\n", offset);
449 qemu_log_mask(LOG_GUEST_ERROR,
450 "IotKit SecCtl S block write: bad offset 0x%x\n",
458 static MemTxResult iotkit_secctl_ns_read(void *opaque, hwaddr addr,
460 unsigned size, MemTxAttrs attrs)
462 IoTKitSecCtl *s = IOTKIT_SECCTL(opaque);
464 uint32_t offset = addr & ~0x3;
470 case A_AHBNSPPPCEXP0:
471 case A_AHBNSPPPCEXP1:
472 case A_AHBNSPPPCEXP2:
473 case A_AHBNSPPPCEXP3:
474 r = s->ahbexp[offset_to_ppc_idx(offset)].nsp;
478 r = s->apb[offset_to_ppc_idx(offset)].nsp;
480 case A_APBNSPPPCEXP0:
481 case A_APBNSPPPCEXP1:
482 case A_APBNSPPPCEXP2:
483 case A_APBNSPPPCEXP3:
484 r = s->apbexp[offset_to_ppc_idx(offset)].nsp;
498 switch (s->sse_version) {
500 r = iotkit_secctl_ns_sse300_idregs[(offset - A_PID4) / 4];
503 r = iotkit_secctl_ns_idregs[(offset - A_PID4) / 4];
508 qemu_log_mask(LOG_GUEST_ERROR,
509 "IotKit SecCtl NS block write: bad offset 0x%x\n",
516 /* None of our registers are access-sensitive, so just pull the right
517 * byte out of the word read result.
519 r = extract32(r, (addr & 3) * 8, size * 8);
522 trace_iotkit_secctl_ns_read(offset, r, size);
527 static MemTxResult iotkit_secctl_ns_write(void *opaque, hwaddr addr,
529 unsigned size, MemTxAttrs attrs)
531 IoTKitSecCtl *s = IOTKIT_SECCTL(opaque);
532 uint32_t offset = addr;
533 IoTKitSecCtlPPC *ppc;
535 trace_iotkit_secctl_ns_write(offset, value, size);
538 /* Byte and halfword writes are ignored */
539 qemu_log_mask(LOG_GUEST_ERROR,
540 "IotKit SecCtl NS block write: bad size, ignored\n");
545 case A_AHBNSPPPCEXP0:
546 case A_AHBNSPPPCEXP1:
547 case A_AHBNSPPPCEXP2:
548 case A_AHBNSPPPCEXP3:
549 ppc = &s->ahbexp[offset_to_ppc_idx(offset)];
550 iotkit_secctl_ppc_nsp_write(ppc, value);
554 ppc = &s->apb[offset_to_ppc_idx(offset)];
555 iotkit_secctl_ppc_nsp_write(ppc, value);
557 case A_APBNSPPPCEXP0:
558 case A_APBNSPPPCEXP1:
559 case A_APBNSPPPCEXP2:
560 case A_APBNSPPPCEXP3:
561 ppc = &s->apbexp[offset_to_ppc_idx(offset)];
562 iotkit_secctl_ppc_nsp_write(ppc, value);
577 qemu_log_mask(LOG_GUEST_ERROR,
578 "IoTKit SecCtl NS block write: "
579 "read-only offset 0x%x\n", offset);
582 qemu_log_mask(LOG_GUEST_ERROR,
583 "IotKit SecCtl NS block write: bad offset 0x%x\n",
591 static const MemoryRegionOps iotkit_secctl_s_ops = {
592 .read_with_attrs = iotkit_secctl_s_read,
593 .write_with_attrs = iotkit_secctl_s_write,
594 .endianness = DEVICE_LITTLE_ENDIAN,
595 .valid.min_access_size = 1,
596 .valid.max_access_size = 4,
597 .impl.min_access_size = 1,
598 .impl.max_access_size = 4,
601 static const MemoryRegionOps iotkit_secctl_ns_ops = {
602 .read_with_attrs = iotkit_secctl_ns_read,
603 .write_with_attrs = iotkit_secctl_ns_write,
604 .endianness = DEVICE_LITTLE_ENDIAN,
605 .valid.min_access_size = 1,
606 .valid.max_access_size = 4,
607 .impl.min_access_size = 1,
608 .impl.max_access_size = 4,
611 static void iotkit_secctl_reset_ppc(IoTKitSecCtlPPC *ppc)
618 static void iotkit_secctl_reset(DeviceState *dev)
620 IoTKitSecCtl *s = IOTKIT_SECCTL(dev);
622 s->secppcintstat = 0;
628 foreach_ppc(s, iotkit_secctl_reset_ppc);
631 static void iotkit_secctl_mpc_status(void *opaque, int n, int level)
633 IoTKitSecCtl *s = IOTKIT_SECCTL(opaque);
635 s->mpcintstatus = deposit32(s->mpcintstatus, n, 1, !!level);
638 static void iotkit_secctl_mpcexp_status(void *opaque, int n, int level)
640 IoTKitSecCtl *s = IOTKIT_SECCTL(opaque);
642 s->mpcintstatus = deposit32(s->mpcintstatus, n + 16, 1, !!level);
645 static void iotkit_secctl_mscexp_status(void *opaque, int n, int level)
647 IoTKitSecCtl *s = IOTKIT_SECCTL(opaque);
649 s->secmscintstat = deposit32(s->secmscintstat, n + 16, 1, !!level);
650 iotkit_secctl_update_msc_irq(s);
653 static void iotkit_secctl_ppc_irqstatus(void *opaque, int n, int level)
655 IoTKitSecCtlPPC *ppc = opaque;
656 IoTKitSecCtl *s = IOTKIT_SECCTL(ppc->parent);
657 int irqbit = ppc->irq_bit_offset + n;
659 s->secppcintstat = deposit32(s->secppcintstat, irqbit, 1, level);
662 static void iotkit_secctl_init_ppc(IoTKitSecCtl *s,
663 IoTKitSecCtlPPC *ppc,
669 DeviceState *dev = DEVICE(s);
671 ppc->numports = numports;
672 ppc->irq_bit_offset = irq_bit_offset;
675 gpioname = g_strdup_printf("%s_nonsec", name);
676 qdev_init_gpio_out_named(dev, ppc->nonsec, gpioname, numports);
678 gpioname = g_strdup_printf("%s_ap", name);
679 qdev_init_gpio_out_named(dev, ppc->ap, gpioname, numports);
681 gpioname = g_strdup_printf("%s_irq_enable", name);
682 qdev_init_gpio_out_named(dev, &ppc->irq_enable, gpioname, 1);
684 gpioname = g_strdup_printf("%s_irq_clear", name);
685 qdev_init_gpio_out_named(dev, &ppc->irq_clear, gpioname, 1);
687 gpioname = g_strdup_printf("%s_irq_status", name);
688 qdev_init_gpio_in_named_with_opaque(dev, iotkit_secctl_ppc_irqstatus,
693 static void iotkit_secctl_init(Object *obj)
695 IoTKitSecCtl *s = IOTKIT_SECCTL(obj);
696 SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
697 DeviceState *dev = DEVICE(obj);
700 iotkit_secctl_init_ppc(s, &s->apb[0], "apb_ppc0",
701 IOTS_APB_PPC0_NUM_PORTS, 0);
702 iotkit_secctl_init_ppc(s, &s->apb[1], "apb_ppc1",
703 IOTS_APB_PPC1_NUM_PORTS, 1);
705 for (i = 0; i < IOTS_NUM_APB_EXP_PPC; i++) {
706 IoTKitSecCtlPPC *ppc = &s->apbexp[i];
707 char *ppcname = g_strdup_printf("apb_ppcexp%d", i);
708 iotkit_secctl_init_ppc(s, ppc, ppcname, IOTS_PPC_NUM_PORTS, 4 + i);
711 for (i = 0; i < IOTS_NUM_AHB_EXP_PPC; i++) {
712 IoTKitSecCtlPPC *ppc = &s->ahbexp[i];
713 char *ppcname = g_strdup_printf("ahb_ppcexp%d", i);
714 iotkit_secctl_init_ppc(s, ppc, ppcname, IOTS_PPC_NUM_PORTS, 20 + i);
718 qdev_init_gpio_out_named(dev, &s->sec_resp_cfg, "sec_resp_cfg", 1);
719 qdev_init_gpio_out_named(dev, &s->nsc_cfg_irq, "nsc_cfg", 1);
721 qdev_init_gpio_in_named(dev, iotkit_secctl_mpc_status, "mpc_status",
723 qdev_init_gpio_in_named(dev, iotkit_secctl_mpcexp_status,
724 "mpcexp_status", IOTS_NUM_EXP_MPC);
726 qdev_init_gpio_in_named(dev, iotkit_secctl_mscexp_status,
727 "mscexp_status", IOTS_NUM_EXP_MSC);
728 qdev_init_gpio_out_named(dev, s->mscexp_clear, "mscexp_clear",
730 qdev_init_gpio_out_named(dev, s->mscexp_ns, "mscexp_ns",
732 qdev_init_gpio_out_named(dev, &s->msc_irq, "msc_irq", 1);
734 memory_region_init_io(&s->s_regs, obj, &iotkit_secctl_s_ops,
735 s, "iotkit-secctl-s-regs", 0x1000);
736 memory_region_init_io(&s->ns_regs, obj, &iotkit_secctl_ns_ops,
737 s, "iotkit-secctl-ns-regs", 0x1000);
738 sysbus_init_mmio(sbd, &s->s_regs);
739 sysbus_init_mmio(sbd, &s->ns_regs);
742 static void iotkit_secctl_realize(DeviceState *dev, Error **errp)
744 IoTKitSecCtl *s = IOTKIT_SECCTL(dev);
746 if (!armsse_version_valid(s->sse_version)) {
747 error_setg(errp, "invalid sse-version value %d", s->sse_version);
752 static const VMStateDescription iotkit_secctl_ppc_vmstate = {
753 .name = "iotkit-secctl-ppc",
755 .minimum_version_id = 1,
756 .fields = (VMStateField[]) {
757 VMSTATE_UINT32(ns, IoTKitSecCtlPPC),
758 VMSTATE_UINT32(sp, IoTKitSecCtlPPC),
759 VMSTATE_UINT32(nsp, IoTKitSecCtlPPC),
760 VMSTATE_END_OF_LIST()
764 static const VMStateDescription iotkit_secctl_mpcintstatus_vmstate = {
765 .name = "iotkit-secctl-mpcintstatus",
767 .minimum_version_id = 1,
768 .fields = (VMStateField[]) {
769 VMSTATE_UINT32(mpcintstatus, IoTKitSecCtl),
770 VMSTATE_END_OF_LIST()
774 static bool needed_always(void *opaque)
779 static const VMStateDescription iotkit_secctl_msc_vmstate = {
780 .name = "iotkit-secctl/msc",
782 .minimum_version_id = 1,
783 .needed = needed_always,
784 .fields = (VMStateField[]) {
785 VMSTATE_UINT32(secmscintstat, IoTKitSecCtl),
786 VMSTATE_UINT32(secmscinten, IoTKitSecCtl),
787 VMSTATE_UINT32(nsmscexp, IoTKitSecCtl),
788 VMSTATE_END_OF_LIST()
792 static const VMStateDescription iotkit_secctl_vmstate = {
793 .name = "iotkit-secctl",
795 .minimum_version_id = 1,
796 .fields = (VMStateField[]) {
797 VMSTATE_UINT32(secppcintstat, IoTKitSecCtl),
798 VMSTATE_UINT32(secppcinten, IoTKitSecCtl),
799 VMSTATE_UINT32(secrespcfg, IoTKitSecCtl),
800 VMSTATE_UINT32(nsccfg, IoTKitSecCtl),
801 VMSTATE_UINT32(brginten, IoTKitSecCtl),
802 VMSTATE_STRUCT_ARRAY(apb, IoTKitSecCtl, IOTS_NUM_APB_PPC, 1,
803 iotkit_secctl_ppc_vmstate, IoTKitSecCtlPPC),
804 VMSTATE_STRUCT_ARRAY(apbexp, IoTKitSecCtl, IOTS_NUM_APB_EXP_PPC, 1,
805 iotkit_secctl_ppc_vmstate, IoTKitSecCtlPPC),
806 VMSTATE_STRUCT_ARRAY(ahbexp, IoTKitSecCtl, IOTS_NUM_AHB_EXP_PPC, 1,
807 iotkit_secctl_ppc_vmstate, IoTKitSecCtlPPC),
808 VMSTATE_END_OF_LIST()
810 .subsections = (const VMStateDescription*[]) {
811 &iotkit_secctl_mpcintstatus_vmstate,
812 &iotkit_secctl_msc_vmstate,
817 static Property iotkit_secctl_props[] = {
818 DEFINE_PROP_UINT32("sse-version", IoTKitSecCtl, sse_version, 0),
819 DEFINE_PROP_END_OF_LIST()
822 static void iotkit_secctl_class_init(ObjectClass *klass, void *data)
824 DeviceClass *dc = DEVICE_CLASS(klass);
826 dc->vmsd = &iotkit_secctl_vmstate;
827 dc->reset = iotkit_secctl_reset;
828 dc->realize = iotkit_secctl_realize;
829 device_class_set_props(dc, iotkit_secctl_props);
832 static const TypeInfo iotkit_secctl_info = {
833 .name = TYPE_IOTKIT_SECCTL,
834 .parent = TYPE_SYS_BUS_DEVICE,
835 .instance_size = sizeof(IoTKitSecCtl),
836 .instance_init = iotkit_secctl_init,
837 .class_init = iotkit_secctl_class_init,
840 static void iotkit_secctl_register_types(void)
842 type_register_static(&iotkit_secctl_info);
845 type_init(iotkit_secctl_register_types);