/*
 * 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 "qapi/error.h"
#include "trace.h"
#include "hw/sysbus.h"
#include "hw/registerfields.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_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_SECMPCINTSTATUS:
    case A_SECMSCINTSTAT:
    case A_SECMSCINTEN:
    case A_NSMSCEXP:
        qemu_log_mask(LOG_UNIMP,
                      "IoTKit SecCtl S block read: "
                      "unimplemented offset 0x%x\n", offset);
        r = 0;
        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 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:
    case A_SECMSCINTEN:
        qemu_log_mask(LOG_UNIMP,
                      "IoTKit SecCtl S block write: "
                      "unimplemented offset 0x%x\n", offset);
        break;
    case A_SECMPCINTSTATUS:
    case A_SECPPCINTSTAT:
    case A_SECMSCINTSTAT:
    case A_BRGINTSTAT:
    case A_AHBNSPPC0:
    case A_AHBSPPPC0:
    case A_NSMSCEXP:
    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_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);

    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_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()
    }
};

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);
