Commit 4487fd349baa6d2ae34ab86dea843642d20a036a
1 parent
b23761f9
ETRAX-FS: Add support for DMA channel resets, needed for recent linux kernels.
* Correct numeric value for the RST state. * Add emulation for reseting a DMA channel. * Add a few sanity checks. * Make it compile with debug enabled. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5147 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
21 additions
and
2 deletions
hw/etraxfs_dma.c
... | ... | @@ -156,7 +156,7 @@ enum { |
156 | 156 | |
157 | 157 | enum dma_ch_state |
158 | 158 | { |
159 | - RST = 0, | |
159 | + RST = 1, | |
160 | 160 | STOPPED = 2, |
161 | 161 | RUNNING = 4 |
162 | 162 | }; |
... | ... | @@ -398,7 +398,7 @@ static void channel_out_run(struct fs_dma_ctrl *ctrl, int c) |
398 | 398 | |
399 | 399 | saved_data_buf = channel_reg(ctrl, c, RW_SAVED_DATA_BUF); |
400 | 400 | |
401 | - D(fprintf(logfile, "ch=%d buf=%x after=%x saved_data_buf=%x\n", | |
401 | + D(printf("ch=%d buf=%x after=%x saved_data_buf=%x\n", | |
402 | 402 | c, |
403 | 403 | (uint32_t)ctrl->channels[c].current_d.buf, |
404 | 404 | (uint32_t)ctrl->channels[c].current_d.after, |
... | ... | @@ -583,6 +583,17 @@ dma_winvalid (void *opaque, target_phys_addr_t addr, uint32_t value) |
583 | 583 | } |
584 | 584 | |
585 | 585 | static void |
586 | +dma_update_state(struct fs_dma_ctrl *ctrl, int c) | |
587 | +{ | |
588 | + if ((ctrl->channels[c].regs[RW_CFG] & 1) != 3) { | |
589 | + if (ctrl->channels[c].regs[RW_CFG] & 2) | |
590 | + ctrl->channels[c].state = STOPPED; | |
591 | + if (!(ctrl->channels[c].regs[RW_CFG] & 1)) | |
592 | + ctrl->channels[c].state = RST; | |
593 | + } | |
594 | +} | |
595 | + | |
596 | +static void | |
586 | 597 | dma_writel (void *opaque, target_phys_addr_t addr, uint32_t value) |
587 | 598 | { |
588 | 599 | struct fs_dma_ctrl *ctrl = opaque; |
... | ... | @@ -599,9 +610,13 @@ dma_writel (void *opaque, target_phys_addr_t addr, uint32_t value) |
599 | 610 | |
600 | 611 | case RW_CFG: |
601 | 612 | ctrl->channels[c].regs[addr] = value; |
613 | + dma_update_state(ctrl, c); | |
602 | 614 | break; |
603 | 615 | case RW_CMD: |
604 | 616 | /* continue. */ |
617 | + if (value & ~1) | |
618 | + printf("Invalid store to ch=%d RW_CMD %x\n", | |
619 | + c, value); | |
605 | 620 | ctrl->channels[c].regs[addr] = value; |
606 | 621 | channel_continue(ctrl, c); |
607 | 622 | break; |
... | ... | @@ -622,6 +637,10 @@ dma_writel (void *opaque, target_phys_addr_t addr, uint32_t value) |
622 | 637 | break; |
623 | 638 | |
624 | 639 | case RW_STREAM_CMD: |
640 | + if (value & ~1023) | |
641 | + printf("Invalid store to ch=%d " | |
642 | + "RW_STREAMCMD %x\n", | |
643 | + c, value); | |
625 | 644 | ctrl->channels[c].regs[addr] = value; |
626 | 645 | D(printf("stream_cmd ch=%d\n", c)); |
627 | 646 | channel_stream_cmd(ctrl, c, value); | ... | ... |