static uint32_t dma_readl (void *opaque, target_phys_addr_t addr) { struct fs_dma_ctrl *ctrl = opaque; int c; uint32_t r = 0; /* Make addr relative to this instances base. */ c = fs_channel(ctrl->base, addr); addr &= 0x1fff; switch (addr) { case RW_STAT: r = ctrl->channels[c].state & 7; r |= ctrl->channels[c].eol << 5; r |= ctrl->channels[c].stream_cmd_src << 8; break; default: r = ctrl->channels[c].regs[addr]; D(printf ("%s c=%d addr=%x pc=%x\n", __func__, c, addr, env->pc)); break; } return r; }
static void dma_writel (void *opaque, target_phys_addr_t addr, uint32_t value) { struct fs_dma_ctrl *ctrl = opaque; int c; /* Make addr relative to this channel and bounded to nr regs. */ c = fs_channel(addr); addr &= 0xff; addr >>= 2; switch (addr) { case RW_DATA: ctrl->channels[c].regs[addr] = value; break; case RW_CFG: ctrl->channels[c].regs[addr] = value; dma_update_state(ctrl, c); break; case RW_CMD: /* continue. */ if (value & ~1) printf("Invalid store to ch=%d RW_CMD %x\n", c, value); ctrl->channels[c].regs[addr] = value; channel_continue(ctrl, c); break; case RW_SAVED_DATA: case RW_SAVED_DATA_BUF: case RW_GROUP: case RW_GROUP_DOWN: ctrl->channels[c].regs[addr] = value; break; case RW_ACK_INTR: case RW_INTR_MASK: ctrl->channels[c].regs[addr] = value; channel_update_irq(ctrl, c); if (addr == RW_ACK_INTR) ctrl->channels[c].regs[RW_ACK_INTR] = 0; break; case RW_STREAM_CMD: if (value & ~1023) printf("Invalid store to ch=%d " "RW_STREAMCMD %x\n", c, value); ctrl->channels[c].regs[addr] = value; D(printf("stream_cmd ch=%d\n", c)); channel_stream_cmd(ctrl, c, value); break; default: D(printf ("%s c=%d " TARGET_FMT_plx "\n", __func__, c, addr)); break; } }
static uint64_t dma_read(void *opaque, hwaddr addr, unsigned int size) { struct fs_dma_ctrl *ctrl = opaque; int c; uint32_t r = 0; if (size != 4) { dma_rinvalid(opaque, addr); } /* Make addr relative to this channel and bounded to nr regs. */ c = fs_channel(addr); addr &= 0xff; addr >>= 2; switch (addr) { case RW_STAT: r = ctrl->channels[c].state & 7; r |= ctrl->channels[c].eol << 5; r |= ctrl->channels[c].stream_cmd_src << 8; break; default: r = ctrl->channels[c].regs[addr]; D(printf ("%s c=%d addr=" TARGET_FMT_plx "\n", __func__, c, addr)); break; } return r; }
static uint32_t dma_readl (void *opaque, target_phys_addr_t addr) { struct fs_dma_ctrl *ctrl = opaque; int c; uint32_t r = 0; /* Make addr relative to this channel and bounded to nr regs. */ c = fs_channel(addr); addr &= 0xff; addr >>= 2; switch (addr) { case RW_STAT: r = ctrl->channels[c].state & 7; r |= ctrl->channels[c].eol << 5; r |= ctrl->channels[c].stream_cmd_src << 8; break; default: r = ctrl->channels[c].regs[addr]; D(printf ("%s c=%d addr=" TARGET_FMT_plx "\n", __func__, c, addr)); break; } return r; }
static void dma_writel (void *opaque, target_phys_addr_t addr, uint32_t value) { struct fs_dma_ctrl *ctrl = opaque; int c; /* Make addr relative to this instances base. */ c = fs_channel(ctrl->base, addr); addr &= 0x1fff; switch (addr) { case RW_DATA: printf("RW_DATA=%x\n", value); break; case RW_CFG: ctrl->channels[c].regs[addr] = value; break; case RW_CMD: /* continue. */ ctrl->channels[c].regs[addr] = value; channel_continue(ctrl, c); break; case RW_SAVED_DATA: case RW_SAVED_DATA_BUF: case RW_GROUP: case RW_GROUP_DOWN: ctrl->channels[c].regs[addr] = value; break; case RW_ACK_INTR: case RW_INTR_MASK: ctrl->channels[c].regs[addr] = value; channel_update_irq(ctrl, c); if (addr == RW_ACK_INTR) ctrl->channels[c].regs[RW_ACK_INTR] = 0; break; case RW_STREAM_CMD: ctrl->channels[c].regs[addr] = value; channel_stream_cmd(ctrl, c, value); break; default: D(printf ("%s c=%d %x %x pc=%x\n", __func__, c, addr, value, env->pc)); break; } }