Commit 4487fd349baa6d2ae34ab86dea843642d20a036a

Authored by edgar_igl
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,7 +156,7 @@ enum {
156 156
157 enum dma_ch_state 157 enum dma_ch_state
158 { 158 {
159 - RST = 0, 159 + RST = 1,
160 STOPPED = 2, 160 STOPPED = 2,
161 RUNNING = 4 161 RUNNING = 4
162 }; 162 };
@@ -398,7 +398,7 @@ static void channel_out_run(struct fs_dma_ctrl *ctrl, int c) @@ -398,7 +398,7 @@ static void channel_out_run(struct fs_dma_ctrl *ctrl, int c)
398 398
399 saved_data_buf = channel_reg(ctrl, c, RW_SAVED_DATA_BUF); 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 c, 402 c,
403 (uint32_t)ctrl->channels[c].current_d.buf, 403 (uint32_t)ctrl->channels[c].current_d.buf,
404 (uint32_t)ctrl->channels[c].current_d.after, 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,6 +583,17 @@ dma_winvalid (void *opaque, target_phys_addr_t addr, uint32_t value)
583 } 583 }
584 584
585 static void 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 dma_writel (void *opaque, target_phys_addr_t addr, uint32_t value) 597 dma_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
587 { 598 {
588 struct fs_dma_ctrl *ctrl = opaque; 599 struct fs_dma_ctrl *ctrl = opaque;
@@ -599,9 +610,13 @@ dma_writel (void *opaque, target_phys_addr_t addr, uint32_t value) @@ -599,9 +610,13 @@ dma_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
599 610
600 case RW_CFG: 611 case RW_CFG:
601 ctrl->channels[c].regs[addr] = value; 612 ctrl->channels[c].regs[addr] = value;
  613 + dma_update_state(ctrl, c);
602 break; 614 break;
603 case RW_CMD: 615 case RW_CMD:
604 /* continue. */ 616 /* continue. */
  617 + if (value & ~1)
  618 + printf("Invalid store to ch=%d RW_CMD %x\n",
  619 + c, value);
605 ctrl->channels[c].regs[addr] = value; 620 ctrl->channels[c].regs[addr] = value;
606 channel_continue(ctrl, c); 621 channel_continue(ctrl, c);
607 break; 622 break;
@@ -622,6 +637,10 @@ dma_writel (void *opaque, target_phys_addr_t addr, uint32_t value) @@ -622,6 +637,10 @@ dma_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
622 break; 637 break;
623 638
624 case RW_STREAM_CMD: 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 ctrl->channels[c].regs[addr] = value; 644 ctrl->channels[c].regs[addr] = value;
626 D(printf("stream_cmd ch=%d\n", c)); 645 D(printf("stream_cmd ch=%d\n", c));
627 channel_stream_cmd(ctrl, c, value); 646 channel_stream_cmd(ctrl, c, value);