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())
|
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
|
||||||
|
@ -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!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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};
|
||||||
|
|
||||||
|
@ -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.
|
||||||
|
@ -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(())
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user