diff --git a/Cargo.toml b/Cargo.toml index 8252a53..4c14fe9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,13 +7,11 @@ edition = "2021" log = "0.4.21" aarch64-cpu = "9.3" -smccc = "0.1.1" tock-registers = "0.8" numeric-enum-macro = "0.2" axerrno = "0.1.0" percpu = "0.1.4" -crate_interface = "0.1" axaddrspace = { git = "https://github.com/arceos-hypervisor/axaddrspace.git" } axvcpu = { git = "https://github.com/arceos-hypervisor/axvcpu.git", branch = "axvcpuhal" } diff --git a/src/exception.rs b/src/exception.rs index 7e9f1e6..5183933 100644 --- a/src/exception.rs +++ b/src/exception.rs @@ -206,9 +206,12 @@ fn handle_psci_call(ctx: &mut TrapFrame) -> Option> { }) } -/// Dispatches IRQs to the appropriate handler provided by the underlying host OS. +/// Dispatches IRQs to the appropriate handler provided by the underlying host OS, +/// which is registered at [`crate::pcpu::IRQ_HANDLER`] during `Aarch64PerCpu::new()`. fn dispatch_irq() { - crate_interface::call_interface!(crate::HalIf::irq_hanlder()) + unsafe { crate::pcpu::IRQ_HANDLER.current_ref_raw() } + .get() + .unwrap()() } /// A trampoline function for handling exceptions (VM exits) in EL2. diff --git a/src/lib.rs b/src/lib.rs index 9cc5c5e..39ad137 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -30,12 +30,3 @@ pub fn has_hardware_support() -> bool { // Current just return true by default. true } - -/// Low-level resource interfaces that must be implemented by the crate user. -#[crate_interface::def_interface] -pub trait HalIf { - /// Irq handler that has to be implemented by the user, - /// this handler is called when an interrupt is triggered with no active vcpu running. - /// TODO: find a way to convergence it inside [`axvcpu::AxVCpuHal`]. - fn irq_hanlder(); -} diff --git a/src/pcpu.rs b/src/pcpu.rs index dc6f7f5..98d4816 100644 --- a/src/pcpu.rs +++ b/src/pcpu.rs @@ -1,4 +1,4 @@ -use core::marker::PhantomData; +use core::{cell::OnceCell, marker::PhantomData}; use aarch64_cpu::registers::*; use tock_registers::interfaces::ReadWriteable; @@ -18,12 +18,24 @@ pub struct Aarch64PerCpu { #[percpu::def_percpu] static ORI_EXCEPTION_VECTOR_BASE: usize = 0; +/// IRQ handler registered by underlying host OS during per-cpu initialization, +/// for dispatching IRQs to the host OS. +/// +/// Set `IRQ_HANDLER` as per-cpu variable to avoid the need of `OnceLock`. +#[percpu::def_percpu] +pub static IRQ_HANDLER: OnceCell<&(dyn Fn() + Send + Sync)> = OnceCell::new(); + extern "C" { fn exception_vector_base_vcpu(); } impl AxArchPerCpu for Aarch64PerCpu { fn new(cpu_id: usize) -> AxResult { + // Register IRQ handler for this CPU. + let _ = unsafe { IRQ_HANDLER.current_ref_mut_raw() } + .set(&|| H::irq_hanlder()) + .map(|_| {}); + Ok(Self { cpu_id, _phantom: PhantomData,