114 lines
3.0 KiB
Rust
114 lines
3.0 KiB
Rust
use core::arch::asm;
|
|
|
|
#[repr(C)]
|
|
pub struct Thread {
|
|
id: usize,
|
|
/// This shall be default before the program is interrupted, otherwise it will store
|
|
/// CPU registers etc to be restored on context switch.
|
|
ctx: ThreadContext,
|
|
}
|
|
|
|
/// CPU state to be saved on context switches.
|
|
#[repr(C)]
|
|
#[derive(Default)]
|
|
pub struct ThreadContext {
|
|
/// Accumulator register.
|
|
rax: u64,
|
|
/// Base register.
|
|
rbx: u64,
|
|
/// Counter register.
|
|
rcx: u64,
|
|
/// Data register.
|
|
rdx: u64,
|
|
/// Source index register.
|
|
rsi: u64,
|
|
/// Destination index register.
|
|
rdi: u64,
|
|
/// Base pointer register.
|
|
rbp: u64,
|
|
/// Stack pointer register.
|
|
rsp: u64,
|
|
/// An extended register.
|
|
r8: u64,
|
|
/// An extended register.
|
|
r9: u64,
|
|
/// An extended register.
|
|
r10: u64,
|
|
/// An extended register.
|
|
r11: u64,
|
|
/// An extended register.
|
|
r12: u64,
|
|
/// An extended register.
|
|
r13: u64,
|
|
/// An extended register.
|
|
r14: u64,
|
|
/// An extended register.
|
|
r15: u64,
|
|
/// The instruction pointer.
|
|
rip: u64,
|
|
/// RFLAGS register.
|
|
rflags: u64,
|
|
}
|
|
|
|
impl ThreadContext {
|
|
/// Saves the current registers of the CPU before a context switch
|
|
/// to be restored later.
|
|
///
|
|
/// # Notes
|
|
///
|
|
/// This function should ONLY be called in interrupt handlers such
|
|
/// as that of the timer. This will then save registers as required
|
|
///
|
|
///
|
|
/// # Safety
|
|
///
|
|
/// This function is unsafe because of the usage of inline ASM.
|
|
#[inline(always)]
|
|
pub unsafe fn save_registers() -> Self {
|
|
let mut context = Self::default();
|
|
unsafe {
|
|
asm!(
|
|
"mov {0}, rax",
|
|
"mov {1}, rbx",
|
|
"mov {2}, rcx",
|
|
"mov {3}, rdx",
|
|
"mov {4}, rsi",
|
|
"mov {5}, rdi",
|
|
"mov {6}, rbp",
|
|
"mov {7}, rsp",
|
|
"mov {8}, r8",
|
|
"mov {9}, r9",
|
|
"mov {10}, r10",
|
|
"mov {11}, r11",
|
|
"mov {12}, r12",
|
|
"mov {13}, r13",
|
|
"mov {14}, r14",
|
|
"mov {15}, r15",
|
|
"lea {16}, [rip]",
|
|
"pushf",
|
|
"pop {17}",
|
|
out(reg) context.rax,
|
|
out(reg) context.rbx,
|
|
out(reg) context.rcx,
|
|
out(reg) context.rdx,
|
|
out(reg) context.rsi,
|
|
out(reg) context.rdi,
|
|
out(reg) context.rbp,
|
|
out(reg) context.rsp,
|
|
out(reg) context.r8,
|
|
out(reg) context.r9,
|
|
out(reg) context.r10,
|
|
out(reg) context.r11,
|
|
out(reg) context.r12,
|
|
out(reg) context.r13,
|
|
out(reg) context.r14,
|
|
out(reg) context.r15,
|
|
out(reg) context.rip,
|
|
out(reg) context.rflags,
|
|
);
|
|
}
|
|
|
|
context
|
|
}
|
|
}
|