xref: /openbmc/qemu/hw/misc/macio/mac_dbdma.c (revision 7f6c3d1a)
1 /*
2  * PowerMac descriptor-based DMA emulation
3  *
4  * Copyright (c) 2005-2007 Fabrice Bellard
5  * Copyright (c) 2007 Jocelyn Mayer
6  * Copyright (c) 2009 Laurent Vivier
7  *
8  * some parts from linux-2.6.28, arch/powerpc/include/asm/dbdma.h
9  *
10  *   Definitions for using the Apple Descriptor-Based DMA controller
11  *   in Power Macintosh computers.
12  *
13  *   Copyright (C) 1996 Paul Mackerras.
14  *
15  * some parts from mol 0.9.71
16  *
17  *   Descriptor based DMA emulation
18  *
19  *   Copyright (C) 1998-2004 Samuel Rydh (samuel@ibrium.se)
20  *
21  * Permission is hereby granted, free of charge, to any person obtaining a copy
22  * of this software and associated documentation files (the "Software"), to deal
23  * in the Software without restriction, including without limitation the rights
24  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
25  * copies of the Software, and to permit persons to whom the Software is
26  * furnished to do so, subject to the following conditions:
27  *
28  * The above copyright notice and this permission notice shall be included in
29  * all copies or substantial portions of the Software.
30  *
31  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
32  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
33  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
34  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
35  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
36  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
37  * THE SOFTWARE.
38  */
39 
40 #include "qemu/osdep.h"
41 #include "hw/irq.h"
42 #include "hw/ppc/mac_dbdma.h"
43 #include "migration/vmstate.h"
44 #include "qemu/main-loop.h"
45 #include "qemu/module.h"
46 #include "qemu/log.h"
47 #include "sysemu/dma.h"
48 
49 /* debug DBDMA */
50 #define DEBUG_DBDMA 0
51 #define DEBUG_DBDMA_CHANMASK ((1ull << DBDMA_CHANNELS) - 1)
52 
53 #define DBDMA_DPRINTF(fmt, ...) do { \
54     if (DEBUG_DBDMA) { \
55         printf("DBDMA: " fmt , ## __VA_ARGS__); \
56     } \
57 } while (0)
58 
59 #define DBDMA_DPRINTFCH(ch, fmt, ...) do { \
60     if (DEBUG_DBDMA) { \
61         if ((1ul << (ch)->channel) & DEBUG_DBDMA_CHANMASK) { \
62             printf("DBDMA[%02x]: " fmt , (ch)->channel, ## __VA_ARGS__); \
63         } \
64     } \
65 } while (0)
66 
67 /*
68  */
69 
70 static DBDMAState *dbdma_from_ch(DBDMA_channel *ch)
71 {
72     return container_of(ch, DBDMAState, channels[ch->channel]);
73 }
74 
75 #if DEBUG_DBDMA
76 static void dump_dbdma_cmd(DBDMA_channel *ch, dbdma_cmd *cmd)
77 {
78     DBDMA_DPRINTFCH(ch, "dbdma_cmd %p\n", cmd);
79     DBDMA_DPRINTFCH(ch, "    req_count 0x%04x\n", le16_to_cpu(cmd->req_count));
80     DBDMA_DPRINTFCH(ch, "    command 0x%04x\n", le16_to_cpu(cmd->command));
81     DBDMA_DPRINTFCH(ch, "    phy_addr 0x%08x\n", le32_to_cpu(cmd->phy_addr));
82     DBDMA_DPRINTFCH(ch, "    cmd_dep 0x%08x\n", le32_to_cpu(cmd->cmd_dep));
83     DBDMA_DPRINTFCH(ch, "    res_count 0x%04x\n", le16_to_cpu(cmd->res_count));
84     DBDMA_DPRINTFCH(ch, "    xfer_status 0x%04x\n",
85                     le16_to_cpu(cmd->xfer_status));
86 }
87 #else
88 static void dump_dbdma_cmd(DBDMA_channel *ch, dbdma_cmd *cmd)
89 {
90 }
91 #endif
92 static void dbdma_cmdptr_load(DBDMA_channel *ch)
93 {
94     DBDMA_DPRINTFCH(ch, "dbdma_cmdptr_load 0x%08x\n",
95                     ch->regs[DBDMA_CMDPTR_LO]);
96     dma_memory_read(&address_space_memory, ch->regs[DBDMA_CMDPTR_LO],
97                     &ch->current, sizeof(dbdma_cmd));
98 }
99 
100 static void dbdma_cmdptr_save(DBDMA_channel *ch)
101 {
102     DBDMA_DPRINTFCH(ch, "-> update 0x%08x stat=0x%08x, res=0x%04x\n",
103                     ch->regs[DBDMA_CMDPTR_LO],
104                     le16_to_cpu(ch->current.xfer_status),
105                     le16_to_cpu(ch->current.res_count));
106     dma_memory_write(&address_space_memory, ch->regs[DBDMA_CMDPTR_LO],
107                      &ch->current, sizeof(dbdma_cmd));
108 }
109 
110 static void kill_channel(DBDMA_channel *ch)
111 {
112     DBDMA_DPRINTFCH(ch, "kill_channel\n");
113 
114     ch->regs[DBDMA_STATUS] |= DEAD;
115     ch->regs[DBDMA_STATUS] &= ~ACTIVE;
116 
117     qemu_irq_raise(ch->irq);
118 }
119 
120 static void conditional_interrupt(DBDMA_channel *ch)
121 {
122     dbdma_cmd *current = &ch->current;
123     uint16_t intr;
124     uint16_t sel_mask, sel_value;
125     uint32_t status;
126     int cond;
127 
128     DBDMA_DPRINTFCH(ch, "%s\n", __func__);
129 
130     intr = le16_to_cpu(current->command) & INTR_MASK;
131 
132     switch(intr) {
133     case INTR_NEVER:  /* don't interrupt */
134         return;
135     case INTR_ALWAYS: /* always interrupt */
136         qemu_irq_raise(ch->irq);
137         DBDMA_DPRINTFCH(ch, "%s: raise\n", __func__);
138         return;
139     }
140 
141     status = ch->regs[DBDMA_STATUS] & DEVSTAT;
142 
143     sel_mask = (ch->regs[DBDMA_INTR_SEL] >> 16) & 0x0f;
144     sel_value = ch->regs[DBDMA_INTR_SEL] & 0x0f;
145 
146     cond = (status & sel_mask) == (sel_value & sel_mask);
147 
148     switch(intr) {
149     case INTR_IFSET:  /* intr if condition bit is 1 */
150         if (cond) {
151             qemu_irq_raise(ch->irq);
152             DBDMA_DPRINTFCH(ch, "%s: raise\n", __func__);
153         }
154         return;
155     case INTR_IFCLR:  /* intr if condition bit is 0 */
156         if (!cond) {
157             qemu_irq_raise(ch->irq);
158             DBDMA_DPRINTFCH(ch, "%s: raise\n", __func__);
159         }
160         return;
161     }
162 }
163 
164 static int conditional_wait(DBDMA_channel *ch)
165 {
166     dbdma_cmd *current = &ch->current;
167     uint16_t wait;
168     uint16_t sel_mask, sel_value;
169     uint32_t status;
170     int cond;
171     int res = 0;
172 
173     wait = le16_to_cpu(current->command) & WAIT_MASK;
174     switch(wait) {
175     case WAIT_NEVER:  /* don't wait */
176         return 0;
177     case WAIT_ALWAYS: /* always wait */
178         DBDMA_DPRINTFCH(ch, "  [WAIT_ALWAYS]\n");
179         return 1;
180     }
181 
182     status = ch->regs[DBDMA_STATUS] & DEVSTAT;
183 
184     sel_mask = (ch->regs[DBDMA_WAIT_SEL] >> 16) & 0x0f;
185     sel_value = ch->regs[DBDMA_WAIT_SEL] & 0x0f;
186 
187     cond = (status & sel_mask) == (sel_value & sel_mask);
188 
189     switch(wait) {
190     case WAIT_IFSET:  /* wait if condition bit is 1 */
191         if (cond) {
192             res = 1;
193         }
194         DBDMA_DPRINTFCH(ch, "  [WAIT_IFSET=%d]\n", res);
195         break;
196     case WAIT_IFCLR:  /* wait if condition bit is 0 */
197         if (!cond) {
198             res = 1;
199         }
200         DBDMA_DPRINTFCH(ch, "  [WAIT_IFCLR=%d]\n", res);
201         break;
202     }
203     return res;
204 }
205 
206 static void next(DBDMA_channel *ch)
207 {
208     uint32_t cp;
209 
210     ch->regs[DBDMA_STATUS] &= ~BT;
211 
212     cp = ch->regs[DBDMA_CMDPTR_LO];
213     ch->regs[DBDMA_CMDPTR_LO] = cp + sizeof(dbdma_cmd);
214     dbdma_cmdptr_load(ch);
215 }
216 
217 static void branch(DBDMA_channel *ch)
218 {
219     dbdma_cmd *current = &ch->current;
220 
221     ch->regs[DBDMA_CMDPTR_LO] = le32_to_cpu(current->cmd_dep);
222     ch->regs[DBDMA_STATUS] |= BT;
223     dbdma_cmdptr_load(ch);
224 }
225 
226 static void conditional_branch(DBDMA_channel *ch)
227 {
228     dbdma_cmd *current = &ch->current;
229     uint16_t br;
230     uint16_t sel_mask, sel_value;
231     uint32_t status;
232     int cond;
233 
234     /* check if we must branch */
235 
236     br = le16_to_cpu(current->command) & BR_MASK;
237 
238     switch(br) {
239     case BR_NEVER:  /* don't branch */
240         next(ch);
241         return;
242     case BR_ALWAYS: /* always branch */
243         DBDMA_DPRINTFCH(ch, "  [BR_ALWAYS]\n");
244         branch(ch);
245         return;
246     }
247 
248     status = ch->regs[DBDMA_STATUS] & DEVSTAT;
249 
250     sel_mask = (ch->regs[DBDMA_BRANCH_SEL] >> 16) & 0x0f;
251     sel_value = ch->regs[DBDMA_BRANCH_SEL] & 0x0f;
252 
253     cond = (status & sel_mask) == (sel_value & sel_mask);
254 
255     switch(br) {
256     case BR_IFSET:  /* branch if condition bit is 1 */
257         if (cond) {
258             DBDMA_DPRINTFCH(ch, "  [BR_IFSET = 1]\n");
259             branch(ch);
260         } else {
261             DBDMA_DPRINTFCH(ch, "  [BR_IFSET = 0]\n");
262             next(ch);
263         }
264         return;
265     case BR_IFCLR:  /* branch if condition bit is 0 */
266         if (!cond) {
267             DBDMA_DPRINTFCH(ch, "  [BR_IFCLR = 1]\n");
268             branch(ch);
269         } else {
270             DBDMA_DPRINTFCH(ch, "  [BR_IFCLR = 0]\n");
271             next(ch);
272         }
273         return;
274     }
275 }
276 
277 static void channel_run(DBDMA_channel *ch);
278 
279 static void dbdma_end(DBDMA_io *io)
280 {
281     DBDMA_channel *ch = io->channel;
282     dbdma_cmd *current = &ch->current;
283 
284     DBDMA_DPRINTFCH(ch, "%s\n", __func__);
285 
286     if (conditional_wait(ch))
287         goto wait;
288 
289     current->xfer_status = cpu_to_le16(ch->regs[DBDMA_STATUS]);
290     current->res_count = cpu_to_le16(io->len);
291     dbdma_cmdptr_save(ch);
292     if (io->is_last)
293         ch->regs[DBDMA_STATUS] &= ~FLUSH;
294 
295     conditional_interrupt(ch);
296     conditional_branch(ch);
297 
298 wait:
299     /* Indicate that we're ready for a new DMA round */
300     ch->io.processing = false;
301 
302     if ((ch->regs[DBDMA_STATUS] & RUN) &&
303         (ch->regs[DBDMA_STATUS] & ACTIVE))
304         channel_run(ch);
305 }
306 
307 static void start_output(DBDMA_channel *ch, int key, uint32_t addr,
308                         uint16_t req_count, int is_last)
309 {
310     DBDMA_DPRINTFCH(ch, "start_output\n");
311 
312     /* KEY_REGS, KEY_DEVICE and KEY_STREAM
313      * are not implemented in the mac-io chip
314      */
315 
316     DBDMA_DPRINTFCH(ch, "addr 0x%x key 0x%x\n", addr, key);
317     if (!addr || key > KEY_STREAM3) {
318         kill_channel(ch);
319         return;
320     }
321 
322     ch->io.addr = addr;
323     ch->io.len = req_count;
324     ch->io.is_last = is_last;
325     ch->io.dma_end = dbdma_end;
326     ch->io.is_dma_out = 1;
327     ch->io.processing = true;
328     if (ch->rw) {
329         ch->rw(&ch->io);
330     }
331 }
332 
333 static void start_input(DBDMA_channel *ch, int key, uint32_t addr,
334                        uint16_t req_count, int is_last)
335 {
336     DBDMA_DPRINTFCH(ch, "start_input\n");
337 
338     /* KEY_REGS, KEY_DEVICE and KEY_STREAM
339      * are not implemented in the mac-io chip
340      */
341 
342     DBDMA_DPRINTFCH(ch, "addr 0x%x key 0x%x\n", addr, key);
343     if (!addr || key > KEY_STREAM3) {
344         kill_channel(ch);
345         return;
346     }
347 
348     ch->io.addr = addr;
349     ch->io.len = req_count;
350     ch->io.is_last = is_last;
351     ch->io.dma_end = dbdma_end;
352     ch->io.is_dma_out = 0;
353     ch->io.processing = true;
354     if (ch->rw) {
355         ch->rw(&ch->io);
356     }
357 }
358 
359 static void load_word(DBDMA_channel *ch, int key, uint32_t addr,
360                      uint16_t len)
361 {
362     dbdma_cmd *current = &ch->current;
363 
364     DBDMA_DPRINTFCH(ch, "load_word %d bytes, addr=%08x\n", len, addr);
365 
366     /* only implements KEY_SYSTEM */
367 
368     if (key != KEY_SYSTEM) {
369         printf("DBDMA: LOAD_WORD, unimplemented key %x\n", key);
370         kill_channel(ch);
371         return;
372     }
373 
374     dma_memory_read(&address_space_memory, addr, &current->cmd_dep, len);
375 
376     if (conditional_wait(ch))
377         goto wait;
378 
379     current->xfer_status = cpu_to_le16(ch->regs[DBDMA_STATUS]);
380     dbdma_cmdptr_save(ch);
381     ch->regs[DBDMA_STATUS] &= ~FLUSH;
382 
383     conditional_interrupt(ch);
384     next(ch);
385 
386 wait:
387     DBDMA_kick(dbdma_from_ch(ch));
388 }
389 
390 static void store_word(DBDMA_channel *ch, int key, uint32_t addr,
391                       uint16_t len)
392 {
393     dbdma_cmd *current = &ch->current;
394 
395     DBDMA_DPRINTFCH(ch, "store_word %d bytes, addr=%08x pa=%x\n",
396                     len, addr, le32_to_cpu(current->cmd_dep));
397 
398     /* only implements KEY_SYSTEM */
399 
400     if (key != KEY_SYSTEM) {
401         printf("DBDMA: STORE_WORD, unimplemented key %x\n", key);
402         kill_channel(ch);
403         return;
404     }
405 
406     dma_memory_write(&address_space_memory, addr, &current->cmd_dep, len);
407 
408     if (conditional_wait(ch))
409         goto wait;
410 
411     current->xfer_status = cpu_to_le16(ch->regs[DBDMA_STATUS]);
412     dbdma_cmdptr_save(ch);
413     ch->regs[DBDMA_STATUS] &= ~FLUSH;
414 
415     conditional_interrupt(ch);
416     next(ch);
417 
418 wait:
419     DBDMA_kick(dbdma_from_ch(ch));
420 }
421 
422 static void nop(DBDMA_channel *ch)
423 {
424     dbdma_cmd *current = &ch->current;
425 
426     if (conditional_wait(ch))
427         goto wait;
428 
429     current->xfer_status = cpu_to_le16(ch->regs[DBDMA_STATUS]);
430     dbdma_cmdptr_save(ch);
431 
432     conditional_interrupt(ch);
433     conditional_branch(ch);
434 
435 wait:
436     DBDMA_kick(dbdma_from_ch(ch));
437 }
438 
439 static void stop(DBDMA_channel *ch)
440 {
441     ch->regs[DBDMA_STATUS] &= ~(ACTIVE);
442 
443     /* the stop command does not increment command pointer */
444 }
445 
446 static void channel_run(DBDMA_channel *ch)
447 {
448     dbdma_cmd *current = &ch->current;
449     uint16_t cmd, key;
450     uint16_t req_count;
451     uint32_t phy_addr;
452 
453     DBDMA_DPRINTFCH(ch, "channel_run\n");
454     dump_dbdma_cmd(ch, current);
455 
456     /* clear WAKE flag at command fetch */
457 
458     ch->regs[DBDMA_STATUS] &= ~WAKE;
459 
460     cmd = le16_to_cpu(current->command) & COMMAND_MASK;
461 
462     switch (cmd) {
463     case DBDMA_NOP:
464         nop(ch);
465         return;
466 
467     case DBDMA_STOP:
468         stop(ch);
469         return;
470     }
471 
472     key = le16_to_cpu(current->command) & 0x0700;
473     req_count = le16_to_cpu(current->req_count);
474     phy_addr = le32_to_cpu(current->phy_addr);
475 
476     if (key == KEY_STREAM4) {
477         printf("command %x, invalid key 4\n", cmd);
478         kill_channel(ch);
479         return;
480     }
481 
482     switch (cmd) {
483     case OUTPUT_MORE:
484         DBDMA_DPRINTFCH(ch, "* OUTPUT_MORE *\n");
485         start_output(ch, key, phy_addr, req_count, 0);
486         return;
487 
488     case OUTPUT_LAST:
489         DBDMA_DPRINTFCH(ch, "* OUTPUT_LAST *\n");
490         start_output(ch, key, phy_addr, req_count, 1);
491         return;
492 
493     case INPUT_MORE:
494         DBDMA_DPRINTFCH(ch, "* INPUT_MORE *\n");
495         start_input(ch, key, phy_addr, req_count, 0);
496         return;
497 
498     case INPUT_LAST:
499         DBDMA_DPRINTFCH(ch, "* INPUT_LAST *\n");
500         start_input(ch, key, phy_addr, req_count, 1);
501         return;
502     }
503 
504     if (key < KEY_REGS) {
505         printf("command %x, invalid key %x\n", cmd, key);
506         key = KEY_SYSTEM;
507     }
508 
509     /* for LOAD_WORD and STORE_WORD, req_count is on 3 bits
510      * and BRANCH is invalid
511      */
512 
513     req_count = req_count & 0x0007;
514     if (req_count & 0x4) {
515         req_count = 4;
516         phy_addr &= ~3;
517     } else if (req_count & 0x2) {
518         req_count = 2;
519         phy_addr &= ~1;
520     } else
521         req_count = 1;
522 
523     switch (cmd) {
524     case LOAD_WORD:
525         DBDMA_DPRINTFCH(ch, "* LOAD_WORD *\n");
526         load_word(ch, key, phy_addr, req_count);
527         return;
528 
529     case STORE_WORD:
530         DBDMA_DPRINTFCH(ch, "* STORE_WORD *\n");
531         store_word(ch, key, phy_addr, req_count);
532         return;
533     }
534 }
535 
536 static void DBDMA_run(DBDMAState *s)
537 {
538     int channel;
539 
540     for (channel = 0; channel < DBDMA_CHANNELS; channel++) {
541         DBDMA_channel *ch = &s->channels[channel];
542         uint32_t status = ch->regs[DBDMA_STATUS];
543         if (!ch->io.processing && (status & RUN) && (status & ACTIVE)) {
544             channel_run(ch);
545         }
546     }
547 }
548 
549 static void DBDMA_run_bh(void *opaque)
550 {
551     DBDMAState *s = opaque;
552 
553     DBDMA_DPRINTF("-> DBDMA_run_bh\n");
554     DBDMA_run(s);
555     DBDMA_DPRINTF("<- DBDMA_run_bh\n");
556 }
557 
558 void DBDMA_kick(DBDMAState *dbdma)
559 {
560     qemu_bh_schedule(dbdma->bh);
561 }
562 
563 void DBDMA_register_channel(void *dbdma, int nchan, qemu_irq irq,
564                             DBDMA_rw rw, DBDMA_flush flush,
565                             void *opaque)
566 {
567     DBDMAState *s = dbdma;
568     DBDMA_channel *ch = &s->channels[nchan];
569 
570     DBDMA_DPRINTFCH(ch, "DBDMA_register_channel 0x%x\n", nchan);
571 
572     assert(rw);
573     assert(flush);
574 
575     ch->irq = irq;
576     ch->rw = rw;
577     ch->flush = flush;
578     ch->io.opaque = opaque;
579 }
580 
581 static void dbdma_control_write(DBDMA_channel *ch)
582 {
583     uint16_t mask, value;
584     uint32_t status;
585     bool do_flush = false;
586 
587     mask = (ch->regs[DBDMA_CONTROL] >> 16) & 0xffff;
588     value = ch->regs[DBDMA_CONTROL] & 0xffff;
589 
590     /* This is the status register which we'll update
591      * appropriately and store back
592      */
593     status = ch->regs[DBDMA_STATUS];
594 
595     /* RUN and PAUSE are bits under SW control only
596      * FLUSH and WAKE are set by SW and cleared by HW
597      * DEAD, ACTIVE and BT are only under HW control
598      *
599      * We handle ACTIVE separately at the end of the
600      * logic to ensure all cases are covered.
601      */
602 
603     /* Setting RUN will tentatively activate the channel
604      */
605     if ((mask & RUN) && (value & RUN)) {
606         status |= RUN;
607         DBDMA_DPRINTFCH(ch, " Setting RUN !\n");
608     }
609 
610     /* Clearing RUN 1->0 will stop the channel */
611     if ((mask & RUN) && !(value & RUN)) {
612         /* This has the side effect of clearing the DEAD bit */
613         status &= ~(DEAD | RUN);
614         DBDMA_DPRINTFCH(ch, " Clearing RUN !\n");
615     }
616 
617     /* Setting WAKE wakes up an idle channel if it's running
618      *
619      * Note: The doc doesn't say so but assume that only works
620      * on a channel whose RUN bit is set.
621      *
622      * We set WAKE in status, it's not terribly useful as it will
623      * be cleared on the next command fetch but it seems to mimmic
624      * the HW behaviour and is useful for the way we handle
625      * ACTIVE further down.
626      */
627     if ((mask & WAKE) && (value & WAKE) && (status & RUN)) {
628         status |= WAKE;
629         DBDMA_DPRINTFCH(ch, " Setting WAKE !\n");
630     }
631 
632     /* PAUSE being set will deactivate (or prevent activation)
633      * of the channel. We just copy it over for now, ACTIVE will
634      * be re-evaluated later.
635      */
636     if (mask & PAUSE) {
637         status = (status & ~PAUSE) | (value & PAUSE);
638         DBDMA_DPRINTFCH(ch, " %sing PAUSE !\n",
639                         (value & PAUSE) ? "sett" : "clear");
640     }
641 
642     /* FLUSH is its own thing */
643     if ((mask & FLUSH) && (value & FLUSH))  {
644         DBDMA_DPRINTFCH(ch, " Setting FLUSH !\n");
645         /* We set flush directly in the status register, we do *NOT*
646          * set it in "status" so that it gets naturally cleared when
647          * we update the status register further down. That way it
648          * will be set only during the HW flush operation so it is
649          * visible to any completions happening during that time.
650          */
651         ch->regs[DBDMA_STATUS] |= FLUSH;
652         do_flush = true;
653     }
654 
655     /* If either RUN or PAUSE is clear, so should ACTIVE be,
656      * otherwise, ACTIVE will be set if we modified RUN, PAUSE or
657      * set WAKE. That means that PAUSE was just cleared, RUN was
658      * just set or WAKE was just set.
659      */
660     if ((status & PAUSE) || !(status & RUN)) {
661         status &= ~ACTIVE;
662         DBDMA_DPRINTFCH(ch, "  -> ACTIVE down !\n");
663 
664         /* We stopped processing, we want the underlying HW command
665          * to complete *before* we clear the ACTIVE bit. Otherwise
666          * we can get into a situation where the command status will
667          * have RUN or ACTIVE not set which is going to confuse the
668          * MacOS driver.
669          */
670         do_flush = true;
671     } else if (mask & (RUN | PAUSE)) {
672         status |= ACTIVE;
673         DBDMA_DPRINTFCH(ch, " -> ACTIVE up !\n");
674     } else if ((mask & WAKE) && (value & WAKE)) {
675         status |= ACTIVE;
676         DBDMA_DPRINTFCH(ch, " -> ACTIVE up !\n");
677     }
678 
679     DBDMA_DPRINTFCH(ch, " new status=0x%08x\n", status);
680 
681     /* If we need to flush the underlying HW, do it now, this happens
682      * both on FLUSH commands and when stopping the channel for safety.
683      */
684     if (do_flush && ch->flush) {
685         ch->flush(&ch->io);
686     }
687 
688     /* Finally update the status register image */
689     ch->regs[DBDMA_STATUS] = status;
690 
691     /* If active, make sure the BH gets to run */
692     if (status & ACTIVE) {
693         DBDMA_kick(dbdma_from_ch(ch));
694     }
695 }
696 
697 static void dbdma_write(void *opaque, hwaddr addr,
698                         uint64_t value, unsigned size)
699 {
700     int channel = addr >> DBDMA_CHANNEL_SHIFT;
701     DBDMAState *s = opaque;
702     DBDMA_channel *ch = &s->channels[channel];
703     int reg = (addr - (channel << DBDMA_CHANNEL_SHIFT)) >> 2;
704 
705     DBDMA_DPRINTFCH(ch, "writel 0x" TARGET_FMT_plx " <= 0x%08"PRIx64"\n",
706                     addr, value);
707     DBDMA_DPRINTFCH(ch, "channel 0x%x reg 0x%x\n",
708                     (uint32_t)addr >> DBDMA_CHANNEL_SHIFT, reg);
709 
710     /* cmdptr cannot be modified if channel is ACTIVE */
711 
712     if (reg == DBDMA_CMDPTR_LO && (ch->regs[DBDMA_STATUS] & ACTIVE)) {
713         return;
714     }
715 
716     ch->regs[reg] = value;
717 
718     switch(reg) {
719     case DBDMA_CONTROL:
720         dbdma_control_write(ch);
721         break;
722     case DBDMA_CMDPTR_LO:
723         /* 16-byte aligned */
724         ch->regs[DBDMA_CMDPTR_LO] &= ~0xf;
725         dbdma_cmdptr_load(ch);
726         break;
727     case DBDMA_STATUS:
728     case DBDMA_INTR_SEL:
729     case DBDMA_BRANCH_SEL:
730     case DBDMA_WAIT_SEL:
731         /* nothing to do */
732         break;
733     case DBDMA_XFER_MODE:
734     case DBDMA_CMDPTR_HI:
735     case DBDMA_DATA2PTR_HI:
736     case DBDMA_DATA2PTR_LO:
737     case DBDMA_ADDRESS_HI:
738     case DBDMA_BRANCH_ADDR_HI:
739     case DBDMA_RES1:
740     case DBDMA_RES2:
741     case DBDMA_RES3:
742     case DBDMA_RES4:
743         /* unused */
744         break;
745     }
746 }
747 
748 static uint64_t dbdma_read(void *opaque, hwaddr addr,
749                            unsigned size)
750 {
751     uint32_t value;
752     int channel = addr >> DBDMA_CHANNEL_SHIFT;
753     DBDMAState *s = opaque;
754     DBDMA_channel *ch = &s->channels[channel];
755     int reg = (addr - (channel << DBDMA_CHANNEL_SHIFT)) >> 2;
756 
757     value = ch->regs[reg];
758 
759     switch(reg) {
760     case DBDMA_CONTROL:
761         value = ch->regs[DBDMA_STATUS];
762         break;
763     case DBDMA_STATUS:
764     case DBDMA_CMDPTR_LO:
765     case DBDMA_INTR_SEL:
766     case DBDMA_BRANCH_SEL:
767     case DBDMA_WAIT_SEL:
768         /* nothing to do */
769         break;
770     case DBDMA_XFER_MODE:
771     case DBDMA_CMDPTR_HI:
772     case DBDMA_DATA2PTR_HI:
773     case DBDMA_DATA2PTR_LO:
774     case DBDMA_ADDRESS_HI:
775     case DBDMA_BRANCH_ADDR_HI:
776         /* unused */
777         value = 0;
778         break;
779     case DBDMA_RES1:
780     case DBDMA_RES2:
781     case DBDMA_RES3:
782     case DBDMA_RES4:
783         /* reserved */
784         break;
785     }
786 
787     DBDMA_DPRINTFCH(ch, "readl 0x" TARGET_FMT_plx " => 0x%08x\n", addr, value);
788     DBDMA_DPRINTFCH(ch, "channel 0x%x reg 0x%x\n",
789                     (uint32_t)addr >> DBDMA_CHANNEL_SHIFT, reg);
790 
791     return value;
792 }
793 
794 static const MemoryRegionOps dbdma_ops = {
795     .read = dbdma_read,
796     .write = dbdma_write,
797     .endianness = DEVICE_LITTLE_ENDIAN,
798     .valid = {
799         .min_access_size = 4,
800         .max_access_size = 4,
801     },
802 };
803 
804 static const VMStateDescription vmstate_dbdma_io = {
805     .name = "dbdma_io",
806     .version_id = 0,
807     .minimum_version_id = 0,
808     .fields = (VMStateField[]) {
809         VMSTATE_UINT64(addr, struct DBDMA_io),
810         VMSTATE_INT32(len, struct DBDMA_io),
811         VMSTATE_INT32(is_last, struct DBDMA_io),
812         VMSTATE_INT32(is_dma_out, struct DBDMA_io),
813         VMSTATE_BOOL(processing, struct DBDMA_io),
814         VMSTATE_END_OF_LIST()
815     }
816 };
817 
818 static const VMStateDescription vmstate_dbdma_cmd = {
819     .name = "dbdma_cmd",
820     .version_id = 0,
821     .minimum_version_id = 0,
822     .fields = (VMStateField[]) {
823         VMSTATE_UINT16(req_count, dbdma_cmd),
824         VMSTATE_UINT16(command, dbdma_cmd),
825         VMSTATE_UINT32(phy_addr, dbdma_cmd),
826         VMSTATE_UINT32(cmd_dep, dbdma_cmd),
827         VMSTATE_UINT16(res_count, dbdma_cmd),
828         VMSTATE_UINT16(xfer_status, dbdma_cmd),
829         VMSTATE_END_OF_LIST()
830     }
831 };
832 
833 static const VMStateDescription vmstate_dbdma_channel = {
834     .name = "dbdma_channel",
835     .version_id = 1,
836     .minimum_version_id = 1,
837     .fields = (VMStateField[]) {
838         VMSTATE_UINT32_ARRAY(regs, struct DBDMA_channel, DBDMA_REGS),
839         VMSTATE_STRUCT(io, struct DBDMA_channel, 0, vmstate_dbdma_io, DBDMA_io),
840         VMSTATE_STRUCT(current, struct DBDMA_channel, 0, vmstate_dbdma_cmd,
841                        dbdma_cmd),
842         VMSTATE_END_OF_LIST()
843     }
844 };
845 
846 static const VMStateDescription vmstate_dbdma = {
847     .name = "dbdma",
848     .version_id = 3,
849     .minimum_version_id = 3,
850     .fields = (VMStateField[]) {
851         VMSTATE_STRUCT_ARRAY(channels, DBDMAState, DBDMA_CHANNELS, 1,
852                              vmstate_dbdma_channel, DBDMA_channel),
853         VMSTATE_END_OF_LIST()
854     }
855 };
856 
857 static void mac_dbdma_reset(DeviceState *d)
858 {
859     DBDMAState *s = MAC_DBDMA(d);
860     int i;
861 
862     for (i = 0; i < DBDMA_CHANNELS; i++) {
863         memset(s->channels[i].regs, 0, DBDMA_SIZE);
864     }
865 }
866 
867 static void dbdma_unassigned_rw(DBDMA_io *io)
868 {
869     DBDMA_channel *ch = io->channel;
870     dbdma_cmd *current = &ch->current;
871     uint16_t cmd;
872     qemu_log_mask(LOG_GUEST_ERROR, "%s: use of unassigned channel %d\n",
873                   __func__, ch->channel);
874     ch->io.processing = false;
875 
876     cmd = le16_to_cpu(current->command) & COMMAND_MASK;
877     if (cmd == OUTPUT_MORE || cmd == OUTPUT_LAST ||
878         cmd == INPUT_MORE || cmd == INPUT_LAST) {
879         current->xfer_status = cpu_to_le16(ch->regs[DBDMA_STATUS]);
880         current->res_count = cpu_to_le16(io->len);
881         dbdma_cmdptr_save(ch);
882     }
883 }
884 
885 static void dbdma_unassigned_flush(DBDMA_io *io)
886 {
887     DBDMA_channel *ch = io->channel;
888     qemu_log_mask(LOG_GUEST_ERROR, "%s: use of unassigned channel %d\n",
889                   __func__, ch->channel);
890 }
891 
892 static void mac_dbdma_init(Object *obj)
893 {
894     SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
895     DBDMAState *s = MAC_DBDMA(obj);
896     int i;
897 
898     for (i = 0; i < DBDMA_CHANNELS; i++) {
899         DBDMA_channel *ch = &s->channels[i];
900 
901         ch->rw = dbdma_unassigned_rw;
902         ch->flush = dbdma_unassigned_flush;
903         ch->channel = i;
904         ch->io.channel = ch;
905     }
906 
907     memory_region_init_io(&s->mem, obj, &dbdma_ops, s, "dbdma", 0x1000);
908     sysbus_init_mmio(sbd, &s->mem);
909 }
910 
911 static void mac_dbdma_realize(DeviceState *dev, Error **errp)
912 {
913     DBDMAState *s = MAC_DBDMA(dev);
914 
915     s->bh = qemu_bh_new(DBDMA_run_bh, s);
916 }
917 
918 static void mac_dbdma_class_init(ObjectClass *oc, void *data)
919 {
920     DeviceClass *dc = DEVICE_CLASS(oc);
921 
922     dc->realize = mac_dbdma_realize;
923     dc->reset = mac_dbdma_reset;
924     dc->vmsd = &vmstate_dbdma;
925 }
926 
927 static const TypeInfo mac_dbdma_type_info = {
928     .name = TYPE_MAC_DBDMA,
929     .parent = TYPE_SYS_BUS_DEVICE,
930     .instance_size = sizeof(DBDMAState),
931     .instance_init = mac_dbdma_init,
932     .class_init = mac_dbdma_class_init
933 };
934 
935 static void mac_dbdma_register_types(void)
936 {
937     type_register_static(&mac_dbdma_type_info);
938 }
939 
940 type_init(mac_dbdma_register_types)
941