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

pl330.c (50348B)


      1/*
      2 * ARM PrimeCell PL330 DMA Controller
      3 *
      4 * Copyright (c) 2009 Samsung Electronics.
      5 * Contributed by Kirill Batuzov <batuzovk@ispras.ru>
      6 * Copyright (c) 2012 Peter A.G. Crosthwaite (peter.crosthwaite@petalogix.com)
      7 * Copyright (c) 2012 PetaLogix Pty Ltd.
      8 *
      9 * This program is free software; you can redistribute it and/or
     10 * modify it under the terms of the GNU General Public License
     11 * as published by the Free Software Foundation; version 2 or later.
     12 *
     13 * You should have received a copy of the GNU General Public License along
     14 * with this program; if not, see <http://www.gnu.org/licenses/>.
     15 */
     16
     17#include "qemu/osdep.h"
     18#include "qemu-common.h"
     19#include "hw/irq.h"
     20#include "hw/qdev-properties.h"
     21#include "hw/sysbus.h"
     22#include "migration/vmstate.h"
     23#include "qapi/error.h"
     24#include "qemu/timer.h"
     25#include "sysemu/dma.h"
     26#include "qemu/log.h"
     27#include "qemu/module.h"
     28#include "trace.h"
     29#include "qom/object.h"
     30
     31#ifndef PL330_ERR_DEBUG
     32#define PL330_ERR_DEBUG 0
     33#endif
     34
     35#define PL330_PERIPH_NUM            32
     36#define PL330_MAX_BURST_LEN         128
     37#define PL330_INSN_MAXSIZE          6
     38
     39#define PL330_FIFO_OK               0
     40#define PL330_FIFO_STALL            1
     41#define PL330_FIFO_ERR              (-1)
     42
     43#define PL330_FAULT_UNDEF_INSTR             (1 <<  0)
     44#define PL330_FAULT_OPERAND_INVALID         (1 <<  1)
     45#define PL330_FAULT_DMAGO_ERR               (1 <<  4)
     46#define PL330_FAULT_EVENT_ERR               (1 <<  5)
     47#define PL330_FAULT_CH_PERIPH_ERR           (1 <<  6)
     48#define PL330_FAULT_CH_RDWR_ERR             (1 <<  7)
     49#define PL330_FAULT_ST_DATA_UNAVAILABLE     (1 << 12)
     50#define PL330_FAULT_FIFOEMPTY_ERR           (1 << 13)
     51#define PL330_FAULT_INSTR_FETCH_ERR         (1 << 16)
     52#define PL330_FAULT_DATA_WRITE_ERR          (1 << 17)
     53#define PL330_FAULT_DATA_READ_ERR           (1 << 18)
     54#define PL330_FAULT_DBG_INSTR               (1 << 30)
     55#define PL330_FAULT_LOCKUP_ERR              (1 << 31)
     56
     57#define PL330_UNTAGGED              0xff
     58
     59#define PL330_SINGLE                0x0
     60#define PL330_BURST                 0x1
     61
     62#define PL330_WATCHDOG_LIMIT        1024
     63
     64/* IOMEM mapped registers */
     65#define PL330_REG_DSR               0x000
     66#define PL330_REG_DPC               0x004
     67#define PL330_REG_INTEN             0x020
     68#define PL330_REG_INT_EVENT_RIS     0x024
     69#define PL330_REG_INTMIS            0x028
     70#define PL330_REG_INTCLR            0x02C
     71#define PL330_REG_FSRD              0x030
     72#define PL330_REG_FSRC              0x034
     73#define PL330_REG_FTRD              0x038
     74#define PL330_REG_FTR_BASE          0x040
     75#define PL330_REG_CSR_BASE          0x100
     76#define PL330_REG_CPC_BASE          0x104
     77#define PL330_REG_CHANCTRL          0x400
     78#define PL330_REG_DBGSTATUS         0xD00
     79#define PL330_REG_DBGCMD            0xD04
     80#define PL330_REG_DBGINST0          0xD08
     81#define PL330_REG_DBGINST1          0xD0C
     82#define PL330_REG_CR0_BASE          0xE00
     83#define PL330_REG_PERIPH_ID         0xFE0
     84
     85#define PL330_IOMEM_SIZE    0x1000
     86
     87#define CFG_BOOT_ADDR 2
     88#define CFG_INS 3
     89#define CFG_PNS 4
     90#define CFG_CRD 5
     91
     92static const uint32_t pl330_id[] = {
     93    0x30, 0x13, 0x24, 0x00, 0x0D, 0xF0, 0x05, 0xB1
     94};
     95
     96/* DMA channel states as they are described in PL330 Technical Reference Manual
     97 * Most of them will not be used in emulation.
     98 */
     99typedef enum  {
    100    pl330_chan_stopped = 0,
    101    pl330_chan_executing = 1,
    102    pl330_chan_cache_miss = 2,
    103    pl330_chan_updating_pc = 3,
    104    pl330_chan_waiting_event = 4,
    105    pl330_chan_at_barrier = 5,
    106    pl330_chan_queue_busy = 6,
    107    pl330_chan_waiting_periph = 7,
    108    pl330_chan_killing = 8,
    109    pl330_chan_completing = 9,
    110    pl330_chan_fault_completing = 14,
    111    pl330_chan_fault = 15,
    112} PL330ChanState;
    113
    114typedef struct PL330State PL330State;
    115
    116typedef struct PL330Chan {
    117    uint32_t src;
    118    uint32_t dst;
    119    uint32_t pc;
    120    uint32_t control;
    121    uint32_t status;
    122    uint32_t lc[2];
    123    uint32_t fault_type;
    124    uint32_t watchdog_timer;
    125
    126    bool ns;
    127    uint8_t request_flag;
    128    uint8_t wakeup;
    129    uint8_t wfp_sbp;
    130
    131    uint8_t state;
    132    uint8_t stall;
    133
    134    bool is_manager;
    135    PL330State *parent;
    136    uint8_t tag;
    137} PL330Chan;
    138
    139static const VMStateDescription vmstate_pl330_chan = {
    140    .name = "pl330_chan",
    141    .version_id = 1,
    142    .minimum_version_id = 1,
    143    .fields = (VMStateField[]) {
    144        VMSTATE_UINT32(src, PL330Chan),
    145        VMSTATE_UINT32(dst, PL330Chan),
    146        VMSTATE_UINT32(pc, PL330Chan),
    147        VMSTATE_UINT32(control, PL330Chan),
    148        VMSTATE_UINT32(status, PL330Chan),
    149        VMSTATE_UINT32_ARRAY(lc, PL330Chan, 2),
    150        VMSTATE_UINT32(fault_type, PL330Chan),
    151        VMSTATE_UINT32(watchdog_timer, PL330Chan),
    152        VMSTATE_BOOL(ns, PL330Chan),
    153        VMSTATE_UINT8(request_flag, PL330Chan),
    154        VMSTATE_UINT8(wakeup, PL330Chan),
    155        VMSTATE_UINT8(wfp_sbp, PL330Chan),
    156        VMSTATE_UINT8(state, PL330Chan),
    157        VMSTATE_UINT8(stall, PL330Chan),
    158        VMSTATE_END_OF_LIST()
    159    }
    160};
    161
    162typedef struct PL330Fifo {
    163    uint8_t *buf;
    164    uint8_t *tag;
    165    uint32_t head;
    166    uint32_t num;
    167    uint32_t buf_size;
    168} PL330Fifo;
    169
    170static const VMStateDescription vmstate_pl330_fifo = {
    171    .name = "pl330_chan",
    172    .version_id = 1,
    173    .minimum_version_id = 1,
    174    .fields = (VMStateField[]) {
    175        VMSTATE_VBUFFER_UINT32(buf, PL330Fifo, 1, NULL, buf_size),
    176        VMSTATE_VBUFFER_UINT32(tag, PL330Fifo, 1, NULL, buf_size),
    177        VMSTATE_UINT32(head, PL330Fifo),
    178        VMSTATE_UINT32(num, PL330Fifo),
    179        VMSTATE_UINT32(buf_size, PL330Fifo),
    180        VMSTATE_END_OF_LIST()
    181    }
    182};
    183
    184typedef struct PL330QueueEntry {
    185    uint32_t addr;
    186    uint32_t len;
    187    uint8_t n;
    188    bool inc;
    189    bool z;
    190    uint8_t tag;
    191    uint8_t seqn;
    192} PL330QueueEntry;
    193
    194static const VMStateDescription vmstate_pl330_queue_entry = {
    195    .name = "pl330_queue_entry",
    196    .version_id = 1,
    197    .minimum_version_id = 1,
    198    .fields = (VMStateField[]) {
    199        VMSTATE_UINT32(addr, PL330QueueEntry),
    200        VMSTATE_UINT32(len, PL330QueueEntry),
    201        VMSTATE_UINT8(n, PL330QueueEntry),
    202        VMSTATE_BOOL(inc, PL330QueueEntry),
    203        VMSTATE_BOOL(z, PL330QueueEntry),
    204        VMSTATE_UINT8(tag, PL330QueueEntry),
    205        VMSTATE_UINT8(seqn, PL330QueueEntry),
    206        VMSTATE_END_OF_LIST()
    207    }
    208};
    209
    210typedef struct PL330Queue {
    211    PL330State *parent;
    212    PL330QueueEntry *queue;
    213    uint32_t queue_size;
    214} PL330Queue;
    215
    216static const VMStateDescription vmstate_pl330_queue = {
    217    .name = "pl330_queue",
    218    .version_id = 2,
    219    .minimum_version_id = 2,
    220    .fields = (VMStateField[]) {
    221        VMSTATE_STRUCT_VARRAY_POINTER_UINT32(queue, PL330Queue, queue_size,
    222                                             vmstate_pl330_queue_entry,
    223                                             PL330QueueEntry),
    224        VMSTATE_END_OF_LIST()
    225    }
    226};
    227
    228struct PL330State {
    229    SysBusDevice parent_obj;
    230
    231    MemoryRegion iomem;
    232    qemu_irq irq_abort;
    233    qemu_irq *irq;
    234
    235    /* Config registers. cfg[5] = CfgDn. */
    236    uint32_t cfg[6];
    237#define EVENT_SEC_STATE 3
    238#define PERIPH_SEC_STATE 4
    239    /* cfg 0 bits and pieces */
    240    uint32_t num_chnls;
    241    uint8_t num_periph_req;
    242    uint8_t num_events;
    243    uint8_t mgr_ns_at_rst;
    244    /* cfg 1 bits and pieces */
    245    uint8_t i_cache_len;
    246    uint8_t num_i_cache_lines;
    247    /* CRD bits and pieces */
    248    uint8_t data_width;
    249    uint8_t wr_cap;
    250    uint8_t wr_q_dep;
    251    uint8_t rd_cap;
    252    uint8_t rd_q_dep;
    253    uint16_t data_buffer_dep;
    254
    255    PL330Chan manager;
    256    PL330Chan *chan;
    257    PL330Fifo fifo;
    258    PL330Queue read_queue;
    259    PL330Queue write_queue;
    260    uint8_t *lo_seqn;
    261    uint8_t *hi_seqn;
    262    QEMUTimer *timer; /* is used for restore dma. */
    263
    264    uint32_t inten;
    265    uint32_t int_status;
    266    uint32_t ev_status;
    267    uint32_t dbg[2];
    268    uint8_t debug_status;
    269    uint8_t num_faulting;
    270    uint8_t periph_busy[PL330_PERIPH_NUM];
    271
    272    /* Memory region that DMA operation access */
    273    MemoryRegion *mem_mr;
    274    AddressSpace *mem_as;
    275};
    276
    277#define TYPE_PL330 "pl330"
    278OBJECT_DECLARE_SIMPLE_TYPE(PL330State, PL330)
    279
    280static const VMStateDescription vmstate_pl330 = {
    281    .name = "pl330",
    282    .version_id = 2,
    283    .minimum_version_id = 2,
    284    .fields = (VMStateField[]) {
    285        VMSTATE_STRUCT(manager, PL330State, 0, vmstate_pl330_chan, PL330Chan),
    286        VMSTATE_STRUCT_VARRAY_POINTER_UINT32(chan, PL330State, num_chnls,
    287                                             vmstate_pl330_chan, PL330Chan),
    288        VMSTATE_VBUFFER_UINT32(lo_seqn, PL330State, 1, NULL, num_chnls),
    289        VMSTATE_VBUFFER_UINT32(hi_seqn, PL330State, 1, NULL, num_chnls),
    290        VMSTATE_STRUCT(fifo, PL330State, 0, vmstate_pl330_fifo, PL330Fifo),
    291        VMSTATE_STRUCT(read_queue, PL330State, 0, vmstate_pl330_queue,
    292                       PL330Queue),
    293        VMSTATE_STRUCT(write_queue, PL330State, 0, vmstate_pl330_queue,
    294                       PL330Queue),
    295        VMSTATE_TIMER_PTR(timer, PL330State),
    296        VMSTATE_UINT32(inten, PL330State),
    297        VMSTATE_UINT32(int_status, PL330State),
    298        VMSTATE_UINT32(ev_status, PL330State),
    299        VMSTATE_UINT32_ARRAY(dbg, PL330State, 2),
    300        VMSTATE_UINT8(debug_status, PL330State),
    301        VMSTATE_UINT8(num_faulting, PL330State),
    302        VMSTATE_UINT8_ARRAY(periph_busy, PL330State, PL330_PERIPH_NUM),
    303        VMSTATE_END_OF_LIST()
    304    }
    305};
    306
    307typedef struct PL330InsnDesc {
    308    /* OPCODE of the instruction */
    309    uint8_t opcode;
    310    /* Mask so we can select several sibling instructions, such as
    311       DMALD, DMALDS and DMALDB */
    312    uint8_t opmask;
    313    /* Size of instruction in bytes */
    314    uint8_t size;
    315    /* Interpreter */
    316    void (*exec)(PL330Chan *, uint8_t opcode, uint8_t *args, int len);
    317} PL330InsnDesc;
    318
    319static void pl330_hexdump(uint8_t *buf, size_t size)
    320{
    321    unsigned int b, i, len;
    322    char tmpbuf[80];
    323
    324    for (b = 0; b < size; b += 16) {
    325        len = size - b;
    326        if (len > 16) {
    327            len = 16;
    328        }
    329        tmpbuf[0] = '\0';
    330        for (i = 0; i < len; i++) {
    331            if ((i % 4) == 0) {
    332                strcat(tmpbuf, " ");
    333            }
    334            sprintf(tmpbuf + strlen(tmpbuf), " %02x", buf[b + i]);
    335        }
    336        trace_pl330_hexdump(b, tmpbuf);
    337    }
    338}
    339
    340/* MFIFO Implementation
    341 *
    342 * MFIFO is implemented as a cyclic buffer of BUF_SIZE size. Tagged bytes are
    343 * stored in this buffer. Data is stored in BUF field, tags - in the
    344 * corresponding array elements of TAG field.
    345 */
    346
    347/* Initialize queue. */
    348
    349static void pl330_fifo_init(PL330Fifo *s, uint32_t size)
    350{
    351    s->buf = g_malloc0(size);
    352    s->tag = g_malloc0(size);
    353    s->buf_size = size;
    354}
    355
    356/* Cyclic increment */
    357
    358static inline int pl330_fifo_inc(PL330Fifo *s, int x)
    359{
    360    return (x + 1) % s->buf_size;
    361}
    362
    363/* Number of empty bytes in MFIFO */
    364
    365static inline int pl330_fifo_num_free(PL330Fifo *s)
    366{
    367    return s->buf_size - s->num;
    368}
    369
    370/* Push LEN bytes of data stored in BUF to MFIFO and tag it with TAG.
    371 * Zero returned on success, PL330_FIFO_STALL if there is no enough free
    372 * space in MFIFO to store requested amount of data. If push was unsuccessful
    373 * no data is stored to MFIFO.
    374 */
    375
    376static int pl330_fifo_push(PL330Fifo *s, uint8_t *buf, int len, uint8_t tag)
    377{
    378    int i;
    379
    380    if (s->buf_size - s->num < len) {
    381        return PL330_FIFO_STALL;
    382    }
    383    for (i = 0; i < len; i++) {
    384        int push_idx = (s->head + s->num + i) % s->buf_size;
    385        s->buf[push_idx] = buf[i];
    386        s->tag[push_idx] = tag;
    387    }
    388    s->num += len;
    389    return PL330_FIFO_OK;
    390}
    391
    392/* Get LEN bytes of data from MFIFO and store it to BUF. Tag value of each
    393 * byte is verified. Zero returned on success, PL330_FIFO_ERR on tag mismatch
    394 * and PL330_FIFO_STALL if there is no enough data in MFIFO. If get was
    395 * unsuccessful no data is removed from MFIFO.
    396 */
    397
    398static int pl330_fifo_get(PL330Fifo *s, uint8_t *buf, int len, uint8_t tag)
    399{
    400    int i;
    401
    402    if (s->num < len) {
    403        return PL330_FIFO_STALL;
    404    }
    405    for (i = 0; i < len; i++) {
    406        if (s->tag[s->head] == tag) {
    407            int get_idx = (s->head + i) % s->buf_size;
    408            buf[i] = s->buf[get_idx];
    409        } else { /* Tag mismatch - Rollback transaction */
    410            return PL330_FIFO_ERR;
    411        }
    412    }
    413    s->head = (s->head + len) % s->buf_size;
    414    s->num -= len;
    415    return PL330_FIFO_OK;
    416}
    417
    418/* Reset MFIFO. This completely erases all data in it. */
    419
    420static inline void pl330_fifo_reset(PL330Fifo *s)
    421{
    422    s->head = 0;
    423    s->num = 0;
    424}
    425
    426/* Return tag of the first byte stored in MFIFO. If MFIFO is empty
    427 * PL330_UNTAGGED is returned.
    428 */
    429
    430static inline uint8_t pl330_fifo_tag(PL330Fifo *s)
    431{
    432    return (!s->num) ? PL330_UNTAGGED : s->tag[s->head];
    433}
    434
    435/* Returns non-zero if tag TAG is present in fifo or zero otherwise */
    436
    437static int pl330_fifo_has_tag(PL330Fifo *s, uint8_t tag)
    438{
    439    int i, n;
    440
    441    i = s->head;
    442    for (n = 0; n < s->num; n++) {
    443        if (s->tag[i] == tag) {
    444            return 1;
    445        }
    446        i = pl330_fifo_inc(s, i);
    447    }
    448    return 0;
    449}
    450
    451/* Remove all entry tagged with TAG from MFIFO */
    452
    453static void pl330_fifo_tagged_remove(PL330Fifo *s, uint8_t tag)
    454{
    455    int i, t, n;
    456
    457    t = i = s->head;
    458    for (n = 0; n < s->num; n++) {
    459        if (s->tag[i] != tag) {
    460            s->buf[t] = s->buf[i];
    461            s->tag[t] = s->tag[i];
    462            t = pl330_fifo_inc(s, t);
    463        } else {
    464            s->num = s->num - 1;
    465        }
    466        i = pl330_fifo_inc(s, i);
    467    }
    468}
    469
    470/* Read-Write Queue implementation
    471 *
    472 * A Read-Write Queue stores up to QUEUE_SIZE instructions (loads or stores).
    473 * Each instruction is described by source (for loads) or destination (for
    474 * stores) address ADDR, width of data to be loaded/stored LEN, number of
    475 * stores/loads to be performed N, INC bit, Z bit and TAG to identify channel
    476 * this instruction belongs to. Queue does not store any information about
    477 * nature of the instruction: is it load or store. PL330 has different queues
    478 * for loads and stores so this is already known at the top level where it
    479 * matters.
    480 *
    481 * Queue works as FIFO for instructions with equivalent tags, but can issue
    482 * instructions with different tags in arbitrary order. SEQN field attached to
    483 * each instruction helps to achieve this. For each TAG queue contains
    484 * instructions with consecutive SEQN values ranging from LO_SEQN[TAG] to
    485 * HI_SEQN[TAG]-1 inclusive. SEQN is 8-bit unsigned integer, so SEQN=255 is
    486 * followed by SEQN=0.
    487 *
    488 * Z bit indicates that zeroes should be stored. No MFIFO fetches are performed
    489 * in this case.
    490 */
    491
    492static void pl330_queue_reset(PL330Queue *s)
    493{
    494    int i;
    495
    496    for (i = 0; i < s->queue_size; i++) {
    497        s->queue[i].tag = PL330_UNTAGGED;
    498    }
    499}
    500
    501/* Initialize queue */
    502static void pl330_queue_init(PL330Queue *s, int size, PL330State *parent)
    503{
    504    s->parent = parent;
    505    s->queue = g_new0(PL330QueueEntry, size);
    506    s->queue_size = size;
    507}
    508
    509/* Returns pointer to an empty slot or NULL if queue is full */
    510static PL330QueueEntry *pl330_queue_find_empty(PL330Queue *s)
    511{
    512    int i;
    513
    514    for (i = 0; i < s->queue_size; i++) {
    515        if (s->queue[i].tag == PL330_UNTAGGED) {
    516            return &s->queue[i];
    517        }
    518    }
    519    return NULL;
    520}
    521
    522/* Put instruction in queue.
    523 * Return value:
    524 * - zero - OK
    525 * - non-zero - queue is full
    526 */
    527
    528static int pl330_queue_put_insn(PL330Queue *s, uint32_t addr,
    529                                int len, int n, bool inc, bool z, uint8_t tag)
    530{
    531    PL330QueueEntry *entry = pl330_queue_find_empty(s);
    532
    533    if (!entry) {
    534        return 1;
    535    }
    536    entry->tag = tag;
    537    entry->addr = addr;
    538    entry->len = len;
    539    entry->n = n;
    540    entry->z = z;
    541    entry->inc = inc;
    542    entry->seqn = s->parent->hi_seqn[tag];
    543    s->parent->hi_seqn[tag]++;
    544    return 0;
    545}
    546
    547/* Returns a pointer to queue slot containing instruction which satisfies
    548 *  following conditions:
    549 *   - it has valid tag value (not PL330_UNTAGGED)
    550 *   - if enforce_seq is set it has to be issuable without violating queue
    551 *     logic (see above)
    552 *   - if TAG argument is not PL330_UNTAGGED this instruction has tag value
    553 *     equivalent to the argument TAG value.
    554 *  If such instruction cannot be found NULL is returned.
    555 */
    556
    557static PL330QueueEntry *pl330_queue_find_insn(PL330Queue *s, uint8_t tag,
    558                                              bool enforce_seq)
    559{
    560    int i;
    561
    562    for (i = 0; i < s->queue_size; i++) {
    563        if (s->queue[i].tag != PL330_UNTAGGED) {
    564            if ((!enforce_seq ||
    565                    s->queue[i].seqn == s->parent->lo_seqn[s->queue[i].tag]) &&
    566                    (s->queue[i].tag == tag || tag == PL330_UNTAGGED ||
    567                    s->queue[i].z)) {
    568                return &s->queue[i];
    569            }
    570        }
    571    }
    572    return NULL;
    573}
    574
    575/* Removes instruction from queue. */
    576
    577static inline void pl330_queue_remove_insn(PL330Queue *s, PL330QueueEntry *e)
    578{
    579    s->parent->lo_seqn[e->tag]++;
    580    e->tag = PL330_UNTAGGED;
    581}
    582
    583/* Removes all instructions tagged with TAG from queue. */
    584
    585static inline void pl330_queue_remove_tagged(PL330Queue *s, uint8_t tag)
    586{
    587    int i;
    588
    589    for (i = 0; i < s->queue_size; i++) {
    590        if (s->queue[i].tag == tag) {
    591            s->queue[i].tag = PL330_UNTAGGED;
    592        }
    593    }
    594}
    595
    596/* DMA instruction execution engine */
    597
    598/* Moves DMA channel to the FAULT state and updates it's status. */
    599
    600static inline void pl330_fault(PL330Chan *ch, uint32_t flags)
    601{
    602    trace_pl330_fault(ch, flags);
    603    ch->fault_type |= flags;
    604    if (ch->state == pl330_chan_fault) {
    605        return;
    606    }
    607    ch->state = pl330_chan_fault;
    608    ch->parent->num_faulting++;
    609    if (ch->parent->num_faulting == 1) {
    610        trace_pl330_fault_abort();
    611        qemu_irq_raise(ch->parent->irq_abort);
    612    }
    613}
    614
    615/*
    616 * For information about instructions see PL330 Technical Reference Manual.
    617 *
    618 * Arguments:
    619 *   CH - channel executing the instruction
    620 *   OPCODE - opcode
    621 *   ARGS - array of 8-bit arguments
    622 *   LEN - number of elements in ARGS array
    623 */
    624
    625static void pl330_dmaadxh(PL330Chan *ch, uint8_t *args, bool ra, bool neg)
    626{
    627    uint32_t im = (args[1] << 8) | args[0];
    628    if (neg) {
    629        im |= 0xffffu << 16;
    630    }
    631
    632    if (ch->is_manager) {
    633        pl330_fault(ch, PL330_FAULT_UNDEF_INSTR);
    634        return;
    635    }
    636    if (ra) {
    637        ch->dst += im;
    638    } else {
    639        ch->src += im;
    640    }
    641}
    642
    643static void pl330_dmaaddh(PL330Chan *ch, uint8_t opcode, uint8_t *args, int len)
    644{
    645    pl330_dmaadxh(ch, args, extract32(opcode, 1, 1), false);
    646}
    647
    648static void pl330_dmaadnh(PL330Chan *ch, uint8_t opcode, uint8_t *args, int len)
    649{
    650    pl330_dmaadxh(ch, args, extract32(opcode, 1, 1), true);
    651}
    652
    653static void pl330_dmaend(PL330Chan *ch, uint8_t opcode,
    654                         uint8_t *args, int len)
    655{
    656    PL330State *s = ch->parent;
    657
    658    if (ch->state == pl330_chan_executing && !ch->is_manager) {
    659        /* Wait for all transfers to complete */
    660        if (pl330_fifo_has_tag(&s->fifo, ch->tag) ||
    661            pl330_queue_find_insn(&s->read_queue, ch->tag, false) != NULL ||
    662            pl330_queue_find_insn(&s->write_queue, ch->tag, false) != NULL) {
    663
    664            ch->stall = 1;
    665            return;
    666        }
    667    }
    668    trace_pl330_dmaend();
    669    pl330_fifo_tagged_remove(&s->fifo, ch->tag);
    670    pl330_queue_remove_tagged(&s->read_queue, ch->tag);
    671    pl330_queue_remove_tagged(&s->write_queue, ch->tag);
    672    ch->state = pl330_chan_stopped;
    673}
    674
    675static void pl330_dmaflushp(PL330Chan *ch, uint8_t opcode,
    676                                            uint8_t *args, int len)
    677{
    678    uint8_t periph_id;
    679
    680    if (args[0] & 7) {
    681        pl330_fault(ch, PL330_FAULT_OPERAND_INVALID);
    682        return;
    683    }
    684    periph_id = (args[0] >> 3) & 0x1f;
    685    if (periph_id >= ch->parent->num_periph_req) {
    686        pl330_fault(ch, PL330_FAULT_OPERAND_INVALID);
    687        return;
    688    }
    689    if (ch->ns && !(ch->parent->cfg[CFG_PNS] & (1 << periph_id))) {
    690        pl330_fault(ch, PL330_FAULT_CH_PERIPH_ERR);
    691        return;
    692    }
    693    /* Do nothing */
    694}
    695
    696static void pl330_dmago(PL330Chan *ch, uint8_t opcode, uint8_t *args, int len)
    697{
    698    uint8_t chan_id;
    699    uint8_t ns;
    700    uint32_t pc;
    701    PL330Chan *s;
    702
    703    trace_pl330_dmago();
    704
    705    if (!ch->is_manager) {
    706        pl330_fault(ch, PL330_FAULT_UNDEF_INSTR);
    707        return;
    708    }
    709    ns = !!(opcode & 2);
    710    chan_id = args[0] & 7;
    711    if ((args[0] >> 3)) {
    712        pl330_fault(ch, PL330_FAULT_OPERAND_INVALID);
    713        return;
    714    }
    715    if (chan_id >= ch->parent->num_chnls) {
    716        pl330_fault(ch, PL330_FAULT_OPERAND_INVALID);
    717        return;
    718    }
    719    pc = (((uint32_t)args[4]) << 24) | (((uint32_t)args[3]) << 16) |
    720         (((uint32_t)args[2]) << 8)  | (((uint32_t)args[1]));
    721    if (ch->parent->chan[chan_id].state != pl330_chan_stopped) {
    722        pl330_fault(ch, PL330_FAULT_OPERAND_INVALID);
    723        return;
    724    }
    725    if (ch->ns && !ns) {
    726        pl330_fault(ch, PL330_FAULT_DMAGO_ERR);
    727        return;
    728    }
    729    s = &ch->parent->chan[chan_id];
    730    s->ns = ns;
    731    s->pc = pc;
    732    s->state = pl330_chan_executing;
    733}
    734
    735static void pl330_dmald(PL330Chan *ch, uint8_t opcode, uint8_t *args, int len)
    736{
    737    uint8_t bs = opcode & 3;
    738    uint32_t size, num;
    739    bool inc;
    740
    741    if (bs == 2) {
    742        pl330_fault(ch, PL330_FAULT_OPERAND_INVALID);
    743        return;
    744    }
    745    if ((bs == 1 && ch->request_flag == PL330_BURST) ||
    746        (bs == 3 && ch->request_flag == PL330_SINGLE)) {
    747        /* Perform NOP */
    748        return;
    749    }
    750    if (bs == 1 && ch->request_flag == PL330_SINGLE) {
    751        num = 1;
    752    } else {
    753        num = ((ch->control >> 4) & 0xf) + 1;
    754    }
    755    size = (uint32_t)1 << ((ch->control >> 1) & 0x7);
    756    inc = !!(ch->control & 1);
    757    ch->stall = pl330_queue_put_insn(&ch->parent->read_queue, ch->src,
    758                                    size, num, inc, 0, ch->tag);
    759    if (!ch->stall) {
    760        trace_pl330_dmald(ch->tag, ch->src, size, num, inc ? 'Y' : 'N');
    761        ch->src += inc ? size * num - (ch->src & (size - 1)) : 0;
    762    }
    763}
    764
    765static void pl330_dmaldp(PL330Chan *ch, uint8_t opcode, uint8_t *args, int len)
    766{
    767    uint8_t periph_id;
    768
    769    if (args[0] & 7) {
    770        pl330_fault(ch, PL330_FAULT_OPERAND_INVALID);
    771        return;
    772    }
    773    periph_id = (args[0] >> 3) & 0x1f;
    774    if (periph_id >= ch->parent->num_periph_req) {
    775        pl330_fault(ch, PL330_FAULT_OPERAND_INVALID);
    776        return;
    777    }
    778    if (ch->ns && !(ch->parent->cfg[CFG_PNS] & (1 << periph_id))) {
    779        pl330_fault(ch, PL330_FAULT_CH_PERIPH_ERR);
    780        return;
    781    }
    782    pl330_dmald(ch, opcode, args, len);
    783}
    784
    785static void pl330_dmalp(PL330Chan *ch, uint8_t opcode, uint8_t *args, int len)
    786{
    787    uint8_t lc = (opcode & 2) >> 1;
    788
    789    ch->lc[lc] = args[0];
    790}
    791
    792static void pl330_dmakill(PL330Chan *ch, uint8_t opcode, uint8_t *args, int len)
    793{
    794    if (ch->state == pl330_chan_fault ||
    795        ch->state == pl330_chan_fault_completing) {
    796        /* This is the only way for a channel to leave the faulting state */
    797        ch->fault_type = 0;
    798        ch->parent->num_faulting--;
    799        if (ch->parent->num_faulting == 0) {
    800            trace_pl330_dmakill();
    801            qemu_irq_lower(ch->parent->irq_abort);
    802        }
    803    }
    804    ch->state = pl330_chan_killing;
    805    pl330_fifo_tagged_remove(&ch->parent->fifo, ch->tag);
    806    pl330_queue_remove_tagged(&ch->parent->read_queue, ch->tag);
    807    pl330_queue_remove_tagged(&ch->parent->write_queue, ch->tag);
    808    ch->state = pl330_chan_stopped;
    809}
    810
    811static void pl330_dmalpend(PL330Chan *ch, uint8_t opcode,
    812                                    uint8_t *args, int len)
    813{
    814    uint8_t nf = (opcode & 0x10) >> 4;
    815    uint8_t bs = opcode & 3;
    816    uint8_t lc = (opcode & 4) >> 2;
    817
    818    trace_pl330_dmalpend(nf, bs, lc, ch->lc[lc], ch->request_flag);
    819
    820    if (bs == 2) {
    821        pl330_fault(ch, PL330_FAULT_OPERAND_INVALID);
    822        return;
    823    }
    824    if ((bs == 1 && ch->request_flag == PL330_BURST) ||
    825        (bs == 3 && ch->request_flag == PL330_SINGLE)) {
    826        /* Perform NOP */
    827        return;
    828    }
    829    if (!nf || ch->lc[lc]) {
    830        if (nf) {
    831            ch->lc[lc]--;
    832        }
    833        trace_pl330_dmalpiter();
    834        ch->pc -= args[0];
    835        ch->pc -= len + 1;
    836        /* "ch->pc -= args[0] + len + 1" is incorrect when args[0] == 256 */
    837    } else {
    838        trace_pl330_dmalpfallthrough();
    839    }
    840}
    841
    842
    843static void pl330_dmamov(PL330Chan *ch, uint8_t opcode, uint8_t *args, int len)
    844{
    845    uint8_t rd = args[0] & 7;
    846    uint32_t im;
    847
    848    if ((args[0] >> 3)) {
    849        pl330_fault(ch, PL330_FAULT_OPERAND_INVALID);
    850        return;
    851    }
    852    im = (((uint32_t)args[4]) << 24) | (((uint32_t)args[3]) << 16) |
    853         (((uint32_t)args[2]) << 8)  | (((uint32_t)args[1]));
    854    switch (rd) {
    855    case 0:
    856        ch->src = im;
    857        break;
    858    case 1:
    859        ch->control = im;
    860        break;
    861    case 2:
    862        ch->dst = im;
    863        break;
    864    default:
    865        pl330_fault(ch, PL330_FAULT_OPERAND_INVALID);
    866        return;
    867    }
    868}
    869
    870static void pl330_dmanop(PL330Chan *ch, uint8_t opcode,
    871                         uint8_t *args, int len)
    872{
    873    /* NOP is NOP. */
    874}
    875
    876static void pl330_dmarmb(PL330Chan *ch, uint8_t opcode, uint8_t *args, int len)
    877{
    878   if (pl330_queue_find_insn(&ch->parent->read_queue, ch->tag, false)) {
    879        ch->state = pl330_chan_at_barrier;
    880        ch->stall = 1;
    881        return;
    882    } else {
    883        ch->state = pl330_chan_executing;
    884    }
    885}
    886
    887static void pl330_dmasev(PL330Chan *ch, uint8_t opcode, uint8_t *args, int len)
    888{
    889    uint8_t ev_id;
    890
    891    if (args[0] & 7) {
    892        pl330_fault(ch, PL330_FAULT_OPERAND_INVALID);
    893        return;
    894    }
    895    ev_id = (args[0] >> 3) & 0x1f;
    896    if (ev_id >= ch->parent->num_events) {
    897        pl330_fault(ch, PL330_FAULT_OPERAND_INVALID);
    898        return;
    899    }
    900    if (ch->ns && !(ch->parent->cfg[CFG_INS] & (1 << ev_id))) {
    901        pl330_fault(ch, PL330_FAULT_EVENT_ERR);
    902        return;
    903    }
    904    if (ch->parent->inten & (1 << ev_id)) {
    905        ch->parent->int_status |= (1 << ev_id);
    906        trace_pl330_dmasev_evirq(ev_id);
    907        qemu_irq_raise(ch->parent->irq[ev_id]);
    908    }
    909    trace_pl330_dmasev_event(ev_id);
    910    ch->parent->ev_status |= (1 << ev_id);
    911}
    912
    913static void pl330_dmast(PL330Chan *ch, uint8_t opcode, uint8_t *args, int len)
    914{
    915    uint8_t bs = opcode & 3;
    916    uint32_t size, num;
    917    bool inc;
    918
    919    if (bs == 2) {
    920        pl330_fault(ch, PL330_FAULT_OPERAND_INVALID);
    921        return;
    922    }
    923    if ((bs == 1 && ch->request_flag == PL330_BURST) ||
    924        (bs == 3 && ch->request_flag == PL330_SINGLE)) {
    925        /* Perform NOP */
    926        return;
    927    }
    928    num = ((ch->control >> 18) & 0xf) + 1;
    929    size = (uint32_t)1 << ((ch->control >> 15) & 0x7);
    930    inc = !!((ch->control >> 14) & 1);
    931    ch->stall = pl330_queue_put_insn(&ch->parent->write_queue, ch->dst,
    932                                    size, num, inc, 0, ch->tag);
    933    if (!ch->stall) {
    934        trace_pl330_dmast(ch->tag, ch->dst, size, num, inc ? 'Y' : 'N');
    935        ch->dst += inc ? size * num - (ch->dst & (size - 1)) : 0;
    936    }
    937}
    938
    939static void pl330_dmastp(PL330Chan *ch, uint8_t opcode,
    940                         uint8_t *args, int len)
    941{
    942    uint8_t periph_id;
    943
    944    if (args[0] & 7) {
    945        pl330_fault(ch, PL330_FAULT_OPERAND_INVALID);
    946        return;
    947    }
    948    periph_id = (args[0] >> 3) & 0x1f;
    949    if (periph_id >= ch->parent->num_periph_req) {
    950        pl330_fault(ch, PL330_FAULT_OPERAND_INVALID);
    951        return;
    952    }
    953    if (ch->ns && !(ch->parent->cfg[CFG_PNS] & (1 << periph_id))) {
    954        pl330_fault(ch, PL330_FAULT_CH_PERIPH_ERR);
    955        return;
    956    }
    957    pl330_dmast(ch, opcode, args, len);
    958}
    959
    960static void pl330_dmastz(PL330Chan *ch, uint8_t opcode,
    961                         uint8_t *args, int len)
    962{
    963    uint32_t size, num;
    964    bool inc;
    965
    966    num = ((ch->control >> 18) & 0xf) + 1;
    967    size = (uint32_t)1 << ((ch->control >> 15) & 0x7);
    968    inc = !!((ch->control >> 14) & 1);
    969    ch->stall = pl330_queue_put_insn(&ch->parent->write_queue, ch->dst,
    970                                    size, num, inc, 1, ch->tag);
    971    if (inc) {
    972        ch->dst += size * num;
    973    }
    974}
    975
    976static void pl330_dmawfe(PL330Chan *ch, uint8_t opcode,
    977                         uint8_t *args, int len)
    978{
    979    uint8_t ev_id;
    980    int i;
    981
    982    if (args[0] & 5) {
    983        pl330_fault(ch, PL330_FAULT_OPERAND_INVALID);
    984        return;
    985    }
    986    ev_id = (args[0] >> 3) & 0x1f;
    987    if (ev_id >= ch->parent->num_events) {
    988        pl330_fault(ch, PL330_FAULT_OPERAND_INVALID);
    989        return;
    990    }
    991    if (ch->ns && !(ch->parent->cfg[CFG_INS] & (1 << ev_id))) {
    992        pl330_fault(ch, PL330_FAULT_EVENT_ERR);
    993        return;
    994    }
    995    ch->wakeup = ev_id;
    996    ch->state = pl330_chan_waiting_event;
    997    if (~ch->parent->inten & ch->parent->ev_status & 1 << ev_id) {
    998        ch->state = pl330_chan_executing;
    999        /* If anyone else is currently waiting on the same event, let them
   1000         * clear the ev_status so they pick up event as well
   1001         */
   1002        for (i = 0; i < ch->parent->num_chnls; ++i) {
   1003            PL330Chan *peer = &ch->parent->chan[i];
   1004            if (peer->state == pl330_chan_waiting_event &&
   1005                    peer->wakeup == ev_id) {
   1006                return;
   1007            }
   1008        }
   1009        ch->parent->ev_status &= ~(1 << ev_id);
   1010        trace_pl330_dmawfe(ev_id);
   1011    } else {
   1012        ch->stall = 1;
   1013    }
   1014}
   1015
   1016static void pl330_dmawfp(PL330Chan *ch, uint8_t opcode,
   1017                         uint8_t *args, int len)
   1018{
   1019    uint8_t bs = opcode & 3;
   1020    uint8_t periph_id;
   1021
   1022    if (args[0] & 7) {
   1023        pl330_fault(ch, PL330_FAULT_OPERAND_INVALID);
   1024        return;
   1025    }
   1026    periph_id = (args[0] >> 3) & 0x1f;
   1027    if (periph_id >= ch->parent->num_periph_req) {
   1028        pl330_fault(ch, PL330_FAULT_OPERAND_INVALID);
   1029        return;
   1030    }
   1031    if (ch->ns && !(ch->parent->cfg[CFG_PNS] & (1 << periph_id))) {
   1032        pl330_fault(ch, PL330_FAULT_CH_PERIPH_ERR);
   1033        return;
   1034    }
   1035    switch (bs) {
   1036    case 0: /* S */
   1037        ch->request_flag = PL330_SINGLE;
   1038        ch->wfp_sbp = 0;
   1039        break;
   1040    case 1: /* P */
   1041        ch->request_flag = PL330_BURST;
   1042        ch->wfp_sbp = 2;
   1043        break;
   1044    case 2: /* B */
   1045        ch->request_flag = PL330_BURST;
   1046        ch->wfp_sbp = 1;
   1047        break;
   1048    default:
   1049        pl330_fault(ch, PL330_FAULT_OPERAND_INVALID);
   1050        return;
   1051    }
   1052
   1053    if (ch->parent->periph_busy[periph_id]) {
   1054        ch->state = pl330_chan_waiting_periph;
   1055        ch->stall = 1;
   1056    } else if (ch->state == pl330_chan_waiting_periph) {
   1057        ch->state = pl330_chan_executing;
   1058    }
   1059}
   1060
   1061static void pl330_dmawmb(PL330Chan *ch, uint8_t opcode,
   1062                         uint8_t *args, int len)
   1063{
   1064    if (pl330_queue_find_insn(&ch->parent->write_queue, ch->tag, false)) {
   1065        ch->state = pl330_chan_at_barrier;
   1066        ch->stall = 1;
   1067        return;
   1068    } else {
   1069        ch->state = pl330_chan_executing;
   1070    }
   1071}
   1072
   1073/* NULL terminated array of the instruction descriptions. */
   1074static const PL330InsnDesc insn_desc[] = {
   1075    { .opcode = 0x54, .opmask = 0xFD, .size = 3, .exec = pl330_dmaaddh, },
   1076    { .opcode = 0x5c, .opmask = 0xFD, .size = 3, .exec = pl330_dmaadnh, },
   1077    { .opcode = 0x00, .opmask = 0xFF, .size = 1, .exec = pl330_dmaend, },
   1078    { .opcode = 0x35, .opmask = 0xFF, .size = 2, .exec = pl330_dmaflushp, },
   1079    { .opcode = 0xA0, .opmask = 0xFD, .size = 6, .exec = pl330_dmago, },
   1080    { .opcode = 0x04, .opmask = 0xFC, .size = 1, .exec = pl330_dmald, },
   1081    { .opcode = 0x25, .opmask = 0xFD, .size = 2, .exec = pl330_dmaldp, },
   1082    { .opcode = 0x20, .opmask = 0xFD, .size = 2, .exec = pl330_dmalp, },
   1083    /* dmastp  must be before dmalpend in this list, because their maps
   1084     * are overlapping
   1085     */
   1086    { .opcode = 0x29, .opmask = 0xFD, .size = 2, .exec = pl330_dmastp, },
   1087    { .opcode = 0x28, .opmask = 0xE8, .size = 2, .exec = pl330_dmalpend, },
   1088    { .opcode = 0x01, .opmask = 0xFF, .size = 1, .exec = pl330_dmakill, },
   1089    { .opcode = 0xBC, .opmask = 0xFF, .size = 6, .exec = pl330_dmamov, },
   1090    { .opcode = 0x18, .opmask = 0xFF, .size = 1, .exec = pl330_dmanop, },
   1091    { .opcode = 0x12, .opmask = 0xFF, .size = 1, .exec = pl330_dmarmb, },
   1092    { .opcode = 0x34, .opmask = 0xFF, .size = 2, .exec = pl330_dmasev, },
   1093    { .opcode = 0x08, .opmask = 0xFC, .size = 1, .exec = pl330_dmast, },
   1094    { .opcode = 0x0C, .opmask = 0xFF, .size = 1, .exec = pl330_dmastz, },
   1095    { .opcode = 0x36, .opmask = 0xFF, .size = 2, .exec = pl330_dmawfe, },
   1096    { .opcode = 0x30, .opmask = 0xFC, .size = 2, .exec = pl330_dmawfp, },
   1097    { .opcode = 0x13, .opmask = 0xFF, .size = 1, .exec = pl330_dmawmb, },
   1098    { .opcode = 0x00, .opmask = 0x00, .size = 0, .exec = NULL, }
   1099};
   1100
   1101/* Instructions which can be issued via debug registers. */
   1102static const PL330InsnDesc debug_insn_desc[] = {
   1103    { .opcode = 0xA0, .opmask = 0xFD, .size = 6, .exec = pl330_dmago, },
   1104    { .opcode = 0x01, .opmask = 0xFF, .size = 1, .exec = pl330_dmakill, },
   1105    { .opcode = 0x34, .opmask = 0xFF, .size = 2, .exec = pl330_dmasev, },
   1106    { .opcode = 0x00, .opmask = 0x00, .size = 0, .exec = NULL, }
   1107};
   1108
   1109static inline const PL330InsnDesc *pl330_fetch_insn(PL330Chan *ch)
   1110{
   1111    uint8_t opcode;
   1112    int i;
   1113
   1114    dma_memory_read(ch->parent->mem_as, ch->pc, &opcode, 1);
   1115    for (i = 0; insn_desc[i].size; i++) {
   1116        if ((opcode & insn_desc[i].opmask) == insn_desc[i].opcode) {
   1117            return &insn_desc[i];
   1118        }
   1119    }
   1120    return NULL;
   1121}
   1122
   1123static inline void pl330_exec_insn(PL330Chan *ch, const PL330InsnDesc *insn)
   1124{
   1125    uint8_t buf[PL330_INSN_MAXSIZE];
   1126
   1127    assert(insn->size <= PL330_INSN_MAXSIZE);
   1128    dma_memory_read(ch->parent->mem_as, ch->pc, buf, insn->size);
   1129    insn->exec(ch, buf[0], &buf[1], insn->size - 1);
   1130}
   1131
   1132static inline void pl330_update_pc(PL330Chan *ch,
   1133                                   const PL330InsnDesc *insn)
   1134{
   1135    ch->pc += insn->size;
   1136}
   1137
   1138/* Try to execute current instruction in channel CH. Number of executed
   1139   instructions is returned (0 or 1). */
   1140static int pl330_chan_exec(PL330Chan *ch)
   1141{
   1142    const PL330InsnDesc *insn;
   1143
   1144    if (ch->state != pl330_chan_executing &&
   1145            ch->state != pl330_chan_waiting_periph &&
   1146            ch->state != pl330_chan_at_barrier &&
   1147            ch->state != pl330_chan_waiting_event) {
   1148        return 0;
   1149    }
   1150    ch->stall = 0;
   1151    insn = pl330_fetch_insn(ch);
   1152    if (!insn) {
   1153        trace_pl330_chan_exec_undef();
   1154        pl330_fault(ch, PL330_FAULT_UNDEF_INSTR);
   1155        return 0;
   1156    }
   1157    pl330_exec_insn(ch, insn);
   1158    if (!ch->stall) {
   1159        pl330_update_pc(ch, insn);
   1160        ch->watchdog_timer = 0;
   1161        return 1;
   1162    /* WDT only active in exec state */
   1163    } else if (ch->state == pl330_chan_executing) {
   1164        ch->watchdog_timer++;
   1165        if (ch->watchdog_timer >= PL330_WATCHDOG_LIMIT) {
   1166            pl330_fault(ch, PL330_FAULT_LOCKUP_ERR);
   1167        }
   1168    }
   1169    return 0;
   1170}
   1171
   1172/* Try to execute 1 instruction in each channel, one instruction from read
   1173   queue and one instruction from write queue. Number of successfully executed
   1174   instructions is returned. */
   1175static int pl330_exec_cycle(PL330Chan *channel)
   1176{
   1177    PL330State *s = channel->parent;
   1178    PL330QueueEntry *q;
   1179    int i;
   1180    int num_exec = 0;
   1181    int fifo_res = 0;
   1182    uint8_t buf[PL330_MAX_BURST_LEN];
   1183
   1184    /* Execute one instruction in each channel */
   1185    num_exec += pl330_chan_exec(channel);
   1186
   1187    /* Execute one instruction from read queue */
   1188    q = pl330_queue_find_insn(&s->read_queue, PL330_UNTAGGED, true);
   1189    if (q != NULL && q->len <= pl330_fifo_num_free(&s->fifo)) {
   1190        int len = q->len - (q->addr & (q->len - 1));
   1191
   1192        dma_memory_read(s->mem_as, q->addr, buf, len);
   1193        trace_pl330_exec_cycle(q->addr, len);
   1194        if (trace_event_get_state_backends(TRACE_PL330_HEXDUMP)) {
   1195            pl330_hexdump(buf, len);
   1196        }
   1197        fifo_res = pl330_fifo_push(&s->fifo, buf, len, q->tag);
   1198        if (fifo_res == PL330_FIFO_OK) {
   1199            if (q->inc) {
   1200                q->addr += len;
   1201            }
   1202            q->n--;
   1203            if (!q->n) {
   1204                pl330_queue_remove_insn(&s->read_queue, q);
   1205            }
   1206            num_exec++;
   1207        }
   1208    }
   1209
   1210    /* Execute one instruction from write queue. */
   1211    q = pl330_queue_find_insn(&s->write_queue, pl330_fifo_tag(&s->fifo), true);
   1212    if (q != NULL) {
   1213        int len = q->len - (q->addr & (q->len - 1));
   1214
   1215        if (q->z) {
   1216            for (i = 0; i < len; i++) {
   1217                buf[i] = 0;
   1218            }
   1219        } else {
   1220            fifo_res = pl330_fifo_get(&s->fifo, buf, len, q->tag);
   1221        }
   1222        if (fifo_res == PL330_FIFO_OK || q->z) {
   1223            dma_memory_write(s->mem_as, q->addr, buf, len);
   1224            trace_pl330_exec_cycle(q->addr, len);
   1225            if (trace_event_get_state_backends(TRACE_PL330_HEXDUMP)) {
   1226                pl330_hexdump(buf, len);
   1227            }
   1228            if (q->inc) {
   1229                q->addr += len;
   1230            }
   1231            num_exec++;
   1232        } else if (fifo_res == PL330_FIFO_STALL) {
   1233            pl330_fault(&channel->parent->chan[q->tag],
   1234                                PL330_FAULT_FIFOEMPTY_ERR);
   1235        }
   1236        q->n--;
   1237        if (!q->n) {
   1238            pl330_queue_remove_insn(&s->write_queue, q);
   1239        }
   1240    }
   1241
   1242    return num_exec;
   1243}
   1244
   1245static int pl330_exec_channel(PL330Chan *channel)
   1246{
   1247    int insr_exec = 0;
   1248
   1249    /* TODO: Is it all right to execute everything or should we do per-cycle
   1250       simulation? */
   1251    while (pl330_exec_cycle(channel)) {
   1252        insr_exec++;
   1253    }
   1254
   1255    /* Detect deadlock */
   1256    if (channel->state == pl330_chan_executing) {
   1257        pl330_fault(channel, PL330_FAULT_LOCKUP_ERR);
   1258    }
   1259    /* Situation when one of the queues has deadlocked but all channels
   1260     * have finished their programs should be impossible.
   1261     */
   1262
   1263    return insr_exec;
   1264}
   1265
   1266static inline void pl330_exec(PL330State *s)
   1267{
   1268    int i, insr_exec;
   1269    trace_pl330_exec();
   1270    do {
   1271        insr_exec = pl330_exec_channel(&s->manager);
   1272
   1273        for (i = 0; i < s->num_chnls; i++) {
   1274            insr_exec += pl330_exec_channel(&s->chan[i]);
   1275        }
   1276    } while (insr_exec);
   1277}
   1278
   1279static void pl330_exec_cycle_timer(void *opaque)
   1280{
   1281    PL330State *s = (PL330State *)opaque;
   1282    pl330_exec(s);
   1283}
   1284
   1285/* Stop or restore dma operations */
   1286
   1287static void pl330_dma_stop_irq(void *opaque, int irq, int level)
   1288{
   1289    PL330State *s = (PL330State *)opaque;
   1290
   1291    if (s->periph_busy[irq] != level) {
   1292        s->periph_busy[irq] = level;
   1293        timer_mod(s->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
   1294    }
   1295}
   1296
   1297static void pl330_debug_exec(PL330State *s)
   1298{
   1299    uint8_t args[5];
   1300    uint8_t opcode;
   1301    uint8_t chan_id;
   1302    int i;
   1303    PL330Chan *ch;
   1304    const PL330InsnDesc *insn;
   1305
   1306    s->debug_status = 1;
   1307    chan_id = (s->dbg[0] >>  8) & 0x07;
   1308    opcode  = (s->dbg[0] >> 16) & 0xff;
   1309    args[0] = (s->dbg[0] >> 24) & 0xff;
   1310    args[1] = (s->dbg[1] >>  0) & 0xff;
   1311    args[2] = (s->dbg[1] >>  8) & 0xff;
   1312    args[3] = (s->dbg[1] >> 16) & 0xff;
   1313    args[4] = (s->dbg[1] >> 24) & 0xff;
   1314    trace_pl330_debug_exec(chan_id);
   1315    if (s->dbg[0] & 1) {
   1316        ch = &s->chan[chan_id];
   1317    } else {
   1318        ch = &s->manager;
   1319    }
   1320    insn = NULL;
   1321    for (i = 0; debug_insn_desc[i].size; i++) {
   1322        if ((opcode & debug_insn_desc[i].opmask) == debug_insn_desc[i].opcode) {
   1323            insn = &debug_insn_desc[i];
   1324        }
   1325    }
   1326    if (!insn) {
   1327        pl330_fault(ch, PL330_FAULT_UNDEF_INSTR | PL330_FAULT_DBG_INSTR);
   1328        return ;
   1329    }
   1330    ch->stall = 0;
   1331    insn->exec(ch, opcode, args, insn->size - 1);
   1332    if (ch->fault_type) {
   1333        ch->fault_type |= PL330_FAULT_DBG_INSTR;
   1334    }
   1335    if (ch->stall) {
   1336        trace_pl330_debug_exec_stall();
   1337        qemu_log_mask(LOG_UNIMP, "pl330: stall of debug instruction not "
   1338                      "implemented\n");
   1339    }
   1340    s->debug_status = 0;
   1341}
   1342
   1343/* IOMEM mapped registers */
   1344
   1345static void pl330_iomem_write(void *opaque, hwaddr offset,
   1346                              uint64_t value, unsigned size)
   1347{
   1348    PL330State *s = (PL330State *) opaque;
   1349    int i;
   1350
   1351    trace_pl330_iomem_write((unsigned)offset, (unsigned)value);
   1352
   1353    switch (offset) {
   1354    case PL330_REG_INTEN:
   1355        s->inten = value;
   1356        break;
   1357    case PL330_REG_INTCLR:
   1358        for (i = 0; i < s->num_events; i++) {
   1359            if (s->int_status & s->inten & value & (1 << i)) {
   1360                trace_pl330_iomem_write_clr(i);
   1361                qemu_irq_lower(s->irq[i]);
   1362            }
   1363        }
   1364        s->ev_status &= ~(value & s->inten);
   1365        s->int_status &= ~(value & s->inten);
   1366        break;
   1367    case PL330_REG_DBGCMD:
   1368        if ((value & 3) == 0) {
   1369            pl330_debug_exec(s);
   1370            pl330_exec(s);
   1371        } else {
   1372            qemu_log_mask(LOG_GUEST_ERROR, "pl330: write of illegal value %u "
   1373                          "for offset " TARGET_FMT_plx "\n", (unsigned)value,
   1374                          offset);
   1375        }
   1376        break;
   1377    case PL330_REG_DBGINST0:
   1378        s->dbg[0] = value;
   1379        break;
   1380    case PL330_REG_DBGINST1:
   1381        s->dbg[1] = value;
   1382        break;
   1383    default:
   1384        qemu_log_mask(LOG_GUEST_ERROR, "pl330: bad write offset " TARGET_FMT_plx
   1385                      "\n", offset);
   1386        break;
   1387    }
   1388}
   1389
   1390static inline uint32_t pl330_iomem_read_imp(void *opaque,
   1391        hwaddr offset)
   1392{
   1393    PL330State *s = (PL330State *)opaque;
   1394    int chan_id;
   1395    int i;
   1396    uint32_t res;
   1397
   1398    if (offset >= PL330_REG_PERIPH_ID && offset < PL330_REG_PERIPH_ID + 32) {
   1399        return pl330_id[(offset - PL330_REG_PERIPH_ID) >> 2];
   1400    }
   1401    if (offset >= PL330_REG_CR0_BASE && offset < PL330_REG_CR0_BASE + 24) {
   1402        return s->cfg[(offset - PL330_REG_CR0_BASE) >> 2];
   1403    }
   1404    if (offset >= PL330_REG_CHANCTRL && offset < PL330_REG_DBGSTATUS) {
   1405        offset -= PL330_REG_CHANCTRL;
   1406        chan_id = offset >> 5;
   1407        if (chan_id >= s->num_chnls) {
   1408            qemu_log_mask(LOG_GUEST_ERROR, "pl330: bad read offset "
   1409                          TARGET_FMT_plx "\n", offset);
   1410            return 0;
   1411        }
   1412        switch (offset & 0x1f) {
   1413        case 0x00:
   1414            return s->chan[chan_id].src;
   1415        case 0x04:
   1416            return s->chan[chan_id].dst;
   1417        case 0x08:
   1418            return s->chan[chan_id].control;
   1419        case 0x0C:
   1420            return s->chan[chan_id].lc[0];
   1421        case 0x10:
   1422            return s->chan[chan_id].lc[1];
   1423        default:
   1424            qemu_log_mask(LOG_GUEST_ERROR, "pl330: bad read offset "
   1425                          TARGET_FMT_plx "\n", offset);
   1426            return 0;
   1427        }
   1428    }
   1429    if (offset >= PL330_REG_CSR_BASE && offset < 0x400) {
   1430        offset -= PL330_REG_CSR_BASE;
   1431        chan_id = offset >> 3;
   1432        if (chan_id >= s->num_chnls) {
   1433            qemu_log_mask(LOG_GUEST_ERROR, "pl330: bad read offset "
   1434                          TARGET_FMT_plx "\n", offset);
   1435            return 0;
   1436        }
   1437        switch ((offset >> 2) & 1) {
   1438        case 0x0:
   1439            res = (s->chan[chan_id].ns << 21) |
   1440                    (s->chan[chan_id].wakeup << 4) |
   1441                    (s->chan[chan_id].state) |
   1442                    (s->chan[chan_id].wfp_sbp << 14);
   1443            return res;
   1444        case 0x1:
   1445            return s->chan[chan_id].pc;
   1446        default:
   1447            qemu_log_mask(LOG_GUEST_ERROR, "pl330: read error\n");
   1448            return 0;
   1449        }
   1450    }
   1451    if (offset >= PL330_REG_FTR_BASE && offset < 0x100) {
   1452        offset -= PL330_REG_FTR_BASE;
   1453        chan_id = offset >> 2;
   1454        if (chan_id >= s->num_chnls) {
   1455            qemu_log_mask(LOG_GUEST_ERROR, "pl330: bad read offset "
   1456                          TARGET_FMT_plx "\n", offset);
   1457            return 0;
   1458        }
   1459        return s->chan[chan_id].fault_type;
   1460    }
   1461    switch (offset) {
   1462    case PL330_REG_DSR:
   1463        return (s->manager.ns << 9) | (s->manager.wakeup << 4) |
   1464            (s->manager.state & 0xf);
   1465    case PL330_REG_DPC:
   1466        return s->manager.pc;
   1467    case PL330_REG_INTEN:
   1468        return s->inten;
   1469    case PL330_REG_INT_EVENT_RIS:
   1470        return s->ev_status;
   1471    case PL330_REG_INTMIS:
   1472        return s->int_status;
   1473    case PL330_REG_INTCLR:
   1474        /* Documentation says that we can't read this register
   1475         * but linux kernel does it
   1476         */
   1477        return 0;
   1478    case PL330_REG_FSRD:
   1479        return s->manager.state ? 1 : 0;
   1480    case PL330_REG_FSRC:
   1481        res = 0;
   1482        for (i = 0; i < s->num_chnls; i++) {
   1483            if (s->chan[i].state == pl330_chan_fault ||
   1484                s->chan[i].state == pl330_chan_fault_completing) {
   1485                res |= 1 << i;
   1486            }
   1487        }
   1488        return res;
   1489    case PL330_REG_FTRD:
   1490        return s->manager.fault_type;
   1491    case PL330_REG_DBGSTATUS:
   1492        return s->debug_status;
   1493    default:
   1494        qemu_log_mask(LOG_GUEST_ERROR, "pl330: bad read offset "
   1495                      TARGET_FMT_plx "\n", offset);
   1496    }
   1497    return 0;
   1498}
   1499
   1500static uint64_t pl330_iomem_read(void *opaque, hwaddr offset,
   1501        unsigned size)
   1502{
   1503    uint32_t ret = pl330_iomem_read_imp(opaque, offset);
   1504    trace_pl330_iomem_read((uint32_t)offset, ret);
   1505    return ret;
   1506}
   1507
   1508static const MemoryRegionOps pl330_ops = {
   1509    .read = pl330_iomem_read,
   1510    .write = pl330_iomem_write,
   1511    .endianness = DEVICE_NATIVE_ENDIAN,
   1512    .impl = {
   1513        .min_access_size = 4,
   1514        .max_access_size = 4,
   1515    }
   1516};
   1517
   1518/* Controller logic and initialization */
   1519
   1520static void pl330_chan_reset(PL330Chan *ch)
   1521{
   1522    ch->src = 0;
   1523    ch->dst = 0;
   1524    ch->pc = 0;
   1525    ch->state = pl330_chan_stopped;
   1526    ch->watchdog_timer = 0;
   1527    ch->stall = 0;
   1528    ch->control = 0;
   1529    ch->status = 0;
   1530    ch->fault_type = 0;
   1531}
   1532
   1533static void pl330_reset(DeviceState *d)
   1534{
   1535    int i;
   1536    PL330State *s = PL330(d);
   1537
   1538    s->inten = 0;
   1539    s->int_status = 0;
   1540    s->ev_status = 0;
   1541    s->debug_status = 0;
   1542    s->num_faulting = 0;
   1543    s->manager.ns = s->mgr_ns_at_rst;
   1544    pl330_fifo_reset(&s->fifo);
   1545    pl330_queue_reset(&s->read_queue);
   1546    pl330_queue_reset(&s->write_queue);
   1547
   1548    for (i = 0; i < s->num_chnls; i++) {
   1549        pl330_chan_reset(&s->chan[i]);
   1550    }
   1551    for (i = 0; i < s->num_periph_req; i++) {
   1552        s->periph_busy[i] = 0;
   1553    }
   1554
   1555    timer_del(s->timer);
   1556}
   1557
   1558static void pl330_realize(DeviceState *dev, Error **errp)
   1559{
   1560    int i;
   1561    PL330State *s = PL330(dev);
   1562
   1563    sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq_abort);
   1564    memory_region_init_io(&s->iomem, OBJECT(s), &pl330_ops, s,
   1565                          "dma", PL330_IOMEM_SIZE);
   1566    sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
   1567
   1568    if (!s->mem_mr) {
   1569        error_setg(errp, "'memory' link is not set");
   1570        return;
   1571    } else if (s->mem_mr == get_system_memory()) {
   1572        /* Avoid creating new AS for system memory. */
   1573        s->mem_as = &address_space_memory;
   1574    } else {
   1575        s->mem_as = g_new0(AddressSpace, 1);
   1576        address_space_init(s->mem_as, s->mem_mr,
   1577                           memory_region_name(s->mem_mr));
   1578    }
   1579
   1580    s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, pl330_exec_cycle_timer, s);
   1581
   1582    s->cfg[0] = (s->mgr_ns_at_rst ? 0x4 : 0) |
   1583                (s->num_periph_req > 0 ? 1 : 0) |
   1584                ((s->num_chnls - 1) & 0x7) << 4 |
   1585                ((s->num_periph_req - 1) & 0x1f) << 12 |
   1586                ((s->num_events - 1) & 0x1f) << 17;
   1587
   1588    switch (s->i_cache_len) {
   1589    case (4):
   1590        s->cfg[1] |= 2;
   1591        break;
   1592    case (8):
   1593        s->cfg[1] |= 3;
   1594        break;
   1595    case (16):
   1596        s->cfg[1] |= 4;
   1597        break;
   1598    case (32):
   1599        s->cfg[1] |= 5;
   1600        break;
   1601    default:
   1602        error_setg(errp, "Bad value for i-cache_len property: %" PRIx8,
   1603                   s->i_cache_len);
   1604        return;
   1605    }
   1606    s->cfg[1] |= ((s->num_i_cache_lines - 1) & 0xf) << 4;
   1607
   1608    s->chan = g_new0(PL330Chan, s->num_chnls);
   1609    s->hi_seqn = g_new0(uint8_t, s->num_chnls);
   1610    s->lo_seqn = g_new0(uint8_t, s->num_chnls);
   1611    for (i = 0; i < s->num_chnls; i++) {
   1612        s->chan[i].parent = s;
   1613        s->chan[i].tag = (uint8_t)i;
   1614    }
   1615    s->manager.parent = s;
   1616    s->manager.tag = s->num_chnls;
   1617    s->manager.is_manager = true;
   1618
   1619    s->irq = g_new0(qemu_irq, s->num_events);
   1620    for (i = 0; i < s->num_events; i++) {
   1621        sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq[i]);
   1622    }
   1623
   1624    qdev_init_gpio_in(dev, pl330_dma_stop_irq, PL330_PERIPH_NUM);
   1625
   1626    switch (s->data_width) {
   1627    case (32):
   1628        s->cfg[CFG_CRD] |= 0x2;
   1629        break;
   1630    case (64):
   1631        s->cfg[CFG_CRD] |= 0x3;
   1632        break;
   1633    case (128):
   1634        s->cfg[CFG_CRD] |= 0x4;
   1635        break;
   1636    default:
   1637        error_setg(errp, "Bad value for data_width property: %" PRIx8,
   1638                   s->data_width);
   1639        return;
   1640    }
   1641
   1642    s->cfg[CFG_CRD] |= ((s->wr_cap - 1) & 0x7) << 4 |
   1643                    ((s->wr_q_dep - 1) & 0xf) << 8 |
   1644                    ((s->rd_cap - 1) & 0x7) << 12 |
   1645                    ((s->rd_q_dep - 1) & 0xf) << 16 |
   1646                    ((s->data_buffer_dep - 1) & 0x1ff) << 20;
   1647
   1648    pl330_queue_init(&s->read_queue, s->rd_q_dep, s);
   1649    pl330_queue_init(&s->write_queue, s->wr_q_dep, s);
   1650    pl330_fifo_init(&s->fifo, s->data_width / 4 * s->data_buffer_dep);
   1651}
   1652
   1653static Property pl330_properties[] = {
   1654    /* CR0 */
   1655    DEFINE_PROP_UINT32("num_chnls", PL330State, num_chnls, 8),
   1656    DEFINE_PROP_UINT8("num_periph_req", PL330State, num_periph_req, 4),
   1657    DEFINE_PROP_UINT8("num_events", PL330State, num_events, 16),
   1658    DEFINE_PROP_UINT8("mgr_ns_at_rst", PL330State, mgr_ns_at_rst, 0),
   1659    /* CR1 */
   1660    DEFINE_PROP_UINT8("i-cache_len", PL330State, i_cache_len, 4),
   1661    DEFINE_PROP_UINT8("num_i-cache_lines", PL330State, num_i_cache_lines, 8),
   1662    /* CR2-4 */
   1663    DEFINE_PROP_UINT32("boot_addr", PL330State, cfg[CFG_BOOT_ADDR], 0),
   1664    DEFINE_PROP_UINT32("INS", PL330State, cfg[CFG_INS], 0),
   1665    DEFINE_PROP_UINT32("PNS", PL330State, cfg[CFG_PNS], 0),
   1666    /* CRD */
   1667    DEFINE_PROP_UINT8("data_width", PL330State, data_width, 64),
   1668    DEFINE_PROP_UINT8("wr_cap", PL330State, wr_cap, 8),
   1669    DEFINE_PROP_UINT8("wr_q_dep", PL330State, wr_q_dep, 16),
   1670    DEFINE_PROP_UINT8("rd_cap", PL330State, rd_cap, 8),
   1671    DEFINE_PROP_UINT8("rd_q_dep", PL330State, rd_q_dep, 16),
   1672    DEFINE_PROP_UINT16("data_buffer_dep", PL330State, data_buffer_dep, 256),
   1673
   1674    DEFINE_PROP_LINK("memory", PL330State, mem_mr,
   1675                     TYPE_MEMORY_REGION, MemoryRegion *),
   1676
   1677    DEFINE_PROP_END_OF_LIST(),
   1678};
   1679
   1680static void pl330_class_init(ObjectClass *klass, void *data)
   1681{
   1682    DeviceClass *dc = DEVICE_CLASS(klass);
   1683
   1684    dc->realize = pl330_realize;
   1685    dc->reset = pl330_reset;
   1686    device_class_set_props(dc, pl330_properties);
   1687    dc->vmsd = &vmstate_pl330;
   1688}
   1689
   1690static const TypeInfo pl330_type_info = {
   1691    .name           = TYPE_PL330,
   1692    .parent         = TYPE_SYS_BUS_DEVICE,
   1693    .instance_size  = sizeof(PL330State),
   1694    .class_init      = pl330_class_init,
   1695};
   1696
   1697static void pl330_register_types(void)
   1698{
   1699    type_register_static(&pl330_type_info);
   1700}
   1701
   1702type_init(pl330_register_types)