diff options
Diffstat (limited to 'src/paging.rs')
-rw-r--r-- | src/paging.rs | 160 |
1 files changed, 106 insertions, 54 deletions
diff --git a/src/paging.rs b/src/paging.rs index aa218d9..22d9526 100644 --- a/src/paging.rs +++ b/src/paging.rs @@ -143,24 +143,24 @@ bitflags! { #[derive(Debug)] flags PML4Entry: u64 { /// Present; must be 1 to reference a page-directory-pointer table - const PML4_P = 0b00000001, + const PML4_P = bit!(0), /// Read/write; if 0, writes may not be allowed to the 512-GByte region /// controlled by this entry (see Section 4.6) - const PML4_RW = 0b00000010, + const PML4_RW = bit!(1), /// User/supervisor; if 0, user-mode accesses are not allowed /// to the 512-GByte region controlled by this entry. - const PML4_US = 0b00000100, + const PML4_US = bit!(2), /// Page-level write-through; indirectly determines the memory type used to /// access the page-directory-pointer table referenced by this entry. - const PML4_PWT = 0b00001000, + const PML4_PWT = bit!(3), /// Page-level cache disable; indirectly determines the memory type used to /// access the page-directory-pointer table referenced by this entry. - const PML4_PCD = 0b00010000, + const PML4_PCD = bit!(4), /// Accessed; indicates whether this entry has been used for linear-address translation. - const PML4_A = 0b00100000, + const PML4_A = bit!(5), /// If IA32_EFER.NXE = 1, execute-disable /// If 1, instruction fetches are not allowed from the 512-GByte region. - const PML4_XD = 1 << 63, + const PML4_XD = bit!(63), } } @@ -183,10 +183,19 @@ impl PML4Entry { PAddr::from_u64(self.bits & ADDRESS_MASK) } - /// Convenience function to check if the present bit is set. - pub fn is_present(self) -> bool { - self.contains(PML4_P) - } + check_flag!(doc = "Is page present?", is_present, PML4_P); + check_flag!(doc = "Read/write; if 0, writes may not be allowed to the 512-GByte region, controlled by this entry (see Section 4.6)", + is_writeable, PML4_RW); + check_flag!(doc = "User/supervisor; if 0, user-mode accesses are not allowed to the 512-GByte region controlled by this entry.", + is_user_mode_allowed, PML4_US); + check_flag!(doc = "Page-level write-through; indirectly determines the memory type used to access the page-directory-pointer table referenced by this entry.", + is_page_write_through, PML4_PWT); + check_flag!(doc = "Page-level cache disable; indirectly determines the memory type used to access the page-directory-pointer table referenced by this entry.", + is_page_level_cache_disabled, PML4_PCD); + check_flag!(doc = "Accessed; indicates whether this entry has been used for linear-address translation.", + is_accessed, PML4_A); + check_flag!(doc = "If IA32_EFER.NXE = 1, execute-disable. If 1, instruction fetches are not allowed from the 512-GByte region.", + is_instruction_fetching_disabled, PML4_XD); } /// PDPT Entry bits description. @@ -194,32 +203,32 @@ bitflags! { #[derive(Debug)] flags PDPTEntry: u64 { /// Present; must be 1 to map a 1-GByte page or reference a page directory. - const PDPT_P = 0b00000001, + const PDPT_P = bit!(0), /// Read/write; if 0, writes may not be allowed to the 1-GByte region controlled by this entry - const PDPT_RW = 0b00000010, + const PDPT_RW = bit!(1), /// User/supervisor; user-mode accesses are not allowed to the 1-GByte region controlled by this entry. - const PDPT_US = 0b00000100, + const PDPT_US = bit!(2), /// Page-level write-through. - const PDPT_PWT = 0b00001000, + const PDPT_PWT = bit!(3), /// Page-level cache disable. - const PDPT_PCD = 0b00010000, + const PDPT_PCD = bit!(4), /// Accessed; if PDPT_PS set indicates whether software has accessed the 1-GByte page /// else indicates whether this entry has been used for linear-address translation - const PDPT_A = 0b00100000, + const PDPT_A = bit!(5), /// Dirty; if PDPT_PS indicates whether software has written to the 1-GByte page referenced by this entry. /// else ignored. - const PDPT_D = 0b01000000, + const PDPT_D = bit!(6), /// Page size; if set this entry maps a 1-GByte page; otherwise, this entry references a page directory. /// if not PDPT_PS this is ignored. - const PDPT_PS = 0b10000000, + const PDPT_PS = bit!(7), /// Global; if PDPT_PS && CR4.PGE = 1, determines whether the translation is global; ignored otherwise /// if not PDPT_PS this is ignored. - const PDPT_G = 1<<8, + const PDPT_G = bit!(8), /// Indirectly determines the memory type used to access the 1-GByte page referenced by this entry. - const PDPT_PAT = 1<<12, + const PDPT_PAT = bit!(12), /// If IA32_EFER.NXE = 1, execute-disable /// If 1, instruction fetches are not allowed from the 512-GByte region. - const PDPT_XD = 1 << 63, + const PDPT_XD = bit!(63), } } @@ -241,10 +250,21 @@ impl PDPTEntry { PAddr::from_u64(self.bits & ADDRESS_MASK) } - /// Convenience function to check if the present bit is set. - pub fn is_present(self) -> bool { - self.contains(PDPT_P) - } + check_flag!(doc = "Is page present?", is_present, PDPT_P); + check_flag!(doc = "Read/write; if 0, writes may not be allowed to the 1-GByte region controlled by this entry.", + is_writeable, PDPT_RW); + check_flag!(doc = "User/supervisor; user-mode accesses are not allowed to the 1-GByte region controlled by this entry.", + is_user_mode_allowed, PDPT_US); + check_flag!(doc = "Page-level write-through.", + is_page_write_through, PDPT_PWT); + check_flag!(doc = "Page-level cache disable.", + is_page_level_cache_disabled, PDPT_PCD); + check_flag!(doc = "Accessed; indicates whether this entry has been used for linear-address translation.", + is_accessed, PDPT_A); + check_flag!(doc = "Indirectly determines the memory type used to access the 1-GByte page referenced by this entry. if not PDPT_PS this is ignored.", + is_pat, PDPT_PAT); + check_flag!(doc = "If IA32_EFER.NXE = 1, execute-disable. If 1, instruction fetches are not allowed from the 512-GByte region.", + is_instruction_fetching_disabled, PDPT_XD); } /// PD Entry bits description. @@ -252,32 +272,32 @@ bitflags! { #[derive(Debug)] flags PDEntry: u64 { /// Present; must be 1 to map a 2-MByte page or reference a page table. - const PD_P = 0b00000001, + const PD_P = bit!(0), /// Read/write; if 0, writes may not be allowed to the 2-MByte region controlled by this entry - const PD_RW = 0b00000010, + const PD_RW = bit!(1), /// User/supervisor; user-mode accesses are not allowed to the 2-MByte region controlled by this entry. - const PD_US = 0b00000100, + const PD_US = bit!(2), /// Page-level write-through. - const PD_PWT = 0b00001000, + const PD_PWT = bit!(3), /// Page-level cache disable. - const PD_PCD = 0b00010000, + const PD_PCD = bit!(4), /// Accessed; if PD_PS set indicates whether software has accessed the 2-MByte page /// else indicates whether this entry has been used for linear-address translation - const PD_A = 0b00100000, + const PD_A = bit!(5), /// Dirty; if PD_PS indicates whether software has written to the 2-MByte page referenced by this entry. /// else ignored. - const PD_D = 0b01000000, + const PD_D = bit!(6), /// Page size; if set this entry maps a 2-MByte page; otherwise, this entry references a page directory. - const PD_PS = 0b10000000, + const PD_PS = bit!(7), /// Global; if PD_PS && CR4.PGE = 1, determines whether the translation is global; ignored otherwise /// if not PD_PS this is ignored. - const PD_G = 1<<8, + const PD_G = bit!(8), /// Indirectly determines the memory type used to access the 2-MByte page referenced by this entry. /// if not PD_PS this is ignored. - const PD_PAT = 1<<12, + const PD_PAT = bit!(12), /// If IA32_EFER.NXE = 1, execute-disable /// If 1, instruction fetches are not allowed from the 512-GByte region. - const PD_XD = 1 << 63, + const PD_XD = bit!(63), } } @@ -299,10 +319,28 @@ impl PDEntry { PAddr::from_u64(self.bits & ADDRESS_MASK) } - /// Convenience function to check if the present bit is set. - pub fn is_present(self) -> bool { - self.contains(PD_P) - } + check_flag!(doc = "Present; must be 1 to map a 2-MByte page or reference a page table.", + is_present, PD_P); + check_flag!(doc = "Read/write; if 0, writes may not be allowed to the 2-MByte region controlled by this entry", + is_writeable, PD_RW); + check_flag!(doc = "User/supervisor; user-mode accesses are not allowed to the 2-MByte region controlled by this entry.", + is_user_mode_allowed, PD_US); + check_flag!(doc = "Page-level write-through.", + is_page_write_through, PD_PWT); + check_flag!(doc = "Page-level cache disable.", + is_page_level_cache_disabled, PD_PCD); + check_flag!(doc = "Accessed; if PD_PS set indicates whether software has accessed the 2-MByte page else indicates whether this entry has been used for linear-address translation.", + is_accessed, PD_A); + check_flag!(doc = "Dirty; if PD_PS set indicates whether software has written to the 2-MByte page referenced by this entry else ignored.", + is_dirty, PD_D); + check_flag!(doc = "Page size; if set this entry maps a 2-MByte page; otherwise, this entry references a page directory.", + is_page, PD_PS); + check_flag!(doc = "Global; if PD_PS && CR4.PGE = 1, determines whether the translation is global; ignored otherwise if not PD_PS this is ignored.", + is_global, PD_G); + check_flag!(doc = "Indirectly determines the memory type used to access the 2-MByte page referenced by this entry. if not PD_PS this is ignored.", + is_pat, PD_PAT); + check_flag!(doc = "If IA32_EFER.NXE = 1, execute-disable. If 1, instruction fetches are not allowed from the 2-Mbyte region.", + is_instruction_fetching_disabled, PD_XD); } /// PT Entry bits description. @@ -310,24 +348,24 @@ bitflags! { #[derive(Debug)] flags PTEntry: u64 { /// Present; must be 1 to map a 4-KByte page. - const PT_P = 0b00000001, + const PT_P = bit!(0), /// Read/write; if 0, writes may not be allowed to the 4-KByte region controlled by this entry - const PT_RW = 0b00000010, + const PT_RW = bit!(1), /// User/supervisor; user-mode accesses are not allowed to the 4-KByte region controlled by this entry. - const PT_US = 0b00000100, + const PT_US = bit!(2), /// Page-level write-through. - const PT_PWT = 0b00001000, + const PT_PWT = bit!(3), /// Page-level cache disable. - const PT_PCD = 0b00010000, + const PT_PCD = bit!(4), /// Accessed; indicates whether software has accessed the 4-KByte page - const PT_A = 0b00100000, + const PT_A = bit!(5), /// Dirty; indicates whether software has written to the 4-KByte page referenced by this entry. - const PT_D = 0b01000000, + const PT_D = bit!(6), /// Global; if CR4.PGE = 1, determines whether the translation is global (see Section 4.10); ignored otherwise - const PT_G = 1<<8, + const PT_G = bit!(8), /// If IA32_EFER.NXE = 1, execute-disable /// If 1, instruction fetches are not allowed from the 512-GByte region. - const PT_XD = 1 << 63, + const PT_XD = bit!(63), } } @@ -350,8 +388,22 @@ impl PTEntry { PAddr::from_u64(self.bits & ADDRESS_MASK) } - /// Convenience function to check if the present bit is set. - pub fn is_present(self) -> bool { - self.contains(PT_P) - } + check_flag!(doc = "Present; must be 1 to map a 4-KByte page or reference a page table.", + is_present, PT_P); + check_flag!(doc = "Read/write; if 0, writes may not be allowed to the 4-KByte region controlled by this entry", + is_writeable, PT_RW); + check_flag!(doc = "User/supervisor; user-mode accesses are not allowed to the 4-KByte region controlled by this entry.", + is_user_mode_allowed, PT_US); + check_flag!(doc = "Page-level write-through.", + is_page_write_through, PT_PWT); + check_flag!(doc = "Page-level cache disable.", + is_page_level_cache_disabled, PT_PCD); + check_flag!(doc = "Accessed; if PT_PS set indicates whether software has accessed the 4-KByte page else indicates whether this entry has been used for linear-address translation.", + is_accessed, PT_A); + check_flag!(doc = "Dirty; if PD_PS set indicates whether software has written to the 4-KByte page referenced by this entry else ignored.", + is_dirty, PT_D); + check_flag!(doc = "Global; if PT_PS && CR4.PGE = 1, determines whether the translation is global; ignored otherwise if not PT_PS this is ignored.", + is_global, PT_G); + check_flag!(doc = "If IA32_EFER.NXE = 1, execute-disable. If 1, instruction fetches are not allowed from the 4-KByte region.", + is_instruction_fetching_disabled, PT_XD); } |