/* Rflags Register */ /// Carry flag. pub const RFLAGS_CF: u64 = 1 << 0; /// Parity flag. pub const RFLAGS_PF: u64 = 1 << 2; /// Adjust flag. pub const RFLAGS_AF: u64 = 1 << 4; /// Zero flag. pub const RFLAGS_ZF: u64 = 1 << 6; /// Sign flag. pub const RFLAGS_SF: u64 = 1 << 7; /// Sign flag. pub const RFLAGS_IF: u64 = 1 << 9; /// Direction flag. pub const RFLAGS_DF: u64 = 1 << 10; /// Overflow flag. pub const RFLAGS_OF: u64 = 1 << 11; /// I/O privilege level. pub const RFLAGS_IOPL: u64 = 0b11 << 12; /// Alignment check. pub const RFLAGS_AC: u64 = 1 << 18; pub const fn rflags_cf(r: u64) -> u64 { (r & RFLAGS_CF) >> 0 } pub const fn rflags_pf(r: u64) -> u64 { (r & RFLAGS_PF) >> 2 } pub const fn rflags_af(r: u64) -> u64 { (r & RFLAGS_AF) >> 4 } pub const fn rflags_zf(r: u64) -> u64 { (r & RFLAGS_ZF) >> 6 } pub const fn rflags_sf(r: u64) -> u64 { (r & RFLAGS_SF) >> 7 } pub const fn rflags_if(r: u64) -> u64 { (r & RFLAGS_IF) >> 9 } pub const fn rflags_df(r: u64) -> u64 { (r & RFLAGS_DF) >> 10 } pub const fn rflags_of(r: u64) -> u64 { (r & RFLAGS_OF) >> 11 } pub const fn rflags_iopl(r: u64) -> u64 { (r & RFLAGS_IOPL) >> 12 } pub const fn rflags_ac(r: u64) -> u64 { (r & RFLAGS_AC) >> 18 } /* Segment Selector */ /// Requested privilege level. /// /// Privilege level of the segment selector, where `0` is the most privileged mode and `3` the /// least. pub const SEG_SELECTOR_RPL : u16 = 0b11 << 0; /// Table indicator. /// /// | TI | Table | /// |----|-------| /// | 0 | GDT | /// | 1 | LDT | pub const SEG_SELECTOR_TI : u16 = 1 << 2; /// Table index. /// /// Index into the `GDT` or `LDT` table to select the segment descriptor. `GDT.base + 8 * index` /// gives the address of the segment descriptor (times `8` because every segment descriptor is `8 /// byte`). pub const SEG_SELECTOR_INDEX : u16 = 0x1fff << 3; pub const fn seg_selector_rpl(s : u16) -> u16 { (s & SEG_SELECTOR_RPL) >> 0 } pub const fn seg_selector_ti(s : u16) -> u16 { (s & SEG_SELECTOR_TI) >> 2 } pub const fn seg_selector_index(s : u16) -> u16 { (s & SEG_SELECTOR_INDEX) >> 3 } /* Control Register CR0 (operation mode & state of the processor) */ /// Protection Enable. /// /// Enables `protected mode` when set and `real-address mode` when cleared. This enables /// `segment-level protection` not paging. pub const CR0_PE: u64 = 1 << 0; /// Monitor Coprocessor. pub const CR0_MP: u64 = 1 << 1; /// Emulation. /// /// When set indicates the process does not have a FPU. FPU instructions will generate an exception /// that software can emulate the instruction. pub const CR0_EM: u64 = 1 << 2; /// Task Switched. pub const CR0_TS: u64 = 1 << 3; /// Extension Type. pub const CR0_ET: u64 = 1 << 4; /// Numeric Error. pub const CR0_NE: u64 = 1 << 5; /// Write Protect. /// /// When set supervisor-level procedures can't write to read-only pages. pub const CR0_WP: u64 = 1 << 16; /// Alignment Mask. /// /// Enables alignment check for `CPL=3`, check is only done if the [AC /// bit](crate::x86_64::RFLAGS_AC) of the `rflags` register ist set. pub const CR0_AM: u64 = 1 << 18; /// Not Write-Torugh. pub const CR0_NW: u64 = 1 << 29; /// Cachine disable. pub const CR0_CD: u64 = 1 << 30; /// Paging. /// /// Enables paging when set, requires [CR0_PE](crate::x86_64::CR0_PE) to be set as well. pub const CR0_PG: u64 = 1 << 31; /* Control Register CR3 (paging information) * * Holds the physical base address of the first paging structure. The 12 lower bytes of the base * address are assumed to be 0 and hence the first paging structure must be aligned to a 4K * boundary. */ /// Mask for physical base address of paging structure. pub const CR3_PAGE_BASE_MASK: u64 = 0xffff_ffff_ffff_0000; /// Page-level Write-Through. pub const CR3_PWT: u64 = 1 << 3; /// Page-level Cache Disable. pub const CR3_PCD: u64 = 1 << 4; /* Control Register CR4 (flags for arch extenstions processor capabilities) */ /// Physical Address Extenstion. /// /// When set enables paging to produce physicall addresses with more than 32 bits. Required before /// entering `long mode`. pub const CR4_PAE: u64 = 1 << 5; /// 57-bit Linear Addresses. /// /// When set in `long mode` enables `5-level` paging to translate `57-bit` linear addresses. When /// cleared use `4-level` paging to translate `48-bit` linear addresses. pub const CR4_LA57: u64 = 1 << 5; /* Extended Feature Enable Register (EFER) */ pub const MSR_EFER: u64 = 0xc000_0080; /// Long Mode Enable. /// /// When set enables long mode operations. pub const EFER_LME: u64 = 1 << 8; /// Long Mode Active (readonly). /// /// When set indicates long mode is active. pub const EFER_LMA: u64 = 1 << 10; /* Paging */ /// Page entry present. pub const PAGE_ENTRY_PRESENT : u64 = 1 << 0; /// Page region read/write. /// /// If set, region reference by paging entry is writeable. pub const PAGE_RENTRY_RW : u64 = 1 << 1;