kvm_rs/
x86_64.rs

1// SPDX-License-Identifier: MIT
2//
3// Copyright (c) 2021, Johannes Stoelp <dev@memzero.de>
4
5//! `x86_64` flags and bitfields.
6
7pub use x86_64::*;
8
9#[rustfmt::skip]
10mod x86_64 {
11    /* Rflags Register */
12
13    /// Carry flag.
14    pub const RFLAGS_CF: u64 = 1 << 0;
15    /// Parity flag.
16    pub const RFLAGS_PF: u64 = 1 << 2;
17    /// Adjust flag.
18    pub const RFLAGS_AF: u64 = 1 << 4;
19    /// Zero flag.
20    pub const RFLAGS_ZF: u64 = 1 << 6;
21    /// Sign flag.
22    pub const RFLAGS_SF: u64 = 1 << 7;
23    /// Trap flag.
24    pub const RFLAGS_TF: u64 = 1 << 8;
25    /// Sign flag.
26    pub const RFLAGS_IF: u64 = 1 << 9;
27    /// Direction flag.
28    pub const RFLAGS_DF: u64 = 1 << 10;
29    /// Overflow flag.
30    pub const RFLAGS_OF: u64 = 1 << 11;
31    /// I/O privilege level.
32    pub const RFLAGS_IOPL: u64 = 0b11 << 12;
33    /// Alignment check.
34    pub const RFLAGS_AC: u64 = 1 << 18;
35
36    pub const fn rflags_cf(r: u64) -> u64   { (r & RFLAGS_CF)   >> 0 }
37    pub const fn rflags_pf(r: u64) -> u64   { (r & RFLAGS_PF)   >> 2 }
38    pub const fn rflags_af(r: u64) -> u64   { (r & RFLAGS_AF)   >> 4 }
39    pub const fn rflags_zf(r: u64) -> u64   { (r & RFLAGS_ZF)   >> 6 }
40    pub const fn rflags_sf(r: u64) -> u64   { (r & RFLAGS_SF)   >> 7 }
41    pub const fn rflags_tf(r: u64) -> u64   { (r & RFLAGS_TF)   >> 8 }
42    pub const fn rflags_if(r: u64) -> u64   { (r & RFLAGS_IF)   >> 9 }
43    pub const fn rflags_df(r: u64) -> u64   { (r & RFLAGS_DF)   >> 10 }
44    pub const fn rflags_of(r: u64) -> u64   { (r & RFLAGS_OF)   >> 11 }
45    pub const fn rflags_iopl(r: u64) -> u64 { (r & RFLAGS_IOPL) >> 12 }
46    pub const fn rflags_ac(r: u64) -> u64   { (r & RFLAGS_AC)   >> 18 }
47
48    /* Segment Selector */
49
50    /// Requested privilege level.
51    ///
52    /// Privilege level of the segment selector, where `0` is the most privileged mode and `3` the
53    /// least.
54    pub const SEG_SELECTOR_RPL: u16 = 0b11 << 0;
55    /// Table indicator.
56    ///
57    /// | TI | Table |
58    /// |----|-------|
59    /// | 0  | GDT   |
60    /// | 1  | LDT   |
61    pub const SEG_SELECTOR_TI: u16 = 1 << 2;
62    /// Table index.
63    ///
64    /// Index into the `GDT` or `LDT` table to select the segment descriptor. `GDT.base + 8 * index`
65    /// gives the address of the segment descriptor (times `8` because every segment descriptor is `8
66    /// byte`).
67    pub const SEG_SELECTOR_INDEX: u16 = 0x1fff << 3;
68
69    pub const fn seg_selector_rpl(s: u16) -> u16   { (s & SEG_SELECTOR_RPL)   >> 0 }
70    pub const fn seg_selector_ti(s: u16) -> u16    { (s & SEG_SELECTOR_TI)    >> 2 }
71    pub const fn seg_selector_index(s: u16) -> u16 { (s & SEG_SELECTOR_INDEX) >> 3 }
72
73    /* Control Register CR0 (operation mode & state of the processor) */
74
75    /// Protection Enable.
76    ///
77    /// Enables `protected mode` when set and `real-address mode` when cleared. This enables
78    /// `segment-level protection` not paging.
79    pub const CR0_PE: u64 = 1 << 0;
80    /// Monitor Coprocessor.
81    pub const CR0_MP: u64 = 1 << 1;
82    /// Emulation.
83    ///
84    /// When set indicates the process does not have a FPU. FPU instructions will generate an exception
85    /// that software can emulate the instruction.
86    pub const CR0_EM: u64 = 1 << 2;
87    /// Task Switched.
88    pub const CR0_TS: u64 = 1 << 3;
89    /// Extension Type.
90    pub const CR0_ET: u64 = 1 << 4;
91    /// Numeric Error.
92    pub const CR0_NE: u64 = 1 << 5;
93    /// Write Protect.
94    ///
95    /// When set supervisor-level procedures can't write to read-only pages.
96    pub const CR0_WP: u64 = 1 << 16;
97    /// Alignment Mask.
98    ///
99    /// Enables alignment check for `CPL=3`, check is only done if the [AC
100    /// bit](crate::x86_64::RFLAGS_AC) of the `rflags` register ist set.
101    pub const CR0_AM: u64 = 1 << 18;
102    /// Not Write-Torugh.
103    pub const CR0_NW: u64 = 1 << 29;
104    /// Cachine disable.
105    pub const CR0_CD: u64 = 1 << 30;
106    /// Paging.
107    ///
108    /// Enables paging when set, requires [CR0_PE](crate::x86_64::CR0_PE) to be set as well.
109    pub const CR0_PG: u64 = 1 << 31;
110
111    /* Control Register CR3 (paging information)
112     *
113     * Holds the physical base address of the first paging structure. The 12 lower bytes of the base
114     * address are assumed to be 0 and hence the first paging structure must be aligned to a 4K
115     * boundary.
116     */
117
118    /// Mask for physical base address of paging structure.
119    pub const CR3_PAGE_BASE_MASK: u64 = 0xffff_ffff_ffff_0000;
120
121    /// Page-level Write-Through.
122    pub const CR3_PWT: u64 = 1 << 3;
123    /// Page-level Cache Disable.
124    pub const CR3_PCD: u64 = 1 << 4;
125
126    /* Control Register CR4 (flags for arch extenstions processor capabilities) */
127
128    /// Physical Address Extenstion.
129    ///
130    /// When set enables paging to produce physicall addresses with more than 32 bits. Required before
131    /// entering `long mode`.
132    pub const CR4_PAE: u64 = 1 << 5;
133    /// 57-bit Linear Addresses.
134    ///
135    /// When set in `long mode` enables `5-level` paging to translate `57-bit` linear addresses. When
136    /// cleared use `4-level` paging to translate `48-bit` linear addresses.
137    pub const CR4_LA57: u64 = 1 << 5;
138
139    /* Extended Feature Enable Register (EFER) */
140
141    /// Extended Feature Enable Register MSR number.
142    ///
143    /// MSR number used with the [`rdmsr`][msr] and [`wrmsr`][msr] instructions to read/write the
144    /// `EFER` model specific register.
145    ///
146    /// [msr]: https://johannst.github.io/notes/arch/x86_64.html#model-specific-register-msr
147    pub const MSR_EFER: u64 = 0xc000_0080;
148
149    /// Long Mode Enable.
150    ///
151    /// When set enables long mode operations.
152    pub const EFER_LME: u64 = 1 << 8;
153    /// Long Mode Active (readonly).
154    ///
155    /// When set indicates long mode is active.
156    pub const EFER_LMA: u64 = 1 << 10;
157
158    /* Paging */
159
160    /// Page entry present.
161    pub const PAGE_ENTRY_PRESENT: u64 = 1 << 0;
162    /// Page region read/write.
163    ///
164    /// If set, region reference by paging entry is writeable.
165    pub const PAGE_ENTRY_RW: u64 = 1 << 1;
166}