Add register descriptions

This commit is contained in:
Yuke Peng 2024-07-18 20:40:46 +08:00 committed by Tate, Hongliang Tian
parent 7d0638958c
commit 63b42bff73
4 changed files with 395 additions and 0 deletions

View File

@ -0,0 +1,162 @@
// SPDX-License-Identifier: MPL-2.0
use core::fmt::Debug;
use bitflags::bitflags;
/// Capability in IOMMU.
pub struct Capability(u64);
impl Capability {
/// Create Capability from `value`
pub const fn new(value: u64) -> Self {
Self(value)
}
/// Capability flags
pub const fn flags(&self) -> CapabilityFlags {
CapabilityFlags::from_bits_truncate(self.0)
}
/// Number of Fault-recording. The maximum number of fault recording registers per
/// remapping hardware unit is 256.
///
/// Number of fault recording registers is computed as N+1, where N is the value
/// reported in this field.
pub const fn fault_recording_number(&self) -> u64 {
const NFR_MASK: u64 = 0xFF << 40;
(self.0 & NFR_MASK) >> 40
}
/// Maximum Address Mask Value, indicates the maximum supported value for them Address
/// Mask (AM) field in the Invalidation Address register (IVA_REG), and IOTLB Invalidation
/// Descriptor (iotlb_inv_dsc) used for invalidations of second-stage translation.
pub const fn maximum_address_mask_value(&self) -> u64 {
const MAMV_MASK: u64 = 0x3F << 48;
(self.0 & MAMV_MASK) >> 48
}
/// Number of domain support.
///
/// ```norun
/// 0 => 4-bit domain-ids with support for up to 16 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.
/// 3 => 10-bit domain-ids with support for up to 1024 domains.
/// 4 => 12-bit domain-ids with support for up to 4K domains.
/// 5 => 14-bit domain-ids with support for up to 16K domains.
/// 6 => 16-bit domain-ids with support for up to 64K domains.
/// 7 => Reserved.
/// ```
pub const fn domain_support_number(&self) -> u64 {
const ND_MASK: u64 = 0x7;
self.0 & ND_MASK
}
/// Supported Adjusted Guest Address Widths.
/// ```norun
/// 0/4 => Reserved
/// 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
/// register relative to the register base address of this remapping hardware unit.
///
/// If the register base address is X, and the value reported in this field
/// is Y, the address for the first fault recording register is calculated as X+(16*Y).
pub const fn fault_recording_register_offset(&self) -> u64 {
const FRO_MASK: u64 = 0x3FFF << 24;
(self.0 & FRO_MASK) >> 24
}
/// Second Stage Large Page Support.
/// ```norun
/// 2/3 => Reserved
/// 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
/// by second-stage translation in remapping hardware.
/// MGAW is computed as (N+1), where N is the valued reported in this field.
pub const fn maximum_guest_address_width(&self) -> u64 {
const MGAW_MASK: u64 = 0x3F << 16;
(self.0 & MGAW_MASK) >> 16
}
}
impl Debug for Capability {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("Capability")
.field("flags", &self.flags())
.field(
"maximum_guest_address_width",
&self.maximum_guest_address_width(),
)
.field(
"second_stage_large_page_support",
&self.second_stage_large_page_support(),
)
.field(
"fault_recording_register_offset",
&self.fault_recording_register_offset(),
)
.field(
"supported_adjusted_guest_address_widths",
&self.supported_adjusted_guest_address_widths(),
)
.field("domain_support_number", &self.domain_support_number())
.field(
"maximum_address_mask_value",
&self.maximum_address_mask_value(),
)
.field("fault_recording_number", &self.fault_recording_number())
.field("raw", &self.0)
.finish()
}
}
bitflags! {
/// Capability flags in IOMMU.
pub struct CapabilityFlags: u64{
/// Required Write-Buffer Flushing.
const RWBF = 1 << 4;
/// Protected Low-Memory Region
const PLMR = 1 << 5;
/// Protected High-Memory Region
const PHMR = 1 << 6;
/// Caching Mode
const CM = 1 << 7;
/// Zero Length Read. Whether the remapping hardware unit supports zero length DMA
/// read requests to write-only pages.
const ZLR = 1 << 22;
/// Page Selective Invalidation. Whether hardware supports page-selective invalidation
/// for IOTLB.
const PSI = 1 << 39;
/// Write Draining.
const DWD = 1 << 54;
/// Read Draining.
const DRD = 1 << 55;
/// First Stage 1-GByte Page Support.
const FS1GP = 1 << 56;
/// Posted Interrupts Support.
const PI = 1 << 59;
/// First Stage 5-level Paging Support.
const FS5LP = 1 << 60;
/// Enhanced Command Support.
const ECMDS = 1 << 61;
/// Enhanced Set Interrupt Remap Table Pointer Support.
const ESIRTPS = 1 << 62;
/// Enhanced Set Root Table Pointer Support.
const ESRTPS = 1 << 63;
}
}

View File

@ -0,0 +1,56 @@
// SPDX-License-Identifier: MPL-2.0
use bitflags::bitflags;
bitflags! {
/// Global Command to enable functions in IOMMU. All field is write-only.
pub struct GlobalCommand: u32{
/// Compatibility Format Interrupt, only valid if interrupt-remapping is supported.
///
/// Interrupt remapping will block compatibility format interrupts if set to 0.
/// Otherwise these interrupts will bypass interrupt remapping.
const CFI = 1 << 23;
/// Set Interrupt Remap Table Pointer, only valid if interrupt-remapping is supported.
///
/// Software sets this filed to set/update the interrupt remapping table pointer used
/// by hardware. The interrupt remapping table pointer is specified through the Interrupt
/// Remapping Table Address (IRTA_REG) register.
const SIRTP = 1 << 24;
/// Interrupt Remapping Enable, only valid if hardware support interrupt remapping.
/// Set to 1 if enable interrupt-remapping hardware.
///
/// Hardware reports the status of the interrupt remapping enable operation through the
/// IRES field in the Global Status register.
const IRE = 1 << 25;
/// Queued Invalidation Enable, only valid if hardware support queued invalidations.
/// Set to 1 to enable use of queued validations.
///
/// Hardware reports the status of queued invalidation enable operation through QIES
/// field in Global Status register.
const QIE = 1 << 26;
/// Write Buffer Flush, only valid for implementations requiring write buffer flushing.
///
/// Software sets this field to request that hardware flush the Root-Complex
/// internal write buffers. This is done to ensure any updates to the memory resident
/// remapping structures are not held in any internal write posting buffers.
///
/// Hardware reports the status of the write buffer flushing operation through WBFS
/// field in Global Status register.
const WBF = 1 << 27;
/// Set Root Table Pointer.
///
/// Software sets this field to set/update the root-table pointer (and translation
/// table mode) used by hardware. The root-table pointer (and translation table
/// mode) is specified through the Root Table Address (RTADDR_REG) register.
const SRTP = 1 << 30;
/// Translation Enable.
///
/// Software writes to this field to request hardware to enable/disable DMA remapping.
///
/// 0: Disable DMA remapping; 1: Enable DMA remapping.
///
/// Hardware reports the status of the translation enable operation through TES field
/// in the Global Status register.
const TE = 1 << 31;
}
}

View File

@ -0,0 +1,123 @@
// SPDX-License-Identifier: MPL-2.0
use core::fmt::Debug;
use bitflags::bitflags;
pub struct ExtendedCapability(u64);
impl ExtendedCapability {
/// Create ExtendedCapability from `value`
pub const fn new(value: u64) -> Self {
Self(value)
}
/// Extended capability flags
pub const fn flags(&self) -> ExtendedCapabilityFlags {
ExtendedCapabilityFlags::from_bits_truncate(self.0)
}
/// IOTLB Register Offset. This field specifies the offset to the IOTLB registers relative
/// to the register base address of this remapping hardware unit.
///
/// If the register base address is X, and the value reported in this field is Y, the
/// address for the IOTLB registers is calculated as X+(16*Y).
pub const fn iotlb_register_offset(&self) -> u64 {
const IRO_MASK: u64 = 0x3FF << 8;
(self.0 & IRO_MASK) >> 8
}
/// Maximum Handle Mask Value, indicates the maximum supported value for the Interrupt
/// Mask (IM) field in the Interrupt Entry Cache Invalidation Descriptorr (iec_inv_dsc).
pub const fn maximum_handle_mask(&self) -> u64 {
const MHMV_MASK: u64 = 0xF << 20;
(self.0 & MHMV_MASK) >> 20
}
/// PASID Size Supported, indicates the PASID size supported by the remapping hardware
/// for requests-with-PASID. A value of N in this field indicates hardware supports
/// PASID field of N+1 bits.
///
/// This field is unused and reported as 0 if Scalable Mode Translation Support (SMTS)
/// field is Clear.
pub const fn pasid_size(&self) -> u64 {
const PSS_MASK: u64 = 0x1F << 35;
(self.0 & PSS_MASK) >> 35
}
}
impl Debug for ExtendedCapability {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("ExtendedCapability")
.field("flags", &self.flags())
.field("maximum_handle_mask", &self.maximum_handle_mask())
.field("pasid_size", &self.pasid_size())
.field("iotlb_register_offset", &self.iotlb_register_offset())
.field("raw", &self.0)
.finish()
}
}
bitflags! {
/// Extended Capability flags in IOMMU.
///
/// TODO: Add adetailed description of each flag.
pub struct ExtendedCapabilityFlags: u64{
/// Page-walk Conherency.
const C = 1 << 0;
/// Queued Invalidation Support.
const QI = 1 << 1;
/// Device-TLB Support.
const DT = 1 << 2;
/// Interrupt Remapping Support
const IR = 1 << 3;
/// Extended Interrupt Mode.
const EIM = 1 << 4;
/// Pass Through Support.
const PT = 1 << 6;
/// Snoop Control.
const SC = 1 << 7;
/// Memory Type Support.
const MTS = 1 << 25;
/// Nested Translation Support.
const NEST = 1 << 26;
/// Page Request Support.
const PRS = 1 << 29;
/// Execute Request Support.
const ERS = 1 << 30;
/// Supervisor Request Support.
const SRS = 1 << 31;
/// No Write Flag Support.
const NWFS = 1 << 33;
/// Extended Accessed Flag Support.
const EAFS = 1 << 34;
/// Process Address Space ID Supported.
const PASID = 1 << 40;
/// Device-TLB Invalidation Throttle.
const DIT = 1 << 41;
/// Page-request Drain Support.
const PDS = 1 << 42;
/// Scalable Mode Translation Support.
const SMTS = 1 << 43;
/// Virtual Command Support.
const VCS = 1 << 44;
/// Second-Stage Accessed/Dirty Support.
const SSADS = 1 << 45;
/// Second-stage Translation Support.
const SSTS = 1 << 46;
/// First-stage Translation Support.
const FSTS = 1 << 47;
/// Scalable-Mode Page-walk Coherency Support.
const SMPWCS = 1 << 48;
/// RID-PASID Support.
const RPS = 1 << 49;
/// Performance Monitoring Support.
const PMS = 1 << 51;
/// Abort DMA Mode Support.
const ADMS = 1 << 52;
/// RID_PRIV Support.
const RPRIVS = 1 << 53;
/// Stop Marker Support.
const SMS = 1 << 58;
}
}

View File

@ -0,0 +1,54 @@
// SPDX-License-Identifier: MPL-2.0
use bitflags::bitflags;
bitflags! {
/// Global Status of the IOMMU. All fields is read-only. Some description of the fields
/// is related to the fields in `GlobalCommand`.
pub struct GlobalStatus: u32{
/// Compatibility Format Interrupt Status. The value reported in this field is
/// applicable only when interrupt-remapping is enabled and extended interrupt
/// model (x2APIC) mode is not enables.
///
/// - 0: Compatibility format interrupts are blocked.
/// - 1: Compatibility format interrupts are processed as pass-through (bypassing
/// interrupt remapping).
const CFIS = 1 << 23;
/// Interrupt Remapping Table Pointer Status.
///
/// This field is cleared by hardware when software sets the SIRTP field in the Global
/// Command register. This field is Set by hardware when hardware completes the
/// `Set Interrupt Remap Table Pointer` operation using the value provided in the
/// Interrupt Remapping Table Address register.
const IRTPS = 1 << 24;
/// Interrupt Remapping Enable Status.
///
/// - 0: Interrupt-remapping hardware is not enabled.
/// - 1: Interrupt-remapping hardware is enabled.
const IRES = 1 << 25;
/// Queued Invalidation Enable Status.
///
/// - 0: queued invalidation is not enabled.
/// - 1: queued invalidation is enabled.
const QIES = 1 << 26;
/// Write Buffer Flush Status. This field is valid only for implementations requiring
/// write buffer flushing. This field indicates the status of the write buffer flush
/// command.
///
/// - Set by hardware when software sets the WBF field in the Global Command register.
/// - Cleared by hardware when hardware completes the write buffer flushing operation.
const WBFS = 1 << 27;
/// Root Table Pointer Status.
///
/// This field is cleared by hardware when software sets the SRTP field in the Global
/// Command register. This field is set by hardware when hardware completes the
/// `Set Root Table Pointer`` operation using the value provided in the Root Table
/// Address register.
const RTPS = 1 << 30;
/// Translation Enable Status.
///
/// - 0: DMA remapping is not enabled.
/// - 1: DMA remapping is enabled.
const TES = 1 << 31;
}
}