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            .finish_non_exhaustive()
43    }
44}
45
46impl UpcallFrame {
47    /// Get the instruction pointer of the frame.
48    pub fn ip(&self) -> usize {
49        self.rip as usize
50    }
51
52    /// Get the stack pointer of the frame.
53    pub fn sp(&self) -> usize {
54        self.rsp as usize
55    }
56
57    /// Get the base pointer of the frame.
58    pub fn bp(&self) -> usize {
59        self.rbp as usize
60    }
61
62    /// Build a new frame set up to enter a context at a start point.
63    pub fn new_entry_frame(
64        stack_base: usize,
65        stack_size: usize,
66        tp: usize,
67        ctx: crate::object::ObjID,
68        entry: usize,
69        arg: usize,
70    ) -> Self {
71        Self {
72            xsave_region: [0; XSAVE_LEN],
73            rip: entry as u64,
74            // Default has the interrupt enabled flag set, and the reserved bit.
75            rflags: 0x202,
76            rsp: (stack_base + stack_size - 8) as u64,
77            rbp: 0,
78            rax: 0,
79            rbx: 0,
80            rcx: 0,
81            rdx: 0,
82            rdi: arg as u64,
83            rsi: 0,
84            r8: 0,
85            r9: 0,
86            r10: 0,
87            r11: 0,
88            r12: 0,
89            r13: 0,
90            r14: 0,
91            r15: 0,
92            thread_ptr: tp as u64,
93            prior_ctx: ctx,
94        }
95    }
96}