From dd72f11186f6a815db495ed41636879b7db9614f Mon Sep 17 00:00:00 2001 From: Robert Jördens Date: Thu, 16 Dec 2021 15:16:30 +0100 Subject: asm/inline: explicitly use asm macro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit removed from prelude in current nightly https://github.com/rust-lang/rust/pull/91728 close #371 Signed-off-by: Robert Jördens --- asm/inline.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/asm/inline.rs b/asm/inline.rs index 5887baf..1307499 100644 --- a/asm/inline.rs +++ b/asm/inline.rs @@ -7,6 +7,7 @@ //! applicable. use core::sync::atomic::{compiler_fence, Ordering}; +use core::arch::asm; #[inline(always)] pub unsafe fn __bkpt() { -- cgit v1.2.3 From 2bf12c62077cd5e533b5463256b3644e57a7c59d Mon Sep 17 00:00:00 2001 From: Robert Jördens Date: Thu, 16 Dec 2021 20:51:27 +0100 Subject: fmt [nfc] --- asm/inline.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asm/inline.rs b/asm/inline.rs index 1307499..dd61925 100644 --- a/asm/inline.rs +++ b/asm/inline.rs @@ -6,8 +6,8 @@ //! All of these functions should be blanket-`unsafe`. `cortex-m` provides safe wrappers where //! applicable. -use core::sync::atomic::{compiler_fence, Ordering}; use core::arch::asm; +use core::sync::atomic::{compiler_fence, Ordering}; #[inline(always)] pub unsafe fn __bkpt() { -- cgit v1.2.3 From fcc09857b3cd61466ff86a58c2b16759766783fb Mon Sep 17 00:00:00 2001 From: Robert Jördens Date: Thu, 16 Dec 2021 21:19:36 +0100 Subject: asm/inline: also use asm macro in mods --- asm/inline.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/asm/inline.rs b/asm/inline.rs index dd61925..1477103 100644 --- a/asm/inline.rs +++ b/asm/inline.rs @@ -215,6 +215,7 @@ pub unsafe fn __bootstrap(msp: u32, rv: u32) -> ! { pub use self::v7m::*; #[cfg(any(armv7m, armv8m_main))] mod v7m { + use core::arch::asm; use core::sync::atomic::{compiler_fence, Ordering}; #[inline(always)] @@ -284,6 +285,8 @@ mod v7m { pub use self::v7em::*; #[cfg(armv7em)] mod v7em { + use core::arch::asm; + #[inline(always)] pub unsafe fn __basepri_max_cm7_r0p1(val: u8) { asm!( @@ -320,6 +323,8 @@ pub use self::v8m::*; /// Baseline and Mainline. #[cfg(armv8m)] mod v8m { + use core::arch::asm; + #[inline(always)] pub unsafe fn __tt(mut target: u32) -> u32 { asm!("tt {target}, {target}", target = inout(reg) target); @@ -367,6 +372,8 @@ pub use self::v8m_main::*; /// Mainline only. #[cfg(armv8m_main)] mod v8m_main { + use core::arch::asm; + #[inline(always)] pub unsafe fn __msplim_r() -> u32 { let r; @@ -397,6 +404,8 @@ pub use self::fpu::*; /// All targets with FPU. #[cfg(has_fpu)] mod fpu { + use core::arch::asm; + #[inline(always)] pub unsafe fn __fpscr_r() -> u32 { let r; -- cgit v1.2.3 From 46a3320d11cade9c9a5f2a914fb5a5bcb53b31d3 Mon Sep 17 00:00:00 2001 From: Robert Jördens Date: Thu, 16 Dec 2021 21:25:42 +0100 Subject: asm: silence warning about asm being stable --- src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index a267750..0914639 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -76,6 +76,8 @@ // - A generated #[derive(Debug)] function (in which case the attribute needs // to be applied to the struct). #![deny(clippy::missing_inline_in_public_items)] +// Don't warn about feature(asm) being stable on Rust >= 1.59.0 +#![allow(stable_features)] extern crate bare_metal; extern crate volatile_register; -- cgit v1.2.3 From d40970c4172d89ebe72cbba79ca4b1b974ba6000 Mon Sep 17 00:00:00 2001 From: Robert Jördens Date: Fri, 17 Dec 2021 08:22:06 +0100 Subject: bump asm-toolchain --- asm-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asm-toolchain b/asm-toolchain index a36829b..cc5dbb2 100644 --- a/asm-toolchain +++ b/asm-toolchain @@ -1 +1 @@ -nightly-2020-08-26 +nightly-2021-12-16 -- cgit v1.2.3 From 981ce3a8fbf44a9f7a5b046de501c645b4c2098a Mon Sep 17 00:00:00 2001 From: Robert Jördens Date: Fri, 17 Dec 2021 08:31:02 +0100 Subject: asm: allow stable asm --- asm/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/asm/lib.rs b/asm/lib.rs index fc8ddc8..48f3dc2 100644 --- a/asm/lib.rs +++ b/asm/lib.rs @@ -34,6 +34,8 @@ #![no_std] #![crate_type = "staticlib"] #![deny(warnings)] +// Don't warn about feature(asm) being stable on Rust >= 1.59.0 +#![allow(stable_features)] mod inline; -- cgit v1.2.3 From 587bf1dbb01f296f08d6624d72186043bfaaa96b Mon Sep 17 00:00:00 2001 From: Robert Jördens Date: Fri, 17 Dec 2021 12:59:33 +0100 Subject: bkpt: nostack --- asm/inline.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asm/inline.rs b/asm/inline.rs index 1477103..89c5cba 100644 --- a/asm/inline.rs +++ b/asm/inline.rs @@ -11,7 +11,7 @@ use core::sync::atomic::{compiler_fence, Ordering}; #[inline(always)] pub unsafe fn __bkpt() { - asm!("bkpt"); + asm!("bkpt", options(nostack)); } #[inline(always)] -- cgit v1.2.3 From 7e1548f2d7c5c26ba898cceadbde9a7dd2949ab2 Mon Sep 17 00:00:00 2001 From: Adam Greig Date: Fri, 17 Dec 2021 12:05:33 +0000 Subject: Add nomem, nostack and preserves_flags options to appropriate asm calls. --- asm/inline.rs | 114 ++++++++++++++++++++++-------------- bin/thumbv6m-none-eabi-lto.a | Bin 11788 -> 11196 bytes bin/thumbv6m-none-eabi.a | Bin 16344 -> 14576 bytes bin/thumbv7em-none-eabi-lto.a | Bin 15928 -> 15280 bytes bin/thumbv7em-none-eabi.a | Bin 21532 -> 19336 bytes bin/thumbv7em-none-eabihf-lto.a | Bin 16892 -> 16104 bytes bin/thumbv7em-none-eabihf.a | Bin 22828 -> 20480 bytes bin/thumbv7m-none-eabi-lto.a | Bin 14908 -> 14244 bytes bin/thumbv7m-none-eabi.a | Bin 20184 -> 18068 bytes bin/thumbv8m.base-none-eabi-lto.a | Bin 15056 -> 14280 bytes bin/thumbv8m.base-none-eabi.a | Bin 20772 -> 18680 bytes bin/thumbv8m.main-none-eabi-lto.a | Bin 19552 -> 18672 bytes bin/thumbv8m.main-none-eabi.a | Bin 27136 -> 24408 bytes bin/thumbv8m.main-none-eabihf-lto.a | Bin 20528 -> 19508 bytes bin/thumbv8m.main-none-eabihf.a | Bin 28404 -> 25524 bytes 15 files changed, 71 insertions(+), 43 deletions(-) diff --git a/asm/inline.rs b/asm/inline.rs index 89c5cba..bbc04d2 100644 --- a/asm/inline.rs +++ b/asm/inline.rs @@ -11,13 +11,13 @@ use core::sync::atomic::{compiler_fence, Ordering}; #[inline(always)] pub unsafe fn __bkpt() { - asm!("bkpt", options(nostack)); + asm!("bkpt", options(nomem, nostack, preserves_flags)); } #[inline(always)] pub unsafe fn __control_r() -> u32 { let r; - asm!("mrs {}, CONTROL", out(reg) r); + asm!("mrs {}, CONTROL", out(reg) r, options(nomem, nostack, preserves_flags)); r } @@ -28,7 +28,8 @@ pub unsafe fn __control_w(w: u32) { asm!( "msr CONTROL, {}", "isb", - in(reg) w + in(reg) w, + options(nomem, nostack, preserves_flags), ); // Ensure memory accesses are not reordered around the CONTROL update. @@ -37,7 +38,7 @@ pub unsafe fn __control_w(w: u32) { #[inline(always)] pub unsafe fn __cpsid() { - asm!("cpsid i"); + asm!("cpsid i", options(nomem, nostack, preserves_flags)); // Ensure no subsequent memory accesses are reordered to before interrupts are disabled. compiler_fence(Ordering::SeqCst); @@ -48,7 +49,7 @@ pub unsafe fn __cpsie() { // Ensure no preceeding memory accesses are reordered to after interrupts are enabled. compiler_fence(Ordering::SeqCst); - asm!("cpsie i"); + asm!("cpsie i", options(nomem, nostack, preserves_flags)); } #[inline(always)] @@ -63,48 +64,53 @@ pub unsafe fn __delay(cyc: u32) { "1:", "subs {}, #1", "bne 1b", - inout(reg) real_cyc => _ + inout(reg) real_cyc => _, + options(nomem, nostack), ); } #[inline(always)] pub unsafe fn __dmb() { compiler_fence(Ordering::SeqCst); - asm!("dmb"); + asm!("dmb", options(nomem, nostack, preserves_flags)); compiler_fence(Ordering::SeqCst); } #[inline(always)] pub unsafe fn __dsb() { compiler_fence(Ordering::SeqCst); - asm!("dsb"); + asm!("dsb", options(nomem, nostack, preserves_flags)); compiler_fence(Ordering::SeqCst); } #[inline(always)] pub unsafe fn __isb() { compiler_fence(Ordering::SeqCst); - asm!("isb"); + asm!("isb", options(nomem, nostack, preserves_flags)); compiler_fence(Ordering::SeqCst); } #[inline(always)] pub unsafe fn __msp_r() -> u32 { let r; - asm!("mrs {}, MSP", out(reg) r); + asm!("mrs {}, MSP", out(reg) r, options(nomem, nostack, preserves_flags)); r } #[inline(always)] pub unsafe fn __msp_w(val: u32) { - asm!("msr MSP, {}", in(reg) val); + // Technically is writing to the stack pointer "not pushing any data to the stack"? + // In any event, if we don't set `nostack` here, this method is useless as the new + // stack value is immediately mutated by returning. Really this is just not a good + // method and its higher-level use is marked as deprecated in cortex-m. + asm!("msr MSP, {}", in(reg) val, options(nomem, nostack, preserves_flags)); } // NOTE: No FFI shim, this requires inline asm. #[inline(always)] pub unsafe fn __apsr_r() -> u32 { let r; - asm!("mrs {}, APSR", out(reg) r); + asm!("mrs {}, APSR", out(reg) r, options(nomem, nostack, preserves_flags)); r } @@ -113,80 +119,82 @@ pub unsafe 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 // nops when they call `nop` N times, let's not add that option. - asm!("nop"); + asm!("nop", options(nomem, nostack, preserves_flags)); } // NOTE: No FFI shim, this requires inline asm. #[inline(always)] pub unsafe fn __pc_r() -> u32 { let r; - asm!("mov {}, pc", out(reg) r); + asm!("mov {}, pc", out(reg) r, options(nomem, nostack, preserves_flags)); r } // NOTE: No FFI shim, this requires inline asm. #[inline(always)] pub unsafe fn __pc_w(val: u32) { - asm!("mov pc, {}", in(reg) val); + asm!("mov pc, {}", in(reg) val, options(nomem, nostack, preserves_flags)); } // NOTE: No FFI shim, this requires inline asm. #[inline(always)] pub unsafe fn __lr_r() -> u32 { let r; - asm!("mov {}, lr", out(reg) r); + asm!("mov {}, lr", out(reg) r, options(nomem, nostack, preserves_flags)); r } // NOTE: No FFI shim, this requires inline asm. #[inline(always)] pub unsafe fn __lr_w(val: u32) { - asm!("mov lr, {}", in(reg) val); + asm!("mov lr, {}", in(reg) val, options(nomem, nostack, preserves_flags)); } #[inline(always)] pub unsafe fn __primask_r() -> u32 { let r; - asm!("mrs {}, PRIMASK", out(reg) r); + asm!("mrs {}, PRIMASK", out(reg) r, options(nomem, nostack, preserves_flags)); r } #[inline(always)] pub unsafe fn __psp_r() -> u32 { let r; - asm!("mrs {}, PSP", out(reg) r); + asm!("mrs {}, PSP", out(reg) r, options(nomem, nostack, preserves_flags)); r } #[inline(always)] pub unsafe fn __psp_w(val: u32) { - asm!("msr PSP, {}", in(reg) val); + // See comment on __msp_w. Unlike MSP, there are legitimate use-cases for modifying PSP + // if MSP is currently being used as the stack pointer. + asm!("msr PSP, {}", in(reg) val, options(nomem, nostack, preserves_flags)); } #[inline(always)] pub unsafe fn __sev() { - asm!("sev"); + asm!("sev", options(nomem, nostack, preserves_flags)); } #[inline(always)] pub unsafe fn __udf() -> ! { - asm!("udf #0", options(noreturn)); + asm!("udf #0", options(noreturn, nomem, nostack, preserves_flags)); } #[inline(always)] pub unsafe fn __wfe() { - asm!("wfe"); + asm!("wfe", options(nomem, nostack, preserves_flags)); } #[inline(always)] pub unsafe fn __wfi() { - asm!("wfi"); + asm!("wfi", options(nomem, nostack, preserves_flags)); } /// Semihosting syscall. #[inline(always)] pub unsafe fn __sh_syscall(mut nr: u32, arg: u32) -> u32 { - asm!("bkpt #0xab", inout("r0") nr, in("r1") arg); + asm!("bkpt #0xab", inout("r0") nr, in("r1") arg, options(nomem, nostack, preserves_flags)); nr } @@ -206,7 +214,7 @@ pub unsafe fn __bootstrap(msp: u32, rv: u32) -> ! { spsel = in(reg) 2, msp = in(reg) msp, rv = in(reg) rv, - options(noreturn), + options(noreturn, nomem, nostack), ); } @@ -220,25 +228,25 @@ mod v7m { #[inline(always)] pub unsafe fn __basepri_max(val: u8) { - asm!("msr BASEPRI_MAX, {}", in(reg) val); + asm!("msr BASEPRI_MAX, {}", in(reg) val, options(nomem, nostack, preserves_flags)); } #[inline(always)] pub unsafe fn __basepri_r() -> u8 { let r; - asm!("mrs {}, BASEPRI", out(reg) r); + asm!("mrs {}, BASEPRI", out(reg) r, options(nomem, nostack, preserves_flags)); r } #[inline(always)] pub unsafe fn __basepri_w(val: u8) { - asm!("msr BASEPRI, {}", in(reg) val); + asm!("msr BASEPRI, {}", in(reg) val, options(nomem, nostack, preserves_flags)); } #[inline(always)] pub unsafe fn __faultmask_r() -> u32 { let r; - asm!("mrs {}, FAULTMASK", out(reg) r); + asm!("mrs {}, FAULTMASK", out(reg) r, options(nomem, nostack, preserves_flags)); r } @@ -257,6 +265,7 @@ mod v7m { out(reg) _, out(reg) _, out(reg) _, + options(nostack), ); compiler_fence(Ordering::SeqCst); } @@ -276,6 +285,7 @@ mod v7m { out(reg) _, out(reg) _, out(reg) _, + options(nostack), ); compiler_fence(Ordering::SeqCst); } @@ -299,6 +309,7 @@ mod v7em { "cpsie i", in(reg) val, out(reg) _, + options(nomem, nostack, preserves_flags), ); } @@ -314,6 +325,7 @@ mod v7em { "cpsie i", in(reg) val, out(reg) _, + options(nomem, nostack, preserves_flags), ); } } @@ -327,43 +339,59 @@ mod v8m { #[inline(always)] pub unsafe fn __tt(mut target: u32) -> u32 { - asm!("tt {target}, {target}", target = inout(reg) target); + asm!( + "tt {target}, {target}", + target = inout(reg) target, + options(nomem, nostack, preserves_flags), + ); target } #[inline(always)] pub unsafe fn __ttt(mut target: u32) -> u32 { - asm!("ttt {target}, {target}", target = inout(reg) target); + asm!( + "ttt {target}, {target}", + target = inout(reg) target, + options(nomem, nostack, preserves_flags), + ); target } #[inline(always)] pub unsafe fn __tta(mut target: u32) -> u32 { - asm!("tta {target}, {target}", target = inout(reg) target); + asm!( + "tta {target}, {target}", + target = inout(reg) target, + options(nomem, nostack, preserves_flags), + ); target } #[inline(always)] pub unsafe fn __ttat(mut target: u32) -> u32 { - asm!("ttat {target}, {target}", target = inout(reg) target); + asm!( + "ttat {target}, {target}", + target = inout(reg) target, + options(nomem, nostack, preserves_flags), + ); target } #[inline(always)] pub unsafe fn __msp_ns_r() -> u32 { let r; - asm!("mrs {}, MSP_NS", out(reg) r); + asm!("mrs {}, MSP_NS", out(reg) r, options(nomem, nostack, preserves_flags)); r } #[inline(always)] pub unsafe fn __msp_ns_w(val: u32) { - asm!("msr MSP_NS, {}", in(reg) val); + asm!("msr MSP_NS, {}", in(reg) val, options(nomem, nostack, preserves_flags)); } #[inline(always)] pub unsafe fn __bxns(val: u32) { - asm!("BXNS {}", in(reg) val); + asm!("BXNS {}", in(reg) val, options(nomem, nostack, preserves_flags)); } } @@ -377,25 +405,25 @@ mod v8m_main { #[inline(always)] pub unsafe fn __msplim_r() -> u32 { let r; - asm!("mrs {}, MSPLIM", out(reg) r); + asm!("mrs {}, MSPLIM", out(reg) r, options(nomem, nostack, preserves_flags)); r } #[inline(always)] pub unsafe fn __msplim_w(val: u32) { - asm!("msr MSPLIM, {}", in(reg) val); + asm!("msr MSPLIM, {}", in(reg) val, options(nomem, nostack, preserves_flags)); } #[inline(always)] pub unsafe fn __psplim_r() -> u32 { let r; - asm!("mrs {}, PSPLIM", out(reg) r); + asm!("mrs {}, PSPLIM", out(reg) r, options(nomem, nostack, preserves_flags)); r } #[inline(always)] pub unsafe fn __psplim_w(val: u32) { - asm!("msr PSPLIM, {}", in(reg) val); + asm!("msr PSPLIM, {}", in(reg) val, options(nomem, nostack, preserves_flags)); } } @@ -409,12 +437,12 @@ mod fpu { #[inline(always)] pub unsafe fn __fpscr_r() -> u32 { let r; - asm!("vmrs {}, fpscr", out(reg) r); + asm!("vmrs {}, fpscr", out(reg) r, options(nomem, nostack, preserves_flags)); r } #[inline(always)] pub unsafe fn __fpscr_w(val: u32) { - asm!("vmsr fpscr, {}", in(reg) val); + asm!("vmsr fpscr, {}", in(reg) val, options(nomem, nostack)); } } diff --git a/bin/thumbv6m-none-eabi-lto.a b/bin/thumbv6m-none-eabi-lto.a index 6136ec6..a203d7a 100644 Binary files a/bin/thumbv6m-none-eabi-lto.a and b/bin/thumbv6m-none-eabi-lto.a differ diff --git a/bin/thumbv6m-none-eabi.a b/bin/thumbv6m-none-eabi.a index c42f579..9640a69 100644 Binary files a/bin/thumbv6m-none-eabi.a and b/bin/thumbv6m-none-eabi.a differ diff --git a/bin/thumbv7em-none-eabi-lto.a b/bin/thumbv7em-none-eabi-lto.a index c2c040a..b34ac64 100644 Binary files a/bin/thumbv7em-none-eabi-lto.a and b/bin/thumbv7em-none-eabi-lto.a differ diff --git a/bin/thumbv7em-none-eabi.a b/bin/thumbv7em-none-eabi.a index 660360f..88acbdd 100644 Binary files a/bin/thumbv7em-none-eabi.a and b/bin/thumbv7em-none-eabi.a differ diff --git a/bin/thumbv7em-none-eabihf-lto.a b/bin/thumbv7em-none-eabihf-lto.a index eba1984..6de94bb 100644 Binary files a/bin/thumbv7em-none-eabihf-lto.a and b/bin/thumbv7em-none-eabihf-lto.a differ diff --git a/bin/thumbv7em-none-eabihf.a b/bin/thumbv7em-none-eabihf.a index 1561fa4..cf91a7a 100644 Binary files a/bin/thumbv7em-none-eabihf.a and b/bin/thumbv7em-none-eabihf.a differ diff --git a/bin/thumbv7m-none-eabi-lto.a b/bin/thumbv7m-none-eabi-lto.a index d964314..7f677a9 100644 Binary files a/bin/thumbv7m-none-eabi-lto.a and b/bin/thumbv7m-none-eabi-lto.a differ diff --git a/bin/thumbv7m-none-eabi.a b/bin/thumbv7m-none-eabi.a index f541274..ff4bf21 100644 Binary files a/bin/thumbv7m-none-eabi.a and b/bin/thumbv7m-none-eabi.a differ diff --git a/bin/thumbv8m.base-none-eabi-lto.a b/bin/thumbv8m.base-none-eabi-lto.a index 8a6ed42..f62acaf 100644 Binary files a/bin/thumbv8m.base-none-eabi-lto.a and b/bin/thumbv8m.base-none-eabi-lto.a differ diff --git a/bin/thumbv8m.base-none-eabi.a b/bin/thumbv8m.base-none-eabi.a index 33cd908..c0cc96c 100644 Binary files a/bin/thumbv8m.base-none-eabi.a and b/bin/thumbv8m.base-none-eabi.a differ diff --git a/bin/thumbv8m.main-none-eabi-lto.a b/bin/thumbv8m.main-none-eabi-lto.a index 8e6ff0a..1a51515 100644 Binary files a/bin/thumbv8m.main-none-eabi-lto.a and b/bin/thumbv8m.main-none-eabi-lto.a differ diff --git a/bin/thumbv8m.main-none-eabi.a b/bin/thumbv8m.main-none-eabi.a index 898fea7..d017a15 100644 Binary files a/bin/thumbv8m.main-none-eabi.a and b/bin/thumbv8m.main-none-eabi.a differ diff --git a/bin/thumbv8m.main-none-eabihf-lto.a b/bin/thumbv8m.main-none-eabihf-lto.a index d9a636a..fd3dc92 100644 Binary files a/bin/thumbv8m.main-none-eabihf-lto.a and b/bin/thumbv8m.main-none-eabihf-lto.a differ diff --git a/bin/thumbv8m.main-none-eabihf.a b/bin/thumbv8m.main-none-eabihf.a index b0513b7..223ff1d 100644 Binary files a/bin/thumbv8m.main-none-eabihf.a and b/bin/thumbv8m.main-none-eabihf.a differ -- cgit v1.2.3