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 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);
... ...