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

imx_gpt.c (15570B)


      1/*
      2 * IMX GPT Timer
      3 *
      4 * Copyright (c) 2008 OK Labs
      5 * Copyright (c) 2011 NICTA Pty Ltd
      6 * Originally written by Hans Jiang
      7 * Updated by Peter Chubb
      8 * Updated by Jean-Christophe Dubois <jcd@tribudubois.net>
      9 *
     10 * This code is licensed under GPL version 2 or later.  See
     11 * the COPYING file in the top-level directory.
     12 *
     13 */
     14
     15#include "qemu/osdep.h"
     16#include "hw/irq.h"
     17#include "hw/timer/imx_gpt.h"
     18#include "migration/vmstate.h"
     19#include "qemu/module.h"
     20#include "qemu/log.h"
     21
     22#ifndef DEBUG_IMX_GPT
     23#define DEBUG_IMX_GPT 0
     24#endif
     25
     26#define DPRINTF(fmt, args...) \
     27    do { \
     28        if (DEBUG_IMX_GPT) { \
     29            fprintf(stderr, "[%s]%s: " fmt , TYPE_IMX_GPT, \
     30                                             __func__, ##args); \
     31        } \
     32    } while (0)
     33
     34static const char *imx_gpt_reg_name(uint32_t reg)
     35{
     36    switch (reg) {
     37    case 0:
     38        return "CR";
     39    case 1:
     40        return "PR";
     41    case 2:
     42        return "SR";
     43    case 3:
     44        return "IR";
     45    case 4:
     46        return "OCR1";
     47    case 5:
     48        return "OCR2";
     49    case 6:
     50        return "OCR3";
     51    case 7:
     52        return "ICR1";
     53    case 8:
     54        return "ICR2";
     55    case 9:
     56        return "CNT";
     57    default:
     58        return "[?]";
     59    }
     60}
     61
     62static const VMStateDescription vmstate_imx_timer_gpt = {
     63    .name = TYPE_IMX_GPT,
     64    .version_id = 3,
     65    .minimum_version_id = 3,
     66    .fields = (VMStateField[]) {
     67        VMSTATE_UINT32(cr, IMXGPTState),
     68        VMSTATE_UINT32(pr, IMXGPTState),
     69        VMSTATE_UINT32(sr, IMXGPTState),
     70        VMSTATE_UINT32(ir, IMXGPTState),
     71        VMSTATE_UINT32(ocr1, IMXGPTState),
     72        VMSTATE_UINT32(ocr2, IMXGPTState),
     73        VMSTATE_UINT32(ocr3, IMXGPTState),
     74        VMSTATE_UINT32(icr1, IMXGPTState),
     75        VMSTATE_UINT32(icr2, IMXGPTState),
     76        VMSTATE_UINT32(cnt, IMXGPTState),
     77        VMSTATE_UINT32(next_timeout, IMXGPTState),
     78        VMSTATE_UINT32(next_int, IMXGPTState),
     79        VMSTATE_UINT32(freq, IMXGPTState),
     80        VMSTATE_PTIMER(timer, IMXGPTState),
     81        VMSTATE_END_OF_LIST()
     82    }
     83};
     84
     85static const IMXClk imx25_gpt_clocks[] = {
     86    CLK_NONE,      /* 000 No clock source */
     87    CLK_IPG,       /* 001 ipg_clk, 532MHz*/
     88    CLK_IPG_HIGH,  /* 010 ipg_clk_highfreq */
     89    CLK_NONE,      /* 011 not defined */
     90    CLK_32k,       /* 100 ipg_clk_32k */
     91    CLK_32k,       /* 101 ipg_clk_32k */
     92    CLK_32k,       /* 110 ipg_clk_32k */
     93    CLK_32k,       /* 111 ipg_clk_32k */
     94};
     95
     96static const IMXClk imx31_gpt_clocks[] = {
     97    CLK_NONE,      /* 000 No clock source */
     98    CLK_IPG,       /* 001 ipg_clk, 532MHz*/
     99    CLK_IPG_HIGH,  /* 010 ipg_clk_highfreq */
    100    CLK_NONE,      /* 011 not defined */
    101    CLK_32k,       /* 100 ipg_clk_32k */
    102    CLK_NONE,      /* 101 not defined */
    103    CLK_NONE,      /* 110 not defined */
    104    CLK_NONE,      /* 111 not defined */
    105};
    106
    107static const IMXClk imx6_gpt_clocks[] = {
    108    CLK_NONE,      /* 000 No clock source */
    109    CLK_IPG,       /* 001 ipg_clk, 532MHz*/
    110    CLK_IPG_HIGH,  /* 010 ipg_clk_highfreq */
    111    CLK_EXT,       /* 011 External clock */
    112    CLK_32k,       /* 100 ipg_clk_32k */
    113    CLK_HIGH_DIV,  /* 101 reference clock / 8 */
    114    CLK_NONE,      /* 110 not defined */
    115    CLK_HIGH,      /* 111 reference clock */
    116};
    117
    118static const IMXClk imx7_gpt_clocks[] = {
    119    CLK_NONE,      /* 000 No clock source */
    120    CLK_IPG,       /* 001 ipg_clk, 532MHz*/
    121    CLK_IPG_HIGH,  /* 010 ipg_clk_highfreq */
    122    CLK_EXT,       /* 011 External clock */
    123    CLK_32k,       /* 100 ipg_clk_32k */
    124    CLK_HIGH,      /* 101 reference clock */
    125    CLK_NONE,      /* 110 not defined */
    126    CLK_NONE,      /* 111 not defined */
    127};
    128
    129/* Must be called from within ptimer_transaction_begin/commit block */
    130static void imx_gpt_set_freq(IMXGPTState *s)
    131{
    132    uint32_t clksrc = extract32(s->cr, GPT_CR_CLKSRC_SHIFT, 3);
    133
    134    s->freq = imx_ccm_get_clock_frequency(s->ccm,
    135                                          s->clocks[clksrc]) / (1 + s->pr);
    136
    137    DPRINTF("Setting clksrc %d to frequency %d\n", clksrc, s->freq);
    138
    139    if (s->freq) {
    140        ptimer_set_freq(s->timer, s->freq);
    141    }
    142}
    143
    144static void imx_gpt_update_int(IMXGPTState *s)
    145{
    146    if ((s->sr & s->ir) && (s->cr & GPT_CR_EN)) {
    147        qemu_irq_raise(s->irq);
    148    } else {
    149        qemu_irq_lower(s->irq);
    150    }
    151}
    152
    153static uint32_t imx_gpt_update_count(IMXGPTState *s)
    154{
    155    s->cnt = s->next_timeout - (uint32_t)ptimer_get_count(s->timer);
    156
    157    return s->cnt;
    158}
    159
    160static inline uint32_t imx_gpt_find_limit(uint32_t count, uint32_t reg,
    161                                          uint32_t timeout)
    162{
    163    if ((count < reg) && (timeout > reg)) {
    164        timeout = reg;
    165    }
    166
    167    return timeout;
    168}
    169
    170/* Must be called from within ptimer_transaction_begin/commit block */
    171static void imx_gpt_compute_next_timeout(IMXGPTState *s, bool event)
    172{
    173    uint32_t timeout = GPT_TIMER_MAX;
    174    uint32_t count;
    175    long long limit;
    176
    177    if (!(s->cr & GPT_CR_EN)) {
    178        /* if not enabled just return */
    179        return;
    180    }
    181
    182    /* update the count */
    183    count = imx_gpt_update_count(s);
    184
    185    if (event) {
    186        /*
    187         * This is an event (the ptimer reached 0 and stopped), and the
    188         * timer counter is now equal to s->next_timeout.
    189         */
    190        if (!(s->cr & GPT_CR_FRR) && (count == s->ocr1)) {
    191            /* We are in restart mode and we crossed the compare channel 1
    192             * value. We need to reset the counter to 0.
    193             */
    194            count = s->cnt = s->next_timeout = 0;
    195        } else if (count == GPT_TIMER_MAX) {
    196            /* We reached GPT_TIMER_MAX so we need to rollover */
    197            count = s->cnt = s->next_timeout = 0;
    198        }
    199    }
    200
    201    /* now, find the next timeout related to count */
    202
    203    if (s->ir & GPT_IR_OF1IE) {
    204        timeout = imx_gpt_find_limit(count, s->ocr1, timeout);
    205    }
    206    if (s->ir & GPT_IR_OF2IE) {
    207        timeout = imx_gpt_find_limit(count, s->ocr2, timeout);
    208    }
    209    if (s->ir & GPT_IR_OF3IE) {
    210        timeout = imx_gpt_find_limit(count, s->ocr3, timeout);
    211    }
    212
    213    /* find the next set of interrupts to raise for next timer event */
    214
    215    s->next_int = 0;
    216    if ((s->ir & GPT_IR_OF1IE) && (timeout == s->ocr1)) {
    217        s->next_int |= GPT_SR_OF1;
    218    }
    219    if ((s->ir & GPT_IR_OF2IE) && (timeout == s->ocr2)) {
    220        s->next_int |= GPT_SR_OF2;
    221    }
    222    if ((s->ir & GPT_IR_OF3IE) && (timeout == s->ocr3)) {
    223        s->next_int |= GPT_SR_OF3;
    224    }
    225    if ((s->ir & GPT_IR_ROVIE) && (timeout == GPT_TIMER_MAX)) {
    226        s->next_int |= GPT_SR_ROV;
    227    }
    228
    229    /* the new range to count down from */
    230    limit = timeout - imx_gpt_update_count(s);
    231
    232    if (limit < 0) {
    233        /*
    234         * if we reach here, then QEMU is running too slow and we pass the
    235         * timeout limit while computing it. Let's deliver the interrupt
    236         * and compute a new limit.
    237         */
    238        s->sr |= s->next_int;
    239
    240        imx_gpt_compute_next_timeout(s, event);
    241
    242        imx_gpt_update_int(s);
    243    } else {
    244        /* New timeout value */
    245        s->next_timeout = timeout;
    246
    247        /* reset the limit to the computed range */
    248        ptimer_set_limit(s->timer, limit, 1);
    249    }
    250}
    251
    252static uint64_t imx_gpt_read(void *opaque, hwaddr offset, unsigned size)
    253{
    254    IMXGPTState *s = IMX_GPT(opaque);
    255    uint32_t reg_value = 0;
    256
    257    switch (offset >> 2) {
    258    case 0: /* Control Register */
    259        reg_value = s->cr;
    260        break;
    261
    262    case 1: /* prescaler */
    263        reg_value = s->pr;
    264        break;
    265
    266    case 2: /* Status Register */
    267        reg_value = s->sr;
    268        break;
    269
    270    case 3: /* Interrupt Register */
    271        reg_value = s->ir;
    272        break;
    273
    274    case 4: /* Output Compare Register 1 */
    275        reg_value = s->ocr1;
    276        break;
    277
    278    case 5: /* Output Compare Register 2 */
    279        reg_value = s->ocr2;
    280        break;
    281
    282    case 6: /* Output Compare Register 3 */
    283        reg_value = s->ocr3;
    284        break;
    285
    286    case 7: /* input Capture Register 1 */
    287        qemu_log_mask(LOG_UNIMP, "[%s]%s: icr1 feature is not implemented\n",
    288                      TYPE_IMX_GPT, __func__);
    289        reg_value = s->icr1;
    290        break;
    291
    292    case 8: /* input Capture Register 2 */
    293        qemu_log_mask(LOG_UNIMP, "[%s]%s: icr2 feature is not implemented\n",
    294                      TYPE_IMX_GPT, __func__);
    295        reg_value = s->icr2;
    296        break;
    297
    298    case 9: /* cnt */
    299        imx_gpt_update_count(s);
    300        reg_value = s->cnt;
    301        break;
    302
    303    default:
    304        qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%"
    305                      HWADDR_PRIx "\n", TYPE_IMX_GPT, __func__, offset);
    306        break;
    307    }
    308
    309    DPRINTF("(%s) = 0x%08x\n", imx_gpt_reg_name(offset >> 2), reg_value);
    310
    311    return reg_value;
    312}
    313
    314
    315static void imx_gpt_reset_common(IMXGPTState *s, bool is_soft_reset)
    316{
    317    ptimer_transaction_begin(s->timer);
    318    /* stop timer */
    319    ptimer_stop(s->timer);
    320
    321    /* Soft reset and hard reset differ only in their handling of the CR
    322     * register -- soft reset preserves the values of some bits there.
    323     */
    324    if (is_soft_reset) {
    325        /* Clear all CR bits except those that are preserved by soft reset. */
    326        s->cr &= GPT_CR_EN | GPT_CR_ENMOD | GPT_CR_STOPEN | GPT_CR_DOZEN |
    327            GPT_CR_WAITEN | GPT_CR_DBGEN |
    328            (GPT_CR_CLKSRC_MASK << GPT_CR_CLKSRC_SHIFT);
    329    } else {
    330        s->cr = 0;
    331    }
    332    s->sr = 0;
    333    s->pr = 0;
    334    s->ir = 0;
    335    s->cnt = 0;
    336    s->ocr1 = GPT_TIMER_MAX;
    337    s->ocr2 = GPT_TIMER_MAX;
    338    s->ocr3 = GPT_TIMER_MAX;
    339    s->icr1 = 0;
    340    s->icr2 = 0;
    341
    342    s->next_timeout = GPT_TIMER_MAX;
    343    s->next_int = 0;
    344
    345    /* compute new freq */
    346    imx_gpt_set_freq(s);
    347
    348    /* reset the limit to GPT_TIMER_MAX */
    349    ptimer_set_limit(s->timer, GPT_TIMER_MAX, 1);
    350
    351    /* if the timer is still enabled, restart it */
    352    if (s->freq && (s->cr & GPT_CR_EN)) {
    353        ptimer_run(s->timer, 1);
    354    }
    355    ptimer_transaction_commit(s->timer);
    356}
    357
    358static void imx_gpt_soft_reset(DeviceState *dev)
    359{
    360    IMXGPTState *s = IMX_GPT(dev);
    361    imx_gpt_reset_common(s, true);
    362}
    363
    364static void imx_gpt_reset(DeviceState *dev)
    365{
    366    IMXGPTState *s = IMX_GPT(dev);
    367    imx_gpt_reset_common(s, false);
    368}
    369
    370static void imx_gpt_write(void *opaque, hwaddr offset, uint64_t value,
    371                          unsigned size)
    372{
    373    IMXGPTState *s = IMX_GPT(opaque);
    374    uint32_t oldreg;
    375
    376    DPRINTF("(%s, value = 0x%08x)\n", imx_gpt_reg_name(offset >> 2),
    377            (uint32_t)value);
    378
    379    switch (offset >> 2) {
    380    case 0:
    381        oldreg = s->cr;
    382        s->cr = value & ~0x7c14;
    383        if (s->cr & GPT_CR_SWR) { /* force reset */
    384            /* handle the reset */
    385            imx_gpt_soft_reset(DEVICE(s));
    386        } else {
    387            /* set our freq, as the source might have changed */
    388            ptimer_transaction_begin(s->timer);
    389            imx_gpt_set_freq(s);
    390
    391            if ((oldreg ^ s->cr) & GPT_CR_EN) {
    392                if (s->cr & GPT_CR_EN) {
    393                    if (s->cr & GPT_CR_ENMOD) {
    394                        s->next_timeout = GPT_TIMER_MAX;
    395                        ptimer_set_count(s->timer, GPT_TIMER_MAX);
    396                        imx_gpt_compute_next_timeout(s, false);
    397                    }
    398                    ptimer_run(s->timer, 1);
    399                } else {
    400                    /* stop timer */
    401                    ptimer_stop(s->timer);
    402                }
    403            }
    404            ptimer_transaction_commit(s->timer);
    405        }
    406        break;
    407
    408    case 1: /* Prescaler */
    409        s->pr = value & 0xfff;
    410        ptimer_transaction_begin(s->timer);
    411        imx_gpt_set_freq(s);
    412        ptimer_transaction_commit(s->timer);
    413        break;
    414
    415    case 2: /* SR */
    416        s->sr &= ~(value & 0x3f);
    417        imx_gpt_update_int(s);
    418        break;
    419
    420    case 3: /* IR -- interrupt register */
    421        s->ir = value & 0x3f;
    422        imx_gpt_update_int(s);
    423
    424        ptimer_transaction_begin(s->timer);
    425        imx_gpt_compute_next_timeout(s, false);
    426        ptimer_transaction_commit(s->timer);
    427
    428        break;
    429
    430    case 4: /* OCR1 -- output compare register */
    431        s->ocr1 = value;
    432
    433        ptimer_transaction_begin(s->timer);
    434        /* In non-freerun mode, reset count when this register is written */
    435        if (!(s->cr & GPT_CR_FRR)) {
    436            s->next_timeout = GPT_TIMER_MAX;
    437            ptimer_set_limit(s->timer, GPT_TIMER_MAX, 1);
    438        }
    439
    440        /* compute the new timeout */
    441        imx_gpt_compute_next_timeout(s, false);
    442        ptimer_transaction_commit(s->timer);
    443
    444        break;
    445
    446    case 5: /* OCR2 -- output compare register */
    447        s->ocr2 = value;
    448
    449        /* compute the new timeout */
    450        ptimer_transaction_begin(s->timer);
    451        imx_gpt_compute_next_timeout(s, false);
    452        ptimer_transaction_commit(s->timer);
    453
    454        break;
    455
    456    case 6: /* OCR3 -- output compare register */
    457        s->ocr3 = value;
    458
    459        /* compute the new timeout */
    460        ptimer_transaction_begin(s->timer);
    461        imx_gpt_compute_next_timeout(s, false);
    462        ptimer_transaction_commit(s->timer);
    463
    464        break;
    465
    466    default:
    467        qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%"
    468                      HWADDR_PRIx "\n", TYPE_IMX_GPT, __func__, offset);
    469        break;
    470    }
    471}
    472
    473static void imx_gpt_timeout(void *opaque)
    474{
    475    IMXGPTState *s = IMX_GPT(opaque);
    476
    477    DPRINTF("\n");
    478
    479    s->sr |= s->next_int;
    480    s->next_int = 0;
    481
    482    imx_gpt_compute_next_timeout(s, true);
    483
    484    imx_gpt_update_int(s);
    485
    486    if (s->freq && (s->cr & GPT_CR_EN)) {
    487        ptimer_run(s->timer, 1);
    488    }
    489}
    490
    491static const MemoryRegionOps imx_gpt_ops = {
    492    .read = imx_gpt_read,
    493    .write = imx_gpt_write,
    494    .endianness = DEVICE_NATIVE_ENDIAN,
    495};
    496
    497
    498static void imx_gpt_realize(DeviceState *dev, Error **errp)
    499{
    500    IMXGPTState *s = IMX_GPT(dev);
    501    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
    502
    503    sysbus_init_irq(sbd, &s->irq);
    504    memory_region_init_io(&s->iomem, OBJECT(s), &imx_gpt_ops, s, TYPE_IMX_GPT,
    505                          0x00001000);
    506    sysbus_init_mmio(sbd, &s->iomem);
    507
    508    s->timer = ptimer_init(imx_gpt_timeout, s, PTIMER_POLICY_DEFAULT);
    509}
    510
    511static void imx_gpt_class_init(ObjectClass *klass, void *data)
    512{
    513    DeviceClass *dc = DEVICE_CLASS(klass);
    514
    515    dc->realize = imx_gpt_realize;
    516    dc->reset = imx_gpt_reset;
    517    dc->vmsd = &vmstate_imx_timer_gpt;
    518    dc->desc = "i.MX general timer";
    519}
    520
    521static void imx25_gpt_init(Object *obj)
    522{
    523    IMXGPTState *s = IMX_GPT(obj);
    524
    525    s->clocks = imx25_gpt_clocks;
    526}
    527
    528static void imx31_gpt_init(Object *obj)
    529{
    530    IMXGPTState *s = IMX_GPT(obj);
    531
    532    s->clocks = imx31_gpt_clocks;
    533}
    534
    535static void imx6_gpt_init(Object *obj)
    536{
    537    IMXGPTState *s = IMX_GPT(obj);
    538
    539    s->clocks = imx6_gpt_clocks;
    540}
    541
    542static void imx7_gpt_init(Object *obj)
    543{
    544    IMXGPTState *s = IMX_GPT(obj);
    545
    546    s->clocks = imx7_gpt_clocks;
    547}
    548
    549static const TypeInfo imx25_gpt_info = {
    550    .name = TYPE_IMX25_GPT,
    551    .parent = TYPE_SYS_BUS_DEVICE,
    552    .instance_size = sizeof(IMXGPTState),
    553    .instance_init = imx25_gpt_init,
    554    .class_init = imx_gpt_class_init,
    555};
    556
    557static const TypeInfo imx31_gpt_info = {
    558    .name = TYPE_IMX31_GPT,
    559    .parent = TYPE_IMX25_GPT,
    560    .instance_init = imx31_gpt_init,
    561};
    562
    563static const TypeInfo imx6_gpt_info = {
    564    .name = TYPE_IMX6_GPT,
    565    .parent = TYPE_IMX25_GPT,
    566    .instance_init = imx6_gpt_init,
    567};
    568
    569static const TypeInfo imx7_gpt_info = {
    570    .name = TYPE_IMX7_GPT,
    571    .parent = TYPE_IMX25_GPT,
    572    .instance_init = imx7_gpt_init,
    573};
    574
    575static void imx_gpt_register_types(void)
    576{
    577    type_register_static(&imx25_gpt_info);
    578    type_register_static(&imx31_gpt_info);
    579    type_register_static(&imx6_gpt_info);
    580    type_register_static(&imx7_gpt_info);
    581}
    582
    583type_init(imx_gpt_register_types)