From c7ae2d2a3a55ca32c43aea177371fea744a154e0 Mon Sep 17 00:00:00 2001 From: Thales Fragoso Date: Tue, 10 Aug 2021 20:40:02 -0300 Subject: [PATCH] stm32: Add fences to DMA code --- embassy-stm32/src/dma/bdma.rs | 7 +++++++ embassy-stm32/src/dma/dma.rs | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/embassy-stm32/src/dma/bdma.rs b/embassy-stm32/src/dma/bdma.rs index d262caeb6..fbd753a71 100644 --- a/embassy-stm32/src/dma/bdma.rs +++ b/embassy-stm32/src/dma/bdma.rs @@ -1,6 +1,7 @@ #![macro_use] use core::future::Future; +use core::sync::atomic::{fence, Ordering}; use core::task::Poll; use embassy::interrupt::{Interrupt, InterruptExt}; @@ -61,6 +62,9 @@ pub(crate) unsafe fn do_transfer( // Wait for the transfer to complete when it was ongoing. while ch.cr().read().en() {} + + // "Subsequent reads and writes cannot be moved ahead of preceding reads." + fence(Ordering::Acquire); }); #[cfg(dmamux)] @@ -72,6 +76,9 @@ pub(crate) unsafe fn do_transfer( .modify(|w| w.set_cs(channel_number as _, request)) }); + // "Preceding reads and writes cannot be moved past subsequent writes." + fence(Ordering::Release); + ch.par().write_value(peri_addr as u32); ch.mar().write_value(mem_addr as u32); ch.ndtr().write(|w| w.set_ndt(mem_len as u16)); diff --git a/embassy-stm32/src/dma/dma.rs b/embassy-stm32/src/dma/dma.rs index 9bf083de4..bce9656d1 100644 --- a/embassy-stm32/src/dma/dma.rs +++ b/embassy-stm32/src/dma/dma.rs @@ -1,4 +1,5 @@ use core::future::Future; +use core::sync::atomic::{fence, Ordering}; use core::task::Poll; use embassy::interrupt::{Interrupt, InterruptExt}; @@ -64,11 +65,17 @@ pub(crate) unsafe fn do_transfer( // Wait for the transfer to complete when it was ongoing. while ch.cr().read().en() {} + + // "Subsequent reads and writes cannot be moved ahead of preceding reads." + fence(Ordering::Acquire); }); #[cfg(dmamux)] super::dmamux::configure_dmamux(dmamux_regs, dmamux_ch_num, request); + // "Preceding reads and writes cannot be moved past subsequent writes." + fence(Ordering::Release); + unsafe { ch.par().write_value(peri_addr as u32); ch.m0ar().write_value(mem_addr as u32);