use crate::{MAIRKind, MAIRSetting};
use aarch64_cpu::registers::*;
pub struct MAIRDefault;
impl MAIRDefault {
#[cfg(target_arch = "aarch64")]
pub const fn mair_value() -> u64 {
use aarch64_cpu::registers::*;
let attr0 = MAIR_EL1::Attr0_Device::nonGathering_nonReordering_EarlyWriteAck.value;
let attr1 = MAIR_EL1::Attr1_Normal_Inner::WriteBack_NonTransient_ReadWriteAlloc.value
| MAIR_EL1::Attr1_Normal_Outer::WriteBack_NonTransient_ReadWriteAlloc.value;
let attr2 = MAIR_EL1::Attr2_Normal_Inner::NonCacheable.value
| MAIR_EL1::Attr2_Normal_Outer::NonCacheable.value;
attr0 | attr1 | attr2 }
#[cfg(target_arch = "aarch64")]
pub fn mair_el1_apply() {
MAIR_EL1.set(Self::mair_value());
}
#[cfg(target_arch = "aarch64")]
pub fn mair_el2_apply() {
MAIR_EL2.set(Self::mair_value());
}
}
impl MAIRSetting for MAIRDefault {
fn get_idx(kind: MAIRKind) -> usize {
match kind {
MAIRKind::Device => 0,
MAIRKind::Normal => 1,
MAIRKind::NonCache => 2,
}
}
fn from_idx(idx: usize) -> MAIRKind {
match idx {
0 => MAIRKind::Device,
1 => MAIRKind::Normal,
2 => MAIRKind::NonCache,
_ => panic!("invalid mair index"),
}
}
}
#[derive(Clone, Copy)]
#[repr(transparent)]
pub struct PTE(u64);
impl PTE {
const PHYS_ADDR_MASK: u64 = 0x0000_ffff_ffff_f000;
pub const fn empty() -> Self {
PTE(0)
}
pub const fn from_paddr(paddr: usize) -> Self {
PTE(paddr as u64 & Self::PHYS_ADDR_MASK)
}
pub fn paddr(&self) -> usize {
(self.0 & Self::PHYS_ADDR_MASK) as _
}
pub fn set_flags(&mut self, flags: PTEFlags) {
self.0 |= flags.bits();
}
pub fn get_flags(&self) -> PTEFlags {
PTEFlags::from_bits_truncate(self.0)
}
pub fn set_mair_idx(&mut self, idx: usize) {
self.0 |= ((idx as u64) & 0b111) << 2;
}
pub fn get_mair_idx(&self) -> usize {
((self.0 >> 2) & 0b111) as usize
}
}
impl From<u64> for PTE {
fn from(value: u64) -> Self {
Self(value)
}
}
impl From<PTE> for u64 {
fn from(value: PTE) -> Self {
value.0
}
}
bitflags::bitflags! {
#[derive(Debug, Clone, Copy)]
pub struct PTEFlags: u64 {
const VALID = 1 << 0;
const NON_BLOCK = 1 << 1;
const NS = 1 << 5;
const AP_EL0 = 1 << 6;
const AP_RO = 1 << 7;
const INNER = 1 << 8;
const SHAREABLE = 1 << 9;
const AF = 1 << 10;
const NG = 1 << 11;
const CONTIGUOUS = 1 << 52;
const PXN = 1 << 53;
const UXN = 1 << 54;
const PXN_TABLE = 1 << 59;
const XN_TABLE = 1 << 60;
const AP_NO_EL0_TABLE = 1 << 61;
const AP_NO_WRITE_TABLE = 1 << 62;
const NS_TABLE = 1 << 63;
}
}