use crate::{
core::error::Result,
memory::{
primitives::{PhysicalAddress, RawVirtualAddress},
readable::Readable,
virtual_address::VirtualAddress,
},
};
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum Endianness {
Little,
Big,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum Bitness {
Bit64,
}
#[derive(Copy, Clone, Debug)]
pub struct PhysicalAddressRange {
address: PhysicalAddress,
size: u64,
}
impl PhysicalAddressRange {
pub fn new(address: PhysicalAddress, remaining_bytes: u64) -> Self {
Self {
address,
size: remaining_bytes,
}
}
pub fn address(&self) -> PhysicalAddress {
self.address
}
pub fn len(&self) -> u64 {
self.size
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
}
pub struct Region {
pub virtual_address: VirtualAddress,
pub physical_address: PhysicalAddress,
pub size: u64,
}
pub trait Architecture: Send + Sync {
fn endianness(&self) -> Endianness;
fn bitness(&self) -> Bitness;
fn iter_page_table_candidates<'a>(
&'a self,
readable: &'a dyn Readable,
physical_address: PhysicalAddress,
raw_virtual_address: RawVirtualAddress,
) -> Result<Box<dyn Iterator<Item = PhysicalAddress> + 'a>>;
fn translate_virtual_address(
&self,
readable: &dyn Readable,
virtual_address: VirtualAddress,
) -> Result<PhysicalAddressRange>;
fn enumerate_page_table_regions(
&self,
readable: &dyn Readable,
root_page_table: PhysicalAddress,
) -> Result<Vec<Region>>;
}