@@ -74,7 +74,7 @@ static void sifive_pdma_run(SiFivePDMAState *s, int ch)
uint64_t dst = s->chan[ch].next_dst;
uint64_t src = s->chan[ch].next_src;
uint32_t config = s->chan[ch].next_config;
- int wsize, rsize, size;
+ int wsize, rsize, size, remainder;
uint8_t buf[64];
int n;
@@ -106,11 +106,7 @@ static void sifive_pdma_run(SiFivePDMAState *s, int ch)
size = 6;
}
size = 1 << size;
-
- /* the bytes to transfer should be multiple of transaction size */
- if (bytes % size) {
- goto error;
- }
+ remainder = bytes % size;
/* indicate a DMA transfer is started */
s->chan[ch].state = DMA_CHAN_STATE_STARTED;
@@ -131,6 +127,14 @@ static void sifive_pdma_run(SiFivePDMAState *s, int ch)
s->chan[ch].exec_bytes -= size;
}
+ if (remainder) {
+ cpu_physical_memory_read(s->chan[ch].exec_src, buf, remainder);
+ cpu_physical_memory_write(s->chan[ch].exec_dst, buf, remainder);
+ s->chan[ch].exec_src += remainder;
+ s->chan[ch].exec_dst += remainder;
+ s->chan[ch].exec_bytes -= remainder;
+ }
+
/* indicate a DMA transfer is done */
s->chan[ch].state = DMA_CHAN_STATE_DONE;
s->chan[ch].control &= ~CONTROL_RUN;