diff options
author | 2022-02-25 01:19:34 +0000 | |
---|---|---|
committer | 2022-02-25 01:21:05 +0000 | |
commit | 3e8a5beec5f96a3c219b840dc26df34f76e4ab1e (patch) | |
tree | 45cfb08fca76efcce333a7f89cb28f32eea8fab9 | |
parent | f2feeb2595fe8f281a50d63055c65d6ac064ae11 (diff) | |
download | cortex-m-3e8a5beec5f96a3c219b840dc26df34f76e4ab1e.tar.gz cortex-m-3e8a5beec5f96a3c219b840dc26df34f76e4ab1e.tar.zst cortex-m-3e8a5beec5f96a3c219b840dc26df34f76e4ab1e.zip |
Fix cortex-m-rt qemu test by removing 'nomem' from semihosting_syscall asm, add inline to most cortex_m::asm methods
-rw-r--r-- | cortex-m-rt/examples/qemu.rs | 30 | ||||
-rw-r--r-- | cortex-m-rt/link.x.in | 2 | ||||
-rw-r--r-- | cortex-m-rt/src/lib.rs | 2 | ||||
-rw-r--r-- | cortex-m-semihosting/src/lib.rs | 13 | ||||
-rw-r--r-- | src/asm.rs | 30 | ||||
-rw-r--r-- | src/peripheral/mod.rs | 2 |
6 files changed, 33 insertions, 46 deletions
diff --git a/cortex-m-rt/examples/qemu.rs b/cortex-m-rt/examples/qemu.rs index e903404..a8ffd20 100644 --- a/cortex-m-rt/examples/qemu.rs +++ b/cortex-m-rt/examples/qemu.rs @@ -1,28 +1,24 @@ -// #![feature(stdsimd)] #![no_main] #![no_std] -extern crate cortex_m; -extern crate cortex_m_rt as rt; -extern crate cortex_m_semihosting as semihosting; +use core::fmt::Write; -extern crate panic_halt; - -use cortex_m::asm; -use rt::entry; - -#[entry] +#[cortex_m_rt::entry] fn main() -> ! { - use core::fmt::Write; let x = 42; loop { - asm::nop(); - - // write something through semihosting interface - let mut hstdout = semihosting::hio::hstdout().unwrap(); + let mut hstdout = cortex_m_semihosting::hio::hstdout().unwrap(); write!(hstdout, "x = {}\n", x).unwrap(); - // exit from qemu - semihosting::debug::exit(semihosting::debug::EXIT_SUCCESS); + cortex_m_semihosting::debug::exit(cortex_m_semihosting::debug::EXIT_SUCCESS); + } +} + +// Define a panic handler that uses semihosting to exit immediately, +// so that any panics cause qemu to quit instead of hang. +#[panic_handler] +fn panic(_: &core::panic::PanicInfo) -> ! { + loop { + cortex_m_semihosting::debug::exit(cortex_m_semihosting::debug::EXIT_FAILURE); } } diff --git a/cortex-m-rt/link.x.in b/cortex-m-rt/link.x.in index 92004b7..deff376 100644 --- a/cortex-m-rt/link.x.in +++ b/cortex-m-rt/link.x.in @@ -66,6 +66,8 @@ SECTIONS /* ### Vector table */ .vector_table ORIGIN(FLASH) : { + __vector_table = .; + /* Initial Stack Pointer (SP) value */ LONG(_stack_start); diff --git a/cortex-m-rt/src/lib.rs b/cortex-m-rt/src/lib.rs index 793b928..1e977c6 100644 --- a/cortex-m-rt/src/lib.rs +++ b/cortex-m-rt/src/lib.rs @@ -439,9 +439,9 @@ extern crate cortex_m_rt_macros as macros; -use core::fmt; #[cfg(cortex_m)] use core::arch::global_asm; +use core::fmt; // HardFault exceptions are bounced through this trampoline which grabs the stack pointer at // the time of the exception and passes it to th euser's HardFault handler in r0. diff --git a/cortex-m-semihosting/src/lib.rs b/cortex-m-semihosting/src/lib.rs index 4ff975d..186e7e7 100644 --- a/cortex-m-semihosting/src/lib.rs +++ b/cortex-m-semihosting/src/lib.rs @@ -194,20 +194,9 @@ pub unsafe fn syscall<T>(nr: usize, arg: &T) -> usize { pub unsafe fn syscall1(_nr: usize, _arg: usize) -> usize { match () { #[cfg(all(thumb, not(feature = "no-semihosting")))] - () => { - let mut nr = _nr; - core::arch::asm!( - "bkpt #0xab", - inout("r0") nr, - in("r1") _arg, - options(nomem, nostack, preserves_flags) - ); - nr - } - + () => cortex_m::asm::semihosting_syscall(_nr as u32, _arg as u32) as usize, #[cfg(all(thumb, feature = "no-semihosting"))] () => 0, - #[cfg(not(thumb))] () => unimplemented!(), } @@ -44,7 +44,7 @@ pub fn delay(cycles: u32) { } /// A no-operation. Useful to prevent delay loops from being optimized away. -#[inline] +#[inline(always)] pub fn nop() { // NOTE: This is a `pure` asm block, but applying that option allows the compiler to eliminate // the nop entirely (or to collapse multiple subsequent ones). Since the user probably wants N @@ -59,28 +59,28 @@ pub fn nop() { /// /// Can be used as a stable alternative to `core::intrinsics::abort`. #[cfg(cortex_m)] -#[inline] +#[inline(always)] pub fn udf() -> ! { unsafe { asm!("udf #0", options(noreturn, nomem, nostack, preserves_flags)) }; } /// Wait For Event #[cfg(cortex_m)] -#[inline] +#[inline(always)] pub fn wfe() { unsafe { asm!("wfe", options(nomem, nostack, preserves_flags)) }; } /// Wait For Interrupt #[cfg(cortex_m)] -#[inline] +#[inline(always)] pub fn wfi() { unsafe { asm!("wfi", options(nomem, nostack, preserves_flags)) }; } /// Send Event #[cfg(cortex_m)] -#[inline] +#[inline(always)] pub fn sev() { unsafe { asm!("sev", options(nomem, nostack, preserves_flags)) }; } @@ -89,7 +89,7 @@ pub fn sev() { /// /// Flushes the pipeline in the processor, so that all instructions following the `ISB` are fetched /// from cache or memory, after the instruction has been completed. -#[inline] +#[inline(always)] pub fn isb() { compiler_fence(Ordering::SeqCst); #[cfg(cortex_m)] @@ -106,7 +106,7 @@ pub fn isb() { /// /// * any explicit memory access made before this instruction is complete /// * all cache and branch predictor maintenance operations before this instruction complete -#[inline] +#[inline(always)] pub fn dsb() { compiler_fence(Ordering::SeqCst); #[cfg(cortex_m)] @@ -121,7 +121,7 @@ pub fn dsb() { /// Ensures that all explicit memory accesses that appear in program order before the `DMB` /// instruction are observed before any explicit memory accesses that appear in program order /// after the `DMB` instruction. -#[inline] +#[inline(always)] pub fn dmb() { compiler_fence(Ordering::SeqCst); #[cfg(cortex_m)] @@ -136,7 +136,7 @@ pub fn dmb() { /// Queries the Security state and access permissions of a memory location. /// Returns a Test Target Response Payload (cf section D1.2.215 of /// Armv8-M Architecture Reference Manual). -#[inline] +#[inline(always)] #[cfg(armv8m)] // The __tt function does not dereference the pointer received. #[allow(clippy::not_unsafe_ptr_arg_deref)] @@ -158,7 +158,7 @@ pub fn tt(addr: *mut u32) -> u32 { /// access to that location. /// Returns a Test Target Response Payload (cf section D1.2.215 of /// Armv8-M Architecture Reference Manual). -#[inline] +#[inline(always)] #[cfg(armv8m)] // The __ttt function does not dereference the pointer received. #[allow(clippy::not_unsafe_ptr_arg_deref)] @@ -181,7 +181,7 @@ pub fn ttt(addr: *mut u32) -> u32 { /// undefined if used from Non-Secure state. /// Returns a Test Target Response Payload (cf section D1.2.215 of /// Armv8-M Architecture Reference Manual). -#[inline] +#[inline(always)] #[cfg(armv8m)] // The __tta function does not dereference the pointer received. #[allow(clippy::not_unsafe_ptr_arg_deref)] @@ -204,7 +204,7 @@ pub fn tta(addr: *mut u32) -> u32 { /// state and is undefined if used from Non-Secure state. /// Returns a Test Target Response Payload (cf section D1.2.215 of /// Armv8-M Architecture Reference Manual). -#[inline] +#[inline(always)] #[cfg(armv8m)] // The __ttat function does not dereference the pointer received. #[allow(clippy::not_unsafe_ptr_arg_deref)] @@ -224,7 +224,7 @@ pub fn ttat(addr: *mut u32) -> u32 { /// /// See section C2.4.26 of Armv8-M Architecture Reference Manual for details. /// Undefined if executed in Non-Secure state. -#[inline] +#[inline(always)] #[cfg(armv8m)] pub unsafe fn bx_ns(addr: u32) { asm!("bxns {}", in(reg) addr, options(nomem, nostack, preserves_flags)); @@ -234,9 +234,9 @@ pub unsafe fn bx_ns(addr: u32) { /// /// This method is used by cortex-m-semihosting to provide semihosting syscalls. #[cfg(cortex_m)] -#[inline] +#[inline(always)] pub unsafe fn semihosting_syscall(mut nr: u32, arg: u32) -> u32 { - asm!("bkpt #0xab", inout("r0") nr, in("r1") arg, options(nomem, nostack, preserves_flags)); + asm!("bkpt #0xab", inout("r0") nr, in("r1") arg, options(nostack, preserves_flags)); nr } diff --git a/src/peripheral/mod.rs b/src/peripheral/mod.rs index 56b663e..c316886 100644 --- a/src/peripheral/mod.rs +++ b/src/peripheral/mod.rs @@ -57,9 +57,9 @@ //! //! - ARMv7-M Architecture Reference Manual (Issue E.b) - Chapter B3 +use crate::interrupt; use core::marker::PhantomData; use core::ops; -use crate::interrupt; #[cfg(cm7)] pub mod ac; |