Skip to main content

uefi_raw/protocol/
iommu.rs

1// SPDX-License-Identifier: MIT OR Apache-2.0
2
3use crate::table::boot::{AllocateType, MemoryType};
4use crate::{Guid, Handle, Status, guid};
5use bitflags::bitflags;
6use core::ffi::c_void;
7
8use crate::newtype_enum;
9
10/// EDKII IOMMU Protocol GUID
11impl EdkiiIommuProtocol {
12    pub const GUID: Guid = guid!("4e939de9-d948-4b0f-88ed-e6e1ce517c1e");
13}
14
15#[derive(Debug)]
16#[repr(C)]
17pub struct EdkiiIommuProtocol {
18    pub revision: u64,
19    pub set_attribute: unsafe extern "efiapi" fn(
20        this: *const Self,
21        device_handle: Handle,
22        mapping: *mut c_void,
23        iommu_access: EdkiiIommuAccess,
24    ) -> Status,
25    pub map: unsafe extern "efiapi" fn(
26        this: *const Self,
27        operation: EdkiiIommuOperation,
28        host_address: *mut c_void,
29        number_of_bytes: *mut usize,
30        device_address: *mut u64,
31        mapping: *mut *mut c_void,
32    ) -> Status,
33    pub unmap: unsafe extern "efiapi" fn(this: *const Self, mapping: *mut c_void) -> Status,
34    pub allocate_buffer: unsafe extern "efiapi" fn(
35        this: *const Self,
36        allocate_type: AllocateType,
37        memory_type: MemoryType,
38        pages: usize,
39        host_address: *mut *mut c_void,
40        attributes: EdkiiIommuAttribute,
41    ) -> Status,
42    pub free_buffer: unsafe extern "efiapi" fn(
43        this: *const Self,
44        pages: usize,
45        host_address: *mut c_void,
46    ) -> Status,
47}
48
49newtype_enum! {
50    /// IOMMU Operation for Map (matches EDKII_IOMMU_OPERATION)
51    pub enum EdkiiIommuOperation: u32 => {
52        /// A read operation from system memory by a bus master that is not capable of producing PCI dual address cycles.
53        BUS_MASTER_READ = 0,
54        /// A write operation to system memory by a bus master that is not capable of producing PCI dual address cycles.
55        BUS_MASTER_WRITE = 1,
56        /// Provides both read and write access to system memory by both the processor and a bus master that is not capable of producing PCI dual address cycles.
57        BUS_MASTER_COMMON_BUFFER = 2,
58        /// A read operation from system memory by a bus master that is capable of producing PCI dual address cycles.
59        BUS_MASTER_READ64 = 3,
60        /// A write operation to system memory by a bus master that is capable of producing PCI dual address cycles.
61        BUS_MASTER_WRITE64 = 4,
62        /// Provides both read and write access to system memory by both the processor and a bus master that is capable of producing PCI dual address cycles.
63        BUS_MASTER_COMMON_BUFFER64 = 5,
64        /// Maximum value (not a valid operation, for bounds checking)
65        MAXIMUM = 6,
66    }
67}
68
69/// EDKII IOMMU protocol revision constant
70pub const EDKII_IOMMU_PROTOCOL_REVISION: u64 = 0x0001_0000;
71
72bitflags! {
73    /// EDKII IOMMU attribute flags
74    #[repr(transparent)]
75    #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
76    pub struct EdkiiIommuAttribute: u64 {
77        /// Memory is write-combined
78        const MEMORY_WRITE_COMBINE   = 0x0080;
79        /// Memory is cached
80        const MEMORY_CACHED          = 0x0800;
81        /// Dual address cycle supported
82        const DUAL_ADDRESS_CYCLE     = 0x8000;
83    }
84}
85
86impl EdkiiIommuAttribute {
87    /// Valid attributes for allocate_buffer
88    pub const VALID_FOR_ALLOCATE_BUFFER: Self = Self::from_bits_truncate(
89        Self::MEMORY_WRITE_COMBINE.bits()
90            | Self::MEMORY_CACHED.bits()
91            | Self::DUAL_ADDRESS_CYCLE.bits(),
92    );
93
94    /// Invalid attributes for allocate_buffer (all bits except valid)
95    pub const INVALID_FOR_ALLOCATE_BUFFER: Self =
96        Self::from_bits_truncate(!Self::VALID_FOR_ALLOCATE_BUFFER.bits());
97}
98
99bitflags! {
100    /// EDKII IOMMU access flags for SetAttribute
101    #[repr(transparent)]
102    #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
103    pub struct EdkiiIommuAccess: u64 {
104        /// Read access
105        const READ  = 0x1;
106        /// Write access
107        const WRITE = 0x2;
108    }
109}