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

pxa2xx_dma.c (17102B)


      1/*
      2 * Intel XScale PXA255/270 DMA controller.
      3 *
      4 * Copyright (c) 2006 Openedhand Ltd.
      5 * Copyright (c) 2006 Thorsten Zitterell
      6 * Written by Andrzej Zaborowski <balrog@zabor.org>
      7 *
      8 * This code is licensed under the GPL.
      9 */
     10
     11#include "qemu/osdep.h"
     12#include "qemu/log.h"
     13#include "hw/hw.h"
     14#include "hw/irq.h"
     15#include "hw/qdev-properties.h"
     16#include "hw/arm/pxa.h"
     17#include "hw/sysbus.h"
     18#include "migration/vmstate.h"
     19#include "qapi/error.h"
     20#include "qemu/module.h"
     21#include "qom/object.h"
     22
     23#define PXA255_DMA_NUM_CHANNELS 16
     24#define PXA27X_DMA_NUM_CHANNELS 32
     25
     26#define PXA2XX_DMA_NUM_REQUESTS 75
     27
     28typedef struct {
     29    uint32_t descr;
     30    uint32_t src;
     31    uint32_t dest;
     32    uint32_t cmd;
     33    uint32_t state;
     34    int request;
     35} PXA2xxDMAChannel;
     36
     37#define TYPE_PXA2XX_DMA "pxa2xx-dma"
     38OBJECT_DECLARE_SIMPLE_TYPE(PXA2xxDMAState, PXA2XX_DMA)
     39
     40struct PXA2xxDMAState {
     41    SysBusDevice parent_obj;
     42
     43    MemoryRegion iomem;
     44    qemu_irq irq;
     45
     46    uint32_t stopintr;
     47    uint32_t eorintr;
     48    uint32_t rasintr;
     49    uint32_t startintr;
     50    uint32_t endintr;
     51
     52    uint32_t align;
     53    uint32_t pio;
     54
     55    int channels;
     56    PXA2xxDMAChannel *chan;
     57
     58    uint8_t req[PXA2XX_DMA_NUM_REQUESTS];
     59
     60    /* Flag to avoid recursive DMA invocations.  */
     61    int running;
     62};
     63
     64#define DCSR0	0x0000	/* DMA Control / Status register for Channel 0 */
     65#define DCSR31	0x007c	/* DMA Control / Status register for Channel 31 */
     66#define DALGN	0x00a0	/* DMA Alignment register */
     67#define DPCSR	0x00a4	/* DMA Programmed I/O Control Status register */
     68#define DRQSR0	0x00e0	/* DMA DREQ<0> Status register */
     69#define DRQSR1	0x00e4	/* DMA DREQ<1> Status register */
     70#define DRQSR2	0x00e8	/* DMA DREQ<2> Status register */
     71#define DINT	0x00f0	/* DMA Interrupt register */
     72#define DRCMR0	0x0100	/* Request to Channel Map register 0 */
     73#define DRCMR63	0x01fc	/* Request to Channel Map register 63 */
     74#define D_CH0	0x0200	/* Channel 0 Descriptor start */
     75#define DRCMR64	0x1100	/* Request to Channel Map register 64 */
     76#define DRCMR74	0x1128	/* Request to Channel Map register 74 */
     77
     78/* Per-channel register */
     79#define DDADR	0x00
     80#define DSADR	0x01
     81#define DTADR	0x02
     82#define DCMD	0x03
     83
     84/* Bit-field masks */
     85#define DRCMR_CHLNUM		0x1f
     86#define DRCMR_MAPVLD		(1 << 7)
     87#define DDADR_STOP		(1 << 0)
     88#define DDADR_BREN		(1 << 1)
     89#define DCMD_LEN		0x1fff
     90#define DCMD_WIDTH(x)		(1 << ((((x) >> 14) & 3) - 1))
     91#define DCMD_SIZE(x)		(4 << (((x) >> 16) & 3))
     92#define DCMD_FLYBYT		(1 << 19)
     93#define DCMD_FLYBYS		(1 << 20)
     94#define DCMD_ENDIRQEN		(1 << 21)
     95#define DCMD_STARTIRQEN		(1 << 22)
     96#define DCMD_CMPEN		(1 << 25)
     97#define DCMD_FLOWTRG		(1 << 28)
     98#define DCMD_FLOWSRC		(1 << 29)
     99#define DCMD_INCTRGADDR		(1 << 30)
    100#define DCMD_INCSRCADDR		(1 << 31)
    101#define DCSR_BUSERRINTR		(1 << 0)
    102#define DCSR_STARTINTR		(1 << 1)
    103#define DCSR_ENDINTR		(1 << 2)
    104#define DCSR_STOPINTR		(1 << 3)
    105#define DCSR_RASINTR		(1 << 4)
    106#define DCSR_REQPEND		(1 << 8)
    107#define DCSR_EORINT		(1 << 9)
    108#define DCSR_CMPST		(1 << 10)
    109#define DCSR_MASKRUN		(1 << 22)
    110#define DCSR_RASIRQEN		(1 << 23)
    111#define DCSR_CLRCMPST		(1 << 24)
    112#define DCSR_SETCMPST		(1 << 25)
    113#define DCSR_EORSTOPEN		(1 << 26)
    114#define DCSR_EORJMPEN		(1 << 27)
    115#define DCSR_EORIRQEN		(1 << 28)
    116#define DCSR_STOPIRQEN		(1 << 29)
    117#define DCSR_NODESCFETCH	(1 << 30)
    118#define DCSR_RUN		(1 << 31)
    119
    120static inline void pxa2xx_dma_update(PXA2xxDMAState *s, int ch)
    121{
    122    if (ch >= 0) {
    123        if ((s->chan[ch].state & DCSR_STOPIRQEN) &&
    124                (s->chan[ch].state & DCSR_STOPINTR))
    125            s->stopintr |= 1 << ch;
    126        else
    127            s->stopintr &= ~(1 << ch);
    128
    129        if ((s->chan[ch].state & DCSR_EORIRQEN) &&
    130                (s->chan[ch].state & DCSR_EORINT))
    131            s->eorintr |= 1 << ch;
    132        else
    133            s->eorintr &= ~(1 << ch);
    134
    135        if ((s->chan[ch].state & DCSR_RASIRQEN) &&
    136                (s->chan[ch].state & DCSR_RASINTR))
    137            s->rasintr |= 1 << ch;
    138        else
    139            s->rasintr &= ~(1 << ch);
    140
    141        if (s->chan[ch].state & DCSR_STARTINTR)
    142            s->startintr |= 1 << ch;
    143        else
    144            s->startintr &= ~(1 << ch);
    145
    146        if (s->chan[ch].state & DCSR_ENDINTR)
    147            s->endintr |= 1 << ch;
    148        else
    149            s->endintr &= ~(1 << ch);
    150    }
    151
    152    if (s->stopintr | s->eorintr | s->rasintr | s->startintr | s->endintr)
    153        qemu_irq_raise(s->irq);
    154    else
    155        qemu_irq_lower(s->irq);
    156}
    157
    158static inline void pxa2xx_dma_descriptor_fetch(
    159                PXA2xxDMAState *s, int ch)
    160{
    161    uint32_t desc[4];
    162    hwaddr daddr = s->chan[ch].descr & ~0xf;
    163    if ((s->chan[ch].descr & DDADR_BREN) && (s->chan[ch].state & DCSR_CMPST))
    164        daddr += 32;
    165
    166    cpu_physical_memory_read(daddr, desc, 16);
    167    s->chan[ch].descr = desc[DDADR];
    168    s->chan[ch].src = desc[DSADR];
    169    s->chan[ch].dest = desc[DTADR];
    170    s->chan[ch].cmd = desc[DCMD];
    171
    172    if (s->chan[ch].cmd & DCMD_FLOWSRC)
    173        s->chan[ch].src &= ~3;
    174    if (s->chan[ch].cmd & DCMD_FLOWTRG)
    175        s->chan[ch].dest &= ~3;
    176
    177    if (s->chan[ch].cmd & (DCMD_CMPEN | DCMD_FLYBYS | DCMD_FLYBYT))
    178        printf("%s: unsupported mode in channel %i\n", __func__, ch);
    179
    180    if (s->chan[ch].cmd & DCMD_STARTIRQEN)
    181        s->chan[ch].state |= DCSR_STARTINTR;
    182}
    183
    184static void pxa2xx_dma_run(PXA2xxDMAState *s)
    185{
    186    int c, srcinc, destinc;
    187    uint32_t n, size;
    188    uint32_t width;
    189    uint32_t length;
    190    uint8_t buffer[32];
    191    PXA2xxDMAChannel *ch;
    192
    193    if (s->running ++)
    194        return;
    195
    196    while (s->running) {
    197        s->running = 1;
    198        for (c = 0; c < s->channels; c ++) {
    199            ch = &s->chan[c];
    200
    201            while ((ch->state & DCSR_RUN) && !(ch->state & DCSR_STOPINTR)) {
    202                /* Test for pending requests */
    203                if ((ch->cmd & (DCMD_FLOWSRC | DCMD_FLOWTRG)) && !ch->request)
    204                    break;
    205
    206                length = ch->cmd & DCMD_LEN;
    207                size = DCMD_SIZE(ch->cmd);
    208                width = DCMD_WIDTH(ch->cmd);
    209
    210                srcinc = (ch->cmd & DCMD_INCSRCADDR) ? width : 0;
    211                destinc = (ch->cmd & DCMD_INCTRGADDR) ? width : 0;
    212
    213                while (length) {
    214                    size = MIN(length, size);
    215
    216                    for (n = 0; n < size; n += width) {
    217                        cpu_physical_memory_read(ch->src, buffer + n, width);
    218                        ch->src += srcinc;
    219                    }
    220
    221                    for (n = 0; n < size; n += width) {
    222                        cpu_physical_memory_write(ch->dest, buffer + n, width);
    223                        ch->dest += destinc;
    224                    }
    225
    226                    length -= size;
    227
    228                    if ((ch->cmd & (DCMD_FLOWSRC | DCMD_FLOWTRG)) &&
    229                            !ch->request) {
    230                        ch->state |= DCSR_EORINT;
    231                        if (ch->state & DCSR_EORSTOPEN)
    232                            ch->state |= DCSR_STOPINTR;
    233                        if ((ch->state & DCSR_EORJMPEN) &&
    234                                        !(ch->state & DCSR_NODESCFETCH))
    235                            pxa2xx_dma_descriptor_fetch(s, c);
    236                        break;
    237                    }
    238                }
    239
    240                ch->cmd = (ch->cmd & ~DCMD_LEN) | length;
    241
    242                /* Is the transfer complete now? */
    243                if (!length) {
    244                    if (ch->cmd & DCMD_ENDIRQEN)
    245                        ch->state |= DCSR_ENDINTR;
    246
    247                    if ((ch->state & DCSR_NODESCFETCH) ||
    248                                (ch->descr & DDADR_STOP) ||
    249                                (ch->state & DCSR_EORSTOPEN)) {
    250                        ch->state |= DCSR_STOPINTR;
    251                        ch->state &= ~DCSR_RUN;
    252
    253                        break;
    254                    }
    255
    256                    ch->state |= DCSR_STOPINTR;
    257                    break;
    258                }
    259            }
    260        }
    261
    262        s->running --;
    263    }
    264}
    265
    266static uint64_t pxa2xx_dma_read(void *opaque, hwaddr offset,
    267                                unsigned size)
    268{
    269    PXA2xxDMAState *s = (PXA2xxDMAState *) opaque;
    270    unsigned int channel;
    271
    272    if (size != 4) {
    273        qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad access width %u\n",
    274                      __func__, size);
    275        return 5;
    276    }
    277
    278    switch (offset) {
    279    case DRCMR64 ... DRCMR74:
    280        offset -= DRCMR64 - DRCMR0 - (64 << 2);
    281        /* Fall through */
    282    case DRCMR0 ... DRCMR63:
    283        channel = (offset - DRCMR0) >> 2;
    284        return s->req[channel];
    285
    286    case DRQSR0:
    287    case DRQSR1:
    288    case DRQSR2:
    289        return 0;
    290
    291    case DCSR0 ... DCSR31:
    292        channel = offset >> 2;
    293        if (s->chan[channel].request)
    294            return s->chan[channel].state | DCSR_REQPEND;
    295        return s->chan[channel].state;
    296
    297    case DINT:
    298        return s->stopintr | s->eorintr | s->rasintr |
    299                s->startintr | s->endintr;
    300
    301    case DALGN:
    302        return s->align;
    303
    304    case DPCSR:
    305        return s->pio;
    306    }
    307
    308    if (offset >= D_CH0 && offset < D_CH0 + (s->channels << 4)) {
    309        channel = (offset - D_CH0) >> 4;
    310        switch ((offset & 0x0f) >> 2) {
    311        case DDADR:
    312            return s->chan[channel].descr;
    313        case DSADR:
    314            return s->chan[channel].src;
    315        case DTADR:
    316            return s->chan[channel].dest;
    317        case DCMD:
    318            return s->chan[channel].cmd;
    319        }
    320    }
    321    qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIX "\n",
    322                  __func__, offset);
    323    return 7;
    324}
    325
    326static void pxa2xx_dma_write(void *opaque, hwaddr offset,
    327                             uint64_t value, unsigned size)
    328{
    329    PXA2xxDMAState *s = (PXA2xxDMAState *) opaque;
    330    unsigned int channel;
    331
    332    if (size != 4) {
    333        qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad access width %u\n",
    334                      __func__, size);
    335        return;
    336    }
    337
    338    switch (offset) {
    339    case DRCMR64 ... DRCMR74:
    340        offset -= DRCMR64 - DRCMR0 - (64 << 2);
    341        /* Fall through */
    342    case DRCMR0 ... DRCMR63:
    343        channel = (offset - DRCMR0) >> 2;
    344
    345        if (value & DRCMR_MAPVLD)
    346            if ((value & DRCMR_CHLNUM) > s->channels)
    347                hw_error("%s: Bad DMA channel %i\n",
    348                         __func__, (unsigned)value & DRCMR_CHLNUM);
    349
    350        s->req[channel] = value;
    351        break;
    352
    353    case DRQSR0:
    354    case DRQSR1:
    355    case DRQSR2:
    356        /* Nothing to do */
    357        break;
    358
    359    case DCSR0 ... DCSR31:
    360        channel = offset >> 2;
    361        s->chan[channel].state &= 0x0000071f & ~(value &
    362                        (DCSR_EORINT | DCSR_ENDINTR |
    363                         DCSR_STARTINTR | DCSR_BUSERRINTR));
    364        s->chan[channel].state |= value & 0xfc800000;
    365
    366        if (s->chan[channel].state & DCSR_STOPIRQEN)
    367            s->chan[channel].state &= ~DCSR_STOPINTR;
    368
    369        if (value & DCSR_NODESCFETCH) {
    370            /* No-descriptor-fetch mode */
    371            if (value & DCSR_RUN) {
    372                s->chan[channel].state &= ~DCSR_STOPINTR;
    373                pxa2xx_dma_run(s);
    374            }
    375        } else {
    376            /* Descriptor-fetch mode */
    377            if (value & DCSR_RUN) {
    378                s->chan[channel].state &= ~DCSR_STOPINTR;
    379                pxa2xx_dma_descriptor_fetch(s, channel);
    380                pxa2xx_dma_run(s);
    381            }
    382        }
    383
    384        /* Shouldn't matter as our DMA is synchronous.  */
    385        if (!(value & (DCSR_RUN | DCSR_MASKRUN)))
    386            s->chan[channel].state |= DCSR_STOPINTR;
    387
    388        if (value & DCSR_CLRCMPST)
    389            s->chan[channel].state &= ~DCSR_CMPST;
    390        if (value & DCSR_SETCMPST)
    391            s->chan[channel].state |= DCSR_CMPST;
    392
    393        pxa2xx_dma_update(s, channel);
    394        break;
    395
    396    case DALGN:
    397        s->align = value;
    398        break;
    399
    400    case DPCSR:
    401        s->pio = value & 0x80000001;
    402        break;
    403
    404    default:
    405        if (offset >= D_CH0 && offset < D_CH0 + (s->channels << 4)) {
    406            channel = (offset - D_CH0) >> 4;
    407            switch ((offset & 0x0f) >> 2) {
    408            case DDADR:
    409                s->chan[channel].descr = value;
    410                break;
    411            case DSADR:
    412                s->chan[channel].src = value;
    413                break;
    414            case DTADR:
    415                s->chan[channel].dest = value;
    416                break;
    417            case DCMD:
    418                s->chan[channel].cmd = value;
    419                break;
    420            default:
    421                goto fail;
    422            }
    423
    424            break;
    425        }
    426    fail:
    427        qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIX "\n",
    428                      __func__, offset);
    429    }
    430}
    431
    432static const MemoryRegionOps pxa2xx_dma_ops = {
    433    .read = pxa2xx_dma_read,
    434    .write = pxa2xx_dma_write,
    435    .endianness = DEVICE_NATIVE_ENDIAN,
    436};
    437
    438static void pxa2xx_dma_request(void *opaque, int req_num, int on)
    439{
    440    PXA2xxDMAState *s = opaque;
    441    int ch;
    442    if (req_num < 0 || req_num >= PXA2XX_DMA_NUM_REQUESTS)
    443        hw_error("%s: Bad DMA request %i\n", __func__, req_num);
    444
    445    if (!(s->req[req_num] & DRCMR_MAPVLD))
    446        return;
    447    ch = s->req[req_num] & DRCMR_CHLNUM;
    448
    449    if (!s->chan[ch].request && on)
    450        s->chan[ch].state |= DCSR_RASINTR;
    451    else
    452        s->chan[ch].state &= ~DCSR_RASINTR;
    453    if (s->chan[ch].request && !on)
    454        s->chan[ch].state |= DCSR_EORINT;
    455
    456    s->chan[ch].request = on;
    457    if (on) {
    458        pxa2xx_dma_run(s);
    459        pxa2xx_dma_update(s, ch);
    460    }
    461}
    462
    463static void pxa2xx_dma_init(Object *obj)
    464{
    465    DeviceState *dev = DEVICE(obj);
    466    PXA2xxDMAState *s = PXA2XX_DMA(obj);
    467    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
    468
    469    memset(s->req, 0, sizeof(uint8_t) * PXA2XX_DMA_NUM_REQUESTS);
    470
    471    qdev_init_gpio_in(dev, pxa2xx_dma_request, PXA2XX_DMA_NUM_REQUESTS);
    472
    473    memory_region_init_io(&s->iomem, obj, &pxa2xx_dma_ops, s,
    474                          "pxa2xx.dma", 0x00010000);
    475    sysbus_init_mmio(sbd, &s->iomem);
    476    sysbus_init_irq(sbd, &s->irq);
    477}
    478
    479static void pxa2xx_dma_realize(DeviceState *dev, Error **errp)
    480{
    481    PXA2xxDMAState *s = PXA2XX_DMA(dev);
    482    int i;
    483
    484    if (s->channels <= 0) {
    485        error_setg(errp, "channels value invalid");
    486        return;
    487    }
    488
    489    s->chan = g_new0(PXA2xxDMAChannel, s->channels);
    490
    491    for (i = 0; i < s->channels; i ++)
    492        s->chan[i].state = DCSR_STOPINTR;
    493}
    494
    495DeviceState *pxa27x_dma_init(hwaddr base, qemu_irq irq)
    496{
    497    DeviceState *dev;
    498
    499    dev = qdev_new("pxa2xx-dma");
    500    qdev_prop_set_int32(dev, "channels", PXA27X_DMA_NUM_CHANNELS);
    501    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
    502
    503    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
    504    sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq);
    505
    506    return dev;
    507}
    508
    509DeviceState *pxa255_dma_init(hwaddr base, qemu_irq irq)
    510{
    511    DeviceState *dev;
    512
    513    dev = qdev_new("pxa2xx-dma");
    514    qdev_prop_set_int32(dev, "channels", PXA27X_DMA_NUM_CHANNELS);
    515    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
    516
    517    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
    518    sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq);
    519
    520    return dev;
    521}
    522
    523static bool is_version_0(void *opaque, int version_id)
    524{
    525    return version_id == 0;
    526}
    527
    528static const VMStateDescription vmstate_pxa2xx_dma_chan = {
    529    .name = "pxa2xx_dma_chan",
    530    .version_id = 1,
    531    .minimum_version_id = 1,
    532    .fields = (VMStateField[]) {
    533        VMSTATE_UINT32(descr, PXA2xxDMAChannel),
    534        VMSTATE_UINT32(src, PXA2xxDMAChannel),
    535        VMSTATE_UINT32(dest, PXA2xxDMAChannel),
    536        VMSTATE_UINT32(cmd, PXA2xxDMAChannel),
    537        VMSTATE_UINT32(state, PXA2xxDMAChannel),
    538        VMSTATE_INT32(request, PXA2xxDMAChannel),
    539        VMSTATE_END_OF_LIST(),
    540    },
    541};
    542
    543static const VMStateDescription vmstate_pxa2xx_dma = {
    544    .name = "pxa2xx_dma",
    545    .version_id = 1,
    546    .minimum_version_id = 0,
    547    .fields = (VMStateField[]) {
    548        VMSTATE_UNUSED_TEST(is_version_0, 4),
    549        VMSTATE_UINT32(stopintr, PXA2xxDMAState),
    550        VMSTATE_UINT32(eorintr, PXA2xxDMAState),
    551        VMSTATE_UINT32(rasintr, PXA2xxDMAState),
    552        VMSTATE_UINT32(startintr, PXA2xxDMAState),
    553        VMSTATE_UINT32(endintr, PXA2xxDMAState),
    554        VMSTATE_UINT32(align, PXA2xxDMAState),
    555        VMSTATE_UINT32(pio, PXA2xxDMAState),
    556        VMSTATE_BUFFER(req, PXA2xxDMAState),
    557        VMSTATE_STRUCT_VARRAY_POINTER_INT32(chan, PXA2xxDMAState, channels,
    558                vmstate_pxa2xx_dma_chan, PXA2xxDMAChannel),
    559        VMSTATE_END_OF_LIST(),
    560    },
    561};
    562
    563static Property pxa2xx_dma_properties[] = {
    564    DEFINE_PROP_INT32("channels", PXA2xxDMAState, channels, -1),
    565    DEFINE_PROP_END_OF_LIST(),
    566};
    567
    568static void pxa2xx_dma_class_init(ObjectClass *klass, void *data)
    569{
    570    DeviceClass *dc = DEVICE_CLASS(klass);
    571
    572    dc->desc = "PXA2xx DMA controller";
    573    dc->vmsd = &vmstate_pxa2xx_dma;
    574    device_class_set_props(dc, pxa2xx_dma_properties);
    575    dc->realize = pxa2xx_dma_realize;
    576}
    577
    578static const TypeInfo pxa2xx_dma_info = {
    579    .name          = TYPE_PXA2XX_DMA,
    580    .parent        = TYPE_SYS_BUS_DEVICE,
    581    .instance_size = sizeof(PXA2xxDMAState),
    582    .instance_init = pxa2xx_dma_init,
    583    .class_init    = pxa2xx_dma_class_init,
    584};
    585
    586static void pxa2xx_dma_register_types(void)
    587{
    588    type_register_static(&pxa2xx_dma_info);
    589}
    590
    591type_init(pxa2xx_dma_register_types)