patina_internal_cpu 23.3.0

CPU support.
Documentation
//! X64 Interrupt module
//!
//! ## License
//!
//! Copyright (c) Microsoft Corporation.
//!
//! SPDX-License-Identifier: Apache-2.0
//!

use crate::{interrupts::ExceptionContextX64, log_registers};
use patina::pi::protocol::cpu_arch::EfiSystemContext;
use patina_stacktrace::{StackFrame, StackTrace};

#[cfg(target_os = "uefi")]
mod idt;
mod interrupt_manager;

#[allow(unused)]
pub use interrupt_manager::InterruptsX64;

impl super::EfiSystemContextFactory for ExceptionContextX64 {
    fn create_efi_system_context(&mut self) -> EfiSystemContext {
        EfiSystemContext { system_context_x64: core::ptr::from_mut(self) }
    }
}

impl super::EfiExceptionInfoDump for ExceptionContextX64 {
    fn dump_stack_trace(&self) {
        let stack_frame = StackFrame { pc: self.rip, sp: self.rsp, fp: self.rbp };
        // SAFETY: Called during exception handling with CPU context registers. The exception context
        // is considered valid to dump at this time.
        if let Err(err) = unsafe { StackTrace::dump_with(stack_frame) } {
            log::error!("StackTrace: {err}");
        }
    }

    fn dump_system_context_registers(&self) {
        log::error!("Control Registers:");
        log_registers!(
            "CR0",
            self.cr0,
            "CR2",
            self.cr2,
            "CR3",
            self.cr3,
            "CR4",
            self.cr4,
            "RIP",
            self.rip,
            "CS",
            self.cs,
            "SS",
            self.ss,
            "DS",
            self.ds,
            "RSP",
            self.rsp,
            "RFLAGS",
            self.rflags
        );

        log::error!("");

        log::error!("General-Purpose Registers:");
        log_registers!(
            "RAX", self.rax, "RBX", self.rbx, "RCX", self.rcx, "RDX", self.rdx, "RSI", self.rsi, "RDI", self.rdi,
            "RBP", self.rbp, "R8", self.r8, "R9", self.r9, "R10", self.r10, "R11", self.r11, "R12", self.r12, "R13",
            self.r13, "R14", self.r14, "R15", self.r15
        );

        log::debug!("Full Context: {self:#X?}");
    }
}