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_spi.c (13407B)


      1/*
      2 * IMX SPI Controller
      3 *
      4 * Copyright (c) 2016 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/irq.h"
     13#include "hw/ssi/imx_spi.h"
     14#include "migration/vmstate.h"
     15#include "qemu/log.h"
     16#include "qemu/module.h"
     17
     18#ifndef DEBUG_IMX_SPI
     19#define DEBUG_IMX_SPI 0
     20#endif
     21
     22#define DPRINTF(fmt, args...) \
     23    do { \
     24        if (DEBUG_IMX_SPI) { \
     25            fprintf(stderr, "[%s]%s: " fmt , TYPE_IMX_SPI, \
     26                                             __func__, ##args); \
     27        } \
     28    } while (0)
     29
     30static const char *imx_spi_reg_name(uint32_t reg)
     31{
     32    static char unknown[20];
     33
     34    switch (reg) {
     35    case ECSPI_RXDATA:
     36        return  "ECSPI_RXDATA";
     37    case ECSPI_TXDATA:
     38        return  "ECSPI_TXDATA";
     39    case ECSPI_CONREG:
     40        return  "ECSPI_CONREG";
     41    case ECSPI_CONFIGREG:
     42        return  "ECSPI_CONFIGREG";
     43    case ECSPI_INTREG:
     44        return  "ECSPI_INTREG";
     45    case ECSPI_DMAREG:
     46        return  "ECSPI_DMAREG";
     47    case ECSPI_STATREG:
     48        return  "ECSPI_STATREG";
     49    case ECSPI_PERIODREG:
     50        return  "ECSPI_PERIODREG";
     51    case ECSPI_TESTREG:
     52        return  "ECSPI_TESTREG";
     53    case ECSPI_MSGDATA:
     54        return  "ECSPI_MSGDATA";
     55    default:
     56        sprintf(unknown, "%u ?", reg);
     57        return unknown;
     58    }
     59}
     60
     61static const VMStateDescription vmstate_imx_spi = {
     62    .name = TYPE_IMX_SPI,
     63    .version_id = 1,
     64    .minimum_version_id = 1,
     65    .fields = (VMStateField[]) {
     66        VMSTATE_FIFO32(tx_fifo, IMXSPIState),
     67        VMSTATE_FIFO32(rx_fifo, IMXSPIState),
     68        VMSTATE_INT16(burst_length, IMXSPIState),
     69        VMSTATE_UINT32_ARRAY(regs, IMXSPIState, ECSPI_MAX),
     70        VMSTATE_END_OF_LIST()
     71    },
     72};
     73
     74static void imx_spi_txfifo_reset(IMXSPIState *s)
     75{
     76    fifo32_reset(&s->tx_fifo);
     77    s->regs[ECSPI_STATREG] |= ECSPI_STATREG_TE;
     78    s->regs[ECSPI_STATREG] &= ~ECSPI_STATREG_TF;
     79}
     80
     81static void imx_spi_rxfifo_reset(IMXSPIState *s)
     82{
     83    fifo32_reset(&s->rx_fifo);
     84    s->regs[ECSPI_STATREG] &= ~ECSPI_STATREG_RR;
     85    s->regs[ECSPI_STATREG] &= ~ECSPI_STATREG_RF;
     86    s->regs[ECSPI_STATREG] &= ~ECSPI_STATREG_RO;
     87}
     88
     89static void imx_spi_update_irq(IMXSPIState *s)
     90{
     91    int level;
     92
     93    if (fifo32_is_empty(&s->rx_fifo)) {
     94        s->regs[ECSPI_STATREG] &= ~ECSPI_STATREG_RR;
     95    } else {
     96        s->regs[ECSPI_STATREG] |= ECSPI_STATREG_RR;
     97    }
     98
     99    if (fifo32_is_full(&s->rx_fifo)) {
    100        s->regs[ECSPI_STATREG] |= ECSPI_STATREG_RF;
    101    } else {
    102        s->regs[ECSPI_STATREG] &= ~ECSPI_STATREG_RF;
    103    }
    104
    105    if (fifo32_is_empty(&s->tx_fifo)) {
    106        s->regs[ECSPI_STATREG] |= ECSPI_STATREG_TE;
    107    } else {
    108        s->regs[ECSPI_STATREG] &= ~ECSPI_STATREG_TE;
    109    }
    110
    111    if (fifo32_is_full(&s->tx_fifo)) {
    112        s->regs[ECSPI_STATREG] |= ECSPI_STATREG_TF;
    113    } else {
    114        s->regs[ECSPI_STATREG] &= ~ECSPI_STATREG_TF;
    115    }
    116
    117    level = s->regs[ECSPI_STATREG] & s->regs[ECSPI_INTREG] ? 1 : 0;
    118
    119    qemu_set_irq(s->irq, level);
    120
    121    DPRINTF("IRQ level is %d\n", level);
    122}
    123
    124static uint8_t imx_spi_selected_channel(IMXSPIState *s)
    125{
    126    return EXTRACT(s->regs[ECSPI_CONREG], ECSPI_CONREG_CHANNEL_SELECT);
    127}
    128
    129static uint32_t imx_spi_burst_length(IMXSPIState *s)
    130{
    131    uint32_t burst;
    132
    133    burst = EXTRACT(s->regs[ECSPI_CONREG], ECSPI_CONREG_BURST_LENGTH) + 1;
    134    if (burst % 8) {
    135        burst = ROUND_UP(burst, 8);
    136    }
    137
    138    return burst;
    139}
    140
    141static bool imx_spi_is_enabled(IMXSPIState *s)
    142{
    143    return s->regs[ECSPI_CONREG] & ECSPI_CONREG_EN;
    144}
    145
    146static bool imx_spi_channel_is_master(IMXSPIState *s)
    147{
    148    uint8_t mode = EXTRACT(s->regs[ECSPI_CONREG], ECSPI_CONREG_CHANNEL_MODE);
    149
    150    return (mode & (1 << imx_spi_selected_channel(s))) ? true : false;
    151}
    152
    153static bool imx_spi_is_multiple_master_burst(IMXSPIState *s)
    154{
    155    uint8_t wave = EXTRACT(s->regs[ECSPI_CONFIGREG], ECSPI_CONFIGREG_SS_CTL);
    156
    157    return imx_spi_channel_is_master(s) &&
    158           !(s->regs[ECSPI_CONREG] & ECSPI_CONREG_SMC) &&
    159           ((wave & (1 << imx_spi_selected_channel(s))) ? true : false);
    160}
    161
    162static void imx_spi_flush_txfifo(IMXSPIState *s)
    163{
    164    uint32_t tx;
    165    uint32_t rx;
    166
    167    DPRINTF("Begin: TX Fifo Size = %d, RX Fifo Size = %d\n",
    168            fifo32_num_used(&s->tx_fifo), fifo32_num_used(&s->rx_fifo));
    169
    170    while (!fifo32_is_empty(&s->tx_fifo)) {
    171        int tx_burst = 0;
    172
    173        if (s->burst_length <= 0) {
    174            s->burst_length = imx_spi_burst_length(s);
    175
    176            DPRINTF("Burst length = %d\n", s->burst_length);
    177
    178            if (imx_spi_is_multiple_master_burst(s)) {
    179                s->regs[ECSPI_CONREG] |= ECSPI_CONREG_XCH;
    180            }
    181        }
    182
    183        tx = fifo32_pop(&s->tx_fifo);
    184
    185        DPRINTF("data tx:0x%08x\n", tx);
    186
    187        tx_burst = (s->burst_length % 32) ? : 32;
    188
    189        rx = 0;
    190
    191        while (tx_burst > 0) {
    192            uint8_t byte = tx >> (tx_burst - 8);
    193
    194            DPRINTF("writing 0x%02x\n", (uint32_t)byte);
    195
    196            /* We need to write one byte at a time */
    197            byte = ssi_transfer(s->bus, byte);
    198
    199            DPRINTF("0x%02x read\n", (uint32_t)byte);
    200
    201            rx = (rx << 8) | byte;
    202
    203            /* Remove 8 bits from the actual burst */
    204            tx_burst -= 8;
    205            s->burst_length -= 8;
    206        }
    207
    208        DPRINTF("data rx:0x%08x\n", rx);
    209
    210        if (fifo32_is_full(&s->rx_fifo)) {
    211            s->regs[ECSPI_STATREG] |= ECSPI_STATREG_RO;
    212        } else {
    213            fifo32_push(&s->rx_fifo, rx);
    214        }
    215
    216        if (s->burst_length <= 0) {
    217            if (!imx_spi_is_multiple_master_burst(s)) {
    218                s->regs[ECSPI_STATREG] |= ECSPI_STATREG_TC;
    219                break;
    220            }
    221        }
    222    }
    223
    224    if (fifo32_is_empty(&s->tx_fifo)) {
    225        s->regs[ECSPI_STATREG] |= ECSPI_STATREG_TC;
    226        s->regs[ECSPI_CONREG] &= ~ECSPI_CONREG_XCH;
    227    }
    228
    229    /* TODO: We should also use TDR and RDR bits */
    230
    231    DPRINTF("End: TX Fifo Size = %d, RX Fifo Size = %d\n",
    232            fifo32_num_used(&s->tx_fifo), fifo32_num_used(&s->rx_fifo));
    233}
    234
    235static void imx_spi_common_reset(IMXSPIState *s)
    236{
    237    int i;
    238
    239    for (i = 0; i < ARRAY_SIZE(s->regs); i++) {
    240        switch (i) {
    241        case ECSPI_CONREG:
    242            /* CONREG is not updated on soft reset */
    243            break;
    244        case ECSPI_STATREG:
    245            s->regs[i] = 0x00000003;
    246            break;
    247        default:
    248            s->regs[i] = 0;
    249            break;
    250        }
    251    }
    252
    253    imx_spi_rxfifo_reset(s);
    254    imx_spi_txfifo_reset(s);
    255
    256    s->burst_length = 0;
    257}
    258
    259static void imx_spi_soft_reset(IMXSPIState *s)
    260{
    261    int i;
    262
    263    imx_spi_common_reset(s);
    264
    265    imx_spi_update_irq(s);
    266
    267    for (i = 0; i < ECSPI_NUM_CS; i++) {
    268        qemu_set_irq(s->cs_lines[i], 1);
    269    }
    270}
    271
    272static void imx_spi_reset(DeviceState *dev)
    273{
    274    IMXSPIState *s = IMX_SPI(dev);
    275
    276    imx_spi_common_reset(s);
    277    s->regs[ECSPI_CONREG] = 0;
    278}
    279
    280static uint64_t imx_spi_read(void *opaque, hwaddr offset, unsigned size)
    281{
    282    uint32_t value = 0;
    283    IMXSPIState *s = opaque;
    284    uint32_t index = offset >> 2;
    285
    286    if (index >=  ECSPI_MAX) {
    287        qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%"
    288                      HWADDR_PRIx "\n", TYPE_IMX_SPI, __func__, offset);
    289        return 0;
    290    }
    291
    292    value = s->regs[index];
    293
    294    if (imx_spi_is_enabled(s)) {
    295        switch (index) {
    296        case ECSPI_RXDATA:
    297            if (fifo32_is_empty(&s->rx_fifo)) {
    298                /* value is undefined */
    299                value = 0xdeadbeef;
    300            } else {
    301                /* read from the RX FIFO */
    302                value = fifo32_pop(&s->rx_fifo);
    303            }
    304            break;
    305        case ECSPI_TXDATA:
    306            qemu_log_mask(LOG_GUEST_ERROR,
    307                          "[%s]%s: Trying to read from TX FIFO\n",
    308                          TYPE_IMX_SPI, __func__);
    309
    310            /* Reading from TXDATA gives 0 */
    311            break;
    312        case ECSPI_MSGDATA:
    313            qemu_log_mask(LOG_GUEST_ERROR,
    314                          "[%s]%s: Trying to read from MSG FIFO\n",
    315                          TYPE_IMX_SPI, __func__);
    316            /* Reading from MSGDATA gives 0 */
    317            break;
    318        default:
    319            break;
    320        }
    321
    322        imx_spi_update_irq(s);
    323    }
    324    DPRINTF("reg[%s] => 0x%" PRIx32 "\n", imx_spi_reg_name(index), value);
    325
    326    return (uint64_t)value;
    327}
    328
    329static void imx_spi_write(void *opaque, hwaddr offset, uint64_t value,
    330                           unsigned size)
    331{
    332    IMXSPIState *s = opaque;
    333    uint32_t index = offset >> 2;
    334    uint32_t change_mask;
    335    uint32_t burst;
    336
    337    if (index >=  ECSPI_MAX) {
    338        qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%"
    339                      HWADDR_PRIx "\n", TYPE_IMX_SPI, __func__, offset);
    340        return;
    341    }
    342
    343    DPRINTF("reg[%s] <= 0x%" PRIx32 "\n", imx_spi_reg_name(index),
    344            (uint32_t)value);
    345
    346    if (!imx_spi_is_enabled(s)) {
    347        /* Block is disabled */
    348        if (index != ECSPI_CONREG) {
    349            /* Ignore access */
    350            return;
    351        }
    352    }
    353
    354    change_mask = s->regs[index] ^ value;
    355
    356    switch (index) {
    357    case ECSPI_RXDATA:
    358        qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Trying to write to RX FIFO\n",
    359                      TYPE_IMX_SPI, __func__);
    360        break;
    361    case ECSPI_TXDATA:
    362        if (fifo32_is_full(&s->tx_fifo)) {
    363            /* Ignore writes if queue is full */
    364            break;
    365        }
    366
    367        fifo32_push(&s->tx_fifo, (uint32_t)value);
    368
    369        if (imx_spi_channel_is_master(s) &&
    370            (s->regs[ECSPI_CONREG] & ECSPI_CONREG_SMC)) {
    371            /*
    372             * Start emitting if current channel is master and SMC bit is
    373             * set.
    374             */
    375            imx_spi_flush_txfifo(s);
    376        }
    377
    378        break;
    379    case ECSPI_STATREG:
    380        /* the RO and TC bits are write-one-to-clear */
    381        value &= ECSPI_STATREG_RO | ECSPI_STATREG_TC;
    382        s->regs[ECSPI_STATREG] &= ~value;
    383
    384        break;
    385    case ECSPI_CONREG:
    386        s->regs[ECSPI_CONREG] = value;
    387
    388        burst = EXTRACT(s->regs[ECSPI_CONREG], ECSPI_CONREG_BURST_LENGTH) + 1;
    389        if (burst % 8) {
    390            qemu_log_mask(LOG_UNIMP,
    391                          "[%s]%s: burst length %d not supported: rounding up to next multiple of 8\n",
    392                          TYPE_IMX_SPI, __func__, burst);
    393        }
    394
    395        if (!imx_spi_is_enabled(s)) {
    396            /* device is disabled, so this is a soft reset */
    397            imx_spi_soft_reset(s);
    398
    399            return;
    400        }
    401
    402        if (imx_spi_channel_is_master(s)) {
    403            int i;
    404
    405            /* We are in master mode */
    406
    407            for (i = 0; i < ECSPI_NUM_CS; i++) {
    408                qemu_set_irq(s->cs_lines[i],
    409                             i == imx_spi_selected_channel(s) ? 0 : 1);
    410            }
    411
    412            if ((value & change_mask & ECSPI_CONREG_SMC) &&
    413                !fifo32_is_empty(&s->tx_fifo)) {
    414                /* SMC bit is set and TX FIFO has some slots filled in */
    415                imx_spi_flush_txfifo(s);
    416            } else if ((value & change_mask & ECSPI_CONREG_XCH) &&
    417                !(value & ECSPI_CONREG_SMC)) {
    418                /* This is a request to start emitting */
    419                imx_spi_flush_txfifo(s);
    420            }
    421        }
    422
    423        break;
    424    case ECSPI_MSGDATA:
    425        /* it is not clear from the spec what MSGDATA is for */
    426        /* Anyway it is not used by Linux driver */
    427        /* So for now we just ignore it */
    428        qemu_log_mask(LOG_UNIMP,
    429                      "[%s]%s: Trying to write to MSGDATA, ignoring\n",
    430                      TYPE_IMX_SPI, __func__);
    431        break;
    432    default:
    433        s->regs[index] = value;
    434
    435        break;
    436    }
    437
    438    imx_spi_update_irq(s);
    439}
    440
    441static const struct MemoryRegionOps imx_spi_ops = {
    442    .read = imx_spi_read,
    443    .write = imx_spi_write,
    444    .endianness = DEVICE_NATIVE_ENDIAN,
    445    .valid = {
    446        /*
    447         * Our device would not work correctly if the guest was doing
    448         * unaligned access. This might not be a limitation on the real
    449         * device but in practice there is no reason for a guest to access
    450         * this device unaligned.
    451         */
    452        .min_access_size = 4,
    453        .max_access_size = 4,
    454        .unaligned = false,
    455    },
    456};
    457
    458static void imx_spi_realize(DeviceState *dev, Error **errp)
    459{
    460    IMXSPIState *s = IMX_SPI(dev);
    461    int i;
    462
    463    s->bus = ssi_create_bus(dev, "spi");
    464
    465    memory_region_init_io(&s->iomem, OBJECT(dev), &imx_spi_ops, s,
    466                          TYPE_IMX_SPI, 0x1000);
    467    sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
    468    sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq);
    469
    470    for (i = 0; i < ECSPI_NUM_CS; ++i) {
    471        sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->cs_lines[i]);
    472    }
    473
    474    fifo32_create(&s->tx_fifo, ECSPI_FIFO_SIZE);
    475    fifo32_create(&s->rx_fifo, ECSPI_FIFO_SIZE);
    476}
    477
    478static void imx_spi_class_init(ObjectClass *klass, void *data)
    479{
    480    DeviceClass *dc = DEVICE_CLASS(klass);
    481
    482    dc->realize = imx_spi_realize;
    483    dc->vmsd = &vmstate_imx_spi;
    484    dc->reset = imx_spi_reset;
    485    dc->desc = "i.MX SPI Controller";
    486}
    487
    488static const TypeInfo imx_spi_info = {
    489    .name          = TYPE_IMX_SPI,
    490    .parent        = TYPE_SYS_BUS_DEVICE,
    491    .instance_size = sizeof(IMXSPIState),
    492    .class_init    = imx_spi_class_init,
    493};
    494
    495static void imx_spi_register_types(void)
    496{
    497    type_register_static(&imx_spi_info);
    498}
    499
    500type_init(imx_spi_register_types)