From 7e8b10eb4aba95d2791431c7b718b7c7f342a4b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20B=C3=B6ck?= Date: Fri, 28 Jun 2024 09:41:06 +0100 Subject: [PATCH] sw: Fix `snrt_dma_wait` implementation The previous implementation of `snrt_dma_wait` was incorrect as it had an infinite loop in the case that `tid` was the last completed transaction. Looking at the documentation, the snippet in custom_instructions.md shows the correct way of implementing the transaction check (get last completed tid and loop if it's less than the one we are waiting for) except it had its register operands swapped. This PR uses that implementation instead, fixes the small bug in the documentation and changes one of the waits in `dma_simple.c` to make sure we don't regress either. --- docs/rm/custom_instructions.md | 2 +- sw/snRuntime/src/dma.h | 3 +-- sw/tests/dma_simple.c | 4 ++-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/docs/rm/custom_instructions.md b/docs/rm/custom_instructions.md index f7fcfbd0d..0e834b33a 100644 --- a/docs/rm/custom_instructions.md +++ b/docs/rm/custom_instructions.md @@ -104,7 +104,7 @@ The DMSTATI instruction can be used to implement a blocking wait for the complet dmcpyi a0, ... 1: dmstati t0, 0 - bltu a0, t0, 1b + bltu t0, a0, 1b Similarly, waiting for the completion of *all* DMA transfers: diff --git a/sw/snRuntime/src/dma.h b/sw/snRuntime/src/dma.h index 21d2adedc..29d5d226c 100644 --- a/sw/snRuntime/src/dma.h +++ b/sw/snRuntime/src/dma.h @@ -151,8 +151,7 @@ inline void snrt_dma_wait(snrt_dma_txid_t tid) { ( 0b000 << 12) | \ ( (5) << 7) | \ (0b0101011 << 0) \n" - "sub t0, t0, %0 \n" - "blez t0, 1b \n" ::"r"(tid) + "bltu t0, %0, 1b \n" ::"r"(tid) : "t0"); } diff --git a/sw/tests/dma_simple.c b/sw/tests/dma_simple.c index 5260236e7..a9388f978 100644 --- a/sw/tests/dma_simple.c +++ b/sw/tests/dma_simple.c @@ -21,8 +21,8 @@ int main() { } // Copy data to main memory. - snrt_dma_start_1d(buffer, buffer_src, sizeof(buffer)); - snrt_dma_wait_all(); + snrt_dma_txid_t id = snrt_dma_start_1d(buffer, buffer_src, sizeof(buffer)); + snrt_dma_wait(id); // Check that the main memory buffer contains the correct data. for (uint32_t i = 0; i < 32; i++) {