Skip to content

Commit 530aae6

Browse files
committed
Move other uses of asm::inner to modules using them.
This removes the inner module entirely.
1 parent fc454e4 commit 530aae6

18 files changed

Lines changed: 215 additions & 58 deletions

File tree

cortex-m/src/asm.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ use core::arch::asm;
77
#[cfg(cortex_m)]
88
use core::sync::atomic::{Ordering, compiler_fence};
99

10-
pub mod inner;
11-
1210
/// Puts the processor in Debug state. Debuggers can pick this up as a "breakpoint".
1311
///
1412
/// **NOTE** calling `bkpt` when the processor is not connected to a debugger will cause an

cortex-m/src/interrupt.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
//! Interrupts
22
3+
use core::arch::asm;
4+
use core::sync::atomic::{Ordering, compiler_fence};
5+
36
pub use bare_metal::{CriticalSection, Mutex, Nr};
47

58
/// Trait for enums of external interrupt numbers.
@@ -35,7 +38,10 @@ unsafe impl<T: Nr + Copy> InterruptNumber for T {
3538
/// Disables all interrupts
3639
#[inline]
3740
pub fn disable() {
38-
unsafe { crate::asm::inner::__cpsid() };
41+
unsafe { asm!("cpsid i", options(nomem, nostack, preserves_flags)) };
42+
43+
// Ensure no subsequent memory accesses are reordered to before interrupts are disabled.
44+
compiler_fence(Ordering::SeqCst);
3945
}
4046

4147
/// Enables all the interrupts
@@ -44,8 +50,12 @@ pub fn disable() {
4450
///
4551
/// - Do not call this function inside an `interrupt::free` critical section
4652
#[inline]
53+
#[cortex_m_macros::asm_cfg(any(armv6m, armv7m, armv7em, armv8m))]
4754
pub unsafe fn enable() {
48-
unsafe { crate::asm::inner::__cpsie() };
55+
// Ensure no preceeding memory accesses are reordered to after interrupts are enabled.
56+
compiler_fence(Ordering::SeqCst);
57+
58+
unsafe { asm!("cpsie i", options(nomem, nostack, preserves_flags)) };
4959
}
5060

5161
/// Execute closure `f` in an interrupt-free context.

cortex-m/src/peripheral/scb.rs

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
//! System Control Block
22
3+
#[cfg(any(armv7m, armv8m))]
4+
use core::arch::asm;
35
use core::ptr;
6+
#[cfg(any(armv7m, armv8m))]
7+
use core::sync::atomic::{Ordering, compiler_fence};
48

59
use volatile_register::RW;
610

@@ -304,6 +308,7 @@ impl SCB {
304308
///
305309
/// This operation first invalidates the entire I-cache.
306310
#[inline]
311+
#[cortex_m_macros::asm_cfg(any(armv7m, armv7em, armv8m))]
307312
pub fn enable_icache(&mut self) {
308313
// Don't do anything if I-cache is already enabled
309314
if Self::icache_enabled() {
@@ -318,10 +323,25 @@ impl SCB {
318323

319324
// NOTE(unsafe): The asm routine manages exclusive access to the SCB
320325
// registers and applies the proper barriers; it is technically safe on
321-
// its own, and is only `unsafe` here because it's `extern "C"`.
326+
// its own, and is only `unsafe` here because it's asm.
322327
unsafe {
323-
crate::asm::inner::__enable_icache();
324-
}
328+
asm!(
329+
"ldr {0}, =0xE000ED14", // CCR
330+
"mrs {2}, PRIMASK", // save critical nesting info
331+
"cpsid i", // mask interrupts
332+
"ldr {1}, [{0}]", // read CCR
333+
"orr.w {1}, {1}, #(1 << 17)", // Set bit 17, IC
334+
"str {1}, [{0}]", // write it back
335+
"dsb", // ensure store completes
336+
"isb", // synchronize pipeline
337+
"msr PRIMASK, {2}", // unnest critical section
338+
out(reg) _,
339+
out(reg) _,
340+
out(reg) _,
341+
options(nostack),
342+
)
343+
};
344+
compiler_fence(Ordering::SeqCst);
325345
}
326346

327347
/// Disables I-cache if currently enabled.
@@ -360,6 +380,7 @@ impl SCB {
360380

361381
/// Invalidates the entire I-cache.
362382
#[inline]
383+
#[cortex_m_macros::asm_cfg(any(armv6m, armv7m, armv7em, armv8m))]
363384
pub fn invalidate_icache(&mut self) {
364385
// NOTE(unsafe): No races as all CBP registers are write-only and stateless
365386
let mut cbp = unsafe { CBP::new() };
@@ -376,6 +397,7 @@ impl SCB {
376397
/// This operation first invalidates the entire D-cache, ensuring it does
377398
/// not contain stale values before being enabled.
378399
#[inline]
400+
#[cortex_m_macros::asm_cfg(any(armv6m, armv7m, armv7em, armv8m))]
379401
pub fn enable_dcache(&mut self, cpuid: &mut CPUID) {
380402
// Don't do anything if D-cache is already enabled
381403
if Self::dcache_enabled() {
@@ -387,10 +409,26 @@ impl SCB {
387409

388410
// NOTE(unsafe): The asm routine manages exclusive access to the SCB
389411
// registers and applies the proper barriers; it is technically safe on
390-
// its own, and is only `unsafe` here because it's `extern "C"`.
412+
// its own, and is only `unsafe` here because it's asm.
391413
unsafe {
392-
crate::asm::inner::__enable_dcache();
393-
}
414+
asm!(
415+
// Should this be replaced with a register modify?
416+
"ldr {0}, =0xE000ED14", // CCR
417+
"mrs {2}, PRIMASK", // save critical nesting info
418+
"cpsid i", // mask interrupts
419+
"ldr {1}, [{0}]", // read CCR
420+
"orr.w {1}, {1}, #(1 << 16)", // Set bit 16, DC
421+
"str {1}, [{0}]", // write it back
422+
"dsb", // ensure store completes
423+
"isb", // synchronize pipeline
424+
"msr PRIMASK, {2}", // unnest critical section
425+
out(reg) _,
426+
out(reg) _,
427+
out(reg) _,
428+
options(nostack),
429+
)
430+
};
431+
compiler_fence(Ordering::SeqCst);
394432
}
395433

396434
/// Disables D-cache if currently enabled.
@@ -429,6 +467,7 @@ impl SCB {
429467
///
430468
/// It's used immediately before enabling the dcache, but not exported publicly.
431469
#[inline]
470+
#[cfg(cortex_m)]
432471
unsafe fn invalidate_dcache(&mut self, cpuid: &mut CPUID) {
433472
unsafe {
434473
// NOTE(unsafe): No races as all CBP registers are write-only and stateless

cortex-m/src/psp.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,7 @@ impl<const N: usize> core::default::Default for Stack<N> {
7979
/// In Unprivileged Mode, code can no longer perform privileged operations,
8080
/// such as disabling interrupts.
8181
///
82-
pub fn switch_to_unprivileged_psp(psp_stack: StackHandle, function: extern "C" fn() -> !) -> ! {
83-
let mut psp_stack = psp_stack;
82+
pub fn switch_to_unprivileged_psp(mut psp_stack: StackHandle, function: extern "C" fn() -> !) -> ! {
8483
// set the stack limit
8584
#[cfg(armv8m_main)]
8685
unsafe {
@@ -93,8 +92,7 @@ pub fn switch_to_unprivileged_psp(psp_stack: StackHandle, function: extern "C" f
9392
}
9493

9594
/// Switch to running on the Process Stack Pointer (PSP), but remain in privileged mode
96-
pub fn switch_to_privileged_psp(psp_stack: StackHandle, function: extern "C" fn() -> !) -> ! {
97-
let mut psp_stack = psp_stack;
95+
pub fn switch_to_privileged_psp(mut psp_stack: StackHandle, function: extern "C" fn() -> !) -> ! {
9896
// set the stack limit
9997
#[cfg(armv8m_main)]
10098
unsafe {

cortex-m/src/register/apsr.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
//! Application Program Status Register
22
3+
#[cfg(any(armv6m, armv7m, armv7em, armv8m))]
4+
use core::arch::asm;
5+
36
/// Application Program Status Register
47
#[derive(Clone, Copy, Debug)]
58
pub struct Apsr {
@@ -48,7 +51,9 @@ impl Apsr {
4851
///
4952
/// **NOTE** This function is available if `cortex-m` is built with the `"inline-asm"` feature.
5053
#[inline]
54+
#[cortex_m_macros::asm_cfg(any(armv6m, armv7m, armv7em, armv8m))]
5155
pub fn read() -> Apsr {
52-
let bits = unsafe { crate::asm::inner::__apsr_r() };
56+
let bits;
57+
unsafe { asm!("mrs {}, APSR", out(reg) bits, options(nomem, nostack, preserves_flags)) };
5358
Apsr { bits }
5459
}

cortex-m/src/register/basepri.rs

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,46 @@
11
//! Base Priority Mask Register
22
3+
#[cfg(any(armv7m, armv8m))]
4+
use core::arch::asm;
5+
36
/// Reads the CPU register
47
#[inline]
8+
#[cortex_m_macros::asm_cfg(any(armv7m, armv8m_main))]
59
pub fn read() -> u8 {
6-
unsafe { crate::asm::inner::__basepri_r() }
10+
let r;
11+
unsafe { asm!("mrs {}, BASEPRI", out(reg) r, options(nomem, nostack, preserves_flags)) };
12+
r
713
}
814

915
/// Writes to the CPU register
1016
///
1117
/// **IMPORTANT** If you are using a Cortex-M7 device with revision r0p1 you MUST enable the
1218
/// `cm7-r0p1` Cargo feature or this function WILL misbehave.
1319
#[inline]
20+
#[cortex_m_macros::asm_cfg(any(armv7m, armv8m_main))]
1421
pub unsafe fn write(basepri: u8) {
15-
#[cfg(feature = "cm7-r0p1")]
22+
#[cfg(not(feature = "cm7-r0p1"))]
1623
{
17-
unsafe { crate::asm::inner::__basepri_w_cm7_r0p1(basepri) }
24+
unsafe {
25+
asm!("msr BASEPRI, {}", in(reg) basepri, options(nomem, nostack, preserves_flags))
26+
};
1827
}
1928

20-
#[cfg(not(feature = "cm7-r0p1"))]
29+
#[cfg(feature = "cm7-r0p1")]
2130
{
22-
unsafe { crate::asm::inner::__basepri_w(basepri) }
31+
unsafe {
32+
asm!(
33+
"mrs {1}, PRIMASK",
34+
"cpsid i",
35+
"tst.w {1}, #1",
36+
"msr BASEPRI, {0}",
37+
"it ne",
38+
"bxne lr",
39+
"cpsie i",
40+
in(reg) basepri,
41+
out(reg) _,
42+
options(nomem, nostack, preserves_flags),
43+
)
44+
};
2345
}
2446
}
Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
//! Base Priority Mask Register (conditional write)
22
3+
#[cfg(any(armv7m, armv8m))]
4+
use core::arch::asm;
5+
36
/// Writes to BASEPRI *if*
47
///
58
/// - `basepri != 0` AND `basepri::read() == 0`, OR
@@ -8,14 +11,30 @@
811
/// **IMPORTANT** If you are using a Cortex-M7 device with revision r0p1 you MUST enable the
912
/// `cm7-r0p1` Cargo feature or this function WILL misbehave.
1013
#[inline]
14+
#[cortex_m_macros::asm_cfg(any(armv7m, armv8m_main))]
1115
pub fn write(basepri: u8) {
12-
#[cfg(feature = "cm7-r0p1")]
16+
#[cfg(not(feature = "cm7-r0p1"))]
1317
{
14-
unsafe { crate::asm::inner::__basepri_max_cm7_r0p1(basepri) }
18+
unsafe {
19+
asm!("msr BASEPRI_MAX, {}", in(reg) basepri, options(nomem, nostack, preserves_flags))
20+
};
1521
}
1622

17-
#[cfg(not(feature = "cm7-r0p1"))]
23+
#[cfg(feature = "cm7-r0p1")]
1824
{
19-
unsafe { crate::asm::inner::__basepri_max(basepri) }
25+
unsafe {
26+
asm!(
27+
"mrs {1}, PRIMASK",
28+
"cpsid i",
29+
"tst.w {1}, #1",
30+
"msr BASEPRI_MAX, {0}",
31+
"it ne",
32+
"bxne lr",
33+
"cpsie i",
34+
in(reg) basepri,
35+
out(reg) _,
36+
options(nomem, nostack, preserves_flags),
37+
)
38+
};
2039
}
2140
}

cortex-m/src/register/control.rs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
//! Control register
22
3+
#[cfg(any(armv6m, armv7m, armv7em, armv8m))]
4+
use core::arch::asm;
5+
#[cfg(any(armv6m, armv7m, armv7em, armv8m))]
6+
use core::sync::atomic::{Ordering, compiler_fence};
7+
38
/// Control register
49
#[derive(Clone, Copy, Debug)]
510
pub struct Control {
@@ -173,14 +178,28 @@ impl Fpca {
173178

174179
/// Reads the CPU register
175180
#[inline]
181+
#[cortex_m_macros::asm_cfg(any(armv6m, armv7m, armv7em, armv8m))]
176182
pub fn read() -> Control {
177-
let bits = unsafe { crate::asm::inner::__control_r() };
183+
let bits;
184+
unsafe { asm!("mrs {}, CONTROL", out(reg) bits, options(nomem, nostack, preserves_flags)) };
178185
Control { bits }
179186
}
180187

181188
/// Writes to the CPU register.
182189
#[inline]
190+
#[cortex_m_macros::asm_cfg(any(armv6m, armv7m, armv7em, armv8m))]
183191
pub unsafe fn write(control: Control) {
184192
let control = control.bits();
185-
unsafe { crate::asm::inner::__control_w(control) };
193+
194+
// ISB is required after writing to CONTROL,
195+
// per ARM architectural requirements (see Application Note 321).
196+
unsafe {
197+
asm!(
198+
"msr CONTROL, {}",
199+
"isb",
200+
in(reg) control,
201+
options(nomem, nostack, preserves_flags),
202+
);
203+
compiler_fence(Ordering::SeqCst);
204+
}
186205
}

cortex-m/src/register/faultmask.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
//! Fault Mask Register
22
3+
#[cfg(any(armv6m, armv7m, armv7em, armv8m))]
4+
use core::arch::asm;
5+
36
/// All exceptions are ...
47
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
58
pub enum Faultmask {
@@ -25,8 +28,10 @@ impl Faultmask {
2528

2629
/// Reads the CPU register
2730
#[inline]
31+
#[cortex_m_macros::asm_cfg(any(armv7m, armv8m_main))]
2832
pub fn read() -> Faultmask {
29-
let r = unsafe { crate::asm::inner::__faultmask_r() };
33+
let r: u32;
34+
unsafe { asm!("mrs {}, FAULTMASK", out(reg) r, options(nomem, nostack, preserves_flags)) };
3035
if r & (1 << 0) == (1 << 0) {
3136
Faultmask::Inactive
3237
} else {

cortex-m/src/register/fpscr.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
//! Floating-point Status Control Register
22
3+
#[cfg(has_fpu)]
4+
use core::arch::asm;
5+
36
/// Floating-point Status Control Register
47
#[derive(Clone, Copy, Debug)]
58
pub struct Fpscr {
@@ -292,14 +295,17 @@ impl RMode {
292295

293296
/// Read the FPSCR register
294297
#[inline]
298+
#[cfg(has_fpu)]
295299
pub fn read() -> Fpscr {
296-
let r = unsafe { crate::asm::inner::__fpscr_r() };
300+
let r;
301+
unsafe { asm!("vmrs {}, fpscr", out(reg) r, options(nomem, nostack, preserves_flags)) };
297302
Fpscr::from_bits(r)
298303
}
299304

300305
/// Set the value of the FPSCR register
301306
#[inline]
307+
#[cfg(has_fpu)]
302308
pub unsafe fn write(fpscr: Fpscr) {
303309
let fpscr = fpscr.bits();
304-
unsafe { crate::asm::inner::__fpscr_w(fpscr) };
310+
unsafe { asm!("vmsr fpscr, {}", in(reg) fpscr, options(nomem, nostack)) };
305311
}

0 commit comments

Comments
 (0)