/*
 * 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:
        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);
