63 lines
1.8 KiB
Rust
63 lines
1.8 KiB
Rust
use core::{fmt, ops::Deref};
|
|
|
|
use super::VirtAddr;
|
|
use crate::os::EFlags;
|
|
|
|
/// Wrapper type for the interrupt stack frame pushed by the CPU.
|
|
///
|
|
/// This type derefs to an [`InterruptStackFrameValue`], which allows reading the actual values.
|
|
///
|
|
/// This wrapper ensures that the stack frame cannot be modified.
|
|
/// This prevents undefined behavior.
|
|
#[repr(transparent)]
|
|
pub struct InterruptStackFrame(InterruptStackFrameValue);
|
|
|
|
impl Deref for InterruptStackFrame {
|
|
type Target = InterruptStackFrameValue;
|
|
|
|
#[inline]
|
|
fn deref(&self) -> &Self::Target {
|
|
&self.0
|
|
}
|
|
}
|
|
|
|
impl fmt::Debug for InterruptStackFrame {
|
|
#[inline]
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
self.0.fmt(f)
|
|
}
|
|
}
|
|
|
|
/// Represents the interrupt stack frame pushed by the CPU on interrupt or exception entry.
|
|
///
|
|
/// See https://wiki.osdev.org/Interrupt_Service_Routines#x86
|
|
#[derive(Clone, Copy)]
|
|
#[repr(C)]
|
|
pub struct InterruptStackFrameValue {
|
|
/// This value points to the instruction that should be executed when the interrupt
|
|
/// handler returns. For most interrupts, this value points to the instruction immediately
|
|
/// following the last executed instruction. However, for some exceptions (e.g., page faults),
|
|
/// this value points to the faulting instruction, so that the instruction is restarted on
|
|
/// return.
|
|
pub eip: VirtAddr,
|
|
|
|
/// The code segment selector at the time of the interrupt.
|
|
pub cs: u16,
|
|
|
|
/// Padding for CS
|
|
_reserved1: [u8; 2],
|
|
|
|
/// The EFLAGS register before the interrupt handler was invoked.
|
|
pub cpu_flags: EFlags,
|
|
}
|
|
|
|
impl fmt::Debug for InterruptStackFrameValue {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
let mut s = f.debug_struct("InterruptStackFrame");
|
|
s.field("instruction_pointer", &self.eip);
|
|
s.field("code_segment", &self.cs);
|
|
s.field("cpu_flags", &self.cpu_flags);
|
|
s.finish()
|
|
}
|
|
}
|