ax_cpu/context.rs
1//! Machine context for the current CPU architecture.
2
3#[cfg(feature = "context")]
4pub use crate::arch::current::context::TaskContext;
5pub use crate::arch::current::{context::TrapFrame as UserRegisters, trap::KernelTrapFrame};
6
7/// Opaque task address installed in the architecture's current-task register.
8///
9/// The runtime owns the pointed-to object and its layout. Creating this value
10/// does not make the object readable or extend its lifetime. A context switch
11/// requires the runtime to keep the anchor pinned and alive through its use.
12#[repr(transparent)]
13#[derive(Clone, Copy, Debug, Eq, PartialEq)]
14pub struct TaskAnchor(core::ptr::NonNull<()>);
15
16impl TaskAnchor {
17 /// Erases the runtime object type without dereferencing its address.
18 pub const fn new<T>(pointer: core::ptr::NonNull<T>) -> Self {
19 Self(pointer.cast())
20 }
21
22 /// Returns the opaque runtime address.
23 pub const fn as_ptr(self) -> *mut () {
24 self.0.as_ptr()
25 }
26}
27
28/// Kernel task-local storage base owned by one execution context.
29///
30/// This value follows a task across CPUs. It must never be used as a CPU-local
31/// anchor or initialized from an architecture per-CPU register.
32#[repr(transparent)]
33#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
34pub struct KernelTlsBase(usize);
35
36impl KernelTlsBase {
37 /// Creates a kernel TLS base from its virtual address.
38 pub const fn new(address: usize) -> Self {
39 Self(address)
40 }
41
42 /// Returns the virtual address represented by this TLS base.
43 pub const fn as_usize(self) -> usize {
44 self.0
45 }
46
47 #[cfg(feature = "context")]
48 pub(crate) fn for_task_context(requested: Self) -> Self {
49 if cfg!(kernel_tls) {
50 requested
51 } else {
52 assert!(
53 requested.0 == 0,
54 "LinuxCurrent task contexts must not own a kernel TLS register"
55 );
56 Self(0)
57 }
58 }
59}