qemu/hw/arm/armsse.c
<<
>>
Prefs
   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 "qapi/error.h"
  17#include "trace.h"
  18#include "hw/sysbus.h"
  19#include "hw/registerfields.h"
  20#include "hw/arm/armsse.h"
  21#include "hw/arm/boot.h"
  22
  23/* Format of the System Information block SYS_CONFIG register */
  24typedef enum SysConfigFormat {
  25    IoTKitFormat,
  26    SSE200Format,
  27} SysConfigFormat;
  28
  29struct ARMSSEInfo {
  30    const char *name;
  31    int sram_banks;
  32    int num_cpus;
  33    uint32_t sys_version;
  34    uint32_t cpuwait_rst;
  35    SysConfigFormat sys_config_format;
  36    bool has_mhus;
  37    bool has_ppus;
  38    bool has_cachectrl;
  39    bool has_cpusecctrl;
  40    bool has_cpuid;
  41    Property *props;
  42};
  43
  44static Property iotkit_properties[] = {
  45    DEFINE_PROP_LINK("memory", ARMSSE, board_memory, TYPE_MEMORY_REGION,
  46                     MemoryRegion *),
  47    DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
  48    DEFINE_PROP_UINT32("MAINCLK", ARMSSE, mainclk_frq, 0),
  49    DEFINE_PROP_UINT32("SRAM_ADDR_WIDTH", ARMSSE, sram_addr_width, 15),
  50    DEFINE_PROP_UINT32("init-svtor", ARMSSE, init_svtor, 0x10000000),
  51    DEFINE_PROP_BOOL("CPU0_FPU", ARMSSE, cpu_fpu[0], true),
  52    DEFINE_PROP_BOOL("CPU0_DSP", ARMSSE, cpu_dsp[0], true),
  53    DEFINE_PROP_END_OF_LIST()
  54};
  55
  56static Property armsse_properties[] = {
  57    DEFINE_PROP_LINK("memory", ARMSSE, board_memory, TYPE_MEMORY_REGION,
  58                     MemoryRegion *),
  59    DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
  60    DEFINE_PROP_UINT32("MAINCLK", ARMSSE, mainclk_frq, 0),
  61    DEFINE_PROP_UINT32("SRAM_ADDR_WIDTH", ARMSSE, sram_addr_width, 15),
  62    DEFINE_PROP_UINT32("init-svtor", ARMSSE, init_svtor, 0x10000000),
  63    DEFINE_PROP_BOOL("CPU0_FPU", ARMSSE, cpu_fpu[0], false),
  64    DEFINE_PROP_BOOL("CPU0_DSP", ARMSSE, cpu_dsp[0], false),
  65    DEFINE_PROP_BOOL("CPU1_FPU", ARMSSE, cpu_fpu[1], true),
  66    DEFINE_PROP_BOOL("CPU1_DSP", ARMSSE, cpu_dsp[1], true),
  67    DEFINE_PROP_END_OF_LIST()
  68};
  69
  70static const ARMSSEInfo armsse_variants[] = {
  71    {
  72        .name = TYPE_IOTKIT,
  73        .sram_banks = 1,
  74        .num_cpus = 1,
  75        .sys_version = 0x41743,
  76        .cpuwait_rst = 0,
  77        .sys_config_format = IoTKitFormat,
  78        .has_mhus = false,
  79        .has_ppus = false,
  80        .has_cachectrl = false,
  81        .has_cpusecctrl = false,
  82        .has_cpuid = false,
  83        .props = iotkit_properties,
  84    },
  85    {
  86        .name = TYPE_SSE200,
  87        .sram_banks = 4,
  88        .num_cpus = 2,
  89        .sys_version = 0x22041743,
  90        .cpuwait_rst = 2,
  91        .sys_config_format = SSE200Format,
  92        .has_mhus = true,
  93        .has_ppus = true,
  94        .has_cachectrl = true,
  95        .has_cpusecctrl = true,
  96        .has_cpuid = true,
  97        .props = armsse_properties,
  98    },
  99};
 100
 101static uint32_t armsse_sys_config_value(ARMSSE *s, const ARMSSEInfo *info)
 102{
 103    /* Return the SYS_CONFIG value for this SSE */
 104    uint32_t sys_config;
 105
 106    switch (info->sys_config_format) {
 107    case IoTKitFormat:
 108        sys_config = 0;
 109        sys_config = deposit32(sys_config, 0, 4, info->sram_banks);
 110        sys_config = deposit32(sys_config, 4, 4, s->sram_addr_width - 12);
 111        break;
 112    case SSE200Format:
 113        sys_config = 0;
 114        sys_config = deposit32(sys_config, 0, 4, info->sram_banks);
 115        sys_config = deposit32(sys_config, 4, 5, s->sram_addr_width);
 116        sys_config = deposit32(sys_config, 24, 4, 2);
 117        if (info->num_cpus > 1) {
 118            sys_config = deposit32(sys_config, 10, 1, 1);
 119            sys_config = deposit32(sys_config, 20, 4, info->sram_banks - 1);
 120            sys_config = deposit32(sys_config, 28, 4, 2);
 121        }
 122        break;
 123    default:
 124        g_assert_not_reached();
 125    }
 126    return sys_config;
 127}
 128
 129/* Clock frequency in HZ of the 32KHz "slow clock" */
 130#define S32KCLK (32 * 1000)
 131
 132/* Is internal IRQ n shared between CPUs in a multi-core SSE ? */
 133static bool irq_is_common[32] = {
 134    [0 ... 5] = true,
 135    /* 6, 7: per-CPU MHU interrupts */
 136    [8 ... 12] = true,
 137    /* 13: per-CPU icache interrupt */
 138    /* 14: reserved */
 139    [15 ... 20] = true,
 140    /* 21: reserved */
 141    [22 ... 26] = true,
 142    /* 27: reserved */
 143    /* 28, 29: per-CPU CTI interrupts */
 144    /* 30, 31: reserved */
 145};
 146
 147/*
 148 * Create an alias region in @container of @size bytes starting at @base
 149 * which mirrors the memory starting at @orig.
 150 */
 151static void make_alias(ARMSSE *s, MemoryRegion *mr, MemoryRegion *container,
 152                       const char *name, hwaddr base, hwaddr size, hwaddr orig)
 153{
 154    memory_region_init_alias(mr, NULL, name, container, orig, size);
 155    /* The alias is even lower priority than unimplemented_device regions */
 156    memory_region_add_subregion_overlap(container, base, mr, -1500);
 157}
 158
 159static void irq_status_forwarder(void *opaque, int n, int level)
 160{
 161    qemu_irq destirq = opaque;
 162
 163    qemu_set_irq(destirq, level);
 164}
 165
 166static void nsccfg_handler(void *opaque, int n, int level)
 167{
 168    ARMSSE *s = ARMSSE(opaque);
 169
 170    s->nsccfg = level;
 171}
 172
 173static void armsse_forward_ppc(ARMSSE *s, const char *ppcname, int ppcnum)
 174{
 175    /* Each of the 4 AHB and 4 APB PPCs that might be present in a
 176     * system using the ARMSSE has a collection of control lines which
 177     * are provided by the security controller and which we want to
 178     * expose as control lines on the ARMSSE device itself, so the
 179     * code using the ARMSSE can wire them up to the PPCs.
 180     */
 181    SplitIRQ *splitter = &s->ppc_irq_splitter[ppcnum];
 182    DeviceState *armssedev = DEVICE(s);
 183    DeviceState *dev_secctl = DEVICE(&s->secctl);
 184    DeviceState *dev_splitter = DEVICE(splitter);
 185    char *name;
 186
 187    name = g_strdup_printf("%s_nonsec", ppcname);
 188    qdev_pass_gpios(dev_secctl, armssedev, name);
 189    g_free(name);
 190    name = g_strdup_printf("%s_ap", ppcname);
 191    qdev_pass_gpios(dev_secctl, armssedev, name);
 192    g_free(name);
 193    name = g_strdup_printf("%s_irq_enable", ppcname);
 194    qdev_pass_gpios(dev_secctl, armssedev, name);
 195    g_free(name);
 196    name = g_strdup_printf("%s_irq_clear", ppcname);
 197    qdev_pass_gpios(dev_secctl, armssedev, name);
 198    g_free(name);
 199
 200    /* irq_status is a little more tricky, because we need to
 201     * split it so we can send it both to the security controller
 202     * and to our OR gate for the NVIC interrupt line.
 203     * Connect up the splitter's outputs, and create a GPIO input
 204     * which will pass the line state to the input splitter.
 205     */
 206    name = g_strdup_printf("%s_irq_status", ppcname);
 207    qdev_connect_gpio_out(dev_splitter, 0,
 208                          qdev_get_gpio_in_named(dev_secctl,
 209                                                 name, 0));
 210    qdev_connect_gpio_out(dev_splitter, 1,
 211                          qdev_get_gpio_in(DEVICE(&s->ppc_irq_orgate), ppcnum));
 212    s->irq_status_in[ppcnum] = qdev_get_gpio_in(dev_splitter, 0);
 213    qdev_init_gpio_in_named_with_opaque(armssedev, irq_status_forwarder,
 214                                        s->irq_status_in[ppcnum], name, 1);
 215    g_free(name);
 216}
 217
 218static void armsse_forward_sec_resp_cfg(ARMSSE *s)
 219{
 220    /* Forward the 3rd output from the splitter device as a
 221     * named GPIO output of the armsse object.
 222     */
 223    DeviceState *dev = DEVICE(s);
 224    DeviceState *dev_splitter = DEVICE(&s->sec_resp_splitter);
 225
 226    qdev_init_gpio_out_named(dev, &s->sec_resp_cfg, "sec_resp_cfg", 1);
 227    s->sec_resp_cfg_in = qemu_allocate_irq(irq_status_forwarder,
 228                                           s->sec_resp_cfg, 1);
 229    qdev_connect_gpio_out(dev_splitter, 2, s->sec_resp_cfg_in);
 230}
 231
 232static void armsse_init(Object *obj)
 233{
 234    ARMSSE *s = ARMSSE(obj);
 235    ARMSSEClass *asc = ARMSSE_GET_CLASS(obj);
 236    const ARMSSEInfo *info = asc->info;
 237    int i;
 238
 239    assert(info->sram_banks <= MAX_SRAM_BANKS);
 240    assert(info->num_cpus <= SSE_MAX_CPUS);
 241
 242    memory_region_init(&s->container, obj, "armsse-container", UINT64_MAX);
 243
 244    for (i = 0; i < info->num_cpus; i++) {
 245        /*
 246         * We put each CPU in its own cluster as they are logically
 247         * distinct and may be configured differently.
 248         */
 249        char *name;
 250
 251        name = g_strdup_printf("cluster%d", i);
 252        object_initialize_child(obj, name, &s->cluster[i],
 253                                sizeof(s->cluster[i]), TYPE_CPU_CLUSTER,
 254                                &error_abort, NULL);
 255        qdev_prop_set_uint32(DEVICE(&s->cluster[i]), "cluster-id", i);
 256        g_free(name);
 257
 258        name = g_strdup_printf("armv7m%d", i);
 259        sysbus_init_child_obj(OBJECT(&s->cluster[i]), name,
 260                              &s->armv7m[i], sizeof(s->armv7m), TYPE_ARMV7M);
 261        qdev_prop_set_string(DEVICE(&s->armv7m[i]), "cpu-type",
 262                             ARM_CPU_TYPE_NAME("cortex-m33"));
 263        g_free(name);
 264        name = g_strdup_printf("arm-sse-cpu-container%d", i);
 265        memory_region_init(&s->cpu_container[i], obj, name, UINT64_MAX);
 266        g_free(name);
 267        if (i > 0) {
 268            name = g_strdup_printf("arm-sse-container-alias%d", i);
 269            memory_region_init_alias(&s->container_alias[i - 1], obj,
 270                                     name, &s->container, 0, UINT64_MAX);
 271            g_free(name);
 272        }
 273    }
 274
 275    sysbus_init_child_obj(obj, "secctl", &s->secctl, sizeof(s->secctl),
 276                          TYPE_IOTKIT_SECCTL);
 277    sysbus_init_child_obj(obj, "apb-ppc0", &s->apb_ppc0, sizeof(s->apb_ppc0),
 278                          TYPE_TZ_PPC);
 279    sysbus_init_child_obj(obj, "apb-ppc1", &s->apb_ppc1, sizeof(s->apb_ppc1),
 280                          TYPE_TZ_PPC);
 281    for (i = 0; i < info->sram_banks; i++) {
 282        char *name = g_strdup_printf("mpc%d", i);
 283        sysbus_init_child_obj(obj, name, &s->mpc[i],
 284                              sizeof(s->mpc[i]), TYPE_TZ_MPC);
 285        g_free(name);
 286    }
 287    object_initialize_child(obj, "mpc-irq-orgate", &s->mpc_irq_orgate,
 288                            sizeof(s->mpc_irq_orgate), TYPE_OR_IRQ,
 289                            &error_abort, NULL);
 290
 291    for (i = 0; i < IOTS_NUM_EXP_MPC + info->sram_banks; i++) {
 292        char *name = g_strdup_printf("mpc-irq-splitter-%d", i);
 293        SplitIRQ *splitter = &s->mpc_irq_splitter[i];
 294
 295        object_initialize_child(obj, name, splitter, sizeof(*splitter),
 296                                TYPE_SPLIT_IRQ, &error_abort, NULL);
 297        g_free(name);
 298    }
 299    sysbus_init_child_obj(obj, "timer0", &s->timer0, sizeof(s->timer0),
 300                          TYPE_CMSDK_APB_TIMER);
 301    sysbus_init_child_obj(obj, "timer1", &s->timer1, sizeof(s->timer1),
 302                          TYPE_CMSDK_APB_TIMER);
 303    sysbus_init_child_obj(obj, "s32ktimer", &s->s32ktimer, sizeof(s->s32ktimer),
 304                          TYPE_CMSDK_APB_TIMER);
 305    sysbus_init_child_obj(obj, "dualtimer", &s->dualtimer, sizeof(s->dualtimer),
 306                          TYPE_CMSDK_APB_DUALTIMER);
 307    sysbus_init_child_obj(obj, "s32kwatchdog", &s->s32kwatchdog,
 308                          sizeof(s->s32kwatchdog), TYPE_CMSDK_APB_WATCHDOG);
 309    sysbus_init_child_obj(obj, "nswatchdog", &s->nswatchdog,
 310                          sizeof(s->nswatchdog), TYPE_CMSDK_APB_WATCHDOG);
 311    sysbus_init_child_obj(obj, "swatchdog", &s->swatchdog,
 312                          sizeof(s->swatchdog), TYPE_CMSDK_APB_WATCHDOG);
 313    sysbus_init_child_obj(obj, "armsse-sysctl", &s->sysctl,
 314                          sizeof(s->sysctl), TYPE_IOTKIT_SYSCTL);
 315    sysbus_init_child_obj(obj, "armsse-sysinfo", &s->sysinfo,
 316                          sizeof(s->sysinfo), TYPE_IOTKIT_SYSINFO);
 317    if (info->has_mhus) {
 318        sysbus_init_child_obj(obj, "mhu0", &s->mhu[0], sizeof(s->mhu[0]),
 319                              TYPE_ARMSSE_MHU);
 320        sysbus_init_child_obj(obj, "mhu1", &s->mhu[1], sizeof(s->mhu[1]),
 321                              TYPE_ARMSSE_MHU);
 322    }
 323    if (info->has_ppus) {
 324        for (i = 0; i < info->num_cpus; i++) {
 325            char *name = g_strdup_printf("CPU%dCORE_PPU", i);
 326            int ppuidx = CPU0CORE_PPU + i;
 327
 328            sysbus_init_child_obj(obj, name, &s->ppu[ppuidx],
 329                                  sizeof(s->ppu[ppuidx]),
 330                                  TYPE_UNIMPLEMENTED_DEVICE);
 331            g_free(name);
 332        }
 333        sysbus_init_child_obj(obj, "DBG_PPU", &s->ppu[DBG_PPU],
 334                              sizeof(s->ppu[DBG_PPU]),
 335                              TYPE_UNIMPLEMENTED_DEVICE);
 336        for (i = 0; i < info->sram_banks; i++) {
 337            char *name = g_strdup_printf("RAM%d_PPU", i);
 338            int ppuidx = RAM0_PPU + i;
 339
 340            sysbus_init_child_obj(obj, name, &s->ppu[ppuidx],
 341                                  sizeof(s->ppu[ppuidx]),
 342                                  TYPE_UNIMPLEMENTED_DEVICE);
 343            g_free(name);
 344        }
 345    }
 346    if (info->has_cachectrl) {
 347        for (i = 0; i < info->num_cpus; i++) {
 348            char *name = g_strdup_printf("cachectrl%d", i);
 349
 350            sysbus_init_child_obj(obj, name, &s->cachectrl[i],
 351                                  sizeof(s->cachectrl[i]),
 352                                  TYPE_UNIMPLEMENTED_DEVICE);
 353            g_free(name);
 354        }
 355    }
 356    if (info->has_cpusecctrl) {
 357        for (i = 0; i < info->num_cpus; i++) {
 358            char *name = g_strdup_printf("cpusecctrl%d", i);
 359
 360            sysbus_init_child_obj(obj, name, &s->cpusecctrl[i],
 361                                  sizeof(s->cpusecctrl[i]),
 362                                  TYPE_UNIMPLEMENTED_DEVICE);
 363            g_free(name);
 364        }
 365    }
 366    if (info->has_cpuid) {
 367        for (i = 0; i < info->num_cpus; i++) {
 368            char *name = g_strdup_printf("cpuid%d", i);
 369
 370            sysbus_init_child_obj(obj, name, &s->cpuid[i],
 371                                  sizeof(s->cpuid[i]),
 372                                  TYPE_ARMSSE_CPUID);
 373            g_free(name);
 374        }
 375    }
 376    object_initialize_child(obj, "nmi-orgate", &s->nmi_orgate,
 377                            sizeof(s->nmi_orgate), TYPE_OR_IRQ,
 378                            &error_abort, NULL);
 379    object_initialize_child(obj, "ppc-irq-orgate", &s->ppc_irq_orgate,
 380                            sizeof(s->ppc_irq_orgate), TYPE_OR_IRQ,
 381                            &error_abort, NULL);
 382    object_initialize_child(obj, "sec-resp-splitter", &s->sec_resp_splitter,
 383                            sizeof(s->sec_resp_splitter), TYPE_SPLIT_IRQ,
 384                            &error_abort, NULL);
 385    for (i = 0; i < ARRAY_SIZE(s->ppc_irq_splitter); i++) {
 386        char *name = g_strdup_printf("ppc-irq-splitter-%d", i);
 387        SplitIRQ *splitter = &s->ppc_irq_splitter[i];
 388
 389        object_initialize_child(obj, name, splitter, sizeof(*splitter),
 390                                TYPE_SPLIT_IRQ, &error_abort, NULL);
 391        g_free(name);
 392    }
 393    if (info->num_cpus > 1) {
 394        for (i = 0; i < ARRAY_SIZE(s->cpu_irq_splitter); i++) {
 395            if (irq_is_common[i]) {
 396                char *name = g_strdup_printf("cpu-irq-splitter%d", i);
 397                SplitIRQ *splitter = &s->cpu_irq_splitter[i];
 398
 399                object_initialize_child(obj, name, splitter, sizeof(*splitter),
 400                                        TYPE_SPLIT_IRQ, &error_abort, NULL);
 401                g_free(name);
 402            }
 403        }
 404    }
 405}
 406
 407static void armsse_exp_irq(void *opaque, int n, int level)
 408{
 409    qemu_irq *irqarray = opaque;
 410
 411    qemu_set_irq(irqarray[n], level);
 412}
 413
 414static void armsse_mpcexp_status(void *opaque, int n, int level)
 415{
 416    ARMSSE *s = ARMSSE(opaque);
 417    qemu_set_irq(s->mpcexp_status_in[n], level);
 418}
 419
 420static qemu_irq armsse_get_common_irq_in(ARMSSE *s, int irqno)
 421{
 422    /*
 423     * Return a qemu_irq which can be used to signal IRQ n to
 424     * all CPUs in the SSE.
 425     */
 426    ARMSSEClass *asc = ARMSSE_GET_CLASS(s);
 427    const ARMSSEInfo *info = asc->info;
 428
 429    assert(irq_is_common[irqno]);
 430
 431    if (info->num_cpus == 1) {
 432        /* Only one CPU -- just connect directly to it */
 433        return qdev_get_gpio_in(DEVICE(&s->armv7m[0]), irqno);
 434    } else {
 435        /* Connect to the splitter which feeds all CPUs */
 436        return qdev_get_gpio_in(DEVICE(&s->cpu_irq_splitter[irqno]), 0);
 437    }
 438}
 439
 440static void map_ppu(ARMSSE *s, int ppuidx, const char *name, hwaddr addr)
 441{
 442    /* Map a PPU unimplemented device stub */
 443    DeviceState *dev = DEVICE(&s->ppu[ppuidx]);
 444
 445    qdev_prop_set_string(dev, "name", name);
 446    qdev_prop_set_uint64(dev, "size", 0x1000);
 447    qdev_init_nofail(dev);
 448    sysbus_mmio_map(SYS_BUS_DEVICE(&s->ppu[ppuidx]), 0, addr);
 449}
 450
 451static void armsse_realize(DeviceState *dev, Error **errp)
 452{
 453    ARMSSE *s = ARMSSE(dev);
 454    ARMSSEClass *asc = ARMSSE_GET_CLASS(dev);
 455    const ARMSSEInfo *info = asc->info;
 456    int i;
 457    MemoryRegion *mr;
 458    Error *err = NULL;
 459    SysBusDevice *sbd_apb_ppc0;
 460    SysBusDevice *sbd_secctl;
 461    DeviceState *dev_apb_ppc0;
 462    DeviceState *dev_apb_ppc1;
 463    DeviceState *dev_secctl;
 464    DeviceState *dev_splitter;
 465    uint32_t addr_width_max;
 466
 467    if (!s->board_memory) {
 468        error_setg(errp, "memory property was not set");
 469        return;
 470    }
 471
 472    if (!s->mainclk_frq) {
 473        error_setg(errp, "MAINCLK property was not set");
 474        return;
 475    }
 476
 477    /* max SRAM_ADDR_WIDTH: 24 - log2(SRAM_NUM_BANK) */
 478    assert(is_power_of_2(info->sram_banks));
 479    addr_width_max = 24 - ctz32(info->sram_banks);
 480    if (s->sram_addr_width < 1 || s->sram_addr_width > addr_width_max) {
 481        error_setg(errp, "SRAM_ADDR_WIDTH must be between 1 and %d",
 482                   addr_width_max);
 483        return;
 484    }
 485
 486    /* Handling of which devices should be available only to secure
 487     * code is usually done differently for M profile than for A profile.
 488     * Instead of putting some devices only into the secure address space,
 489     * devices exist in both address spaces but with hard-wired security
 490     * permissions that will cause the CPU to fault for non-secure accesses.
 491     *
 492     * The ARMSSE has an IDAU (Implementation Defined Access Unit),
 493     * which specifies hard-wired security permissions for different
 494     * areas of the physical address space. For the ARMSSE IDAU, the
 495     * top 4 bits of the physical address are the IDAU region ID, and
 496     * if bit 28 (ie the lowest bit of the ID) is 0 then this is an NS
 497     * region, otherwise it is an S region.
 498     *
 499     * The various devices and RAMs are generally all mapped twice,
 500     * once into a region that the IDAU defines as secure and once
 501     * into a non-secure region. They sit behind either a Memory
 502     * Protection Controller (for RAM) or a Peripheral Protection
 503     * Controller (for devices), which allow a more fine grained
 504     * configuration of whether non-secure accesses are permitted.
 505     *
 506     * (The other place that guest software can configure security
 507     * permissions is in the architected SAU (Security Attribution
 508     * Unit), which is entirely inside the CPU. The IDAU can upgrade
 509     * the security attributes for a region to more restrictive than
 510     * the SAU specifies, but cannot downgrade them.)
 511     *
 512     * 0x10000000..0x1fffffff  alias of 0x00000000..0x0fffffff
 513     * 0x20000000..0x2007ffff  32KB FPGA block RAM
 514     * 0x30000000..0x3fffffff  alias of 0x20000000..0x2fffffff
 515     * 0x40000000..0x4000ffff  base peripheral region 1
 516     * 0x40010000..0x4001ffff  CPU peripherals (none for ARMSSE)
 517     * 0x40020000..0x4002ffff  system control element peripherals
 518     * 0x40080000..0x400fffff  base peripheral region 2
 519     * 0x50000000..0x5fffffff  alias of 0x40000000..0x4fffffff
 520     */
 521
 522    memory_region_add_subregion_overlap(&s->container, 0, s->board_memory, -2);
 523
 524    for (i = 0; i < info->num_cpus; i++) {
 525        DeviceState *cpudev = DEVICE(&s->armv7m[i]);
 526        Object *cpuobj = OBJECT(&s->armv7m[i]);
 527        int j;
 528        char *gpioname;
 529
 530        qdev_prop_set_uint32(cpudev, "num-irq", s->exp_numirq + 32);
 531        /*
 532         * In real hardware the initial Secure VTOR is set from the INITSVTOR*
 533         * registers in the IoT Kit System Control Register block. In QEMU
 534         * we set the initial value here, and also the reset value of the
 535         * sysctl register, from this object's QOM init-svtor property.
 536         * If the guest changes the INITSVTOR* registers at runtime then the
 537         * code in iotkit-sysctl.c will update the CPU init-svtor property
 538         * (which will then take effect on the next CPU warm-reset).
 539         *
 540         * Note that typically a board using the SSE-200 will have a system
 541         * control processor whose boot firmware initializes the INITSVTOR*
 542         * registers before powering up the CPUs. QEMU doesn't emulate
 543         * the control processor, so instead we behave in the way that the
 544         * firmware does: the initial value should be set by the board code
 545         * (using the init-svtor property on the ARMSSE object) to match
 546         * whatever its firmware does.
 547         */
 548        qdev_prop_set_uint32(cpudev, "init-svtor", s->init_svtor);
 549        /*
 550         * CPUs start powered down if the corresponding bit in the CPUWAIT
 551         * register is 1. In real hardware the CPUWAIT register reset value is
 552         * a configurable property of the SSE-200 (via the CPUWAIT0_RST and
 553         * CPUWAIT1_RST parameters), but since all the boards we care about
 554         * start CPU0 and leave CPU1 powered off, we hard-code that in
 555         * info->cpuwait_rst for now. We can add QOM properties for this
 556         * later if necessary.
 557         */
 558        if (extract32(info->cpuwait_rst, i, 1)) {
 559            object_property_set_bool(cpuobj, true, "start-powered-off", &err);
 560            if (err) {
 561                error_propagate(errp, err);
 562                return;
 563            }
 564        }
 565        if (!s->cpu_fpu[i]) {
 566            object_property_set_bool(cpuobj, false, "vfp", &err);
 567            if (err) {
 568                error_propagate(errp, err);
 569                return;
 570            }
 571        }
 572        if (!s->cpu_dsp[i]) {
 573            object_property_set_bool(cpuobj, false, "dsp", &err);
 574            if (err) {
 575                error_propagate(errp, err);
 576                return;
 577            }
 578        }
 579
 580        if (i > 0) {
 581            memory_region_add_subregion_overlap(&s->cpu_container[i], 0,
 582                                                &s->container_alias[i - 1], -1);
 583        } else {
 584            memory_region_add_subregion_overlap(&s->cpu_container[i], 0,
 585                                                &s->container, -1);
 586        }
 587        object_property_set_link(cpuobj, OBJECT(&s->cpu_container[i]),
 588                                 "memory", &err);
 589        if (err) {
 590            error_propagate(errp, err);
 591            return;
 592        }
 593        object_property_set_link(cpuobj, OBJECT(s), "idau", &err);
 594        if (err) {
 595            error_propagate(errp, err);
 596            return;
 597        }
 598        object_property_set_bool(cpuobj, true, "realized", &err);
 599        if (err) {
 600            error_propagate(errp, err);
 601            return;
 602        }
 603        /*
 604         * The cluster must be realized after the armv7m container, as
 605         * the container's CPU object is only created on realize, and the
 606         * CPU must exist and have been parented into the cluster before
 607         * the cluster is realized.
 608         */
 609        object_property_set_bool(OBJECT(&s->cluster[i]),
 610                                 true, "realized", &err);
 611        if (err) {
 612            error_propagate(errp, err);
 613            return;
 614        }
 615
 616        /* Connect EXP_IRQ/EXP_CPUn_IRQ GPIOs to the NVIC's lines 32 and up */
 617        s->exp_irqs[i] = g_new(qemu_irq, s->exp_numirq);
 618        for (j = 0; j < s->exp_numirq; j++) {
 619            s->exp_irqs[i][j] = qdev_get_gpio_in(cpudev, j + 32);
 620        }
 621        if (i == 0) {
 622            gpioname = g_strdup("EXP_IRQ");
 623        } else {
 624            gpioname = g_strdup_printf("EXP_CPU%d_IRQ", i);
 625        }
 626        qdev_init_gpio_in_named_with_opaque(dev, armsse_exp_irq,
 627                                            s->exp_irqs[i],
 628                                            gpioname, s->exp_numirq);
 629        g_free(gpioname);
 630    }
 631
 632    /* Wire up the splitters that connect common IRQs to all CPUs */
 633    if (info->num_cpus > 1) {
 634        for (i = 0; i < ARRAY_SIZE(s->cpu_irq_splitter); i++) {
 635            if (irq_is_common[i]) {
 636                Object *splitter = OBJECT(&s->cpu_irq_splitter[i]);
 637                DeviceState *devs = DEVICE(splitter);
 638                int cpunum;
 639
 640                object_property_set_int(splitter, info->num_cpus,
 641                                        "num-lines", &err);
 642                if (err) {
 643                    error_propagate(errp, err);
 644                    return;
 645                }
 646                object_property_set_bool(splitter, true, "realized", &err);
 647                if (err) {
 648                    error_propagate(errp, err);
 649                    return;
 650                }
 651                for (cpunum = 0; cpunum < info->num_cpus; cpunum++) {
 652                    DeviceState *cpudev = DEVICE(&s->armv7m[cpunum]);
 653
 654                    qdev_connect_gpio_out(devs, cpunum,
 655                                          qdev_get_gpio_in(cpudev, i));
 656                }
 657            }
 658        }
 659    }
 660
 661    /* Set up the big aliases first */
 662    make_alias(s, &s->alias1, &s->container, "alias 1",
 663               0x10000000, 0x10000000, 0x00000000);
 664    make_alias(s, &s->alias2, &s->container,
 665               "alias 2", 0x30000000, 0x10000000, 0x20000000);
 666    /* The 0x50000000..0x5fffffff region is not a pure alias: it has
 667     * a few extra devices that only appear there (generally the
 668     * control interfaces for the protection controllers).
 669     * We implement this by mapping those devices over the top of this
 670     * alias MR at a higher priority. Some of the devices in this range
 671     * are per-CPU, so we must put this alias in the per-cpu containers.
 672     */
 673    for (i = 0; i < info->num_cpus; i++) {
 674        make_alias(s, &s->alias3[i], &s->cpu_container[i],
 675                   "alias 3", 0x50000000, 0x10000000, 0x40000000);
 676    }
 677
 678    /* Security controller */
 679    object_property_set_bool(OBJECT(&s->secctl), true, "realized", &err);
 680    if (err) {
 681        error_propagate(errp, err);
 682        return;
 683    }
 684    sbd_secctl = SYS_BUS_DEVICE(&s->secctl);
 685    dev_secctl = DEVICE(&s->secctl);
 686    sysbus_mmio_map(sbd_secctl, 0, 0x50080000);
 687    sysbus_mmio_map(sbd_secctl, 1, 0x40080000);
 688
 689    s->nsc_cfg_in = qemu_allocate_irq(nsccfg_handler, s, 1);
 690    qdev_connect_gpio_out_named(dev_secctl, "nsc_cfg", 0, s->nsc_cfg_in);
 691
 692    /* The sec_resp_cfg output from the security controller must be split into
 693     * multiple lines, one for each of the PPCs within the ARMSSE and one
 694     * that will be an output from the ARMSSE to the system.
 695     */
 696    object_property_set_int(OBJECT(&s->sec_resp_splitter), 3,
 697                            "num-lines", &err);
 698    if (err) {
 699        error_propagate(errp, err);
 700        return;
 701    }
 702    object_property_set_bool(OBJECT(&s->sec_resp_splitter), true,
 703                             "realized", &err);
 704    if (err) {
 705        error_propagate(errp, err);
 706        return;
 707    }
 708    dev_splitter = DEVICE(&s->sec_resp_splitter);
 709    qdev_connect_gpio_out_named(dev_secctl, "sec_resp_cfg", 0,
 710                                qdev_get_gpio_in(dev_splitter, 0));
 711
 712    /* Each SRAM bank lives behind its own Memory Protection Controller */
 713    for (i = 0; i < info->sram_banks; i++) {
 714        char *ramname = g_strdup_printf("armsse.sram%d", i);
 715        SysBusDevice *sbd_mpc;
 716        uint32_t sram_bank_size = 1 << s->sram_addr_width;
 717
 718        memory_region_init_ram(&s->sram[i], NULL, ramname,
 719                               sram_bank_size, &err);
 720        g_free(ramname);
 721        if (err) {
 722            error_propagate(errp, err);
 723            return;
 724        }
 725        object_property_set_link(OBJECT(&s->mpc[i]), OBJECT(&s->sram[i]),
 726                                 "downstream", &err);
 727        if (err) {
 728            error_propagate(errp, err);
 729            return;
 730        }
 731        object_property_set_bool(OBJECT(&s->mpc[i]), true, "realized", &err);
 732        if (err) {
 733            error_propagate(errp, err);
 734            return;
 735        }
 736        /* Map the upstream end of the MPC into the right place... */
 737        sbd_mpc = SYS_BUS_DEVICE(&s->mpc[i]);
 738        memory_region_add_subregion(&s->container,
 739                                    0x20000000 + i * sram_bank_size,
 740                                    sysbus_mmio_get_region(sbd_mpc, 1));
 741        /* ...and its register interface */
 742        memory_region_add_subregion(&s->container, 0x50083000 + i * 0x1000,
 743                                    sysbus_mmio_get_region(sbd_mpc, 0));
 744    }
 745
 746    /* We must OR together lines from the MPC splitters to go to the NVIC */
 747    object_property_set_int(OBJECT(&s->mpc_irq_orgate),
 748                            IOTS_NUM_EXP_MPC + info->sram_banks,
 749                            "num-lines", &err);
 750    if (err) {
 751        error_propagate(errp, err);
 752        return;
 753    }
 754    object_property_set_bool(OBJECT(&s->mpc_irq_orgate), true,
 755                             "realized", &err);
 756    if (err) {
 757        error_propagate(errp, err);
 758        return;
 759    }
 760    qdev_connect_gpio_out(DEVICE(&s->mpc_irq_orgate), 0,
 761                          armsse_get_common_irq_in(s, 9));
 762
 763    /* Devices behind APB PPC0:
 764     *   0x40000000: timer0
 765     *   0x40001000: timer1
 766     *   0x40002000: dual timer
 767     *   0x40003000: MHU0 (SSE-200 only)
 768     *   0x40004000: MHU1 (SSE-200 only)
 769     * We must configure and realize each downstream device and connect
 770     * it to the appropriate PPC port; then we can realize the PPC and
 771     * map its upstream ends to the right place in the container.
 772     */
 773    qdev_prop_set_uint32(DEVICE(&s->timer0), "pclk-frq", s->mainclk_frq);
 774    object_property_set_bool(OBJECT(&s->timer0), true, "realized", &err);
 775    if (err) {
 776        error_propagate(errp, err);
 777        return;
 778    }
 779    sysbus_connect_irq(SYS_BUS_DEVICE(&s->timer0), 0,
 780                       armsse_get_common_irq_in(s, 3));
 781    mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->timer0), 0);
 782    object_property_set_link(OBJECT(&s->apb_ppc0), OBJECT(mr), "port[0]", &err);
 783    if (err) {
 784        error_propagate(errp, err);
 785        return;
 786    }
 787
 788    qdev_prop_set_uint32(DEVICE(&s->timer1), "pclk-frq", s->mainclk_frq);
 789    object_property_set_bool(OBJECT(&s->timer1), true, "realized", &err);
 790    if (err) {
 791        error_propagate(errp, err);
 792        return;
 793    }
 794    sysbus_connect_irq(SYS_BUS_DEVICE(&s->timer1), 0,
 795                       armsse_get_common_irq_in(s, 4));
 796    mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->timer1), 0);
 797    object_property_set_link(OBJECT(&s->apb_ppc0), OBJECT(mr), "port[1]", &err);
 798    if (err) {
 799        error_propagate(errp, err);
 800        return;
 801    }
 802
 803
 804    qdev_prop_set_uint32(DEVICE(&s->dualtimer), "pclk-frq", s->mainclk_frq);
 805    object_property_set_bool(OBJECT(&s->dualtimer), true, "realized", &err);
 806    if (err) {
 807        error_propagate(errp, err);
 808        return;
 809    }
 810    sysbus_connect_irq(SYS_BUS_DEVICE(&s->dualtimer), 0,
 811                       armsse_get_common_irq_in(s, 5));
 812    mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->dualtimer), 0);
 813    object_property_set_link(OBJECT(&s->apb_ppc0), OBJECT(mr), "port[2]", &err);
 814    if (err) {
 815        error_propagate(errp, err);
 816        return;
 817    }
 818
 819    if (info->has_mhus) {
 820        /*
 821         * An SSE-200 with only one CPU should have only one MHU created,
 822         * with the region where the second MHU usually is being RAZ/WI.
 823         * We don't implement that SSE-200 config; if we want to support
 824         * it then this code needs to be enhanced to handle creating the
 825         * RAZ/WI region instead of the second MHU.
 826         */
 827        assert(info->num_cpus == ARRAY_SIZE(s->mhu));
 828
 829        for (i = 0; i < ARRAY_SIZE(s->mhu); i++) {
 830            char *port;
 831            int cpunum;
 832            SysBusDevice *mhu_sbd = SYS_BUS_DEVICE(&s->mhu[i]);
 833
 834            object_property_set_bool(OBJECT(&s->mhu[i]), true,
 835                                     "realized", &err);
 836            if (err) {
 837                error_propagate(errp, err);
 838                return;
 839            }
 840            port = g_strdup_printf("port[%d]", i + 3);
 841            mr = sysbus_mmio_get_region(mhu_sbd, 0);
 842            object_property_set_link(OBJECT(&s->apb_ppc0), OBJECT(mr),
 843                                     port, &err);
 844            g_free(port);
 845            if (err) {
 846                error_propagate(errp, err);
 847                return;
 848            }
 849
 850            /*
 851             * Each MHU has an irq line for each CPU:
 852             *  MHU 0 irq line 0 -> CPU 0 IRQ 6
 853             *  MHU 0 irq line 1 -> CPU 1 IRQ 6
 854             *  MHU 1 irq line 0 -> CPU 0 IRQ 7
 855             *  MHU 1 irq line 1 -> CPU 1 IRQ 7
 856             */
 857            for (cpunum = 0; cpunum < info->num_cpus; cpunum++) {
 858                DeviceState *cpudev = DEVICE(&s->armv7m[cpunum]);
 859
 860                sysbus_connect_irq(mhu_sbd, cpunum,
 861                                   qdev_get_gpio_in(cpudev, 6 + i));
 862            }
 863        }
 864    }
 865
 866    object_property_set_bool(OBJECT(&s->apb_ppc0), true, "realized", &err);
 867    if (err) {
 868        error_propagate(errp, err);
 869        return;
 870    }
 871
 872    sbd_apb_ppc0 = SYS_BUS_DEVICE(&s->apb_ppc0);
 873    dev_apb_ppc0 = DEVICE(&s->apb_ppc0);
 874
 875    mr = sysbus_mmio_get_region(sbd_apb_ppc0, 0);
 876    memory_region_add_subregion(&s->container, 0x40000000, mr);
 877    mr = sysbus_mmio_get_region(sbd_apb_ppc0, 1);
 878    memory_region_add_subregion(&s->container, 0x40001000, mr);
 879    mr = sysbus_mmio_get_region(sbd_apb_ppc0, 2);
 880    memory_region_add_subregion(&s->container, 0x40002000, mr);
 881    if (info->has_mhus) {
 882        mr = sysbus_mmio_get_region(sbd_apb_ppc0, 3);
 883        memory_region_add_subregion(&s->container, 0x40003000, mr);
 884        mr = sysbus_mmio_get_region(sbd_apb_ppc0, 4);
 885        memory_region_add_subregion(&s->container, 0x40004000, mr);
 886    }
 887    for (i = 0; i < IOTS_APB_PPC0_NUM_PORTS; i++) {
 888        qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_nonsec", i,
 889                                    qdev_get_gpio_in_named(dev_apb_ppc0,
 890                                                           "cfg_nonsec", i));
 891        qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_ap", i,
 892                                    qdev_get_gpio_in_named(dev_apb_ppc0,
 893                                                           "cfg_ap", i));
 894    }
 895    qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_irq_enable", 0,
 896                                qdev_get_gpio_in_named(dev_apb_ppc0,
 897                                                       "irq_enable", 0));
 898    qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_irq_clear", 0,
 899                                qdev_get_gpio_in_named(dev_apb_ppc0,
 900                                                       "irq_clear", 0));
 901    qdev_connect_gpio_out(dev_splitter, 0,
 902                          qdev_get_gpio_in_named(dev_apb_ppc0,
 903                                                 "cfg_sec_resp", 0));
 904
 905    /* All the PPC irq lines (from the 2 internal PPCs and the 8 external
 906     * ones) are sent individually to the security controller, and also
 907     * ORed together to give a single combined PPC interrupt to the NVIC.
 908     */
 909    object_property_set_int(OBJECT(&s->ppc_irq_orgate),
 910                            NUM_PPCS, "num-lines", &err);
 911    if (err) {
 912        error_propagate(errp, err);
 913        return;
 914    }
 915    object_property_set_bool(OBJECT(&s->ppc_irq_orgate), true,
 916                             "realized", &err);
 917    if (err) {
 918        error_propagate(errp, err);
 919        return;
 920    }
 921    qdev_connect_gpio_out(DEVICE(&s->ppc_irq_orgate), 0,
 922                          armsse_get_common_irq_in(s, 10));
 923
 924    /*
 925     * 0x40010000 .. 0x4001ffff (and the 0x5001000... secure-only alias):
 926     * private per-CPU region (all these devices are SSE-200 only):
 927     *  0x50010000: L1 icache control registers
 928     *  0x50011000: CPUSECCTRL (CPU local security control registers)
 929     *  0x4001f000 and 0x5001f000: CPU_IDENTITY register block
 930     */
 931    if (info->has_cachectrl) {
 932        for (i = 0; i < info->num_cpus; i++) {
 933            char *name = g_strdup_printf("cachectrl%d", i);
 934            MemoryRegion *mr;
 935
 936            qdev_prop_set_string(DEVICE(&s->cachectrl[i]), "name", name);
 937            g_free(name);
 938            qdev_prop_set_uint64(DEVICE(&s->cachectrl[i]), "size", 0x1000);
 939            object_property_set_bool(OBJECT(&s->cachectrl[i]), true,
 940                                     "realized", &err);
 941            if (err) {
 942                error_propagate(errp, err);
 943                return;
 944            }
 945
 946            mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->cachectrl[i]), 0);
 947            memory_region_add_subregion(&s->cpu_container[i], 0x50010000, mr);
 948        }
 949    }
 950    if (info->has_cpusecctrl) {
 951        for (i = 0; i < info->num_cpus; i++) {
 952            char *name = g_strdup_printf("CPUSECCTRL%d", i);
 953            MemoryRegion *mr;
 954
 955            qdev_prop_set_string(DEVICE(&s->cpusecctrl[i]), "name", name);
 956            g_free(name);
 957            qdev_prop_set_uint64(DEVICE(&s->cpusecctrl[i]), "size", 0x1000);
 958            object_property_set_bool(OBJECT(&s->cpusecctrl[i]), true,
 959                                     "realized", &err);
 960            if (err) {
 961                error_propagate(errp, err);
 962                return;
 963            }
 964
 965            mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->cpusecctrl[i]), 0);
 966            memory_region_add_subregion(&s->cpu_container[i], 0x50011000, mr);
 967        }
 968    }
 969    if (info->has_cpuid) {
 970        for (i = 0; i < info->num_cpus; i++) {
 971            MemoryRegion *mr;
 972
 973            qdev_prop_set_uint32(DEVICE(&s->cpuid[i]), "CPUID", i);
 974            object_property_set_bool(OBJECT(&s->cpuid[i]), true,
 975                                     "realized", &err);
 976            if (err) {
 977                error_propagate(errp, err);
 978                return;
 979            }
 980
 981            mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->cpuid[i]), 0);
 982            memory_region_add_subregion(&s->cpu_container[i], 0x4001F000, mr);
 983        }
 984    }
 985
 986    /* 0x40020000 .. 0x4002ffff : ARMSSE system control peripheral region */
 987    /* Devices behind APB PPC1:
 988     *   0x4002f000: S32K timer
 989     */
 990    qdev_prop_set_uint32(DEVICE(&s->s32ktimer), "pclk-frq", S32KCLK);
 991    object_property_set_bool(OBJECT(&s->s32ktimer), true, "realized", &err);
 992    if (err) {
 993        error_propagate(errp, err);
 994        return;
 995    }
 996    sysbus_connect_irq(SYS_BUS_DEVICE(&s->s32ktimer), 0,
 997                       armsse_get_common_irq_in(s, 2));
 998    mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->s32ktimer), 0);
 999    object_property_set_link(OBJECT(&s->apb_ppc1), OBJECT(mr), "port[0]", &err);
1000    if (err) {
1001        error_propagate(errp, err);
1002        return;
1003    }
1004
1005    object_property_set_bool(OBJECT(&s->apb_ppc1), true, "realized", &err);
1006    if (err) {
1007        error_propagate(errp, err);
1008        return;
1009    }
1010    mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->apb_ppc1), 0);
1011    memory_region_add_subregion(&s->container, 0x4002f000, mr);
1012
1013    dev_apb_ppc1 = DEVICE(&s->apb_ppc1);
1014    qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_nonsec", 0,
1015                                qdev_get_gpio_in_named(dev_apb_ppc1,
1016                                                       "cfg_nonsec", 0));
1017    qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_ap", 0,
1018                                qdev_get_gpio_in_named(dev_apb_ppc1,
1019                                                       "cfg_ap", 0));
1020    qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_irq_enable", 0,
1021                                qdev_get_gpio_in_named(dev_apb_ppc1,
1022                                                       "irq_enable", 0));
1023    qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_irq_clear", 0,
1024                                qdev_get_gpio_in_named(dev_apb_ppc1,
1025                                                       "irq_clear", 0));
1026    qdev_connect_gpio_out(dev_splitter, 1,
1027                          qdev_get_gpio_in_named(dev_apb_ppc1,
1028                                                 "cfg_sec_resp", 0));
1029
1030    object_property_set_int(OBJECT(&s->sysinfo), info->sys_version,
1031                            "SYS_VERSION", &err);
1032    if (err) {
1033        error_propagate(errp, err);
1034        return;
1035    }
1036    object_property_set_int(OBJECT(&s->sysinfo),
1037                            armsse_sys_config_value(s, info),
1038                            "SYS_CONFIG", &err);
1039    if (err) {
1040        error_propagate(errp, err);
1041        return;
1042    }
1043    object_property_set_bool(OBJECT(&s->sysinfo), true, "realized", &err);
1044    if (err) {
1045        error_propagate(errp, err);
1046        return;
1047    }
1048    /* System information registers */
1049    sysbus_mmio_map(SYS_BUS_DEVICE(&s->sysinfo), 0, 0x40020000);
1050    /* System control registers */
1051    object_property_set_int(OBJECT(&s->sysctl), info->sys_version,
1052                            "SYS_VERSION", &err);
1053    object_property_set_int(OBJECT(&s->sysctl), info->cpuwait_rst,
1054                            "CPUWAIT_RST", &err);
1055    object_property_set_int(OBJECT(&s->sysctl), s->init_svtor,
1056                            "INITSVTOR0_RST", &err);
1057    object_property_set_int(OBJECT(&s->sysctl), s->init_svtor,
1058                            "INITSVTOR1_RST", &err);
1059    object_property_set_bool(OBJECT(&s->sysctl), true, "realized", &err);
1060    if (err) {
1061        error_propagate(errp, err);
1062        return;
1063    }
1064    sysbus_mmio_map(SYS_BUS_DEVICE(&s->sysctl), 0, 0x50021000);
1065
1066    if (info->has_ppus) {
1067        /* CPUnCORE_PPU for each CPU */
1068        for (i = 0; i < info->num_cpus; i++) {
1069            char *name = g_strdup_printf("CPU%dCORE_PPU", i);
1070
1071            map_ppu(s, CPU0CORE_PPU + i, name, 0x50023000 + i * 0x2000);
1072            /*
1073             * We don't support CPU debug so don't create the
1074             * CPU0DEBUG_PPU at 0x50024000 and 0x50026000.
1075             */
1076            g_free(name);
1077        }
1078        map_ppu(s, DBG_PPU, "DBG_PPU", 0x50029000);
1079
1080        for (i = 0; i < info->sram_banks; i++) {
1081            char *name = g_strdup_printf("RAM%d_PPU", i);
1082
1083            map_ppu(s, RAM0_PPU + i, name, 0x5002a000 + i * 0x1000);
1084            g_free(name);
1085        }
1086    }
1087
1088    /* This OR gate wires together outputs from the secure watchdogs to NMI */
1089    object_property_set_int(OBJECT(&s->nmi_orgate), 2, "num-lines", &err);
1090    if (err) {
1091        error_propagate(errp, err);
1092        return;
1093    }
1094    object_property_set_bool(OBJECT(&s->nmi_orgate), true, "realized", &err);
1095    if (err) {
1096        error_propagate(errp, err);
1097        return;
1098    }
1099    qdev_connect_gpio_out(DEVICE(&s->nmi_orgate), 0,
1100                          qdev_get_gpio_in_named(DEVICE(&s->armv7m), "NMI", 0));
1101
1102    qdev_prop_set_uint32(DEVICE(&s->s32kwatchdog), "wdogclk-frq", S32KCLK);
1103    object_property_set_bool(OBJECT(&s->s32kwatchdog), true, "realized", &err);
1104    if (err) {
1105        error_propagate(errp, err);
1106        return;
1107    }
1108    sysbus_connect_irq(SYS_BUS_DEVICE(&s->s32kwatchdog), 0,
1109                       qdev_get_gpio_in(DEVICE(&s->nmi_orgate), 0));
1110    sysbus_mmio_map(SYS_BUS_DEVICE(&s->s32kwatchdog), 0, 0x5002e000);
1111
1112    /* 0x40080000 .. 0x4008ffff : ARMSSE second Base peripheral region */
1113
1114    qdev_prop_set_uint32(DEVICE(&s->nswatchdog), "wdogclk-frq", s->mainclk_frq);
1115    object_property_set_bool(OBJECT(&s->nswatchdog), true, "realized", &err);
1116    if (err) {
1117        error_propagate(errp, err);
1118        return;
1119    }
1120    sysbus_connect_irq(SYS_BUS_DEVICE(&s->nswatchdog), 0,
1121                       armsse_get_common_irq_in(s, 1));
1122    sysbus_mmio_map(SYS_BUS_DEVICE(&s->nswatchdog), 0, 0x40081000);
1123
1124    qdev_prop_set_uint32(DEVICE(&s->swatchdog), "wdogclk-frq", s->mainclk_frq);
1125    object_property_set_bool(OBJECT(&s->swatchdog), true, "realized", &err);
1126    if (err) {
1127        error_propagate(errp, err);
1128        return;
1129    }
1130    sysbus_connect_irq(SYS_BUS_DEVICE(&s->swatchdog), 0,
1131                       qdev_get_gpio_in(DEVICE(&s->nmi_orgate), 1));
1132    sysbus_mmio_map(SYS_BUS_DEVICE(&s->swatchdog), 0, 0x50081000);
1133
1134    for (i = 0; i < ARRAY_SIZE(s->ppc_irq_splitter); i++) {
1135        Object *splitter = OBJECT(&s->ppc_irq_splitter[i]);
1136
1137        object_property_set_int(splitter, 2, "num-lines", &err);
1138        if (err) {
1139            error_propagate(errp, err);
1140            return;
1141        }
1142        object_property_set_bool(splitter, true, "realized", &err);
1143        if (err) {
1144            error_propagate(errp, err);
1145            return;
1146        }
1147    }
1148
1149    for (i = 0; i < IOTS_NUM_AHB_EXP_PPC; i++) {
1150        char *ppcname = g_strdup_printf("ahb_ppcexp%d", i);
1151
1152        armsse_forward_ppc(s, ppcname, i);
1153        g_free(ppcname);
1154    }
1155
1156    for (i = 0; i < IOTS_NUM_APB_EXP_PPC; i++) {
1157        char *ppcname = g_strdup_printf("apb_ppcexp%d", i);
1158
1159        armsse_forward_ppc(s, ppcname, i + IOTS_NUM_AHB_EXP_PPC);
1160        g_free(ppcname);
1161    }
1162
1163    for (i = NUM_EXTERNAL_PPCS; i < NUM_PPCS; i++) {
1164        /* Wire up IRQ splitter for internal PPCs */
1165        DeviceState *devs = DEVICE(&s->ppc_irq_splitter[i]);
1166        char *gpioname = g_strdup_printf("apb_ppc%d_irq_status",
1167                                         i - NUM_EXTERNAL_PPCS);
1168        TZPPC *ppc = (i == NUM_EXTERNAL_PPCS) ? &s->apb_ppc0 : &s->apb_ppc1;
1169
1170        qdev_connect_gpio_out(devs, 0,
1171                              qdev_get_gpio_in_named(dev_secctl, gpioname, 0));
1172        qdev_connect_gpio_out(devs, 1,
1173                              qdev_get_gpio_in(DEVICE(&s->ppc_irq_orgate), i));
1174        qdev_connect_gpio_out_named(DEVICE(ppc), "irq", 0,
1175                                    qdev_get_gpio_in(devs, 0));
1176        g_free(gpioname);
1177    }
1178
1179    /* Wire up the splitters for the MPC IRQs */
1180    for (i = 0; i < IOTS_NUM_EXP_MPC + info->sram_banks; i++) {
1181        SplitIRQ *splitter = &s->mpc_irq_splitter[i];
1182        DeviceState *dev_splitter = DEVICE(splitter);
1183
1184        object_property_set_int(OBJECT(splitter), 2, "num-lines", &err);
1185        if (err) {
1186            error_propagate(errp, err);
1187            return;
1188        }
1189        object_property_set_bool(OBJECT(splitter), true, "realized", &err);
1190        if (err) {
1191            error_propagate(errp, err);
1192            return;
1193        }
1194
1195        if (i < IOTS_NUM_EXP_MPC) {
1196            /* Splitter input is from GPIO input line */
1197            s->mpcexp_status_in[i] = qdev_get_gpio_in(dev_splitter, 0);
1198            qdev_connect_gpio_out(dev_splitter, 0,
1199                                  qdev_get_gpio_in_named(dev_secctl,
1200                                                         "mpcexp_status", i));
1201        } else {
1202            /* Splitter input is from our own MPC */
1203            qdev_connect_gpio_out_named(DEVICE(&s->mpc[i - IOTS_NUM_EXP_MPC]),
1204                                        "irq", 0,
1205                                        qdev_get_gpio_in(dev_splitter, 0));
1206            qdev_connect_gpio_out(dev_splitter, 0,
1207                                  qdev_get_gpio_in_named(dev_secctl,
1208                                                         "mpc_status", 0));
1209        }
1210
1211        qdev_connect_gpio_out(dev_splitter, 1,
1212                              qdev_get_gpio_in(DEVICE(&s->mpc_irq_orgate), i));
1213    }
1214    /* Create GPIO inputs which will pass the line state for our
1215     * mpcexp_irq inputs to the correct splitter devices.
1216     */
1217    qdev_init_gpio_in_named(dev, armsse_mpcexp_status, "mpcexp_status",
1218                            IOTS_NUM_EXP_MPC);
1219
1220    armsse_forward_sec_resp_cfg(s);
1221
1222    /* Forward the MSC related signals */
1223    qdev_pass_gpios(dev_secctl, dev, "mscexp_status");
1224    qdev_pass_gpios(dev_secctl, dev, "mscexp_clear");
1225    qdev_pass_gpios(dev_secctl, dev, "mscexp_ns");
1226    qdev_connect_gpio_out_named(dev_secctl, "msc_irq", 0,
1227                                armsse_get_common_irq_in(s, 11));
1228
1229    /*
1230     * Expose our container region to the board model; this corresponds
1231     * to the AHB Slave Expansion ports which allow bus master devices
1232     * (eg DMA controllers) in the board model to make transactions into
1233     * devices in the ARMSSE.
1234     */
1235    sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->container);
1236
1237    system_clock_scale = NANOSECONDS_PER_SECOND / s->mainclk_frq;
1238}
1239
1240static void armsse_idau_check(IDAUInterface *ii, uint32_t address,
1241                              int *iregion, bool *exempt, bool *ns, bool *nsc)
1242{
1243    /*
1244     * For ARMSSE systems the IDAU responses are simple logical functions
1245     * of the address bits. The NSC attribute is guest-adjustable via the
1246     * NSCCFG register in the security controller.
1247     */
1248    ARMSSE *s = ARMSSE(ii);
1249    int region = extract32(address, 28, 4);
1250
1251    *ns = !(region & 1);
1252    *nsc = (region == 1 && (s->nsccfg & 1)) || (region == 3 && (s->nsccfg & 2));
1253    /* 0xe0000000..0xe00fffff and 0xf0000000..0xf00fffff are exempt */
1254    *exempt = (address & 0xeff00000) == 0xe0000000;
1255    *iregion = region;
1256}
1257
1258static const VMStateDescription armsse_vmstate = {
1259    .name = "iotkit",
1260    .version_id = 1,
1261    .minimum_version_id = 1,
1262    .fields = (VMStateField[]) {
1263        VMSTATE_UINT32(nsccfg, ARMSSE),
1264        VMSTATE_END_OF_LIST()
1265    }
1266};
1267
1268static void armsse_reset(DeviceState *dev)
1269{
1270    ARMSSE *s = ARMSSE(dev);
1271
1272    s->nsccfg = 0;
1273}
1274
1275static void armsse_class_init(ObjectClass *klass, void *data)
1276{
1277    DeviceClass *dc = DEVICE_CLASS(klass);
1278    IDAUInterfaceClass *iic = IDAU_INTERFACE_CLASS(klass);
1279    ARMSSEClass *asc = ARMSSE_CLASS(klass);
1280    const ARMSSEInfo *info = data;
1281
1282    dc->realize = armsse_realize;
1283    dc->vmsd = &armsse_vmstate;
1284    dc->props = info->props;
1285    dc->reset = armsse_reset;
1286    iic->check = armsse_idau_check;
1287    asc->info = info;
1288}
1289
1290static const TypeInfo armsse_info = {
1291    .name = TYPE_ARMSSE,
1292    .parent = TYPE_SYS_BUS_DEVICE,
1293    .instance_size = sizeof(ARMSSE),
1294    .instance_init = armsse_init,
1295    .abstract = true,
1296    .interfaces = (InterfaceInfo[]) {
1297        { TYPE_IDAU_INTERFACE },
1298        { }
1299    }
1300};
1301
1302static void armsse_register_types(void)
1303{
1304    int i;
1305
1306    type_register_static(&armsse_info);
1307
1308    for (i = 0; i < ARRAY_SIZE(armsse_variants); i++) {
1309        TypeInfo ti = {
1310            .name = armsse_variants[i].name,
1311            .parent = TYPE_ARMSSE,
1312            .class_init = armsse_class_init,
1313            .class_data = (void *)&armsse_variants[i],
1314        };
1315        type_register(&ti);
1316    }
1317}
1318
1319type_init(armsse_register_types);
1320