qemu/hw/misc/iotkit-sysctl.c
<<
>>
Prefs
   1/*
   2 * ARM IoTKit system control element
   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/*
  13 * This is a model of the "system control element" which is part of the
  14 * Arm IoTKit and documented in
  15 * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
  16 * Specifically, it implements the "system control register" blocks.
  17 */
  18
  19#include "qemu/osdep.h"
  20#include "qemu/bitops.h"
  21#include "qemu/log.h"
  22#include "qemu/module.h"
  23#include "trace.h"
  24#include "qapi/error.h"
  25#include "sysemu/sysemu.h"
  26#include "hw/sysbus.h"
  27#include "hw/registerfields.h"
  28#include "hw/misc/iotkit-sysctl.h"
  29#include "target/arm/arm-powerctl.h"
  30#include "target/arm/cpu.h"
  31
  32REG32(SECDBGSTAT, 0x0)
  33REG32(SECDBGSET, 0x4)
  34REG32(SECDBGCLR, 0x8)
  35REG32(SCSECCTRL, 0xc)
  36REG32(FCLK_DIV, 0x10)
  37REG32(SYSCLK_DIV, 0x14)
  38REG32(CLOCK_FORCE, 0x18)
  39REG32(RESET_SYNDROME, 0x100)
  40REG32(RESET_MASK, 0x104)
  41REG32(SWRESET, 0x108)
  42    FIELD(SWRESET, SWRESETREQ, 9, 1)
  43REG32(GRETREG, 0x10c)
  44REG32(INITSVTOR0, 0x110)
  45REG32(INITSVTOR1, 0x114)
  46REG32(CPUWAIT, 0x118)
  47REG32(NMI_ENABLE, 0x11c) /* BUSWAIT in IoTKit */
  48REG32(WICCTRL, 0x120)
  49REG32(EWCTRL, 0x124)
  50REG32(PDCM_PD_SYS_SENSE, 0x200)
  51REG32(PDCM_PD_SRAM0_SENSE, 0x20c)
  52REG32(PDCM_PD_SRAM1_SENSE, 0x210)
  53REG32(PDCM_PD_SRAM2_SENSE, 0x214)
  54REG32(PDCM_PD_SRAM3_SENSE, 0x218)
  55REG32(PID4, 0xfd0)
  56REG32(PID5, 0xfd4)
  57REG32(PID6, 0xfd8)
  58REG32(PID7, 0xfdc)
  59REG32(PID0, 0xfe0)
  60REG32(PID1, 0xfe4)
  61REG32(PID2, 0xfe8)
  62REG32(PID3, 0xfec)
  63REG32(CID0, 0xff0)
  64REG32(CID1, 0xff4)
  65REG32(CID2, 0xff8)
  66REG32(CID3, 0xffc)
  67
  68/* PID/CID values */
  69static const int sysctl_id[] = {
  70    0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
  71    0x54, 0xb8, 0x0b, 0x00, /* PID0..PID3 */
  72    0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
  73};
  74
  75/*
  76 * Set the initial secure vector table offset address for the core.
  77 * This will take effect when the CPU next resets.
  78 */
  79static void set_init_vtor(uint64_t cpuid, uint32_t vtor)
  80{
  81    Object *cpuobj = OBJECT(arm_get_cpu_by_id(cpuid));
  82
  83    if (cpuobj) {
  84        if (object_property_find(cpuobj, "init-svtor", NULL)) {
  85            object_property_set_uint(cpuobj, vtor, "init-svtor", &error_abort);
  86        }
  87    }
  88}
  89
  90static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
  91                                    unsigned size)
  92{
  93    IoTKitSysCtl *s = IOTKIT_SYSCTL(opaque);
  94    uint64_t r;
  95
  96    switch (offset) {
  97    case A_SECDBGSTAT:
  98        r = s->secure_debug;
  99        break;
 100    case A_SCSECCTRL:
 101        if (!s->is_sse200) {
 102            goto bad_offset;
 103        }
 104        r = s->scsecctrl;
 105        break;
 106    case A_FCLK_DIV:
 107        if (!s->is_sse200) {
 108            goto bad_offset;
 109        }
 110        r = s->fclk_div;
 111        break;
 112    case A_SYSCLK_DIV:
 113        if (!s->is_sse200) {
 114            goto bad_offset;
 115        }
 116        r = s->sysclk_div;
 117        break;
 118    case A_CLOCK_FORCE:
 119        if (!s->is_sse200) {
 120            goto bad_offset;
 121        }
 122        r = s->clock_force;
 123        break;
 124    case A_RESET_SYNDROME:
 125        r = s->reset_syndrome;
 126        break;
 127    case A_RESET_MASK:
 128        r = s->reset_mask;
 129        break;
 130    case A_GRETREG:
 131        r = s->gretreg;
 132        break;
 133    case A_INITSVTOR0:
 134        r = s->initsvtor0;
 135        break;
 136    case A_INITSVTOR1:
 137        if (!s->is_sse200) {
 138            goto bad_offset;
 139        }
 140        r = s->initsvtor1;
 141        break;
 142    case A_CPUWAIT:
 143        r = s->cpuwait;
 144        break;
 145    case A_NMI_ENABLE:
 146        /* In IoTKit this is named BUSWAIT but is marked reserved, R/O, zero */
 147        if (!s->is_sse200) {
 148            r = 0;
 149            break;
 150        }
 151        r = s->nmi_enable;
 152        break;
 153    case A_WICCTRL:
 154        r = s->wicctrl;
 155        break;
 156    case A_EWCTRL:
 157        if (!s->is_sse200) {
 158            goto bad_offset;
 159        }
 160        r = s->ewctrl;
 161        break;
 162    case A_PDCM_PD_SYS_SENSE:
 163        if (!s->is_sse200) {
 164            goto bad_offset;
 165        }
 166        r = s->pdcm_pd_sys_sense;
 167        break;
 168    case A_PDCM_PD_SRAM0_SENSE:
 169        if (!s->is_sse200) {
 170            goto bad_offset;
 171        }
 172        r = s->pdcm_pd_sram0_sense;
 173        break;
 174    case A_PDCM_PD_SRAM1_SENSE:
 175        if (!s->is_sse200) {
 176            goto bad_offset;
 177        }
 178        r = s->pdcm_pd_sram1_sense;
 179        break;
 180    case A_PDCM_PD_SRAM2_SENSE:
 181        if (!s->is_sse200) {
 182            goto bad_offset;
 183        }
 184        r = s->pdcm_pd_sram2_sense;
 185        break;
 186    case A_PDCM_PD_SRAM3_SENSE:
 187        if (!s->is_sse200) {
 188            goto bad_offset;
 189        }
 190        r = s->pdcm_pd_sram3_sense;
 191        break;
 192    case A_PID4 ... A_CID3:
 193        r = sysctl_id[(offset - A_PID4) / 4];
 194        break;
 195    case A_SECDBGSET:
 196    case A_SECDBGCLR:
 197    case A_SWRESET:
 198        qemu_log_mask(LOG_GUEST_ERROR,
 199                      "IoTKit SysCtl read: read of WO offset %x\n",
 200                      (int)offset);
 201        r = 0;
 202        break;
 203    default:
 204    bad_offset:
 205        qemu_log_mask(LOG_GUEST_ERROR,
 206                      "IoTKit SysCtl read: bad offset %x\n", (int)offset);
 207        r = 0;
 208        break;
 209    }
 210    trace_iotkit_sysctl_read(offset, r, size);
 211    return r;
 212}
 213
 214static void iotkit_sysctl_write(void *opaque, hwaddr offset,
 215                                 uint64_t value, unsigned size)
 216{
 217    IoTKitSysCtl *s = IOTKIT_SYSCTL(opaque);
 218
 219    trace_iotkit_sysctl_write(offset, value, size);
 220
 221    /*
 222     * Most of the state here has to do with control of reset and
 223     * similar kinds of power up -- for instance the guest can ask
 224     * what the reason for the last reset was, or forbid reset for
 225     * some causes (like the non-secure watchdog). Most of this is
 226     * not relevant to QEMU, which doesn't really model anything other
 227     * than a full power-on reset.
 228     * We just model the registers as reads-as-written.
 229     */
 230
 231    switch (offset) {
 232    case A_RESET_SYNDROME:
 233        qemu_log_mask(LOG_UNIMP,
 234                      "IoTKit SysCtl RESET_SYNDROME unimplemented\n");
 235        s->reset_syndrome = value;
 236        break;
 237    case A_RESET_MASK:
 238        qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl RESET_MASK unimplemented\n");
 239        s->reset_mask = value;
 240        break;
 241    case A_GRETREG:
 242        /*
 243         * General retention register, which is only reset by a power-on
 244         * reset. Technically this implementation is complete, since
 245         * QEMU only supports power-on resets...
 246         */
 247        s->gretreg = value;
 248        break;
 249    case A_INITSVTOR0:
 250        s->initsvtor0 = value;
 251        set_init_vtor(0, s->initsvtor0);
 252        break;
 253    case A_CPUWAIT:
 254        if ((s->cpuwait & 1) && !(value & 1)) {
 255            /* Powering up CPU 0 */
 256            arm_set_cpu_on_and_reset(0);
 257        }
 258        if ((s->cpuwait & 2) && !(value & 2)) {
 259            /* Powering up CPU 1 */
 260            arm_set_cpu_on_and_reset(1);
 261        }
 262        s->cpuwait = value;
 263        break;
 264    case A_WICCTRL:
 265        qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl WICCTRL unimplemented\n");
 266        s->wicctrl = value;
 267        break;
 268    case A_SECDBGSET:
 269        /* write-1-to-set */
 270        qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SECDBGSET unimplemented\n");
 271        s->secure_debug |= value;
 272        break;
 273    case A_SECDBGCLR:
 274        /* write-1-to-clear */
 275        s->secure_debug &= ~value;
 276        break;
 277    case A_SWRESET:
 278        /* One w/o bit to request a reset; all other bits reserved */
 279        if (value & R_SWRESET_SWRESETREQ_MASK) {
 280            qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
 281        }
 282        break;
 283    case A_SCSECCTRL:
 284        if (!s->is_sse200) {
 285            goto bad_offset;
 286        }
 287        qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SCSECCTRL unimplemented\n");
 288        s->scsecctrl = value;
 289        break;
 290    case A_FCLK_DIV:
 291        if (!s->is_sse200) {
 292            goto bad_offset;
 293        }
 294        qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl FCLK_DIV unimplemented\n");
 295        s->fclk_div = value;
 296        break;
 297    case A_SYSCLK_DIV:
 298        if (!s->is_sse200) {
 299            goto bad_offset;
 300        }
 301        qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SYSCLK_DIV unimplemented\n");
 302        s->sysclk_div = value;
 303        break;
 304    case A_CLOCK_FORCE:
 305        if (!s->is_sse200) {
 306            goto bad_offset;
 307        }
 308        qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl CLOCK_FORCE unimplemented\n");
 309        s->clock_force = value;
 310        break;
 311    case A_INITSVTOR1:
 312        if (!s->is_sse200) {
 313            goto bad_offset;
 314        }
 315        s->initsvtor1 = value;
 316        set_init_vtor(1, s->initsvtor1);
 317        break;
 318    case A_EWCTRL:
 319        if (!s->is_sse200) {
 320            goto bad_offset;
 321        }
 322        qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl EWCTRL unimplemented\n");
 323        s->ewctrl = value;
 324        break;
 325    case A_PDCM_PD_SYS_SENSE:
 326        if (!s->is_sse200) {
 327            goto bad_offset;
 328        }
 329        qemu_log_mask(LOG_UNIMP,
 330                      "IoTKit SysCtl PDCM_PD_SYS_SENSE unimplemented\n");
 331        s->pdcm_pd_sys_sense = value;
 332        break;
 333    case A_PDCM_PD_SRAM0_SENSE:
 334        if (!s->is_sse200) {
 335            goto bad_offset;
 336        }
 337        qemu_log_mask(LOG_UNIMP,
 338                      "IoTKit SysCtl PDCM_PD_SRAM0_SENSE unimplemented\n");
 339        s->pdcm_pd_sram0_sense = value;
 340        break;
 341    case A_PDCM_PD_SRAM1_SENSE:
 342        if (!s->is_sse200) {
 343            goto bad_offset;
 344        }
 345        qemu_log_mask(LOG_UNIMP,
 346                      "IoTKit SysCtl PDCM_PD_SRAM1_SENSE unimplemented\n");
 347        s->pdcm_pd_sram1_sense = value;
 348        break;
 349    case A_PDCM_PD_SRAM2_SENSE:
 350        if (!s->is_sse200) {
 351            goto bad_offset;
 352        }
 353        qemu_log_mask(LOG_UNIMP,
 354                      "IoTKit SysCtl PDCM_PD_SRAM2_SENSE unimplemented\n");
 355        s->pdcm_pd_sram2_sense = value;
 356        break;
 357    case A_PDCM_PD_SRAM3_SENSE:
 358        if (!s->is_sse200) {
 359            goto bad_offset;
 360        }
 361        qemu_log_mask(LOG_UNIMP,
 362                      "IoTKit SysCtl PDCM_PD_SRAM3_SENSE unimplemented\n");
 363        s->pdcm_pd_sram3_sense = value;
 364        break;
 365    case A_NMI_ENABLE:
 366        /* In IoTKit this is BUSWAIT: reserved, R/O, zero */
 367        if (!s->is_sse200) {
 368            goto ro_offset;
 369        }
 370        qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl NMI_ENABLE unimplemented\n");
 371        s->nmi_enable = value;
 372        break;
 373    case A_SECDBGSTAT:
 374    case A_PID4 ... A_CID3:
 375    ro_offset:
 376        qemu_log_mask(LOG_GUEST_ERROR,
 377                      "IoTKit SysCtl write: write of RO offset %x\n",
 378                      (int)offset);
 379        break;
 380    default:
 381    bad_offset:
 382        qemu_log_mask(LOG_GUEST_ERROR,
 383                      "IoTKit SysCtl write: bad offset %x\n", (int)offset);
 384        break;
 385    }
 386}
 387
 388static const MemoryRegionOps iotkit_sysctl_ops = {
 389    .read = iotkit_sysctl_read,
 390    .write = iotkit_sysctl_write,
 391    .endianness = DEVICE_LITTLE_ENDIAN,
 392    /* byte/halfword accesses are just zero-padded on reads and writes */
 393    .impl.min_access_size = 4,
 394    .impl.max_access_size = 4,
 395    .valid.min_access_size = 1,
 396    .valid.max_access_size = 4,
 397};
 398
 399static void iotkit_sysctl_reset(DeviceState *dev)
 400{
 401    IoTKitSysCtl *s = IOTKIT_SYSCTL(dev);
 402
 403    trace_iotkit_sysctl_reset();
 404    s->secure_debug = 0;
 405    s->reset_syndrome = 1;
 406    s->reset_mask = 0;
 407    s->gretreg = 0;
 408    s->initsvtor0 = s->initsvtor0_rst;
 409    s->initsvtor1 = s->initsvtor1_rst;
 410    s->cpuwait = s->cpuwait_rst;
 411    s->wicctrl = 0;
 412    s->scsecctrl = 0;
 413    s->fclk_div = 0;
 414    s->sysclk_div = 0;
 415    s->clock_force = 0;
 416    s->nmi_enable = 0;
 417    s->ewctrl = 0;
 418    s->pdcm_pd_sys_sense = 0x7f;
 419    s->pdcm_pd_sram0_sense = 0;
 420    s->pdcm_pd_sram1_sense = 0;
 421    s->pdcm_pd_sram2_sense = 0;
 422    s->pdcm_pd_sram3_sense = 0;
 423}
 424
 425static void iotkit_sysctl_init(Object *obj)
 426{
 427    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
 428    IoTKitSysCtl *s = IOTKIT_SYSCTL(obj);
 429
 430    memory_region_init_io(&s->iomem, obj, &iotkit_sysctl_ops,
 431                          s, "iotkit-sysctl", 0x1000);
 432    sysbus_init_mmio(sbd, &s->iomem);
 433}
 434
 435static void iotkit_sysctl_realize(DeviceState *dev, Error **errp)
 436{
 437    IoTKitSysCtl *s = IOTKIT_SYSCTL(dev);
 438
 439    /* The top 4 bits of the SYS_VERSION register tell us if we're an SSE-200 */
 440    if (extract32(s->sys_version, 28, 4) == 2) {
 441        s->is_sse200 = true;
 442    }
 443}
 444
 445static bool sse200_needed(void *opaque)
 446{
 447    IoTKitSysCtl *s = IOTKIT_SYSCTL(opaque);
 448
 449    return s->is_sse200;
 450}
 451
 452static const VMStateDescription iotkit_sysctl_sse200_vmstate = {
 453    .name = "iotkit-sysctl/sse-200",
 454    .version_id = 1,
 455    .minimum_version_id = 1,
 456    .needed = sse200_needed,
 457    .fields = (VMStateField[]) {
 458        VMSTATE_UINT32(scsecctrl, IoTKitSysCtl),
 459        VMSTATE_UINT32(fclk_div, IoTKitSysCtl),
 460        VMSTATE_UINT32(sysclk_div, IoTKitSysCtl),
 461        VMSTATE_UINT32(clock_force, IoTKitSysCtl),
 462        VMSTATE_UINT32(initsvtor1, IoTKitSysCtl),
 463        VMSTATE_UINT32(nmi_enable, IoTKitSysCtl),
 464        VMSTATE_UINT32(pdcm_pd_sys_sense, IoTKitSysCtl),
 465        VMSTATE_UINT32(pdcm_pd_sram0_sense, IoTKitSysCtl),
 466        VMSTATE_UINT32(pdcm_pd_sram1_sense, IoTKitSysCtl),
 467        VMSTATE_UINT32(pdcm_pd_sram2_sense, IoTKitSysCtl),
 468        VMSTATE_UINT32(pdcm_pd_sram3_sense, IoTKitSysCtl),
 469        VMSTATE_END_OF_LIST()
 470    }
 471};
 472
 473static const VMStateDescription iotkit_sysctl_vmstate = {
 474    .name = "iotkit-sysctl",
 475    .version_id = 1,
 476    .minimum_version_id = 1,
 477    .fields = (VMStateField[]) {
 478        VMSTATE_UINT32(secure_debug, IoTKitSysCtl),
 479        VMSTATE_UINT32(reset_syndrome, IoTKitSysCtl),
 480        VMSTATE_UINT32(reset_mask, IoTKitSysCtl),
 481        VMSTATE_UINT32(gretreg, IoTKitSysCtl),
 482        VMSTATE_UINT32(initsvtor0, IoTKitSysCtl),
 483        VMSTATE_UINT32(cpuwait, IoTKitSysCtl),
 484        VMSTATE_UINT32(wicctrl, IoTKitSysCtl),
 485        VMSTATE_END_OF_LIST()
 486    },
 487    .subsections = (const VMStateDescription*[]) {
 488        &iotkit_sysctl_sse200_vmstate,
 489        NULL
 490    }
 491};
 492
 493static Property iotkit_sysctl_props[] = {
 494    DEFINE_PROP_UINT32("SYS_VERSION", IoTKitSysCtl, sys_version, 0),
 495    DEFINE_PROP_UINT32("CPUWAIT_RST", IoTKitSysCtl, cpuwait_rst, 0),
 496    DEFINE_PROP_UINT32("INITSVTOR0_RST", IoTKitSysCtl, initsvtor0_rst,
 497                       0x10000000),
 498    DEFINE_PROP_UINT32("INITSVTOR1_RST", IoTKitSysCtl, initsvtor1_rst,
 499                       0x10000000),
 500    DEFINE_PROP_END_OF_LIST()
 501};
 502
 503static void iotkit_sysctl_class_init(ObjectClass *klass, void *data)
 504{
 505    DeviceClass *dc = DEVICE_CLASS(klass);
 506
 507    dc->vmsd = &iotkit_sysctl_vmstate;
 508    dc->reset = iotkit_sysctl_reset;
 509    dc->props = iotkit_sysctl_props;
 510    dc->realize = iotkit_sysctl_realize;
 511}
 512
 513static const TypeInfo iotkit_sysctl_info = {
 514    .name = TYPE_IOTKIT_SYSCTL,
 515    .parent = TYPE_SYS_BUS_DEVICE,
 516    .instance_size = sizeof(IoTKitSysCtl),
 517    .instance_init = iotkit_sysctl_init,
 518    .class_init = iotkit_sysctl_class_init,
 519};
 520
 521static void iotkit_sysctl_register_types(void)
 522{
 523    type_register_static(&iotkit_sysctl_info);
 524}
 525
 526type_init(iotkit_sysctl_register_types);
 527