12
#include "qemu/osdep.h"
14
#include "qemu/module.h"
15
#include "qapi/error.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"
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)
39
REG32(AHBNSPPCEXP0, 0x60)
40
REG32(AHBNSPPCEXP1, 0x64)
41
REG32(AHBNSPPCEXP2, 0x68)
42
REG32(AHBNSPPCEXP3, 0x6c)
45
REG32(APBNSPPCEXP0, 0x80)
46
REG32(APBNSPPCEXP1, 0x84)
47
REG32(APBNSPPCEXP2, 0x88)
48
REG32(APBNSPPCEXP3, 0x8c)
50
REG32(AHBSPPPCEXP0, 0xa0)
51
REG32(AHBSPPPCEXP1, 0xa4)
52
REG32(AHBSPPPCEXP2, 0xa8)
53
REG32(AHBSPPPCEXP3, 0xac)
56
REG32(APBSPPPCEXP0, 0xc0)
57
REG32(APBSPPPCEXP1, 0xc4)
58
REG32(APBSPPPCEXP2, 0xc8)
59
REG32(APBSPPPCEXP3, 0xcc)
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)
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,
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;
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);
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)
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);
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",
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);
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 = (const 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 = (const 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 = (const 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 = (const 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 * const []) {
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);