1use super::Base;
2use crate::arch::{ArchConfig, wrmsr};
3use core::arch::asm;
4use core::marker::PhantomPinned;
5use core::mem::offset_of;
6use core::pin::Pin;
7
8pub const fn current_trap_rsp_offset() -> usize {
9 offset_of!(Context, trap_rsp)
10}
11
12pub const fn current_user_rsp_offset() -> usize {
13 offset_of!(Context, user_rsp)
14}
15
16#[repr(C)]
18pub(super) struct Context {
19 pub base: Base, pub trap_rsp: *mut u8, pub user_rsp: usize, phantom: PhantomPinned,
23}
24
25impl Context {
26 pub fn new(base: Base, arch: &ArchConfig) -> Self {
27 Self {
28 base,
29 trap_rsp: arch.trap_rsp as *mut u8,
30 user_rsp: 0,
31 phantom: PhantomPinned,
32 }
33 }
34
35 pub unsafe fn activate(self: Pin<&mut Self>) {
44 unsafe { wrmsr(0xc0000101, self.get_unchecked_mut() as *mut Self as usize) };
46
47 unsafe { wrmsr(0xc0000100, 0) };
49 unsafe { wrmsr(0xc0000102, 0) };
50 }
51
52 pub unsafe fn load_static_ptr<const O: usize, T>() -> *const T {
53 let mut v;
54
55 unsafe {
56 asm!(
57 "mov {out}, gs:[{off}]",
58 off = const O,
59 out = out(reg) v,
60 options(pure, nomem, preserves_flags, nostack)
61 )
62 };
63
64 v
65 }
66
67 pub unsafe fn load_ptr<const O: usize, T>() -> *const T {
68 let mut v;
69
70 unsafe {
71 asm!(
72 "mov {out}, gs:[{off}]",
73 off = const O,
74 out = out(reg) v,
75 options(pure, readonly, preserves_flags, nostack)
76 )
77 };
78
79 v
80 }
81
82 pub unsafe fn load_volatile_usize<const O: usize>() -> usize {
83 let mut v;
84
85 unsafe {
86 asm!(
87 "mov {out}, gs:[{off}]",
88 off = const O,
89 out = out(reg) v,
90 options(preserves_flags, nostack)
91 )
92 };
93
94 v
95 }
96}