Skip to content

Commit 1265eb9

Browse files
Merge pull request #17 from thalesfragoso/fences
Add fences
2 parents 730275a + d52ab2e commit 1265eb9

File tree

4 files changed

+54
-18
lines changed

4 files changed

+54
-18
lines changed

Cargo.toml

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,15 @@ volatile-register = "0.2"
2222
aligned = "0.3"
2323
stm32f7xx-hal = {version = "0.2.0", optional = true}
2424
stm32f4xx-hal = {version = "0.8.3", optional = true}
25-
cortex-m = "0.6.0"
25+
cortex-m = "0.6.2"
2626

2727
smoltcp = { version = "0.6.0", default-features = false, features = ["proto-ipv4", "proto-ipv6", "socket-icmp", "socket-udp", "socket-tcp", "ethernet"], optional = true }
2828
log = { version = "0.4", optional = true }
2929

3030
[features]
3131
device-selected = []
32+
fence = []
33+
3234
stm32f407 = ["stm32f4xx-hal/stm32f407", "device-selected"]
3335
stm32f417 = ["stm32f4xx-hal/stm32f417", "device-selected"]
3436
stm32f427 = ["stm32f4xx-hal/stm32f427", "device-selected"]
@@ -38,15 +40,15 @@ stm32f439 = ["stm32f4xx-hal/stm32f439", "device-selected"]
3840
stm32f469 = ["stm32f4xx-hal/stm32f469", "device-selected"]
3941
stm32f479 = ["stm32f4xx-hal/stm32f479", "device-selected"]
4042

41-
stm32f745 = ["stm32f7xx-hal/stm32f745", "device-selected"]
42-
stm32f746 = ["stm32f7xx-hal/stm32f746", "device-selected"]
43-
stm32f756 = ["stm32f7xx-hal/stm32f756", "device-selected"]
44-
stm32f765 = ["stm32f7xx-hal/stm32f765", "device-selected"]
45-
stm32f767 = ["stm32f7xx-hal/stm32f767", "device-selected"]
46-
stm32f769 = ["stm32f7xx-hal/stm32f769", "device-selected"]
47-
stm32f777 = ["stm32f7xx-hal/stm32f777", "device-selected"]
48-
stm32f778 = ["stm32f7xx-hal/stm32f778", "device-selected"]
49-
stm32f779 = ["stm32f7xx-hal/stm32f779", "device-selected"]
43+
stm32f745 = ["stm32f7xx-hal/stm32f745", "device-selected", "fence"]
44+
stm32f746 = ["stm32f7xx-hal/stm32f746", "device-selected", "fence"]
45+
stm32f756 = ["stm32f7xx-hal/stm32f756", "device-selected", "fence"]
46+
stm32f765 = ["stm32f7xx-hal/stm32f765", "device-selected", "fence"]
47+
stm32f767 = ["stm32f7xx-hal/stm32f767", "device-selected", "fence"]
48+
stm32f769 = ["stm32f7xx-hal/stm32f769", "device-selected", "fence"]
49+
stm32f777 = ["stm32f7xx-hal/stm32f777", "device-selected", "fence"]
50+
stm32f778 = ["stm32f7xx-hal/stm32f778", "device-selected", "fence"]
51+
stm32f779 = ["stm32f7xx-hal/stm32f779", "device-selected", "fence"]
5052

5153
smoltcp-phy = ["smoltcp"]
5254
smoltcp-log = ["log", "smoltcp/log"]

src/lib.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ pub use stm32f4xx_hal::stm32;
1717
use hal::rcc::Clocks;
1818
use stm32::{Interrupt, ETHERNET_DMA, ETHERNET_MAC, NVIC};
1919

20-
use cortex_m::asm;
21-
2220
pub mod phy;
2321
use phy::{Phy, PhyStatus};
2422
mod ring;
@@ -88,7 +86,7 @@ impl<'rx, 'tx> Eth<'rx, 'tx> {
8886
///
8987
/// Make sure that the buffers reside in a memory region that is
9088
/// accessible by the peripheral. Core-Coupled Memory (CCM) is
91-
/// usually not accessible. HCLK must be between 25MHz and 168MHz for STM32F4xx
89+
/// usually not accessible. HCLK must be between 25MHz and 168MHz for STM32F4xx
9290
/// or 25MHz to 216MHz for STM32F7xx.
9391
///
9492
/// Uses an interrupt free critical section to turn on the ethernet clock for STM32F7xx.
@@ -314,8 +312,6 @@ impl<'rx, 'tx> Eth<'rx, 'tx> {
314312
f: F,
315313
) -> Result<R, TxError> {
316314
let result = self.tx_ring.send(length, f);
317-
//Make sure the memory write occurs before triggering DMA
318-
asm::dmb();
319315
self.tx_ring.demand_poll(&self.eth_dma);
320316
result
321317
}

src/rx.rs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@ use stm32f7xx_hal::device as stm32;
55

66
use stm32::ETHERNET_DMA;
77

8-
use core::default::Default;
9-
use core::ops::{Deref, DerefMut};
8+
use core::{
9+
default::Default,
10+
ops::{Deref, DerefMut},
11+
sync::atomic::{self, Ordering},
12+
};
1013

1114
use crate::{
1215
desc::Descriptor,
@@ -63,9 +66,19 @@ impl RxDescriptor {
6366

6467
/// Pass ownership to the DMA engine
6568
fn set_owned(&mut self) {
69+
// "Preceding reads and writes cannot be moved past subsequent writes."
70+
#[cfg(feature = "fence")]
71+
atomic::fence(Ordering::Release);
72+
73+
atomic::compiler_fence(Ordering::Release);
6674
unsafe {
6775
self.desc.modify(0, |w| w | RXDESC_0_OWN);
6876
}
77+
78+
// Used to flush the store buffer as fast as possible to make the buffer available for the
79+
// DMA.
80+
#[cfg(feature = "fence")]
81+
atomic::fence(Ordering::SeqCst);
6982
}
7083

7184
fn has_error(&self) -> bool {
@@ -136,6 +149,9 @@ impl RxRingEntry {
136149
} else if self.desc().is_first() && self.desc().is_last() {
137150
let frame_len = self.desc().get_frame_len();
138151

152+
// "Subsequent reads and writes cannot be moved ahead of preceding reads."
153+
atomic::compiler_fence(Ordering::Acquire);
154+
139155
// TODO: obtain ethernet frame type (RDESC_1_FT)
140156
let pkt = RxPacket {
141157
entry: self,
@@ -216,6 +232,8 @@ impl<'a> RxRing<'a> {
216232
// Register RxDescriptor
217233
eth_dma.dmardlar.write(|w| w.srl().bits(ring_ptr as u32));
218234

235+
// We already have fences in `set_owned`, which is called in `setup`
236+
219237
// Start receive
220238
eth_dma.dmaomr.modify(|_, w| w.sr().set_bit());
221239

src/tx.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ use stm32f7xx_hal::device as stm32;
55

66
use stm32::ETHERNET_DMA;
77

8-
use core::ops::{Deref, DerefMut};
8+
use core::{
9+
ops::{Deref, DerefMut},
10+
sync::atomic::{self, Ordering},
11+
};
912

1013
use crate::{
1114
desc::Descriptor,
@@ -60,9 +63,19 @@ impl TxDescriptor {
6063

6164
/// Pass ownership to the DMA engine
6265
fn set_owned(&mut self) {
66+
// "Preceding reads and writes cannot be moved past subsequent writes."
67+
#[cfg(feature = "fence")]
68+
atomic::fence(Ordering::Release);
69+
70+
atomic::compiler_fence(Ordering::Release);
6371
unsafe {
6472
self.desc.modify(0, |w| w | TXDESC_0_OWN);
6573
}
74+
75+
// Used to flush the store buffer as fast as possible to make the buffer available for the
76+
// DMA.
77+
#[cfg(feature = "fence")]
78+
atomic::fence(Ordering::SeqCst);
6679
}
6780

6881
#[allow(unused)]
@@ -193,6 +206,13 @@ impl<'a> TxRing<'a> {
193206
// Register TxDescriptor
194207
eth_dma.dmatdlar.write(|w| w.stl().bits(ring_ptr as u32));
195208

209+
// "Preceding reads and writes cannot be moved past subsequent writes."
210+
#[cfg(feature = "fence")]
211+
atomic::fence(Ordering::Release);
212+
213+
// We don't need a compiler fence here because all interactions with `Descriptor` are
214+
// volatiles
215+
196216
// Start transmission
197217
eth_dma.dmaomr.modify(|_, w| w.st().set_bit());
198218
}

0 commit comments

Comments
 (0)