hal/memory/
physical_address.rsuse cfg_if::cfg_if;
use core::{
fmt,
ops::{Add, AddAssign, Sub, SubAssign},
};
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default)]
#[repr(transparent)]
pub struct PAddr(usize);
impl PAddr {
cfg_if! {
if #[cfg(target_arch = "x86_64")] {
pub const fn new(address: usize) -> Option<PAddr> {
const MAX_PHYSICAL_ADDRESS: usize = (1 << 52) - 1;
match address {
0..=MAX_PHYSICAL_ADDRESS => Some(PAddr(address)),
_ => None
}
}
} else {
pub const fn new(address: usize) -> Option<PAddr> {
Some(PAddr(address))
}
}
}
pub fn align_down(self, align: usize) -> PAddr {
if align.is_power_of_two() {
PAddr(self.0 & !(align - 1))
} else {
assert!(align == 0);
self
}
}
pub fn align_up(self, align: usize) -> PAddr {
PAddr(self.0 + align - 1).align_down(align)
}
pub fn is_aligned(self, align: usize) -> bool {
self.0 % align == 0
}
pub fn checked_add(self, rhs: usize) -> Option<Self> {
PAddr::new(self.0.checked_add(rhs)?)
}
pub fn checked_sub(self, rhs: usize) -> Option<Self> {
PAddr::new(self.0.checked_sub(rhs)?)
}
}
impl fmt::LowerHex for PAddr {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:#x}", self.0)
}
}
impl fmt::UpperHex for PAddr {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:#X}", self.0)
}
}
impl fmt::Debug for PAddr {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "PAddr({:#x})", self)
}
}
impl From<PAddr> for usize {
fn from(address: PAddr) -> usize {
address.0
}
}
impl Add<usize> for PAddr {
type Output = PAddr;
fn add(self, rhs: usize) -> Self::Output {
match PAddr::new(self.0 + rhs) {
Some(address) => address,
None => panic!("Physical address arithmetic led to invalid address: {:#x} + {:#x}", self, rhs),
}
}
}
impl AddAssign<usize> for PAddr {
fn add_assign(&mut self, rhs: usize) {
*self = *self + rhs;
}
}
impl Sub<usize> for PAddr {
type Output = PAddr;
fn sub(self, rhs: usize) -> Self::Output {
match PAddr::new(self.0 - rhs) {
Some(address) => address,
None => panic!("Physical address arithmetic led to invalid address: {:#x} - {:#x}", self, rhs),
}
}
}
impl SubAssign<usize> for PAddr {
fn sub_assign(&mut self, rhs: usize) {
*self = *self - rhs;
}
}