From 8a020debbe58f0fe9411039a31fbfdebd6af5302 Mon Sep 17 00:00:00 2001 From: Luca Colagrande Date: Thu, 12 Oct 2023 09:04:20 +0200 Subject: [PATCH] snRuntime: Add check on DMA transfer size --- sw/snRuntime/src/dma.h | 204 +++++++++++++++++++++------------------ sw/snRuntime/src/start.c | 2 +- 2 files changed, 109 insertions(+), 97 deletions(-) diff --git a/sw/snRuntime/src/dma.h b/sw/snRuntime/src/dma.h index 7c94acdd9..169e54d7b 100644 --- a/sw/snRuntime/src/dma.h +++ b/sw/snRuntime/src/dma.h @@ -8,43 +8,49 @@ typedef uint32_t snrt_dma_txid_t; /// Initiate an asynchronous 1D DMA transfer with wide 64-bit pointers. inline snrt_dma_txid_t snrt_dma_start_1d_wideptr(uint64_t dst, uint64_t src, size_t size) { - register uint32_t reg_dst_low asm("a0") = dst >> 0; // 10 - register uint32_t reg_dst_high asm("a1") = dst >> 32; // 11 - register uint32_t reg_src_low asm("a2") = src >> 0; // 12 - register uint32_t reg_src_high asm("a3") = src >> 32; // 13 - register uint32_t reg_size asm("a4") = size; // 14 - - // dmsrc a2, a3 - asm volatile( - ".word (0b0000000 << 25) | \ - ( (13) << 20) | \ - ( (12) << 15) | \ - ( 0b000 << 12) | \ - (0b0101011 << 0) \n" ::"r"(reg_src_high), - "r"(reg_src_low)); - - // dmdst a0, a1 - asm volatile( - ".word (0b0000001 << 25) | \ - ( (11) << 20) | \ - ( (10) << 15) | \ - ( 0b000 << 12) | \ - (0b0101011 << 0) \n" ::"r"(reg_dst_high), - "r"(reg_dst_low)); - - // dmcpyi a0, a4, 0b00 - register uint32_t reg_txid asm("a0"); // 10 - asm volatile( - ".word (0b0000010 << 25) | \ - ( 0b00000 << 20) | \ - ( (14) << 15) | \ - ( 0b000 << 12) | \ - ( (10) << 7) | \ - (0b0101011 << 0) \n" - : "=r"(reg_txid) - : "r"(reg_size)); - - return reg_txid; + // Current DMA does not allow transfers with size == 0 (blocks) + // TODO(colluca) remove this check once new DMA is integrated + if (size > 0) { + register uint32_t reg_dst_low asm("a0") = dst >> 0; // 10 + register uint32_t reg_dst_high asm("a1") = dst >> 32; // 11 + register uint32_t reg_src_low asm("a2") = src >> 0; // 12 + register uint32_t reg_src_high asm("a3") = src >> 32; // 13 + register uint32_t reg_size asm("a4") = size; // 14 + + // dmsrc a2, a3 + asm volatile( + ".word (0b0000000 << 25) | \ + ( (13) << 20) | \ + ( (12) << 15) | \ + ( 0b000 << 12) | \ + (0b0101011 << 0) \n" ::"r"(reg_src_high), + "r"(reg_src_low)); + + // dmdst a0, a1 + asm volatile( + ".word (0b0000001 << 25) | \ + ( (11) << 20) | \ + ( (10) << 15) | \ + ( 0b000 << 12) | \ + (0b0101011 << 0) \n" ::"r"(reg_dst_high), + "r"(reg_dst_low)); + + // dmcpyi a0, a4, 0b00 + register uint32_t reg_txid asm("a0"); // 10 + asm volatile( + ".word (0b0000010 << 25) | \ + ( 0b00000 << 20) | \ + ( (14) << 15) | \ + ( 0b000 << 12) | \ + ( (10) << 7) | \ + (0b0101011 << 0) \n" + : "=r"(reg_txid) + : "r"(reg_size)); + + return reg_txid; + } else { + return -1; + } } /// Initiate an asynchronous 1D DMA transfer. @@ -58,65 +64,71 @@ inline snrt_dma_txid_t snrt_dma_start_2d_wideptr(uint64_t dst, uint64_t src, size_t size, size_t dst_stride, size_t src_stride, size_t repeat) { - register uint32_t reg_dst_low asm("a0") = dst >> 0; // 10 - register uint32_t reg_dst_high asm("a1") = dst >> 32; // 11 - register uint32_t reg_src_low asm("a2") = src >> 0; // 12 - register uint32_t reg_src_high asm("a3") = src >> 32; // 13 - register uint32_t reg_size asm("a4") = size; // 14 - register uint32_t reg_dst_stride asm("a5") = dst_stride; // 15 - register uint32_t reg_src_stride asm("a6") = src_stride; // 16 - register uint32_t reg_repeat asm("a7") = repeat; // 17 - - // dmsrc a0, a1 - asm volatile( - ".word (0b0000000 << 25) | \ - ( (13) << 20) | \ - ( (12) << 15) | \ - ( 0b000 << 12) | \ - (0b0101011 << 0) \n" ::"r"(reg_src_high), - "r"(reg_src_low)); - - // dmdst a0, a1 - asm volatile( - ".word (0b0000001 << 25) | \ - ( (11) << 20) | \ - ( (10) << 15) | \ - ( 0b000 << 12) | \ - (0b0101011 << 0) \n" ::"r"(reg_dst_high), - "r"(reg_dst_low)); - - // dmstr a5, a6 - asm volatile( - ".word (0b0000110 << 25) | \ - ( (15) << 20) | \ - ( (16) << 15) | \ - ( 0b000 << 12) | \ - (0b0101011 << 0) \n" - : - : "r"(reg_dst_stride), "r"(reg_src_stride)); - - // dmrep a7 - asm volatile( - ".word (0b0000111 << 25) | \ - ( (17) << 15) | \ - ( 0b000 << 12) | \ - (0b0101011 << 0) \n" - : - : "r"(reg_repeat)); - - // dmcpyi a0, a4, 0b10 - register uint32_t reg_txid asm("a0"); // 10 - asm volatile( - ".word (0b0000010 << 25) | \ - ( 0b00010 << 20) | \ - ( (14) << 15) | \ - ( 0b000 << 12) | \ - ( (10) << 7) | \ - (0b0101011 << 0) \n" - : "=r"(reg_txid) - : "r"(reg_size)); - - return reg_txid; + // Current DMA does not allow transfers with size == 0 (blocks) + // TODO(colluca) remove this check once new DMA is integrated + if (size > 0) { + register uint32_t reg_dst_low asm("a0") = dst >> 0; // 10 + register uint32_t reg_dst_high asm("a1") = dst >> 32; // 11 + register uint32_t reg_src_low asm("a2") = src >> 0; // 12 + register uint32_t reg_src_high asm("a3") = src >> 32; // 13 + register uint32_t reg_size asm("a4") = size; // 14 + register uint32_t reg_dst_stride asm("a5") = dst_stride; // 15 + register uint32_t reg_src_stride asm("a6") = src_stride; // 16 + register uint32_t reg_repeat asm("a7") = repeat; // 17 + + // dmsrc a0, a1 + asm volatile( + ".word (0b0000000 << 25) | \ + ( (13) << 20) | \ + ( (12) << 15) | \ + ( 0b000 << 12) | \ + (0b0101011 << 0) \n" ::"r"(reg_src_high), + "r"(reg_src_low)); + + // dmdst a0, a1 + asm volatile( + ".word (0b0000001 << 25) | \ + ( (11) << 20) | \ + ( (10) << 15) | \ + ( 0b000 << 12) | \ + (0b0101011 << 0) \n" ::"r"(reg_dst_high), + "r"(reg_dst_low)); + + // dmstr a5, a6 + asm volatile( + ".word (0b0000110 << 25) | \ + ( (15) << 20) | \ + ( (16) << 15) | \ + ( 0b000 << 12) | \ + (0b0101011 << 0) \n" + : + : "r"(reg_dst_stride), "r"(reg_src_stride)); + + // dmrep a7 + asm volatile( + ".word (0b0000111 << 25) | \ + ( (17) << 15) | \ + ( 0b000 << 12) | \ + (0b0101011 << 0) \n" + : + : "r"(reg_repeat)); + + // dmcpyi a0, a4, 0b10 + register uint32_t reg_txid asm("a0"); // 10 + asm volatile( + ".word (0b0000010 << 25) | \ + ( 0b00010 << 20) | \ + ( (14) << 15) | \ + ( 0b000 << 12) | \ + ( (10) << 7) | \ + (0b0101011 << 0) \n" + : "=r"(reg_txid) + : "r"(reg_size)); + + return reg_txid; + } else { + return -1; + } } /// Initiate an asynchronous 2D DMA transfer. diff --git a/sw/snRuntime/src/start.c b/sw/snRuntime/src/start.c index c2b91bad4..4e4cd2152 100644 --- a/sw/snRuntime/src/start.c +++ b/sw/snRuntime/src/start.c @@ -82,7 +82,7 @@ static inline void snrt_init_cls() { // Copy cdata section to base of the TCDM size = (size_t)(&__cdata_end) - (size_t)(&__cdata_start); - if (size > 0) snrt_dma_start_1d(ptr, (void*)(&__cdata_start), size); + snrt_dma_start_1d(ptr, (void*)(&__cdata_start), size); // Clear cbss section ptr = (void*)((uint32_t)ptr + size);