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