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

imx6_src.c (9069B)


      1/*
      2 * IMX6 System Reset Controller
      3 *
      4 * Copyright (c) 2015 Jean-Christophe Dubois <jcd@tribudubois.net>
      5 *
      6 * This work is licensed under the terms of the GNU GPL, version 2 or later.
      7 * See the COPYING file in the top-level directory.
      8 *
      9 */
     10
     11#include "qemu/osdep.h"
     12#include "hw/misc/imx6_src.h"
     13#include "migration/vmstate.h"
     14#include "qemu/bitops.h"
     15#include "qemu/log.h"
     16#include "qemu/main-loop.h"
     17#include "qemu/module.h"
     18#include "arm-powerctl.h"
     19#include "hw/core/cpu.h"
     20
     21#ifndef DEBUG_IMX6_SRC
     22#define DEBUG_IMX6_SRC 0
     23#endif
     24
     25#define DPRINTF(fmt, args...) \
     26    do { \
     27        if (DEBUG_IMX6_SRC) { \
     28            fprintf(stderr, "[%s]%s: " fmt , TYPE_IMX6_SRC, \
     29                                             __func__, ##args); \
     30        } \
     31    } while (0)
     32
     33static const char *imx6_src_reg_name(uint32_t reg)
     34{
     35    static char unknown[20];
     36
     37    switch (reg) {
     38    case SRC_SCR:
     39        return "SRC_SCR";
     40    case SRC_SBMR1:
     41        return "SRC_SBMR1";
     42    case SRC_SRSR:
     43        return "SRC_SRSR";
     44    case SRC_SISR:
     45        return "SRC_SISR";
     46    case SRC_SIMR:
     47        return "SRC_SIMR";
     48    case SRC_SBMR2:
     49        return "SRC_SBMR2";
     50    case SRC_GPR1:
     51        return "SRC_GPR1";
     52    case SRC_GPR2:
     53        return "SRC_GPR2";
     54    case SRC_GPR3:
     55        return "SRC_GPR3";
     56    case SRC_GPR4:
     57        return "SRC_GPR4";
     58    case SRC_GPR5:
     59        return "SRC_GPR5";
     60    case SRC_GPR6:
     61        return "SRC_GPR6";
     62    case SRC_GPR7:
     63        return "SRC_GPR7";
     64    case SRC_GPR8:
     65        return "SRC_GPR8";
     66    case SRC_GPR9:
     67        return "SRC_GPR9";
     68    case SRC_GPR10:
     69        return "SRC_GPR10";
     70    default:
     71        sprintf(unknown, "%u ?", reg);
     72        return unknown;
     73    }
     74}
     75
     76static const VMStateDescription vmstate_imx6_src = {
     77    .name = TYPE_IMX6_SRC,
     78    .version_id = 1,
     79    .minimum_version_id = 1,
     80    .fields = (VMStateField[]) {
     81        VMSTATE_UINT32_ARRAY(regs, IMX6SRCState, SRC_MAX),
     82        VMSTATE_END_OF_LIST()
     83    },
     84};
     85
     86static void imx6_src_reset(DeviceState *dev)
     87{
     88    IMX6SRCState *s = IMX6_SRC(dev);
     89
     90    DPRINTF("\n");
     91
     92    memset(s->regs, 0, sizeof(s->regs));
     93
     94    /* Set reset values */
     95    s->regs[SRC_SCR] = 0x521;
     96    s->regs[SRC_SRSR] = 0x1;
     97    s->regs[SRC_SIMR] = 0x1F;
     98}
     99
    100static uint64_t imx6_src_read(void *opaque, hwaddr offset, unsigned size)
    101{
    102    uint32_t value = 0;
    103    IMX6SRCState *s = (IMX6SRCState *)opaque;
    104    uint32_t index = offset >> 2;
    105
    106    if (index < SRC_MAX) {
    107        value = s->regs[index];
    108    } else {
    109        qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%"
    110                      HWADDR_PRIx "\n", TYPE_IMX6_SRC, __func__, offset);
    111
    112    }
    113
    114    DPRINTF("reg[%s] => 0x%" PRIx32 "\n", imx6_src_reg_name(index), value);
    115
    116    return value;
    117}
    118
    119
    120/* The reset is asynchronous so we need to defer clearing the reset
    121 * bit until the work is completed.
    122 */
    123
    124struct SRCSCRResetInfo {
    125    IMX6SRCState *s;
    126    int reset_bit;
    127};
    128
    129static void imx6_clear_reset_bit(CPUState *cpu, run_on_cpu_data data)
    130{
    131    struct SRCSCRResetInfo *ri = data.host_ptr;
    132    IMX6SRCState *s = ri->s;
    133
    134    assert(qemu_mutex_iothread_locked());
    135
    136    s->regs[SRC_SCR] = deposit32(s->regs[SRC_SCR], ri->reset_bit, 1, 0);
    137    DPRINTF("reg[%s] <= 0x%" PRIx32 "\n",
    138            imx6_src_reg_name(SRC_SCR), s->regs[SRC_SCR]);
    139
    140    g_free(ri);
    141}
    142
    143static void imx6_defer_clear_reset_bit(int cpuid,
    144                                       IMX6SRCState *s,
    145                                       unsigned long reset_shift)
    146{
    147    struct SRCSCRResetInfo *ri;
    148    CPUState *cpu = arm_get_cpu_by_id(cpuid);
    149
    150    if (!cpu) {
    151        return;
    152    }
    153
    154    ri = g_malloc(sizeof(struct SRCSCRResetInfo));
    155    ri->s = s;
    156    ri->reset_bit = reset_shift;
    157
    158    async_run_on_cpu(cpu, imx6_clear_reset_bit, RUN_ON_CPU_HOST_PTR(ri));
    159}
    160
    161
    162static void imx6_src_write(void *opaque, hwaddr offset, uint64_t value,
    163                           unsigned size)
    164{
    165    IMX6SRCState *s = (IMX6SRCState *)opaque;
    166    uint32_t index = offset >> 2;
    167    unsigned long change_mask;
    168    unsigned long current_value = value;
    169
    170    if (index >=  SRC_MAX) {
    171        qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%"
    172                      HWADDR_PRIx "\n", TYPE_IMX6_SRC, __func__, offset);
    173        return;
    174    }
    175
    176    DPRINTF("reg[%s] <= 0x%" PRIx32 "\n", imx6_src_reg_name(index),
    177            (uint32_t)current_value);
    178
    179    change_mask = s->regs[index] ^ (uint32_t)current_value;
    180
    181    switch (index) {
    182    case SRC_SCR:
    183        /*
    184         * On real hardware when the system reset controller starts a
    185         * secondary CPU it runs through some boot ROM code which reads
    186         * the SRC_GPRX registers controlling the start address and branches
    187         * to it.
    188         * Here we are taking a short cut and branching directly to the
    189         * requested address (we don't want to run the boot ROM code inside
    190         * QEMU)
    191         */
    192        if (EXTRACT(change_mask, CORE3_ENABLE)) {
    193            if (EXTRACT(current_value, CORE3_ENABLE)) {
    194                /* CORE 3 is brought up */
    195                arm_set_cpu_on(3, s->regs[SRC_GPR7], s->regs[SRC_GPR8],
    196                               3, false);
    197            } else {
    198                /* CORE 3 is shut down */
    199                arm_set_cpu_off(3);
    200            }
    201            /* We clear the reset bits as the processor changed state */
    202            imx6_defer_clear_reset_bit(3, s, CORE3_RST_SHIFT);
    203            clear_bit(CORE3_RST_SHIFT, &change_mask);
    204        }
    205        if (EXTRACT(change_mask, CORE2_ENABLE)) {
    206            if (EXTRACT(current_value, CORE2_ENABLE)) {
    207                /* CORE 2 is brought up */
    208                arm_set_cpu_on(2, s->regs[SRC_GPR5], s->regs[SRC_GPR6],
    209                               3, false);
    210            } else {
    211                /* CORE 2 is shut down */
    212                arm_set_cpu_off(2);
    213            }
    214            /* We clear the reset bits as the processor changed state */
    215            imx6_defer_clear_reset_bit(2, s, CORE2_RST_SHIFT);
    216            clear_bit(CORE2_RST_SHIFT, &change_mask);
    217        }
    218        if (EXTRACT(change_mask, CORE1_ENABLE)) {
    219            if (EXTRACT(current_value, CORE1_ENABLE)) {
    220                /* CORE 1 is brought up */
    221                arm_set_cpu_on(1, s->regs[SRC_GPR3], s->regs[SRC_GPR4],
    222                               3, false);
    223            } else {
    224                /* CORE 1 is shut down */
    225                arm_set_cpu_off(1);
    226            }
    227            /* We clear the reset bits as the processor changed state */
    228            imx6_defer_clear_reset_bit(1, s, CORE1_RST_SHIFT);
    229            clear_bit(CORE1_RST_SHIFT, &change_mask);
    230        }
    231        if (EXTRACT(change_mask, CORE0_RST)) {
    232            arm_reset_cpu(0);
    233            imx6_defer_clear_reset_bit(0, s, CORE0_RST_SHIFT);
    234        }
    235        if (EXTRACT(change_mask, CORE1_RST)) {
    236            arm_reset_cpu(1);
    237            imx6_defer_clear_reset_bit(1, s, CORE1_RST_SHIFT);
    238        }
    239        if (EXTRACT(change_mask, CORE2_RST)) {
    240            arm_reset_cpu(2);
    241            imx6_defer_clear_reset_bit(2, s, CORE2_RST_SHIFT);
    242        }
    243        if (EXTRACT(change_mask, CORE3_RST)) {
    244            arm_reset_cpu(3);
    245            imx6_defer_clear_reset_bit(3, s, CORE3_RST_SHIFT);
    246        }
    247        if (EXTRACT(change_mask, SW_IPU2_RST)) {
    248            /* We pretend the IPU2 is reset */
    249            clear_bit(SW_IPU2_RST_SHIFT, &current_value);
    250        }
    251        if (EXTRACT(change_mask, SW_IPU1_RST)) {
    252            /* We pretend the IPU1 is reset */
    253            clear_bit(SW_IPU1_RST_SHIFT, &current_value);
    254        }
    255        s->regs[index] = current_value;
    256        break;
    257    default:
    258        s->regs[index] = current_value;
    259        break;
    260    }
    261}
    262
    263static const struct MemoryRegionOps imx6_src_ops = {
    264    .read = imx6_src_read,
    265    .write = imx6_src_write,
    266    .endianness = DEVICE_NATIVE_ENDIAN,
    267    .valid = {
    268        /*
    269         * Our device would not work correctly if the guest was doing
    270         * unaligned access. This might not be a limitation on the real
    271         * device but in practice there is no reason for a guest to access
    272         * this device unaligned.
    273         */
    274        .min_access_size = 4,
    275        .max_access_size = 4,
    276        .unaligned = false,
    277    },
    278};
    279
    280static void imx6_src_realize(DeviceState *dev, Error **errp)
    281{
    282    IMX6SRCState *s = IMX6_SRC(dev);
    283
    284    memory_region_init_io(&s->iomem, OBJECT(dev), &imx6_src_ops, s,
    285                          TYPE_IMX6_SRC, 0x1000);
    286    sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
    287}
    288
    289static void imx6_src_class_init(ObjectClass *klass, void *data)
    290{
    291    DeviceClass *dc = DEVICE_CLASS(klass);
    292
    293    dc->realize = imx6_src_realize;
    294    dc->reset = imx6_src_reset;
    295    dc->vmsd = &vmstate_imx6_src;
    296    dc->desc = "i.MX6 System Reset Controller";
    297}
    298
    299static const TypeInfo imx6_src_info = {
    300    .name          = TYPE_IMX6_SRC,
    301    .parent        = TYPE_SYS_BUS_DEVICE,
    302    .instance_size = sizeof(IMX6SRCState),
    303    .class_init    = imx6_src_class_init,
    304};
    305
    306static void imx6_src_register_types(void)
    307{
    308    type_register_static(&imx6_src_info);
    309}
    310
    311type_init(imx6_src_register_types)