55
66#![ allow( missing_docs) ]
77
8- #[ cfg_attr( any( armv6m, armv7m, armv7em, armv8m) , path = "asm/inner.rs" ) ]
9- #[ cfg_attr(
10- all( not( armv6m) , not( armv7m) , not( armv7em) , not( armv8m) ) ,
11- path = "asm/inner_mock.rs"
12- ) ]
8+ #[ cfg( any( armv6m, armv7m, armv7em, armv8m) ) ]
9+ use core:: arch:: asm;
10+
11+ // #[cfg_attr(any(armv6m, armv7m, armv7em, armv8m), path = "asm/inner.rs")]
12+ // #[cfg_attr(
13+ // all(not(armv6m), not(armv7m), not(armv7em), not(armv8m)),
14+ // path = "asm/inner_mock.rs"
15+ // )]
1316pub mod inner;
1417
1518/// Puts the processor in Debug state. Debuggers can pick this up as a "breakpoint".
1619///
1720/// **NOTE** calling `bkpt` when the processor is not connected to a debugger will cause an
1821/// exception.
1922#[ inline( always) ]
23+ #[ cortex_m_macros:: asm_wrapper( any( armv6m, armv7m, armv7em, armv8m) ) ]
2024pub fn bkpt ( ) {
21- unsafe { inner :: __bkpt ( ) } ;
25+ unsafe { asm ! ( "bkpt" , options ( nomem , nostack , preserves_flags ) ) } ;
2226}
2327
2428/// Blocks the program for *at least* `cycles` CPU cycles.
@@ -36,12 +40,14 @@ pub fn bkpt() {
3640/// initialization of peripherals if and only if accurate timing is not essential. In any other case
3741/// please use a more accurate method to produce a delay.
3842#[ inline]
43+ #[ cortex_m_macros:: asm_wrapper( any( armv6m, armv7m, armv7em, armv8m) ) ]
3944pub fn delay ( cycles : u32 ) {
4045 unsafe { inner:: __delay ( cycles) } ;
4146}
4247
4348/// A no-operation. Useful to prevent delay loops from being optimized away.
4449#[ inline]
50+ #[ cortex_m_macros:: asm_wrapper( any( armv6m, armv7m, armv7em, armv8m) ) ]
4551pub fn nop ( ) {
4652 unsafe { inner:: __nop ( ) } ;
4753}
@@ -50,24 +56,28 @@ pub fn nop() {
5056///
5157/// Can be used as a stable alternative to `core::intrinsics::abort`.
5258#[ inline]
59+ #[ cortex_m_macros:: asm_wrapper( any( armv6m, armv7m, armv7em, armv8m) ) ]
5360pub fn udf ( ) -> ! {
5461 unsafe { inner:: __udf ( ) }
5562}
5663
5764/// Wait For Event
5865#[ inline]
66+ #[ cortex_m_macros:: asm_wrapper( any( armv6m, armv7m, armv7em, armv8m) ) ]
5967pub fn wfe ( ) {
6068 unsafe { inner:: __wfe ( ) }
6169}
6270
6371/// Wait For Interrupt
6472#[ inline]
73+ #[ cortex_m_macros:: asm_wrapper( any( armv6m, armv7m, armv7em, armv8m) ) ]
6574pub fn wfi ( ) {
6675 unsafe { inner:: __wfi ( ) }
6776}
6877
6978/// Send Event
7079#[ inline]
80+ #[ cortex_m_macros:: asm_wrapper( any( armv6m, armv7m, armv7em, armv8m) ) ]
7181pub fn sev ( ) {
7282 unsafe { inner:: __sev ( ) }
7383}
@@ -77,6 +87,7 @@ pub fn sev() {
7787/// Flushes the pipeline in the processor, so that all instructions following the `ISB` are fetched
7888/// from cache or memory, after the instruction has been completed.
7989#[ inline]
90+ #[ cortex_m_macros:: asm_wrapper( any( armv6m, armv7m, armv7em, armv8m) ) ]
8091pub fn isb ( ) {
8192 unsafe { inner:: __isb ( ) }
8293}
@@ -89,6 +100,7 @@ pub fn isb() {
89100/// * any explicit memory access made before this instruction is complete
90101/// * all cache and branch predictor maintenance operations before this instruction complete
91102#[ inline]
103+ #[ cortex_m_macros:: asm_wrapper( any( armv6m, armv7m, armv7em, armv8m) ) ]
92104pub fn dsb ( ) {
93105 unsafe { inner:: __dsb ( ) }
94106}
@@ -99,6 +111,7 @@ pub fn dsb() {
99111/// instruction are observed before any explicit memory accesses that appear in program order
100112/// after the `DMB` instruction.
101113#[ inline]
114+ #[ cortex_m_macros:: asm_wrapper( any( armv6m, armv7m, armv7em, armv8m) ) ]
102115pub fn dmb ( ) {
103116 unsafe { inner:: __dmb ( ) }
104117}
@@ -109,7 +122,7 @@ pub fn dmb() {
109122/// Returns a Test Target Response Payload (cf section D1.2.215 of
110123/// Armv8-M Architecture Reference Manual).
111124#[ inline]
112- #[ cfg ( armv8m) ]
125+ #[ cortex_m_macros :: asm_wrapper ( armv8m) ]
113126// The __tt function does not dereference the pointer received.
114127#[ allow( clippy:: not_unsafe_ptr_arg_deref) ]
115128pub fn tt ( addr : * mut u32 ) -> u32 {
@@ -124,7 +137,7 @@ pub fn tt(addr: *mut u32) -> u32 {
124137/// Returns a Test Target Response Payload (cf section D1.2.215 of
125138/// Armv8-M Architecture Reference Manual).
126139#[ inline]
127- #[ cfg ( armv8m) ]
140+ #[ cortex_m_macros :: asm_wrapper ( armv8m) ]
128141// The __ttt function does not dereference the pointer received.
129142#[ allow( clippy:: not_unsafe_ptr_arg_deref) ]
130143pub fn ttt ( addr : * mut u32 ) -> u32 {
@@ -140,7 +153,7 @@ pub fn ttt(addr: *mut u32) -> u32 {
140153/// Returns a Test Target Response Payload (cf section D1.2.215 of
141154/// Armv8-M Architecture Reference Manual).
142155#[ inline]
143- #[ cfg ( armv8m) ]
156+ #[ cortex_m_macros :: asm_wrapper ( armv8m) ]
144157// The __tta function does not dereference the pointer received.
145158#[ allow( clippy:: not_unsafe_ptr_arg_deref) ]
146159pub fn tta ( addr : * mut u32 ) -> u32 {
@@ -156,7 +169,7 @@ pub fn tta(addr: *mut u32) -> u32 {
156169/// Returns a Test Target Response Payload (cf section D1.2.215 of
157170/// Armv8-M Architecture Reference Manual).
158171#[ inline]
159- #[ cfg ( armv8m) ]
172+ #[ cortex_m_macros :: asm_wrapper ( armv8m) ]
160173// The __ttat function does not dereference the pointer received.
161174#[ allow( clippy:: not_unsafe_ptr_arg_deref) ]
162175pub fn ttat ( addr : * mut u32 ) -> u32 {
@@ -169,7 +182,7 @@ pub fn ttat(addr: *mut u32) -> u32 {
169182/// See section C2.4.26 of Armv8-M Architecture Reference Manual for details.
170183/// Undefined if executed in Non-Secure state.
171184#[ inline]
172- #[ cfg ( armv8m) ]
185+ #[ cortex_m_macros :: asm_wrapper ( armv8m) ]
173186pub unsafe fn bx_ns ( addr : u32 ) {
174187 unsafe { crate :: asm:: inner:: __bxns ( addr) } ;
175188}
@@ -178,8 +191,13 @@ pub unsafe fn bx_ns(addr: u32) {
178191///
179192/// This method is used by cortex-m-semihosting to provide semihosting syscalls.
180193#[ inline]
194+ #[ cortex_m_macros:: asm_wrapper( any( armv6m, armv7m, armv7em, armv8m) ) ]
181195pub unsafe fn semihosting_syscall ( nr : u32 , arg : u32 ) -> u32 {
182- unsafe { inner:: __sh_syscall ( nr, arg) }
196+ let mut nr = nr;
197+ unsafe {
198+ asm ! ( "bkpt #0xab" , inout( "r0" ) nr, in( "r1" ) arg, options( nomem, nostack, preserves_flags) )
199+ } ;
200+ nr
183201}
184202
185203/// Switch to unprivileged mode using the Process Stack
@@ -198,8 +216,8 @@ pub unsafe fn semihosting_syscall(nr: u32, arg: u32) -> u32 {
198216/// * The size of the stack provided here must be large enough for your
199217/// program - stack overflows are obviously UB. If your processor supports
200218/// it, you may wish to set the `PSPLIM` register to guard against this.
201- #[ cfg( cortex_m) ]
202219#[ inline( always) ]
220+ #[ cortex_m_macros:: asm_wrapper( cortex_m) ]
203221pub unsafe fn enter_unprivileged_psp ( psp : * const u32 , entry : extern "C" fn ( ) -> !) -> ! {
204222 use crate :: register:: control:: { Control , Npriv , Spsel } ;
205223 const CONTROL_FLAGS : u32 = {
@@ -240,8 +258,8 @@ pub unsafe fn enter_unprivileged_psp(psp: *const u32, entry: extern "C" fn() ->
240258/// * The size of the stack provided here must be large enough for your
241259/// program - stack overflows are obviously UB. If your processor supports
242260/// it, you may wish to set the `PSPLIM` register to guard against this.
243- #[ cfg( cortex_m) ]
244261#[ inline( always) ]
262+ #[ cortex_m_macros:: asm_wrapper( cortex_m) ]
245263pub unsafe fn enter_privileged_psp ( psp : * const u32 , entry : extern "C" fn ( ) -> !) -> ! {
246264 use crate :: register:: control:: { Control , Npriv , Spsel } ;
247265 const CONTROL_FLAGS : u32 = {
@@ -278,6 +296,7 @@ pub unsafe fn enter_privileged_psp(psp: *const u32, entry: extern "C" fn() -> !)
278296/// `msp` and `rv` must point to valid stack memory and executable code,
279297/// respectively.
280298#[ inline]
299+ #[ cortex_m_macros:: asm_wrapper( any( armv6m, armv7m, armv7em, armv8m) ) ]
281300pub unsafe fn bootstrap ( msp : * const u32 , rv : * const u32 ) -> ! {
282301 // Ensure thumb mode is set.
283302 let rv = ( rv as u32 ) | 1 ;
@@ -298,6 +317,7 @@ pub unsafe fn bootstrap(msp: *const u32, rv: *const u32) -> ! {
298317/// table, with a valid stack pointer as the first word and
299318/// a valid reset vector as the second word.
300319#[ inline]
320+ #[ cortex_m_macros:: asm_wrapper( any( armv6m, armv7m, armv7em, armv8m) ) ]
301321pub unsafe fn bootload ( vector_table : * const u32 ) -> ! {
302322 unsafe {
303323 let msp = core:: ptr:: read_volatile ( vector_table) ;
0 commit comments