diff options
author | 2020-03-14 15:27:28 +0000 | |
---|---|---|
committer | 2020-03-14 15:27:28 +0000 | |
commit | 1cb6baf8bd46b602c01d51e7a3c5c6e77af9c8f2 (patch) | |
tree | ebe6d29b0f9f9ad2ffde71db0e8e71c27ddc9bf2 /src/asm.rs | |
parent | 72befe4c163e59393789d3043afe1e67a7fc0044 (diff) | |
parent | 2433d85190dad9e4cbaa4086eba796ab59bf0adb (diff) | |
download | cortex-m-1cb6baf8bd46b602c01d51e7a3c5c6e77af9c8f2.tar.gz cortex-m-1cb6baf8bd46b602c01d51e7a3c5c6e77af9c8f2.tar.zst cortex-m-1cb6baf8bd46b602c01d51e7a3c5c6e77af9c8f2.zip |
Merge #189
189: Initial Rust CMSE support r=thejpster a=hug-dev
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
Executed `assemble.sh` to generate the new static libraries containing the `TT*` instructions. Tested `check_blobs.sh` locally and it passed.
Tested on QEMU using the `mps2-an505` machine.
Co-authored-by: Hugues de Valon <hugues.devalon@arm.com>
Diffstat (limited to 'src/asm.rs')
-rw-r--r-- | src/asm.rs | 141 |
1 files changed, 141 insertions, 0 deletions
@@ -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!(), + } +} |