Merge pull request #2933 from embassy-rs/update-stable
Update stable Rust.
This commit is contained in:
		
						commit
						b56a0419bd
					
				@ -478,8 +478,12 @@ mod tests {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    #[test]
 | 
					    #[test]
 | 
				
			||||||
    fn zero_len() {
 | 
					    fn zero_len() {
 | 
				
			||||||
 | 
					        let mut b = [0; 0];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let rb = RingBuffer::new();
 | 
					        let rb = RingBuffer::new();
 | 
				
			||||||
        unsafe {
 | 
					        unsafe {
 | 
				
			||||||
 | 
					            rb.init(b.as_mut_ptr(), b.len());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            assert_eq!(rb.is_empty(), true);
 | 
					            assert_eq!(rb.is_empty(), true);
 | 
				
			||||||
            assert_eq!(rb.is_full(), true);
 | 
					            assert_eq!(rb.is_full(), true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -52,6 +52,7 @@ trait SealedInstance {
 | 
				
			|||||||
    #[allow(unused)]
 | 
					    #[allow(unused)]
 | 
				
			||||||
    fn regs() -> crate::pac::adc::Adc;
 | 
					    fn regs() -> crate::pac::adc::Adc;
 | 
				
			||||||
    #[cfg(not(any(adc_f1, adc_v1, adc_l0, adc_f3_v2, adc_f3_v1_1, adc_g0)))]
 | 
					    #[cfg(not(any(adc_f1, adc_v1, adc_l0, adc_f3_v2, adc_f3_v1_1, adc_g0)))]
 | 
				
			||||||
 | 
					    #[allow(unused)]
 | 
				
			||||||
    fn common_regs() -> crate::pac::adccommon::AdcCommon;
 | 
					    fn common_regs() -> crate::pac::adccommon::AdcCommon;
 | 
				
			||||||
    #[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))]
 | 
					    #[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))]
 | 
				
			||||||
    fn state() -> &'static State;
 | 
					    fn state() -> &'static State;
 | 
				
			||||||
 | 
				
			|||||||
@ -47,6 +47,7 @@ trait SealedInstance {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Enable global interrupt
 | 
					    /// Enable global interrupt
 | 
				
			||||||
 | 
					    #[allow(unused)]
 | 
				
			||||||
    fn enable_irq(&self) {
 | 
					    fn enable_irq(&self) {
 | 
				
			||||||
        Self::regs().csr().modify(|v| v.set_ien(true))
 | 
					        Self::regs().csr().modify(|v| v.set_ien(true))
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -969,17 +969,6 @@ fn finish_dma(regs: Regs) {
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
trait RegsExt {
 | 
					 | 
				
			||||||
    fn dr_ptr<W>(&self) -> *mut W;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl RegsExt for Regs {
 | 
					 | 
				
			||||||
    fn dr_ptr<W>(&self) -> *mut W {
 | 
					 | 
				
			||||||
        let dr = self.dr();
 | 
					 | 
				
			||||||
        dr.as_ptr() as *mut W
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub(crate) trait SealedInstance {
 | 
					pub(crate) trait SealedInstance {
 | 
				
			||||||
    const REGS: Regs;
 | 
					    const REGS: Regs;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -177,9 +177,10 @@ embassy_time_queue_driver::timer_queue_impl!(static QUEUE: Queue = Queue::new())
 | 
				
			|||||||
#[cfg(test)]
 | 
					#[cfg(test)]
 | 
				
			||||||
#[cfg(feature = "mock-driver")]
 | 
					#[cfg(feature = "mock-driver")]
 | 
				
			||||||
mod tests {
 | 
					mod tests {
 | 
				
			||||||
    use core::cell::Cell;
 | 
					    use core::sync::atomic::{AtomicBool, Ordering};
 | 
				
			||||||
    use core::task::{RawWaker, RawWakerVTable, Waker};
 | 
					    use core::task::Waker;
 | 
				
			||||||
    use std::rc::Rc;
 | 
					    use std::sync::Arc;
 | 
				
			||||||
 | 
					    use std::task::Wake;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    use serial_test::serial;
 | 
					    use serial_test::serial;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -188,42 +189,26 @@ mod tests {
 | 
				
			|||||||
    use crate::{Duration, Instant};
 | 
					    use crate::{Duration, Instant};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    struct TestWaker {
 | 
					    struct TestWaker {
 | 
				
			||||||
        pub awoken: Rc<Cell<bool>>,
 | 
					        pub awoken: AtomicBool,
 | 
				
			||||||
        pub waker: Waker,
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    impl TestWaker {
 | 
					    impl Wake for TestWaker {
 | 
				
			||||||
        fn new() -> Self {
 | 
					        fn wake(self: Arc<Self>) {
 | 
				
			||||||
            let flag = Rc::new(Cell::new(false));
 | 
					            self.awoken.store(true, Ordering::Relaxed);
 | 
				
			||||||
 | 
					 | 
				
			||||||
            const VTABLE: RawWakerVTable = RawWakerVTable::new(
 | 
					 | 
				
			||||||
                |data: *const ()| {
 | 
					 | 
				
			||||||
                    unsafe {
 | 
					 | 
				
			||||||
                        Rc::increment_strong_count(data as *const Cell<bool>);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    RawWaker::new(data as _, &VTABLE)
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                |data: *const ()| unsafe {
 | 
					 | 
				
			||||||
                    let data = data as *const Cell<bool>;
 | 
					 | 
				
			||||||
                    data.as_ref().unwrap().set(true);
 | 
					 | 
				
			||||||
                    Rc::decrement_strong_count(data);
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                |data: *const ()| unsafe {
 | 
					 | 
				
			||||||
                    (data as *const Cell<bool>).as_ref().unwrap().set(true);
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                |data: *const ()| unsafe {
 | 
					 | 
				
			||||||
                    Rc::decrement_strong_count(data);
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            let raw = RawWaker::new(Rc::into_raw(flag.clone()) as _, &VTABLE);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            Self {
 | 
					 | 
				
			||||||
                awoken: flag.clone(),
 | 
					 | 
				
			||||||
                waker: unsafe { Waker::from_raw(raw) },
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        fn wake_by_ref(self: &Arc<Self>) {
 | 
				
			||||||
 | 
					            self.awoken.store(true, Ordering::Relaxed);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn test_waker() -> (Arc<TestWaker>, Waker) {
 | 
				
			||||||
 | 
					        let arc = Arc::new(TestWaker {
 | 
				
			||||||
 | 
					            awoken: AtomicBool::new(false),
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        let waker = Waker::from(arc.clone());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        (arc, waker)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn setup() {
 | 
					    fn setup() {
 | 
				
			||||||
@ -249,11 +234,11 @@ mod tests {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        assert_eq!(queue_len(), 0);
 | 
					        assert_eq!(queue_len(), 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let waker = TestWaker::new();
 | 
					        let (flag, waker) = test_waker();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        QUEUE.schedule_wake(Instant::from_secs(1), &waker.waker);
 | 
					        QUEUE.schedule_wake(Instant::from_secs(1), &waker);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        assert!(!waker.awoken.get());
 | 
					        assert!(!flag.awoken.load(Ordering::Relaxed));
 | 
				
			||||||
        assert_eq!(queue_len(), 1);
 | 
					        assert_eq!(queue_len(), 1);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -262,23 +247,23 @@ mod tests {
 | 
				
			|||||||
    fn test_schedule_same() {
 | 
					    fn test_schedule_same() {
 | 
				
			||||||
        setup();
 | 
					        setup();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let waker = TestWaker::new();
 | 
					        let (_flag, waker) = test_waker();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        QUEUE.schedule_wake(Instant::from_secs(1), &waker.waker);
 | 
					        QUEUE.schedule_wake(Instant::from_secs(1), &waker);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        assert_eq!(queue_len(), 1);
 | 
					        assert_eq!(queue_len(), 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        QUEUE.schedule_wake(Instant::from_secs(1), &waker.waker);
 | 
					        QUEUE.schedule_wake(Instant::from_secs(1), &waker);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        assert_eq!(queue_len(), 1);
 | 
					        assert_eq!(queue_len(), 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        QUEUE.schedule_wake(Instant::from_secs(100), &waker.waker);
 | 
					        QUEUE.schedule_wake(Instant::from_secs(100), &waker);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        assert_eq!(queue_len(), 1);
 | 
					        assert_eq!(queue_len(), 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let waker2 = TestWaker::new();
 | 
					        let (_flag2, waker2) = test_waker();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        QUEUE.schedule_wake(Instant::from_secs(100), &waker2.waker);
 | 
					        QUEUE.schedule_wake(Instant::from_secs(100), &waker2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        assert_eq!(queue_len(), 2);
 | 
					        assert_eq!(queue_len(), 2);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -288,21 +273,21 @@ mod tests {
 | 
				
			|||||||
    fn test_trigger() {
 | 
					    fn test_trigger() {
 | 
				
			||||||
        setup();
 | 
					        setup();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let waker = TestWaker::new();
 | 
					        let (flag, waker) = test_waker();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        QUEUE.schedule_wake(Instant::from_secs(100), &waker.waker);
 | 
					        QUEUE.schedule_wake(Instant::from_secs(100), &waker);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        assert!(!waker.awoken.get());
 | 
					        assert!(!flag.awoken.load(Ordering::Relaxed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        MockDriver::get().advance(Duration::from_secs(99));
 | 
					        MockDriver::get().advance(Duration::from_secs(99));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        assert!(!waker.awoken.get());
 | 
					        assert!(!flag.awoken.load(Ordering::Relaxed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        assert_eq!(queue_len(), 1);
 | 
					        assert_eq!(queue_len(), 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        MockDriver::get().advance(Duration::from_secs(1));
 | 
					        MockDriver::get().advance(Duration::from_secs(1));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        assert!(waker.awoken.get());
 | 
					        assert!(flag.awoken.load(Ordering::Relaxed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        assert_eq!(queue_len(), 0);
 | 
					        assert_eq!(queue_len(), 0);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -312,18 +297,18 @@ mod tests {
 | 
				
			|||||||
    fn test_immediate_trigger() {
 | 
					    fn test_immediate_trigger() {
 | 
				
			||||||
        setup();
 | 
					        setup();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let waker = TestWaker::new();
 | 
					        let (flag, waker) = test_waker();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        QUEUE.schedule_wake(Instant::from_secs(100), &waker.waker);
 | 
					        QUEUE.schedule_wake(Instant::from_secs(100), &waker);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        MockDriver::get().advance(Duration::from_secs(50));
 | 
					        MockDriver::get().advance(Duration::from_secs(50));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let waker2 = TestWaker::new();
 | 
					        let (flag2, waker2) = test_waker();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        QUEUE.schedule_wake(Instant::from_secs(40), &waker2.waker);
 | 
					        QUEUE.schedule_wake(Instant::from_secs(40), &waker2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        assert!(!waker.awoken.get());
 | 
					        assert!(!flag.awoken.load(Ordering::Relaxed));
 | 
				
			||||||
        assert!(waker2.awoken.get());
 | 
					        assert!(flag2.awoken.load(Ordering::Relaxed));
 | 
				
			||||||
        assert_eq!(queue_len(), 1);
 | 
					        assert_eq!(queue_len(), 1);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -333,30 +318,31 @@ mod tests {
 | 
				
			|||||||
        setup();
 | 
					        setup();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for i in 1..super::QUEUE_SIZE {
 | 
					        for i in 1..super::QUEUE_SIZE {
 | 
				
			||||||
            let waker = TestWaker::new();
 | 
					            let (flag, waker) = test_waker();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            QUEUE.schedule_wake(Instant::from_secs(310), &waker.waker);
 | 
					            QUEUE.schedule_wake(Instant::from_secs(310), &waker);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            assert_eq!(queue_len(), i);
 | 
					            assert_eq!(queue_len(), i);
 | 
				
			||||||
            assert!(!waker.awoken.get());
 | 
					            assert!(!flag.awoken.load(Ordering::Relaxed));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let first_waker = TestWaker::new();
 | 
					        let (flag, waker) = test_waker();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        QUEUE.schedule_wake(Instant::from_secs(300), &first_waker.waker);
 | 
					        QUEUE.schedule_wake(Instant::from_secs(300), &waker);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        assert_eq!(queue_len(), super::QUEUE_SIZE);
 | 
					        assert_eq!(queue_len(), super::QUEUE_SIZE);
 | 
				
			||||||
        assert!(!first_waker.awoken.get());
 | 
					        assert!(!flag.awoken.load(Ordering::Relaxed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let second_waker = TestWaker::new();
 | 
					        let (flag2, waker2) = test_waker();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        QUEUE.schedule_wake(Instant::from_secs(305), &second_waker.waker);
 | 
					        QUEUE.schedule_wake(Instant::from_secs(305), &waker2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        assert_eq!(queue_len(), super::QUEUE_SIZE);
 | 
					        assert_eq!(queue_len(), super::QUEUE_SIZE);
 | 
				
			||||||
        assert!(first_waker.awoken.get());
 | 
					        assert!(flag.awoken.load(Ordering::Relaxed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        QUEUE.schedule_wake(Instant::from_secs(320), &TestWaker::new().waker);
 | 
					        let (_flag3, waker3) = test_waker();
 | 
				
			||||||
 | 
					        QUEUE.schedule_wake(Instant::from_secs(320), &waker3);
 | 
				
			||||||
        assert_eq!(queue_len(), super::QUEUE_SIZE);
 | 
					        assert_eq!(queue_len(), super::QUEUE_SIZE);
 | 
				
			||||||
        assert!(second_waker.awoken.get());
 | 
					        assert!(flag2.awoken.load(Ordering::Relaxed));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
[toolchain]
 | 
					[toolchain]
 | 
				
			||||||
channel = "1.77"
 | 
					channel = "1.78"
 | 
				
			||||||
components = [ "rust-src", "rustfmt", "llvm-tools" ]
 | 
					components = [ "rust-src", "rustfmt", "llvm-tools" ]
 | 
				
			||||||
targets = [
 | 
					targets = [
 | 
				
			||||||
    "thumbv7em-none-eabi",
 | 
					    "thumbv7em-none-eabi",
 | 
				
			||||||
 | 
				
			|||||||
@ -11,8 +11,8 @@ embassy-executor = { version = "0.5.0", path = "../../embassy-executor", feature
 | 
				
			|||||||
embassy-time = { version = "0.3.0", path = "../../embassy-time" }
 | 
					embassy-time = { version = "0.3.0", path = "../../embassy-time" }
 | 
				
			||||||
embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
 | 
					embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
riscv-rt = "0.11"
 | 
					riscv-rt = "0.12.2"
 | 
				
			||||||
riscv = { version = "0.10", features = ["critical-section-single-hart"] }
 | 
					riscv = { version = "0.11.1", features = ["critical-section-single-hart"] }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[profile.dev]
 | 
					[profile.dev]
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										214
									
								
								tests/riscv32/link.x
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										214
									
								
								tests/riscv32/link.x
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,214 @@
 | 
				
			|||||||
 | 
					/* # EMBASSY notes
 | 
				
			||||||
 | 
					  This file is a workaround for https://github.com/rust-embedded/riscv/issues/196
 | 
				
			||||||
 | 
					  Remove when fixed upstream.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					/* # Developer notes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Symbols that start with a double underscore (__) are considered "private"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Symbols that start with a single underscore (_) are considered "semi-public"; they can be
 | 
				
			||||||
 | 
					  overridden in a user linker script, but should not be referred from user code (e.g. `extern "C" {
 | 
				
			||||||
 | 
					  static mut _heap_size }`).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- `EXTERN` forces the linker to keep a symbol in the final binary. We use this to make sure a
 | 
				
			||||||
 | 
					  symbol if not dropped if it appears in or near the front of the linker arguments and "it's not
 | 
				
			||||||
 | 
					  needed" by any of the preceding objects (linker arguments)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- `PROVIDE` is used to provide default values that can be overridden by a user linker script
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- In this linker script, you may find symbols that look like `${...}` (e.g., `4`).
 | 
				
			||||||
 | 
					  These are wildcards used by the `build.rs` script to adapt to different target particularities.
 | 
				
			||||||
 | 
					  Check `build.rs` for more details about these symbols.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- On alignment: it's important for correctness that the VMA boundaries of both .bss and .data *and*
 | 
				
			||||||
 | 
					  the LMA of .data are all `4`-byte aligned. These alignments are assumed by the RAM
 | 
				
			||||||
 | 
					  initialization routine. There's also a second benefit: `4`-byte aligned boundaries
 | 
				
			||||||
 | 
					  means that you won't see "Address (..) is out of bounds" in the disassembly produced by `objdump`.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PROVIDE(_stext = ORIGIN(REGION_TEXT));
 | 
				
			||||||
 | 
					PROVIDE(_stack_start = ORIGIN(REGION_STACK) + LENGTH(REGION_STACK));
 | 
				
			||||||
 | 
					PROVIDE(_max_hart_id = 0);
 | 
				
			||||||
 | 
					PROVIDE(_hart_stack_size = 2K);
 | 
				
			||||||
 | 
					PROVIDE(_heap_size = 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PROVIDE(InstructionMisaligned = ExceptionHandler);
 | 
				
			||||||
 | 
					PROVIDE(InstructionFault = ExceptionHandler);
 | 
				
			||||||
 | 
					PROVIDE(IllegalInstruction = ExceptionHandler);
 | 
				
			||||||
 | 
					PROVIDE(Breakpoint = ExceptionHandler);
 | 
				
			||||||
 | 
					PROVIDE(LoadMisaligned = ExceptionHandler);
 | 
				
			||||||
 | 
					PROVIDE(LoadFault = ExceptionHandler);
 | 
				
			||||||
 | 
					PROVIDE(StoreMisaligned = ExceptionHandler);
 | 
				
			||||||
 | 
					PROVIDE(StoreFault = ExceptionHandler);;
 | 
				
			||||||
 | 
					PROVIDE(UserEnvCall = ExceptionHandler);
 | 
				
			||||||
 | 
					PROVIDE(SupervisorEnvCall = ExceptionHandler);
 | 
				
			||||||
 | 
					PROVIDE(MachineEnvCall = ExceptionHandler);
 | 
				
			||||||
 | 
					PROVIDE(InstructionPageFault = ExceptionHandler);
 | 
				
			||||||
 | 
					PROVIDE(LoadPageFault = ExceptionHandler);
 | 
				
			||||||
 | 
					PROVIDE(StorePageFault = ExceptionHandler);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PROVIDE(SupervisorSoft = DefaultHandler);
 | 
				
			||||||
 | 
					PROVIDE(MachineSoft = DefaultHandler);
 | 
				
			||||||
 | 
					PROVIDE(SupervisorTimer = DefaultHandler);
 | 
				
			||||||
 | 
					PROVIDE(MachineTimer = DefaultHandler);
 | 
				
			||||||
 | 
					PROVIDE(SupervisorExternal = DefaultHandler);
 | 
				
			||||||
 | 
					PROVIDE(MachineExternal = DefaultHandler);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PROVIDE(DefaultHandler = DefaultInterruptHandler);
 | 
				
			||||||
 | 
					PROVIDE(ExceptionHandler = DefaultExceptionHandler);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* # Pre-initialization function */
 | 
				
			||||||
 | 
					/* If the user overrides this using the `#[pre_init]` attribute or by creating a `__pre_init` function,
 | 
				
			||||||
 | 
					   then the function this points to will be called before the RAM is initialized. */
 | 
				
			||||||
 | 
					PROVIDE(__pre_init = default_pre_init);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* A PAC/HAL defined routine that should initialize custom interrupt controller if needed. */
 | 
				
			||||||
 | 
					PROVIDE(_setup_interrupts = default_setup_interrupts);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* # Multi-processing hook function
 | 
				
			||||||
 | 
					   fn _mp_hook() -> bool;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   This function is called from all the harts and must return true only for one hart,
 | 
				
			||||||
 | 
					   which will perform memory initialization. For other harts it must return false
 | 
				
			||||||
 | 
					   and implement wake-up in platform-dependent way (e.g. after waiting for a user interrupt).
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					PROVIDE(_mp_hook = default_mp_hook);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* # Start trap function override
 | 
				
			||||||
 | 
					  By default uses the riscv crates default trap handler
 | 
				
			||||||
 | 
					  but by providing the `_start_trap` symbol external crates can override.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					PROVIDE(_start_trap = default_start_trap);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SECTIONS
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  .text.dummy (NOLOAD) :
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    /* This section is intended to make _stext address work */
 | 
				
			||||||
 | 
					    . = ABSOLUTE(_stext);
 | 
				
			||||||
 | 
					  } > REGION_TEXT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  .text _stext :
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    /* Put reset handler first in .text section so it ends up as the entry */
 | 
				
			||||||
 | 
					    /* point of the program. */
 | 
				
			||||||
 | 
					    KEEP(*(.init));
 | 
				
			||||||
 | 
					    KEEP(*(.init.rust));
 | 
				
			||||||
 | 
					    . = ALIGN(4);
 | 
				
			||||||
 | 
					    *(.trap);
 | 
				
			||||||
 | 
					    *(.trap.rust);
 | 
				
			||||||
 | 
					    *(.text.abort);
 | 
				
			||||||
 | 
					    *(.text .text.*);
 | 
				
			||||||
 | 
					  } > REGION_TEXT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  .eh_frame : { KEEP(*(.eh_frame)) } > REGION_TEXT
 | 
				
			||||||
 | 
					  .eh_frame_hdr : { *(.eh_frame_hdr) } > REGION_TEXT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  .rodata : ALIGN(4)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    *(.srodata .srodata.*);
 | 
				
			||||||
 | 
					    *(.rodata .rodata.*);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* 4-byte align the end (VMA) of this section.
 | 
				
			||||||
 | 
					       This is required by LLD to ensure the LMA of the following .data
 | 
				
			||||||
 | 
					       section will have the correct alignment. */
 | 
				
			||||||
 | 
					    . = ALIGN(4);
 | 
				
			||||||
 | 
					  } > REGION_RODATA
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  .data : ALIGN(4)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    _sidata = LOADADDR(.data);
 | 
				
			||||||
 | 
					    _sdata = .;
 | 
				
			||||||
 | 
					    /* Must be called __global_pointer$ for linker relaxations to work. */
 | 
				
			||||||
 | 
					    PROVIDE(__global_pointer$ = . + 0x800);
 | 
				
			||||||
 | 
					    *(.sdata .sdata.* .sdata2 .sdata2.*);
 | 
				
			||||||
 | 
					    *(.data .data.*);
 | 
				
			||||||
 | 
					    . = ALIGN(4);
 | 
				
			||||||
 | 
					    _edata = .;
 | 
				
			||||||
 | 
					  } > REGION_DATA AT > REGION_RODATA
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  .bss (NOLOAD) : ALIGN(4)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    _sbss = .;
 | 
				
			||||||
 | 
					    *(.sbss .sbss.* .bss .bss.*);
 | 
				
			||||||
 | 
					    . = ALIGN(4);
 | 
				
			||||||
 | 
					    _ebss = .;
 | 
				
			||||||
 | 
					  } > REGION_BSS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* fictitious region that represents the memory available for the heap */
 | 
				
			||||||
 | 
					  .heap (NOLOAD) :
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    _sheap = .;
 | 
				
			||||||
 | 
					    . += _heap_size;
 | 
				
			||||||
 | 
					    . = ALIGN(4);
 | 
				
			||||||
 | 
					    _eheap = .;
 | 
				
			||||||
 | 
					  } > REGION_HEAP
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* fictitious region that represents the memory available for the stack */
 | 
				
			||||||
 | 
					  .stack (NOLOAD) :
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    _estack = .;
 | 
				
			||||||
 | 
					    . = ABSOLUTE(_stack_start);
 | 
				
			||||||
 | 
					    _sstack = .;
 | 
				
			||||||
 | 
					  } > REGION_STACK
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* fake output .got section */
 | 
				
			||||||
 | 
					  /* Dynamic relocations are unsupported. This section is only used to detect
 | 
				
			||||||
 | 
					     relocatable code in the input files and raise an error if relocatable code
 | 
				
			||||||
 | 
					     is found */
 | 
				
			||||||
 | 
					  .got (INFO) :
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    KEEP(*(.got .got.*));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Do not exceed this mark in the error messages above                                    | */
 | 
				
			||||||
 | 
					ASSERT(ORIGIN(REGION_TEXT) % 4 == 0, "
 | 
				
			||||||
 | 
					ERROR(riscv-rt): the start of the REGION_TEXT must be 4-byte aligned");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ASSERT(ORIGIN(REGION_RODATA) % 4 == 0, "
 | 
				
			||||||
 | 
					ERROR(riscv-rt): the start of the REGION_RODATA must be 4-byte aligned");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ASSERT(ORIGIN(REGION_DATA) % 4 == 0, "
 | 
				
			||||||
 | 
					ERROR(riscv-rt): the start of the REGION_DATA must be 4-byte aligned");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ASSERT(ORIGIN(REGION_HEAP) % 4 == 0, "
 | 
				
			||||||
 | 
					ERROR(riscv-rt): the start of the REGION_HEAP must be 4-byte aligned");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ASSERT(ORIGIN(REGION_TEXT) % 4 == 0, "
 | 
				
			||||||
 | 
					ERROR(riscv-rt): the start of the REGION_TEXT must be 4-byte aligned");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ASSERT(ORIGIN(REGION_STACK) % 4 == 0, "
 | 
				
			||||||
 | 
					ERROR(riscv-rt): the start of the REGION_STACK must be 4-byte aligned");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ASSERT(_stext % 4 == 0, "
 | 
				
			||||||
 | 
					ERROR(riscv-rt): `_stext` must be 4-byte aligned");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ASSERT(_sdata % 4 == 0 && _edata % 4 == 0, "
 | 
				
			||||||
 | 
					BUG(riscv-rt): .data is not 4-byte aligned");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ASSERT(_sidata % 4 == 0, "
 | 
				
			||||||
 | 
					BUG(riscv-rt): the LMA of .data is not 4-byte aligned");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ASSERT(_sbss % 4 == 0 && _ebss % 4 == 0, "
 | 
				
			||||||
 | 
					BUG(riscv-rt): .bss is not 4-byte aligned");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ASSERT(_sheap % 4 == 0, "
 | 
				
			||||||
 | 
					BUG(riscv-rt): start of .heap is not 4-byte aligned");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ASSERT(_stext + SIZEOF(.text) < ORIGIN(REGION_TEXT) + LENGTH(REGION_TEXT), "
 | 
				
			||||||
 | 
					ERROR(riscv-rt): The .text section must be placed inside the REGION_TEXT region.
 | 
				
			||||||
 | 
					Set _stext to an address smaller than 'ORIGIN(REGION_TEXT) + LENGTH(REGION_TEXT)'");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ASSERT(SIZEOF(.stack) > (_max_hart_id + 1) * _hart_stack_size, "
 | 
				
			||||||
 | 
					ERROR(riscv-rt): .stack section is too small for allocating stacks for all the harts.
 | 
				
			||||||
 | 
					Consider changing `_max_hart_id` or `_hart_stack_size`.");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ASSERT(SIZEOF(.got) == 0, "
 | 
				
			||||||
 | 
					.got section detected in the input files. Dynamic relocations are not
 | 
				
			||||||
 | 
					supported. If you are linking to C code compiled using the `gcc` crate
 | 
				
			||||||
 | 
					then modify your build script to compile the C code _without_ the
 | 
				
			||||||
 | 
					-fPIC flag. See the documentation of the `gcc::Config.fpic` method for
 | 
				
			||||||
 | 
					details.");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Do not exceed this mark in the error messages above                                    | */
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user