diff --git a/ostd/src/arch/riscv/irq.rs b/ostd/src/arch/riscv/irq.rs index f2aa0a61..8c134c29 100644 --- a/ostd/src/arch/riscv/irq.rs +++ b/ostd/src/arch/riscv/irq.rs @@ -83,6 +83,14 @@ impl IrqLine { Arc::new(IRQ_LIST.get().unwrap().get(irq_num as usize).unwrap()) } + /// Gets the remapping index of the IRQ line. + /// + /// This method will return `None` if interrupt remapping is disabled or + /// not supported by the architecture. + pub fn remapping_index(&self) -> Option { + None + } + /// Get the IRQ number. pub fn num(&self) -> u8 { self.irq_num diff --git a/ostd/src/arch/riscv/pci.rs b/ostd/src/arch/riscv/pci.rs index 8850578c..5d8c3aed 100644 --- a/ostd/src/arch/riscv/pci.rs +++ b/ostd/src/arch/riscv/pci.rs @@ -6,9 +6,7 @@ use log::warn; use spin::Once; use super::boot::DEVICE_TREE; -use crate::{ - bus::pci::PciDeviceLocation, io::IoMem, mm::VmIoOnce, prelude::*, trap::IrqLine, Error, -}; +use crate::{bus::pci::PciDeviceLocation, io::IoMem, mm::VmIoOnce, prelude::*, Error}; static PCI_BASE_ADDR: Once = Once::new(); @@ -64,7 +62,7 @@ pub(crate) fn init() -> Result<()> { pub(crate) const MSIX_DEFAULT_MSG_ADDR: u32 = 0x2400_0000; -pub(crate) fn construct_remappable_msix_address(irq: &IrqLine) -> u32 { +pub(crate) fn construct_remappable_msix_address(remapping_index: u32) -> u32 { unimplemented!() } diff --git a/ostd/src/arch/x86/iommu/mod.rs b/ostd/src/arch/x86/iommu/mod.rs index b46728e5..401273bc 100644 --- a/ostd/src/arch/x86/iommu/mod.rs +++ b/ostd/src/arch/x86/iommu/mod.rs @@ -9,7 +9,9 @@ mod invalidate; mod registers; pub(crate) use dma_remapping::{has_dma_remapping, map, unmap}; -pub(crate) use interrupt_remapping::{alloc_irt_entry, has_interrupt_remapping, IrtEntryHandle}; +pub(in crate::arch) use interrupt_remapping::{ + alloc_irt_entry, has_interrupt_remapping, IrtEntryHandle, +}; use crate::{io::IoMemAllocatorBuilder, mm::page_table::PageTableError}; diff --git a/ostd/src/arch/x86/irq.rs b/ostd/src/arch/x86/irq.rs index 83e8ee94..de9c707e 100644 --- a/ostd/src/arch/x86/irq.rs +++ b/ostd/src/arch/x86/irq.rs @@ -104,14 +104,24 @@ impl IrqLine { if has_interrupt_remapping() { let handle = alloc_irt_entry(); if let Some(handle) = handle { + // Enable the IRT entry + handle + .lock() + .irt_entry_mut() + .unwrap() + .enable_default(irq_num as u32); irq.bind_remapping_entry.call_once(|| handle); } } irq } - pub fn bind_remapping_entry(&self) -> Option<&Arc>> { - self.bind_remapping_entry.get() + /// Gets the remapping index of the IRQ line. + /// + /// This method will return `None` if interrupt remapping is disabled or + /// not supported by the architecture. + pub fn remapping_index(&self) -> Option { + Some(self.bind_remapping_entry.get()?.lock().index()) } /// Gets the IRQ number. diff --git a/ostd/src/arch/x86/kernel/apic/ioapic.rs b/ostd/src/arch/x86/kernel/apic/ioapic.rs index 20e096c6..0c67df12 100644 --- a/ostd/src/arch/x86/kernel/apic/ioapic.rs +++ b/ostd/src/arch/x86/kernel/apic/ioapic.rs @@ -15,7 +15,7 @@ use volatile::{ }; use crate::{ - arch::{if_tdx_enabled, iommu::has_interrupt_remapping, kernel::acpi::get_platform_info}, + arch::{if_tdx_enabled, kernel::acpi::get_platform_info}, io::IoMemAllocatorBuilder, mm::paddr_to_vaddr, sync::SpinLock, @@ -54,19 +54,14 @@ impl IoApic { if value.get_bits(0..8) as u8 != 0 { return Err(Error::AccessDenied); } - if has_interrupt_remapping() { - let mut handle = irq.inner_irq().bind_remapping_entry().unwrap().lock(); - - // Enable irt entry - let irt_entry_mut = handle.irt_entry_mut().unwrap(); - irt_entry_mut.enable_default(irq.num() as u32); + if let Some(remapping_index) = irq.remapping_index() { // Construct remappable format RTE with RTE[48] set. let mut value: u64 = irq.num() as u64 | 0x1_0000_0000_0000; // Interrupt index[14:0] is on RTE[63:49] and interrupt index[15] is on RTE[11]. - value |= ((handle.index() & 0x8000) >> 4) as u64; - value |= (handle.index() as u64 & 0x7FFF) << 49; + value |= ((remapping_index & 0x8000) >> 4) as u64; + value |= (remapping_index as u64 & 0x7FFF) << 49; self.access.write( Self::TABLE_REG_BASE + 2 * index, @@ -76,15 +71,12 @@ impl IoApic { Self::TABLE_REG_BASE + 2 * index + 1, value.get_bits(32..64) as u32, ); - - drop(handle); - self.irqs.push(irq); - return Ok(()); + } else { + self.access + .write(Self::TABLE_REG_BASE + 2 * index, irq.num() as u32); + self.access.write(Self::TABLE_REG_BASE + 2 * index + 1, 0); } - self.access - .write(Self::TABLE_REG_BASE + 2 * index, irq.num() as u32); - self.access.write(Self::TABLE_REG_BASE + 2 * index + 1, 0); self.irqs.push(irq); Ok(()) } diff --git a/ostd/src/arch/x86/pci.rs b/ostd/src/arch/x86/pci.rs index f748d788..b4f22ddb 100644 --- a/ostd/src/arch/x86/pci.rs +++ b/ostd/src/arch/x86/pci.rs @@ -3,7 +3,7 @@ //! PCI bus access use super::device::io_port::{ReadWriteAccess, WriteOnlyAccess}; -use crate::{bus::pci::PciDeviceLocation, io::IoPort, prelude::*, trap::IrqLine}; +use crate::{bus::pci::PciDeviceLocation, io::IoPort, prelude::*}; static PCI_ADDRESS_PORT: IoPort = unsafe { IoPort::new(0x0CF8) }; static PCI_DATA_PORT: IoPort = unsafe { IoPort::new(0x0CFC) }; @@ -27,19 +27,13 @@ pub(crate) fn has_pci_bus() -> bool { pub(crate) const MSIX_DEFAULT_MSG_ADDR: u32 = 0xFEE0_0000; -pub(crate) fn construct_remappable_msix_address(irq: &IrqLine) -> u32 { - let mut handle = irq.inner_irq().bind_remapping_entry().unwrap().lock(); - - // Enable irt entry - let irt_entry_mut = handle.irt_entry_mut().unwrap(); - irt_entry_mut.enable_default(irq.num() as u32); - +pub(crate) fn construct_remappable_msix_address(remapping_index: u32) -> u32 { // Use remappable format. The bits[4:3] should be always set to 1 according to the manual. let mut address = MSIX_DEFAULT_MSG_ADDR | 0b1_1000; // Interrupt index[14:0] is on address[19:5] and interrupt index[15] is on address[2]. - address |= (handle.index() as u32 & 0x7FFF) << 5; - address |= (handle.index() as u32 & 0x8000) >> 13; + address |= (remapping_index & 0x7FFF) << 5; + address |= (remapping_index & 0x8000) >> 13; address } diff --git a/ostd/src/bus/pci/capability/msix.rs b/ostd/src/bus/pci/capability/msix.rs index 241aefec..fb4d1444 100644 --- a/ostd/src/bus/pci/capability/msix.rs +++ b/ostd/src/bus/pci/capability/msix.rs @@ -8,10 +8,7 @@ use alloc::{sync::Arc, vec::Vec}; use crate::{ - arch::{ - iommu::has_interrupt_remapping, - pci::{construct_remappable_msix_address, MSIX_DEFAULT_MSG_ADDR}, - }, + arch::pci::{construct_remappable_msix_address, MSIX_DEFAULT_MSG_ADDR}, bus::pci::{ cfg_space::{Bar, Command, MemoryBar}, common_device::PciCommonDevice, @@ -150,8 +147,8 @@ impl CapabilityMsixData { } // If interrupt remapping is enabled, then we need to change the value of the message address. - if has_interrupt_remapping() { - let address = construct_remappable_msix_address(&irq); + if let Some(remapping_index) = irq.remapping_index() { + let address = construct_remappable_msix_address(remapping_index as u32); self.table_bar .io_mem() diff --git a/ostd/src/trap/irq.rs b/ostd/src/trap/irq.rs index a79f9370..74c7587f 100644 --- a/ostd/src/trap/irq.rs +++ b/ostd/src/trap/irq.rs @@ -80,8 +80,12 @@ impl IrqLine { self.callbacks.is_empty() } - pub(crate) fn inner_irq(&self) -> &'static irq::IrqLine { - &self.inner_irq + /// Gets the remapping index of the IRQ line. + /// + /// This method will return `None` if interrupt remapping is disabled or + /// not supported by the architecture. + pub fn remapping_index(&self) -> Option { + self.inner_irq.remapping_index() } }