|
@@ -1,180 +1,6 @@
|
|
|
-use core::{
|
|
|
|
|
- arch::{asm, global_asm},
|
|
|
|
|
- pin::Pin,
|
|
|
|
|
- ptr::NonNull,
|
|
|
|
|
-};
|
|
|
|
|
-
|
|
|
|
|
-use crate::rdmsr;
|
|
|
|
|
-
|
|
|
|
|
use super::pause;
|
|
use super::pause;
|
|
|
-
|
|
|
|
|
-global_asm!(
|
|
|
|
|
- r"
|
|
|
|
|
- .set RAX, 0x00
|
|
|
|
|
- .set RBX, 0x08
|
|
|
|
|
- .set RCX, 0x10
|
|
|
|
|
- .set RDX, 0x18
|
|
|
|
|
- .set RDI, 0x20
|
|
|
|
|
- .set RSI, 0x28
|
|
|
|
|
- .set R8, 0x30
|
|
|
|
|
- .set R9, 0x38
|
|
|
|
|
- .set R10, 0x40
|
|
|
|
|
- .set R11, 0x48
|
|
|
|
|
- .set R12, 0x50
|
|
|
|
|
- .set R13, 0x58
|
|
|
|
|
- .set R14, 0x60
|
|
|
|
|
- .set R15, 0x68
|
|
|
|
|
- .set RBP, 0x70
|
|
|
|
|
- .set INT_NO, 0x78
|
|
|
|
|
- .set ERRCODE, 0x80
|
|
|
|
|
- .set RIP, 0x88
|
|
|
|
|
- .set CS, 0x90
|
|
|
|
|
- .set FLAGS, 0x98
|
|
|
|
|
- .set RSP, 0xa0
|
|
|
|
|
- .set SS, 0xa8
|
|
|
|
|
-
|
|
|
|
|
- .macro movcfi reg, offset
|
|
|
|
|
- mov \reg, \offset(%rsp)
|
|
|
|
|
- .cfi_rel_offset \reg, \offset
|
|
|
|
|
- .endm
|
|
|
|
|
-
|
|
|
|
|
- .macro movrst reg, offset
|
|
|
|
|
- mov \offset(%rsp), \reg
|
|
|
|
|
- .cfi_restore \reg
|
|
|
|
|
- .endm
|
|
|
|
|
-
|
|
|
|
|
- .globl ISR_stub_restore
|
|
|
|
|
- .type ISR_stub_restore @function
|
|
|
|
|
-
|
|
|
|
|
- ISR_stub:
|
|
|
|
|
- .cfi_startproc
|
|
|
|
|
- .cfi_signal_frame
|
|
|
|
|
- .cfi_def_cfa_offset 0x18
|
|
|
|
|
- .cfi_offset %rsp, 0x10
|
|
|
|
|
-
|
|
|
|
|
- cmpq $0x08, 24(%rsp)
|
|
|
|
|
- je 1f
|
|
|
|
|
- swapgs
|
|
|
|
|
-
|
|
|
|
|
- 1:
|
|
|
|
|
- sub $0x78, %rsp
|
|
|
|
|
- .cfi_def_cfa_offset 0x90
|
|
|
|
|
-
|
|
|
|
|
- movcfi %rax, RAX
|
|
|
|
|
- movcfi %rbx, RBX
|
|
|
|
|
- movcfi %rcx, RCX
|
|
|
|
|
- movcfi %rdx, RDX
|
|
|
|
|
- movcfi %rdi, RDI
|
|
|
|
|
- movcfi %rsi, RSI
|
|
|
|
|
- movcfi %r8, R8
|
|
|
|
|
- movcfi %r9, R9
|
|
|
|
|
- movcfi %r10, R10
|
|
|
|
|
- movcfi %r11, R11
|
|
|
|
|
- movcfi %r12, R12
|
|
|
|
|
- movcfi %r13, R13
|
|
|
|
|
- movcfi %r14, R14
|
|
|
|
|
- movcfi %r15, R15
|
|
|
|
|
- movcfi %rbp, RBP
|
|
|
|
|
-
|
|
|
|
|
- mov INT_NO(%rsp), %rax
|
|
|
|
|
- sub $ISR0, %rax
|
|
|
|
|
- shr $3, %rax
|
|
|
|
|
- mov %rax, INT_NO(%rsp)
|
|
|
|
|
-
|
|
|
|
|
- mov %rsp, %rbx
|
|
|
|
|
- .cfi_def_cfa_register %rbx
|
|
|
|
|
-
|
|
|
|
|
- and $~0xf, %rsp
|
|
|
|
|
- sub $512, %rsp
|
|
|
|
|
- fxsave (%rsp)
|
|
|
|
|
-
|
|
|
|
|
- mov %rbx, %rdi
|
|
|
|
|
- mov %rsp, %rsi
|
|
|
|
|
-
|
|
|
|
|
- ISR_stub_restore:
|
|
|
|
|
- fxrstor (%rsp)
|
|
|
|
|
- mov %rbx, %rsp
|
|
|
|
|
- .cfi_def_cfa_register %rsp
|
|
|
|
|
-
|
|
|
|
|
- .globl _arch_fork_return
|
|
|
|
|
- _arch_fork_return:
|
|
|
|
|
- movrst %rax, RAX
|
|
|
|
|
- movrst %rbx, RBX
|
|
|
|
|
- movrst %rcx, RCX
|
|
|
|
|
- movrst %rdx, RDX
|
|
|
|
|
- movrst %rdi, RDI
|
|
|
|
|
- movrst %rsi, RSI
|
|
|
|
|
- movrst %r8, R8
|
|
|
|
|
- movrst %r9, R9
|
|
|
|
|
- movrst %r10, R10
|
|
|
|
|
- movrst %r11, R11
|
|
|
|
|
- movrst %r12, R12
|
|
|
|
|
- movrst %r13, R13
|
|
|
|
|
- movrst %r14, R14
|
|
|
|
|
- movrst %r15, R15
|
|
|
|
|
- movrst %rbp, RBP
|
|
|
|
|
-
|
|
|
|
|
- add $0x88, %rsp
|
|
|
|
|
- .cfi_def_cfa_offset 0x08
|
|
|
|
|
-
|
|
|
|
|
- cmpq $0x08, 8(%rsp)
|
|
|
|
|
- je 1f
|
|
|
|
|
- swapgs
|
|
|
|
|
-
|
|
|
|
|
- 1:
|
|
|
|
|
- iretq
|
|
|
|
|
- .cfi_endproc
|
|
|
|
|
-
|
|
|
|
|
- .section .rodata
|
|
|
|
|
-
|
|
|
|
|
- .align 8
|
|
|
|
|
- .globl ISR_START_ADDR
|
|
|
|
|
- .type ISR_START_ADDR @object
|
|
|
|
|
- ISR_START_ADDR:
|
|
|
|
|
- .quad 0
|
|
|
|
|
- ",
|
|
|
|
|
- options(att_syntax),
|
|
|
|
|
-);
|
|
|
|
|
-
|
|
|
|
|
-/// Saved registers when a trap (interrupt or exception) occurs.
|
|
|
|
|
-#[allow(missing_docs)]
|
|
|
|
|
-#[repr(C)]
|
|
|
|
|
-#[derive(Debug, Default, Clone, Copy)]
|
|
|
|
|
-pub struct InterruptContext {
|
|
|
|
|
- pub rax: u64,
|
|
|
|
|
- pub rbx: u64,
|
|
|
|
|
- pub rcx: u64,
|
|
|
|
|
- pub rdx: u64,
|
|
|
|
|
- pub rdi: u64,
|
|
|
|
|
- pub rsi: u64,
|
|
|
|
|
- pub r8: u64,
|
|
|
|
|
- pub r9: u64,
|
|
|
|
|
- pub r10: u64,
|
|
|
|
|
- pub r11: u64,
|
|
|
|
|
- pub r12: u64,
|
|
|
|
|
- pub r13: u64,
|
|
|
|
|
- pub r14: u64,
|
|
|
|
|
- pub r15: u64,
|
|
|
|
|
- pub rbp: u64,
|
|
|
|
|
-
|
|
|
|
|
- pub int_no: u64,
|
|
|
|
|
- pub error_code: u64,
|
|
|
|
|
-
|
|
|
|
|
- // Pushed by CPU
|
|
|
|
|
- pub rip: u64,
|
|
|
|
|
- pub cs: u64,
|
|
|
|
|
- pub eflags: u64,
|
|
|
|
|
- pub rsp: u64,
|
|
|
|
|
- pub ss: u64,
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-#[allow(missing_docs)]
|
|
|
|
|
-#[repr(C)]
|
|
|
|
|
-#[derive(Clone, Copy)]
|
|
|
|
|
-pub struct ExtendedContext {
|
|
|
|
|
- /// For FPU states
|
|
|
|
|
- data: [u8; 512],
|
|
|
|
|
-}
|
|
|
|
|
|
|
+use crate::rdmsr;
|
|
|
|
|
+use core::{arch::asm, pin::Pin, ptr::NonNull};
|
|
|
|
|
|
|
|
#[repr(C)]
|
|
#[repr(C)]
|
|
|
#[derive(Clone, Copy)]
|
|
#[derive(Clone, Copy)]
|
|
@@ -204,42 +30,6 @@ pub struct InterruptControl {
|
|
|
/// State of the interrupt flag.
|
|
/// State of the interrupt flag.
|
|
|
pub struct IrqState(u64);
|
|
pub struct IrqState(u64);
|
|
|
|
|
|
|
|
-impl InterruptContext {
|
|
|
|
|
- pub fn set_return_value(&mut self, value: u64) {
|
|
|
|
|
- // The return value is stored in rax.
|
|
|
|
|
- self.rax = value;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- pub fn set_return_address(&mut self, addr: u64, user: bool) {
|
|
|
|
|
- // The return address is stored in rip.
|
|
|
|
|
- self.rip = addr;
|
|
|
|
|
- if user {
|
|
|
|
|
- self.cs = 0x2b; // User code segment
|
|
|
|
|
- } else {
|
|
|
|
|
- self.cs = 0x08; // Kernel code segment
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- pub fn set_stack_pointer(&mut self, sp: u64, user: bool) {
|
|
|
|
|
- // The stack pointer is stored in rsp.
|
|
|
|
|
- self.rsp = sp;
|
|
|
|
|
- if user {
|
|
|
|
|
- self.ss = 0x33; // User stack segment
|
|
|
|
|
- } else {
|
|
|
|
|
- self.ss = 0x10; // Kernel stack segment
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- pub fn set_interrupt_enabled(&mut self, enabled: bool) {
|
|
|
|
|
- // The interrupt state is stored in eflags.
|
|
|
|
|
- if enabled {
|
|
|
|
|
- self.eflags |= 0x200; // Set the interrupt flag
|
|
|
|
|
- } else {
|
|
|
|
|
- self.eflags &= !0x200; // Clear the interrupt flag
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
impl IDTEntry {
|
|
impl IDTEntry {
|
|
|
const fn new(offset: usize, selector: u16, attributes: u8) -> Self {
|
|
const fn new(offset: usize, selector: u16, attributes: u8) -> Self {
|
|
|
Self {
|
|
Self {
|