22
33#![ allow( missing_docs) ]
44
5- #[ cfg_attr( cortex_m, path = "asm/inner.rs" ) ]
6- #[ cfg_attr( not( cortex_m) , path = "asm/inner_mock.rs" ) ]
5+ #[ cfg( cortex_m) ]
6+ use core:: arch:: asm;
7+
78pub mod inner;
89
910/// Puts the processor in Debug state. Debuggers can pick this up as a "breakpoint".
1011///
1112/// **NOTE** calling `bkpt` when the processor is not connected to a debugger will cause an
1213/// exception.
1314#[ inline( always) ]
15+ #[ cortex_m_macros:: asm_cfg( cortex_m) ]
1416pub fn bkpt ( ) {
15- unsafe { inner :: __bkpt ( ) } ;
17+ unsafe { asm ! ( "bkpt" , options ( nomem , nostack , preserves_flags ) ) } ;
1618}
1719
1820/// Blocks the program for *at least* `cycles` CPU cycles.
@@ -30,12 +32,14 @@ pub fn bkpt() {
3032/// initialization of peripherals if and only if accurate timing is not essential. In any other case
3133/// please use a more accurate method to produce a delay.
3234#[ inline]
35+ #[ cortex_m_macros:: asm_cfg( cortex_m) ]
3336pub fn delay ( cycles : u32 ) {
3437 unsafe { inner:: __delay ( cycles) } ;
3538}
3639
3740/// A no-operation. Useful to prevent delay loops from being optimized away.
3841#[ inline]
42+ #[ cortex_m_macros:: asm_cfg( cortex_m) ]
3943pub fn nop ( ) {
4044 unsafe { inner:: __nop ( ) } ;
4145}
@@ -44,24 +48,28 @@ pub fn nop() {
4448///
4549/// Can be used as a stable alternative to `core::intrinsics::abort`.
4650#[ inline]
51+ #[ cortex_m_macros:: asm_cfg( cortex_m) ]
4752pub fn udf ( ) -> ! {
4853 unsafe { inner:: __udf ( ) }
4954}
5055
5156/// Wait For Event
5257#[ inline]
58+ #[ cortex_m_macros:: asm_cfg( cortex_m) ]
5359pub fn wfe ( ) {
5460 unsafe { inner:: __wfe ( ) }
5561}
5662
5763/// Wait For Interrupt
5864#[ inline]
65+ #[ cortex_m_macros:: asm_cfg( cortex_m) ]
5966pub fn wfi ( ) {
6067 unsafe { inner:: __wfi ( ) }
6168}
6269
6370/// Send Event
6471#[ inline]
72+ #[ cortex_m_macros:: asm_cfg( cortex_m) ]
6573pub fn sev ( ) {
6674 unsafe { inner:: __sev ( ) }
6775}
@@ -71,6 +79,7 @@ pub fn sev() {
7179/// Flushes the pipeline in the processor, so that all instructions following the `ISB` are fetched
7280/// from cache or memory, after the instruction has been completed.
7381#[ inline]
82+ #[ cortex_m_macros:: asm_cfg( cortex_m) ]
7483pub fn isb ( ) {
7584 unsafe { inner:: __isb ( ) }
7685}
@@ -83,6 +92,7 @@ pub fn isb() {
8392/// * any explicit memory access made before this instruction is complete
8493/// * all cache and branch predictor maintenance operations before this instruction complete
8594#[ inline]
95+ #[ cortex_m_macros:: asm_cfg( cortex_m) ]
8696pub fn dsb ( ) {
8797 unsafe { inner:: __dsb ( ) }
8898}
@@ -93,6 +103,7 @@ pub fn dsb() {
93103/// instruction are observed before any explicit memory accesses that appear in program order
94104/// after the `DMB` instruction.
95105#[ inline]
106+ #[ cortex_m_macros:: asm_cfg( cortex_m) ]
96107pub fn dmb ( ) {
97108 unsafe { inner:: __dmb ( ) }
98109}
@@ -103,7 +114,7 @@ pub fn dmb() {
103114/// Returns a Test Target Response Payload (cf section D1.2.215 of
104115/// Armv8-M Architecture Reference Manual).
105116#[ inline]
106- #[ cfg ( armv8m) ]
117+ #[ cortex_m_macros :: asm_cfg ( armv8m) ]
107118// The __tt function does not dereference the pointer received.
108119#[ allow( clippy:: not_unsafe_ptr_arg_deref) ]
109120pub fn tt ( addr : * mut u32 ) -> u32 {
@@ -118,7 +129,7 @@ pub fn tt(addr: *mut u32) -> u32 {
118129/// Returns a Test Target Response Payload (cf section D1.2.215 of
119130/// Armv8-M Architecture Reference Manual).
120131#[ inline]
121- #[ cfg ( armv8m) ]
132+ #[ cortex_m_macros :: asm_cfg ( armv8m) ]
122133// The __ttt function does not dereference the pointer received.
123134#[ allow( clippy:: not_unsafe_ptr_arg_deref) ]
124135pub fn ttt ( addr : * mut u32 ) -> u32 {
@@ -134,7 +145,7 @@ pub fn ttt(addr: *mut u32) -> u32 {
134145/// Returns a Test Target Response Payload (cf section D1.2.215 of
135146/// Armv8-M Architecture Reference Manual).
136147#[ inline]
137- #[ cfg ( armv8m) ]
148+ #[ cortex_m_macros :: asm_cfg ( armv8m) ]
138149// The __tta function does not dereference the pointer received.
139150#[ allow( clippy:: not_unsafe_ptr_arg_deref) ]
140151pub fn tta ( addr : * mut u32 ) -> u32 {
@@ -150,7 +161,7 @@ pub fn tta(addr: *mut u32) -> u32 {
150161/// Returns a Test Target Response Payload (cf section D1.2.215 of
151162/// Armv8-M Architecture Reference Manual).
152163#[ inline]
153- #[ cfg ( armv8m) ]
164+ #[ cortex_m_macros :: asm_cfg ( armv8m) ]
154165// The __ttat function does not dereference the pointer received.
155166#[ allow( clippy:: not_unsafe_ptr_arg_deref) ]
156167pub fn ttat ( addr : * mut u32 ) -> u32 {
@@ -163,7 +174,7 @@ pub fn ttat(addr: *mut u32) -> u32 {
163174/// See section C2.4.26 of Armv8-M Architecture Reference Manual for details.
164175/// Undefined if executed in Non-Secure state.
165176#[ inline]
166- #[ cfg ( armv8m) ]
177+ #[ cortex_m_macros :: asm_cfg ( armv8m) ]
167178pub unsafe fn bx_ns ( addr : u32 ) {
168179 unsafe { crate :: asm:: inner:: __bxns ( addr) } ;
169180}
@@ -172,8 +183,12 @@ pub unsafe fn bx_ns(addr: u32) {
172183///
173184/// This method is used by cortex-m-semihosting to provide semihosting syscalls.
174185#[ inline]
175- pub unsafe fn semihosting_syscall ( nr : u32 , arg : u32 ) -> u32 {
176- unsafe { inner:: __sh_syscall ( nr, arg) }
186+ #[ cortex_m_macros:: asm_cfg( cortex_m) ]
187+ pub unsafe fn semihosting_syscall ( mut nr : u32 , arg : u32 ) -> u32 {
188+ unsafe {
189+ asm ! ( "bkpt #0xab" , inout( "r0" ) nr, in( "r1" ) arg, options( nomem, nostack, preserves_flags) )
190+ } ;
191+ nr
177192}
178193
179194/// Switch to unprivileged mode using the Process Stack
@@ -192,8 +207,8 @@ pub unsafe fn semihosting_syscall(nr: u32, arg: u32) -> u32 {
192207/// * The size of the stack provided here must be large enough for your
193208/// program - stack overflows are obviously UB. If your processor supports
194209/// it, you may wish to set the `PSPLIM` register to guard against this.
195- #[ cfg( cortex_m) ]
196210#[ inline( always) ]
211+ #[ cortex_m_macros:: asm_cfg( cortex_m) ]
197212pub unsafe fn enter_unprivileged_psp ( psp : * const u32 , entry : extern "C" fn ( ) -> !) -> ! {
198213 use crate :: register:: control:: { Control , Npriv , Spsel } ;
199214 const CONTROL_FLAGS : u32 = {
@@ -234,8 +249,8 @@ pub unsafe fn enter_unprivileged_psp(psp: *const u32, entry: extern "C" fn() ->
234249/// * The size of the stack provided here must be large enough for your
235250/// program - stack overflows are obviously UB. If your processor supports
236251/// it, you may wish to set the `PSPLIM` register to guard against this.
237- #[ cfg( cortex_m) ]
238252#[ inline( always) ]
253+ #[ cortex_m_macros:: asm_cfg( cortex_m) ]
239254pub unsafe fn enter_privileged_psp ( psp : * const u32 , entry : extern "C" fn ( ) -> !) -> ! {
240255 use crate :: register:: control:: { Control , Npriv , Spsel } ;
241256 const CONTROL_FLAGS : u32 = {
@@ -272,6 +287,7 @@ pub unsafe fn enter_privileged_psp(psp: *const u32, entry: extern "C" fn() -> !)
272287/// `msp` and `rv` must point to valid stack memory and executable code,
273288/// respectively.
274289#[ inline]
290+ #[ cortex_m_macros:: asm_cfg( cortex_m) ]
275291pub unsafe fn bootstrap ( msp : * const u32 , rv : * const u32 ) -> ! {
276292 // Ensure thumb mode is set.
277293 let rv = ( rv as u32 ) | 1 ;
@@ -292,6 +308,7 @@ pub unsafe fn bootstrap(msp: *const u32, rv: *const u32) -> ! {
292308/// table, with a valid stack pointer as the first word and
293309/// a valid reset vector as the second word.
294310#[ inline]
311+ #[ cortex_m_macros:: asm_cfg( cortex_m) ]
295312pub unsafe fn bootload ( vector_table : * const u32 ) -> ! {
296313 unsafe {
297314 let msp = core:: ptr:: read_volatile ( vector_table) ;
0 commit comments