diff options
Diffstat (limited to 'src/x86_64.rs')
-rw-r--r-- | src/x86_64.rs | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/src/x86_64.rs b/src/x86_64.rs new file mode 100644 index 0000000..978bd84 --- /dev/null +++ b/src/x86_64.rs @@ -0,0 +1,146 @@ +/* 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; |