aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Adam Greig <adam@adamgreig.com> 2022-02-25 01:19:34 +0000
committerGravatar Adam Greig <adam@adamgreig.com> 2022-02-25 01:21:05 +0000
commit3e8a5beec5f96a3c219b840dc26df34f76e4ab1e (patch)
tree45cfb08fca76efcce333a7f89cb28f32eea8fab9
parentf2feeb2595fe8f281a50d63055c65d6ac064ae11 (diff)
downloadcortex-m-3e8a5beec5f96a3c219b840dc26df34f76e4ab1e.tar.gz
cortex-m-3e8a5beec5f96a3c219b840dc26df34f76e4ab1e.tar.zst
cortex-m-3e8a5beec5f96a3c219b840dc26df34f76e4ab1e.zip
Fix cortex-m-rt qemu test by removing 'nomem' from semihosting_syscall asm, add inline to most cortex_m::asm methods
-rw-r--r--cortex-m-rt/examples/qemu.rs30
-rw-r--r--cortex-m-rt/link.x.in2
-rw-r--r--cortex-m-rt/src/lib.rs2
-rw-r--r--cortex-m-semihosting/src/lib.rs13
-rw-r--r--src/asm.rs30
-rw-r--r--src/peripheral/mod.rs2
6 files changed, 33 insertions, 46 deletions
diff --git a/cortex-m-rt/examples/qemu.rs b/cortex-m-rt/examples/qemu.rs
index e903404..a8ffd20 100644
--- a/cortex-m-rt/examples/qemu.rs
+++ b/cortex-m-rt/examples/qemu.rs
@@ -1,28 +1,24 @@
-// #![feature(stdsimd)]
#![no_main]
#![no_std]
-extern crate cortex_m;
-extern crate cortex_m_rt as rt;
-extern crate cortex_m_semihosting as semihosting;
+use core::fmt::Write;
-extern crate panic_halt;
-
-use cortex_m::asm;
-use rt::entry;
-
-#[entry]
+#[cortex_m_rt::entry]
fn main() -> ! {
- use core::fmt::Write;
let x = 42;
loop {
- asm::nop();
-
- // write something through semihosting interface
- let mut hstdout = semihosting::hio::hstdout().unwrap();
+ let mut hstdout = cortex_m_semihosting::hio::hstdout().unwrap();
write!(hstdout, "x = {}\n", x).unwrap();
- // exit from qemu
- semihosting::debug::exit(semihosting::debug::EXIT_SUCCESS);
+ cortex_m_semihosting::debug::exit(cortex_m_semihosting::debug::EXIT_SUCCESS);
+ }
+}
+
+// Define a panic handler that uses semihosting to exit immediately,
+// so that any panics cause qemu to quit instead of hang.
+#[panic_handler]
+fn panic(_: &core::panic::PanicInfo) -> ! {
+ loop {
+ cortex_m_semihosting::debug::exit(cortex_m_semihosting::debug::EXIT_FAILURE);
}
}
diff --git a/cortex-m-rt/link.x.in b/cortex-m-rt/link.x.in
index 92004b7..deff376 100644
--- a/cortex-m-rt/link.x.in
+++ b/cortex-m-rt/link.x.in
@@ -66,6 +66,8 @@ SECTIONS
/* ### Vector table */
.vector_table ORIGIN(FLASH) :
{
+ __vector_table = .;
+
/* Initial Stack Pointer (SP) value */
LONG(_stack_start);
diff --git a/cortex-m-rt/src/lib.rs b/cortex-m-rt/src/lib.rs
index 793b928..1e977c6 100644
--- a/cortex-m-rt/src/lib.rs
+++ b/cortex-m-rt/src/lib.rs
@@ -439,9 +439,9 @@
extern crate cortex_m_rt_macros as macros;
-use core::fmt;
#[cfg(cortex_m)]
use core::arch::global_asm;
+use core::fmt;
// HardFault exceptions are bounced through this trampoline which grabs the stack pointer at
// the time of the exception and passes it to th euser's HardFault handler in r0.
diff --git a/cortex-m-semihosting/src/lib.rs b/cortex-m-semihosting/src/lib.rs
index 4ff975d..186e7e7 100644
--- a/cortex-m-semihosting/src/lib.rs
+++ b/cortex-m-semihosting/src/lib.rs
@@ -194,20 +194,9 @@ pub unsafe fn syscall<T>(nr: usize, arg: &T) -> usize {
pub unsafe fn syscall1(_nr: usize, _arg: usize) -> usize {
match () {
#[cfg(all(thumb, not(feature = "no-semihosting")))]
- () => {
- let mut nr = _nr;
- core::arch::asm!(
- "bkpt #0xab",
- inout("r0") nr,
- in("r1") _arg,
- options(nomem, nostack, preserves_flags)
- );
- nr
- }
-
+ () => cortex_m::asm::semihosting_syscall(_nr as u32, _arg as u32) as usize,
#[cfg(all(thumb, feature = "no-semihosting"))]
() => 0,
-
#[cfg(not(thumb))]
() => unimplemented!(),
}
diff --git a/src/asm.rs b/src/asm.rs
index 0434b5f..3a3485a 100644
--- a/src/asm.rs
+++ b/src/asm.rs
@@ -44,7 +44,7 @@ pub fn delay(cycles: u32) {
}
/// A no-operation. Useful to prevent delay loops from being optimized away.
-#[inline]
+#[inline(always)]
pub 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
@@ -59,28 +59,28 @@ pub fn nop() {
///
/// Can be used as a stable alternative to `core::intrinsics::abort`.
#[cfg(cortex_m)]
-#[inline]
+#[inline(always)]
pub fn udf() -> ! {
unsafe { asm!("udf #0", options(noreturn, nomem, nostack, preserves_flags)) };
}
/// Wait For Event
#[cfg(cortex_m)]
-#[inline]
+#[inline(always)]
pub fn wfe() {
unsafe { asm!("wfe", options(nomem, nostack, preserves_flags)) };
}
/// Wait For Interrupt
#[cfg(cortex_m)]
-#[inline]
+#[inline(always)]
pub fn wfi() {
unsafe { asm!("wfi", options(nomem, nostack, preserves_flags)) };
}
/// Send Event
#[cfg(cortex_m)]
-#[inline]
+#[inline(always)]
pub fn sev() {
unsafe { asm!("sev", options(nomem, nostack, preserves_flags)) };
}
@@ -89,7 +89,7 @@ pub fn sev() {
///
/// Flushes the pipeline in the processor, so that all instructions following the `ISB` are fetched
/// from cache or memory, after the instruction has been completed.
-#[inline]
+#[inline(always)]
pub fn isb() {
compiler_fence(Ordering::SeqCst);
#[cfg(cortex_m)]
@@ -106,7 +106,7 @@ pub fn isb() {
///
/// * any explicit memory access made before this instruction is complete
/// * all cache and branch predictor maintenance operations before this instruction complete
-#[inline]
+#[inline(always)]
pub fn dsb() {
compiler_fence(Ordering::SeqCst);
#[cfg(cortex_m)]
@@ -121,7 +121,7 @@ pub fn dsb() {
/// Ensures that all explicit memory accesses that appear in program order before the `DMB`
/// instruction are observed before any explicit memory accesses that appear in program order
/// after the `DMB` instruction.
-#[inline]
+#[inline(always)]
pub fn dmb() {
compiler_fence(Ordering::SeqCst);
#[cfg(cortex_m)]
@@ -136,7 +136,7 @@ pub fn dmb() {
/// Queries the Security state and access permissions of a memory location.
/// Returns a Test Target Response Payload (cf section D1.2.215 of
/// Armv8-M Architecture Reference Manual).
-#[inline]
+#[inline(always)]
#[cfg(armv8m)]
// The __tt function does not dereference the pointer received.
#[allow(clippy::not_unsafe_ptr_arg_deref)]
@@ -158,7 +158,7 @@ pub fn tt(addr: *mut u32) -> u32 {
/// access to that location.
/// Returns a Test Target Response Payload (cf section D1.2.215 of
/// Armv8-M Architecture Reference Manual).
-#[inline]
+#[inline(always)]
#[cfg(armv8m)]
// The __ttt function does not dereference the pointer received.
#[allow(clippy::not_unsafe_ptr_arg_deref)]
@@ -181,7 +181,7 @@ pub fn ttt(addr: *mut u32) -> u32 {
/// undefined if used from Non-Secure state.
/// Returns a Test Target Response Payload (cf section D1.2.215 of
/// Armv8-M Architecture Reference Manual).
-#[inline]
+#[inline(always)]
#[cfg(armv8m)]
// The __tta function does not dereference the pointer received.
#[allow(clippy::not_unsafe_ptr_arg_deref)]
@@ -204,7 +204,7 @@ pub fn tta(addr: *mut u32) -> u32 {
/// state and is undefined if used from Non-Secure state.
/// Returns a Test Target Response Payload (cf section D1.2.215 of
/// Armv8-M Architecture Reference Manual).
-#[inline]
+#[inline(always)]
#[cfg(armv8m)]
// The __ttat function does not dereference the pointer received.
#[allow(clippy::not_unsafe_ptr_arg_deref)]
@@ -224,7 +224,7 @@ pub fn ttat(addr: *mut u32) -> u32 {
///
/// See section C2.4.26 of Armv8-M Architecture Reference Manual for details.
/// Undefined if executed in Non-Secure state.
-#[inline]
+#[inline(always)]
#[cfg(armv8m)]
pub unsafe fn bx_ns(addr: u32) {
asm!("bxns {}", in(reg) addr, options(nomem, nostack, preserves_flags));
@@ -234,9 +234,9 @@ pub unsafe fn bx_ns(addr: u32) {
///
/// This method is used by cortex-m-semihosting to provide semihosting syscalls.
#[cfg(cortex_m)]
-#[inline]
+#[inline(always)]
pub unsafe fn semihosting_syscall(mut nr: u32, arg: u32) -> u32 {
- asm!("bkpt #0xab", inout("r0") nr, in("r1") arg, options(nomem, nostack, preserves_flags));
+ asm!("bkpt #0xab", inout("r0") nr, in("r1") arg, options(nostack, preserves_flags));
nr
}
diff --git a/src/peripheral/mod.rs b/src/peripheral/mod.rs
index 56b663e..c316886 100644
--- a/src/peripheral/mod.rs
+++ b/src/peripheral/mod.rs
@@ -57,9 +57,9 @@
//!
//! - ARMv7-M Architecture Reference Manual (Issue E.b) - Chapter B3
+use crate::interrupt;
use core::marker::PhantomData;
use core::ops;
-use crate::interrupt;
#[cfg(cm7)]
pub mod ac;