Refactor interrupt remapping in OSTD

This commit is contained in:
Yuke Peng 2025-05-21 13:12:50 +08:00 committed by Ruihan Li
parent 95744692a5
commit d4872af3c7
8 changed files with 46 additions and 41 deletions

View File

@ -83,6 +83,14 @@ impl IrqLine {
Arc::new(IRQ_LIST.get().unwrap().get(irq_num as usize).unwrap()) 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<u16> {
None
}
/// Get the IRQ number. /// Get the IRQ number.
pub fn num(&self) -> u8 { pub fn num(&self) -> u8 {
self.irq_num self.irq_num

View File

@ -6,9 +6,7 @@ use log::warn;
use spin::Once; use spin::Once;
use super::boot::DEVICE_TREE; use super::boot::DEVICE_TREE;
use crate::{ use crate::{bus::pci::PciDeviceLocation, io::IoMem, mm::VmIoOnce, prelude::*, Error};
bus::pci::PciDeviceLocation, io::IoMem, mm::VmIoOnce, prelude::*, trap::IrqLine, Error,
};
static PCI_BASE_ADDR: Once<IoMem> = Once::new(); static PCI_BASE_ADDR: Once<IoMem> = Once::new();
@ -64,7 +62,7 @@ pub(crate) fn init() -> Result<()> {
pub(crate) const MSIX_DEFAULT_MSG_ADDR: u32 = 0x2400_0000; 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!() unimplemented!()
} }

View File

@ -9,7 +9,9 @@ mod invalidate;
mod registers; mod registers;
pub(crate) use dma_remapping::{has_dma_remapping, map, unmap}; 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}; use crate::{io::IoMemAllocatorBuilder, mm::page_table::PageTableError};

View File

@ -104,14 +104,24 @@ impl IrqLine {
if has_interrupt_remapping() { if has_interrupt_remapping() {
let handle = alloc_irt_entry(); let handle = alloc_irt_entry();
if let Some(handle) = handle { 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.bind_remapping_entry.call_once(|| handle);
} }
} }
irq irq
} }
pub fn bind_remapping_entry(&self) -> Option<&Arc<SpinLock<IrtEntryHandle, LocalIrqDisabled>>> { /// Gets the remapping index of the IRQ line.
self.bind_remapping_entry.get() ///
/// This method will return `None` if interrupt remapping is disabled or
/// not supported by the architecture.
pub fn remapping_index(&self) -> Option<u16> {
Some(self.bind_remapping_entry.get()?.lock().index())
} }
/// Gets the IRQ number. /// Gets the IRQ number.

View File

@ -15,7 +15,7 @@ use volatile::{
}; };
use crate::{ 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, io::IoMemAllocatorBuilder,
mm::paddr_to_vaddr, mm::paddr_to_vaddr,
sync::SpinLock, sync::SpinLock,
@ -54,19 +54,14 @@ impl IoApic {
if value.get_bits(0..8) as u8 != 0 { if value.get_bits(0..8) as u8 != 0 {
return Err(Error::AccessDenied); 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. // Construct remappable format RTE with RTE[48] set.
let mut value: u64 = irq.num() as u64 | 0x1_0000_0000_0000; 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]. // 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 |= ((remapping_index & 0x8000) >> 4) as u64;
value |= (handle.index() as u64 & 0x7FFF) << 49; value |= (remapping_index as u64 & 0x7FFF) << 49;
self.access.write( self.access.write(
Self::TABLE_REG_BASE + 2 * index, Self::TABLE_REG_BASE + 2 * index,
@ -76,15 +71,12 @@ impl IoApic {
Self::TABLE_REG_BASE + 2 * index + 1, Self::TABLE_REG_BASE + 2 * index + 1,
value.get_bits(32..64) as u32, value.get_bits(32..64) as u32,
); );
} else {
drop(handle); self.access
self.irqs.push(irq); .write(Self::TABLE_REG_BASE + 2 * index, irq.num() as u32);
return Ok(()); 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); self.irqs.push(irq);
Ok(()) Ok(())
} }

View File

@ -3,7 +3,7 @@
//! PCI bus access //! PCI bus access
use super::device::io_port::{ReadWriteAccess, WriteOnlyAccess}; 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<u32, WriteOnlyAccess> = unsafe { IoPort::new(0x0CF8) }; static PCI_ADDRESS_PORT: IoPort<u32, WriteOnlyAccess> = unsafe { IoPort::new(0x0CF8) };
static PCI_DATA_PORT: IoPort<u32, ReadWriteAccess> = unsafe { IoPort::new(0x0CFC) }; static PCI_DATA_PORT: IoPort<u32, ReadWriteAccess> = 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) const MSIX_DEFAULT_MSG_ADDR: u32 = 0xFEE0_0000;
pub(crate) fn construct_remappable_msix_address(irq: &IrqLine) -> u32 { pub(crate) fn construct_remappable_msix_address(remapping_index: u32) -> 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);
// Use remappable format. The bits[4:3] should be always set to 1 according to the manual. // 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; 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]. // 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 |= (remapping_index & 0x7FFF) << 5;
address |= (handle.index() as u32 & 0x8000) >> 13; address |= (remapping_index & 0x8000) >> 13;
address address
} }

View File

@ -8,10 +8,7 @@
use alloc::{sync::Arc, vec::Vec}; use alloc::{sync::Arc, vec::Vec};
use crate::{ use crate::{
arch::{ arch::pci::{construct_remappable_msix_address, MSIX_DEFAULT_MSG_ADDR},
iommu::has_interrupt_remapping,
pci::{construct_remappable_msix_address, MSIX_DEFAULT_MSG_ADDR},
},
bus::pci::{ bus::pci::{
cfg_space::{Bar, Command, MemoryBar}, cfg_space::{Bar, Command, MemoryBar},
common_device::PciCommonDevice, 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 interrupt remapping is enabled, then we need to change the value of the message address.
if has_interrupt_remapping() { if let Some(remapping_index) = irq.remapping_index() {
let address = construct_remappable_msix_address(&irq); let address = construct_remappable_msix_address(remapping_index as u32);
self.table_bar self.table_bar
.io_mem() .io_mem()

View File

@ -80,8 +80,12 @@ impl IrqLine {
self.callbacks.is_empty() self.callbacks.is_empty()
} }
pub(crate) fn inner_irq(&self) -> &'static irq::IrqLine { /// Gets the remapping index of the IRQ line.
&self.inner_irq ///
/// This method will return `None` if interrupt remapping is disabled or
/// not supported by the architecture.
pub fn remapping_index(&self) -> Option<u16> {
self.inner_irq.remapping_index()
} }
} }