rustubs/arch/x86_64/arch_regs.rs
1//! both [Context64] and [TrapFrame] define architecture specific registers and
2//! combine into the full execution context of a thread.
3//! [Context64] includes the callee saved registers plus FP state, and
4//! [TrapFrame] includes caller saved registers.
5
6use core::arch::asm;
7#[repr(C)]
8#[repr(packed)]
9#[derive(Debug)]
10/// the Context64 is part of the task struct; it's saved and restored explicitly
11/// on context swap.
12pub struct Context64 {
13 pub rbx: u64,
14 pub r12: u64,
15 pub r13: u64,
16 pub r14: u64,
17 pub r15: u64,
18 pub rbp: u64,
19 pub rsp: u64,
20 pub fpu: [u8; 108],
21}
22
23impl Default for Context64 {
24 fn default() -> Context64 {
25 Context64 {
26 rbx: 0,
27 r12: 0,
28 r13: 0,
29 r14: 0,
30 r15: 0,
31 rbp: 0,
32 rsp: 0,
33 fpu: [0; 108],
34 }
35 }
36}
37
38/// `TrapFrame` is saved and restored by the interrupt handler assembly code
39/// upon interrupt entry and exit.
40///
41/// The complete picture (in pushing sequence, addr from high to low)
42#[repr(C)]
43#[repr(packed)]
44#[derive(Debug)]
45pub struct TrapFrame {
46 // TODO the stack may need 16 byte alignment. Sanitize it!
47 // these are what we manually push in the vector wrapper.
48 // the "callee saved registers". See the documentations in vector.s
49 pub rbx: u64,
50 pub r12: u64,
51 pub r13: u64,
52 pub r14: u64,
53 pub r15: u64,
54 pub rbp: u64,
55 // the mandatory "caller saved registers"
56 // also the "caller saved registers"
57 pub r11: u64,
58 pub r10: u64,
59 pub r9: u64,
60 pub r8: u64,
61 pub rsi: u64,
62 pub rdi: u64,
63 pub rdx: u64,
64 pub rcx: u64,
65 pub rax: u64,
66 // below are automatically pushed by the CPU.
67 /// for some exceptions, the CPU automatically pushes an error code (see
68 /// `docs/interrupt.txt`) to the stack. For those who don't have error code,
69 /// we manually push a dummy value (0)
70 pub err_code: u64,
71 pub rip: u64,
72 pub cs: u64,
73 pub rflags: u64,
74 pub rsp: u64, // user stack
75 pub ss: u64, // all user segments share the same selector
76}
77
78/// get the current stack pointer
79#[inline]
80pub fn get_sp() -> u64 {
81 let sp: u64;
82 unsafe {
83 asm!("mov {}, rsp", out(reg) sp);
84 }
85 sp
86}
87
88impl TrapFrame {
89 /// get rpl from auto-pushed cs register
90 pub fn from_user(&self) -> bool { return (self.cs & 0b11) == 3; }
91}