Files
zynq7000-rs/zynq-mmu/src/lib.rs

52 lines
1.3 KiB
Rust

//! The MMU structures live inside a dedicated shared crate so it can be used by both the Zynq
//! runtime crate and teh HAL crate.
#![no_std]
use cortex_ar::{
asm::{dsb, isb},
cache::clean_and_invalidate_l1_cache,
mmu::SectionAttributes,
register::{BpIAll, TlbIAll},
};
pub const NUM_L1_PAGE_TABLE_ENTRIES: usize = 4096;
#[derive(Debug, PartialEq, Eq, thiserror::Error)]
#[error("address is not aligned to 1MB boundary")]
pub struct AddrNotAlignedToOneMb;
#[repr(C, align(16384))]
pub struct L1Table(pub [u32; NUM_L1_PAGE_TABLE_ENTRIES]);
impl L1Table {
#[inline(always)]
pub const fn as_ptr(&self) -> *const u32 {
self.0.as_ptr()
}
#[inline(always)]
pub const fn as_mut_ptr(&mut self) -> *mut u32 {
self.0.as_mut_ptr()
}
pub fn update(
&mut self,
addr: u32,
section_attrs: SectionAttributes,
) -> Result<(), AddrNotAlignedToOneMb> {
if addr & 0x000F_FFFF != 0 {
return Err(AddrNotAlignedToOneMb);
}
let index = addr as usize / 0x10_0000;
self.0[index] = (self.0[index] & 0xFFF0_0000) | section_attrs.as_raw_bits();
clean_and_invalidate_l1_cache();
TlbIAll::write();
BpIAll::write();
dsb();
isb();
Ok(())
}
}