@@ -10,7 +10,9 @@ use defmt_rtt as _;
1010use panic_probe as _;
1111
1212use stm32_eth:: {
13+ dma:: { RxRingEntry , TxRingEntry } ,
1314 hal:: { gpio:: GpioExt , rcc:: Clocks } ,
15+ stm32:: MPU ,
1416 PartsIn ,
1517} ;
1618
@@ -25,12 +27,72 @@ use stm32_eth::hal::rcc::RccExt;
2527#[ allow( unused) ]
2628fn main ( ) { }
2729
30+ /// Mark RAM as non-cachable. Also validate that the RX ring
31+ /// and TX ring are within them.
32+ fn mpu_mark_noncachable ( mpu : MPU , rx_ring : & [ RxRingEntry ] , tx_ring : & [ TxRingEntry ] ) {
33+ let start = 0x20000000u32 ;
34+ let len = 32u32 * 1024 ;
35+ let range = start as usize ..( start as usize + len as usize ) ;
36+
37+ let rx_start = rx_ring. as_ptr ( ) ;
38+ let rx_first_addr = rx_start. addr ( ) ;
39+ let rx_last_addr = unsafe { rx_start. add ( rx_ring. len ( ) + 1 ) } . addr ( ) - 1 ;
40+ assert ! (
41+ range. contains( & rx_first_addr) ,
42+ "RX ring starts before non-cacheable region"
43+ ) ;
44+
45+ assert ! (
46+ range. contains( & rx_last_addr) ,
47+ "RX ring ends after non-cacheable region"
48+ ) ;
49+
50+ let tx_start = tx_ring. as_ptr ( ) ;
51+ let tx_first_addr = tx_start. addr ( ) ;
52+ let tx_last_addr = unsafe { rx_start. add ( tx_ring. len ( ) + 1 ) } . addr ( ) - 1 ;
53+ assert ! (
54+ range. contains( & tx_first_addr) ,
55+ "TX ring starts before non-cacheable region"
56+ ) ;
57+
58+ assert ! (
59+ range. contains( & tx_last_addr) ,
60+ "TX ring ends after non-cacheable region"
61+ ) ;
62+
63+ let size_field = len. trailing_zeros ( ) - 1 ;
64+
65+ unsafe {
66+ mpu. ctrl . write ( 0 ) ;
67+ let region = 0 ;
68+ mpu. rnr . write ( region) ;
69+ mpu. rbar . write ( start | 1 << 4 | region) ;
70+
71+ mpu. rasr . write (
72+ ( 1 << 28 )
73+ | ( 0b011 << 24 )
74+ | ( 0b0001 << 19 )
75+ | ( 0 << 17 )
76+ | ( 0 << 16 )
77+ | ( size_field << 1 )
78+ | ( 1 << 0 ) ,
79+ )
80+ }
81+ }
82+
2883/// Setup the clocks and return clocks and a GPIO struct that
2984/// can be used to set up all of the pins.
3085///
3186/// This configures HCLK to be at least 25 MHz, which is the minimum required
3287/// for ethernet operation to be valid.
33- pub fn setup_peripherals ( p : stm32_eth:: stm32:: Peripherals ) -> ( Clocks , Gpio , PartsIn ) {
88+ pub fn setup_peripherals (
89+ p : stm32_eth:: stm32:: Peripherals ,
90+ mpu : MPU ,
91+ rx_ring : & [ RxRingEntry ] ,
92+ tx_ring : & [ TxRingEntry ] ,
93+ ) -> ( Clocks , Gpio , PartsIn ) {
94+ mpu_mark_noncachable ( mpu, rx_ring, tx_ring) ;
95+
3496 let ethernet = PartsIn {
3597 dma : p. ETHERNET_DMA ,
3698 mac : p. ETHERNET_MAC ,
0 commit comments