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

imx31_ccm.c (9227B)


      1/*
      2 * IMX31 Clock Control Module
      3 *
      4 * Copyright (C) 2012 NICTA
      5 * Updated by Jean-Christophe Dubois <jcd@tribudubois.net>
      6 *
      7 * This work is licensed under the terms of the GNU GPL, version 2 or later.
      8 * See the COPYING file in the top-level directory.
      9 *
     10 * To get the timer frequencies right, we need to emulate at least part of
     11 * the i.MX31 CCM.
     12 */
     13
     14#include "qemu/osdep.h"
     15#include "hw/misc/imx31_ccm.h"
     16#include "migration/vmstate.h"
     17#include "qemu/log.h"
     18#include "qemu/module.h"
     19
     20#define CKIH_FREQ 26000000 /* 26MHz crystal input */
     21
     22#ifndef DEBUG_IMX31_CCM
     23#define DEBUG_IMX31_CCM 0
     24#endif
     25
     26#define DPRINTF(fmt, args...) \
     27    do { \
     28        if (DEBUG_IMX31_CCM) { \
     29            fprintf(stderr, "[%s]%s: " fmt , TYPE_IMX31_CCM, \
     30                                             __func__, ##args); \
     31        } \
     32    } while (0)
     33
     34static const char *imx31_ccm_reg_name(uint32_t reg)
     35{
     36    static char unknown[20];
     37
     38    switch (reg) {
     39    case IMX31_CCM_CCMR_REG:
     40        return "CCMR";
     41    case IMX31_CCM_PDR0_REG:
     42        return "PDR0";
     43    case IMX31_CCM_PDR1_REG:
     44        return "PDR1";
     45    case IMX31_CCM_RCSR_REG:
     46        return "RCSR";
     47    case IMX31_CCM_MPCTL_REG:
     48        return "MPCTL";
     49    case IMX31_CCM_UPCTL_REG:
     50        return "UPCTL";
     51    case IMX31_CCM_SPCTL_REG:
     52        return "SPCTL";
     53    case IMX31_CCM_COSR_REG:
     54        return "COSR";
     55    case IMX31_CCM_CGR0_REG:
     56        return "CGR0";
     57    case IMX31_CCM_CGR1_REG:
     58        return "CGR1";
     59    case IMX31_CCM_CGR2_REG:
     60        return "CGR2";
     61    case IMX31_CCM_WIMR_REG:
     62        return "WIMR";
     63    case IMX31_CCM_LDC_REG:
     64        return "LDC";
     65    case IMX31_CCM_DCVR0_REG:
     66        return "DCVR0";
     67    case IMX31_CCM_DCVR1_REG:
     68        return "DCVR1";
     69    case IMX31_CCM_DCVR2_REG:
     70        return "DCVR2";
     71    case IMX31_CCM_DCVR3_REG:
     72        return "DCVR3";
     73    case IMX31_CCM_LTR0_REG:
     74        return "LTR0";
     75    case IMX31_CCM_LTR1_REG:
     76        return "LTR1";
     77    case IMX31_CCM_LTR2_REG:
     78        return "LTR2";
     79    case IMX31_CCM_LTR3_REG:
     80        return "LTR3";
     81    case IMX31_CCM_LTBR0_REG:
     82        return "LTBR0";
     83    case IMX31_CCM_LTBR1_REG:
     84        return "LTBR1";
     85    case IMX31_CCM_PMCR0_REG:
     86        return "PMCR0";
     87    case IMX31_CCM_PMCR1_REG:
     88        return "PMCR1";
     89    case IMX31_CCM_PDR2_REG:
     90        return "PDR2";
     91    default:
     92        sprintf(unknown, "[%u ?]", reg);
     93        return unknown;
     94    }
     95}
     96
     97static const VMStateDescription vmstate_imx31_ccm = {
     98    .name = TYPE_IMX31_CCM,
     99    .version_id = 2,
    100    .minimum_version_id = 2,
    101    .fields = (VMStateField[]) {
    102        VMSTATE_UINT32_ARRAY(reg, IMX31CCMState, IMX31_CCM_MAX_REG),
    103        VMSTATE_END_OF_LIST()
    104    },
    105};
    106
    107static uint32_t imx31_ccm_get_pll_ref_clk(IMXCCMState *dev)
    108{
    109    uint32_t freq = 0;
    110    IMX31CCMState *s = IMX31_CCM(dev);
    111
    112    if ((s->reg[IMX31_CCM_CCMR_REG] & CCMR_PRCS) == 2) {
    113        if (s->reg[IMX31_CCM_CCMR_REG] & CCMR_FPME) {
    114            freq = CKIL_FREQ;
    115            if (s->reg[IMX31_CCM_CCMR_REG] & CCMR_FPMF) {
    116                freq *= 1024;
    117            }
    118        } 
    119    } else {
    120        freq = CKIH_FREQ;
    121    }
    122
    123    DPRINTF("freq = %u\n", freq);
    124
    125    return freq;
    126}
    127
    128static uint32_t imx31_ccm_get_mpll_clk(IMXCCMState *dev)
    129{
    130    uint32_t freq;
    131    IMX31CCMState *s = IMX31_CCM(dev);
    132
    133    freq = imx_ccm_calc_pll(s->reg[IMX31_CCM_MPCTL_REG],
    134                            imx31_ccm_get_pll_ref_clk(dev));
    135
    136    DPRINTF("freq = %u\n", freq);
    137
    138    return freq;
    139}
    140
    141static uint32_t imx31_ccm_get_mcu_main_clk(IMXCCMState *dev)
    142{
    143    uint32_t freq;
    144    IMX31CCMState *s = IMX31_CCM(dev);
    145
    146    if ((s->reg[IMX31_CCM_CCMR_REG] & CCMR_MDS) ||
    147        !(s->reg[IMX31_CCM_CCMR_REG] & CCMR_MPE)) {
    148        freq = imx31_ccm_get_pll_ref_clk(dev);
    149    } else {
    150        freq = imx31_ccm_get_mpll_clk(dev);
    151    }
    152
    153    DPRINTF("freq = %u\n", freq);
    154
    155    return freq;
    156}
    157
    158static uint32_t imx31_ccm_get_hclk_clk(IMXCCMState *dev)
    159{
    160    uint32_t freq;
    161    IMX31CCMState *s = IMX31_CCM(dev);
    162
    163    freq = imx31_ccm_get_mcu_main_clk(dev)
    164           / (1 + EXTRACT(s->reg[IMX31_CCM_PDR0_REG], MAX));
    165
    166    DPRINTF("freq = %u\n", freq);
    167
    168    return freq;
    169}
    170
    171static uint32_t imx31_ccm_get_ipg_clk(IMXCCMState *dev)
    172{
    173    uint32_t freq;
    174    IMX31CCMState *s = IMX31_CCM(dev);
    175
    176    freq = imx31_ccm_get_hclk_clk(dev)
    177           / (1 + EXTRACT(s->reg[IMX31_CCM_PDR0_REG], IPG));
    178
    179    DPRINTF("freq = %u\n", freq);
    180
    181    return freq;
    182}
    183
    184static uint32_t imx31_ccm_get_clock_frequency(IMXCCMState *dev, IMXClk clock)
    185{
    186    uint32_t freq = 0;
    187
    188    switch (clock) {
    189    case CLK_NONE:
    190        break;
    191    case CLK_IPG:
    192    case CLK_IPG_HIGH:
    193        freq = imx31_ccm_get_ipg_clk(dev);
    194        break;
    195    case CLK_32k:
    196        freq = CKIL_FREQ;
    197        break;
    198    default:
    199        qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: unsupported clock %d\n",
    200                      TYPE_IMX31_CCM, __func__, clock);
    201        break;
    202    }
    203
    204    DPRINTF("Clock = %d) = %u\n", clock, freq);
    205
    206    return freq;
    207}
    208
    209static void imx31_ccm_reset(DeviceState *dev)
    210{
    211    IMX31CCMState *s = IMX31_CCM(dev);
    212
    213    DPRINTF("()\n");
    214
    215    memset(s->reg, 0, sizeof(uint32_t) * IMX31_CCM_MAX_REG);
    216
    217    s->reg[IMX31_CCM_CCMR_REG]   = 0x074b0b7d;
    218    s->reg[IMX31_CCM_PDR0_REG]   = 0xff870b48;
    219    s->reg[IMX31_CCM_PDR1_REG]   = 0x49fcfe7f;
    220    s->reg[IMX31_CCM_RCSR_REG]   = 0x007f0000;
    221    s->reg[IMX31_CCM_MPCTL_REG]  = 0x04001800;
    222    s->reg[IMX31_CCM_UPCTL_REG]  = 0x04051c03;
    223    s->reg[IMX31_CCM_SPCTL_REG]  = 0x04043001;
    224    s->reg[IMX31_CCM_COSR_REG]   = 0x00000280;
    225    s->reg[IMX31_CCM_CGR0_REG]   = 0xffffffff;
    226    s->reg[IMX31_CCM_CGR1_REG]   = 0xffffffff;
    227    s->reg[IMX31_CCM_CGR2_REG]   = 0xffffffff;
    228    s->reg[IMX31_CCM_WIMR_REG]   = 0xffffffff;
    229    s->reg[IMX31_CCM_LTR1_REG]   = 0x00004040;
    230    s->reg[IMX31_CCM_PMCR0_REG]  = 0x80209828;
    231    s->reg[IMX31_CCM_PMCR1_REG]  = 0x00aa0000;
    232    s->reg[IMX31_CCM_PDR2_REG]   = 0x00000285;
    233}
    234
    235static uint64_t imx31_ccm_read(void *opaque, hwaddr offset, unsigned size)
    236{
    237    uint32_t value = 0;
    238    IMX31CCMState *s = (IMX31CCMState *)opaque;
    239
    240    if ((offset >> 2) < IMX31_CCM_MAX_REG) {
    241        value = s->reg[offset >> 2];
    242    } else {
    243        qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%"
    244                      HWADDR_PRIx "\n", TYPE_IMX31_CCM, __func__, offset);
    245    }
    246
    247    DPRINTF("reg[%s] => 0x%" PRIx32 "\n", imx31_ccm_reg_name(offset >> 2),
    248            value);
    249
    250    return (uint64_t)value;
    251}
    252
    253static void imx31_ccm_write(void *opaque, hwaddr offset, uint64_t value,
    254                            unsigned size)
    255{
    256    IMX31CCMState *s = (IMX31CCMState *)opaque;
    257
    258    DPRINTF("reg[%s] <= 0x%" PRIx32 "\n", imx31_ccm_reg_name(offset >> 2),
    259            (uint32_t)value);
    260
    261    switch (offset >> 2) {
    262    case IMX31_CCM_CCMR_REG:
    263        s->reg[IMX31_CCM_CCMR_REG] = CCMR_FPMF | (value & 0x3b6fdfff);
    264        break;
    265    case IMX31_CCM_PDR0_REG:
    266        s->reg[IMX31_CCM_PDR0_REG] = value & 0xff9f3fff;
    267        break;
    268    case IMX31_CCM_PDR1_REG:
    269        s->reg[IMX31_CCM_PDR1_REG] = value;
    270        break;
    271    case IMX31_CCM_MPCTL_REG:
    272        s->reg[IMX31_CCM_MPCTL_REG] = value & 0xbfff3fff;
    273        break;
    274    case IMX31_CCM_SPCTL_REG:
    275        s->reg[IMX31_CCM_SPCTL_REG] = value & 0xbfff3fff;
    276        break;
    277    case IMX31_CCM_CGR0_REG:
    278        s->reg[IMX31_CCM_CGR0_REG] = value;
    279        break;
    280    case IMX31_CCM_CGR1_REG:
    281        s->reg[IMX31_CCM_CGR1_REG] = value;
    282        break;
    283    case IMX31_CCM_CGR2_REG:
    284        s->reg[IMX31_CCM_CGR2_REG] = value;
    285        break;
    286    default:
    287        qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%"
    288                      HWADDR_PRIx "\n", TYPE_IMX31_CCM, __func__, offset);
    289        break;
    290    }
    291}
    292
    293static const struct MemoryRegionOps imx31_ccm_ops = {
    294    .read = imx31_ccm_read,
    295    .write = imx31_ccm_write,
    296    .endianness = DEVICE_NATIVE_ENDIAN,
    297    .valid = {
    298        /*
    299         * Our device would not work correctly if the guest was doing
    300         * unaligned access. This might not be a limitation on the real
    301         * device but in practice there is no reason for a guest to access
    302         * this device unaligned.
    303         */
    304        .min_access_size = 4,
    305        .max_access_size = 4,
    306        .unaligned = false,
    307    },
    308
    309};
    310
    311static void imx31_ccm_init(Object *obj)
    312{
    313    DeviceState *dev = DEVICE(obj);
    314    SysBusDevice *sd = SYS_BUS_DEVICE(obj);
    315    IMX31CCMState *s = IMX31_CCM(obj);
    316
    317    memory_region_init_io(&s->iomem, OBJECT(dev), &imx31_ccm_ops, s,
    318                          TYPE_IMX31_CCM, 0x1000);
    319    sysbus_init_mmio(sd, &s->iomem);
    320}
    321
    322static void imx31_ccm_class_init(ObjectClass *klass, void *data)
    323{
    324    DeviceClass *dc  = DEVICE_CLASS(klass);
    325    IMXCCMClass *ccm = IMX_CCM_CLASS(klass);
    326
    327    dc->reset = imx31_ccm_reset;
    328    dc->vmsd  = &vmstate_imx31_ccm;
    329    dc->desc  = "i.MX31 Clock Control Module";
    330
    331    ccm->get_clock_frequency = imx31_ccm_get_clock_frequency;
    332}
    333
    334static const TypeInfo imx31_ccm_info = {
    335    .name          = TYPE_IMX31_CCM,
    336    .parent        = TYPE_IMX_CCM,
    337    .instance_size = sizeof(IMX31CCMState),
    338    .instance_init = imx31_ccm_init,
    339    .class_init    = imx31_ccm_class_init,
    340};
    341
    342static void imx31_ccm_register_types(void)
    343{
    344    type_register_static(&imx31_ccm_info);
    345}
    346
    347type_init(imx31_ccm_register_types)