@@ -905,6 +905,7 @@ static void dcr_write_dma(void *opaque, int dcrn, uint32_t val)
uint8_t *rptr, *wptr;
hwaddr rlen, wlen;
hwaddr xferlen;
+ bool fastpathed = false;
sidx = didx = 0;
width = 1 << ((val & DMA0_CR_PW) >> 25);
@@ -915,6 +916,7 @@ static void dcr_write_dma(void *opaque, int dcrn, uint32_t val)
wptr = cpu_physical_memory_map(dma->ch[chnl].da, &wlen,
true);
if (rptr && rlen == xferlen && wptr && wlen == xferlen) {
+ fastpathed = true;
if (!(val & DMA0_CR_DEC) &&
val & DMA0_CR_SAI && val & DMA0_CR_DAI) {
/* optimise common case */
@@ -940,6 +942,33 @@ static void dcr_write_dma(void *opaque, int dcrn, uint32_t val)
if (rptr) {
cpu_physical_memory_unmap(rptr, rlen, 0, sidx);
}
+ if (!fastpathed) {
+ /* Fast-path failed, do each access one at a time */
+ for (sidx = didx = i = 0; i < count; i++) {
+ uint8_t buf[8];
+ assert(width <= sizeof(buf));
+ if (address_space_read(&address_space_memory,
+ dma->ch[chnl].sa + sidx,
+ MEMTXATTRS_UNSPECIFIED,
+ buf, width) != MEMTX_OK) {
+ /* FIXME: model correct behaviour on errors */
+ break;
+ }
+ if (address_space_write(&address_space_memory,
+ dma->ch[chnl].da + didx,
+ MEMTXATTRS_UNSPECIFIED,
+ buf, width) != MEMTX_OK) {
+ /* FIXME: model correct behaviour on errors */
+ break;
+ }
+ if (val & DMA0_CR_SAI) {
+ sidx += width;
+ }
+ if (val & DMA0_CR_DAI) {
+ didx += width;
+ }
+ }
+ }
}
}
break;
Currently the code for doing DMA in dcr_write_dma() has no fallback code for if its calls to cpu_physical_memory_map() fail. Add handling for this situation, by using address_space_read() and address_space_write() to do the data transfers. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- I believe this to be equivalent to the fastpath code. However, as the comments note, I don't know what the intended behaviour on a DMA memory access error is, because I couldn't find a datasheet for this hardware. I am also a bit suspicious that the current code does not seem to update any of the count, source or destination addresses after the memory transfer: is that really how the hardware behaves? --- hw/ppc/ppc440_uc.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+)