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