From 2bbfd8c976fed21e24865618b0a9975d9ab542c4 Mon Sep 17 00:00:00 2001 From: Hugues de Valon Date: Tue, 14 Jan 2020 11:38:34 +0000 Subject: Initial Rust CMSE support Armv8-M and Armv8.1-M architecture profiles have an optional Security Extension which provides a set of Security features. This patch adds initial support of the Cortex-M Security Extensions but providing support for the TT intrinsics and helper functions on top of it in the newly added cmse module of this crate. The code is a Rust idiomatic implementation of the C requirements described in this document: https://developer.arm.com/docs/ecm0359818/latest Signed-off-by: Hugues de Valon --- src/asm.rs | 141 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) (limited to 'src/asm.rs') diff --git a/src/asm.rs b/src/asm.rs index 5a35fa3..7b1a9ce 100644 --- a/src/asm.rs +++ b/src/asm.rs @@ -222,3 +222,144 @@ pub fn dmb() { () => unimplemented!(), } } + +/// Test Target +/// +/// 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] +#[cfg(armv8m)] +// The __tt function does not dereference the pointer received. +#[allow(clippy::not_unsafe_ptr_arg_deref)] +pub fn tt(addr: *mut u32) -> u32 { + match () { + #[cfg(all(cortex_m, feature = "inline-asm"))] + () => { + let tt_resp: u32; + unsafe { + asm!("tt $0, $1" : "=r"(tt_resp) : "r"(addr) :: "volatile"); + } + tt_resp + } + + #[cfg(all(cortex_m, not(feature = "inline-asm")))] + () => unsafe { + extern "C" { + fn __tt(_: *mut u32) -> u32; + } + + __tt(addr) + }, + + #[cfg(not(cortex_m))] + () => unimplemented!(), + } +} + +/// Test Target Unprivileged +/// +/// Queries the Security state and access permissions of a memory location for an unprivileged +/// access to that location. +/// Returns a Test Target Response Payload (cf section D1.2.215 of +/// Armv8-M Architecture Reference Manual). +#[inline] +#[cfg(armv8m)] +// The __ttt function does not dereference the pointer received. +#[allow(clippy::not_unsafe_ptr_arg_deref)] +pub fn ttt(addr: *mut u32) -> u32 { + match () { + #[cfg(all(cortex_m, feature = "inline-asm"))] + () => { + let tt_resp: u32; + unsafe { + asm!("ttt $0, $1" : "=r"(tt_resp) : "r"(addr) :: "volatile"); + } + tt_resp + } + + #[cfg(all(cortex_m, not(feature = "inline-asm")))] + () => unsafe { + extern "C" { + fn __ttt(_: *mut u32) -> u32; + } + + __ttt(addr) + }, + + #[cfg(not(cortex_m))] + () => unimplemented!(), + } +} + +/// Test Target Alternate Domain +/// +/// Queries the Security state and access permissions of a memory location for a Non-Secure access +/// to that location. This instruction is only valid when executing in Secure 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] +#[cfg(armv8m)] +// The __tta function does not dereference the pointer received. +#[allow(clippy::not_unsafe_ptr_arg_deref)] +pub fn tta(addr: *mut u32) -> u32 { + match () { + #[cfg(all(cortex_m, feature = "inline-asm"))] + () => { + let tt_resp: u32; + unsafe { + asm!("tta $0, $1" : "=r"(tt_resp) : "r"(addr) :: "volatile"); + } + tt_resp + } + + #[cfg(all(cortex_m, not(feature = "inline-asm")))] + () => unsafe { + extern "C" { + fn __tta(_: *mut u32) -> u32; + } + + __tta(addr) + }, + + #[cfg(not(cortex_m))] + () => unimplemented!(), + } +} + +/// Test Target Alternate Domain Unprivileged +/// +/// Queries the Security state and access permissions of a memory location for a Non-Secure and +/// unprivileged access to that location. This instruction is only valid when executing in Secure +/// 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] +#[cfg(armv8m)] +// The __ttat function does not dereference the pointer received. +#[allow(clippy::not_unsafe_ptr_arg_deref)] +pub fn ttat(addr: *mut u32) -> u32 { + match () { + #[cfg(all(cortex_m, feature = "inline-asm"))] + () => { + let tt_resp: u32; + unsafe { + asm!("ttat $0, $1" : "=r"(tt_resp) : "r"(addr) :: "volatile"); + } + tt_resp + } + + #[cfg(all(cortex_m, not(feature = "inline-asm")))] + () => unsafe { + extern "C" { + fn __ttat(_: *mut u32) -> u32; + } + + __ttat(addr) + }, + + #[cfg(not(cortex_m))] + () => unimplemented!(), + } +} -- cgit v1.2.3