aboutsummaryrefslogtreecommitdiff
path: root/src/asm.rs
diff options
context:
space:
mode:
authorGravatar Hugues de Valon <hugues.devalon@arm.com> 2020-01-14 11:38:34 +0000
committerGravatar Hugues de Valon <hugues.devalon@arm.com> 2020-03-02 09:06:34 +0000
commit2bbfd8c976fed21e24865618b0a9975d9ab542c4 (patch)
tree453957fade88692549fbbc40ffb1639ae2036398 /src/asm.rs
parent72befe4c163e59393789d3043afe1e67a7fc0044 (diff)
downloadcortex-m-2bbfd8c976fed21e24865618b0a9975d9ab542c4.tar.gz
cortex-m-2bbfd8c976fed21e24865618b0a9975d9ab542c4.tar.zst
cortex-m-2bbfd8c976fed21e24865618b0a9975d9ab542c4.zip
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 <hugues.devalon@arm.com>
Diffstat (limited to 'src/asm.rs')
-rw-r--r--src/asm.rs141
1 files changed, 141 insertions, 0 deletions
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!(),
+ }
+}