1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39#include "qemu/osdep.h"
40#include "hw/hw.h"
41#include "hw/isa/isa.h"
42#include "hw/ppc/mac_dbdma.h"
43#include "qemu/main-loop.h"
44
45
46
47
48#ifdef DEBUG_DBDMA
49#define DBDMA_DPRINTF(fmt, ...) \
50 do { printf("DBDMA: " fmt , ## __VA_ARGS__); } while (0)
51#else
52#define DBDMA_DPRINTF(fmt, ...)
53#endif
54
55
56
57
58static DBDMAState *dbdma_from_ch(DBDMA_channel *ch)
59{
60 return container_of(ch, DBDMAState, channels[ch->channel]);
61}
62
63#ifdef DEBUG_DBDMA
64static void dump_dbdma_cmd(dbdma_cmd *cmd)
65{
66 printf("dbdma_cmd %p\n", cmd);
67 printf(" req_count 0x%04x\n", le16_to_cpu(cmd->req_count));
68 printf(" command 0x%04x\n", le16_to_cpu(cmd->command));
69 printf(" phy_addr 0x%08x\n", le32_to_cpu(cmd->phy_addr));
70 printf(" cmd_dep 0x%08x\n", le32_to_cpu(cmd->cmd_dep));
71 printf(" res_count 0x%04x\n", le16_to_cpu(cmd->res_count));
72 printf(" xfer_status 0x%04x\n", le16_to_cpu(cmd->xfer_status));
73}
74#else
75static void dump_dbdma_cmd(dbdma_cmd *cmd)
76{
77}
78#endif
79static void dbdma_cmdptr_load(DBDMA_channel *ch)
80{
81 DBDMA_DPRINTF("dbdma_cmdptr_load 0x%08x\n",
82 ch->regs[DBDMA_CMDPTR_LO]);
83 cpu_physical_memory_read(ch->regs[DBDMA_CMDPTR_LO],
84 &ch->current, sizeof(dbdma_cmd));
85}
86
87static void dbdma_cmdptr_save(DBDMA_channel *ch)
88{
89 DBDMA_DPRINTF("dbdma_cmdptr_save 0x%08x\n",
90 ch->regs[DBDMA_CMDPTR_LO]);
91 DBDMA_DPRINTF("xfer_status 0x%08x res_count 0x%04x\n",
92 le16_to_cpu(ch->current.xfer_status),
93 le16_to_cpu(ch->current.res_count));
94 cpu_physical_memory_write(ch->regs[DBDMA_CMDPTR_LO],
95 &ch->current, sizeof(dbdma_cmd));
96}
97
98static void kill_channel(DBDMA_channel *ch)
99{
100 DBDMA_DPRINTF("kill_channel\n");
101
102 ch->regs[DBDMA_STATUS] |= DEAD;
103 ch->regs[DBDMA_STATUS] &= ~ACTIVE;
104
105 qemu_irq_raise(ch->irq);
106}
107
108static void conditional_interrupt(DBDMA_channel *ch)
109{
110 dbdma_cmd *current = &ch->current;
111 uint16_t intr;
112 uint16_t sel_mask, sel_value;
113 uint32_t status;
114 int cond;
115
116 DBDMA_DPRINTF("%s\n", __func__);
117
118 intr = le16_to_cpu(current->command) & INTR_MASK;
119
120 switch(intr) {
121 case INTR_NEVER:
122 return;
123 case INTR_ALWAYS:
124 qemu_irq_raise(ch->irq);
125 DBDMA_DPRINTF("%s: raise\n", __func__);
126 return;
127 }
128
129 status = ch->regs[DBDMA_STATUS] & DEVSTAT;
130
131 sel_mask = (ch->regs[DBDMA_INTR_SEL] >> 16) & 0x0f;
132 sel_value = ch->regs[DBDMA_INTR_SEL] & 0x0f;
133
134 cond = (status & sel_mask) == (sel_value & sel_mask);
135
136 switch(intr) {
137 case INTR_IFSET:
138 if (cond) {
139 qemu_irq_raise(ch->irq);
140 DBDMA_DPRINTF("%s: raise\n", __func__);
141 }
142 return;
143 case INTR_IFCLR:
144 if (!cond) {
145 qemu_irq_raise(ch->irq);
146 DBDMA_DPRINTF("%s: raise\n", __func__);
147 }
148 return;
149 }
150}
151
152static int conditional_wait(DBDMA_channel *ch)
153{
154 dbdma_cmd *current = &ch->current;
155 uint16_t wait;
156 uint16_t sel_mask, sel_value;
157 uint32_t status;
158 int cond;
159
160 DBDMA_DPRINTF("conditional_wait\n");
161
162 wait = le16_to_cpu(current->command) & WAIT_MASK;
163
164 switch(wait) {
165 case WAIT_NEVER:
166 return 0;
167 case WAIT_ALWAYS:
168 return 1;
169 }
170
171 status = ch->regs[DBDMA_STATUS] & DEVSTAT;
172
173 sel_mask = (ch->regs[DBDMA_WAIT_SEL] >> 16) & 0x0f;
174 sel_value = ch->regs[DBDMA_WAIT_SEL] & 0x0f;
175
176 cond = (status & sel_mask) == (sel_value & sel_mask);
177
178 switch(wait) {
179 case WAIT_IFSET:
180 if (cond)
181 return 1;
182 return 0;
183 case WAIT_IFCLR:
184 if (!cond)
185 return 1;
186 return 0;
187 }
188 return 0;
189}
190
191static void next(DBDMA_channel *ch)
192{
193 uint32_t cp;
194
195 ch->regs[DBDMA_STATUS] &= ~BT;
196
197 cp = ch->regs[DBDMA_CMDPTR_LO];
198 ch->regs[DBDMA_CMDPTR_LO] = cp + sizeof(dbdma_cmd);
199 dbdma_cmdptr_load(ch);
200}
201
202static void branch(DBDMA_channel *ch)
203{
204 dbdma_cmd *current = &ch->current;
205
206 ch->regs[DBDMA_CMDPTR_LO] = current->cmd_dep;
207 ch->regs[DBDMA_STATUS] |= BT;
208 dbdma_cmdptr_load(ch);
209}
210
211static void conditional_branch(DBDMA_channel *ch)
212{
213 dbdma_cmd *current = &ch->current;
214 uint16_t br;
215 uint16_t sel_mask, sel_value;
216 uint32_t status;
217 int cond;
218
219 DBDMA_DPRINTF("conditional_branch\n");
220
221
222
223 br = le16_to_cpu(current->command) & BR_MASK;
224
225 switch(br) {
226 case BR_NEVER:
227 next(ch);
228 return;
229 case BR_ALWAYS:
230 branch(ch);
231 return;
232 }
233
234 status = ch->regs[DBDMA_STATUS] & DEVSTAT;
235
236 sel_mask = (ch->regs[DBDMA_BRANCH_SEL] >> 16) & 0x0f;
237 sel_value = ch->regs[DBDMA_BRANCH_SEL] & 0x0f;
238
239 cond = (status & sel_mask) == (sel_value & sel_mask);
240
241 switch(br) {
242 case BR_IFSET:
243 if (cond)
244 branch(ch);
245 else
246 next(ch);
247 return;
248 case BR_IFCLR:
249 if (!cond)
250 branch(ch);
251 else
252 next(ch);
253 return;
254 }
255}
256
257static void channel_run(DBDMA_channel *ch);
258
259static void dbdma_end(DBDMA_io *io)
260{
261 DBDMA_channel *ch = io->channel;
262 dbdma_cmd *current = &ch->current;
263
264 DBDMA_DPRINTF("%s\n", __func__);
265
266 if (conditional_wait(ch))
267 goto wait;
268
269 current->xfer_status = cpu_to_le16(ch->regs[DBDMA_STATUS]);
270 current->res_count = cpu_to_le16(io->len);
271 dbdma_cmdptr_save(ch);
272 if (io->is_last)
273 ch->regs[DBDMA_STATUS] &= ~FLUSH;
274
275 conditional_interrupt(ch);
276 conditional_branch(ch);
277
278wait:
279
280 ch->io.processing = false;
281
282 if ((ch->regs[DBDMA_STATUS] & RUN) &&
283 (ch->regs[DBDMA_STATUS] & ACTIVE))
284 channel_run(ch);
285}
286
287static void start_output(DBDMA_channel *ch, int key, uint32_t addr,
288 uint16_t req_count, int is_last)
289{
290 DBDMA_DPRINTF("start_output\n");
291
292
293
294
295
296 DBDMA_DPRINTF("addr 0x%x key 0x%x\n", addr, key);
297 if (!addr || key > KEY_STREAM3) {
298 kill_channel(ch);
299 return;
300 }
301
302 ch->io.addr = addr;
303 ch->io.len = req_count;
304 ch->io.is_last = is_last;
305 ch->io.dma_end = dbdma_end;
306 ch->io.is_dma_out = 1;
307 ch->io.processing = true;
308 if (ch->rw) {
309 ch->rw(&ch->io);
310 }
311}
312
313static void start_input(DBDMA_channel *ch, int key, uint32_t addr,
314 uint16_t req_count, int is_last)
315{
316 DBDMA_DPRINTF("start_input\n");
317
318
319
320
321
322 DBDMA_DPRINTF("addr 0x%x key 0x%x\n", addr, key);
323 if (!addr || key > KEY_STREAM3) {
324 kill_channel(ch);
325 return;
326 }
327
328 ch->io.addr = addr;
329 ch->io.len = req_count;
330 ch->io.is_last = is_last;
331 ch->io.dma_end = dbdma_end;
332 ch->io.is_dma_out = 0;
333 ch->io.processing = true;
334 if (ch->rw) {
335 ch->rw(&ch->io);
336 }
337}
338
339static void load_word(DBDMA_channel *ch, int key, uint32_t addr,
340 uint16_t len)
341{
342 dbdma_cmd *current = &ch->current;
343 uint32_t val;
344
345 DBDMA_DPRINTF("load_word\n");
346
347
348
349 if (key != KEY_SYSTEM) {
350 printf("DBDMA: LOAD_WORD, unimplemented key %x\n", key);
351 kill_channel(ch);
352 return;
353 }
354
355 cpu_physical_memory_read(addr, &val, len);
356
357 if (len == 2)
358 val = (val << 16) | (current->cmd_dep & 0x0000ffff);
359 else if (len == 1)
360 val = (val << 24) | (current->cmd_dep & 0x00ffffff);
361
362 current->cmd_dep = val;
363
364 if (conditional_wait(ch))
365 goto wait;
366
367 current->xfer_status = cpu_to_le16(ch->regs[DBDMA_STATUS]);
368 dbdma_cmdptr_save(ch);
369 ch->regs[DBDMA_STATUS] &= ~FLUSH;
370
371 conditional_interrupt(ch);
372 next(ch);
373
374wait:
375 DBDMA_kick(dbdma_from_ch(ch));
376}
377
378static void store_word(DBDMA_channel *ch, int key, uint32_t addr,
379 uint16_t len)
380{
381 dbdma_cmd *current = &ch->current;
382 uint32_t val;
383
384 DBDMA_DPRINTF("store_word\n");
385
386
387
388 if (key != KEY_SYSTEM) {
389 printf("DBDMA: STORE_WORD, unimplemented key %x\n", key);
390 kill_channel(ch);
391 return;
392 }
393
394 val = current->cmd_dep;
395 if (len == 2)
396 val >>= 16;
397 else if (len == 1)
398 val >>= 24;
399
400 cpu_physical_memory_write(addr, &val, len);
401
402 if (conditional_wait(ch))
403 goto wait;
404
405 current->xfer_status = cpu_to_le16(ch->regs[DBDMA_STATUS]);
406 dbdma_cmdptr_save(ch);
407 ch->regs[DBDMA_STATUS] &= ~FLUSH;
408
409 conditional_interrupt(ch);
410 next(ch);
411
412wait:
413 DBDMA_kick(dbdma_from_ch(ch));
414}
415
416static void nop(DBDMA_channel *ch)
417{
418 dbdma_cmd *current = &ch->current;
419
420 if (conditional_wait(ch))
421 goto wait;
422
423 current->xfer_status = cpu_to_le16(ch->regs[DBDMA_STATUS]);
424 dbdma_cmdptr_save(ch);
425
426 conditional_interrupt(ch);
427 conditional_branch(ch);
428
429wait:
430 DBDMA_kick(dbdma_from_ch(ch));
431}
432
433static void stop(DBDMA_channel *ch)
434{
435 ch->regs[DBDMA_STATUS] &= ~(ACTIVE|DEAD|FLUSH);
436
437
438}
439
440static void channel_run(DBDMA_channel *ch)
441{
442 dbdma_cmd *current = &ch->current;
443 uint16_t cmd, key;
444 uint16_t req_count;
445 uint32_t phy_addr;
446
447 DBDMA_DPRINTF("channel_run\n");
448 dump_dbdma_cmd(current);
449
450
451
452 ch->regs[DBDMA_STATUS] &= ~WAKE;
453
454 cmd = le16_to_cpu(current->command) & COMMAND_MASK;
455
456 switch (cmd) {
457 case DBDMA_NOP:
458 nop(ch);
459 return;
460
461 case DBDMA_STOP:
462 stop(ch);
463 return;
464 }
465
466 key = le16_to_cpu(current->command) & 0x0700;
467 req_count = le16_to_cpu(current->req_count);
468 phy_addr = le32_to_cpu(current->phy_addr);
469
470 if (key == KEY_STREAM4) {
471 printf("command %x, invalid key 4\n", cmd);
472 kill_channel(ch);
473 return;
474 }
475
476 switch (cmd) {
477 case OUTPUT_MORE:
478 start_output(ch, key, phy_addr, req_count, 0);
479 return;
480
481 case OUTPUT_LAST:
482 start_output(ch, key, phy_addr, req_count, 1);
483 return;
484
485 case INPUT_MORE:
486 start_input(ch, key, phy_addr, req_count, 0);
487 return;
488
489 case INPUT_LAST:
490 start_input(ch, key, phy_addr, req_count, 1);
491 return;
492 }
493
494 if (key < KEY_REGS) {
495 printf("command %x, invalid key %x\n", cmd, key);
496 key = KEY_SYSTEM;
497 }
498
499
500
501
502
503 req_count = req_count & 0x0007;
504 if (req_count & 0x4) {
505 req_count = 4;
506 phy_addr &= ~3;
507 } else if (req_count & 0x2) {
508 req_count = 2;
509 phy_addr &= ~1;
510 } else
511 req_count = 1;
512
513 switch (cmd) {
514 case LOAD_WORD:
515 load_word(ch, key, phy_addr, req_count);
516 return;
517
518 case STORE_WORD:
519 store_word(ch, key, phy_addr, req_count);
520 return;
521 }
522}
523
524static void DBDMA_run(DBDMAState *s)
525{
526 int channel;
527
528 for (channel = 0; channel < DBDMA_CHANNELS; channel++) {
529 DBDMA_channel *ch = &s->channels[channel];
530 uint32_t status = ch->regs[DBDMA_STATUS];
531 if (!ch->io.processing && (status & RUN) && (status & ACTIVE)) {
532 channel_run(ch);
533 }
534 }
535}
536
537static void DBDMA_run_bh(void *opaque)
538{
539 DBDMAState *s = opaque;
540
541 DBDMA_DPRINTF("DBDMA_run_bh\n");
542
543 DBDMA_run(s);
544}
545
546void DBDMA_kick(DBDMAState *dbdma)
547{
548 qemu_bh_schedule(dbdma->bh);
549}
550
551void DBDMA_register_channel(void *dbdma, int nchan, qemu_irq irq,
552 DBDMA_rw rw, DBDMA_flush flush,
553 void *opaque)
554{
555 DBDMAState *s = dbdma;
556 DBDMA_channel *ch = &s->channels[nchan];
557
558 DBDMA_DPRINTF("DBDMA_register_channel 0x%x\n", nchan);
559
560 assert(rw);
561 assert(flush);
562
563 ch->irq = irq;
564 ch->rw = rw;
565 ch->flush = flush;
566 ch->io.opaque = opaque;
567}
568
569static void
570dbdma_control_write(DBDMA_channel *ch)
571{
572 uint16_t mask, value;
573 uint32_t status;
574
575 mask = (ch->regs[DBDMA_CONTROL] >> 16) & 0xffff;
576 value = ch->regs[DBDMA_CONTROL] & 0xffff;
577
578 value &= (RUN | PAUSE | FLUSH | WAKE | DEVSTAT);
579
580 status = ch->regs[DBDMA_STATUS];
581
582 status = (value & mask) | (status & ~mask);
583
584 if (status & WAKE)
585 status |= ACTIVE;
586 if (status & RUN) {
587 status |= ACTIVE;
588 status &= ~DEAD;
589 }
590 if (status & PAUSE)
591 status &= ~ACTIVE;
592 if ((ch->regs[DBDMA_STATUS] & RUN) && !(status & RUN)) {
593
594 status &= ~(ACTIVE|DEAD);
595 }
596
597 if ((status & FLUSH) && ch->flush) {
598 ch->flush(&ch->io);
599 status &= ~FLUSH;
600 }
601
602 DBDMA_DPRINTF(" status 0x%08x\n", status);
603
604 ch->regs[DBDMA_STATUS] = status;
605
606 if (status & ACTIVE) {
607 DBDMA_kick(dbdma_from_ch(ch));
608 }
609}
610
611static void dbdma_write(void *opaque, hwaddr addr,
612 uint64_t value, unsigned size)
613{
614 int channel = addr >> DBDMA_CHANNEL_SHIFT;
615 DBDMAState *s = opaque;
616 DBDMA_channel *ch = &s->channels[channel];
617 int reg = (addr - (channel << DBDMA_CHANNEL_SHIFT)) >> 2;
618
619 DBDMA_DPRINTF("writel 0x" TARGET_FMT_plx " <= 0x%08"PRIx64"\n",
620 addr, value);
621 DBDMA_DPRINTF("channel 0x%x reg 0x%x\n",
622 (uint32_t)addr >> DBDMA_CHANNEL_SHIFT, reg);
623
624
625
626 if (reg == DBDMA_CMDPTR_LO && (ch->regs[DBDMA_STATUS] & ACTIVE)) {
627 return;
628 }
629
630 ch->regs[reg] = value;
631
632 switch(reg) {
633 case DBDMA_CONTROL:
634 dbdma_control_write(ch);
635 break;
636 case DBDMA_CMDPTR_LO:
637
638 ch->regs[DBDMA_CMDPTR_LO] &= ~0xf;
639 dbdma_cmdptr_load(ch);
640 break;
641 case DBDMA_STATUS:
642 case DBDMA_INTR_SEL:
643 case DBDMA_BRANCH_SEL:
644 case DBDMA_WAIT_SEL:
645
646 break;
647 case DBDMA_XFER_MODE:
648 case DBDMA_CMDPTR_HI:
649 case DBDMA_DATA2PTR_HI:
650 case DBDMA_DATA2PTR_LO:
651 case DBDMA_ADDRESS_HI:
652 case DBDMA_BRANCH_ADDR_HI:
653 case DBDMA_RES1:
654 case DBDMA_RES2:
655 case DBDMA_RES3:
656 case DBDMA_RES4:
657
658 break;
659 }
660}
661
662static uint64_t dbdma_read(void *opaque, hwaddr addr,
663 unsigned size)
664{
665 uint32_t value;
666 int channel = addr >> DBDMA_CHANNEL_SHIFT;
667 DBDMAState *s = opaque;
668 DBDMA_channel *ch = &s->channels[channel];
669 int reg = (addr - (channel << DBDMA_CHANNEL_SHIFT)) >> 2;
670
671 value = ch->regs[reg];
672
673 DBDMA_DPRINTF("readl 0x" TARGET_FMT_plx " => 0x%08x\n", addr, value);
674 DBDMA_DPRINTF("channel 0x%x reg 0x%x\n",
675 (uint32_t)addr >> DBDMA_CHANNEL_SHIFT, reg);
676
677 switch(reg) {
678 case DBDMA_CONTROL:
679 value = 0;
680 break;
681 case DBDMA_STATUS:
682 case DBDMA_CMDPTR_LO:
683 case DBDMA_INTR_SEL:
684 case DBDMA_BRANCH_SEL:
685 case DBDMA_WAIT_SEL:
686
687 break;
688 case DBDMA_XFER_MODE:
689 case DBDMA_CMDPTR_HI:
690 case DBDMA_DATA2PTR_HI:
691 case DBDMA_DATA2PTR_LO:
692 case DBDMA_ADDRESS_HI:
693 case DBDMA_BRANCH_ADDR_HI:
694
695 value = 0;
696 break;
697 case DBDMA_RES1:
698 case DBDMA_RES2:
699 case DBDMA_RES3:
700 case DBDMA_RES4:
701
702 break;
703 }
704
705 return value;
706}
707
708static const MemoryRegionOps dbdma_ops = {
709 .read = dbdma_read,
710 .write = dbdma_write,
711 .endianness = DEVICE_LITTLE_ENDIAN,
712 .valid = {
713 .min_access_size = 4,
714 .max_access_size = 4,
715 },
716};
717
718static const VMStateDescription vmstate_dbdma_io = {
719 .name = "dbdma_io",
720 .version_id = 0,
721 .minimum_version_id = 0,
722 .fields = (VMStateField[]) {
723 VMSTATE_UINT64(addr, struct DBDMA_io),
724 VMSTATE_INT32(len, struct DBDMA_io),
725 VMSTATE_INT32(is_last, struct DBDMA_io),
726 VMSTATE_INT32(is_dma_out, struct DBDMA_io),
727 VMSTATE_BOOL(processing, struct DBDMA_io),
728 VMSTATE_END_OF_LIST()
729 }
730};
731
732static const VMStateDescription vmstate_dbdma_cmd = {
733 .name = "dbdma_cmd",
734 .version_id = 0,
735 .minimum_version_id = 0,
736 .fields = (VMStateField[]) {
737 VMSTATE_UINT16(req_count, dbdma_cmd),
738 VMSTATE_UINT16(command, dbdma_cmd),
739 VMSTATE_UINT32(phy_addr, dbdma_cmd),
740 VMSTATE_UINT32(cmd_dep, dbdma_cmd),
741 VMSTATE_UINT16(res_count, dbdma_cmd),
742 VMSTATE_UINT16(xfer_status, dbdma_cmd),
743 VMSTATE_END_OF_LIST()
744 }
745};
746
747static const VMStateDescription vmstate_dbdma_channel = {
748 .name = "dbdma_channel",
749 .version_id = 1,
750 .minimum_version_id = 1,
751 .fields = (VMStateField[]) {
752 VMSTATE_UINT32_ARRAY(regs, struct DBDMA_channel, DBDMA_REGS),
753 VMSTATE_STRUCT(io, struct DBDMA_channel, 0, vmstate_dbdma_io, DBDMA_io),
754 VMSTATE_STRUCT(current, struct DBDMA_channel, 0, vmstate_dbdma_cmd,
755 dbdma_cmd),
756 VMSTATE_END_OF_LIST()
757 }
758};
759
760static const VMStateDescription vmstate_dbdma = {
761 .name = "dbdma",
762 .version_id = 3,
763 .minimum_version_id = 3,
764 .fields = (VMStateField[]) {
765 VMSTATE_STRUCT_ARRAY(channels, DBDMAState, DBDMA_CHANNELS, 1,
766 vmstate_dbdma_channel, DBDMA_channel),
767 VMSTATE_END_OF_LIST()
768 }
769};
770
771static void dbdma_reset(void *opaque)
772{
773 DBDMAState *s = opaque;
774 int i;
775
776 for (i = 0; i < DBDMA_CHANNELS; i++)
777 memset(s->channels[i].regs, 0, DBDMA_SIZE);
778}
779
780static void dbdma_unassigned_rw(DBDMA_io *io)
781{
782 DBDMA_channel *ch = io->channel;
783 qemu_log_mask(LOG_GUEST_ERROR, "%s: use of unassigned channel %d\n",
784 __func__, ch->channel);
785}
786
787static void dbdma_unassigned_flush(DBDMA_io *io)
788{
789 DBDMA_channel *ch = io->channel;
790 qemu_log_mask(LOG_GUEST_ERROR, "%s: use of unassigned channel %d\n",
791 __func__, ch->channel);
792}
793
794void* DBDMA_init (MemoryRegion **dbdma_mem)
795{
796 DBDMAState *s;
797 int i;
798
799 s = g_malloc0(sizeof(DBDMAState));
800
801 for (i = 0; i < DBDMA_CHANNELS; i++) {
802 DBDMA_io *io = &s->channels[i].io;
803 DBDMA_channel *ch = &s->channels[i];
804 qemu_iovec_init(&io->iov, 1);
805
806 ch->rw = dbdma_unassigned_rw;
807 ch->flush = dbdma_unassigned_flush;
808 ch->channel = i;
809 ch->io.channel = ch;
810 }
811
812 memory_region_init_io(&s->mem, NULL, &dbdma_ops, s, "dbdma", 0x1000);
813 *dbdma_mem = &s->mem;
814 vmstate_register(NULL, -1, &vmstate_dbdma, s);
815 qemu_register_reset(dbdma_reset, s);
816
817 s->bh = qemu_bh_new(DBDMA_run_bh, s);
818
819 return s;
820}
821