Skip to content

Commit d52ab2e

Browse files
committed
Add fence feature
1 parent 669d03e commit d52ab2e

File tree

3 files changed

+33
-45
lines changed

3 files changed

+33
-45
lines changed

Cargo.toml

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ 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/rx.rs

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,19 @@ impl RxDescriptor {
6666

6767
/// Pass ownership to the DMA engine
6868
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);
6974
unsafe {
7075
self.desc.modify(0, |w| w | RXDESC_0_OWN);
7176
}
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);
7282
}
7383

7484
fn has_error(&self) -> bool {
@@ -125,7 +135,6 @@ impl RingDescriptor for RxDescriptor {
125135
self.set_end_of_ring();
126136
}
127137
};
128-
// There is already a fence before starting the DMA engine
129138
self.set_owned();
130139
}
131140
}
@@ -177,13 +186,6 @@ impl<'a> DerefMut for RxPacket<'a> {
177186

178187
impl<'a> Drop for RxPacket<'a> {
179188
fn drop(&mut self) {
180-
// "Preceding reads and writes cannot be moved past subsequent writes."
181-
#[cfg(feature = "stm32f7xx-hal")]
182-
atomic::fence(Ordering::Release);
183-
184-
#[cfg(not(feature = "stm32f7xx-hal"))]
185-
atomic::compiler_fence(Ordering::Release);
186-
187189
self.entry.desc_mut().set_owned();
188190
}
189191
}
@@ -230,12 +232,7 @@ impl<'a> RxRing<'a> {
230232
// Register RxDescriptor
231233
eth_dma.dmardlar.write(|w| w.srl().bits(ring_ptr as u32));
232234

233-
// "Preceding reads and writes cannot be moved past subsequent writes."
234-
#[cfg(feature = "stm32f7xx-hal")]
235-
atomic::fence(Ordering::Release);
236-
237-
// We don't need a compiler fence here because all interactions with `Descriptor` are
238-
// volatiles
235+
// We already have fences in `set_owned`, which is called in `setup`
239236

240237
// Start receive
241238
eth_dma.dmaomr.modify(|_, w| w.sr().set_bit());
@@ -246,11 +243,6 @@ impl<'a> RxRing<'a> {
246243
/// Demand that the DMA engine polls the current `RxDescriptor`
247244
/// (when in `RunningState::Stopped`.)
248245
pub fn demand_poll(&self, eth_dma: &ETHERNET_DMA) {
249-
// Prevent `set_owned` to me moved to after the poll
250-
// "Preceding reads and writes cannot be moved past subsequent writes."
251-
#[cfg(feature = "stm32f7xx-hal")]
252-
atomic::fence(Ordering::Release);
253-
254246
eth_dma.dmarpdr.write(|w| unsafe { w.rpd().bits(1) });
255247
}
256248

src/tx.rs

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,19 @@ impl TxDescriptor {
6363

6464
/// Pass ownership to the DMA engine
6565
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);
6671
unsafe {
6772
self.desc.modify(0, |w| w | TXDESC_0_OWN);
6873
}
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);
6979
}
7080

7181
#[allow(unused)]
@@ -155,13 +165,6 @@ impl<'a> DerefMut for TxPacket<'a> {
155165
impl<'a> TxPacket<'a> {
156166
// Pass to DMA engine
157167
pub fn send(self) {
158-
// "Preceding reads and writes cannot be moved past subsequent writes."
159-
#[cfg(feature = "stm32f7xx-hal")]
160-
atomic::fence(Ordering::Release);
161-
162-
#[cfg(not(feature = "stm32f7xx-hal"))]
163-
atomic::compiler_fence(Ordering::Release);
164-
165168
self.entry.desc_mut().set_owned();
166169
}
167170
}
@@ -204,7 +207,7 @@ impl<'a> TxRing<'a> {
204207
eth_dma.dmatdlar.write(|w| w.stl().bits(ring_ptr as u32));
205208

206209
// "Preceding reads and writes cannot be moved past subsequent writes."
207-
#[cfg(feature = "stm32f7xx-hal")]
210+
#[cfg(feature = "fence")]
208211
atomic::fence(Ordering::Release);
209212

210213
// We don't need a compiler fence here because all interactions with `Descriptor` are
@@ -239,15 +242,6 @@ impl<'a> TxRing<'a> {
239242
/// Demand that the DMA engine polls the current `TxDescriptor`
240243
/// (when we just transferred ownership to the hardware).
241244
pub fn demand_poll(&self, eth_dma: &ETHERNET_DMA) {
242-
// "Preceding reads and writes cannot be moved past subsequent writes."
243-
#[cfg(feature = "stm32f7xx-hal")]
244-
atomic::fence(Ordering::Release);
245-
246-
// We don't need a compiler fence here because all operations to the buffer were done before
247-
// setting the owned bit (see fences in `TxPacket::send`). We also don't need a compiler
248-
// fence between setting the owned bit and starting the poll, because setting the owned bit
249-
// is a volatile operation
250-
251245
eth_dma.dmatpdr.write(|w| w.tpd().poll());
252246
}
253247

0 commit comments

Comments
 (0)