Skip to main content

uefi_raw/protocol/
firmware_volume.rs

1// SPDX-License-Identifier: MIT OR Apache-2.0
2
3use crate::firmware_storage::FirmwareVolumeAttributes;
4use crate::protocol::block::Lba;
5use crate::{Guid, Handle, PhysicalAddress, Status, guid, newtype_enum};
6use core::ffi::c_void;
7use core::ops::RangeInclusive;
8
9bitflags::bitflags! {
10    /// EFI_FV_ATTRIBUTES
11    #[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
12    #[repr(transparent)]
13    pub struct FvAttributes: u64 {
14        const READ_DISABLE_CAP = 1 << 0;
15        const READ_ENABLE_CAP = 1 << 1;
16        const READ_STATUS = 1 << 2;
17
18        const WRITE_DISABLE_CAP = 1 << 3;
19        const WRITE_ENABLE_CAP = 1 << 4;
20        const WRITE_STATUS = 1 << 5;
21
22        const LOCK_CAP = 1 << 6;
23        const LOCK_STATUS = 1 << 7;
24        const WRITE_POLICY_RELIABLE = 1 << 8;
25        const READ_LOCK_CAP = 1 << 12;
26        const READ_LOCK_STATUS = 1 << 13;
27        const WRITE_LOCK_CAP = 1 << 14;
28        const WRITE_LOCK_STATUS = 1 << 15;
29
30        const ALIGNMENT = 0x1F << 16;
31        const ALIGNMENT_1 = 0x00 << 16;
32        const ALIGNMENT_2 = 0x01 << 16;
33        const ALIGNMENT_4 = 0x02 << 16;
34        const ALIGNMENT_8 = 0x03 << 16;
35        const ALIGNMENT_16 = 0x04 << 16;
36        const ALIGNMENT_32 = 0x05 << 16;
37        const ALIGNMENT_64 = 0x06 << 16;
38        const ALIGNMENT_128 = 0x07 << 16;
39        const ALIGNMENT_256 = 0x08 << 16;
40        const ALIGNMENT_512 = 0x09 << 16;
41        const ALIGNMENT_1K = 0x0A << 16;
42        const ALIGNMENT_2K = 0x0B << 16;
43        const ALIGNMENT_4K = 0x0C << 16;
44        const ALIGNMENT_8K = 0x0D << 16;
45        const ALIGNMENT_16K = 0x0E << 16;
46        const ALIGNMENT_32K = 0x0F << 16;
47        const ALIGNMENT_64K = 0x10 << 16;
48        const ALIGNMENT_128K = 0x11 << 16;
49        const ALIGNMENT_256K = 0x12 << 16;
50        const ALIGNMENT_512K = 0x13 << 16;
51        const ALIGNMENT_1M = 0x14 << 16;
52        const ALIGNMENT_2M = 0x15 << 16;
53        const ALIGNMENT_4M = 0x16 << 16;
54        const ALIGNMENT_8M = 0x17 << 16;
55        const ALIGNMENT_16M = 0x18 << 16;
56        const ALIGNMENT_32M = 0x19 << 16;
57        const ALIGNMENT_64M = 0x1A << 16;
58        const ALIGNMENT_128M = 0x1B << 16;
59        const ALIGNMENT_256M = 0x1C << 16;
60        const ALIGNMENT_512M = 0x1D << 16;
61        const ALIGNMENT_1G = 0x1E << 16;
62        const ALIGNMENT_2G = 0x1F << 16;
63    }
64}
65
66bitflags::bitflags! {
67    /// EFI_FV_FILE_ATTRIBUTES
68    #[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
69    #[repr(transparent)]
70    pub struct FvFileAttributes: u32 {
71        const ALIGNMENT = 0x1F;
72        const FIXED = 1 << 8;
73        const MEMORY_MAPPED = 1 << 9;
74    }
75}
76
77newtype_enum! {
78    /// EFI_FV_WRITE_POLICY
79    pub enum FvWritePolicy: u32 => {
80        EFI_FV_UNRELIABLE_WRITE = 0,
81        EFI_FV_RELIABLE_WRITE = 1,
82    }
83}
84
85newtype_enum! {
86    /// EFI_FV_FILETYPE
87    pub enum FvFiletype: u8 => {
88        ALL = 0x00,
89        RAW = 0x01,
90        FREEFORM = 0x02,
91        SECURITY_CORE = 0x03,
92        PEI_CORE = 0x04,
93        DXE_CORE = 0x05,
94        PEIM = 0x06,
95        DRIVER = 0x07,
96        COMBINED_PEIM_DRIVER = 0x08,
97        APPLICATION = 0x09,
98        MM = 0x0A,
99        FIRMWARE_VOLUME_IMAGE = 0x0B,
100        COMBINED_MM_DXE = 0x0C,
101        MM_CORE = 0x0D,
102        MM_STANDALONE = 0x0E,
103        MM_CORE_STANDALONE = 0x0F,
104        FFS_PAD = 0xF0,
105    }
106}
107
108impl FvFiletype {
109    pub const OEM_RANGE: RangeInclusive<u8> = 0xC0..=0xDF;
110    pub const DEBUG_RANGE: RangeInclusive<u8> = 0xE0..=0xEF;
111    pub const FFS_RANGE: RangeInclusive<u8> = 0xF0..=0xFF;
112}
113
114newtype_enum! {
115    /// EFI_SECTION_TYPE
116    pub enum SectionType: u8 => {
117        ALL = 0x00,
118        COMPRESSION = 0x01,
119        GUID_DEFINED = 0x02,
120        DISPOSABLE = 0x03,
121        PE32 = 0x10,
122        PIC = 0x11,
123        TE = 0x12,
124        DXE_DEPEX = 0x13,
125        VERSION = 0x14,
126        USER_INTERFACE = 0x15,
127        COMPATIBILITY16 = 0x16,
128        FIRMWARE_VOLUME_IMAGE = 0x17,
129        FREEFORM_SUBTYPE_GUID = 0x18,
130        RAW = 0x19,
131        PEI_DEPEX = 0x1B,
132        MM_DEPEX = 0x1C,
133    }
134}
135
136/// EFI_FV_WRITE_FILE_DATA
137#[derive(Debug)]
138#[repr(C)]
139pub struct FvWriteFileData {
140    pub name_guid: *const Guid,
141    pub r#type: FvFiletype,
142    pub file_attributes: FvFileAttributes,
143    pub buffer: *const u8,
144    pub buffer_size: u32,
145}
146
147/// EFI_FIRMWARE_VOLUME2_PROTOCOL
148#[derive(Debug)]
149#[repr(C)]
150pub struct FirmwareVolume2Protocol {
151    pub get_volume_attributes:
152        unsafe extern "efiapi" fn(this: *const Self, fv_attributes: *mut FvAttributes) -> Status,
153    pub set_volume_attributes:
154        unsafe extern "efiapi" fn(this: *const Self, fv_attributes: *mut FvAttributes) -> Status,
155    pub read_file: unsafe extern "efiapi" fn(
156        this: *const Self,
157        name_guid: *const Guid,
158        buffer: *mut *mut c_void,
159        buffer_size: *mut usize,
160        found_type: *mut FvFiletype,
161        file_attributes: *mut FvFileAttributes,
162        authentication_status: *mut u32,
163    ) -> Status,
164    pub read_section: unsafe extern "efiapi" fn(
165        this: *const Self,
166        name_guid: *const Guid,
167        section_type: SectionType,
168        section_instance: usize,
169        buffer: *mut *mut c_void,
170        buffer_size: *mut usize,
171        authentication_status: *mut u32,
172    ) -> Status,
173    pub write_file: unsafe extern "efiapi" fn(
174        this: *const Self,
175        number_of_files: u32,
176        write_policy: FvWritePolicy,
177        file_data: *const FvWriteFileData,
178    ) -> Status,
179    pub get_next_file: unsafe extern "efiapi" fn(
180        this: *const Self,
181        key: *mut c_void,
182        file_type: *mut FvFiletype,
183        name_guid: *mut Guid,
184        attributes: *mut FvFileAttributes,
185        size: *mut usize,
186    ) -> Status,
187    pub key_size: u32,
188    pub parent_handle: Handle,
189    pub get_info: unsafe extern "efiapi" fn(
190        this: *const Self,
191        information_type: *const Guid,
192        buffer_size: *mut usize,
193        buffer: *mut c_void,
194    ) -> Status,
195    pub set_info: unsafe extern "efiapi" fn(
196        this: *const Self,
197        information_type: *const Guid,
198        buffer_size: usize,
199        buffer: *const c_void,
200    ) -> Status,
201}
202
203impl FirmwareVolume2Protocol {
204    pub const GUID: Guid = guid!("220e73b6-6bdb-4413-8405-b974b108619a");
205}
206
207/// EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL
208#[derive(Debug)]
209#[repr(C)]
210pub struct FirmwareVolumeBlock2Protocol {
211    pub get_attributes: unsafe extern "efiapi" fn(
212        this: *const Self,
213        attributes: *mut FirmwareVolumeAttributes,
214    ) -> Status,
215    pub set_attributes: unsafe extern "efiapi" fn(
216        this: *const Self,
217        attributes: *mut FirmwareVolumeAttributes,
218    ) -> Status,
219    pub get_physical_address:
220        unsafe extern "efiapi" fn(this: *const Self, address: *mut PhysicalAddress) -> Status,
221    pub get_block_size: unsafe extern "efiapi" fn(
222        this: *const Self,
223        lba: Lba,
224        block_size: *mut usize,
225        number_of_blocks: *mut usize,
226    ) -> Status,
227    pub read: unsafe extern "efiapi" fn(
228        this: *const Self,
229        lba: Lba,
230        offset: usize,
231        num_bytes: *mut usize,
232        buffer: *mut u8,
233    ) -> Status,
234    pub write: unsafe extern "efiapi" fn(
235        this: *const Self,
236        lba: Lba,
237        offset: usize,
238        num_bytes: *mut usize,
239        buffer: *mut u8,
240    ) -> Status,
241    // TODO: Change to efiapi (https://github.com/rust-lang/rust/issues/100189)
242    pub erase_blocks: unsafe extern "C" fn(this: *const Self, ...) -> Status,
243    pub parent_handle: Handle,
244}
245
246impl FirmwareVolumeBlock2Protocol {
247    pub const GUID: Guid = guid!("8f644fa9-e850-4db1-9ce2-0b44698e8da4");
248    pub const LBA_LIST_TERMINATOR: u64 = u64::MAX;
249}