diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 459d2e370..1f9a51678 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml @@ -115,6 +115,9 @@ low-power-debug-with-sleep = [] ## Automatically generate `memory.x` file using [`stm32-metapac`](https://docs.rs/stm32-metapac/) memory-x = ["stm32-metapac/memory-x"] +## Use secure registers when TrustZone is enabled +trustzone-secure = [] + ## Re-export stm32-metapac at `embassy_stm32::pac`. ## This is unstable because semver-minor (non-breaking) releases of embassy-stm32 may major-bump (breaking) the stm32-metapac version. ## If this is an issue for you, you're encouraged to directly depend on a fixed version of the PAC. diff --git a/embassy-stm32/src/flash/u5.rs b/embassy-stm32/src/flash/u5.rs index 4a2168b14..ddd4d73ff 100644 --- a/embassy-stm32/src/flash/u5.rs +++ b/embassy-stm32/src/flash/u5.rs @@ -14,10 +14,19 @@ pub(crate) const fn get_flash_regions() -> &'static [&'static FlashRegion] { } pub(crate) unsafe fn lock() { + #[cfg(feature = "trustzone-secure")] + pac::FLASH.seccr().modify(|w| w.set_lock(true)); + #[cfg(not(feature = "trustzone-secure"))] pac::FLASH.nscr().modify(|w| w.set_lock(true)); } pub(crate) unsafe fn unlock() { + #[cfg(feature = "trustzone-secure")] + if pac::FLASH.seccr().read().lock() { + pac::FLASH.seckeyr().write_value(0x4567_0123); + pac::FLASH.seckeyr().write_value(0xCDEF_89AB); + } + #[cfg(not(feature = "trustzone-secure"))] if pac::FLASH.nscr().read().lock() { pac::FLASH.nskeyr().write_value(0x4567_0123); pac::FLASH.nskeyr().write_value(0xCDEF_89AB); @@ -27,12 +36,20 @@ pub(crate) unsafe fn unlock() { pub(crate) unsafe fn enable_blocking_write() { assert_eq!(0, WRITE_SIZE % 4); + #[cfg(feature = "trustzone-secure")] + pac::FLASH.seccr().write(|w| { + w.set_pg(pac::flash::vals::SeccrPg::B_0X1); + }); + #[cfg(not(feature = "trustzone-secure"))] pac::FLASH.nscr().write(|w| { w.set_pg(pac::flash::vals::NscrPg::B_0X1); }); } pub(crate) unsafe fn disable_blocking_write() { + #[cfg(feature = "trustzone-secure")] + pac::FLASH.seccr().write(|w| w.set_pg(pac::flash::vals::SeccrPg::B_0X0)); + #[cfg(not(feature = "trustzone-secure"))] pac::FLASH.nscr().write(|w| w.set_pg(pac::flash::vals::NscrPg::B_0X0)); } @@ -50,16 +67,32 @@ pub(crate) unsafe fn blocking_write(start_address: u32, buf: &[u8; WRITE_SIZE]) } pub(crate) unsafe fn blocking_erase_sector(sector: &FlashSector) -> Result<(), Error> { + #[cfg(feature = "trustzone-secure")] + pac::FLASH.seccr().modify(|w| { + w.set_per(pac::flash::vals::SeccrPer::B_0X1); + w.set_pnb(sector.index_in_bank) + }); + #[cfg(not(feature = "trustzone-secure"))] pac::FLASH.nscr().modify(|w| { w.set_per(pac::flash::vals::NscrPer::B_0X1); w.set_pnb(sector.index_in_bank) }); + #[cfg(feature = "trustzone-secure")] + pac::FLASH.seccr().modify(|w| { + w.set_strt(true); + }); + #[cfg(not(feature = "trustzone-secure"))] pac::FLASH.nscr().modify(|w| { w.set_strt(true); }); let ret: Result<(), Error> = blocking_wait_ready(); + #[cfg(feature = "trustzone-secure")] + pac::FLASH + .seccr() + .modify(|w| w.set_per(pac::flash::vals::SeccrPer::B_0X0)); + #[cfg(not(feature = "trustzone-secure"))] pac::FLASH .nscr() .modify(|w| w.set_per(pac::flash::vals::NscrPer::B_0X0)); @@ -70,11 +103,17 @@ pub(crate) unsafe fn blocking_erase_sector(sector: &FlashSector) -> Result<(), E pub(crate) unsafe fn clear_all_err() { // read and write back the same value. // This clears all "write 1 to clear" bits. + #[cfg(feature = "trustzone-secure")] + pac::FLASH.secsr().modify(|_| {}); + #[cfg(not(feature = "trustzone-secure"))] pac::FLASH.nssr().modify(|_| {}); } unsafe fn blocking_wait_ready() -> Result<(), Error> { loop { + #[cfg(feature = "trustzone-secure")] + let sr = pac::FLASH.secsr().read(); + #[cfg(not(feature = "trustzone-secure"))] let sr = pac::FLASH.nssr().read(); if !sr.bsy() { diff --git a/examples/stm32u5/Cargo.toml b/examples/stm32u5/Cargo.toml index 03294339d..01320b88d 100644 --- a/examples/stm32u5/Cargo.toml +++ b/examples/stm32u5/Cargo.toml @@ -24,5 +24,9 @@ heapless = { version = "0.8", default-features = false } micromath = "2.0.0" +[features] +## Use secure registers when TrustZone is enabled +trustzone-secure = ["embassy-stm32/trustzone-secure"] + [profile.release] debug = 2