mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-08 12:56:48 +00:00
Check SAGAW before enabling DMA remapping
This commit is contained in:
parent
79b3f68892
commit
d2ff5fc1a9
@ -1,13 +1,13 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
pub use context_table::RootTable;
|
pub use context_table::RootTable;
|
||||||
use log::info;
|
use log::{info, warn};
|
||||||
use second_stage::{DeviceMode, PageTableEntry, PagingConsts};
|
use second_stage::{DeviceMode, PageTableEntry, PagingConsts};
|
||||||
use spin::Once;
|
use spin::Once;
|
||||||
|
|
||||||
use super::IommuError;
|
use super::IommuError;
|
||||||
use crate::{
|
use crate::{
|
||||||
arch::iommu::registers::IOMMU_REGS,
|
arch::iommu::registers::{CapabilitySagaw, IOMMU_REGS},
|
||||||
bus::pci::PciDeviceLocation,
|
bus::pci::PciDeviceLocation,
|
||||||
mm::{Daddr, PageTable},
|
mm::{Daddr, PageTable},
|
||||||
prelude::Paddr,
|
prelude::Paddr,
|
||||||
@ -59,16 +59,28 @@ pub fn unmap(daddr: Daddr) -> Result<(), IommuError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn init() {
|
pub fn init() {
|
||||||
// Create Root Table instance
|
if !IOMMU_REGS
|
||||||
|
.get()
|
||||||
|
.unwrap()
|
||||||
|
.lock()
|
||||||
|
.read_capability()
|
||||||
|
.supported_adjusted_guest_address_widths()
|
||||||
|
.contains(CapabilitySagaw::AGAW_39BIT_3LP)
|
||||||
|
{
|
||||||
|
warn!("[IOMMU] 3-level page tables not supported, disabling DMA remapping");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a Root Table instance.
|
||||||
let mut root_table = RootTable::new();
|
let mut root_table = RootTable::new();
|
||||||
// For all PCI Device, use the same page table.
|
// For all PCI devices, use the same page table.
|
||||||
let page_table = PageTable::<DeviceMode, PageTableEntry, PagingConsts>::empty();
|
let page_table = PageTable::<DeviceMode, PageTableEntry, PagingConsts>::empty();
|
||||||
for table in PciDeviceLocation::all() {
|
for table in PciDeviceLocation::all() {
|
||||||
root_table.specify_device_page_table(table, unsafe { page_table.shallow_copy() })
|
root_table.specify_device_page_table(table, unsafe { page_table.shallow_copy() })
|
||||||
}
|
}
|
||||||
PAGE_TABLE.call_once(|| SpinLock::new(root_table));
|
PAGE_TABLE.call_once(|| SpinLock::new(root_table));
|
||||||
|
|
||||||
// Enable DMA remapping
|
// Enable DMA remapping.
|
||||||
let mut iommu_regs = IOMMU_REGS.get().unwrap().lock();
|
let mut iommu_regs = IOMMU_REGS.get().unwrap().lock();
|
||||||
iommu_regs.enable_dma_remapping(PAGE_TABLE.get().unwrap());
|
iommu_regs.enable_dma_remapping(PAGE_TABLE.get().unwrap());
|
||||||
info!("[IOMMU] DMA remapping enabled");
|
info!("[IOMMU] DMA remapping enabled");
|
||||||
|
@ -38,7 +38,7 @@ impl Capability {
|
|||||||
|
|
||||||
/// Number of domain support.
|
/// Number of domain support.
|
||||||
///
|
///
|
||||||
/// ```norun
|
/// ```text
|
||||||
/// 0 => 4-bit domain-ids with support for up to 16 domains.
|
/// 0 => 4-bit domain-ids with support for up to 16 domains.
|
||||||
/// 1 => 6-bit domain-ids with support for up to 64 domains.
|
/// 1 => 6-bit domain-ids with support for up to 64 domains.
|
||||||
/// 2 => 8-bit domain-ids with support for up to 256 domains.
|
/// 2 => 8-bit domain-ids with support for up to 256 domains.
|
||||||
@ -54,15 +54,8 @@ impl Capability {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Supported Adjusted Guest Address Widths.
|
/// Supported Adjusted Guest Address Widths.
|
||||||
/// ```norun
|
pub const fn supported_adjusted_guest_address_widths(&self) -> CapabilitySagaw {
|
||||||
/// 0/4 => Reserved
|
CapabilitySagaw::from_bits_truncate(self.0 >> 8)
|
||||||
/// 1 => 39-bit AGAW (3-level page-table)
|
|
||||||
/// 2 => 48-bit AGAW (4-level page-table)
|
|
||||||
/// 3 => 57-bit AGAW (5-level page-table)
|
|
||||||
/// ```
|
|
||||||
pub const fn supported_adjusted_guest_address_widths(&self) -> u64 {
|
|
||||||
const SAGAW_MASK: u64 = 0x1F << 8;
|
|
||||||
(self.0 & SAGAW_MASK) >> 8
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Fault-recording Register offset, specifies the offset of the first fault recording
|
/// Fault-recording Register offset, specifies the offset of the first fault recording
|
||||||
@ -74,15 +67,10 @@ impl Capability {
|
|||||||
const FRO_MASK: u64 = 0x3FF << 24;
|
const FRO_MASK: u64 = 0x3FF << 24;
|
||||||
(self.0 & FRO_MASK) >> 24
|
(self.0 & FRO_MASK) >> 24
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Second Stage Large Page Support.
|
/// Second Stage Large Page Support.
|
||||||
/// ```norun
|
pub const fn second_stage_large_page_support(&self) -> CapabilitySslps {
|
||||||
/// 2/3 => Reserved
|
CapabilitySslps::from_bits_truncate(self.0 >> 34)
|
||||||
/// 0 => 21-bit offset to page frame(2MB)
|
|
||||||
/// 1 => 30-bit offset to page frame(1GB)
|
|
||||||
/// ```
|
|
||||||
pub const fn second_stage_large_page_support(&self) -> u64 {
|
|
||||||
const SSLPS_MASK: u64 = 0xF << 34;
|
|
||||||
(self.0 & SSLPS_MASK) >> 34
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Maximum Guest Address Width. The maximum guest physical address width supported
|
/// Maximum Guest Address Width. The maximum guest physical address width supported
|
||||||
@ -127,7 +115,7 @@ impl Debug for Capability {
|
|||||||
|
|
||||||
bitflags! {
|
bitflags! {
|
||||||
/// Capability flags in IOMMU.
|
/// Capability flags in IOMMU.
|
||||||
pub struct CapabilityFlags: u64{
|
pub struct CapabilityFlags: u64 {
|
||||||
/// Required Write-Buffer Flushing.
|
/// Required Write-Buffer Flushing.
|
||||||
const RWBF = 1 << 4;
|
const RWBF = 1 << 4;
|
||||||
/// Protected Low-Memory Region
|
/// Protected Low-Memory Region
|
||||||
@ -160,3 +148,27 @@ bitflags! {
|
|||||||
const ESRTPS = 1 << 63;
|
const ESRTPS = 1 << 63;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bitflags! {
|
||||||
|
/// Supported Adjusted Guest Address Widths (SAGAW) in IOMMU.
|
||||||
|
pub struct CapabilitySagaw: u64 {
|
||||||
|
/// 39-bit AGAW (3-level page-table).
|
||||||
|
const AGAW_39BIT_3LP = 1 << 1;
|
||||||
|
/// 48-bit AGAW (4-level page-table).
|
||||||
|
const AGAW_48BIT_4LP = 1 << 2;
|
||||||
|
/// 57-bit AGAW (5-level page-table).
|
||||||
|
const AGAW_57BIT_5LP = 1 << 3;
|
||||||
|
// 0th and 4th bits are reserved.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bitflags! {
|
||||||
|
/// Second Stage Large Page Support (SSLPS) in IOMMU.
|
||||||
|
pub struct CapabilitySslps: u64 {
|
||||||
|
/// 21-bit offset to page frame (2MB).
|
||||||
|
const PAGE_21BIT_2MB = 1 << 0;
|
||||||
|
/// 30-bit offset to page frame (1GB).
|
||||||
|
const PAGE_30BIT_1GB = 1 << 1;
|
||||||
|
// 2nd and 3rd bits are reserved.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -11,7 +11,7 @@ mod status;
|
|||||||
use core::ptr::NonNull;
|
use core::ptr::NonNull;
|
||||||
|
|
||||||
use bit_field::BitField;
|
use bit_field::BitField;
|
||||||
pub use capability::Capability;
|
pub use capability::{Capability, CapabilitySagaw};
|
||||||
use command::GlobalCommand;
|
use command::GlobalCommand;
|
||||||
use extended_cap::ExtendedCapability;
|
use extended_cap::ExtendedCapability;
|
||||||
pub use extended_cap::ExtendedCapabilityFlags;
|
pub use extended_cap::ExtendedCapabilityFlags;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user