aboutsummaryrefslogtreecommitdiff
path: root/src/peripheral/sau.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/peripheral/sau.rs')
-rw-r--r--src/peripheral/sau.rs242
1 files changed, 0 insertions, 242 deletions
diff --git a/src/peripheral/sau.rs b/src/peripheral/sau.rs
deleted file mode 100644
index 6b8477f..0000000
--- a/src/peripheral/sau.rs
+++ /dev/null
@@ -1,242 +0,0 @@
-//! Security Attribution Unit
-//!
-//! *NOTE* Available only on Armv8-M and Armv8.1-M, for the following Rust target triples:
-//! * `thumbv8m.base-none-eabi`
-//! * `thumbv8m.main-none-eabi`
-//! * `thumbv8m.main-none-eabihf`
-//!
-//! For reference please check the section B8.3 of the Armv8-M Architecture Reference Manual.
-
-use crate::peripheral::SAU;
-use bitfield::bitfield;
-use volatile_register::{RO, RW};
-
-/// Register block
-#[repr(C)]
-pub struct RegisterBlock {
- /// Control Register
- pub ctrl: RW<Ctrl>,
- /// Type Register
- pub _type: RO<Type>,
- /// Region Number Register
- pub rnr: RW<Rnr>,
- /// Region Base Address Register
- pub rbar: RW<Rbar>,
- /// Region Limit Address Register
- pub rlar: RW<Rlar>,
- /// Secure Fault Status Register
- pub sfsr: RO<Sfsr>,
- /// Secure Fault Address Register
- pub sfar: RO<Sfar>,
-}
-
-bitfield! {
- /// Control Register description
- #[repr(C)]
- #[derive(Copy, Clone)]
- pub struct Ctrl(u32);
- get_enable, set_enable: 0;
- get_allns, set_allns: 1;
-}
-
-bitfield! {
- /// Type Register description
- #[repr(C)]
- #[derive(Copy, Clone)]
- pub struct Type(u32);
- u8;
- sregion, _: 7, 0;
-}
-
-bitfield! {
- /// Region Number Register description
- #[repr(C)]
- #[derive(Copy, Clone)]
- pub struct Rnr(u32);
- u8;
- get_region, set_region: 7, 0;
-}
-
-bitfield! {
- /// Region Base Address Register description
- #[repr(C)]
- #[derive(Copy, Clone)]
- pub struct Rbar(u32);
- u32;
- get_baddr, set_baddr: 31, 5;
-}
-
-bitfield! {
- /// Region Limit Address Register description
- #[repr(C)]
- #[derive(Copy, Clone)]
- pub struct Rlar(u32);
- u32;
- get_laddr, set_laddr: 31, 5;
- get_nsc, set_nsc: 1;
- get_enable, set_enable: 0;
-}
-
-bitfield! {
- /// Secure Fault Status Register description
- #[repr(C)]
- #[derive(Copy, Clone)]
- pub struct Sfsr(u32);
- invep, _: 0;
- invis, _: 1;
- inver, _: 2;
- auviol, _: 3;
- invtran, _: 4;
- lsperr, _: 5;
- sfarvalid, _: 6;
- lserr, _: 7;
-}
-
-bitfield! {
- /// Secure Fault Address Register description
- #[repr(C)]
- #[derive(Copy, Clone)]
- pub struct Sfar(u32);
- u32;
- address, _: 31, 0;
-}
-
-/// Possible attribute of a SAU region.
-#[derive(Debug)]
-pub enum SauRegionAttribute {
- /// SAU region is Secure
- Secure,
- /// SAU region is Non-Secure Callable
- NonSecureCallable,
- /// SAU region is Non-Secure
- NonSecure,
-}
-
-/// Description of a SAU region.
-#[derive(Debug)]
-pub struct SauRegion {
- /// First address of the region, its 5 least significant bits must be set to zero.
- pub base_address: u32,
- /// Last address of the region, its 5 least significant bits must be set to one.
- pub limit_address: u32,
- /// Attribute of the region.
- pub attribute: SauRegionAttribute,
-}
-
-/// Possible error values returned by the SAU methods.
-#[derive(Debug)]
-pub enum SauError {
- /// The region number parameter to set or get a region must be between 0 and
- /// region_numbers() - 1.
- RegionNumberTooBig,
- /// Bits 0 to 4 of the base address of a SAU region must be set to zero.
- WrongBaseAddress,
- /// Bits 0 to 4 of the limit address of a SAU region must be set to one.
- WrongLimitAddress,
-}
-
-impl SAU {
- /// Get the number of implemented SAU regions.
- #[inline]
- pub fn region_numbers(&self) -> u8 {
- self._type.read().sregion()
- }
-
- /// Enable the SAU.
- #[inline]
- pub fn enable(&mut self) {
- unsafe {
- self.ctrl.modify(|mut ctrl| {
- ctrl.set_enable(true);
- ctrl
- });
- }
- }
-
- /// Set a SAU region to a region number.
- /// SAU regions must be 32 bytes aligned and their sizes must be a multiple of 32 bytes. It
- /// means that the 5 least significant bits of the base address of a SAU region must be set to
- /// zero and the 5 least significant bits of the limit address must be set to one.
- /// The region number must be valid.
- /// This function is executed under a critical section to prevent having inconsistent results.
- #[inline]
- pub fn set_region(&mut self, region_number: u8, region: SauRegion) -> Result<(), SauError> {
- critical_section::with(|_| {
- let base_address = region.base_address;
- let limit_address = region.limit_address;
- let attribute = region.attribute;
-
- if region_number >= self.region_numbers() {
- Err(SauError::RegionNumberTooBig)
- } else if base_address & 0x1F != 0 {
- Err(SauError::WrongBaseAddress)
- } else if limit_address & 0x1F != 0x1F {
- Err(SauError::WrongLimitAddress)
- } else {
- // All fields of these registers are going to be modified so we don't need to read them
- // before.
- let mut rnr = Rnr(0);
- let mut rbar = Rbar(0);
- let mut rlar = Rlar(0);
-
- rnr.set_region(region_number);
- rbar.set_baddr(base_address >> 5);
- rlar.set_laddr(limit_address >> 5);
-
- match attribute {
- SauRegionAttribute::Secure => {
- rlar.set_nsc(false);
- rlar.set_enable(false);
- }
- SauRegionAttribute::NonSecureCallable => {
- rlar.set_nsc(true);
- rlar.set_enable(true);
- }
- SauRegionAttribute::NonSecure => {
- rlar.set_nsc(false);
- rlar.set_enable(true);
- }
- }
-
- unsafe {
- self.rnr.write(rnr);
- self.rbar.write(rbar);
- self.rlar.write(rlar);
- }
-
- Ok(())
- }
- })
- }
-
- /// Get a region from the SAU.
- /// The region number must be valid.
- /// This function is executed under a critical section to prevent having inconsistent results.
- #[inline]
- pub fn get_region(&mut self, region_number: u8) -> Result<SauRegion, SauError> {
- critical_section::with(|_| {
- if region_number >= self.region_numbers() {
- Err(SauError::RegionNumberTooBig)
- } else {
- unsafe {
- self.rnr.write(Rnr(region_number.into()));
- }
-
- let rbar = self.rbar.read();
- let rlar = self.rlar.read();
-
- let attribute = match (rlar.get_enable(), rlar.get_nsc()) {
- (false, _) => SauRegionAttribute::Secure,
- (true, false) => SauRegionAttribute::NonSecure,
- (true, true) => SauRegionAttribute::NonSecureCallable,
- };
-
- Ok(SauRegion {
- base_address: rbar.get_baddr() << 5,
- limit_address: (rlar.get_laddr() << 5) | 0x1F,
- attribute,
- })
- }
- })
- }
-}