aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--asm/inline.rs142
-rw-r--r--bin/thumbv6m-none-eabi-lto.abin13592 -> 14084 bytes
-rw-r--r--bin/thumbv6m-none-eabi.abin16124 -> 17048 bytes
-rw-r--r--bin/thumbv7em-none-eabi-lto.abin19224 -> 18308 bytes
-rw-r--r--bin/thumbv7em-none-eabi.abin20436 -> 21440 bytes
-rw-r--r--bin/thumbv7em-none-eabihf-lto.abin20180 -> 19280 bytes
-rw-r--r--bin/thumbv7em-none-eabihf.abin21552 -> 22524 bytes
-rw-r--r--bin/thumbv7m-none-eabi-lto.abin17628 -> 17076 bytes
-rw-r--r--bin/thumbv7m-none-eabi.abin19276 -> 20276 bytes
-rw-r--r--bin/thumbv8m.base-none-eabi-lto.abin15496 -> 16048 bytes
-rw-r--r--bin/thumbv8m.base-none-eabi.abin18352 -> 19256 bytes
-rw-r--r--bin/thumbv8m.main-none-eabi-lto.abin21228 -> 20764 bytes
-rw-r--r--bin/thumbv8m.main-none-eabi.abin23652 -> 24624 bytes
-rw-r--r--bin/thumbv8m.main-none-eabihf-lto.abin22168 -> 21744 bytes
-rw-r--r--bin/thumbv8m.main-none-eabihf.abin24704 -> 25672 bytes
15 files changed, 76 insertions, 66 deletions
diff --git a/asm/inline.rs b/asm/inline.rs
index 67e4925..67fa70e 100644
--- a/asm/inline.rs
+++ b/asm/inline.rs
@@ -6,6 +6,8 @@
//! All of these functions should be blanket-`unsafe`. `cortex-m` provides safe wrappers where
//! applicable.
+use core::sync::atomic::{Ordering, compiler_fence};
+
#[inline(always)]
pub unsafe fn __bkpt() {
asm!("bkpt");
@@ -20,45 +22,58 @@ pub unsafe fn __control_r() -> u32 {
#[inline(always)]
pub unsafe fn __control_w(w: u32) {
- asm!("msr CONTROL, {}", in(reg) w);
+ // ISB is required after writing to CONTROL,
+ // per ARM architectural requirements (see Application Note 321).
+ asm!("msr CONTROL, {}", "isb", in(reg) w);
+
+ // Ensure instructions are not reordered around the CONTROL update.
+ compiler_fence(Ordering::SeqCst);
}
#[inline(always)]
pub unsafe fn __cpsid() {
asm!("cpsid i");
+
+ // Ensure no subsequent instructions are reordered to before interrupts are disabled.
+ compiler_fence(Ordering::SeqCst);
}
#[inline(always)]
pub unsafe fn __cpsie() {
+ // Ensure no preceeding instructions are reordered to after interrupts are enabled.
+ compiler_fence(Ordering::SeqCst);
+
asm!("cpsie i");
}
#[inline(always)]
pub unsafe fn __delay(cyc: u32) {
- asm!("
- 1:
- nop
- subs {}, #1
- bne 1b
- // Branch to 1 instead of delay does not generate R_ARM_THM_JUMP8 relocation, which breaks
- // linking on the thumbv6m-none-eabi target
- ", in(reg) cyc);
+ // Use local labels to avoid R_ARM_THM_JUMP8 relocations which fail on thumbv6m.
+ asm!(
+ "1:",
+ "nop",
+ "subs {}, #1",
+ "bne 1b",
+ in(reg) cyc
+ );
}
-// FIXME do we need compiler fences here or should we expect them in the caller?
#[inline(always)]
pub unsafe fn __dmb() {
- asm!("dmb 0xF");
+ asm!("dmb");
+ compiler_fence(Ordering::AcqRel);
}
#[inline(always)]
pub unsafe fn __dsb() {
- asm!("dsb 0xF");
+ asm!("dsb");
+ compiler_fence(Ordering::SeqCst);
}
#[inline(always)]
pub unsafe fn __isb() {
- asm!("isb 0xF");
+ asm!("isb");
+ compiler_fence(Ordering::SeqCst);
}
#[inline(always)]
@@ -93,28 +108,28 @@ pub unsafe fn __nop() {
#[inline(always)]
pub unsafe fn __pc_r() -> u32 {
let r;
- asm!("mov {}, R15", out(reg) r);
+ asm!("mov {}, pc", out(reg) r);
r
}
// NOTE: No FFI shim, this requires inline asm.
#[inline(always)]
pub unsafe fn __pc_w(val: u32) {
- asm!("mov R15, {}", in(reg) val);
+ asm!("mov pc, {}", in(reg) val);
}
// NOTE: No FFI shim, this requires inline asm.
#[inline(always)]
pub unsafe fn __lr_r() -> u32 {
let r;
- asm!("mov {}, R14", out(reg) r);
+ asm!("mov {}, lr", out(reg) r);
r
}
// NOTE: No FFI shim, this requires inline asm.
#[inline(always)]
pub unsafe fn __lr_w(val: u32) {
- asm!("mov R14, {}", in(reg) val);
+ asm!("mov lr, {}", in(reg) val);
}
#[inline(always)]
@@ -161,6 +176,8 @@ pub unsafe fn __wfi() {
pub use self::v7m::*;
#[cfg(any(armv7m, armv8m_main))]
mod v7m {
+ use core::sync::atomic::{Ordering, compiler_fence};
+
#[inline(always)]
pub unsafe fn __basepri_max(val: u8) {
asm!("msr BASEPRI_MAX, {}", in(reg) val);
@@ -185,45 +202,42 @@ mod v7m {
r
}
- // FIXME: compiler_fences necessary?
#[inline(always)]
pub unsafe fn __enable_icache() {
asm!(
- "
- ldr r0, =0xE000ED14 @ CCR
- mrs r2, PRIMASK @ save critical nesting info
- cpsid i @ mask interrupts
- ldr r1, [r0] @ read CCR
- orr.w r1, r1, #(1 << 17) @ Set bit 17, IC
- str r1, [r0] @ write it back
- dsb @ ensure store completes
- isb @ synchronize pipeline
- msr PRIMASK, r2 @ unnest critical section
- ",
- out("r0") _,
- out("r1") _,
- out("r2") _,
+ "ldr {0}, =0xE000ED14", // CCR
+ "mrs {2}, PRIMASK", // save critical nesting info
+ "cpsid i", // mask interrupts
+ "ldr {1}, [{0}]", // read CCR
+ "orr.w {1}, {1}, #(1 << 17)", // Set bit 17, IC
+ "str {1}, [{0}]", // write it back
+ "dsb", // ensure store completes
+ "isb", // synchronize pipeline
+ "msr PRIMASK, {2}", // unnest critical section
+ out(reg) _,
+ out(reg) _,
+ out(reg) _,
);
+ compiler_fence(Ordering::SeqCst);
}
#[inline(always)]
pub unsafe fn __enable_dcache() {
asm!(
- "
- ldr r0, =0xE000ED14 @ CCR
- mrs r2, PRIMASK @ save critical nesting info
- cpsid i @ mask interrupts
- ldr r1, [r0] @ read CCR
- orr.w r1, r1, #(1 << 16) @ Set bit 16, DC
- str r1, [r0] @ write it back
- dsb @ ensure store completes
- isb @ synchronize pipeline
- msr PRIMASK, r2 @ unnest critical section
- ",
- out("r0") _,
- out("r1") _,
- out("r2") _,
+ "ldr {0}, =0xE000ED14", // CCR
+ "mrs {2}, PRIMASK", // save critical nesting info
+ "cpsid i", // mask interrupts
+ "ldr {1}, [{0}]", // read CCR
+ "orr.w {1}, {1}, #(1 << 16)", // Set bit 16, DC
+ "str {1}, [{0}]", // write it back
+ "dsb", // ensure store completes
+ "isb", // synchronize pipeline
+ "msr PRIMASK, {2}", // unnest critical section
+ out(reg) _,
+ out(reg) _,
+ out(reg) _,
);
+ compiler_fence(Ordering::SeqCst);
}
}
@@ -234,34 +248,30 @@ mod v7em {
#[inline(always)]
pub unsafe fn __basepri_max_cm7_r0p1(val: u8) {
asm!(
- "
- mrs r1, PRIMASK
- cpsid i
- tst.w r1, #1
- msr BASEPRI_MAX, {}
- it ne
- bxne lr
- cpsie i
- ",
+ "mrs {1}, PRIMASK",
+ "cpsid i",
+ "tst.w {1}, #1",
+ "msr BASEPRI_MAX, {0}",
+ "it ne",
+ "bxne lr",
+ "cpsie i",
in(reg) val,
- out("r1") _,
+ out(reg) _,
);
}
#[inline(always)]
pub unsafe fn __basepri_w_cm7_r0p1(val: u8) {
asm!(
- "
- mrs r1, PRIMASK
- cpsid i
- tst.w r1, #1
- msr BASEPRI, {}
- it ne
- bxne lr
- cpsie i
- ",
+ "mrs {1}, PRIMASK",
+ "cpsid i",
+ "tst.w {1}, #1",
+ "msr BASEPRI, {0}",
+ "it ne",
+ "bxne lr",
+ "cpsie i",
in(reg) val,
- out("r1") _,
+ out(reg) _,
);
}
}
diff --git a/bin/thumbv6m-none-eabi-lto.a b/bin/thumbv6m-none-eabi-lto.a
index 32667b1..fdc21d5 100644
--- a/bin/thumbv6m-none-eabi-lto.a
+++ b/bin/thumbv6m-none-eabi-lto.a
Binary files differ
diff --git a/bin/thumbv6m-none-eabi.a b/bin/thumbv6m-none-eabi.a
index 5c8c758..ca134d8 100644
--- a/bin/thumbv6m-none-eabi.a
+++ b/bin/thumbv6m-none-eabi.a
Binary files differ
diff --git a/bin/thumbv7em-none-eabi-lto.a b/bin/thumbv7em-none-eabi-lto.a
index c405e9e..bb598bd 100644
--- a/bin/thumbv7em-none-eabi-lto.a
+++ b/bin/thumbv7em-none-eabi-lto.a
Binary files differ
diff --git a/bin/thumbv7em-none-eabi.a b/bin/thumbv7em-none-eabi.a
index ec56934..8f31d50 100644
--- a/bin/thumbv7em-none-eabi.a
+++ b/bin/thumbv7em-none-eabi.a
Binary files differ
diff --git a/bin/thumbv7em-none-eabihf-lto.a b/bin/thumbv7em-none-eabihf-lto.a
index bd5ad83..55e9ef4 100644
--- a/bin/thumbv7em-none-eabihf-lto.a
+++ b/bin/thumbv7em-none-eabihf-lto.a
Binary files differ
diff --git a/bin/thumbv7em-none-eabihf.a b/bin/thumbv7em-none-eabihf.a
index 75a7e5d..a89a367 100644
--- a/bin/thumbv7em-none-eabihf.a
+++ b/bin/thumbv7em-none-eabihf.a
Binary files differ
diff --git a/bin/thumbv7m-none-eabi-lto.a b/bin/thumbv7m-none-eabi-lto.a
index a95b069..e679a55 100644
--- a/bin/thumbv7m-none-eabi-lto.a
+++ b/bin/thumbv7m-none-eabi-lto.a
Binary files differ
diff --git a/bin/thumbv7m-none-eabi.a b/bin/thumbv7m-none-eabi.a
index ae9db60..5b14804 100644
--- a/bin/thumbv7m-none-eabi.a
+++ b/bin/thumbv7m-none-eabi.a
Binary files differ
diff --git a/bin/thumbv8m.base-none-eabi-lto.a b/bin/thumbv8m.base-none-eabi-lto.a
index dd7553e..085482e 100644
--- a/bin/thumbv8m.base-none-eabi-lto.a
+++ b/bin/thumbv8m.base-none-eabi-lto.a
Binary files differ
diff --git a/bin/thumbv8m.base-none-eabi.a b/bin/thumbv8m.base-none-eabi.a
index e8bb7a6..82a6f5f 100644
--- a/bin/thumbv8m.base-none-eabi.a
+++ b/bin/thumbv8m.base-none-eabi.a
Binary files differ
diff --git a/bin/thumbv8m.main-none-eabi-lto.a b/bin/thumbv8m.main-none-eabi-lto.a
index 1f5b29d..694a7fa 100644
--- a/bin/thumbv8m.main-none-eabi-lto.a
+++ b/bin/thumbv8m.main-none-eabi-lto.a
Binary files differ
diff --git a/bin/thumbv8m.main-none-eabi.a b/bin/thumbv8m.main-none-eabi.a
index af9179a..ce0374c 100644
--- a/bin/thumbv8m.main-none-eabi.a
+++ b/bin/thumbv8m.main-none-eabi.a
Binary files differ
diff --git a/bin/thumbv8m.main-none-eabihf-lto.a b/bin/thumbv8m.main-none-eabihf-lto.a
index c243d5d..ae05ba0 100644
--- a/bin/thumbv8m.main-none-eabihf-lto.a
+++ b/bin/thumbv8m.main-none-eabihf-lto.a
Binary files differ
diff --git a/bin/thumbv8m.main-none-eabihf.a b/bin/thumbv8m.main-none-eabihf.a
index 3189a29..0efcaea 100644
--- a/bin/thumbv8m.main-none-eabihf.a
+++ b/bin/thumbv8m.main-none-eabihf.a
Binary files differ