?? pxa2xx_dma.c
字號(hào):
case DINT: return s->stopintr | s->eorintr | s->rasintr | s->startintr | s->endintr; case DALGN: return s->align; case DPCSR: return s->pio; } if (offset >= D_CH0 && offset < D_CH0 + (s->channels << 4)) { channel = (offset - D_CH0) >> 4; switch ((offset & 0x0f) >> 2) { case DDADR: return s->chan[channel].descr; case DSADR: return s->chan[channel].src; case DTADR: return s->chan[channel].dest; case DCMD: return s->chan[channel].cmd; } } cpu_abort(cpu_single_env, "%s: Bad offset 0x" TARGET_FMT_plx "\n", __FUNCTION__, offset); return 7;}static void pxa2xx_dma_write(void *opaque, target_phys_addr_t offset, uint32_t value){ struct pxa2xx_dma_state_s *s = (struct pxa2xx_dma_state_s *) opaque; unsigned int channel; offset -= s->base; switch (offset) { case DRCMR64 ... DRCMR74: offset -= DRCMR64 - DRCMR0 - (64 << 2); /* Fall through */ case DRCMR0 ... DRCMR63: channel = (offset - DRCMR0) >> 2; if (value & DRCMR_MAPVLD) if ((value & DRCMR_CHLNUM) > s->channels) cpu_abort(cpu_single_env, "%s: Bad DMA channel %i\n", __FUNCTION__, value & DRCMR_CHLNUM); s->req[channel] = value; break; case DRQSR0: case DRQSR1: case DRQSR2: /* Nothing to do */ break; case DCSR0 ... DCSR31: channel = offset >> 2; s->chan[channel].state &= 0x0000071f & ~(value & (DCSR_EORINT | DCSR_ENDINTR | DCSR_STARTINTR | DCSR_BUSERRINTR)); s->chan[channel].state |= value & 0xfc800000; if (s->chan[channel].state & DCSR_STOPIRQEN) s->chan[channel].state &= ~DCSR_STOPINTR; if (value & DCSR_NODESCFETCH) { /* No-descriptor-fetch mode */ if (value & DCSR_RUN) { s->chan[channel].state &= ~DCSR_STOPINTR; pxa2xx_dma_run(s); } } else { /* Descriptor-fetch mode */ if (value & DCSR_RUN) { s->chan[channel].state &= ~DCSR_STOPINTR; pxa2xx_dma_descriptor_fetch(s, channel); pxa2xx_dma_run(s); } } /* Shouldn't matter as our DMA is synchronous. */ if (!(value & (DCSR_RUN | DCSR_MASKRUN))) s->chan[channel].state |= DCSR_STOPINTR; if (value & DCSR_CLRCMPST) s->chan[channel].state &= ~DCSR_CMPST; if (value & DCSR_SETCMPST) s->chan[channel].state |= DCSR_CMPST; pxa2xx_dma_update(s, channel); break; case DALGN: s->align = value; break; case DPCSR: s->pio = value & 0x80000001; break; default: if (offset >= D_CH0 && offset < D_CH0 + (s->channels << 4)) { channel = (offset - D_CH0) >> 4; switch ((offset & 0x0f) >> 2) { case DDADR: s->chan[channel].descr = value; break; case DSADR: s->chan[channel].src = value; break; case DTADR: s->chan[channel].dest = value; break; case DCMD: s->chan[channel].cmd = value; break; default: goto fail; } break; } fail: cpu_abort(cpu_single_env, "%s: Bad offset " TARGET_FMT_plx "\n", __FUNCTION__, offset); }}static uint32_t pxa2xx_dma_readbad(void *opaque, target_phys_addr_t offset){ cpu_abort(cpu_single_env, "%s: Bad access width\n", __FUNCTION__); return 5;}static void pxa2xx_dma_writebad(void *opaque, target_phys_addr_t offset, uint32_t value){ cpu_abort(cpu_single_env, "%s: Bad access width\n", __FUNCTION__);}static CPUReadMemoryFunc *pxa2xx_dma_readfn[] = { pxa2xx_dma_readbad, pxa2xx_dma_readbad, pxa2xx_dma_read};static CPUWriteMemoryFunc *pxa2xx_dma_writefn[] = { pxa2xx_dma_writebad, pxa2xx_dma_writebad, pxa2xx_dma_write};static void pxa2xx_dma_save(QEMUFile *f, void *opaque){ struct pxa2xx_dma_state_s *s = (struct pxa2xx_dma_state_s *) opaque; int i; qemu_put_be32(f, s->channels); qemu_put_be32s(f, &s->stopintr); qemu_put_be32s(f, &s->eorintr); qemu_put_be32s(f, &s->rasintr); qemu_put_be32s(f, &s->startintr); qemu_put_be32s(f, &s->endintr); qemu_put_be32s(f, &s->align); qemu_put_be32s(f, &s->pio); qemu_put_buffer(f, s->req, PXA2XX_DMA_NUM_REQUESTS); for (i = 0; i < s->channels; i ++) { qemu_put_betl(f, s->chan[i].descr); qemu_put_betl(f, s->chan[i].src); qemu_put_betl(f, s->chan[i].dest); qemu_put_be32s(f, &s->chan[i].cmd); qemu_put_be32s(f, &s->chan[i].state); qemu_put_be32(f, s->chan[i].request); };}static int pxa2xx_dma_load(QEMUFile *f, void *opaque, int version_id){ struct pxa2xx_dma_state_s *s = (struct pxa2xx_dma_state_s *) opaque; int i; if (qemu_get_be32(f) != s->channels) return -EINVAL; qemu_get_be32s(f, &s->stopintr); qemu_get_be32s(f, &s->eorintr); qemu_get_be32s(f, &s->rasintr); qemu_get_be32s(f, &s->startintr); qemu_get_be32s(f, &s->endintr); qemu_get_be32s(f, &s->align); qemu_get_be32s(f, &s->pio); qemu_get_buffer(f, s->req, PXA2XX_DMA_NUM_REQUESTS); for (i = 0; i < s->channels; i ++) { s->chan[i].descr = qemu_get_betl(f); s->chan[i].src = qemu_get_betl(f); s->chan[i].dest = qemu_get_betl(f); qemu_get_be32s(f, &s->chan[i].cmd); qemu_get_be32s(f, &s->chan[i].state); s->chan[i].request = qemu_get_be32(f); }; return 0;}static struct pxa2xx_dma_state_s *pxa2xx_dma_init(target_phys_addr_t base, qemu_irq irq, int channels){ int i, iomemtype; struct pxa2xx_dma_state_s *s; s = (struct pxa2xx_dma_state_s *) qemu_mallocz(sizeof(struct pxa2xx_dma_state_s)); s->channels = channels; s->chan = qemu_mallocz(sizeof(struct pxa2xx_dma_channel_s) * s->channels); s->base = base; s->irq = irq; s->handler = (pxa2xx_dma_handler_t) pxa2xx_dma_request; s->req = qemu_mallocz(sizeof(uint8_t) * PXA2XX_DMA_NUM_REQUESTS); memset(s->chan, 0, sizeof(struct pxa2xx_dma_channel_s) * s->channels); for (i = 0; i < s->channels; i ++) s->chan[i].state = DCSR_STOPINTR; memset(s->req, 0, sizeof(uint8_t) * PXA2XX_DMA_NUM_REQUESTS); iomemtype = cpu_register_io_memory(0, pxa2xx_dma_readfn, pxa2xx_dma_writefn, s); cpu_register_physical_memory(base, 0x00010000, iomemtype); register_savevm("pxa2xx_dma", 0, 0, pxa2xx_dma_save, pxa2xx_dma_load, s); return s;}struct pxa2xx_dma_state_s *pxa27x_dma_init(target_phys_addr_t base, qemu_irq irq){ return pxa2xx_dma_init(base, irq, PXA27X_DMA_NUM_CHANNELS);}struct pxa2xx_dma_state_s *pxa255_dma_init(target_phys_addr_t base, qemu_irq irq){ return pxa2xx_dma_init(base, irq, PXA255_DMA_NUM_CHANNELS);}void pxa2xx_dma_request(struct pxa2xx_dma_state_s *s, int req_num, int on){ int ch; if (req_num < 0 || req_num >= PXA2XX_DMA_NUM_REQUESTS) cpu_abort(cpu_single_env, "%s: Bad DMA request %i\n", __FUNCTION__, req_num); if (!(s->req[req_num] & DRCMR_MAPVLD)) return; ch = s->req[req_num] & DRCMR_CHLNUM; if (!s->chan[ch].request && on) s->chan[ch].state |= DCSR_RASINTR; else s->chan[ch].state &= ~DCSR_RASINTR; if (s->chan[ch].request && !on) s->chan[ch].state |= DCSR_EORINT; s->chan[ch].request = on; if (on) { pxa2xx_dma_run(s); pxa2xx_dma_update(s, ch); }}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -