mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-08 12:56:48 +00:00
Refactor interrupt remapping in OSTD
This commit is contained in:
parent
95744692a5
commit
d4872af3c7
@ -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<u16> {
|
||||
None
|
||||
}
|
||||
|
||||
/// Get the IRQ number.
|
||||
pub fn num(&self) -> u8 {
|
||||
self.irq_num
|
||||
|
@ -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<IoMem> = 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!()
|
||||
}
|
||||
|
||||
|
@ -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};
|
||||
|
||||
|
@ -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<SpinLock<IrtEntryHandle, LocalIrqDisabled>>> {
|
||||
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<u16> {
|
||||
Some(self.bind_remapping_entry.get()?.lock().index())
|
||||
}
|
||||
|
||||
/// Gets the IRQ number.
|
||||
|
@ -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.irqs.push(irq);
|
||||
Ok(())
|
||||
}
|
||||
|
@ -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<u32, WriteOnlyAccess> = unsafe { IoPort::new(0x0CF8) };
|
||||
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) 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
|
||||
}
|
||||
|
@ -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()
|
||||
|
@ -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<u16> {
|
||||
self.inner_irq.remapping_index()
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user