Files
tetros/tetros/src/idt/stackframe.rs
Mark cf60d6734a
All checks were successful
CI / Typos (push) Successful in 13s
CI / Clippy (push) Successful in 32s
CI / Build (push) Successful in 1m15s
Comments
2025-03-04 19:41:22 -08:00

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()
}
}