use crate::paging::PFN; use bitflags::bitflags; bitflags! { #[derive(Clone, Copy, PartialEq)] pub struct TableAttribute: usize { const PRESENT = 1; const USER = 2; const ACCESSED = 4; const GLOBAL = 8; } #[derive(Clone, Copy, PartialEq)] pub struct PageAttribute: usize { const PRESENT = 1; const READ = 2; const WRITE = 4; const EXECUTE = 8; const USER = 16; const ACCESSED = 32; const DIRTY = 64; const GLOBAL = 128; const COPY_ON_WRITE = 256; const MAPPED = 512; const ANONYMOUS = 1024; const HUGE = 2048; } } #[doc(notable_trait)] pub trait RawAttribute: Copy + From + From { /// Create a new attribute representing a non-present page. fn null() -> Self; /// Interpret the attribute as a page table attribute. Return `None` if it is /// not an attribute for a page table. /// /// # Panic /// The implementor should panic if invalid combinations of flags are present. fn as_table_attr(self) -> Option; /// Interpret the attribute as a page attribute. Return `None` if it is not /// an attribute for a page. /// /// # Panic /// The implementor should panic if invalid combinations of flags are present. fn as_page_attr(self) -> Option; } #[doc(notable_trait)] pub trait PTE: Sized { type Attr: RawAttribute; fn set(&mut self, pfn: PFN, attr: Self::Attr); fn get(&self) -> (PFN, Self::Attr); fn take(&mut self) -> (PFN, Self::Attr) { let pfn_attr = self.get(); self.set(PFN::from_val(0), Self::Attr::null()); pfn_attr } fn set_pfn(&mut self, pfn: PFN) { self.set(pfn, self.get_attr()); } fn set_attr(&mut self, attr: Self::Attr) { self.set(self.get_pfn(), attr); } fn get_pfn(&self) -> PFN { self.get().0 } fn get_attr(&self) -> Self::Attr { self.get().1 } }