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(super) unsafe fn store_ptr<const O: usize, T>(v: *const T) {
53 unsafe {
54 asm!("mov gs:[{o}], {v}", o = const O, v = in(reg) v, options(preserves_flags, nostack))
55 };
56 }
57
58 pub unsafe fn load_static_ptr<const O: usize, T>() -> *const T {
59 let mut v;
60
61 unsafe {
62 asm!(
63 "mov {out}, gs:[{off}]",
64 off = const O,
65 out = out(reg) v,
66 options(pure, nomem, preserves_flags, nostack)
67 )
68 };
69
70 v
71 }
72
73 pub unsafe fn load_ptr<const O: usize, T>() -> *const T {
74 let mut v;
75
76 unsafe {
77 asm!(
78 "mov {out}, gs:[{off}]",
79 off = const O,
80 out = out(reg) v,
81 options(pure, readonly, preserves_flags, nostack)
82 )
83 };
84
85 v
86 }
87
88 pub unsafe fn load_volatile_usize<const O: usize>() -> usize {
89 let mut v;
90
91 unsafe {
92 asm!(
93 "mov {out}, gs:[{off}]",
94 off = const O,
95 out = out(reg) v,
96 options(preserves_flags, nostack)
97 )
98 };
99
100 v
101 }
102}