use alloc::boxed::Box;
use core::time::Duration;
use ax_memory_addr::{PhysAddr, VirtAddr};
#[ax_crate_interface::def_interface]
pub trait ArmVgicHostIf {
fn alloc_contiguous_frames(frame_count: usize, frame_align: usize) -> Option<PhysAddr>;
fn dealloc_contiguous_frames(start_paddr: PhysAddr, frame_count: usize);
fn phys_to_virt(paddr: PhysAddr) -> VirtAddr;
fn host_cpu_num() -> usize;
fn current_vm_id() -> usize;
fn current_vcpu_id() -> usize;
fn queue_virtual_interrupt(vm_id: usize, vcpu_id: usize, vector: u8);
fn current_time_nanos() -> u64;
fn register_timer(
deadline: Duration,
callback: Box<dyn FnOnce(Duration) + Send + 'static>,
) -> usize;
fn cancel_timer(token: usize);
fn read_vgicd_iidr() -> u32;
fn read_vgicd_typer() -> u32;
fn get_host_gicd_base() -> PhysAddr;
fn get_host_gicr_base() -> PhysAddr;
fn hardware_inject_virtual_interrupt(vector: u8);
}
#[cfg(feature = "vgicv3")]
pub(crate) fn alloc_contiguous_frames(frame_count: usize, frame_align: usize) -> Option<PhysAddr> {
ax_crate_interface::call_interface!(ArmVgicHostIf::alloc_contiguous_frames(
frame_count,
frame_align
))
}
#[cfg(feature = "vgicv3")]
pub(crate) fn dealloc_contiguous_frames(start_paddr: PhysAddr, frame_count: usize) {
ax_crate_interface::call_interface!(ArmVgicHostIf::dealloc_contiguous_frames(
start_paddr,
frame_count
));
}
#[cfg(feature = "vgicv3")]
pub(crate) fn phys_to_virt(paddr: PhysAddr) -> VirtAddr {
ax_crate_interface::call_interface!(ArmVgicHostIf::phys_to_virt(paddr))
}
#[cfg(feature = "vgicv3")]
pub(crate) fn host_cpu_num() -> usize {
ax_crate_interface::call_interface!(ArmVgicHostIf::host_cpu_num())
}
#[cfg(target_arch = "aarch64")]
pub(crate) fn current_vm_id() -> usize {
ax_crate_interface::call_interface!(ArmVgicHostIf::current_vm_id())
}
pub(crate) fn current_vcpu_id() -> usize {
ax_crate_interface::call_interface!(ArmVgicHostIf::current_vcpu_id())
}
#[cfg(target_arch = "aarch64")]
pub(crate) fn queue_virtual_interrupt(vm_id: usize, vcpu_id: usize, vector: u8) {
ax_crate_interface::call_interface!(ArmVgicHostIf::queue_virtual_interrupt(
vm_id, vcpu_id, vector
));
}
#[cfg(target_arch = "aarch64")]
pub(crate) fn current_time_nanos() -> u64 {
ax_crate_interface::call_interface!(ArmVgicHostIf::current_time_nanos())
}
#[cfg(target_arch = "aarch64")]
pub(crate) fn register_timer(
deadline: Duration,
callback: Box<dyn FnOnce(Duration) + Send + 'static>,
) -> usize {
ax_crate_interface::call_interface!(ArmVgicHostIf::register_timer(deadline, callback))
}
#[cfg(target_arch = "aarch64")]
pub(crate) fn cancel_timer(token: usize) {
ax_crate_interface::call_interface!(ArmVgicHostIf::cancel_timer(token));
}
pub fn read_vgicd_iidr() -> u32 {
ax_crate_interface::call_interface!(ArmVgicHostIf::read_vgicd_iidr())
}
pub fn read_vgicd_typer() -> u32 {
ax_crate_interface::call_interface!(ArmVgicHostIf::read_vgicd_typer())
}
pub fn get_host_gicd_base() -> PhysAddr {
ax_crate_interface::call_interface!(ArmVgicHostIf::get_host_gicd_base())
}
pub fn get_host_gicr_base() -> PhysAddr {
ax_crate_interface::call_interface!(ArmVgicHostIf::get_host_gicr_base())
}
pub fn hardware_inject_virtual_interrupt(vector: u8) {
ax_crate_interface::call_interface!(ArmVgicHostIf::hardware_inject_virtual_interrupt(vector));
}