cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

armsse.c (60814B)


      1/*
      2 * Arm SSE (Subsystems for Embedded): IoTKit
      3 *
      4 * Copyright (c) 2018 Linaro Limited
      5 * Written by Peter Maydell
      6 *
      7 * This program is free software; you can redistribute it and/or modify
      8 * it under the terms of the GNU General Public License version 2 or
      9 * (at your option) any later version.
     10 */
     11
     12#include "qemu/osdep.h"
     13#include "qemu/log.h"
     14#include "qemu/module.h"
     15#include "qemu/bitops.h"
     16#include "qemu/units.h"
     17#include "qapi/error.h"
     18#include "trace.h"
     19#include "hw/sysbus.h"
     20#include "migration/vmstate.h"
     21#include "hw/registerfields.h"
     22#include "hw/arm/armsse.h"
     23#include "hw/arm/armsse-version.h"
     24#include "hw/arm/boot.h"
     25#include "hw/irq.h"
     26#include "hw/qdev-clock.h"
     27
     28/*
     29 * The SSE-300 puts some devices in different places to the
     30 * SSE-200 (and original IoTKit). We use an array of these structs
     31 * to define how each variant lays out these devices. (Parts of the
     32 * SoC that are the same for all variants aren't handled via these
     33 * data structures.)
     34 */
     35
     36#define NO_IRQ -1
     37#define NO_PPC -1
     38/*
     39 * Special values for ARMSSEDeviceInfo::irq to indicate that this
     40 * device uses one of the inputs to the OR gate that feeds into the
     41 * CPU NMI input.
     42 */
     43#define NMI_0 10000
     44#define NMI_1 10001
     45
     46typedef struct ARMSSEDeviceInfo {
     47    const char *name; /* name to use for the QOM object; NULL terminates list */
     48    const char *type; /* QOM type name */
     49    unsigned int index; /* Which of the N devices of this type is this ? */
     50    hwaddr addr;
     51    hwaddr size; /* only needed for TYPE_UNIMPLEMENTED_DEVICE */
     52    int ppc; /* Index of APB PPC this device is wired up to, or NO_PPC */
     53    int ppc_port; /* Port number of this device on the PPC */
     54    int irq; /* NO_IRQ, or 0..NUM_SSE_IRQS-1, or NMI_0 or NMI_1 */
     55    bool slowclk; /* true if device uses the slow 32KHz clock */
     56} ARMSSEDeviceInfo;
     57
     58struct ARMSSEInfo {
     59    const char *name;
     60    const char *cpu_type;
     61    uint32_t sse_version;
     62    int sram_banks;
     63    uint32_t sram_bank_base;
     64    int num_cpus;
     65    uint32_t sys_version;
     66    uint32_t iidr;
     67    uint32_t cpuwait_rst;
     68    bool has_mhus;
     69    bool has_cachectrl;
     70    bool has_cpusecctrl;
     71    bool has_cpuid;
     72    bool has_cpu_pwrctrl;
     73    bool has_sse_counter;
     74    bool has_tcms;
     75    Property *props;
     76    const ARMSSEDeviceInfo *devinfo;
     77    const bool *irq_is_common;
     78};
     79
     80static Property iotkit_properties[] = {
     81    DEFINE_PROP_LINK("memory", ARMSSE, board_memory, TYPE_MEMORY_REGION,
     82                     MemoryRegion *),
     83    DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
     84    DEFINE_PROP_UINT32("SRAM_ADDR_WIDTH", ARMSSE, sram_addr_width, 15),
     85    DEFINE_PROP_UINT32("init-svtor", ARMSSE, init_svtor, 0x10000000),
     86    DEFINE_PROP_BOOL("CPU0_FPU", ARMSSE, cpu_fpu[0], true),
     87    DEFINE_PROP_BOOL("CPU0_DSP", ARMSSE, cpu_dsp[0], true),
     88    DEFINE_PROP_END_OF_LIST()
     89};
     90
     91static Property sse200_properties[] = {
     92    DEFINE_PROP_LINK("memory", ARMSSE, board_memory, TYPE_MEMORY_REGION,
     93                     MemoryRegion *),
     94    DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
     95    DEFINE_PROP_UINT32("SRAM_ADDR_WIDTH", ARMSSE, sram_addr_width, 15),
     96    DEFINE_PROP_UINT32("init-svtor", ARMSSE, init_svtor, 0x10000000),
     97    DEFINE_PROP_BOOL("CPU0_FPU", ARMSSE, cpu_fpu[0], false),
     98    DEFINE_PROP_BOOL("CPU0_DSP", ARMSSE, cpu_dsp[0], false),
     99    DEFINE_PROP_BOOL("CPU1_FPU", ARMSSE, cpu_fpu[1], true),
    100    DEFINE_PROP_BOOL("CPU1_DSP", ARMSSE, cpu_dsp[1], true),
    101    DEFINE_PROP_END_OF_LIST()
    102};
    103
    104static Property sse300_properties[] = {
    105    DEFINE_PROP_LINK("memory", ARMSSE, board_memory, TYPE_MEMORY_REGION,
    106                     MemoryRegion *),
    107    DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
    108    DEFINE_PROP_UINT32("SRAM_ADDR_WIDTH", ARMSSE, sram_addr_width, 18),
    109    DEFINE_PROP_UINT32("init-svtor", ARMSSE, init_svtor, 0x10000000),
    110    DEFINE_PROP_BOOL("CPU0_FPU", ARMSSE, cpu_fpu[0], true),
    111    DEFINE_PROP_BOOL("CPU0_DSP", ARMSSE, cpu_dsp[0], true),
    112    DEFINE_PROP_END_OF_LIST()
    113};
    114
    115static const ARMSSEDeviceInfo iotkit_devices[] = {
    116    {
    117        .name = "timer0",
    118        .type = TYPE_CMSDK_APB_TIMER,
    119        .index = 0,
    120        .addr = 0x40000000,
    121        .ppc = 0,
    122        .ppc_port = 0,
    123        .irq = 3,
    124    },
    125    {
    126        .name = "timer1",
    127        .type = TYPE_CMSDK_APB_TIMER,
    128        .index = 1,
    129        .addr = 0x40001000,
    130        .ppc = 0,
    131        .ppc_port = 1,
    132        .irq = 4,
    133    },
    134    {
    135        .name = "s32ktimer",
    136        .type = TYPE_CMSDK_APB_TIMER,
    137        .index = 2,
    138        .addr = 0x4002f000,
    139        .ppc = 1,
    140        .ppc_port = 0,
    141        .irq = 2,
    142        .slowclk = true,
    143    },
    144    {
    145        .name = "dualtimer",
    146        .type = TYPE_CMSDK_APB_DUALTIMER,
    147        .index = 0,
    148        .addr = 0x40002000,
    149        .ppc = 0,
    150        .ppc_port = 2,
    151        .irq = 5,
    152    },
    153    {
    154        .name = "s32kwatchdog",
    155        .type = TYPE_CMSDK_APB_WATCHDOG,
    156        .index = 0,
    157        .addr = 0x5002e000,
    158        .ppc = NO_PPC,
    159        .irq = NMI_0,
    160        .slowclk = true,
    161    },
    162    {
    163        .name = "nswatchdog",
    164        .type = TYPE_CMSDK_APB_WATCHDOG,
    165        .index = 1,
    166        .addr = 0x40081000,
    167        .ppc = NO_PPC,
    168        .irq = 1,
    169    },
    170    {
    171        .name = "swatchdog",
    172        .type = TYPE_CMSDK_APB_WATCHDOG,
    173        .index = 2,
    174        .addr = 0x50081000,
    175        .ppc = NO_PPC,
    176        .irq = NMI_1,
    177    },
    178    {
    179        .name = "armsse-sysinfo",
    180        .type = TYPE_IOTKIT_SYSINFO,
    181        .index = 0,
    182        .addr = 0x40020000,
    183        .ppc = NO_PPC,
    184        .irq = NO_IRQ,
    185    },
    186    {
    187        .name = "armsse-sysctl",
    188        .type = TYPE_IOTKIT_SYSCTL,
    189        .index = 0,
    190        .addr = 0x50021000,
    191        .ppc = NO_PPC,
    192        .irq = NO_IRQ,
    193    },
    194    {
    195        .name = NULL,
    196    }
    197};
    198
    199static const ARMSSEDeviceInfo sse200_devices[] = {
    200    {
    201        .name = "timer0",
    202        .type = TYPE_CMSDK_APB_TIMER,
    203        .index = 0,
    204        .addr = 0x40000000,
    205        .ppc = 0,
    206        .ppc_port = 0,
    207        .irq = 3,
    208    },
    209    {
    210        .name = "timer1",
    211        .type = TYPE_CMSDK_APB_TIMER,
    212        .index = 1,
    213        .addr = 0x40001000,
    214        .ppc = 0,
    215        .ppc_port = 1,
    216        .irq = 4,
    217    },
    218    {
    219        .name = "s32ktimer",
    220        .type = TYPE_CMSDK_APB_TIMER,
    221        .index = 2,
    222        .addr = 0x4002f000,
    223        .ppc = 1,
    224        .ppc_port = 0,
    225        .irq = 2,
    226        .slowclk = true,
    227    },
    228    {
    229        .name = "dualtimer",
    230        .type = TYPE_CMSDK_APB_DUALTIMER,
    231        .index = 0,
    232        .addr = 0x40002000,
    233        .ppc = 0,
    234        .ppc_port = 2,
    235        .irq = 5,
    236    },
    237    {
    238        .name = "s32kwatchdog",
    239        .type = TYPE_CMSDK_APB_WATCHDOG,
    240        .index = 0,
    241        .addr = 0x5002e000,
    242        .ppc = NO_PPC,
    243        .irq = NMI_0,
    244        .slowclk = true,
    245    },
    246    {
    247        .name = "nswatchdog",
    248        .type = TYPE_CMSDK_APB_WATCHDOG,
    249        .index = 1,
    250        .addr = 0x40081000,
    251        .ppc = NO_PPC,
    252        .irq = 1,
    253    },
    254    {
    255        .name = "swatchdog",
    256        .type = TYPE_CMSDK_APB_WATCHDOG,
    257        .index = 2,
    258        .addr = 0x50081000,
    259        .ppc = NO_PPC,
    260        .irq = NMI_1,
    261    },
    262    {
    263        .name = "armsse-sysinfo",
    264        .type = TYPE_IOTKIT_SYSINFO,
    265        .index = 0,
    266        .addr = 0x40020000,
    267        .ppc = NO_PPC,
    268        .irq = NO_IRQ,
    269    },
    270    {
    271        .name = "armsse-sysctl",
    272        .type = TYPE_IOTKIT_SYSCTL,
    273        .index = 0,
    274        .addr = 0x50021000,
    275        .ppc = NO_PPC,
    276        .irq = NO_IRQ,
    277    },
    278    {
    279        .name = "CPU0CORE_PPU",
    280        .type = TYPE_UNIMPLEMENTED_DEVICE,
    281        .index = 0,
    282        .addr = 0x50023000,
    283        .size = 0x1000,
    284        .ppc = NO_PPC,
    285        .irq = NO_IRQ,
    286    },
    287    {
    288        .name = "CPU1CORE_PPU",
    289        .type = TYPE_UNIMPLEMENTED_DEVICE,
    290        .index = 1,
    291        .addr = 0x50025000,
    292        .size = 0x1000,
    293        .ppc = NO_PPC,
    294        .irq = NO_IRQ,
    295    },
    296    {
    297        .name = "DBG_PPU",
    298        .type = TYPE_UNIMPLEMENTED_DEVICE,
    299        .index = 2,
    300        .addr = 0x50029000,
    301        .size = 0x1000,
    302        .ppc = NO_PPC,
    303        .irq = NO_IRQ,
    304    },
    305    {
    306        .name = "RAM0_PPU",
    307        .type = TYPE_UNIMPLEMENTED_DEVICE,
    308        .index = 3,
    309        .addr = 0x5002a000,
    310        .size = 0x1000,
    311        .ppc = NO_PPC,
    312        .irq = NO_IRQ,
    313    },
    314    {
    315        .name = "RAM1_PPU",
    316        .type = TYPE_UNIMPLEMENTED_DEVICE,
    317        .index = 4,
    318        .addr = 0x5002b000,
    319        .size = 0x1000,
    320        .ppc = NO_PPC,
    321        .irq = NO_IRQ,
    322    },
    323    {
    324        .name = "RAM2_PPU",
    325        .type = TYPE_UNIMPLEMENTED_DEVICE,
    326        .index = 5,
    327        .addr = 0x5002c000,
    328        .size = 0x1000,
    329        .ppc = NO_PPC,
    330        .irq = NO_IRQ,
    331    },
    332    {
    333        .name = "RAM3_PPU",
    334        .type = TYPE_UNIMPLEMENTED_DEVICE,
    335        .index = 6,
    336        .addr = 0x5002d000,
    337        .size = 0x1000,
    338        .ppc = NO_PPC,
    339        .irq = NO_IRQ,
    340    },
    341    {
    342        .name = "SYS_PPU",
    343        .type = TYPE_UNIMPLEMENTED_DEVICE,
    344        .index = 7,
    345        .addr = 0x50022000,
    346        .size = 0x1000,
    347        .ppc = NO_PPC,
    348        .irq = NO_IRQ,
    349    },
    350    {
    351        .name = NULL,
    352    }
    353};
    354
    355static const ARMSSEDeviceInfo sse300_devices[] = {
    356    {
    357        .name = "timer0",
    358        .type = TYPE_SSE_TIMER,
    359        .index = 0,
    360        .addr = 0x48000000,
    361        .ppc = 0,
    362        .ppc_port = 0,
    363        .irq = 3,
    364    },
    365    {
    366        .name = "timer1",
    367        .type = TYPE_SSE_TIMER,
    368        .index = 1,
    369        .addr = 0x48001000,
    370        .ppc = 0,
    371        .ppc_port = 1,
    372        .irq = 4,
    373    },
    374    {
    375        .name = "timer2",
    376        .type = TYPE_SSE_TIMER,
    377        .index = 2,
    378        .addr = 0x48002000,
    379        .ppc = 0,
    380        .ppc_port = 2,
    381        .irq = 5,
    382    },
    383    {
    384        .name = "timer3",
    385        .type = TYPE_SSE_TIMER,
    386        .index = 3,
    387        .addr = 0x48003000,
    388        .ppc = 0,
    389        .ppc_port = 5,
    390        .irq = 27,
    391    },
    392    {
    393        .name = "s32ktimer",
    394        .type = TYPE_CMSDK_APB_TIMER,
    395        .index = 0,
    396        .addr = 0x4802f000,
    397        .ppc = 1,
    398        .ppc_port = 0,
    399        .irq = 2,
    400        .slowclk = true,
    401    },
    402    {
    403        .name = "s32kwatchdog",
    404        .type = TYPE_CMSDK_APB_WATCHDOG,
    405        .index = 0,
    406        .addr = 0x4802e000,
    407        .ppc = NO_PPC,
    408        .irq = NMI_0,
    409        .slowclk = true,
    410    },
    411    {
    412        .name = "watchdog",
    413        .type = TYPE_UNIMPLEMENTED_DEVICE,
    414        .index = 0,
    415        .addr = 0x48040000,
    416        .size = 0x2000,
    417        .ppc = NO_PPC,
    418        .irq = NO_IRQ,
    419    },
    420    {
    421        .name = "armsse-sysinfo",
    422        .type = TYPE_IOTKIT_SYSINFO,
    423        .index = 0,
    424        .addr = 0x48020000,
    425        .ppc = NO_PPC,
    426        .irq = NO_IRQ,
    427    },
    428    {
    429        .name = "armsse-sysctl",
    430        .type = TYPE_IOTKIT_SYSCTL,
    431        .index = 0,
    432        .addr = 0x58021000,
    433        .ppc = NO_PPC,
    434        .irq = NO_IRQ,
    435    },
    436    {
    437        .name = "SYS_PPU",
    438        .type = TYPE_UNIMPLEMENTED_DEVICE,
    439        .index = 1,
    440        .addr = 0x58022000,
    441        .size = 0x1000,
    442        .ppc = NO_PPC,
    443        .irq = NO_IRQ,
    444    },
    445    {
    446        .name = "CPU0CORE_PPU",
    447        .type = TYPE_UNIMPLEMENTED_DEVICE,
    448        .index = 2,
    449        .addr = 0x50023000,
    450        .size = 0x1000,
    451        .ppc = NO_PPC,
    452        .irq = NO_IRQ,
    453    },
    454    {
    455        .name = "MGMT_PPU",
    456        .type = TYPE_UNIMPLEMENTED_DEVICE,
    457        .index = 3,
    458        .addr = 0x50028000,
    459        .size = 0x1000,
    460        .ppc = NO_PPC,
    461        .irq = NO_IRQ,
    462    },
    463    {
    464        .name = "DEBUG_PPU",
    465        .type = TYPE_UNIMPLEMENTED_DEVICE,
    466        .index = 4,
    467        .addr = 0x50029000,
    468        .size = 0x1000,
    469        .ppc = NO_PPC,
    470        .irq = NO_IRQ,
    471    },
    472    {
    473        .name = NULL,
    474    }
    475};
    476
    477/* Is internal IRQ n shared between CPUs in a multi-core SSE ? */
    478static const bool sse200_irq_is_common[32] = {
    479    [0 ... 5] = true,
    480    /* 6, 7: per-CPU MHU interrupts */
    481    [8 ... 12] = true,
    482    /* 13: per-CPU icache interrupt */
    483    /* 14: reserved */
    484    [15 ... 20] = true,
    485    /* 21: reserved */
    486    [22 ... 26] = true,
    487    /* 27: reserved */
    488    /* 28, 29: per-CPU CTI interrupts */
    489    /* 30, 31: reserved */
    490};
    491
    492static const bool sse300_irq_is_common[32] = {
    493    [0 ... 5] = true,
    494    /* 6, 7: per-CPU MHU interrupts */
    495    [8 ... 12] = true,
    496    /* 13: reserved */
    497    [14 ... 16] = true,
    498    /* 17-25: reserved */
    499    [26 ... 27] = true,
    500    /* 28, 29: per-CPU CTI interrupts */
    501    /* 30, 31: reserved */
    502};
    503
    504static const ARMSSEInfo armsse_variants[] = {
    505    {
    506        .name = TYPE_IOTKIT,
    507        .sse_version = ARMSSE_IOTKIT,
    508        .cpu_type = ARM_CPU_TYPE_NAME("cortex-m33"),
    509        .sram_banks = 1,
    510        .sram_bank_base = 0x20000000,
    511        .num_cpus = 1,
    512        .sys_version = 0x41743,
    513        .iidr = 0,
    514        .cpuwait_rst = 0,
    515        .has_mhus = false,
    516        .has_cachectrl = false,
    517        .has_cpusecctrl = false,
    518        .has_cpuid = false,
    519        .has_cpu_pwrctrl = false,
    520        .has_sse_counter = false,
    521        .has_tcms = false,
    522        .props = iotkit_properties,
    523        .devinfo = iotkit_devices,
    524        .irq_is_common = sse200_irq_is_common,
    525    },
    526    {
    527        .name = TYPE_SSE200,
    528        .sse_version = ARMSSE_SSE200,
    529        .cpu_type = ARM_CPU_TYPE_NAME("cortex-m33"),
    530        .sram_banks = 4,
    531        .sram_bank_base = 0x20000000,
    532        .num_cpus = 2,
    533        .sys_version = 0x22041743,
    534        .iidr = 0,
    535        .cpuwait_rst = 2,
    536        .has_mhus = true,
    537        .has_cachectrl = true,
    538        .has_cpusecctrl = true,
    539        .has_cpuid = true,
    540        .has_cpu_pwrctrl = false,
    541        .has_sse_counter = false,
    542        .has_tcms = false,
    543        .props = sse200_properties,
    544        .devinfo = sse200_devices,
    545        .irq_is_common = sse200_irq_is_common,
    546    },
    547    {
    548        .name = TYPE_SSE300,
    549        .sse_version = ARMSSE_SSE300,
    550        .cpu_type = ARM_CPU_TYPE_NAME("cortex-m55"),
    551        .sram_banks = 2,
    552        .sram_bank_base = 0x21000000,
    553        .num_cpus = 1,
    554        .sys_version = 0x7e00043b,
    555        .iidr = 0x74a0043b,
    556        .cpuwait_rst = 0,
    557        .has_mhus = false,
    558        .has_cachectrl = false,
    559        .has_cpusecctrl = true,
    560        .has_cpuid = true,
    561        .has_cpu_pwrctrl = true,
    562        .has_sse_counter = true,
    563        .has_tcms = true,
    564        .props = sse300_properties,
    565        .devinfo = sse300_devices,
    566        .irq_is_common = sse300_irq_is_common,
    567    },
    568};
    569
    570static uint32_t armsse_sys_config_value(ARMSSE *s, const ARMSSEInfo *info)
    571{
    572    /* Return the SYS_CONFIG value for this SSE */
    573    uint32_t sys_config;
    574
    575    switch (info->sse_version) {
    576    case ARMSSE_IOTKIT:
    577        sys_config = 0;
    578        sys_config = deposit32(sys_config, 0, 4, info->sram_banks);
    579        sys_config = deposit32(sys_config, 4, 4, s->sram_addr_width - 12);
    580        break;
    581    case ARMSSE_SSE200:
    582        sys_config = 0;
    583        sys_config = deposit32(sys_config, 0, 4, info->sram_banks);
    584        sys_config = deposit32(sys_config, 4, 5, s->sram_addr_width);
    585        sys_config = deposit32(sys_config, 24, 4, 2);
    586        if (info->num_cpus > 1) {
    587            sys_config = deposit32(sys_config, 10, 1, 1);
    588            sys_config = deposit32(sys_config, 20, 4, info->sram_banks - 1);
    589            sys_config = deposit32(sys_config, 28, 4, 2);
    590        }
    591        break;
    592    case ARMSSE_SSE300:
    593        sys_config = 0;
    594        sys_config = deposit32(sys_config, 0, 4, info->sram_banks);
    595        sys_config = deposit32(sys_config, 4, 5, s->sram_addr_width);
    596        sys_config = deposit32(sys_config, 16, 3, 3); /* CPU0 = Cortex-M55 */
    597        break;
    598    default:
    599        g_assert_not_reached();
    600    }
    601    return sys_config;
    602}
    603
    604/* Clock frequency in HZ of the 32KHz "slow clock" */
    605#define S32KCLK (32 * 1000)
    606
    607/*
    608 * Create an alias region in @container of @size bytes starting at @base
    609 * which mirrors the memory starting at @orig.
    610 */
    611static void make_alias(ARMSSE *s, MemoryRegion *mr, MemoryRegion *container,
    612                       const char *name, hwaddr base, hwaddr size, hwaddr orig)
    613{
    614    memory_region_init_alias(mr, NULL, name, container, orig, size);
    615    /* The alias is even lower priority than unimplemented_device regions */
    616    memory_region_add_subregion_overlap(container, base, mr, -1500);
    617}
    618
    619static void irq_status_forwarder(void *opaque, int n, int level)
    620{
    621    qemu_irq destirq = opaque;
    622
    623    qemu_set_irq(destirq, level);
    624}
    625
    626static void nsccfg_handler(void *opaque, int n, int level)
    627{
    628    ARMSSE *s = ARM_SSE(opaque);
    629
    630    s->nsccfg = level;
    631}
    632
    633static void armsse_forward_ppc(ARMSSE *s, const char *ppcname, int ppcnum)
    634{
    635    /* Each of the 4 AHB and 4 APB PPCs that might be present in a
    636     * system using the ARMSSE has a collection of control lines which
    637     * are provided by the security controller and which we want to
    638     * expose as control lines on the ARMSSE device itself, so the
    639     * code using the ARMSSE can wire them up to the PPCs.
    640     */
    641    SplitIRQ *splitter = &s->ppc_irq_splitter[ppcnum];
    642    DeviceState *armssedev = DEVICE(s);
    643    DeviceState *dev_secctl = DEVICE(&s->secctl);
    644    DeviceState *dev_splitter = DEVICE(splitter);
    645    char *name;
    646
    647    name = g_strdup_printf("%s_nonsec", ppcname);
    648    qdev_pass_gpios(dev_secctl, armssedev, name);
    649    g_free(name);
    650    name = g_strdup_printf("%s_ap", ppcname);
    651    qdev_pass_gpios(dev_secctl, armssedev, name);
    652    g_free(name);
    653    name = g_strdup_printf("%s_irq_enable", ppcname);
    654    qdev_pass_gpios(dev_secctl, armssedev, name);
    655    g_free(name);
    656    name = g_strdup_printf("%s_irq_clear", ppcname);
    657    qdev_pass_gpios(dev_secctl, armssedev, name);
    658    g_free(name);
    659
    660    /* irq_status is a little more tricky, because we need to
    661     * split it so we can send it both to the security controller
    662     * and to our OR gate for the NVIC interrupt line.
    663     * Connect up the splitter's outputs, and create a GPIO input
    664     * which will pass the line state to the input splitter.
    665     */
    666    name = g_strdup_printf("%s_irq_status", ppcname);
    667    qdev_connect_gpio_out(dev_splitter, 0,
    668                          qdev_get_gpio_in_named(dev_secctl,
    669                                                 name, 0));
    670    qdev_connect_gpio_out(dev_splitter, 1,
    671                          qdev_get_gpio_in(DEVICE(&s->ppc_irq_orgate), ppcnum));
    672    s->irq_status_in[ppcnum] = qdev_get_gpio_in(dev_splitter, 0);
    673    qdev_init_gpio_in_named_with_opaque(armssedev, irq_status_forwarder,
    674                                        s->irq_status_in[ppcnum], name, 1);
    675    g_free(name);
    676}
    677
    678static void armsse_forward_sec_resp_cfg(ARMSSE *s)
    679{
    680    /* Forward the 3rd output from the splitter device as a
    681     * named GPIO output of the armsse object.
    682     */
    683    DeviceState *dev = DEVICE(s);
    684    DeviceState *dev_splitter = DEVICE(&s->sec_resp_splitter);
    685
    686    qdev_init_gpio_out_named(dev, &s->sec_resp_cfg, "sec_resp_cfg", 1);
    687    s->sec_resp_cfg_in = qemu_allocate_irq(irq_status_forwarder,
    688                                           s->sec_resp_cfg, 1);
    689    qdev_connect_gpio_out(dev_splitter, 2, s->sec_resp_cfg_in);
    690}
    691
    692static void armsse_init(Object *obj)
    693{
    694    ARMSSE *s = ARM_SSE(obj);
    695    ARMSSEClass *asc = ARM_SSE_GET_CLASS(obj);
    696    const ARMSSEInfo *info = asc->info;
    697    const ARMSSEDeviceInfo *devinfo;
    698    int i;
    699
    700    assert(info->sram_banks <= MAX_SRAM_BANKS);
    701    assert(info->num_cpus <= SSE_MAX_CPUS);
    702
    703    s->mainclk = qdev_init_clock_in(DEVICE(s), "MAINCLK", NULL, NULL, 0);
    704    s->s32kclk = qdev_init_clock_in(DEVICE(s), "S32KCLK", NULL, NULL, 0);
    705
    706    memory_region_init(&s->container, obj, "armsse-container", UINT64_MAX);
    707
    708    for (i = 0; i < info->num_cpus; i++) {
    709        /*
    710         * We put each CPU in its own cluster as they are logically
    711         * distinct and may be configured differently.
    712         */
    713        char *name;
    714
    715        name = g_strdup_printf("cluster%d", i);
    716        object_initialize_child(obj, name, &s->cluster[i], TYPE_CPU_CLUSTER);
    717        qdev_prop_set_uint32(DEVICE(&s->cluster[i]), "cluster-id", i);
    718        g_free(name);
    719
    720        name = g_strdup_printf("armv7m%d", i);
    721        object_initialize_child(OBJECT(&s->cluster[i]), name, &s->armv7m[i],
    722                                TYPE_ARMV7M);
    723        qdev_prop_set_string(DEVICE(&s->armv7m[i]), "cpu-type", info->cpu_type);
    724        g_free(name);
    725        name = g_strdup_printf("arm-sse-cpu-container%d", i);
    726        memory_region_init(&s->cpu_container[i], obj, name, UINT64_MAX);
    727        g_free(name);
    728        if (i > 0) {
    729            name = g_strdup_printf("arm-sse-container-alias%d", i);
    730            memory_region_init_alias(&s->container_alias[i - 1], obj,
    731                                     name, &s->container, 0, UINT64_MAX);
    732            g_free(name);
    733        }
    734    }
    735
    736    for (devinfo = info->devinfo; devinfo->name; devinfo++) {
    737        assert(devinfo->ppc == NO_PPC || devinfo->ppc < ARRAY_SIZE(s->apb_ppc));
    738        if (!strcmp(devinfo->type, TYPE_CMSDK_APB_TIMER)) {
    739            assert(devinfo->index < ARRAY_SIZE(s->timer));
    740            object_initialize_child(obj, devinfo->name,
    741                                    &s->timer[devinfo->index],
    742                                    TYPE_CMSDK_APB_TIMER);
    743        } else if (!strcmp(devinfo->type, TYPE_CMSDK_APB_DUALTIMER)) {
    744            assert(devinfo->index == 0);
    745            object_initialize_child(obj, devinfo->name, &s->dualtimer,
    746                                    TYPE_CMSDK_APB_DUALTIMER);
    747        } else if (!strcmp(devinfo->type, TYPE_SSE_TIMER)) {
    748            assert(devinfo->index < ARRAY_SIZE(s->sse_timer));
    749            object_initialize_child(obj, devinfo->name,
    750                                    &s->sse_timer[devinfo->index],
    751                                    TYPE_SSE_TIMER);
    752        } else if (!strcmp(devinfo->type, TYPE_CMSDK_APB_WATCHDOG)) {
    753            assert(devinfo->index < ARRAY_SIZE(s->cmsdk_watchdog));
    754            object_initialize_child(obj, devinfo->name,
    755                                    &s->cmsdk_watchdog[devinfo->index],
    756                                    TYPE_CMSDK_APB_WATCHDOG);
    757        } else if (!strcmp(devinfo->type, TYPE_IOTKIT_SYSINFO)) {
    758            assert(devinfo->index == 0);
    759            object_initialize_child(obj, devinfo->name, &s->sysinfo,
    760                                    TYPE_IOTKIT_SYSINFO);
    761        } else if (!strcmp(devinfo->type, TYPE_IOTKIT_SYSCTL)) {
    762            assert(devinfo->index == 0);
    763            object_initialize_child(obj, devinfo->name, &s->sysctl,
    764                                    TYPE_IOTKIT_SYSCTL);
    765        } else if (!strcmp(devinfo->type, TYPE_UNIMPLEMENTED_DEVICE)) {
    766            assert(devinfo->index < ARRAY_SIZE(s->unimp));
    767            object_initialize_child(obj, devinfo->name,
    768                                    &s->unimp[devinfo->index],
    769                                    TYPE_UNIMPLEMENTED_DEVICE);
    770        } else {
    771            g_assert_not_reached();
    772        }
    773    }
    774
    775    object_initialize_child(obj, "secctl", &s->secctl, TYPE_IOTKIT_SECCTL);
    776
    777    for (i = 0; i < ARRAY_SIZE(s->apb_ppc); i++) {
    778        g_autofree char *name = g_strdup_printf("apb-ppc%d", i);
    779        object_initialize_child(obj, name, &s->apb_ppc[i], TYPE_TZ_PPC);
    780    }
    781
    782    for (i = 0; i < info->sram_banks; i++) {
    783        char *name = g_strdup_printf("mpc%d", i);
    784        object_initialize_child(obj, name, &s->mpc[i], TYPE_TZ_MPC);
    785        g_free(name);
    786    }
    787    object_initialize_child(obj, "mpc-irq-orgate", &s->mpc_irq_orgate,
    788                            TYPE_OR_IRQ);
    789
    790    for (i = 0; i < IOTS_NUM_EXP_MPC + info->sram_banks; i++) {
    791        char *name = g_strdup_printf("mpc-irq-splitter-%d", i);
    792        SplitIRQ *splitter = &s->mpc_irq_splitter[i];
    793
    794        object_initialize_child(obj, name, splitter, TYPE_SPLIT_IRQ);
    795        g_free(name);
    796    }
    797
    798    if (info->has_mhus) {
    799        object_initialize_child(obj, "mhu0", &s->mhu[0], TYPE_ARMSSE_MHU);
    800        object_initialize_child(obj, "mhu1", &s->mhu[1], TYPE_ARMSSE_MHU);
    801    }
    802    if (info->has_cachectrl) {
    803        for (i = 0; i < info->num_cpus; i++) {
    804            char *name = g_strdup_printf("cachectrl%d", i);
    805
    806            object_initialize_child(obj, name, &s->cachectrl[i],
    807                                    TYPE_UNIMPLEMENTED_DEVICE);
    808            g_free(name);
    809        }
    810    }
    811    if (info->has_cpusecctrl) {
    812        for (i = 0; i < info->num_cpus; i++) {
    813            char *name = g_strdup_printf("cpusecctrl%d", i);
    814
    815            object_initialize_child(obj, name, &s->cpusecctrl[i],
    816                                    TYPE_UNIMPLEMENTED_DEVICE);
    817            g_free(name);
    818        }
    819    }
    820    if (info->has_cpuid) {
    821        for (i = 0; i < info->num_cpus; i++) {
    822            char *name = g_strdup_printf("cpuid%d", i);
    823
    824            object_initialize_child(obj, name, &s->cpuid[i],
    825                                    TYPE_ARMSSE_CPUID);
    826            g_free(name);
    827        }
    828    }
    829    if (info->has_cpu_pwrctrl) {
    830        for (i = 0; i < info->num_cpus; i++) {
    831            char *name = g_strdup_printf("cpu_pwrctrl%d", i);
    832
    833            object_initialize_child(obj, name, &s->cpu_pwrctrl[i],
    834                                    TYPE_ARMSSE_CPU_PWRCTRL);
    835            g_free(name);
    836        }
    837    }
    838    if (info->has_sse_counter) {
    839        object_initialize_child(obj, "sse-counter", &s->sse_counter,
    840                                TYPE_SSE_COUNTER);
    841    }
    842
    843    object_initialize_child(obj, "nmi-orgate", &s->nmi_orgate, TYPE_OR_IRQ);
    844    object_initialize_child(obj, "ppc-irq-orgate", &s->ppc_irq_orgate,
    845                            TYPE_OR_IRQ);
    846    object_initialize_child(obj, "sec-resp-splitter", &s->sec_resp_splitter,
    847                            TYPE_SPLIT_IRQ);
    848    for (i = 0; i < ARRAY_SIZE(s->ppc_irq_splitter); i++) {
    849        char *name = g_strdup_printf("ppc-irq-splitter-%d", i);
    850        SplitIRQ *splitter = &s->ppc_irq_splitter[i];
    851
    852        object_initialize_child(obj, name, splitter, TYPE_SPLIT_IRQ);
    853        g_free(name);
    854    }
    855    if (info->num_cpus > 1) {
    856        for (i = 0; i < ARRAY_SIZE(s->cpu_irq_splitter); i++) {
    857            if (info->irq_is_common[i]) {
    858                char *name = g_strdup_printf("cpu-irq-splitter%d", i);
    859                SplitIRQ *splitter = &s->cpu_irq_splitter[i];
    860
    861                object_initialize_child(obj, name, splitter, TYPE_SPLIT_IRQ);
    862                g_free(name);
    863            }
    864        }
    865    }
    866}
    867
    868static void armsse_exp_irq(void *opaque, int n, int level)
    869{
    870    qemu_irq *irqarray = opaque;
    871
    872    qemu_set_irq(irqarray[n], level);
    873}
    874
    875static void armsse_mpcexp_status(void *opaque, int n, int level)
    876{
    877    ARMSSE *s = ARM_SSE(opaque);
    878    qemu_set_irq(s->mpcexp_status_in[n], level);
    879}
    880
    881static qemu_irq armsse_get_common_irq_in(ARMSSE *s, int irqno)
    882{
    883    /*
    884     * Return a qemu_irq which can be used to signal IRQ n to
    885     * all CPUs in the SSE.
    886     */
    887    ARMSSEClass *asc = ARM_SSE_GET_CLASS(s);
    888    const ARMSSEInfo *info = asc->info;
    889
    890    assert(info->irq_is_common[irqno]);
    891
    892    if (info->num_cpus == 1) {
    893        /* Only one CPU -- just connect directly to it */
    894        return qdev_get_gpio_in(DEVICE(&s->armv7m[0]), irqno);
    895    } else {
    896        /* Connect to the splitter which feeds all CPUs */
    897        return qdev_get_gpio_in(DEVICE(&s->cpu_irq_splitter[irqno]), 0);
    898    }
    899}
    900
    901static void armsse_realize(DeviceState *dev, Error **errp)
    902{
    903    ARMSSE *s = ARM_SSE(dev);
    904    ARMSSEClass *asc = ARM_SSE_GET_CLASS(dev);
    905    const ARMSSEInfo *info = asc->info;
    906    const ARMSSEDeviceInfo *devinfo;
    907    int i;
    908    MemoryRegion *mr;
    909    SysBusDevice *sbd_apb_ppc0;
    910    SysBusDevice *sbd_secctl;
    911    DeviceState *dev_apb_ppc0;
    912    DeviceState *dev_apb_ppc1;
    913    DeviceState *dev_secctl;
    914    DeviceState *dev_splitter;
    915    uint32_t addr_width_max;
    916
    917    ERRP_GUARD();
    918
    919    if (!s->board_memory) {
    920        error_setg(errp, "memory property was not set");
    921        return;
    922    }
    923
    924    if (!clock_has_source(s->mainclk)) {
    925        error_setg(errp, "MAINCLK clock was not connected");
    926    }
    927    if (!clock_has_source(s->s32kclk)) {
    928        error_setg(errp, "S32KCLK clock was not connected");
    929    }
    930
    931    assert(info->num_cpus <= SSE_MAX_CPUS);
    932
    933    /* max SRAM_ADDR_WIDTH: 24 - log2(SRAM_NUM_BANK) */
    934    assert(is_power_of_2(info->sram_banks));
    935    addr_width_max = 24 - ctz32(info->sram_banks);
    936    if (s->sram_addr_width < 1 || s->sram_addr_width > addr_width_max) {
    937        error_setg(errp, "SRAM_ADDR_WIDTH must be between 1 and %d",
    938                   addr_width_max);
    939        return;
    940    }
    941
    942    /* Handling of which devices should be available only to secure
    943     * code is usually done differently for M profile than for A profile.
    944     * Instead of putting some devices only into the secure address space,
    945     * devices exist in both address spaces but with hard-wired security
    946     * permissions that will cause the CPU to fault for non-secure accesses.
    947     *
    948     * The ARMSSE has an IDAU (Implementation Defined Access Unit),
    949     * which specifies hard-wired security permissions for different
    950     * areas of the physical address space. For the ARMSSE IDAU, the
    951     * top 4 bits of the physical address are the IDAU region ID, and
    952     * if bit 28 (ie the lowest bit of the ID) is 0 then this is an NS
    953     * region, otherwise it is an S region.
    954     *
    955     * The various devices and RAMs are generally all mapped twice,
    956     * once into a region that the IDAU defines as secure and once
    957     * into a non-secure region. They sit behind either a Memory
    958     * Protection Controller (for RAM) or a Peripheral Protection
    959     * Controller (for devices), which allow a more fine grained
    960     * configuration of whether non-secure accesses are permitted.
    961     *
    962     * (The other place that guest software can configure security
    963     * permissions is in the architected SAU (Security Attribution
    964     * Unit), which is entirely inside the CPU. The IDAU can upgrade
    965     * the security attributes for a region to more restrictive than
    966     * the SAU specifies, but cannot downgrade them.)
    967     *
    968     * 0x10000000..0x1fffffff  alias of 0x00000000..0x0fffffff
    969     * 0x20000000..0x2007ffff  32KB FPGA block RAM
    970     * 0x30000000..0x3fffffff  alias of 0x20000000..0x2fffffff
    971     * 0x40000000..0x4000ffff  base peripheral region 1
    972     * 0x40010000..0x4001ffff  CPU peripherals (none for ARMSSE)
    973     * 0x40020000..0x4002ffff  system control element peripherals
    974     * 0x40080000..0x400fffff  base peripheral region 2
    975     * 0x50000000..0x5fffffff  alias of 0x40000000..0x4fffffff
    976     */
    977
    978    memory_region_add_subregion_overlap(&s->container, 0, s->board_memory, -2);
    979
    980    for (i = 0; i < info->num_cpus; i++) {
    981        DeviceState *cpudev = DEVICE(&s->armv7m[i]);
    982        Object *cpuobj = OBJECT(&s->armv7m[i]);
    983        int j;
    984        char *gpioname;
    985
    986        qdev_connect_clock_in(cpudev, "cpuclk", s->mainclk);
    987        /* The SSE subsystems do not wire up a systick refclk */
    988
    989        qdev_prop_set_uint32(cpudev, "num-irq", s->exp_numirq + NUM_SSE_IRQS);
    990        /*
    991         * In real hardware the initial Secure VTOR is set from the INITSVTOR*
    992         * registers in the IoT Kit System Control Register block. In QEMU
    993         * we set the initial value here, and also the reset value of the
    994         * sysctl register, from this object's QOM init-svtor property.
    995         * If the guest changes the INITSVTOR* registers at runtime then the
    996         * code in iotkit-sysctl.c will update the CPU init-svtor property
    997         * (which will then take effect on the next CPU warm-reset).
    998         *
    999         * Note that typically a board using the SSE-200 will have a system
   1000         * control processor whose boot firmware initializes the INITSVTOR*
   1001         * registers before powering up the CPUs. QEMU doesn't emulate
   1002         * the control processor, so instead we behave in the way that the
   1003         * firmware does: the initial value should be set by the board code
   1004         * (using the init-svtor property on the ARMSSE object) to match
   1005         * whatever its firmware does.
   1006         */
   1007        qdev_prop_set_uint32(cpudev, "init-svtor", s->init_svtor);
   1008        /*
   1009         * CPUs start powered down if the corresponding bit in the CPUWAIT
   1010         * register is 1. In real hardware the CPUWAIT register reset value is
   1011         * a configurable property of the SSE-200 (via the CPUWAIT0_RST and
   1012         * CPUWAIT1_RST parameters), but since all the boards we care about
   1013         * start CPU0 and leave CPU1 powered off, we hard-code that in
   1014         * info->cpuwait_rst for now. We can add QOM properties for this
   1015         * later if necessary.
   1016         */
   1017        if (extract32(info->cpuwait_rst, i, 1)) {
   1018            if (!object_property_set_bool(cpuobj, "start-powered-off", true,
   1019                                          errp)) {
   1020                return;
   1021            }
   1022        }
   1023        if (!s->cpu_fpu[i]) {
   1024            if (!object_property_set_bool(cpuobj, "vfp", false, errp)) {
   1025                return;
   1026            }
   1027        }
   1028        if (!s->cpu_dsp[i]) {
   1029            if (!object_property_set_bool(cpuobj, "dsp", false, errp)) {
   1030                return;
   1031            }
   1032        }
   1033
   1034        if (i > 0) {
   1035            memory_region_add_subregion_overlap(&s->cpu_container[i], 0,
   1036                                                &s->container_alias[i - 1], -1);
   1037        } else {
   1038            memory_region_add_subregion_overlap(&s->cpu_container[i], 0,
   1039                                                &s->container, -1);
   1040        }
   1041        object_property_set_link(cpuobj, "memory",
   1042                                 OBJECT(&s->cpu_container[i]), &error_abort);
   1043        object_property_set_link(cpuobj, "idau", OBJECT(s), &error_abort);
   1044        if (!sysbus_realize(SYS_BUS_DEVICE(cpuobj), errp)) {
   1045            return;
   1046        }
   1047        /*
   1048         * The cluster must be realized after the armv7m container, as
   1049         * the container's CPU object is only created on realize, and the
   1050         * CPU must exist and have been parented into the cluster before
   1051         * the cluster is realized.
   1052         */
   1053        if (!qdev_realize(DEVICE(&s->cluster[i]), NULL, errp)) {
   1054            return;
   1055        }
   1056
   1057        /* Connect EXP_IRQ/EXP_CPUn_IRQ GPIOs to the NVIC's lines 32 and up */
   1058        s->exp_irqs[i] = g_new(qemu_irq, s->exp_numirq);
   1059        for (j = 0; j < s->exp_numirq; j++) {
   1060            s->exp_irqs[i][j] = qdev_get_gpio_in(cpudev, j + NUM_SSE_IRQS);
   1061        }
   1062        if (i == 0) {
   1063            gpioname = g_strdup("EXP_IRQ");
   1064        } else {
   1065            gpioname = g_strdup_printf("EXP_CPU%d_IRQ", i);
   1066        }
   1067        qdev_init_gpio_in_named_with_opaque(dev, armsse_exp_irq,
   1068                                            s->exp_irqs[i],
   1069                                            gpioname, s->exp_numirq);
   1070        g_free(gpioname);
   1071    }
   1072
   1073    /* Wire up the splitters that connect common IRQs to all CPUs */
   1074    if (info->num_cpus > 1) {
   1075        for (i = 0; i < ARRAY_SIZE(s->cpu_irq_splitter); i++) {
   1076            if (info->irq_is_common[i]) {
   1077                Object *splitter = OBJECT(&s->cpu_irq_splitter[i]);
   1078                DeviceState *devs = DEVICE(splitter);
   1079                int cpunum;
   1080
   1081                if (!object_property_set_int(splitter, "num-lines",
   1082                                             info->num_cpus, errp)) {
   1083                    return;
   1084                }
   1085                if (!qdev_realize(DEVICE(splitter), NULL, errp)) {
   1086                    return;
   1087                }
   1088                for (cpunum = 0; cpunum < info->num_cpus; cpunum++) {
   1089                    DeviceState *cpudev = DEVICE(&s->armv7m[cpunum]);
   1090
   1091                    qdev_connect_gpio_out(devs, cpunum,
   1092                                          qdev_get_gpio_in(cpudev, i));
   1093                }
   1094            }
   1095        }
   1096    }
   1097
   1098    /* Set up the big aliases first */
   1099    make_alias(s, &s->alias1, &s->container, "alias 1",
   1100               0x10000000, 0x10000000, 0x00000000);
   1101    make_alias(s, &s->alias2, &s->container,
   1102               "alias 2", 0x30000000, 0x10000000, 0x20000000);
   1103    /* The 0x50000000..0x5fffffff region is not a pure alias: it has
   1104     * a few extra devices that only appear there (generally the
   1105     * control interfaces for the protection controllers).
   1106     * We implement this by mapping those devices over the top of this
   1107     * alias MR at a higher priority. Some of the devices in this range
   1108     * are per-CPU, so we must put this alias in the per-cpu containers.
   1109     */
   1110    for (i = 0; i < info->num_cpus; i++) {
   1111        make_alias(s, &s->alias3[i], &s->cpu_container[i],
   1112                   "alias 3", 0x50000000, 0x10000000, 0x40000000);
   1113    }
   1114
   1115    /* Security controller */
   1116    object_property_set_int(OBJECT(&s->secctl), "sse-version",
   1117                            info->sse_version, &error_abort);
   1118    if (!sysbus_realize(SYS_BUS_DEVICE(&s->secctl), errp)) {
   1119        return;
   1120    }
   1121    sbd_secctl = SYS_BUS_DEVICE(&s->secctl);
   1122    dev_secctl = DEVICE(&s->secctl);
   1123    sysbus_mmio_map(sbd_secctl, 0, 0x50080000);
   1124    sysbus_mmio_map(sbd_secctl, 1, 0x40080000);
   1125
   1126    s->nsc_cfg_in = qemu_allocate_irq(nsccfg_handler, s, 1);
   1127    qdev_connect_gpio_out_named(dev_secctl, "nsc_cfg", 0, s->nsc_cfg_in);
   1128
   1129    /* The sec_resp_cfg output from the security controller must be split into
   1130     * multiple lines, one for each of the PPCs within the ARMSSE and one
   1131     * that will be an output from the ARMSSE to the system.
   1132     */
   1133    if (!object_property_set_int(OBJECT(&s->sec_resp_splitter),
   1134                                 "num-lines", 3, errp)) {
   1135        return;
   1136    }
   1137    if (!qdev_realize(DEVICE(&s->sec_resp_splitter), NULL, errp)) {
   1138        return;
   1139    }
   1140    dev_splitter = DEVICE(&s->sec_resp_splitter);
   1141    qdev_connect_gpio_out_named(dev_secctl, "sec_resp_cfg", 0,
   1142                                qdev_get_gpio_in(dev_splitter, 0));
   1143
   1144    /* Each SRAM bank lives behind its own Memory Protection Controller */
   1145    for (i = 0; i < info->sram_banks; i++) {
   1146        char *ramname = g_strdup_printf("armsse.sram%d", i);
   1147        SysBusDevice *sbd_mpc;
   1148        uint32_t sram_bank_size = 1 << s->sram_addr_width;
   1149
   1150        memory_region_init_ram(&s->sram[i], NULL, ramname,
   1151                               sram_bank_size, errp);
   1152        g_free(ramname);
   1153        if (*errp) {
   1154            return;
   1155        }
   1156        object_property_set_link(OBJECT(&s->mpc[i]), "downstream",
   1157                                 OBJECT(&s->sram[i]), &error_abort);
   1158        if (!sysbus_realize(SYS_BUS_DEVICE(&s->mpc[i]), errp)) {
   1159            return;
   1160        }
   1161        /* Map the upstream end of the MPC into the right place... */
   1162        sbd_mpc = SYS_BUS_DEVICE(&s->mpc[i]);
   1163        memory_region_add_subregion(&s->container,
   1164                                    info->sram_bank_base + i * sram_bank_size,
   1165                                    sysbus_mmio_get_region(sbd_mpc, 1));
   1166        /* ...and its register interface */
   1167        memory_region_add_subregion(&s->container, 0x50083000 + i * 0x1000,
   1168                                    sysbus_mmio_get_region(sbd_mpc, 0));
   1169    }
   1170
   1171    /* We must OR together lines from the MPC splitters to go to the NVIC */
   1172    if (!object_property_set_int(OBJECT(&s->mpc_irq_orgate), "num-lines",
   1173                                 IOTS_NUM_EXP_MPC + info->sram_banks,
   1174                                 errp)) {
   1175        return;
   1176    }
   1177    if (!qdev_realize(DEVICE(&s->mpc_irq_orgate), NULL, errp)) {
   1178        return;
   1179    }
   1180    qdev_connect_gpio_out(DEVICE(&s->mpc_irq_orgate), 0,
   1181                          armsse_get_common_irq_in(s, 9));
   1182
   1183    /* This OR gate wires together outputs from the secure watchdogs to NMI */
   1184    if (!object_property_set_int(OBJECT(&s->nmi_orgate), "num-lines", 2,
   1185                                 errp)) {
   1186        return;
   1187    }
   1188    if (!qdev_realize(DEVICE(&s->nmi_orgate), NULL, errp)) {
   1189        return;
   1190    }
   1191    qdev_connect_gpio_out(DEVICE(&s->nmi_orgate), 0,
   1192                          qdev_get_gpio_in_named(DEVICE(&s->armv7m), "NMI", 0));
   1193
   1194    /* The SSE-300 has a System Counter / System Timestamp Generator */
   1195    if (info->has_sse_counter) {
   1196        SysBusDevice *sbd = SYS_BUS_DEVICE(&s->sse_counter);
   1197
   1198        qdev_connect_clock_in(DEVICE(sbd), "CLK", s->mainclk);
   1199        if (!sysbus_realize(sbd, errp)) {
   1200            return;
   1201        }
   1202        /*
   1203         * The control frame is only in the Secure region;
   1204         * the status frame is in the NS region (and visible in the
   1205         * S region via the alias mapping).
   1206         */
   1207        memory_region_add_subregion(&s->container, 0x58100000,
   1208                                    sysbus_mmio_get_region(sbd, 0));
   1209        memory_region_add_subregion(&s->container, 0x48101000,
   1210                                    sysbus_mmio_get_region(sbd, 1));
   1211    }
   1212
   1213    if (info->has_tcms) {
   1214        /* The SSE-300 has an ITCM at 0x0000_0000 and a DTCM at 0x2000_0000 */
   1215        memory_region_init_ram(&s->itcm, NULL, "sse300-itcm", 512 * KiB, errp);
   1216        if (*errp) {
   1217            return;
   1218        }
   1219        memory_region_init_ram(&s->dtcm, NULL, "sse300-dtcm", 512 * KiB, errp);
   1220        if (*errp) {
   1221            return;
   1222        }
   1223        memory_region_add_subregion(&s->container, 0x00000000, &s->itcm);
   1224        memory_region_add_subregion(&s->container, 0x20000000, &s->dtcm);
   1225    }
   1226
   1227    /* Devices behind APB PPC0:
   1228     *   0x40000000: timer0
   1229     *   0x40001000: timer1
   1230     *   0x40002000: dual timer
   1231     *   0x40003000: MHU0 (SSE-200 only)
   1232     *   0x40004000: MHU1 (SSE-200 only)
   1233     * We must configure and realize each downstream device and connect
   1234     * it to the appropriate PPC port; then we can realize the PPC and
   1235     * map its upstream ends to the right place in the container.
   1236     */
   1237    for (devinfo = info->devinfo; devinfo->name; devinfo++) {
   1238        SysBusDevice *sbd;
   1239        qemu_irq irq;
   1240
   1241        if (!strcmp(devinfo->type, TYPE_CMSDK_APB_TIMER)) {
   1242            sbd = SYS_BUS_DEVICE(&s->timer[devinfo->index]);
   1243
   1244            qdev_connect_clock_in(DEVICE(sbd), "pclk",
   1245                                  devinfo->slowclk ? s->s32kclk : s->mainclk);
   1246            if (!sysbus_realize(sbd, errp)) {
   1247                return;
   1248            }
   1249            mr = sysbus_mmio_get_region(sbd, 0);
   1250        } else if (!strcmp(devinfo->type, TYPE_CMSDK_APB_DUALTIMER)) {
   1251            sbd = SYS_BUS_DEVICE(&s->dualtimer);
   1252
   1253            qdev_connect_clock_in(DEVICE(sbd), "TIMCLK", s->mainclk);
   1254            if (!sysbus_realize(sbd, errp)) {
   1255                return;
   1256            }
   1257            mr = sysbus_mmio_get_region(sbd, 0);
   1258        } else if (!strcmp(devinfo->type, TYPE_SSE_TIMER)) {
   1259            sbd = SYS_BUS_DEVICE(&s->sse_timer[devinfo->index]);
   1260
   1261            assert(info->has_sse_counter);
   1262            object_property_set_link(OBJECT(sbd), "counter",
   1263                                     OBJECT(&s->sse_counter), &error_abort);
   1264            if (!sysbus_realize(sbd, errp)) {
   1265                return;
   1266            }
   1267            mr = sysbus_mmio_get_region(sbd, 0);
   1268        } else if (!strcmp(devinfo->type, TYPE_CMSDK_APB_WATCHDOG)) {
   1269            sbd = SYS_BUS_DEVICE(&s->cmsdk_watchdog[devinfo->index]);
   1270
   1271            qdev_connect_clock_in(DEVICE(sbd), "WDOGCLK",
   1272                                  devinfo->slowclk ? s->s32kclk : s->mainclk);
   1273            if (!sysbus_realize(sbd, errp)) {
   1274                return;
   1275            }
   1276            mr = sysbus_mmio_get_region(sbd, 0);
   1277        } else if (!strcmp(devinfo->type, TYPE_IOTKIT_SYSINFO)) {
   1278            sbd = SYS_BUS_DEVICE(&s->sysinfo);
   1279
   1280            object_property_set_int(OBJECT(&s->sysinfo), "SYS_VERSION",
   1281                                    info->sys_version, &error_abort);
   1282            object_property_set_int(OBJECT(&s->sysinfo), "SYS_CONFIG",
   1283                                    armsse_sys_config_value(s, info),
   1284                                    &error_abort);
   1285            object_property_set_int(OBJECT(&s->sysinfo), "sse-version",
   1286                                    info->sse_version, &error_abort);
   1287            object_property_set_int(OBJECT(&s->sysinfo), "IIDR",
   1288                                    info->iidr, &error_abort);
   1289            if (!sysbus_realize(sbd, errp)) {
   1290                return;
   1291            }
   1292            mr = sysbus_mmio_get_region(sbd, 0);
   1293        } else if (!strcmp(devinfo->type, TYPE_IOTKIT_SYSCTL)) {
   1294            /* System control registers */
   1295            sbd = SYS_BUS_DEVICE(&s->sysctl);
   1296
   1297            object_property_set_int(OBJECT(&s->sysctl), "sse-version",
   1298                                    info->sse_version, &error_abort);
   1299            object_property_set_int(OBJECT(&s->sysctl), "CPUWAIT_RST",
   1300                                    info->cpuwait_rst, &error_abort);
   1301            object_property_set_int(OBJECT(&s->sysctl), "INITSVTOR0_RST",
   1302                                    s->init_svtor, &error_abort);
   1303            object_property_set_int(OBJECT(&s->sysctl), "INITSVTOR1_RST",
   1304                                    s->init_svtor, &error_abort);
   1305            if (!sysbus_realize(sbd, errp)) {
   1306                return;
   1307            }
   1308            mr = sysbus_mmio_get_region(sbd, 0);
   1309        } else if (!strcmp(devinfo->type, TYPE_UNIMPLEMENTED_DEVICE)) {
   1310            sbd = SYS_BUS_DEVICE(&s->unimp[devinfo->index]);
   1311
   1312            qdev_prop_set_string(DEVICE(sbd), "name", devinfo->name);
   1313            qdev_prop_set_uint64(DEVICE(sbd), "size", devinfo->size);
   1314            if (!sysbus_realize(sbd, errp)) {
   1315                return;
   1316            }
   1317            mr = sysbus_mmio_get_region(sbd, 0);
   1318        } else {
   1319            g_assert_not_reached();
   1320        }
   1321
   1322        switch (devinfo->irq) {
   1323        case NO_IRQ:
   1324            irq = NULL;
   1325            break;
   1326        case 0 ... NUM_SSE_IRQS - 1:
   1327            irq = armsse_get_common_irq_in(s, devinfo->irq);
   1328            break;
   1329        case NMI_0:
   1330        case NMI_1:
   1331            irq = qdev_get_gpio_in(DEVICE(&s->nmi_orgate),
   1332                                   devinfo->irq - NMI_0);
   1333            break;
   1334        default:
   1335            g_assert_not_reached();
   1336        }
   1337
   1338        if (irq) {
   1339            sysbus_connect_irq(sbd, 0, irq);
   1340        }
   1341
   1342        /*
   1343         * Devices connected to a PPC are connected to the port here;
   1344         * we will map the upstream end of that port to the right address
   1345         * in the container later after the PPC has been realized.
   1346         * Devices not connected to a PPC can be mapped immediately.
   1347         */
   1348        if (devinfo->ppc != NO_PPC) {
   1349            TZPPC *ppc = &s->apb_ppc[devinfo->ppc];
   1350            g_autofree char *portname = g_strdup_printf("port[%d]",
   1351                                                        devinfo->ppc_port);
   1352            object_property_set_link(OBJECT(ppc), portname, OBJECT(mr),
   1353                                     &error_abort);
   1354        } else {
   1355            memory_region_add_subregion(&s->container, devinfo->addr, mr);
   1356        }
   1357    }
   1358
   1359    if (info->has_mhus) {
   1360        /*
   1361         * An SSE-200 with only one CPU should have only one MHU created,
   1362         * with the region where the second MHU usually is being RAZ/WI.
   1363         * We don't implement that SSE-200 config; if we want to support
   1364         * it then this code needs to be enhanced to handle creating the
   1365         * RAZ/WI region instead of the second MHU.
   1366         */
   1367        assert(info->num_cpus == ARRAY_SIZE(s->mhu));
   1368
   1369        for (i = 0; i < ARRAY_SIZE(s->mhu); i++) {
   1370            char *port;
   1371            int cpunum;
   1372            SysBusDevice *mhu_sbd = SYS_BUS_DEVICE(&s->mhu[i]);
   1373
   1374            if (!sysbus_realize(SYS_BUS_DEVICE(&s->mhu[i]), errp)) {
   1375                return;
   1376            }
   1377            port = g_strdup_printf("port[%d]", i + 3);
   1378            mr = sysbus_mmio_get_region(mhu_sbd, 0);
   1379            object_property_set_link(OBJECT(&s->apb_ppc[0]), port, OBJECT(mr),
   1380                                     &error_abort);
   1381            g_free(port);
   1382
   1383            /*
   1384             * Each MHU has an irq line for each CPU:
   1385             *  MHU 0 irq line 0 -> CPU 0 IRQ 6
   1386             *  MHU 0 irq line 1 -> CPU 1 IRQ 6
   1387             *  MHU 1 irq line 0 -> CPU 0 IRQ 7
   1388             *  MHU 1 irq line 1 -> CPU 1 IRQ 7
   1389             */
   1390            for (cpunum = 0; cpunum < info->num_cpus; cpunum++) {
   1391                DeviceState *cpudev = DEVICE(&s->armv7m[cpunum]);
   1392
   1393                sysbus_connect_irq(mhu_sbd, cpunum,
   1394                                   qdev_get_gpio_in(cpudev, 6 + i));
   1395            }
   1396        }
   1397    }
   1398
   1399    if (!sysbus_realize(SYS_BUS_DEVICE(&s->apb_ppc[0]), errp)) {
   1400        return;
   1401    }
   1402
   1403    sbd_apb_ppc0 = SYS_BUS_DEVICE(&s->apb_ppc[0]);
   1404    dev_apb_ppc0 = DEVICE(&s->apb_ppc[0]);
   1405
   1406    if (info->has_mhus) {
   1407        mr = sysbus_mmio_get_region(sbd_apb_ppc0, 3);
   1408        memory_region_add_subregion(&s->container, 0x40003000, mr);
   1409        mr = sysbus_mmio_get_region(sbd_apb_ppc0, 4);
   1410        memory_region_add_subregion(&s->container, 0x40004000, mr);
   1411    }
   1412    for (i = 0; i < IOTS_APB_PPC0_NUM_PORTS; i++) {
   1413        qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_nonsec", i,
   1414                                    qdev_get_gpio_in_named(dev_apb_ppc0,
   1415                                                           "cfg_nonsec", i));
   1416        qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_ap", i,
   1417                                    qdev_get_gpio_in_named(dev_apb_ppc0,
   1418                                                           "cfg_ap", i));
   1419    }
   1420    qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_irq_enable", 0,
   1421                                qdev_get_gpio_in_named(dev_apb_ppc0,
   1422                                                       "irq_enable", 0));
   1423    qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_irq_clear", 0,
   1424                                qdev_get_gpio_in_named(dev_apb_ppc0,
   1425                                                       "irq_clear", 0));
   1426    qdev_connect_gpio_out(dev_splitter, 0,
   1427                          qdev_get_gpio_in_named(dev_apb_ppc0,
   1428                                                 "cfg_sec_resp", 0));
   1429
   1430    /* All the PPC irq lines (from the 2 internal PPCs and the 8 external
   1431     * ones) are sent individually to the security controller, and also
   1432     * ORed together to give a single combined PPC interrupt to the NVIC.
   1433     */
   1434    if (!object_property_set_int(OBJECT(&s->ppc_irq_orgate),
   1435                                 "num-lines", NUM_PPCS, errp)) {
   1436        return;
   1437    }
   1438    if (!qdev_realize(DEVICE(&s->ppc_irq_orgate), NULL, errp)) {
   1439        return;
   1440    }
   1441    qdev_connect_gpio_out(DEVICE(&s->ppc_irq_orgate), 0,
   1442                          armsse_get_common_irq_in(s, 10));
   1443
   1444    /*
   1445     * 0x40010000 .. 0x4001ffff (and the 0x5001000... secure-only alias):
   1446     * private per-CPU region (all these devices are SSE-200 only):
   1447     *  0x50010000: L1 icache control registers
   1448     *  0x50011000: CPUSECCTRL (CPU local security control registers)
   1449     *  0x4001f000 and 0x5001f000: CPU_IDENTITY register block
   1450     * The SSE-300 has an extra:
   1451     *  0x40012000 and 0x50012000: CPU_PWRCTRL register block
   1452     */
   1453    if (info->has_cachectrl) {
   1454        for (i = 0; i < info->num_cpus; i++) {
   1455            char *name = g_strdup_printf("cachectrl%d", i);
   1456            MemoryRegion *mr;
   1457
   1458            qdev_prop_set_string(DEVICE(&s->cachectrl[i]), "name", name);
   1459            g_free(name);
   1460            qdev_prop_set_uint64(DEVICE(&s->cachectrl[i]), "size", 0x1000);
   1461            if (!sysbus_realize(SYS_BUS_DEVICE(&s->cachectrl[i]), errp)) {
   1462                return;
   1463            }
   1464
   1465            mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->cachectrl[i]), 0);
   1466            memory_region_add_subregion(&s->cpu_container[i], 0x50010000, mr);
   1467        }
   1468    }
   1469    if (info->has_cpusecctrl) {
   1470        for (i = 0; i < info->num_cpus; i++) {
   1471            char *name = g_strdup_printf("CPUSECCTRL%d", i);
   1472            MemoryRegion *mr;
   1473
   1474            qdev_prop_set_string(DEVICE(&s->cpusecctrl[i]), "name", name);
   1475            g_free(name);
   1476            qdev_prop_set_uint64(DEVICE(&s->cpusecctrl[i]), "size", 0x1000);
   1477            if (!sysbus_realize(SYS_BUS_DEVICE(&s->cpusecctrl[i]), errp)) {
   1478                return;
   1479            }
   1480
   1481            mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->cpusecctrl[i]), 0);
   1482            memory_region_add_subregion(&s->cpu_container[i], 0x50011000, mr);
   1483        }
   1484    }
   1485    if (info->has_cpuid) {
   1486        for (i = 0; i < info->num_cpus; i++) {
   1487            MemoryRegion *mr;
   1488
   1489            qdev_prop_set_uint32(DEVICE(&s->cpuid[i]), "CPUID", i);
   1490            if (!sysbus_realize(SYS_BUS_DEVICE(&s->cpuid[i]), errp)) {
   1491                return;
   1492            }
   1493
   1494            mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->cpuid[i]), 0);
   1495            memory_region_add_subregion(&s->cpu_container[i], 0x4001F000, mr);
   1496        }
   1497    }
   1498    if (info->has_cpu_pwrctrl) {
   1499        for (i = 0; i < info->num_cpus; i++) {
   1500            MemoryRegion *mr;
   1501
   1502            if (!sysbus_realize(SYS_BUS_DEVICE(&s->cpu_pwrctrl[i]), errp)) {
   1503                return;
   1504            }
   1505
   1506            mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->cpu_pwrctrl[i]), 0);
   1507            memory_region_add_subregion(&s->cpu_container[i], 0x40012000, mr);
   1508        }
   1509    }
   1510
   1511    if (!sysbus_realize(SYS_BUS_DEVICE(&s->apb_ppc[1]), errp)) {
   1512        return;
   1513    }
   1514
   1515    dev_apb_ppc1 = DEVICE(&s->apb_ppc[1]);
   1516    qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_nonsec", 0,
   1517                                qdev_get_gpio_in_named(dev_apb_ppc1,
   1518                                                       "cfg_nonsec", 0));
   1519    qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_ap", 0,
   1520                                qdev_get_gpio_in_named(dev_apb_ppc1,
   1521                                                       "cfg_ap", 0));
   1522    qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_irq_enable", 0,
   1523                                qdev_get_gpio_in_named(dev_apb_ppc1,
   1524                                                       "irq_enable", 0));
   1525    qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_irq_clear", 0,
   1526                                qdev_get_gpio_in_named(dev_apb_ppc1,
   1527                                                       "irq_clear", 0));
   1528    qdev_connect_gpio_out(dev_splitter, 1,
   1529                          qdev_get_gpio_in_named(dev_apb_ppc1,
   1530                                                 "cfg_sec_resp", 0));
   1531
   1532    /*
   1533     * Now both PPCs are realized we can map the upstream ends of
   1534     * ports which correspond to entries in the devinfo array.
   1535     * The ports which are connected to non-devinfo devices have
   1536     * already been mapped.
   1537     */
   1538    for (devinfo = info->devinfo; devinfo->name; devinfo++) {
   1539        SysBusDevice *ppc_sbd;
   1540
   1541        if (devinfo->ppc == NO_PPC) {
   1542            continue;
   1543        }
   1544        ppc_sbd = SYS_BUS_DEVICE(&s->apb_ppc[devinfo->ppc]);
   1545        mr = sysbus_mmio_get_region(ppc_sbd, devinfo->ppc_port);
   1546        memory_region_add_subregion(&s->container, devinfo->addr, mr);
   1547    }
   1548
   1549    for (i = 0; i < ARRAY_SIZE(s->ppc_irq_splitter); i++) {
   1550        Object *splitter = OBJECT(&s->ppc_irq_splitter[i]);
   1551
   1552        if (!object_property_set_int(splitter, "num-lines", 2, errp)) {
   1553            return;
   1554        }
   1555        if (!qdev_realize(DEVICE(splitter), NULL, errp)) {
   1556            return;
   1557        }
   1558    }
   1559
   1560    for (i = 0; i < IOTS_NUM_AHB_EXP_PPC; i++) {
   1561        char *ppcname = g_strdup_printf("ahb_ppcexp%d", i);
   1562
   1563        armsse_forward_ppc(s, ppcname, i);
   1564        g_free(ppcname);
   1565    }
   1566
   1567    for (i = 0; i < IOTS_NUM_APB_EXP_PPC; i++) {
   1568        char *ppcname = g_strdup_printf("apb_ppcexp%d", i);
   1569
   1570        armsse_forward_ppc(s, ppcname, i + IOTS_NUM_AHB_EXP_PPC);
   1571        g_free(ppcname);
   1572    }
   1573
   1574    for (i = NUM_EXTERNAL_PPCS; i < NUM_PPCS; i++) {
   1575        /* Wire up IRQ splitter for internal PPCs */
   1576        DeviceState *devs = DEVICE(&s->ppc_irq_splitter[i]);
   1577        char *gpioname = g_strdup_printf("apb_ppc%d_irq_status",
   1578                                         i - NUM_EXTERNAL_PPCS);
   1579        TZPPC *ppc = &s->apb_ppc[i - NUM_EXTERNAL_PPCS];
   1580
   1581        qdev_connect_gpio_out(devs, 0,
   1582                              qdev_get_gpio_in_named(dev_secctl, gpioname, 0));
   1583        qdev_connect_gpio_out(devs, 1,
   1584                              qdev_get_gpio_in(DEVICE(&s->ppc_irq_orgate), i));
   1585        qdev_connect_gpio_out_named(DEVICE(ppc), "irq", 0,
   1586                                    qdev_get_gpio_in(devs, 0));
   1587        g_free(gpioname);
   1588    }
   1589
   1590    /* Wire up the splitters for the MPC IRQs */
   1591    for (i = 0; i < IOTS_NUM_EXP_MPC + info->sram_banks; i++) {
   1592        SplitIRQ *splitter = &s->mpc_irq_splitter[i];
   1593        DeviceState *dev_splitter = DEVICE(splitter);
   1594
   1595        if (!object_property_set_int(OBJECT(splitter), "num-lines", 2,
   1596                                     errp)) {
   1597            return;
   1598        }
   1599        if (!qdev_realize(DEVICE(splitter), NULL, errp)) {
   1600            return;
   1601        }
   1602
   1603        if (i < IOTS_NUM_EXP_MPC) {
   1604            /* Splitter input is from GPIO input line */
   1605            s->mpcexp_status_in[i] = qdev_get_gpio_in(dev_splitter, 0);
   1606            qdev_connect_gpio_out(dev_splitter, 0,
   1607                                  qdev_get_gpio_in_named(dev_secctl,
   1608                                                         "mpcexp_status", i));
   1609        } else {
   1610            /* Splitter input is from our own MPC */
   1611            qdev_connect_gpio_out_named(DEVICE(&s->mpc[i - IOTS_NUM_EXP_MPC]),
   1612                                        "irq", 0,
   1613                                        qdev_get_gpio_in(dev_splitter, 0));
   1614            qdev_connect_gpio_out(dev_splitter, 0,
   1615                                  qdev_get_gpio_in_named(dev_secctl,
   1616                                                         "mpc_status",
   1617                                                         i - IOTS_NUM_EXP_MPC));
   1618        }
   1619
   1620        qdev_connect_gpio_out(dev_splitter, 1,
   1621                              qdev_get_gpio_in(DEVICE(&s->mpc_irq_orgate), i));
   1622    }
   1623    /* Create GPIO inputs which will pass the line state for our
   1624     * mpcexp_irq inputs to the correct splitter devices.
   1625     */
   1626    qdev_init_gpio_in_named(dev, armsse_mpcexp_status, "mpcexp_status",
   1627                            IOTS_NUM_EXP_MPC);
   1628
   1629    armsse_forward_sec_resp_cfg(s);
   1630
   1631    /* Forward the MSC related signals */
   1632    qdev_pass_gpios(dev_secctl, dev, "mscexp_status");
   1633    qdev_pass_gpios(dev_secctl, dev, "mscexp_clear");
   1634    qdev_pass_gpios(dev_secctl, dev, "mscexp_ns");
   1635    qdev_connect_gpio_out_named(dev_secctl, "msc_irq", 0,
   1636                                armsse_get_common_irq_in(s, 11));
   1637
   1638    /*
   1639     * Expose our container region to the board model; this corresponds
   1640     * to the AHB Slave Expansion ports which allow bus master devices
   1641     * (eg DMA controllers) in the board model to make transactions into
   1642     * devices in the ARMSSE.
   1643     */
   1644    sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->container);
   1645}
   1646
   1647static void armsse_idau_check(IDAUInterface *ii, uint32_t address,
   1648                              int *iregion, bool *exempt, bool *ns, bool *nsc)
   1649{
   1650    /*
   1651     * For ARMSSE systems the IDAU responses are simple logical functions
   1652     * of the address bits. The NSC attribute is guest-adjustable via the
   1653     * NSCCFG register in the security controller.
   1654     */
   1655    ARMSSE *s = ARM_SSE(ii);
   1656    int region = extract32(address, 28, 4);
   1657
   1658    *ns = !(region & 1);
   1659    *nsc = (region == 1 && (s->nsccfg & 1)) || (region == 3 && (s->nsccfg & 2));
   1660    /* 0xe0000000..0xe00fffff and 0xf0000000..0xf00fffff are exempt */
   1661    *exempt = (address & 0xeff00000) == 0xe0000000;
   1662    *iregion = region;
   1663}
   1664
   1665static const VMStateDescription armsse_vmstate = {
   1666    .name = "iotkit",
   1667    .version_id = 2,
   1668    .minimum_version_id = 2,
   1669    .fields = (VMStateField[]) {
   1670        VMSTATE_CLOCK(mainclk, ARMSSE),
   1671        VMSTATE_CLOCK(s32kclk, ARMSSE),
   1672        VMSTATE_UINT32(nsccfg, ARMSSE),
   1673        VMSTATE_END_OF_LIST()
   1674    }
   1675};
   1676
   1677static void armsse_reset(DeviceState *dev)
   1678{
   1679    ARMSSE *s = ARM_SSE(dev);
   1680
   1681    s->nsccfg = 0;
   1682}
   1683
   1684static void armsse_class_init(ObjectClass *klass, void *data)
   1685{
   1686    DeviceClass *dc = DEVICE_CLASS(klass);
   1687    IDAUInterfaceClass *iic = IDAU_INTERFACE_CLASS(klass);
   1688    ARMSSEClass *asc = ARM_SSE_CLASS(klass);
   1689    const ARMSSEInfo *info = data;
   1690
   1691    dc->realize = armsse_realize;
   1692    dc->vmsd = &armsse_vmstate;
   1693    device_class_set_props(dc, info->props);
   1694    dc->reset = armsse_reset;
   1695    iic->check = armsse_idau_check;
   1696    asc->info = info;
   1697}
   1698
   1699static const TypeInfo armsse_info = {
   1700    .name = TYPE_ARM_SSE,
   1701    .parent = TYPE_SYS_BUS_DEVICE,
   1702    .instance_size = sizeof(ARMSSE),
   1703    .class_size = sizeof(ARMSSEClass),
   1704    .instance_init = armsse_init,
   1705    .abstract = true,
   1706    .interfaces = (InterfaceInfo[]) {
   1707        { TYPE_IDAU_INTERFACE },
   1708        { }
   1709    }
   1710};
   1711
   1712static void armsse_register_types(void)
   1713{
   1714    int i;
   1715
   1716    type_register_static(&armsse_info);
   1717
   1718    for (i = 0; i < ARRAY_SIZE(armsse_variants); i++) {
   1719        TypeInfo ti = {
   1720            .name = armsse_variants[i].name,
   1721            .parent = TYPE_ARM_SSE,
   1722            .class_init = armsse_class_init,
   1723            .class_data = (void *)&armsse_variants[i],
   1724        };
   1725        type_register(&ti);
   1726    }
   1727}
   1728
   1729type_init(armsse_register_types);