/*
 * Arm SSE (Subsystems for Embedded): IoTKit
 *
 * 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 "qemu/bitops.h"
#include "qapi/error.h"
#include "trace.h"
#include "hw/sysbus.h"
#include "migration/vmstate.h"
#include "hw/registerfields.h"
#include "hw/arm/armsse.h"
#include "hw/arm/boot.h"
#include "hw/irq.h"

/* Format of the System Information block SYS_CONFIG register */
typedef enum SysConfigFormat {
    IoTKitFormat,
    SSE200Format,
} SysConfigFormat;

struct ARMSSEInfo {
    const char *name;
    int sram_banks;
    int num_cpus;
    uint32_t sys_version;
    uint32_t cpuwait_rst;
    SysConfigFormat sys_config_format;
    bool has_mhus;
    bool has_ppus;
    bool has_cachectrl;
    bool has_cpusecctrl;
    bool has_cpuid;
    Property *props;
};

static Property iotkit_properties[] = {
    DEFINE_PROP_LINK("memory", ARMSSE, board_memory, TYPE_MEMORY_REGION,
                     MemoryRegion *),
    DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
    DEFINE_PROP_UINT32("MAINCLK", ARMSSE, mainclk_frq, 0),
    DEFINE_PROP_UINT32("SRAM_ADDR_WIDTH", ARMSSE, sram_addr_width, 15),
    DEFINE_PROP_UINT32("init-svtor", ARMSSE, init_svtor, 0x10000000),
    DEFINE_PROP_BOOL("CPU0_FPU", ARMSSE, cpu_fpu[0], true),
    DEFINE_PROP_BOOL("CPU0_DSP", ARMSSE, cpu_dsp[0], true),
    DEFINE_PROP_END_OF_LIST()
};

static Property armsse_properties[] = {
    DEFINE_PROP_LINK("memory", ARMSSE, board_memory, TYPE_MEMORY_REGION,
                     MemoryRegion *),
    DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
    DEFINE_PROP_UINT32("MAINCLK", ARMSSE, mainclk_frq, 0),
    DEFINE_PROP_UINT32("SRAM_ADDR_WIDTH", ARMSSE, sram_addr_width, 15),
    DEFINE_PROP_UINT32("init-svtor", ARMSSE, init_svtor, 0x10000000),
    DEFINE_PROP_BOOL("CPU0_FPU", ARMSSE, cpu_fpu[0], false),
    DEFINE_PROP_BOOL("CPU0_DSP", ARMSSE, cpu_dsp[0], false),
    DEFINE_PROP_BOOL("CPU1_FPU", ARMSSE, cpu_fpu[1], true),
    DEFINE_PROP_BOOL("CPU1_DSP", ARMSSE, cpu_dsp[1], true),
    DEFINE_PROP_END_OF_LIST()
};

static const ARMSSEInfo armsse_variants[] = {
    {
        .name = TYPE_IOTKIT,
        .sram_banks = 1,
        .num_cpus = 1,
        .sys_version = 0x41743,
        .cpuwait_rst = 0,
        .sys_config_format = IoTKitFormat,
        .has_mhus = false,
        .has_ppus = false,
        .has_cachectrl = false,
        .has_cpusecctrl = false,
        .has_cpuid = false,
        .props = iotkit_properties,
    },
    {
        .name = TYPE_SSE200,
        .sram_banks = 4,
        .num_cpus = 2,
        .sys_version = 0x22041743,
        .cpuwait_rst = 2,
        .sys_config_format = SSE200Format,
        .has_mhus = true,
        .has_ppus = true,
        .has_cachectrl = true,
        .has_cpusecctrl = true,
        .has_cpuid = true,
        .props = armsse_properties,
    },
};

static uint32_t armsse_sys_config_value(ARMSSE *s, const ARMSSEInfo *info)
{
    /* Return the SYS_CONFIG value for this SSE */
    uint32_t sys_config;

    switch (info->sys_config_format) {
    case IoTKitFormat:
        sys_config = 0;
        sys_config = deposit32(sys_config, 0, 4, info->sram_banks);
        sys_config = deposit32(sys_config, 4, 4, s->sram_addr_width - 12);
        break;
    case SSE200Format:
        sys_config = 0;
        sys_config = deposit32(sys_config, 0, 4, info->sram_banks);
        sys_config = deposit32(sys_config, 4, 5, s->sram_addr_width);
        sys_config = deposit32(sys_config, 24, 4, 2);
        if (info->num_cpus > 1) {
            sys_config = deposit32(sys_config, 10, 1, 1);
            sys_config = deposit32(sys_config, 20, 4, info->sram_banks - 1);
            sys_config = deposit32(sys_config, 28, 4, 2);
        }
        break;
    default:
        g_assert_not_reached();
    }
    return sys_config;
}

/* Clock frequency in HZ of the 32KHz "slow clock" */
#define S32KCLK (32 * 1000)

/* Is internal IRQ n shared between CPUs in a multi-core SSE ? */
static bool irq_is_common[32] = {
    [0 ... 5] = true,
    /* 6, 7: per-CPU MHU interrupts */
    [8 ... 12] = true,
    /* 13: per-CPU icache interrupt */
    /* 14: reserved */
    [15 ... 20] = true,
    /* 21: reserved */
    [22 ... 26] = true,
    /* 27: reserved */
    /* 28, 29: per-CPU CTI interrupts */
    /* 30, 31: reserved */
};

/*
 * Create an alias region in @container of @size bytes starting at @base
 * which mirrors the memory starting at @orig.
 */
static void make_alias(ARMSSE *s, MemoryRegion *mr, MemoryRegion *container,
                       const char *name, hwaddr base, hwaddr size, hwaddr orig)
{
    memory_region_init_alias(mr, NULL, name, container, orig, size);
    /* The alias is even lower priority than unimplemented_device regions */
    memory_region_add_subregion_overlap(container, base, mr, -1500);
}

static void irq_status_forwarder(void *opaque, int n, int level)
{
    qemu_irq destirq = opaque;

    qemu_set_irq(destirq, level);
}

static void nsccfg_handler(void *opaque, int n, int level)
{
    ARMSSE *s = ARMSSE(opaque);

    s->nsccfg = level;
}

static void armsse_forward_ppc(ARMSSE *s, const char *ppcname, int ppcnum)
{
    /* Each of the 4 AHB and 4 APB PPCs that might be present in a
     * system using the ARMSSE has a collection of control lines which
     * are provided by the security controller and which we want to
     * expose as control lines on the ARMSSE device itself, so the
     * code using the ARMSSE can wire them up to the PPCs.
     */
    SplitIRQ *splitter = &s->ppc_irq_splitter[ppcnum];
    DeviceState *armssedev = DEVICE(s);
    DeviceState *dev_secctl = DEVICE(&s->secctl);
    DeviceState *dev_splitter = DEVICE(splitter);
    char *name;

    name = g_strdup_printf("%s_nonsec", ppcname);
    qdev_pass_gpios(dev_secctl, armssedev, name);
    g_free(name);
    name = g_strdup_printf("%s_ap", ppcname);
    qdev_pass_gpios(dev_secctl, armssedev, name);
    g_free(name);
    name = g_strdup_printf("%s_irq_enable", ppcname);
    qdev_pass_gpios(dev_secctl, armssedev, name);
    g_free(name);
    name = g_strdup_printf("%s_irq_clear", ppcname);
    qdev_pass_gpios(dev_secctl, armssedev, name);
    g_free(name);

    /* irq_status is a little more tricky, because we need to
     * split it so we can send it both to the security controller
     * and to our OR gate for the NVIC interrupt line.
     * Connect up the splitter's outputs, and create a GPIO input
     * which will pass the line state to the input splitter.
     */
    name = g_strdup_printf("%s_irq_status", ppcname);
    qdev_connect_gpio_out(dev_splitter, 0,
                          qdev_get_gpio_in_named(dev_secctl,
                                                 name, 0));
    qdev_connect_gpio_out(dev_splitter, 1,
                          qdev_get_gpio_in(DEVICE(&s->ppc_irq_orgate), ppcnum));
    s->irq_status_in[ppcnum] = qdev_get_gpio_in(dev_splitter, 0);
    qdev_init_gpio_in_named_with_opaque(armssedev, irq_status_forwarder,
                                        s->irq_status_in[ppcnum], name, 1);
    g_free(name);
}

static void armsse_forward_sec_resp_cfg(ARMSSE *s)
{
    /* Forward the 3rd output from the splitter device as a
     * named GPIO output of the armsse object.
     */
    DeviceState *dev = DEVICE(s);
    DeviceState *dev_splitter = DEVICE(&s->sec_resp_splitter);

    qdev_init_gpio_out_named(dev, &s->sec_resp_cfg, "sec_resp_cfg", 1);
    s->sec_resp_cfg_in = qemu_allocate_irq(irq_status_forwarder,
                                           s->sec_resp_cfg, 1);
    qdev_connect_gpio_out(dev_splitter, 2, s->sec_resp_cfg_in);
}

static void armsse_init(Object *obj)
{
    ARMSSE *s = ARMSSE(obj);
    ARMSSEClass *asc = ARMSSE_GET_CLASS(obj);
    const ARMSSEInfo *info = asc->info;
    int i;

    assert(info->sram_banks <= MAX_SRAM_BANKS);
    assert(info->num_cpus <= SSE_MAX_CPUS);

    memory_region_init(&s->container, obj, "armsse-container", UINT64_MAX);

    for (i = 0; i < info->num_cpus; i++) {
        /*
         * We put each CPU in its own cluster as they are logically
         * distinct and may be configured differently.
         */
        char *name;

        name = g_strdup_printf("cluster%d", i);
        object_initialize_child(obj, name, &s->cluster[i], TYPE_CPU_CLUSTER);
        qdev_prop_set_uint32(DEVICE(&s->cluster[i]), "cluster-id", i);
        g_free(name);

        name = g_strdup_printf("armv7m%d", i);
        object_initialize_child(OBJECT(&s->cluster[i]), name, &s->armv7m[i],
                                TYPE_ARMV7M);
        qdev_prop_set_string(DEVICE(&s->armv7m[i]), "cpu-type",
                             ARM_CPU_TYPE_NAME("cortex-m33"));
        g_free(name);
        name = g_strdup_printf("arm-sse-cpu-container%d", i);
        memory_region_init(&s->cpu_container[i], obj, name, UINT64_MAX);
        g_free(name);
        if (i > 0) {
            name = g_strdup_printf("arm-sse-container-alias%d", i);
            memory_region_init_alias(&s->container_alias[i - 1], obj,
                                     name, &s->container, 0, UINT64_MAX);
            g_free(name);
        }
    }

    object_initialize_child(obj, "secctl", &s->secctl, TYPE_IOTKIT_SECCTL);
    object_initialize_child(obj, "apb-ppc0", &s->apb_ppc0, TYPE_TZ_PPC);
    object_initialize_child(obj, "apb-ppc1", &s->apb_ppc1, TYPE_TZ_PPC);
    for (i = 0; i < info->sram_banks; i++) {
        char *name = g_strdup_printf("mpc%d", i);
        object_initialize_child(obj, name, &s->mpc[i], TYPE_TZ_MPC);
        g_free(name);
    }
    object_initialize_child(obj, "mpc-irq-orgate", &s->mpc_irq_orgate,
                            TYPE_OR_IRQ);

    for (i = 0; i < IOTS_NUM_EXP_MPC + info->sram_banks; i++) {
        char *name = g_strdup_printf("mpc-irq-splitter-%d", i);
        SplitIRQ *splitter = &s->mpc_irq_splitter[i];

        object_initialize_child(obj, name, splitter, TYPE_SPLIT_IRQ);
        g_free(name);
    }
    object_initialize_child(obj, "timer0", &s->timer0, TYPE_CMSDK_APB_TIMER);
    object_initialize_child(obj, "timer1", &s->timer1, TYPE_CMSDK_APB_TIMER);
    object_initialize_child(obj, "s32ktimer", &s->s32ktimer,
                            TYPE_CMSDK_APB_TIMER);
    object_initialize_child(obj, "dualtimer", &s->dualtimer,
                            TYPE_CMSDK_APB_DUALTIMER);
    object_initialize_child(obj, "s32kwatchdog", &s->s32kwatchdog,
                            TYPE_CMSDK_APB_WATCHDOG);
    object_initialize_child(obj, "nswatchdog", &s->nswatchdog,
                            TYPE_CMSDK_APB_WATCHDOG);
    object_initialize_child(obj, "swatchdog", &s->swatchdog,
                            TYPE_CMSDK_APB_WATCHDOG);
    object_initialize_child(obj, "armsse-sysctl", &s->sysctl,
                            TYPE_IOTKIT_SYSCTL);
    object_initialize_child(obj, "armsse-sysinfo", &s->sysinfo,
                            TYPE_IOTKIT_SYSINFO);
    if (info->has_mhus) {
        object_initialize_child(obj, "mhu0", &s->mhu[0], TYPE_ARMSSE_MHU);
        object_initialize_child(obj, "mhu1", &s->mhu[1], TYPE_ARMSSE_MHU);
    }
    if (info->has_ppus) {
        for (i = 0; i < info->num_cpus; i++) {
            char *name = g_strdup_printf("CPU%dCORE_PPU", i);
            int ppuidx = CPU0CORE_PPU + i;

            object_initialize_child(obj, name, &s->ppu[ppuidx],
                                    TYPE_UNIMPLEMENTED_DEVICE);
            g_free(name);
        }
        object_initialize_child(obj, "DBG_PPU", &s->ppu[DBG_PPU],
                                TYPE_UNIMPLEMENTED_DEVICE);
        for (i = 0; i < info->sram_banks; i++) {
            char *name = g_strdup_printf("RAM%d_PPU", i);
            int ppuidx = RAM0_PPU + i;

            object_initialize_child(obj, name, &s->ppu[ppuidx],
                                    TYPE_UNIMPLEMENTED_DEVICE);
            g_free(name);
        }
    }
    if (info->has_cachectrl) {
        for (i = 0; i < info->num_cpus; i++) {
            char *name = g_strdup_printf("cachectrl%d", i);

            object_initialize_child(obj, name, &s->cachectrl[i],
                                    TYPE_UNIMPLEMENTED_DEVICE);
            g_free(name);
        }
    }
    if (info->has_cpusecctrl) {
        for (i = 0; i < info->num_cpus; i++) {
            char *name = g_strdup_printf("cpusecctrl%d", i);

            object_initialize_child(obj, name, &s->cpusecctrl[i],
                                    TYPE_UNIMPLEMENTED_DEVICE);
            g_free(name);
        }
    }
    if (info->has_cpuid) {
        for (i = 0; i < info->num_cpus; i++) {
            char *name = g_strdup_printf("cpuid%d", i);

            object_initialize_child(obj, name, &s->cpuid[i],
                                    TYPE_ARMSSE_CPUID);
            g_free(name);
        }
    }
    object_initialize_child(obj, "nmi-orgate", &s->nmi_orgate, TYPE_OR_IRQ);
    object_initialize_child(obj, "ppc-irq-orgate", &s->ppc_irq_orgate,
                            TYPE_OR_IRQ);
    object_initialize_child(obj, "sec-resp-splitter", &s->sec_resp_splitter,
                            TYPE_SPLIT_IRQ);
    for (i = 0; i < ARRAY_SIZE(s->ppc_irq_splitter); i++) {
        char *name = g_strdup_printf("ppc-irq-splitter-%d", i);
        SplitIRQ *splitter = &s->ppc_irq_splitter[i];

        object_initialize_child(obj, name, splitter, TYPE_SPLIT_IRQ);
        g_free(name);
    }
    if (info->num_cpus > 1) {
        for (i = 0; i < ARRAY_SIZE(s->cpu_irq_splitter); i++) {
            if (irq_is_common[i]) {
                char *name = g_strdup_printf("cpu-irq-splitter%d", i);
                SplitIRQ *splitter = &s->cpu_irq_splitter[i];

                object_initialize_child(obj, name, splitter, TYPE_SPLIT_IRQ);
                g_free(name);
            }
        }
    }
}

static void armsse_exp_irq(void *opaque, int n, int level)
{
    qemu_irq *irqarray = opaque;

    qemu_set_irq(irqarray[n], level);
}

static void armsse_mpcexp_status(void *opaque, int n, int level)
{
    ARMSSE *s = ARMSSE(opaque);
    qemu_set_irq(s->mpcexp_status_in[n], level);
}

static qemu_irq armsse_get_common_irq_in(ARMSSE *s, int irqno)
{
    /*
     * Return a qemu_irq which can be used to signal IRQ n to
     * all CPUs in the SSE.
     */
    ARMSSEClass *asc = ARMSSE_GET_CLASS(s);
    const ARMSSEInfo *info = asc->info;

    assert(irq_is_common[irqno]);

    if (info->num_cpus == 1) {
        /* Only one CPU -- just connect directly to it */
        return qdev_get_gpio_in(DEVICE(&s->armv7m[0]), irqno);
    } else {
        /* Connect to the splitter which feeds all CPUs */
        return qdev_get_gpio_in(DEVICE(&s->cpu_irq_splitter[irqno]), 0);
    }
}

static void map_ppu(ARMSSE *s, int ppuidx, const char *name, hwaddr addr)
{
    /* Map a PPU unimplemented device stub */
    DeviceState *dev = DEVICE(&s->ppu[ppuidx]);

    qdev_prop_set_string(dev, "name", name);
    qdev_prop_set_uint64(dev, "size", 0x1000);
    sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal);
    sysbus_mmio_map(SYS_BUS_DEVICE(&s->ppu[ppuidx]), 0, addr);
}

static void armsse_realize(DeviceState *dev, Error **errp)
{
    ARMSSE *s = ARMSSE(dev);
    ARMSSEClass *asc = ARMSSE_GET_CLASS(dev);
    const ARMSSEInfo *info = asc->info;
    int i;
    MemoryRegion *mr;
    Error *err = NULL;
    SysBusDevice *sbd_apb_ppc0;
    SysBusDevice *sbd_secctl;
    DeviceState *dev_apb_ppc0;
    DeviceState *dev_apb_ppc1;
    DeviceState *dev_secctl;
    DeviceState *dev_splitter;
    uint32_t addr_width_max;

    if (!s->board_memory) {
        error_setg(errp, "memory property was not set");
        return;
    }

    if (!s->mainclk_frq) {
        error_setg(errp, "MAINCLK property was not set");
        return;
    }

    /* max SRAM_ADDR_WIDTH: 24 - log2(SRAM_NUM_BANK) */
    assert(is_power_of_2(info->sram_banks));
    addr_width_max = 24 - ctz32(info->sram_banks);
    if (s->sram_addr_width < 1 || s->sram_addr_width > addr_width_max) {
        error_setg(errp, "SRAM_ADDR_WIDTH must be between 1 and %d",
                   addr_width_max);
        return;
    }

    /* Handling of which devices should be available only to secure
     * code is usually done differently for M profile than for A profile.
     * Instead of putting some devices only into the secure address space,
     * devices exist in both address spaces but with hard-wired security
     * permissions that will cause the CPU to fault for non-secure accesses.
     *
     * The ARMSSE has an IDAU (Implementation Defined Access Unit),
     * which specifies hard-wired security permissions for different
     * areas of the physical address space. For the ARMSSE IDAU, the
     * top 4 bits of the physical address are the IDAU region ID, and
     * if bit 28 (ie the lowest bit of the ID) is 0 then this is an NS
     * region, otherwise it is an S region.
     *
     * The various devices and RAMs are generally all mapped twice,
     * once into a region that the IDAU defines as secure and once
     * into a non-secure region. They sit behind either a Memory
     * Protection Controller (for RAM) or a Peripheral Protection
     * Controller (for devices), which allow a more fine grained
     * configuration of whether non-secure accesses are permitted.
     *
     * (The other place that guest software can configure security
     * permissions is in the architected SAU (Security Attribution
     * Unit), which is entirely inside the CPU. The IDAU can upgrade
     * the security attributes for a region to more restrictive than
     * the SAU specifies, but cannot downgrade them.)
     *
     * 0x10000000..0x1fffffff  alias of 0x00000000..0x0fffffff
     * 0x20000000..0x2007ffff  32KB FPGA block RAM
     * 0x30000000..0x3fffffff  alias of 0x20000000..0x2fffffff
     * 0x40000000..0x4000ffff  base peripheral region 1
     * 0x40010000..0x4001ffff  CPU peripherals (none for ARMSSE)
     * 0x40020000..0x4002ffff  system control element peripherals
     * 0x40080000..0x400fffff  base peripheral region 2
     * 0x50000000..0x5fffffff  alias of 0x40000000..0x4fffffff
     */

    memory_region_add_subregion_overlap(&s->container, 0, s->board_memory, -2);

    for (i = 0; i < info->num_cpus; i++) {
        DeviceState *cpudev = DEVICE(&s->armv7m[i]);
        Object *cpuobj = OBJECT(&s->armv7m[i]);
        int j;
        char *gpioname;

        qdev_prop_set_uint32(cpudev, "num-irq", s->exp_numirq + 32);
        /*
         * In real hardware the initial Secure VTOR is set from the INITSVTOR*
         * registers in the IoT Kit System Control Register block. In QEMU
         * we set the initial value here, and also the reset value of the
         * sysctl register, from this object's QOM init-svtor property.
         * If the guest changes the INITSVTOR* registers at runtime then the
         * code in iotkit-sysctl.c will update the CPU init-svtor property
         * (which will then take effect on the next CPU warm-reset).
         *
         * Note that typically a board using the SSE-200 will have a system
         * control processor whose boot firmware initializes the INITSVTOR*
         * registers before powering up the CPUs. QEMU doesn't emulate
         * the control processor, so instead we behave in the way that the
         * firmware does: the initial value should be set by the board code
         * (using the init-svtor property on the ARMSSE object) to match
         * whatever its firmware does.
         */
        qdev_prop_set_uint32(cpudev, "init-svtor", s->init_svtor);
        /*
         * CPUs start powered down if the corresponding bit in the CPUWAIT
         * register is 1. In real hardware the CPUWAIT register reset value is
         * a configurable property of the SSE-200 (via the CPUWAIT0_RST and
         * CPUWAIT1_RST parameters), but since all the boards we care about
         * start CPU0 and leave CPU1 powered off, we hard-code that in
         * info->cpuwait_rst for now. We can add QOM properties for this
         * later if necessary.
         */
        if (extract32(info->cpuwait_rst, i, 1)) {
            if (!object_property_set_bool(cpuobj, "start-powered-off", true,
                                          &err)) {
                error_propagate(errp, err);
                return;
            }
        }
        if (!s->cpu_fpu[i]) {
            if (!object_property_set_bool(cpuobj, "vfp", false, &err)) {
                error_propagate(errp, err);
                return;
            }
        }
        if (!s->cpu_dsp[i]) {
            if (!object_property_set_bool(cpuobj, "dsp", false, &err)) {
                error_propagate(errp, err);
                return;
            }
        }

        if (i > 0) {
            memory_region_add_subregion_overlap(&s->cpu_container[i], 0,
                                                &s->container_alias[i - 1], -1);
        } else {
            memory_region_add_subregion_overlap(&s->cpu_container[i], 0,
                                                &s->container, -1);
        }
        object_property_set_link(cpuobj, "memory",
                                 OBJECT(&s->cpu_container[i]), &error_abort);
        object_property_set_link(cpuobj, "idau", OBJECT(s), &error_abort);
        if (!sysbus_realize(SYS_BUS_DEVICE(cpuobj), &err)) {
            error_propagate(errp, err);
            return;
        }
        /*
         * The cluster must be realized after the armv7m container, as
         * the container's CPU object is only created on realize, and the
         * CPU must exist and have been parented into the cluster before
         * the cluster is realized.
         */
        if (!qdev_realize(DEVICE(&s->cluster[i]), NULL, &err)) {
            error_propagate(errp, err);
            return;
        }

        /* Connect EXP_IRQ/EXP_CPUn_IRQ GPIOs to the NVIC's lines 32 and up */
        s->exp_irqs[i] = g_new(qemu_irq, s->exp_numirq);
        for (j = 0; j < s->exp_numirq; j++) {
            s->exp_irqs[i][j] = qdev_get_gpio_in(cpudev, j + 32);
        }
        if (i == 0) {
            gpioname = g_strdup("EXP_IRQ");
        } else {
            gpioname = g_strdup_printf("EXP_CPU%d_IRQ", i);
        }
        qdev_init_gpio_in_named_with_opaque(dev, armsse_exp_irq,
                                            s->exp_irqs[i],
                                            gpioname, s->exp_numirq);
        g_free(gpioname);
    }

    /* Wire up the splitters that connect common IRQs to all CPUs */
    if (info->num_cpus > 1) {
        for (i = 0; i < ARRAY_SIZE(s->cpu_irq_splitter); i++) {
            if (irq_is_common[i]) {
                Object *splitter = OBJECT(&s->cpu_irq_splitter[i]);
                DeviceState *devs = DEVICE(splitter);
                int cpunum;

                if (!object_property_set_int(splitter, "num-lines",
                                             info->num_cpus, &err)) {
                    error_propagate(errp, err);
                    return;
                }
                if (!qdev_realize(DEVICE(splitter), NULL, &err)) {
                    error_propagate(errp, err);
                    return;
                }
                for (cpunum = 0; cpunum < info->num_cpus; cpunum++) {
                    DeviceState *cpudev = DEVICE(&s->armv7m[cpunum]);

                    qdev_connect_gpio_out(devs, cpunum,
                                          qdev_get_gpio_in(cpudev, i));
                }
            }
        }
    }

    /* Set up the big aliases first */
    make_alias(s, &s->alias1, &s->container, "alias 1",
               0x10000000, 0x10000000, 0x00000000);
    make_alias(s, &s->alias2, &s->container,
               "alias 2", 0x30000000, 0x10000000, 0x20000000);
    /* The 0x50000000..0x5fffffff region is not a pure alias: it has
     * a few extra devices that only appear there (generally the
     * control interfaces for the protection controllers).
     * We implement this by mapping those devices over the top of this
     * alias MR at a higher priority. Some of the devices in this range
     * are per-CPU, so we must put this alias in the per-cpu containers.
     */
    for (i = 0; i < info->num_cpus; i++) {
        make_alias(s, &s->alias3[i], &s->cpu_container[i],
                   "alias 3", 0x50000000, 0x10000000, 0x40000000);
    }

    /* Security controller */
    if (!sysbus_realize(SYS_BUS_DEVICE(&s->secctl), &err)) {
        error_propagate(errp, err);
        return;
    }
    sbd_secctl = SYS_BUS_DEVICE(&s->secctl);
    dev_secctl = DEVICE(&s->secctl);
    sysbus_mmio_map(sbd_secctl, 0, 0x50080000);
    sysbus_mmio_map(sbd_secctl, 1, 0x40080000);

    s->nsc_cfg_in = qemu_allocate_irq(nsccfg_handler, s, 1);
    qdev_connect_gpio_out_named(dev_secctl, "nsc_cfg", 0, s->nsc_cfg_in);

    /* The sec_resp_cfg output from the security controller must be split into
     * multiple lines, one for each of the PPCs within the ARMSSE and one
     * that will be an output from the ARMSSE to the system.
     */
    if (!object_property_set_int(OBJECT(&s->sec_resp_splitter),
                                 "num-lines", 3, &err)) {
        error_propagate(errp, err);
        return;
    }
    if (!qdev_realize(DEVICE(&s->sec_resp_splitter), NULL, &err)) {
        error_propagate(errp, err);
        return;
    }
    dev_splitter = DEVICE(&s->sec_resp_splitter);
    qdev_connect_gpio_out_named(dev_secctl, "sec_resp_cfg", 0,
                                qdev_get_gpio_in(dev_splitter, 0));

    /* Each SRAM bank lives behind its own Memory Protection Controller */
    for (i = 0; i < info->sram_banks; i++) {
        char *ramname = g_strdup_printf("armsse.sram%d", i);
        SysBusDevice *sbd_mpc;
        uint32_t sram_bank_size = 1 << s->sram_addr_width;

        memory_region_init_ram(&s->sram[i], NULL, ramname,
                               sram_bank_size, &err);
        g_free(ramname);
        if (err) {
            error_propagate(errp, err);
            return;
        }
        object_property_set_link(OBJECT(&s->mpc[i]), "downstream",
                                 OBJECT(&s->sram[i]), &error_abort);
        if (!sysbus_realize(SYS_BUS_DEVICE(&s->mpc[i]), &err)) {
            error_propagate(errp, err);
            return;
        }
        /* Map the upstream end of the MPC into the right place... */
        sbd_mpc = SYS_BUS_DEVICE(&s->mpc[i]);
        memory_region_add_subregion(&s->container,
                                    0x20000000 + i * sram_bank_size,
                                    sysbus_mmio_get_region(sbd_mpc, 1));
        /* ...and its register interface */
        memory_region_add_subregion(&s->container, 0x50083000 + i * 0x1000,
                                    sysbus_mmio_get_region(sbd_mpc, 0));
    }

    /* We must OR together lines from the MPC splitters to go to the NVIC */
    if (!object_property_set_int(OBJECT(&s->mpc_irq_orgate), "num-lines",
                                 IOTS_NUM_EXP_MPC + info->sram_banks,
                                 &err)) {
        error_propagate(errp, err);
        return;
    }
    if (!qdev_realize(DEVICE(&s->mpc_irq_orgate), NULL, &err)) {
        error_propagate(errp, err);
        return;
    }
    qdev_connect_gpio_out(DEVICE(&s->mpc_irq_orgate), 0,
                          armsse_get_common_irq_in(s, 9));

    /* Devices behind APB PPC0:
     *   0x40000000: timer0
     *   0x40001000: timer1
     *   0x40002000: dual timer
     *   0x40003000: MHU0 (SSE-200 only)
     *   0x40004000: MHU1 (SSE-200 only)
     * We must configure and realize each downstream device and connect
     * it to the appropriate PPC port; then we can realize the PPC and
     * map its upstream ends to the right place in the container.
     */
    qdev_prop_set_uint32(DEVICE(&s->timer0), "pclk-frq", s->mainclk_frq);
    if (!sysbus_realize(SYS_BUS_DEVICE(&s->timer0), &err)) {
        error_propagate(errp, err);
        return;
    }
    sysbus_connect_irq(SYS_BUS_DEVICE(&s->timer0), 0,
                       armsse_get_common_irq_in(s, 3));
    mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->timer0), 0);
    object_property_set_link(OBJECT(&s->apb_ppc0), "port[0]", OBJECT(mr),
                             &error_abort);

    qdev_prop_set_uint32(DEVICE(&s->timer1), "pclk-frq", s->mainclk_frq);
    if (!sysbus_realize(SYS_BUS_DEVICE(&s->timer1), &err)) {
        error_propagate(errp, err);
        return;
    }
    sysbus_connect_irq(SYS_BUS_DEVICE(&s->timer1), 0,
                       armsse_get_common_irq_in(s, 4));
    mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->timer1), 0);
    object_property_set_link(OBJECT(&s->apb_ppc0), "port[1]", OBJECT(mr),
                             &error_abort);

    qdev_prop_set_uint32(DEVICE(&s->dualtimer), "pclk-frq", s->mainclk_frq);
    if (!sysbus_realize(SYS_BUS_DEVICE(&s->dualtimer), &err)) {
        error_propagate(errp, err);
        return;
    }
    sysbus_connect_irq(SYS_BUS_DEVICE(&s->dualtimer), 0,
                       armsse_get_common_irq_in(s, 5));
    mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->dualtimer), 0);
    object_property_set_link(OBJECT(&s->apb_ppc0), "port[2]", OBJECT(mr),
                             &error_abort);

    if (info->has_mhus) {
        /*
         * An SSE-200 with only one CPU should have only one MHU created,
         * with the region where the second MHU usually is being RAZ/WI.
         * We don't implement that SSE-200 config; if we want to support
         * it then this code needs to be enhanced to handle creating the
         * RAZ/WI region instead of the second MHU.
         */
        assert(info->num_cpus == ARRAY_SIZE(s->mhu));

        for (i = 0; i < ARRAY_SIZE(s->mhu); i++) {
            char *port;
            int cpunum;
            SysBusDevice *mhu_sbd = SYS_BUS_DEVICE(&s->mhu[i]);

            if (!sysbus_realize(SYS_BUS_DEVICE(&s->mhu[i]), &err)) {
                error_propagate(errp, err);
                return;
            }
            port = g_strdup_printf("port[%d]", i + 3);
            mr = sysbus_mmio_get_region(mhu_sbd, 0);
            object_property_set_link(OBJECT(&s->apb_ppc0), port, OBJECT(mr),
                                     &error_abort);
            g_free(port);

            /*
             * Each MHU has an irq line for each CPU:
             *  MHU 0 irq line 0 -> CPU 0 IRQ 6
             *  MHU 0 irq line 1 -> CPU 1 IRQ 6
             *  MHU 1 irq line 0 -> CPU 0 IRQ 7
             *  MHU 1 irq line 1 -> CPU 1 IRQ 7
             */
            for (cpunum = 0; cpunum < info->num_cpus; cpunum++) {
                DeviceState *cpudev = DEVICE(&s->armv7m[cpunum]);

                sysbus_connect_irq(mhu_sbd, cpunum,
                                   qdev_get_gpio_in(cpudev, 6 + i));
            }
        }
    }

    if (!sysbus_realize(SYS_BUS_DEVICE(&s->apb_ppc0), &err)) {
        error_propagate(errp, err);
        return;
    }

    sbd_apb_ppc0 = SYS_BUS_DEVICE(&s->apb_ppc0);
    dev_apb_ppc0 = DEVICE(&s->apb_ppc0);

    mr = sysbus_mmio_get_region(sbd_apb_ppc0, 0);
    memory_region_add_subregion(&s->container, 0x40000000, mr);
    mr = sysbus_mmio_get_region(sbd_apb_ppc0, 1);
    memory_region_add_subregion(&s->container, 0x40001000, mr);
    mr = sysbus_mmio_get_region(sbd_apb_ppc0, 2);
    memory_region_add_subregion(&s->container, 0x40002000, mr);
    if (info->has_mhus) {
        mr = sysbus_mmio_get_region(sbd_apb_ppc0, 3);
        memory_region_add_subregion(&s->container, 0x40003000, mr);
        mr = sysbus_mmio_get_region(sbd_apb_ppc0, 4);
        memory_region_add_subregion(&s->container, 0x40004000, mr);
    }
    for (i = 0; i < IOTS_APB_PPC0_NUM_PORTS; i++) {
        qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_nonsec", i,
                                    qdev_get_gpio_in_named(dev_apb_ppc0,
                                                           "cfg_nonsec", i));
        qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_ap", i,
                                    qdev_get_gpio_in_named(dev_apb_ppc0,
                                                           "cfg_ap", i));
    }
    qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_irq_enable", 0,
                                qdev_get_gpio_in_named(dev_apb_ppc0,
                                                       "irq_enable", 0));
    qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_irq_clear", 0,
                                qdev_get_gpio_in_named(dev_apb_ppc0,
                                                       "irq_clear", 0));
    qdev_connect_gpio_out(dev_splitter, 0,
                          qdev_get_gpio_in_named(dev_apb_ppc0,
                                                 "cfg_sec_resp", 0));

    /* All the PPC irq lines (from the 2 internal PPCs and the 8 external
     * ones) are sent individually to the security controller, and also
     * ORed together to give a single combined PPC interrupt to the NVIC.
     */
    if (!object_property_set_int(OBJECT(&s->ppc_irq_orgate),
                                 "num-lines", NUM_PPCS, &err)) {
        error_propagate(errp, err);
        return;
    }
    if (!qdev_realize(DEVICE(&s->ppc_irq_orgate), NULL, &err)) {
        error_propagate(errp, err);
        return;
    }
    qdev_connect_gpio_out(DEVICE(&s->ppc_irq_orgate), 0,
                          armsse_get_common_irq_in(s, 10));

    /*
     * 0x40010000 .. 0x4001ffff (and the 0x5001000... secure-only alias):
     * private per-CPU region (all these devices are SSE-200 only):
     *  0x50010000: L1 icache control registers
     *  0x50011000: CPUSECCTRL (CPU local security control registers)
     *  0x4001f000 and 0x5001f000: CPU_IDENTITY register block
     */
    if (info->has_cachectrl) {
        for (i = 0; i < info->num_cpus; i++) {
            char *name = g_strdup_printf("cachectrl%d", i);
            MemoryRegion *mr;

            qdev_prop_set_string(DEVICE(&s->cachectrl[i]), "name", name);
            g_free(name);
            qdev_prop_set_uint64(DEVICE(&s->cachectrl[i]), "size", 0x1000);
            if (!sysbus_realize(SYS_BUS_DEVICE(&s->cachectrl[i]), &err)) {
                error_propagate(errp, err);
                return;
            }

            mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->cachectrl[i]), 0);
            memory_region_add_subregion(&s->cpu_container[i], 0x50010000, mr);
        }
    }
    if (info->has_cpusecctrl) {
        for (i = 0; i < info->num_cpus; i++) {
            char *name = g_strdup_printf("CPUSECCTRL%d", i);
            MemoryRegion *mr;

            qdev_prop_set_string(DEVICE(&s->cpusecctrl[i]), "name", name);
            g_free(name);
            qdev_prop_set_uint64(DEVICE(&s->cpusecctrl[i]), "size", 0x1000);
            if (!sysbus_realize(SYS_BUS_DEVICE(&s->cpusecctrl[i]), &err)) {
                error_propagate(errp, err);
                return;
            }

            mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->cpusecctrl[i]), 0);
            memory_region_add_subregion(&s->cpu_container[i], 0x50011000, mr);
        }
    }
    if (info->has_cpuid) {
        for (i = 0; i < info->num_cpus; i++) {
            MemoryRegion *mr;

            qdev_prop_set_uint32(DEVICE(&s->cpuid[i]), "CPUID", i);
            if (!sysbus_realize(SYS_BUS_DEVICE(&s->cpuid[i]), &err)) {
                error_propagate(errp, err);
                return;
            }

            mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->cpuid[i]), 0);
            memory_region_add_subregion(&s->cpu_container[i], 0x4001F000, mr);
        }
    }

    /* 0x40020000 .. 0x4002ffff : ARMSSE system control peripheral region */
    /* Devices behind APB PPC1:
     *   0x4002f000: S32K timer
     */
    qdev_prop_set_uint32(DEVICE(&s->s32ktimer), "pclk-frq", S32KCLK);
    if (!sysbus_realize(SYS_BUS_DEVICE(&s->s32ktimer), &err)) {
        error_propagate(errp, err);
        return;
    }
    sysbus_connect_irq(SYS_BUS_DEVICE(&s->s32ktimer), 0,
                       armsse_get_common_irq_in(s, 2));
    mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->s32ktimer), 0);
    object_property_set_link(OBJECT(&s->apb_ppc1), "port[0]", OBJECT(mr),
                             &error_abort);

    if (!sysbus_realize(SYS_BUS_DEVICE(&s->apb_ppc1), &err)) {
        error_propagate(errp, err);
        return;
    }
    mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->apb_ppc1), 0);
    memory_region_add_subregion(&s->container, 0x4002f000, mr);

    dev_apb_ppc1 = DEVICE(&s->apb_ppc1);
    qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_nonsec", 0,
                                qdev_get_gpio_in_named(dev_apb_ppc1,
                                                       "cfg_nonsec", 0));
    qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_ap", 0,
                                qdev_get_gpio_in_named(dev_apb_ppc1,
                                                       "cfg_ap", 0));
    qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_irq_enable", 0,
                                qdev_get_gpio_in_named(dev_apb_ppc1,
                                                       "irq_enable", 0));
    qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_irq_clear", 0,
                                qdev_get_gpio_in_named(dev_apb_ppc1,
                                                       "irq_clear", 0));
    qdev_connect_gpio_out(dev_splitter, 1,
                          qdev_get_gpio_in_named(dev_apb_ppc1,
                                                 "cfg_sec_resp", 0));

    if (!object_property_set_int(OBJECT(&s->sysinfo), "SYS_VERSION",
                                 info->sys_version, &err)) {
        error_propagate(errp, err);
        return;
    }
    if (!object_property_set_int(OBJECT(&s->sysinfo), "SYS_CONFIG",
                                 armsse_sys_config_value(s, info), &err)) {
        error_propagate(errp, err);
        return;
    }
    if (!sysbus_realize(SYS_BUS_DEVICE(&s->sysinfo), &err)) {
        error_propagate(errp, err);
        return;
    }
    /* System information registers */
    sysbus_mmio_map(SYS_BUS_DEVICE(&s->sysinfo), 0, 0x40020000);
    /* System control registers */
    object_property_set_int(OBJECT(&s->sysctl), "SYS_VERSION",
                            info->sys_version, &error_abort);
    object_property_set_int(OBJECT(&s->sysctl), "CPUWAIT_RST",
                            info->cpuwait_rst, &error_abort);
    object_property_set_int(OBJECT(&s->sysctl), "INITSVTOR0_RST",
                            s->init_svtor, &error_abort);
    object_property_set_int(OBJECT(&s->sysctl), "INITSVTOR1_RST",
                            s->init_svtor, &error_abort);
    if (!sysbus_realize(SYS_BUS_DEVICE(&s->sysctl), &err)) {
        error_propagate(errp, err);
        return;
    }
    sysbus_mmio_map(SYS_BUS_DEVICE(&s->sysctl), 0, 0x50021000);

    if (info->has_ppus) {
        /* CPUnCORE_PPU for each CPU */
        for (i = 0; i < info->num_cpus; i++) {
            char *name = g_strdup_printf("CPU%dCORE_PPU", i);

            map_ppu(s, CPU0CORE_PPU + i, name, 0x50023000 + i * 0x2000);
            /*
             * We don't support CPU debug so don't create the
             * CPU0DEBUG_PPU at 0x50024000 and 0x50026000.
             */
            g_free(name);
        }
        map_ppu(s, DBG_PPU, "DBG_PPU", 0x50029000);

        for (i = 0; i < info->sram_banks; i++) {
            char *name = g_strdup_printf("RAM%d_PPU", i);

            map_ppu(s, RAM0_PPU + i, name, 0x5002a000 + i * 0x1000);
            g_free(name);
        }
    }

    /* This OR gate wires together outputs from the secure watchdogs to NMI */
    if (!object_property_set_int(OBJECT(&s->nmi_orgate), "num-lines", 2,
                                 &err)) {
        error_propagate(errp, err);
        return;
    }
    if (!qdev_realize(DEVICE(&s->nmi_orgate), NULL, &err)) {
        error_propagate(errp, err);
        return;
    }
    qdev_connect_gpio_out(DEVICE(&s->nmi_orgate), 0,
                          qdev_get_gpio_in_named(DEVICE(&s->armv7m), "NMI", 0));

    qdev_prop_set_uint32(DEVICE(&s->s32kwatchdog), "wdogclk-frq", S32KCLK);
    if (!sysbus_realize(SYS_BUS_DEVICE(&s->s32kwatchdog), &err)) {
        error_propagate(errp, err);
        return;
    }
    sysbus_connect_irq(SYS_BUS_DEVICE(&s->s32kwatchdog), 0,
                       qdev_get_gpio_in(DEVICE(&s->nmi_orgate), 0));
    sysbus_mmio_map(SYS_BUS_DEVICE(&s->s32kwatchdog), 0, 0x5002e000);

    /* 0x40080000 .. 0x4008ffff : ARMSSE second Base peripheral region */

    qdev_prop_set_uint32(DEVICE(&s->nswatchdog), "wdogclk-frq", s->mainclk_frq);
    if (!sysbus_realize(SYS_BUS_DEVICE(&s->nswatchdog), &err)) {
        error_propagate(errp, err);
        return;
    }
    sysbus_connect_irq(SYS_BUS_DEVICE(&s->nswatchdog), 0,
                       armsse_get_common_irq_in(s, 1));
    sysbus_mmio_map(SYS_BUS_DEVICE(&s->nswatchdog), 0, 0x40081000);

    qdev_prop_set_uint32(DEVICE(&s->swatchdog), "wdogclk-frq", s->mainclk_frq);
    if (!sysbus_realize(SYS_BUS_DEVICE(&s->swatchdog), &err)) {
        error_propagate(errp, err);
        return;
    }
    sysbus_connect_irq(SYS_BUS_DEVICE(&s->swatchdog), 0,
                       qdev_get_gpio_in(DEVICE(&s->nmi_orgate), 1));
    sysbus_mmio_map(SYS_BUS_DEVICE(&s->swatchdog), 0, 0x50081000);

    for (i = 0; i < ARRAY_SIZE(s->ppc_irq_splitter); i++) {
        Object *splitter = OBJECT(&s->ppc_irq_splitter[i]);

        if (!object_property_set_int(splitter, "num-lines", 2, &err)) {
            error_propagate(errp, err);
            return;
        }
        if (!qdev_realize(DEVICE(splitter), NULL, &err)) {
            error_propagate(errp, err);
            return;
        }
    }

    for (i = 0; i < IOTS_NUM_AHB_EXP_PPC; i++) {
        char *ppcname = g_strdup_printf("ahb_ppcexp%d", i);

        armsse_forward_ppc(s, ppcname, i);
        g_free(ppcname);
    }

    for (i = 0; i < IOTS_NUM_APB_EXP_PPC; i++) {
        char *ppcname = g_strdup_printf("apb_ppcexp%d", i);

        armsse_forward_ppc(s, ppcname, i + IOTS_NUM_AHB_EXP_PPC);
        g_free(ppcname);
    }

    for (i = NUM_EXTERNAL_PPCS; i < NUM_PPCS; i++) {
        /* Wire up IRQ splitter for internal PPCs */
        DeviceState *devs = DEVICE(&s->ppc_irq_splitter[i]);
        char *gpioname = g_strdup_printf("apb_ppc%d_irq_status",
                                         i - NUM_EXTERNAL_PPCS);
        TZPPC *ppc = (i == NUM_EXTERNAL_PPCS) ? &s->apb_ppc0 : &s->apb_ppc1;

        qdev_connect_gpio_out(devs, 0,
                              qdev_get_gpio_in_named(dev_secctl, gpioname, 0));
        qdev_connect_gpio_out(devs, 1,
                              qdev_get_gpio_in(DEVICE(&s->ppc_irq_orgate), i));
        qdev_connect_gpio_out_named(DEVICE(ppc), "irq", 0,
                                    qdev_get_gpio_in(devs, 0));
        g_free(gpioname);
    }

    /* Wire up the splitters for the MPC IRQs */
    for (i = 0; i < IOTS_NUM_EXP_MPC + info->sram_banks; i++) {
        SplitIRQ *splitter = &s->mpc_irq_splitter[i];
        DeviceState *dev_splitter = DEVICE(splitter);

        if (!object_property_set_int(OBJECT(splitter), "num-lines", 2,
                                     &err)) {
            error_propagate(errp, err);
            return;
        }
        if (!qdev_realize(DEVICE(splitter), NULL, &err)) {
            error_propagate(errp, err);
            return;
        }

        if (i < IOTS_NUM_EXP_MPC) {
            /* Splitter input is from GPIO input line */
            s->mpcexp_status_in[i] = qdev_get_gpio_in(dev_splitter, 0);
            qdev_connect_gpio_out(dev_splitter, 0,
                                  qdev_get_gpio_in_named(dev_secctl,
                                                         "mpcexp_status", i));
        } else {
            /* Splitter input is from our own MPC */
            qdev_connect_gpio_out_named(DEVICE(&s->mpc[i - IOTS_NUM_EXP_MPC]),
                                        "irq", 0,
                                        qdev_get_gpio_in(dev_splitter, 0));
            qdev_connect_gpio_out(dev_splitter, 0,
                                  qdev_get_gpio_in_named(dev_secctl,
                                                         "mpc_status", 0));
        }

        qdev_connect_gpio_out(dev_splitter, 1,
                              qdev_get_gpio_in(DEVICE(&s->mpc_irq_orgate), i));
    }
    /* Create GPIO inputs which will pass the line state for our
     * mpcexp_irq inputs to the correct splitter devices.
     */
    qdev_init_gpio_in_named(dev, armsse_mpcexp_status, "mpcexp_status",
                            IOTS_NUM_EXP_MPC);

    armsse_forward_sec_resp_cfg(s);

    /* Forward the MSC related signals */
    qdev_pass_gpios(dev_secctl, dev, "mscexp_status");
    qdev_pass_gpios(dev_secctl, dev, "mscexp_clear");
    qdev_pass_gpios(dev_secctl, dev, "mscexp_ns");
    qdev_connect_gpio_out_named(dev_secctl, "msc_irq", 0,
                                armsse_get_common_irq_in(s, 11));

    /*
     * Expose our container region to the board model; this corresponds
     * to the AHB Slave Expansion ports which allow bus master devices
     * (eg DMA controllers) in the board model to make transactions into
     * devices in the ARMSSE.
     */
    sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->container);

    system_clock_scale = NANOSECONDS_PER_SECOND / s->mainclk_frq;
}

static void armsse_idau_check(IDAUInterface *ii, uint32_t address,
                              int *iregion, bool *exempt, bool *ns, bool *nsc)
{
    /*
     * For ARMSSE systems the IDAU responses are simple logical functions
     * of the address bits. The NSC attribute is guest-adjustable via the
     * NSCCFG register in the security controller.
     */
    ARMSSE *s = ARMSSE(ii);
    int region = extract32(address, 28, 4);

    *ns = !(region & 1);
    *nsc = (region == 1 && (s->nsccfg & 1)) || (region == 3 && (s->nsccfg & 2));
    /* 0xe0000000..0xe00fffff and 0xf0000000..0xf00fffff are exempt */
    *exempt = (address & 0xeff00000) == 0xe0000000;
    *iregion = region;
}

static const VMStateDescription armsse_vmstate = {
    .name = "iotkit",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_UINT32(nsccfg, ARMSSE),
        VMSTATE_END_OF_LIST()
    }
};

static void armsse_reset(DeviceState *dev)
{
    ARMSSE *s = ARMSSE(dev);

    s->nsccfg = 0;
}

static void armsse_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    IDAUInterfaceClass *iic = IDAU_INTERFACE_CLASS(klass);
    ARMSSEClass *asc = ARMSSE_CLASS(klass);
    const ARMSSEInfo *info = data;

    dc->realize = armsse_realize;
    dc->vmsd = &armsse_vmstate;
    device_class_set_props(dc, info->props);
    dc->reset = armsse_reset;
    iic->check = armsse_idau_check;
    asc->info = info;
}

static const TypeInfo armsse_info = {
    .name = TYPE_ARMSSE,
    .parent = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(ARMSSE),
    .instance_init = armsse_init,
    .abstract = true,
    .interfaces = (InterfaceInfo[]) {
        { TYPE_IDAU_INTERFACE },
        { }
    }
};

static void armsse_register_types(void)
{
    int i;

    type_register_static(&armsse_info);

    for (i = 0; i < ARRAY_SIZE(armsse_variants); i++) {
        TypeInfo ti = {
            .name = armsse_variants[i].name,
            .parent = TYPE_ARMSSE,
            .class_init = armsse_class_init,
            .class_data = (void *)&armsse_variants[i],
        };
        type_register(&ti);
    }
}

type_init(armsse_register_types);
