peripheral: add SCB NSACR and NVIC ITNS support for ARMv8-M TrustZone#647
peripheral: add SCB NSACR and NVIC ITNS support for ARMv8-M TrustZone#647leftger wants to merge 3 commits intorust-embedded:masterfrom
Conversation
Add the missing ARMv8-M TrustZone registers and typed helper methods: - SCB: add `nsacr` field (Non-Secure Access Control Register, 0xE000_ED8C) gated behind `#[cfg(armv8m)]`. Add `enable_nonsecure_fpu()`, `disable_nonsecure_fpu()`, and `is_nonsecure_fpu_enabled()` helpers on SCB for controlling CP10/CP11 (FPU) access from Non-Secure code. - NVIC: add `route_to_nonsecure<I>()`, `route_to_secure<I>()`, and `is_routed_to_nonsecure<I>()` typed methods on NVIC, using the existing `itns` register field (already present since rust-embedded#580). Gated behind `#[cfg(armv8m)]`. - test: add address assertions for `nvic.itns` (0xE000_E380) and `scb.nsacr` (0xE000_ED8C), both gated `#[cfg(armv8m)]`.
|
The |
|
One downstream motivating use-case for this PR is the embassy-stm32 TrustZone/SAU driver. Currently |
Improves readability of the ARMv8-M route_to_nonsecure, route_to_secure, and is_routed_to_nonsecure methods by naming the nr/32 and nr%32 sub- expressions as suggested in PR review.
Motivation
When setting up a TrustZone Secure world on Cortex-M33 (ARMv8-M), three things need to happen before jumping to the Non-Secure application:
SCB->NSACRbits 10–11 (CP10/CP11).NVIC->ITNS[n].Neither
SCB->NSACRnor typedNVIC->ITNSaccessors are currently exposed by this crate, forcing users to fall back to raw pointer writes against magic addresses. This PR closes that gap.Changes
scb.rspub nsacr: RW<u32>toRegisterBlock, gated#[cfg(armv8m)], at the correct offset (CPACR + 4 =0xE000_ED8C).#[cfg(armv8m)] impl SCBblock with three methods:enable_nonsecure_fpu(&mut self)— sets NSACR bits 10–11.disable_nonsecure_fpu(&mut self)— clears them.is_nonsecure_fpu_enabled() -> bool— reads the current state.nvic.rsThe
itns: [RW<u32>; 16]field already exists (added in #580) but had no typed methods. Three#[cfg(armv8m)]methods are added toimpl NVIC:unsafe route_to_nonsecure<I: InterruptNumber>(interrupt: I)— sets the ITNS bit.unsafe route_to_secure<I: InterruptNumber>(interrupt: I)— clears it.is_routed_to_nonsecure<I: InterruptNumber>(interrupt: I) -> bool— reads it.The
unsafeon the mutating methods matches the precedent set byunmask— incorrect routing can violate security invariants.test.rsnvic.itns(0xE000_E380) andnvic.itns[1](0xE000_E384), gated#[cfg(armv8m)].scb.nsacr(0xE000_ED8C), gated#[cfg(armv8m)].Testing
cargo test -p cortex-m --features std --libpasses (11/11). The new#[cfg(armv8m)]assertions are verified when targetingthumbv8m.main-none-eabihf. The pre-existingmacros::CPASS_ATTRdoctest failure is a macOS LLVM section-specifier issue unrelated to this PR.