From 44a535161c464fd56455c03c0ecbdff1a916a688 Mon Sep 17 00:00:00 2001 From: hky1999 <976929993@qq.com> Date: Mon, 11 Nov 2024 23:53:48 +0800 Subject: [PATCH 1/5] [wip] support irq handling routine from arceos-umhv under aarch64 --- Cargo.lock | 3 +- modules/axhal/Cargo.toml | 2 +- modules/axhal/src/irq.rs | 5 +- .../platform/aarch64_common/generic_timer.rs | 10 +- .../axhal/src/platform/aarch64_common/gic.rs | 289 +++++++++--------- .../src/platform/aarch64_qemu_virt/mod.rs | 1 + modules/axhal/src/platform/dummy/mod.rs | 5 + 7 files changed, 167 insertions(+), 148 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 91f9d62321..1f80f02ae7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -125,9 +125,8 @@ dependencies = [ [[package]] name = "arm_gicv2" version = "0.1.0" -source = "git+https://github.com/arceos-hypervisor/arm_gicv2?rev=7acc0dd#7acc0dd1e1fefa90b4cd45342072d2350a74b071" +source = "git+https://github.com/arceos-hypervisor/arm_gicv2?branch=axvcpuhal#2908fd02d954b44695027805de234d5b3d045cf0" dependencies = [ - "crate_interface", "tock-registers", ] diff --git a/modules/axhal/Cargo.toml b/modules/axhal/Cargo.toml index d3305e79ce..6cb7f7f745 100644 --- a/modules/axhal/Cargo.toml +++ b/modules/axhal/Cargo.toml @@ -55,7 +55,7 @@ riscv_goldfish = { version = "0.1", optional = true } [target.'cfg(target_arch = "aarch64")'.dependencies] aarch64-cpu = "9.4" tock-registers = "0.8" -arm_gicv2 = { git = "https://github.com/arceos-hypervisor/arm_gicv2", rev = "7acc0dd" } +arm_gicv2 = { git = "https://github.com/arceos-hypervisor/arm_gicv2", branch = "axvcpuhal" } crate_interface = { version = "0.1.3", optional = true } arm_pl011 = "0.1" arm_pl031 = { version = "0.2", optional = true } diff --git a/modules/axhal/src/irq.rs b/modules/axhal/src/irq.rs index fdaa788462..7e9e82b9a1 100644 --- a/modules/axhal/src/irq.rs +++ b/modules/axhal/src/irq.rs @@ -7,6 +7,9 @@ use crate::trap::{register_trap_handler, IRQ}; pub use crate::platform::irq::{register_handler, set_enable}; +#[cfg(target_arch = "aarch64")] +pub use crate::platform::irq::fetch_irq; + /// The type if an IRQ handler. pub type IrqHandler = handler_table::Handler; @@ -36,7 +39,7 @@ pub(crate) fn register_handler_common(irq_num: usize, handler: IrqHandler) -> bo } #[register_trap_handler(IRQ)] -fn handler_irq(irq_num: usize) -> bool { +pub fn handler_irq(irq_num: usize) -> bool { let guard = kernel_guard::NoPreempt::new(); dispatch_irq(irq_num); drop(guard); // rescheduling may occur when preemption is re-enabled. diff --git a/modules/axhal/src/platform/aarch64_common/generic_timer.rs b/modules/axhal/src/platform/aarch64_common/generic_timer.rs index 8b9007fdda..8707d55ed1 100644 --- a/modules/axhal/src/platform/aarch64_common/generic_timer.rs +++ b/modules/axhal/src/platform/aarch64_common/generic_timer.rs @@ -101,12 +101,12 @@ pub(crate) fn init_percpu() { } #[cfg(all(feature = "irq", feature = "hv"))] { - // ENABLE, bit [0], Enables the timer. - let ctl = 1; - let tval = 0; unsafe { - core::arch::asm!("msr CNTHP_CTL_EL2, {0:x}", in(reg) ctl); - core::arch::asm!("msr CNTHP_TVAL_EL2, {0:x}", in(reg) tval); + // ENABLE, bit [0], Enables the timer. + // * 0b0: Timer disabled. + // * 0b1: Timer enabled. + core::arch::asm!("msr CNTHP_CTL_EL2, {0:x}", in(reg) 0b1); + core::arch::asm!("msr CNTHP_TVAL_EL2, {0:x}", in(reg) 0); } } #[cfg(feature = "irq")] diff --git a/modules/axhal/src/platform/aarch64_common/gic.rs b/modules/axhal/src/platform/aarch64_common/gic.rs index 98bffa6ee8..59c46bb39e 100644 --- a/modules/axhal/src/platform/aarch64_common/gic.rs +++ b/modules/axhal/src/platform/aarch64_common/gic.rs @@ -41,13 +41,24 @@ pub fn register_handler(irq_num: usize, handler: IrqHandler) -> bool { crate::irq::register_handler_common(irq_num, handler) } +/// Fetches the IRQ number. +pub fn fetch_irq() -> usize { + GICC.iar() as usize +} + /// Dispatches the IRQ. /// /// This function is called by the common interrupt handler. It looks /// up in the IRQ handler table and calls the corresponding handler. If /// necessary, it also acknowledges the interrupt controller after handling. -pub fn dispatch_irq(_unused: usize) { - GICC.handle_irq(|irq_num| crate::irq::dispatch_irq_common(irq_num as _)); +pub fn dispatch_irq(irq_no: usize) { + if irq_no == 0 { + GICC.handle_irq(|irq_num| crate::irq::dispatch_irq_common(irq_num as _)); + } else { + crate::irq::dispatch_irq_common(irq_no as _); + GICC.eoi(irq_no as _); + GICC.dir(irq_no as _); + } } /// Initializes GICD, GICC on the primary CPU. @@ -63,140 +74,140 @@ pub(crate) fn init_secondary() { GICC.init(); } -#[cfg(feature = "hv")] -mod gic_if { - - use super::{GICC, GICD}; - use arm_gicv2::GicTrait; - struct GicIfImpl; - - #[crate_interface::impl_interface] - impl GicTrait for GicIfImpl { - /// Sets the enable status of a specific interrupt in the GICD (Distributor). - /// - /// # Parameters - /// - `vector`: The interrupt vector number, identifying the interrupt to be enabled or disabled. - /// - `enable`: A boolean value indicating whether to enable the interrupt. `true` enables the interrupt, `false` disables it. - /// - /// This function locks and accesses the GICD controller, then sets the enable status of the specified interrupt vector based on the `enable` parameter. - /// It provides a mechanism for controlling whether interrupts can trigger CPU responses, used for interrupt management. - fn set_enable(vector: usize, enable: bool) { - GICD.lock().set_enable(vector, enable); - } - - /// Retrieves the enable status of a specified interrupt vector from the GICD. - /// - /// # Parameters - /// - `vector`: The index of the interrupt vector, used to identify a specific interrupt source. - /// - /// # Returns - /// - `bool`: Indicates whether the specified interrupt vector is enabled. `true` means the interrupt vector is enabled, `false` means it is not enabled. - fn get_enable(vector: usize) -> bool { - GICD.lock().get_enable(vector) - } - - /// Get the type of the GICD register - /// - /// This function locks the GICD and calls its internal `get_typer` method to retrieve the type of the GICD register - /// - /// # Returns - /// * `u32` - The type of the GICD register - fn get_typer() -> u32 { - GICD.lock().get_typer() - } - - /// Get the Implementer ID Register (IIDR) of the interrupt controller - /// - /// This function locks the GICD (interrupt controller) and calls its `get_iidr` method to retrieve the value of the Implementer ID Register. - /// This register can be used to identify the specific hardware implementer and version. - fn get_iidr() -> u32 { - GICD.lock().get_iidr() - } - - /// Set the state of an interrupt source - /// - /// This function updates the state of a specific interrupt source in the GICD (Interrupt Controller). - /// It first locks the GICD and then updates the interrupt source state using the provided interrupt ID (`int_id`), - /// new state value (`state`), and current CPU ID (`current_cpu_id`). - /// - /// Parameters: - /// - `int_id`: The ID of the interrupt source. - /// - `state`: The new state value for the interrupt source. - /// - `current_cpu_id`: The ID of the current CPU. - fn set_state(int_id: usize, state: usize, current_cpu_id: usize) { - GICD.lock().set_state(int_id, state, current_cpu_id); - } - - /// Get the state of an interrupt source - /// - /// This function retrieves the current state of a specific interrupt source. - /// - /// Parameters: - /// - `int_id`: The ID of the interrupt source. - /// - /// Returns: - /// - The current state value. - fn get_state(int_id: usize) -> usize { - GICD.lock().get_state(int_id) - } - - /// Set the ICFGR (Interrupt Configuration and Control Register) - /// - /// This function sets the configuration of a specific interrupt source in the ICFGR. - /// - /// Parameters: - /// - `int_id`: The ID of the interrupt source. - /// - `cfg`: The new configuration value. - fn set_icfgr(int_id: usize, cfg: u8) { - GICD.lock().set_icfgr(int_id, cfg); - } - - /// Get the target CPU for an interrupt source - /// - /// This function retrieves the target CPU for a specific interrupt source. - /// - /// Parameters: - /// - `int_id`: The ID of the interrupt source. - /// - /// Returns: - /// - The target CPU ID. - fn get_target_cpu(int_id: usize) -> usize { - GICD.lock().get_target_cpu(int_id) - } - - /// Set the target CPU for an interrupt source - /// - /// This function sets the target CPU for a specific interrupt source. - /// - /// Parameters: - /// - `int_id`: The ID of the interrupt source. - /// - `target`: The new target CPU value. - fn set_target_cpu(int_id: usize, target: u8) { - GICD.lock().set_target_cpu(int_id, target); - } - - /// Get the priority of an interrupt source - /// - /// This function retrieves the priority of a specific interrupt source. - /// - /// Parameters: - /// - `int_id`: The ID of the interrupt source. - /// - /// Returns: - /// - The priority value. - fn get_priority(int_id: usize) -> usize { - GICD.lock().get_priority(int_id) - } - - /// Set the priority of an interrupt source - /// - /// This function sets the priority of a specific interrupt source. - /// - /// Parameters: - /// - `int_id`: The ID of the interrupt source. - /// - `priority`: The new priority value. - fn set_priority(int_id: usize, priority: u8) { - GICD.lock().set_priority(int_id, priority); - } - } -} +// #[cfg(feature = "hv")] +// mod gic_if { + +// use super::{GICC, GICD}; +// use arm_gicv2::GicTrait; +// struct GicIfImpl; + +// #[crate_interface::impl_interface] +// impl GicTrait for GicIfImpl { +// /// Sets the enable status of a specific interrupt in the GICD (Distributor). +// /// +// /// # Parameters +// /// - `vector`: The interrupt vector number, identifying the interrupt to be enabled or disabled. +// /// - `enable`: A boolean value indicating whether to enable the interrupt. `true` enables the interrupt, `false` disables it. +// /// +// /// This function locks and accesses the GICD controller, then sets the enable status of the specified interrupt vector based on the `enable` parameter. +// /// It provides a mechanism for controlling whether interrupts can trigger CPU responses, used for interrupt management. +// fn set_enable(vector: usize, enable: bool) { +// GICD.lock().set_enable(vector, enable); +// } + +// /// Retrieves the enable status of a specified interrupt vector from the GICD. +// /// +// /// # Parameters +// /// - `vector`: The index of the interrupt vector, used to identify a specific interrupt source. +// /// +// /// # Returns +// /// - `bool`: Indicates whether the specified interrupt vector is enabled. `true` means the interrupt vector is enabled, `false` means it is not enabled. +// fn get_enable(vector: usize) -> bool { +// GICD.lock().get_enable(vector) +// } + +// /// Get the type of the GICD register +// /// +// /// This function locks the GICD and calls its internal `get_typer` method to retrieve the type of the GICD register +// /// +// /// # Returns +// /// * `u32` - The type of the GICD register +// fn get_typer() -> u32 { +// GICD.lock().get_typer() +// } + +// /// Get the Implementer ID Register (IIDR) of the interrupt controller +// /// +// /// This function locks the GICD (interrupt controller) and calls its `get_iidr` method to retrieve the value of the Implementer ID Register. +// /// This register can be used to identify the specific hardware implementer and version. +// fn get_iidr() -> u32 { +// GICD.lock().get_iidr() +// } + +// /// Set the state of an interrupt source +// /// +// /// This function updates the state of a specific interrupt source in the GICD (Interrupt Controller). +// /// It first locks the GICD and then updates the interrupt source state using the provided interrupt ID (`int_id`), +// /// new state value (`state`), and current CPU ID (`current_cpu_id`). +// /// +// /// Parameters: +// /// - `int_id`: The ID of the interrupt source. +// /// - `state`: The new state value for the interrupt source. +// /// - `current_cpu_id`: The ID of the current CPU. +// fn set_state(int_id: usize, state: usize, current_cpu_id: usize) { +// GICD.lock().set_state(int_id, state, current_cpu_id); +// } + +// /// Get the state of an interrupt source +// /// +// /// This function retrieves the current state of a specific interrupt source. +// /// +// /// Parameters: +// /// - `int_id`: The ID of the interrupt source. +// /// +// /// Returns: +// /// - The current state value. +// fn get_state(int_id: usize) -> usize { +// GICD.lock().get_state(int_id) +// } + +// /// Set the ICFGR (Interrupt Configuration and Control Register) +// /// +// /// This function sets the configuration of a specific interrupt source in the ICFGR. +// /// +// /// Parameters: +// /// - `int_id`: The ID of the interrupt source. +// /// - `cfg`: The new configuration value. +// fn set_icfgr(int_id: usize, cfg: u8) { +// GICD.lock().set_icfgr(int_id, cfg); +// } + +// /// Get the target CPU for an interrupt source +// /// +// /// This function retrieves the target CPU for a specific interrupt source. +// /// +// /// Parameters: +// /// - `int_id`: The ID of the interrupt source. +// /// +// /// Returns: +// /// - The target CPU ID. +// fn get_target_cpu(int_id: usize) -> usize { +// GICD.lock().get_target_cpu(int_id) +// } + +// /// Set the target CPU for an interrupt source +// /// +// /// This function sets the target CPU for a specific interrupt source. +// /// +// /// Parameters: +// /// - `int_id`: The ID of the interrupt source. +// /// - `target`: The new target CPU value. +// fn set_target_cpu(int_id: usize, target: u8) { +// GICD.lock().set_target_cpu(int_id, target); +// } + +// /// Get the priority of an interrupt source +// /// +// /// This function retrieves the priority of a specific interrupt source. +// /// +// /// Parameters: +// /// - `int_id`: The ID of the interrupt source. +// /// +// /// Returns: +// /// - The priority value. +// fn get_priority(int_id: usize) -> usize { +// GICD.lock().get_priority(int_id) +// } + +// /// Set the priority of an interrupt source +// /// +// /// This function sets the priority of a specific interrupt source. +// /// +// /// Parameters: +// /// - `int_id`: The ID of the interrupt source. +// /// - `priority`: The new priority value. +// fn set_priority(int_id: usize, priority: u8) { +// GICD.lock().set_priority(int_id, priority); +// } +// } +// } diff --git a/modules/axhal/src/platform/aarch64_qemu_virt/mod.rs b/modules/axhal/src/platform/aarch64_qemu_virt/mod.rs index 4565a8d7ad..8f382f650a 100644 --- a/modules/axhal/src/platform/aarch64_qemu_virt/mod.rs +++ b/modules/axhal/src/platform/aarch64_qemu_virt/mod.rs @@ -42,6 +42,7 @@ pub(crate) unsafe extern "C" fn rust_entry(cpu_id: usize, dtb: usize) { #[allow(dead_code)] // FIXME: temporariy allowd to bypass clippy warnings. pub(crate) unsafe extern "C" fn rust_entry_secondary(cpu_id: usize) { crate::arch::set_exception_vector_base(exception_vector_base as usize); + #[cfg(not(feature = "hv"))] crate::arch::write_page_table_root0(0.into()); // disable low address access crate::cpu::init_secondary(cpu_id); rust_main_secondary(cpu_id); diff --git a/modules/axhal/src/platform/dummy/mod.rs b/modules/axhal/src/platform/dummy/mod.rs index 389f14c778..e8f10394c3 100644 --- a/modules/axhal/src/platform/dummy/mod.rs +++ b/modules/axhal/src/platform/dummy/mod.rs @@ -82,6 +82,11 @@ pub mod irq { /// up in the IRQ handler table and calls the corresponding handler. If /// necessary, it also acknowledges the interrupt controller after handling. pub fn dispatch_irq(irq_num: usize) {} + + /// Fetches the IRQ number. + pub fn fetch_irq() -> usize { + 0 + } } /// Initializes the platform devices for the primary CPU. From 9422e20f75b321bb999964c6e4067160e6d33b35 Mon Sep 17 00:00:00 2001 From: hky1999 <976929993@qq.com> Date: Tue, 19 Nov 2024 21:00:28 +0800 Subject: [PATCH 2/5] [fix] enable IRQ in boot_el2.rs --- modules/axhal/src/irq.rs | 5 +++++ .../axhal/src/platform/aarch64_common/boot_el2.rs | 13 ++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/modules/axhal/src/irq.rs b/modules/axhal/src/irq.rs index 7e9e82b9a1..7c0ba41088 100644 --- a/modules/axhal/src/irq.rs +++ b/modules/axhal/src/irq.rs @@ -38,6 +38,11 @@ pub(crate) fn register_handler_common(irq_num: usize, handler: IrqHandler) -> bo false } +/// Core IRQ handling routine, registered at [`IRQ`], +/// which dispatches IRQs to registered handlers. +/// +/// Note: this function is denoted as public here because it'll be called by the +/// hypervisor for hypervisor reserved IRQ handling. #[register_trap_handler(IRQ)] pub fn handler_irq(irq_num: usize) -> bool { let guard = kernel_guard::NoPreempt::new(); diff --git a/modules/axhal/src/platform/aarch64_common/boot_el2.rs b/modules/axhal/src/platform/aarch64_common/boot_el2.rs index d8b6bc0cf1..fd15e6ac36 100644 --- a/modules/axhal/src/platform/aarch64_common/boot_el2.rs +++ b/modules/axhal/src/platform/aarch64_common/boot_el2.rs @@ -38,7 +38,18 @@ unsafe fn switch_to_el2() { unsafe fn init_mmu_el2() { // Set EL1 to 64bit. - HCR_EL2.write(HCR_EL2::RW::EL1IsAarch64); + // Enable `IMO` and `FMO` to make sure that: + // * Physical IRQ interrupts are taken to EL2; + // * Virtual IRQ interrupts are enabled; + // * Physical FIQ interrupts are taken to EL2; + // * Virtual FIQ interrupts are enabled. + HCR_EL2.modify( + HCR_EL2::VM::Enable + + HCR_EL2::RW::EL1IsAarch64 + + HCR_EL2::IMO::EnableVirtualIRQ // Physical IRQ Routing. + + HCR_EL2::FMO::EnableVirtualFIQ // Physical FIQ Routing. + + HCR_EL2::TSC::EnableTrapEl1SmcToEl2, + ); // Device-nGnRE memory let attr0 = MAIR_EL2::Attr0_Device::nonGathering_nonReordering_EarlyWriteAck; From f34e70e4f186ee0ccb6ffea042987ba8aebaad7e Mon Sep 17 00:00:00 2001 From: hky1999 <976929993@qq.com> Date: Tue, 19 Nov 2024 21:07:55 +0800 Subject: [PATCH 3/5] [fix] cargo doc error in handler_irq, revert gic_if --- modules/axhal/src/irq.rs | 2 +- .../axhal/src/platform/aarch64_common/gic.rs | 274 +++++++++--------- 2 files changed, 138 insertions(+), 138 deletions(-) diff --git a/modules/axhal/src/irq.rs b/modules/axhal/src/irq.rs index 7c0ba41088..5d83e3e882 100644 --- a/modules/axhal/src/irq.rs +++ b/modules/axhal/src/irq.rs @@ -38,7 +38,7 @@ pub(crate) fn register_handler_common(irq_num: usize, handler: IrqHandler) -> bo false } -/// Core IRQ handling routine, registered at [`IRQ`], +/// Core IRQ handling routine, registered at `axhal::trap::IRQ`, /// which dispatches IRQs to registered handlers. /// /// Note: this function is denoted as public here because it'll be called by the diff --git a/modules/axhal/src/platform/aarch64_common/gic.rs b/modules/axhal/src/platform/aarch64_common/gic.rs index 59c46bb39e..4ca71ef6b9 100644 --- a/modules/axhal/src/platform/aarch64_common/gic.rs +++ b/modules/axhal/src/platform/aarch64_common/gic.rs @@ -74,140 +74,140 @@ pub(crate) fn init_secondary() { GICC.init(); } -// #[cfg(feature = "hv")] -// mod gic_if { - -// use super::{GICC, GICD}; -// use arm_gicv2::GicTrait; -// struct GicIfImpl; - -// #[crate_interface::impl_interface] -// impl GicTrait for GicIfImpl { -// /// Sets the enable status of a specific interrupt in the GICD (Distributor). -// /// -// /// # Parameters -// /// - `vector`: The interrupt vector number, identifying the interrupt to be enabled or disabled. -// /// - `enable`: A boolean value indicating whether to enable the interrupt. `true` enables the interrupt, `false` disables it. -// /// -// /// This function locks and accesses the GICD controller, then sets the enable status of the specified interrupt vector based on the `enable` parameter. -// /// It provides a mechanism for controlling whether interrupts can trigger CPU responses, used for interrupt management. -// fn set_enable(vector: usize, enable: bool) { -// GICD.lock().set_enable(vector, enable); -// } - -// /// Retrieves the enable status of a specified interrupt vector from the GICD. -// /// -// /// # Parameters -// /// - `vector`: The index of the interrupt vector, used to identify a specific interrupt source. -// /// -// /// # Returns -// /// - `bool`: Indicates whether the specified interrupt vector is enabled. `true` means the interrupt vector is enabled, `false` means it is not enabled. -// fn get_enable(vector: usize) -> bool { -// GICD.lock().get_enable(vector) -// } - -// /// Get the type of the GICD register -// /// -// /// This function locks the GICD and calls its internal `get_typer` method to retrieve the type of the GICD register -// /// -// /// # Returns -// /// * `u32` - The type of the GICD register -// fn get_typer() -> u32 { -// GICD.lock().get_typer() -// } - -// /// Get the Implementer ID Register (IIDR) of the interrupt controller -// /// -// /// This function locks the GICD (interrupt controller) and calls its `get_iidr` method to retrieve the value of the Implementer ID Register. -// /// This register can be used to identify the specific hardware implementer and version. -// fn get_iidr() -> u32 { -// GICD.lock().get_iidr() -// } - -// /// Set the state of an interrupt source -// /// -// /// This function updates the state of a specific interrupt source in the GICD (Interrupt Controller). -// /// It first locks the GICD and then updates the interrupt source state using the provided interrupt ID (`int_id`), -// /// new state value (`state`), and current CPU ID (`current_cpu_id`). -// /// -// /// Parameters: -// /// - `int_id`: The ID of the interrupt source. -// /// - `state`: The new state value for the interrupt source. -// /// - `current_cpu_id`: The ID of the current CPU. -// fn set_state(int_id: usize, state: usize, current_cpu_id: usize) { -// GICD.lock().set_state(int_id, state, current_cpu_id); -// } - -// /// Get the state of an interrupt source -// /// -// /// This function retrieves the current state of a specific interrupt source. -// /// -// /// Parameters: -// /// - `int_id`: The ID of the interrupt source. -// /// -// /// Returns: -// /// - The current state value. -// fn get_state(int_id: usize) -> usize { -// GICD.lock().get_state(int_id) -// } - -// /// Set the ICFGR (Interrupt Configuration and Control Register) -// /// -// /// This function sets the configuration of a specific interrupt source in the ICFGR. -// /// -// /// Parameters: -// /// - `int_id`: The ID of the interrupt source. -// /// - `cfg`: The new configuration value. -// fn set_icfgr(int_id: usize, cfg: u8) { -// GICD.lock().set_icfgr(int_id, cfg); -// } - -// /// Get the target CPU for an interrupt source -// /// -// /// This function retrieves the target CPU for a specific interrupt source. -// /// -// /// Parameters: -// /// - `int_id`: The ID of the interrupt source. -// /// -// /// Returns: -// /// - The target CPU ID. -// fn get_target_cpu(int_id: usize) -> usize { -// GICD.lock().get_target_cpu(int_id) -// } - -// /// Set the target CPU for an interrupt source -// /// -// /// This function sets the target CPU for a specific interrupt source. -// /// -// /// Parameters: -// /// - `int_id`: The ID of the interrupt source. -// /// - `target`: The new target CPU value. -// fn set_target_cpu(int_id: usize, target: u8) { -// GICD.lock().set_target_cpu(int_id, target); -// } - -// /// Get the priority of an interrupt source -// /// -// /// This function retrieves the priority of a specific interrupt source. -// /// -// /// Parameters: -// /// - `int_id`: The ID of the interrupt source. -// /// -// /// Returns: -// /// - The priority value. -// fn get_priority(int_id: usize) -> usize { -// GICD.lock().get_priority(int_id) -// } - -// /// Set the priority of an interrupt source -// /// -// /// This function sets the priority of a specific interrupt source. -// /// -// /// Parameters: -// /// - `int_id`: The ID of the interrupt source. -// /// - `priority`: The new priority value. -// fn set_priority(int_id: usize, priority: u8) { -// GICD.lock().set_priority(int_id, priority); -// } -// } -// } +#[cfg(feature = "hv")] +mod gic_if { + + use super::{GICC, GICD}; + use arm_gicv2::GicTrait; + struct GicIfImpl; + + #[crate_interface::impl_interface] + impl GicTrait for GicIfImpl { + /// Sets the enable status of a specific interrupt in the GICD (Distributor). + /// + /// # Parameters + /// - `vector`: The interrupt vector number, identifying the interrupt to be enabled or disabled. + /// - `enable`: A boolean value indicating whether to enable the interrupt. `true` enables the interrupt, `false` disables it. + /// + /// This function locks and accesses the GICD controller, then sets the enable status of the specified interrupt vector based on the `enable` parameter. + /// It provides a mechanism for controlling whether interrupts can trigger CPU responses, used for interrupt management. + fn set_enable(vector: usize, enable: bool) { + GICD.lock().set_enable(vector, enable); + } + + /// Retrieves the enable status of a specified interrupt vector from the GICD. + /// + /// # Parameters + /// - `vector`: The index of the interrupt vector, used to identify a specific interrupt source. + /// + /// # Returns + /// - `bool`: Indicates whether the specified interrupt vector is enabled. `true` means the interrupt vector is enabled, `false` means it is not enabled. + fn get_enable(vector: usize) -> bool { + GICD.lock().get_enable(vector) + } + + /// Get the type of the GICD register + /// + /// This function locks the GICD and calls its internal `get_typer` method to retrieve the type of the GICD register + /// + /// # Returns + /// * `u32` - The type of the GICD register + fn get_typer() -> u32 { + GICD.lock().get_typer() + } + + /// Get the Implementer ID Register (IIDR) of the interrupt controller + /// + /// This function locks the GICD (interrupt controller) and calls its `get_iidr` method to retrieve the value of the Implementer ID Register. + /// This register can be used to identify the specific hardware implementer and version. + fn get_iidr() -> u32 { + GICD.lock().get_iidr() + } + + /// Set the state of an interrupt source + /// + /// This function updates the state of a specific interrupt source in the GICD (Interrupt Controller). + /// It first locks the GICD and then updates the interrupt source state using the provided interrupt ID (`int_id`), + /// new state value (`state`), and current CPU ID (`current_cpu_id`). + /// + /// Parameters: + /// - `int_id`: The ID of the interrupt source. + /// - `state`: The new state value for the interrupt source. + /// - `current_cpu_id`: The ID of the current CPU. + fn set_state(int_id: usize, state: usize, current_cpu_id: usize) { + GICD.lock().set_state(int_id, state, current_cpu_id); + } + + /// Get the state of an interrupt source + /// + /// This function retrieves the current state of a specific interrupt source. + /// + /// Parameters: + /// - `int_id`: The ID of the interrupt source. + /// + /// Returns: + /// - The current state value. + fn get_state(int_id: usize) -> usize { + GICD.lock().get_state(int_id) + } + + /// Set the ICFGR (Interrupt Configuration and Control Register) + /// + /// This function sets the configuration of a specific interrupt source in the ICFGR. + /// + /// Parameters: + /// - `int_id`: The ID of the interrupt source. + /// - `cfg`: The new configuration value. + fn set_icfgr(int_id: usize, cfg: u8) { + GICD.lock().set_icfgr(int_id, cfg); + } + + /// Get the target CPU for an interrupt source + /// + /// This function retrieves the target CPU for a specific interrupt source. + /// + /// Parameters: + /// - `int_id`: The ID of the interrupt source. + /// + /// Returns: + /// - The target CPU ID. + fn get_target_cpu(int_id: usize) -> usize { + GICD.lock().get_target_cpu(int_id) + } + + /// Set the target CPU for an interrupt source + /// + /// This function sets the target CPU for a specific interrupt source. + /// + /// Parameters: + /// - `int_id`: The ID of the interrupt source. + /// - `target`: The new target CPU value. + fn set_target_cpu(int_id: usize, target: u8) { + GICD.lock().set_target_cpu(int_id, target); + } + + /// Get the priority of an interrupt source + /// + /// This function retrieves the priority of a specific interrupt source. + /// + /// Parameters: + /// - `int_id`: The ID of the interrupt source. + /// + /// Returns: + /// - The priority value. + fn get_priority(int_id: usize) -> usize { + GICD.lock().get_priority(int_id) + } + + /// Set the priority of an interrupt source + /// + /// This function sets the priority of a specific interrupt source. + /// + /// Parameters: + /// - `int_id`: The ID of the interrupt source. + /// - `priority`: The new priority value. + fn set_priority(int_id: usize, priority: u8) { + GICD.lock().set_priority(int_id, priority); + } + } +} From 4ef4b7139e838036f4ead69484e129f51909701d Mon Sep 17 00:00:00 2001 From: hky1999 <976929993@qq.com> Date: Tue, 19 Nov 2024 21:31:17 +0800 Subject: [PATCH 4/5] [fix] delete gic_if --- .../axhal/src/platform/aarch64_common/gic.rs | 138 ------------------ 1 file changed, 138 deletions(-) diff --git a/modules/axhal/src/platform/aarch64_common/gic.rs b/modules/axhal/src/platform/aarch64_common/gic.rs index 4ca71ef6b9..c62a6e0f54 100644 --- a/modules/axhal/src/platform/aarch64_common/gic.rs +++ b/modules/axhal/src/platform/aarch64_common/gic.rs @@ -73,141 +73,3 @@ pub(crate) fn init_primary() { pub(crate) fn init_secondary() { GICC.init(); } - -#[cfg(feature = "hv")] -mod gic_if { - - use super::{GICC, GICD}; - use arm_gicv2::GicTrait; - struct GicIfImpl; - - #[crate_interface::impl_interface] - impl GicTrait for GicIfImpl { - /// Sets the enable status of a specific interrupt in the GICD (Distributor). - /// - /// # Parameters - /// - `vector`: The interrupt vector number, identifying the interrupt to be enabled or disabled. - /// - `enable`: A boolean value indicating whether to enable the interrupt. `true` enables the interrupt, `false` disables it. - /// - /// This function locks and accesses the GICD controller, then sets the enable status of the specified interrupt vector based on the `enable` parameter. - /// It provides a mechanism for controlling whether interrupts can trigger CPU responses, used for interrupt management. - fn set_enable(vector: usize, enable: bool) { - GICD.lock().set_enable(vector, enable); - } - - /// Retrieves the enable status of a specified interrupt vector from the GICD. - /// - /// # Parameters - /// - `vector`: The index of the interrupt vector, used to identify a specific interrupt source. - /// - /// # Returns - /// - `bool`: Indicates whether the specified interrupt vector is enabled. `true` means the interrupt vector is enabled, `false` means it is not enabled. - fn get_enable(vector: usize) -> bool { - GICD.lock().get_enable(vector) - } - - /// Get the type of the GICD register - /// - /// This function locks the GICD and calls its internal `get_typer` method to retrieve the type of the GICD register - /// - /// # Returns - /// * `u32` - The type of the GICD register - fn get_typer() -> u32 { - GICD.lock().get_typer() - } - - /// Get the Implementer ID Register (IIDR) of the interrupt controller - /// - /// This function locks the GICD (interrupt controller) and calls its `get_iidr` method to retrieve the value of the Implementer ID Register. - /// This register can be used to identify the specific hardware implementer and version. - fn get_iidr() -> u32 { - GICD.lock().get_iidr() - } - - /// Set the state of an interrupt source - /// - /// This function updates the state of a specific interrupt source in the GICD (Interrupt Controller). - /// It first locks the GICD and then updates the interrupt source state using the provided interrupt ID (`int_id`), - /// new state value (`state`), and current CPU ID (`current_cpu_id`). - /// - /// Parameters: - /// - `int_id`: The ID of the interrupt source. - /// - `state`: The new state value for the interrupt source. - /// - `current_cpu_id`: The ID of the current CPU. - fn set_state(int_id: usize, state: usize, current_cpu_id: usize) { - GICD.lock().set_state(int_id, state, current_cpu_id); - } - - /// Get the state of an interrupt source - /// - /// This function retrieves the current state of a specific interrupt source. - /// - /// Parameters: - /// - `int_id`: The ID of the interrupt source. - /// - /// Returns: - /// - The current state value. - fn get_state(int_id: usize) -> usize { - GICD.lock().get_state(int_id) - } - - /// Set the ICFGR (Interrupt Configuration and Control Register) - /// - /// This function sets the configuration of a specific interrupt source in the ICFGR. - /// - /// Parameters: - /// - `int_id`: The ID of the interrupt source. - /// - `cfg`: The new configuration value. - fn set_icfgr(int_id: usize, cfg: u8) { - GICD.lock().set_icfgr(int_id, cfg); - } - - /// Get the target CPU for an interrupt source - /// - /// This function retrieves the target CPU for a specific interrupt source. - /// - /// Parameters: - /// - `int_id`: The ID of the interrupt source. - /// - /// Returns: - /// - The target CPU ID. - fn get_target_cpu(int_id: usize) -> usize { - GICD.lock().get_target_cpu(int_id) - } - - /// Set the target CPU for an interrupt source - /// - /// This function sets the target CPU for a specific interrupt source. - /// - /// Parameters: - /// - `int_id`: The ID of the interrupt source. - /// - `target`: The new target CPU value. - fn set_target_cpu(int_id: usize, target: u8) { - GICD.lock().set_target_cpu(int_id, target); - } - - /// Get the priority of an interrupt source - /// - /// This function retrieves the priority of a specific interrupt source. - /// - /// Parameters: - /// - `int_id`: The ID of the interrupt source. - /// - /// Returns: - /// - The priority value. - fn get_priority(int_id: usize) -> usize { - GICD.lock().get_priority(int_id) - } - - /// Set the priority of an interrupt source - /// - /// This function sets the priority of a specific interrupt source. - /// - /// Parameters: - /// - `int_id`: The ID of the interrupt source. - /// - `priority`: The new priority value. - fn set_priority(int_id: usize, priority: u8) { - GICD.lock().set_priority(int_id, priority); - } - } -} From 6e23019659e3ab6af884fc4bab21d356e53b82b7 Mon Sep 17 00:00:00 2001 From: hky1999 <976929993@qq.com> Date: Wed, 20 Nov 2024 14:34:04 +0800 Subject: [PATCH 5/5] [fix] update arm_gicv2 dep url --- Cargo.lock | 2 +- modules/axhal/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1f80f02ae7..d3878e02f0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -125,7 +125,7 @@ dependencies = [ [[package]] name = "arm_gicv2" version = "0.1.0" -source = "git+https://github.com/arceos-hypervisor/arm_gicv2?branch=axvcpuhal#2908fd02d954b44695027805de234d5b3d045cf0" +source = "git+https://github.com/arceos-hypervisor/arm_gicv2#dfe5f164b94cdd07081c2fe74a0cfe4bef2852c9" dependencies = [ "tock-registers", ] diff --git a/modules/axhal/Cargo.toml b/modules/axhal/Cargo.toml index 6cb7f7f745..1ea552db1b 100644 --- a/modules/axhal/Cargo.toml +++ b/modules/axhal/Cargo.toml @@ -55,7 +55,7 @@ riscv_goldfish = { version = "0.1", optional = true } [target.'cfg(target_arch = "aarch64")'.dependencies] aarch64-cpu = "9.4" tock-registers = "0.8" -arm_gicv2 = { git = "https://github.com/arceos-hypervisor/arm_gicv2", branch = "axvcpuhal" } +arm_gicv2 = { git = "https://github.com/arceos-hypervisor/arm_gicv2" } crate_interface = { version = "0.1.3", optional = true } arm_pl011 = "0.1" arm_pl031 = { version = "0.2", optional = true }