twizzler_abi/arch/x86_64/
upcall.rs

1#[allow(unused_imports)]
2use crate::upcall::{UpcallData, UpcallInfo};
3
4pub const XSAVE_LEN: usize = 2048 + 1024;
5
6/// Arch-specific frame info for upcall.
7#[derive(Clone, Copy)]
8#[repr(C, align(64))]
9pub struct UpcallFrame {
10    pub xsave_region: [u8; XSAVE_LEN],
11    pub rip: u64,
12    pub rflags: u64,
13    pub rsp: u64,
14    pub rbp: u64,
15    pub rax: u64,
16    pub rbx: u64,
17    pub rcx: u64,
18    pub rdx: u64,
19    pub rdi: u64,
20    pub rsi: u64,
21    pub r8: u64,
22    pub r9: u64,
23    pub r10: u64,
24    pub r11: u64,
25    pub r12: u64,
26    pub r13: u64,
27    pub r14: u64,
28    pub r15: u64,
29    pub thread_ptr: u64,
30    pub prior_ctx: crate::object::ObjID,
31}
32
33impl core::fmt::Debug for UpcallFrame {
34    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
35        f.debug_struct("UpcallFrame")
36            .field("rip", &format_args!("0x{:x}", self.rip))
37            .field("rsp", &format_args!("0x{:x}", self.rsp))
38            .field("rbp", &format_args!("0x{:x}", self.rbp))
39            .field("rflags", &format_args!("0x{:x}", self.rflags))
40            .field("thread_ptr", &format_args!("0x{:x}", self.thread_ptr))
41            .field("prior_ctx", &format_args!("0x{:x}", self.prior_ctx))
42            .field("rax", &format_args!("0x{:x}", self.rax))
43            .field("rbx", &format_args!("0x{:x}", self.rbx))
44            .field("rcx", &format_args!("0x{:x}", self.rcx))
45            .field("rdx", &format_args!("0x{:x}", self.rdx))
46            .field("rdi", &format_args!("0x{:x}", self.rdi))
47            .field("rsi", &format_args!("0x{:x}", self.rsi))
48            .field("r8", &format_args!("0x{:x}", self.r8))
49            .field("r9", &format_args!("0x{:x}", self.r9))
50            .field("r10", &format_args!("0x{:x}", self.r10))
51            .field("r11", &format_args!("0x{:x}", self.r11))
52            .field("r12", &format_args!("0x{:x}", self.r12))
53            .field("r13", &format_args!("0x{:x}", self.r13))
54            .field("r14", &format_args!("0x{:x}", self.r14))
55            .field("r15", &format_args!("0x{:x}", self.r15))
56            .finish_non_exhaustive()
57    }
58}
59
60impl UpcallFrame {
61    /// Get the instruction pointer of the frame.
62    pub fn ip(&self) -> usize {
63        self.rip as usize
64    }
65
66    /// Get the stack pointer of the frame.
67    pub fn sp(&self) -> usize {
68        self.rsp as usize
69    }
70
71    /// Get the base pointer of the frame.
72    pub fn bp(&self) -> usize {
73        self.rbp as usize
74    }
75
76    /// Build a new frame set up to enter a context at a start point.
77    pub fn new_entry_frame(
78        stack_base: usize,
79        stack_size: usize,
80        tp: usize,
81        ctx: crate::object::ObjID,
82        entry: usize,
83        arg: usize,
84    ) -> Self {
85        Self {
86            xsave_region: [0; XSAVE_LEN],
87            rip: entry as u64,
88            // Default has the interrupt enabled flag set, and the reserved bit.
89            rflags: 0x202,
90            rsp: (stack_base + stack_size - 8) as u64,
91            rbp: 0,
92            rax: 0,
93            rbx: 0,
94            rcx: 0,
95            rdx: 0,
96            rdi: arg as u64,
97            rsi: 0,
98            r8: 0,
99            r9: 0,
100            r10: 0,
101            r11: 0,
102            r12: 0,
103            r13: 0,
104            r14: 0,
105            r15: 0,
106            thread_ptr: tp as u64,
107            prior_ctx: ctx,
108        }
109    }
110}