diff --git a/modules/axhal/Cargo.toml b/modules/axhal/Cargo.toml index 39a01bb433..ea3d51bcd3 100644 --- a/modules/axhal/Cargo.toml +++ b/modules/axhal/Cargo.toml @@ -18,7 +18,7 @@ irq = [] tls = ["alloc"] rtc = ["x86_rtc", "riscv_goldfish", "arm_pl031"] default = [] -hv = ["paging", "cortex-a", "percpu/arm-el2", "page_table_entry/arm-el2", "arm_gicv2/el2", "dep:crate_interface"] +hv = ["paging", "cortex-a", "percpu/arm-el2", "page_table_entry/arm-el2", "arm_gicv2/el2", "arm_gicv2/hv", "dep:crate_interface"] [dependencies] log = "=0.4.21" diff --git a/modules/axhal/src/irq.rs b/modules/axhal/src/irq.rs index 2d6b1247c6..e185641b42 100644 --- a/modules/axhal/src/irq.rs +++ b/modules/axhal/src/irq.rs @@ -5,7 +5,7 @@ use handler_table::HandlerTable; use crate::platform::irq::{MAX_IRQ_COUNT, dispatch_irq}; use crate::trap::{IRQ, register_trap_handler}; -pub use crate::platform::irq::{register_handler, set_enable}; +pub use crate::platform::irq::{MyVgic, register_handler, set_enable}; #[cfg(target_arch = "aarch64")] pub use crate::platform::irq::fetch_irq; diff --git a/modules/axhal/src/platform/aarch64_common/generic_timer.rs b/modules/axhal/src/platform/aarch64_common/generic_timer.rs index 127db32c39..5793619fc9 100644 --- a/modules/axhal/src/platform/aarch64_common/generic_timer.rs +++ b/modules/axhal/src/platform/aarch64_common/generic_timer.rs @@ -1,6 +1,6 @@ #![allow(unused_imports)] -use aarch64_cpu::registers::{CNTFRQ_EL0, CNTP_CTL_EL0, CNTP_TVAL_EL0, CNTPCT_EL0}; +use aarch64_cpu::registers::{CNTFRQ_EL0, CNTP_CTL_EL0, CNTP_TVAL_EL0, CNTPCT_EL0, CNTV_TVAL_EL0}; use int_ratio::Ratio; use tock_registers::interfaces::{Readable, Writeable}; @@ -48,8 +48,22 @@ pub fn set_oneshot_timer(deadline_ns: u64) { } } +pub fn set_oneshot_timer_cntp(deadline_ns: u64) { + // debug!("set_oneshot_timer: cntp_deadline_ns={}", deadline_ns); + let cnptct = CNTPCT_EL0.get(); + let cnptct_deadline = nanos_to_ticks(deadline_ns); + if cnptct < cnptct_deadline { + let interval = cnptct_deadline - cnptct; + debug_assert!(interval <= u32::MAX as u64); + CNTV_TVAL_EL0.set(interval); + } else { + CNTV_TVAL_EL0.set(0); + } +} + #[cfg(all(feature = "irq", feature = "hv"))] pub fn set_oneshot_timer(deadline_ns: u64) { + // debug!("set_oneshot_timer: deadline_ns={}", deadline_ns); let cnptct = CNTPCT_EL0.get(); let cnptct_deadline = nanos_to_ticks(deadline_ns); if cnptct < cnptct_deadline { diff --git a/modules/axhal/src/platform/aarch64_common/gic.rs b/modules/axhal/src/platform/aarch64_common/gic.rs index dad3172cd3..9994a088aa 100644 --- a/modules/axhal/src/platform/aarch64_common/gic.rs +++ b/modules/axhal/src/platform/aarch64_common/gic.rs @@ -1,6 +1,8 @@ use crate::{irq::IrqHandler, mem::phys_to_virt}; -use arm_gicv2::{GicCpuInterface, GicDistributor, InterruptType, translate_irq}; -use axconfig::devices::{GICC_PADDR, GICD_PADDR, UART_IRQ}; +use arm_gicv2::{ + GicCpuInterface, GicDistributor, GicHypervisorInterface, InterruptType, translate_irq, +}; +use axconfig::devices::{GICC_PADDR, GICD_PADDR, GICH_PADDR, GICV_PADDR, UART_IRQ}; use kspin::SpinNoIrq; use memory_addr::PhysAddr; @@ -20,12 +22,17 @@ pub const UART_IRQ_NUM: usize = translate_irq(UART_IRQ, InterruptType::SPI).unwr const GICD_BASE: PhysAddr = pa!(GICD_PADDR); const GICC_BASE: PhysAddr = pa!(GICC_PADDR); +const GICV_BASE: PhysAddr = pa!(GICV_PADDR); +const GICH_BASE: PhysAddr = pa!(GICH_PADDR); static GICD: SpinNoIrq = SpinNoIrq::new(GicDistributor::new(phys_to_virt(GICD_BASE).as_mut_ptr())); // per-CPU, no lock static GICC: GicCpuInterface = GicCpuInterface::new(phys_to_virt(GICC_BASE).as_mut_ptr()); +static GICV: GicCpuInterface = GicCpuInterface::new(phys_to_virt(GICV_BASE).as_mut_ptr()); +static GICH: GicHypervisorInterface = + GicHypervisorInterface::new(phys_to_virt(GICH_BASE).as_mut_ptr()); /// Enables or disables the given IRQ. pub fn set_enable(irq_num: usize, enabled: bool) { @@ -38,7 +45,7 @@ pub fn set_enable(irq_num: usize, enabled: bool) { /// It also enables the IRQ if the registration succeeds. It returns `false` if /// the registration failed. pub fn register_handler(irq_num: usize, handler: IrqHandler) -> bool { - trace!("register handler irq {}", irq_num); + debug!("register handler irq {}", irq_num); crate::irq::register_handler_common(irq_num, handler) } @@ -64,9 +71,28 @@ pub fn dispatch_irq(irq_no: usize) { /// Initializes GICD, GICC on the primary CPU. pub(crate) fn init_primary() { - info!("Initialize GICv2..."); + info!("Initialize GICv2... {:?}", GICH_BASE); GICD.lock().init(); GICC.init(); + GICV.init(); + GICH.get_hcr(); +} + +pub struct MyVgic {} + +impl MyVgic { + pub fn get_gich() -> &'static GicHypervisorInterface { + &GICH + } + pub fn get_gicd() -> &'static SpinNoIrq { + &GICD + } + pub fn get_gicc() -> &'static GicCpuInterface { + &GICC + } + pub fn get_gicv() -> &'static GicCpuInterface { + &GICV + } } /// Initializes GICC on secondary CPUs. diff --git a/modules/axhal/src/time.rs b/modules/axhal/src/time.rs index 3c39e3d316..690a4b7877 100644 --- a/modules/axhal/src/time.rs +++ b/modules/axhal/src/time.rs @@ -10,9 +10,9 @@ pub type TimeValue = Duration; #[cfg(feature = "irq")] pub use crate::platform::irq::TIMER_IRQ_NUM; -#[cfg(feature = "irq")] -pub use crate::platform::time::set_oneshot_timer; pub use crate::platform::time::{current_ticks, epochoffset_nanos, nanos_to_ticks, ticks_to_nanos}; +#[cfg(feature = "irq")] +pub use crate::platform::time::{set_oneshot_timer, set_oneshot_timer_cntp}; /// Number of milliseconds in a second. pub const MILLIS_PER_SEC: u64 = 1_000; diff --git a/modules/axtask/src/api.rs b/modules/axtask/src/api.rs index 7cf96a043c..47cadf1423 100644 --- a/modules/axtask/src/api.rs +++ b/modules/axtask/src/api.rs @@ -210,7 +210,7 @@ pub fn exit(exit_code: i32) -> ! { pub fn run_idle() -> ! { loop { yield_now(); - debug!("idle task: waiting for IRQs..."); + trace!("idle task: waiting for IRQs..."); #[cfg(feature = "irq")] axhal::arch::wait_for_irqs(); }