/*
 * Arm IoT Kit security controller
 *
 * Copyright (c) 2018 Linaro Limited
 * Written by Peter Maydell
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 or
 * (at your option) any later version.
 */

#include "qemu/osdep.h"
#include "qemu/log.h"
#include "qemu/module.h"
#include "qapi/error.h"
#include "trace.h"
#include "hw/sysbus.h"
#include "migration/vmstate.h"
#include "hw/registerfields.h"
#include "hw/irq.h"
#include "hw/misc/iotkit-secctl.h"

/* Registers in the secure privilege control block */
REG32(SECRESPCFG, 0x10)
REG32(NSCCFG, 0x14)
REG32(SECMPCINTSTATUS, 0x1c)
REG32(SECPPCINTSTAT, 0x20)
REG32(SECPPCINTCLR, 0x24)
REG32(SECPPCINTEN, 0x28)
REG32(SECMSCINTSTAT, 0x30)
REG32(SECMSCINTCLR, 0x34)
REG32(SECMSCINTEN, 0x38)
REG32(BRGINTSTAT, 0x40)
REG32(BRGINTCLR, 0x44)
REG32(BRGINTEN, 0x48)
REG32(AHBNSPPC0, 0x50)
REG32(AHBNSPPCEXP0, 0x60)
REG32(AHBNSPPCEXP1, 0x64)
REG32(AHBNSPPCEXP2, 0x68)
REG32(AHBNSPPCEXP3, 0x6c)
REG32(APBNSPPC0, 0x70)
REG32(APBNSPPC1, 0x74)
REG32(APBNSPPCEXP0, 0x80)
REG32(APBNSPPCEXP1, 0x84)
REG32(APBNSPPCEXP2, 0x88)
REG32(APBNSPPCEXP3, 0x8c)
REG32(AHBSPPPC0, 0x90)
REG32(AHBSPPPCEXP0, 0xa0)
REG32(AHBSPPPCEXP1, 0xa4)
REG32(AHBSPPPCEXP2, 0xa8)
REG32(AHBSPPPCEXP3, 0xac)
REG32(APBSPPPC0, 0xb0)
REG32(APBSPPPC1, 0xb4)
REG32(APBSPPPCEXP0, 0xc0)
REG32(APBSPPPCEXP1, 0xc4)
REG32(APBSPPPCEXP2, 0xc8)
REG32(APBSPPPCEXP3, 0xcc)
REG32(NSMSCEXP, 0xd0)
REG32(PID4, 0xfd0)
REG32(PID5, 0xfd4)
REG32(PID6, 0xfd8)
REG32(PID7, 0xfdc)
REG32(PID0, 0xfe0)
REG32(PID1, 0xfe4)
REG32(PID2, 0xfe8)
REG32(PID3, 0xfec)
REG32(CID0, 0xff0)
REG32(CID1, 0xff4)
REG32(CID2, 0xff8)
REG32(CID3, 0xffc)

/* Registers in the non-secure privilege control block */
REG32(AHBNSPPPC0, 0x90)
REG32(AHBNSPPPCEXP0, 0xa0)
REG32(AHBNSPPPCEXP1, 0xa4)
REG32(AHBNSPPPCEXP2, 0xa8)
REG32(AHBNSPPPCEXP3, 0xac)
REG32(APBNSPPPC0, 0xb0)
REG32(APBNSPPPC1, 0xb4)
REG32(APBNSPPPCEXP0, 0xc0)
REG32(APBNSPPPCEXP1, 0xc4)
REG32(APBNSPPPCEXP2, 0xc8)
REG32(APBNSPPPCEXP3, 0xcc)
/* PID and CID registers are also present in the NS block */

static const uint8_t iotkit_secctl_s_idregs[] = {
    0x04, 0x00, 0x00, 0x00,
    0x52, 0xb8, 0x0b, 0x00,
    0x0d, 0xf0, 0x05, 0xb1,
};

static const uint8_t iotkit_secctl_ns_idregs[] = {
    0x04, 0x00, 0x00, 0x00,
    0x53, 0xb8, 0x0b, 0x00,
    0x0d, 0xf0, 0x05, 0xb1,
};

/* The register sets for the various PPCs (AHB internal, APB internal,
 * AHB expansion, APB expansion) are all set up so that they are
 * in 16-aligned blocks so offsets 0xN0, 0xN4, 0xN8, 0xNC are PPCs
 * 0, 1, 2, 3 of that type, so we can convert a register address offset
 * into an an index into a PPC array easily.
 */
static inline int offset_to_ppc_idx(uint32_t offset)
{
    return extract32(offset, 2, 2);
}

typedef void PerPPCFunction(IoTKitSecCtlPPC *ppc);

static void foreach_ppc(IoTKitSecCtl *s, PerPPCFunction *fn)
{
    int i;

    for (i = 0; i < IOTS_NUM_APB_PPC; i++) {
        fn(&s->apb[i]);
    }
    for (i = 0; i < IOTS_NUM_APB_EXP_PPC; i++) {
        fn(&s->apbexp[i]);
    }
    for (i = 0; i < IOTS_NUM_AHB_EXP_PPC; i++) {
        fn(&s->ahbexp[i]);
    }
}

static MemTxResult iotkit_secctl_s_read(void *opaque, hwaddr addr,
                                        uint64_t *pdata,
                                        unsigned size, MemTxAttrs attrs)
{
    uint64_t r;
    uint32_t offset = addr & ~0x3;
    IoTKitSecCtl *s = IOTKIT_SECCTL(opaque);

    switch (offset) {
    case A_AHBNSPPC0:
    case A_AHBSPPPC0:
        r = 0;
        break;
    case A_SECRESPCFG:
        r = s->secrespcfg;
        break;
    case A_NSCCFG:
        r = s->nsccfg;
        break;
    case A_SECMPCINTSTATUS:
        r = s->mpcintstatus;
        break;
    case A_SECPPCINTSTAT:
        r = s->secppcintstat;
        break;
    case A_SECPPCINTEN:
        r = s->secppcinten;
        break;
    case A_BRGINTSTAT:
        /* QEMU's bus fabric can never report errors as it doesn't buffer
         * writes, so we never report bridge interrupts.
         */
        r = 0;
        break;
    case A_BRGINTEN:
        r = s->brginten;
        break;
    case A_AHBNSPPCEXP0:
    case A_AHBNSPPCEXP1:
    case A_AHBNSPPCEXP2:
    case A_AHBNSPPCEXP3:
        r = s->ahbexp[offset_to_ppc_idx(offset)].ns;
        break;
    case A_APBNSPPC0:
    case A_APBNSPPC1:
        r = s->apb[offset_to_ppc_idx(offset)].ns;
        break;
    case A_APBNSPPCEXP0:
    case A_APBNSPPCEXP1:
    case A_APBNSPPCEXP2:
    case A_APBNSPPCEXP3:
        r = s->apbexp[offset_to_ppc_idx(offset)].ns;
        break;
    case A_AHBSPPPCEXP0:
    case A_AHBSPPPCEXP1:
    case A_AHBSPPPCEXP2:
    case A_AHBSPPPCEXP3:
        r = s->apbexp[offset_to_ppc_idx(offset)].sp;
        break;
    case A_APBSPPPC0:
    case A_APBSPPPC1:
        r = s->apb[offset_to_ppc_idx(offset)].sp;
        break;
    case A_APBSPPPCEXP0:
    case A_APBSPPPCEXP1:
    case A_APBSPPPCEXP2:
    case A_APBSPPPCEXP3:
        r = s->apbexp[offset_to_ppc_idx(offset)].sp;
        break;
    case A_SECMSCINTSTAT:
        r = s->secmscintstat;
        break;
    case A_SECMSCINTEN:
        r = s->secmscinten;
        break;
    case A_NSMSCEXP:
        r = s->nsmscexp;
        break;
    case A_PID4:
    case A_PID5:
    case A_PID6:
    case A_PID7:
    case A_PID0:
    case A_PID1:
    case A_PID2:
    case A_PID3:
    case A_CID0:
    case A_CID1:
    case A_CID2:
    case A_CID3:
        r = iotkit_secctl_s_idregs[(offset - A_PID4) / 4];
        break;
    case A_SECPPCINTCLR:
    case A_SECMSCINTCLR:
    case A_BRGINTCLR:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "IotKit SecCtl S block read: write-only offset 0x%x\n",
                      offset);
        r = 0;
        break;
    default:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "IotKit SecCtl S block read: bad offset 0x%x\n", offset);
        r = 0;
        break;
    }

    if (size != 4) {
        /* None of our registers are access-sensitive, so just pull the right
         * byte out of the word read result.
         */
        r = extract32(r, (addr & 3) * 8, size * 8);
    }

    trace_iotkit_secctl_s_read(offset, r, size);
    *pdata = r;
    return MEMTX_OK;
}

static void iotkit_secctl_update_ppc_ap(IoTKitSecCtlPPC *ppc)
{
    int i;

    for (i = 0; i < ppc->numports; i++) {
        bool v;

        if (extract32(ppc->ns, i, 1)) {
            v = extract32(ppc->nsp, i, 1);
        } else {
            v = extract32(ppc->sp, i, 1);
        }
        qemu_set_irq(ppc->ap[i], v);
    }
}

static void iotkit_secctl_ppc_ns_write(IoTKitSecCtlPPC *ppc, uint32_t value)
{
    int i;

    ppc->ns = value & MAKE_64BIT_MASK(0, ppc->numports);
    for (i = 0; i < ppc->numports; i++) {
        qemu_set_irq(ppc->nonsec[i], extract32(ppc->ns, i, 1));
    }
    iotkit_secctl_update_ppc_ap(ppc);
}

static void iotkit_secctl_ppc_sp_write(IoTKitSecCtlPPC *ppc, uint32_t value)
{
    ppc->sp = value & MAKE_64BIT_MASK(0, ppc->numports);
    iotkit_secctl_update_ppc_ap(ppc);
}

static void iotkit_secctl_ppc_nsp_write(IoTKitSecCtlPPC *ppc, uint32_t value)
{
    ppc->nsp = value & MAKE_64BIT_MASK(0, ppc->numports);
    iotkit_secctl_update_ppc_ap(ppc);
}

static void iotkit_secctl_ppc_update_irq_clear(IoTKitSecCtlPPC *ppc)
{
    uint32_t value = ppc->parent->secppcintstat;

    qemu_set_irq(ppc->irq_clear, extract32(value, ppc->irq_bit_offset, 1));
}

static void iotkit_secctl_ppc_update_irq_enable(IoTKitSecCtlPPC *ppc)
{
    uint32_t value = ppc->parent->secppcinten;

    qemu_set_irq(ppc->irq_enable, extract32(value, ppc->irq_bit_offset, 1));
}

static void iotkit_secctl_update_mscexp_irqs(qemu_irq *msc_irqs, uint32_t value)
{
    int i;

    for (i = 0; i < IOTS_NUM_EXP_MSC; i++) {
        qemu_set_irq(msc_irqs[i], extract32(value, i + 16, 1));
    }
}

static void iotkit_secctl_update_msc_irq(IoTKitSecCtl *s)
{
    /* Update the combined MSC IRQ, based on S_MSCEXP_STATUS and S_MSCEXP_EN */
    bool level = s->secmscintstat & s->secmscinten;

    qemu_set_irq(s->msc_irq, level);
}

static MemTxResult iotkit_secctl_s_write(void *opaque, hwaddr addr,
                                         uint64_t value,
                                         unsigned size, MemTxAttrs attrs)
{
    IoTKitSecCtl *s = IOTKIT_SECCTL(opaque);
    uint32_t offset = addr;
    IoTKitSecCtlPPC *ppc;

    trace_iotkit_secctl_s_write(offset, value, size);

    if (size != 4) {
        /* Byte and halfword writes are ignored */
        qemu_log_mask(LOG_GUEST_ERROR,
                      "IotKit SecCtl S block write: bad size, ignored\n");
        return MEMTX_OK;
    }

    switch (offset) {
    case A_NSCCFG:
        s->nsccfg = value & 3;
        qemu_set_irq(s->nsc_cfg_irq, s->nsccfg);
        break;
    case A_SECRESPCFG:
        value &= 1;
        s->secrespcfg = value;
        qemu_set_irq(s->sec_resp_cfg, s->secrespcfg);
        break;
    case A_SECPPCINTCLR:
        s->secppcintstat &= ~(value & 0x00f000f3);
        foreach_ppc(s, iotkit_secctl_ppc_update_irq_clear);
        break;
    case A_SECPPCINTEN:
        s->secppcinten = value & 0x00f000f3;
        foreach_ppc(s, iotkit_secctl_ppc_update_irq_enable);
        break;
    case A_BRGINTCLR:
        break;
    case A_BRGINTEN:
        s->brginten = value & 0xffff0000;
        break;
    case A_AHBNSPPCEXP0:
    case A_AHBNSPPCEXP1:
    case A_AHBNSPPCEXP2:
    case A_AHBNSPPCEXP3:
        ppc = &s->ahbexp[offset_to_ppc_idx(offset)];
        iotkit_secctl_ppc_ns_write(ppc, value);
        break;
    case A_APBNSPPC0:
    case A_APBNSPPC1:
        ppc = &s->apb[offset_to_ppc_idx(offset)];
        iotkit_secctl_ppc_ns_write(ppc, value);
        break;
    case A_APBNSPPCEXP0:
    case A_APBNSPPCEXP1:
    case A_APBNSPPCEXP2:
    case A_APBNSPPCEXP3:
        ppc = &s->apbexp[offset_to_ppc_idx(offset)];
        iotkit_secctl_ppc_ns_write(ppc, value);
        break;
    case A_AHBSPPPCEXP0:
    case A_AHBSPPPCEXP1:
    case A_AHBSPPPCEXP2:
    case A_AHBSPPPCEXP3:
        ppc = &s->ahbexp[offset_to_ppc_idx(offset)];
        iotkit_secctl_ppc_sp_write(ppc, value);
        break;
    case A_APBSPPPC0:
    case A_APBSPPPC1:
        ppc = &s->apb[offset_to_ppc_idx(offset)];
        iotkit_secctl_ppc_sp_write(ppc, value);
        break;
    case A_APBSPPPCEXP0:
    case A_APBSPPPCEXP1:
    case A_APBSPPPCEXP2:
    case A_APBSPPPCEXP3:
        ppc = &s->apbexp[offset_to_ppc_idx(offset)];
        iotkit_secctl_ppc_sp_write(ppc, value);
        break;
    case A_SECMSCINTCLR:
        iotkit_secctl_update_mscexp_irqs(s->mscexp_clear, value);
        break;
    case A_SECMSCINTEN:
        s->secmscinten = value;
        iotkit_secctl_update_msc_irq(s);
        break;
    case A_NSMSCEXP:
        s->nsmscexp = value;
        iotkit_secctl_update_mscexp_irqs(s->mscexp_ns, value);
        break;
    case A_SECMPCINTSTATUS:
    case A_SECPPCINTSTAT:
    case A_SECMSCINTSTAT:
    case A_BRGINTSTAT:
    case A_AHBNSPPC0:
    case A_AHBSPPPC0:
    case A_PID4:
    case A_PID5:
    case A_PID6:
    case A_PID7:
    case A_PID0:
    case A_PID1:
    case A_PID2:
    case A_PID3:
    case A_CID0:
    case A_CID1:
    case A_CID2:
    case A_CID3:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "IoTKit SecCtl S block write: "
                      "read-only offset 0x%x\n", offset);
        break;
    default:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "IotKit SecCtl S block write: bad offset 0x%x\n",
                      offset);
        break;
    }

    return MEMTX_OK;
}

static MemTxResult iotkit_secctl_ns_read(void *opaque, hwaddr addr,
                                         uint64_t *pdata,
                                         unsigned size, MemTxAttrs attrs)
{
    IoTKitSecCtl *s = IOTKIT_SECCTL(opaque);
    uint64_t r;
    uint32_t offset = addr & ~0x3;

    switch (offset) {
    case A_AHBNSPPPC0:
        r = 0;
        break;
    case A_AHBNSPPPCEXP0:
    case A_AHBNSPPPCEXP1:
    case A_AHBNSPPPCEXP2:
    case A_AHBNSPPPCEXP3:
        r = s->ahbexp[offset_to_ppc_idx(offset)].nsp;
        break;
    case A_APBNSPPPC0:
    case A_APBNSPPPC1:
        r = s->apb[offset_to_ppc_idx(offset)].nsp;
        break;
    case A_APBNSPPPCEXP0:
    case A_APBNSPPPCEXP1:
    case A_APBNSPPPCEXP2:
    case A_APBNSPPPCEXP3:
        r = s->apbexp[offset_to_ppc_idx(offset)].nsp;
        break;
    case A_PID4:
    case A_PID5:
    case A_PID6:
    case A_PID7:
    case A_PID0:
    case A_PID1:
    case A_PID2:
    case A_PID3:
    case A_CID0:
    case A_CID1:
    case A_CID2:
    case A_CID3:
        r = iotkit_secctl_ns_idregs[(offset - A_PID4) / 4];
        break;
    default:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "IotKit SecCtl NS block write: bad offset 0x%x\n",
                      offset);
        r = 0;
        break;
    }

    if (size != 4) {
        /* None of our registers are access-sensitive, so just pull the right
         * byte out of the word read result.
         */
        r = extract32(r, (addr & 3) * 8, size * 8);
    }

    trace_iotkit_secctl_ns_read(offset, r, size);
    *pdata = r;
    return MEMTX_OK;
}

static MemTxResult iotkit_secctl_ns_write(void *opaque, hwaddr addr,
                                          uint64_t value,
                                          unsigned size, MemTxAttrs attrs)
{
    IoTKitSecCtl *s = IOTKIT_SECCTL(opaque);
    uint32_t offset = addr;
    IoTKitSecCtlPPC *ppc;

    trace_iotkit_secctl_ns_write(offset, value, size);

    if (size != 4) {
        /* Byte and halfword writes are ignored */
        qemu_log_mask(LOG_GUEST_ERROR,
                      "IotKit SecCtl NS block write: bad size, ignored\n");
        return MEMTX_OK;
    }

    switch (offset) {
    case A_AHBNSPPPCEXP0:
    case A_AHBNSPPPCEXP1:
    case A_AHBNSPPPCEXP2:
    case A_AHBNSPPPCEXP3:
        ppc = &s->ahbexp[offset_to_ppc_idx(offset)];
        iotkit_secctl_ppc_nsp_write(ppc, value);
        break;
    case A_APBNSPPPC0:
    case A_APBNSPPPC1:
        ppc = &s->apb[offset_to_ppc_idx(offset)];
        iotkit_secctl_ppc_nsp_write(ppc, value);
        break;
    case A_APBNSPPPCEXP0:
    case A_APBNSPPPCEXP1:
    case A_APBNSPPPCEXP2:
    case A_APBNSPPPCEXP3:
        ppc = &s->apbexp[offset_to_ppc_idx(offset)];
        iotkit_secctl_ppc_nsp_write(ppc, value);
        break;
    case A_AHBNSPPPC0:
    case A_PID4:
    case A_PID5:
    case A_PID6:
    case A_PID7:
    case A_PID0:
    case A_PID1:
    case A_PID2:
    case A_PID3:
    case A_CID0:
    case A_CID1:
    case A_CID2:
    case A_CID3:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "IoTKit SecCtl NS block write: "
                      "read-only offset 0x%x\n", offset);
        break;
    default:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "IotKit SecCtl NS block write: bad offset 0x%x\n",
                      offset);
        break;
    }

    return MEMTX_OK;
}

static const MemoryRegionOps iotkit_secctl_s_ops = {
    .read_with_attrs = iotkit_secctl_s_read,
    .write_with_attrs = iotkit_secctl_s_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
    .valid.min_access_size = 1,
    .valid.max_access_size = 4,
    .impl.min_access_size = 1,
    .impl.max_access_size = 4,
};

static const MemoryRegionOps iotkit_secctl_ns_ops = {
    .read_with_attrs = iotkit_secctl_ns_read,
    .write_with_attrs = iotkit_secctl_ns_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
    .valid.min_access_size = 1,
    .valid.max_access_size = 4,
    .impl.min_access_size = 1,
    .impl.max_access_size = 4,
};

static void iotkit_secctl_reset_ppc(IoTKitSecCtlPPC *ppc)
{
    ppc->ns = 0;
    ppc->sp = 0;
    ppc->nsp = 0;
}

static void iotkit_secctl_reset(DeviceState *dev)
{
    IoTKitSecCtl *s = IOTKIT_SECCTL(dev);

    s->secppcintstat = 0;
    s->secppcinten = 0;
    s->secrespcfg = 0;
    s->nsccfg = 0;
    s->brginten = 0;

    foreach_ppc(s, iotkit_secctl_reset_ppc);
}

static void iotkit_secctl_mpc_status(void *opaque, int n, int level)
{
    IoTKitSecCtl *s = IOTKIT_SECCTL(opaque);

    s->mpcintstatus = deposit32(s->mpcintstatus, n, 1, !!level);
}

static void iotkit_secctl_mpcexp_status(void *opaque, int n, int level)
{
    IoTKitSecCtl *s = IOTKIT_SECCTL(opaque);

    s->mpcintstatus = deposit32(s->mpcintstatus, n + 16, 1, !!level);
}

static void iotkit_secctl_mscexp_status(void *opaque, int n, int level)
{
    IoTKitSecCtl *s = IOTKIT_SECCTL(opaque);

    s->secmscintstat = deposit32(s->secmscintstat, n + 16, 1, !!level);
    iotkit_secctl_update_msc_irq(s);
}

static void iotkit_secctl_ppc_irqstatus(void *opaque, int n, int level)
{
    IoTKitSecCtlPPC *ppc = opaque;
    IoTKitSecCtl *s = IOTKIT_SECCTL(ppc->parent);
    int irqbit = ppc->irq_bit_offset + n;

    s->secppcintstat = deposit32(s->secppcintstat, irqbit, 1, level);
}

static void iotkit_secctl_init_ppc(IoTKitSecCtl *s,
                                   IoTKitSecCtlPPC *ppc,
                                   const char *name,
                                   int numports,
                                   int irq_bit_offset)
{
    char *gpioname;
    DeviceState *dev = DEVICE(s);

    ppc->numports = numports;
    ppc->irq_bit_offset = irq_bit_offset;
    ppc->parent = s;

    gpioname = g_strdup_printf("%s_nonsec", name);
    qdev_init_gpio_out_named(dev, ppc->nonsec, gpioname, numports);
    g_free(gpioname);
    gpioname = g_strdup_printf("%s_ap", name);
    qdev_init_gpio_out_named(dev, ppc->ap, gpioname, numports);
    g_free(gpioname);
    gpioname = g_strdup_printf("%s_irq_enable", name);
    qdev_init_gpio_out_named(dev, &ppc->irq_enable, gpioname, 1);
    g_free(gpioname);
    gpioname = g_strdup_printf("%s_irq_clear", name);
    qdev_init_gpio_out_named(dev, &ppc->irq_clear, gpioname, 1);
    g_free(gpioname);
    gpioname = g_strdup_printf("%s_irq_status", name);
    qdev_init_gpio_in_named_with_opaque(dev, iotkit_secctl_ppc_irqstatus,
                                        ppc, gpioname, 1);
    g_free(gpioname);
}

static void iotkit_secctl_init(Object *obj)
{
    IoTKitSecCtl *s = IOTKIT_SECCTL(obj);
    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
    DeviceState *dev = DEVICE(obj);
    int i;

    iotkit_secctl_init_ppc(s, &s->apb[0], "apb_ppc0",
                           IOTS_APB_PPC0_NUM_PORTS, 0);
    iotkit_secctl_init_ppc(s, &s->apb[1], "apb_ppc1",
                           IOTS_APB_PPC1_NUM_PORTS, 1);

    for (i = 0; i < IOTS_NUM_APB_EXP_PPC; i++) {
        IoTKitSecCtlPPC *ppc = &s->apbexp[i];
        char *ppcname = g_strdup_printf("apb_ppcexp%d", i);
        iotkit_secctl_init_ppc(s, ppc, ppcname, IOTS_PPC_NUM_PORTS, 4 + i);
        g_free(ppcname);
    }
    for (i = 0; i < IOTS_NUM_AHB_EXP_PPC; i++) {
        IoTKitSecCtlPPC *ppc = &s->ahbexp[i];
        char *ppcname = g_strdup_printf("ahb_ppcexp%d", i);
        iotkit_secctl_init_ppc(s, ppc, ppcname, IOTS_PPC_NUM_PORTS, 20 + i);
        g_free(ppcname);
    }

    qdev_init_gpio_out_named(dev, &s->sec_resp_cfg, "sec_resp_cfg", 1);
    qdev_init_gpio_out_named(dev, &s->nsc_cfg_irq, "nsc_cfg", 1);

    qdev_init_gpio_in_named(dev, iotkit_secctl_mpc_status, "mpc_status",
                            IOTS_NUM_MPC);
    qdev_init_gpio_in_named(dev, iotkit_secctl_mpcexp_status,
                            "mpcexp_status", IOTS_NUM_EXP_MPC);

    qdev_init_gpio_in_named(dev, iotkit_secctl_mscexp_status,
                            "mscexp_status", IOTS_NUM_EXP_MSC);
    qdev_init_gpio_out_named(dev, s->mscexp_clear, "mscexp_clear",
                             IOTS_NUM_EXP_MSC);
    qdev_init_gpio_out_named(dev, s->mscexp_ns, "mscexp_ns",
                             IOTS_NUM_EXP_MSC);
    qdev_init_gpio_out_named(dev, &s->msc_irq, "msc_irq", 1);

    memory_region_init_io(&s->s_regs, obj, &iotkit_secctl_s_ops,
                          s, "iotkit-secctl-s-regs", 0x1000);
    memory_region_init_io(&s->ns_regs, obj, &iotkit_secctl_ns_ops,
                          s, "iotkit-secctl-ns-regs", 0x1000);
    sysbus_init_mmio(sbd, &s->s_regs);
    sysbus_init_mmio(sbd, &s->ns_regs);
}

static const VMStateDescription iotkit_secctl_ppc_vmstate = {
    .name = "iotkit-secctl-ppc",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_UINT32(ns, IoTKitSecCtlPPC),
        VMSTATE_UINT32(sp, IoTKitSecCtlPPC),
        VMSTATE_UINT32(nsp, IoTKitSecCtlPPC),
        VMSTATE_END_OF_LIST()
    }
};

static const VMStateDescription iotkit_secctl_mpcintstatus_vmstate = {
    .name = "iotkit-secctl-mpcintstatus",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_UINT32(mpcintstatus, IoTKitSecCtl),
        VMSTATE_END_OF_LIST()
    }
};

static bool needed_always(void *opaque)
{
    return true;
}

static const VMStateDescription iotkit_secctl_msc_vmstate = {
    .name = "iotkit-secctl/msc",
    .version_id = 1,
    .minimum_version_id = 1,
    .needed = needed_always,
    .fields = (VMStateField[]) {
        VMSTATE_UINT32(secmscintstat, IoTKitSecCtl),
        VMSTATE_UINT32(secmscinten, IoTKitSecCtl),
        VMSTATE_UINT32(nsmscexp, IoTKitSecCtl),
        VMSTATE_END_OF_LIST()
    }
};

static const VMStateDescription iotkit_secctl_vmstate = {
    .name = "iotkit-secctl",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_UINT32(secppcintstat, IoTKitSecCtl),
        VMSTATE_UINT32(secppcinten, IoTKitSecCtl),
        VMSTATE_UINT32(secrespcfg, IoTKitSecCtl),
        VMSTATE_UINT32(nsccfg, IoTKitSecCtl),
        VMSTATE_UINT32(brginten, IoTKitSecCtl),
        VMSTATE_STRUCT_ARRAY(apb, IoTKitSecCtl, IOTS_NUM_APB_PPC, 1,
                             iotkit_secctl_ppc_vmstate, IoTKitSecCtlPPC),
        VMSTATE_STRUCT_ARRAY(apbexp, IoTKitSecCtl, IOTS_NUM_APB_EXP_PPC, 1,
                             iotkit_secctl_ppc_vmstate, IoTKitSecCtlPPC),
        VMSTATE_STRUCT_ARRAY(ahbexp, IoTKitSecCtl, IOTS_NUM_AHB_EXP_PPC, 1,
                             iotkit_secctl_ppc_vmstate, IoTKitSecCtlPPC),
        VMSTATE_END_OF_LIST()
    },
    .subsections = (const VMStateDescription*[]) {
        &iotkit_secctl_mpcintstatus_vmstate,
        &iotkit_secctl_msc_vmstate,
        NULL
    },
};

static void iotkit_secctl_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);

    dc->vmsd = &iotkit_secctl_vmstate;
    dc->reset = iotkit_secctl_reset;
}

static const TypeInfo iotkit_secctl_info = {
    .name = TYPE_IOTKIT_SECCTL,
    .parent = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(IoTKitSecCtl),
    .instance_init = iotkit_secctl_init,
    .class_init = iotkit_secctl_class_init,
};

static void iotkit_secctl_register_types(void)
{
    type_register_static(&iotkit_secctl_info);
}

type_init(iotkit_secctl_register_types);
