Skip to content

Commit

Permalink
Merge pull request #1503 from crawfxrd/fv2
Browse files Browse the repository at this point in the history
uefi-raw: Add FirmwareVolume{,Block}2Protocol
  • Loading branch information
nicholasbishop authored Jan 3, 2025
2 parents 94eb0b6 + abd4145 commit 21fabff
Show file tree
Hide file tree
Showing 3 changed files with 250 additions and 0 deletions.
2 changes: 2 additions & 0 deletions uefi-raw/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
- Added `protocol::string::UnicodeCollationProtocol`.
- Added `protocol::tcg` module, containing the TCG v1 and v2 protocols.
- Added `DriverBindingProtocol`.
- Added `FirmwareVolume2Protocol`.
- Added `FirmwareVolumeBlock2Protocol`.


# uefi-raw - 0.9.0 (2024-10-23)
Expand Down
247 changes: 247 additions & 0 deletions uefi-raw/src/protocol/firmware_volume.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,247 @@
use crate::firmware_storage::FirmwareVolumeAttributes;
use crate::protocol::block::Lba;
use crate::{guid, Guid, Handle, PhysicalAddress, Status};
use core::ffi::c_void;
use core::ops::RangeInclusive;

bitflags::bitflags! {
/// EFI_FV_ATTRIBUTES
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[repr(transparent)]
pub struct FvAttributes: u64 {
const READ_DISABLE_CAP = 1 << 0;
const READ_ENABLE_CAP = 1 << 1;
const READ_STATUS = 1 << 2;

const WRITE_DISABLE_CAP = 1 << 3;
const WRITE_ENABLE_CAP = 1 << 4;
const WRITE_STATUS = 1 << 5;

const LOCK_CAP = 1 << 6;
const LOCK_STATUS = 1 << 7;
const WRITE_POLICY_RELIABLE = 1 << 8;
const READ_LOCK_CAP = 1 << 12;
const READ_LOCK_STATUS = 1 << 13;
const WRITE_LOCK_CAP = 1 << 14;
const WRITE_LOCK_STATUS = 1 << 15;

const ALIGNMENT = 0x1F << 16;
const ALIGNMENT_1 = 0x00 << 16;
const ALIGNMENT_2 = 0x01 << 16;
const ALIGNMENT_4 = 0x02 << 16;
const ALIGNMENT_8 = 0x03 << 16;
const ALIGNMENT_16 = 0x04 << 16;
const ALIGNMENT_32 = 0x05 << 16;
const ALIGNMENT_64 = 0x06 << 16;
const ALIGNMENT_128 = 0x07 << 16;
const ALIGNMENT_256 = 0x08 << 16;
const ALIGNMENT_512 = 0x09 << 16;
const ALIGNMENT_1K = 0x0A << 16;
const ALIGNMENT_2K = 0x0B << 16;
const ALIGNMENT_4K = 0x0C << 16;
const ALIGNMENT_8K = 0x0D << 16;
const ALIGNMENT_16K = 0x0E << 16;
const ALIGNMENT_32K = 0x0F << 16;
const ALIGNMENT_64K = 0x10 << 16;
const ALIGNMENT_128K = 0x11 << 16;
const ALIGNMENT_256K = 0x12 << 16;
const ALIGNMENT_512K = 0x13 << 16;
const ALIGNMENT_1M = 0x14 << 16;
const ALIGNMENT_2M = 0x15 << 16;
const ALIGNMENT_4M = 0x16 << 16;
const ALIGNMENT_8M = 0x17 << 16;
const ALIGNMENT_16M = 0x18 << 16;
const ALIGNMENT_32M = 0x19 << 16;
const ALIGNMENT_64M = 0x1A << 16;
const ALIGNMENT_128M = 0x1B << 16;
const ALIGNMENT_256M = 0x1C << 16;
const ALIGNMENT_512M = 0x1D << 16;
const ALIGNMENT_1G = 0x1E << 16;
const ALIGNMENT_2G = 0x1F << 16;
}
}

bitflags::bitflags! {
/// EFI_FV_FILE_ATTRIBUTES
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[repr(transparent)]
pub struct FvFileAttributes: u32 {
const ALIGNMENT = 0x1F;
const FIXED = 1 << 8;
const MEMORY_MAPPED = 1 << 9;
}
}

newtype_enum! {
/// EFI_FV_WRITE_POLICY
pub enum FvWritePolicy: u32 => {
EFI_FV_UNRELIABLE_WRITE = 0,
EFI_FV_RELIABLE_WRITE = 1,
}
}

newtype_enum! {
/// EFI_FV_FILETYPE
pub enum FvFiletype: u8 => {
ALL = 0x00,
RAW = 0x01,
FREEFORM = 0x02,
SECURITY_CORE = 0x03,
PEI_CORE = 0x04,
DXE_CORE = 0x05,
PEIM = 0x06,
DRIVER = 0x07,
COMBINED_PEIM_DRIVER = 0x08,
APPLICATION = 0x09,
MM = 0x0A,
FIRMWARE_VOLUME_IMAGE = 0x0B,
COMBINED_MM_DXE = 0x0C,
MM_CORE = 0x0D,
MM_STANDALONE = 0x0E,
MM_CORE_STANDALONE = 0x0F,
FFS_PAD = 0xF0,
}
}

impl FvFiletype {
pub const OEM_RANGE: RangeInclusive<u8> = 0xC0..=0xDF;
pub const DEBUG_RANGE: RangeInclusive<u8> = 0xE0..=0xEF;
pub const FFS_RANGE: RangeInclusive<u8> = 0xF0..=0xFF;
}

newtype_enum! {
/// EFI_SECTION_TYPE
pub enum SectionType: u8 => {
ALL = 0x00,
COMPRESSION = 0x01,
GUID_DEFINED = 0x02,
DISPOSABLE = 0x03,
PE32 = 0x10,
PIC = 0x11,
TE = 0x12,
DXE_DEPEX = 0x13,
VERSION = 0x14,
USER_INTERFACE = 0x15,
COMPATIBILITY16 = 0x16,
FIRMWARE_VOLUME_IMAGE = 0x17,
FREEFORM_SUBTYPE_GUID = 0x18,
RAW = 0x19,
PEI_DEPEX = 0x1B,
MM_DEPEX = 0x1C,
}
}

/// EFI_FV_WRITE_FILE_DATA
#[derive(Debug)]
#[repr(C)]
pub struct FvWriteFileData {
pub name_guid: *const Guid,
pub r#type: FvFiletype,
pub file_attributes: FvFileAttributes,
pub buffer: *const u8,
pub buffer_size: u32,
}

/// EFI_FIRMWARE_VOLUME2_PROTOCOL
#[derive(Debug)]
#[repr(C)]
pub struct FirmwareVolume2Protocol {
pub get_volume_attributes:
unsafe extern "efiapi" fn(this: *const Self, fv_attributes: *mut FvAttributes) -> Status,
pub set_volume_attributes:
unsafe extern "efiapi" fn(this: *const Self, fv_attributes: *mut FvAttributes) -> Status,
pub read_file: unsafe extern "efiapi" fn(
this: *const Self,
name_guid: *const Guid,
buffer: *mut *mut c_void,
buffer_size: *mut usize,
found_type: *mut FvFiletype,
file_attributes: *mut FvFileAttributes,
authentication_status: *mut u32,
) -> Status,
pub read_section: unsafe extern "efiapi" fn(
this: *const Self,
name_guid: *const Guid,
section_type: SectionType,
section_instance: usize,
buffer: *mut *mut c_void,
buffer_size: *mut usize,
authentication_status: *mut u32,
) -> Status,
pub write_file: unsafe extern "efiapi" fn(
this: *const Self,
number_of_files: u32,
write_policy: FvWritePolicy,
file_data: *const FvWriteFileData,
) -> Status,
pub get_next_file: unsafe extern "efiapi" fn(
this: *const Self,
key: *mut c_void,
file_type: *mut FvFiletype,
name_guid: *mut Guid,
attributes: *mut FvFileAttributes,
size: *mut usize,
) -> Status,
pub key_size: u32,
pub parent_handle: Handle,
pub get_info: unsafe extern "efiapi" fn(
this: *const Self,
information_type: *const Guid,
buffer_size: *mut usize,
buffer: *mut c_void,
) -> Status,
pub set_info: unsafe extern "efiapi" fn(
this: *const Self,
information_type: *const Guid,
buffer_size: usize,
buffer: *const c_void,
) -> Status,
}

impl FirmwareVolume2Protocol {
pub const GUID: Guid = guid!("220e73b6-6bdb-4413-8405-b974b108619a");
}

/// EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL
#[derive(Debug)]
#[repr(C)]
pub struct FirmwareVolumeBlock2Protocol {
pub get_attributes: unsafe extern "efiapi" fn(
this: *const Self,
attributes: *mut FirmwareVolumeAttributes,
) -> Status,
pub set_attributes: unsafe extern "efiapi" fn(
this: *const Self,
attributes: *mut FirmwareVolumeAttributes,
) -> Status,
pub get_physical_address:
unsafe extern "efiapi" fn(this: *const Self, address: *mut PhysicalAddress) -> Status,
pub get_block_size: unsafe extern "efiapi" fn(
this: *const Self,
lba: Lba,
block_size: *mut usize,
number_of_blocks: *mut usize,
) -> Status,
pub read: unsafe extern "efiapi" fn(
this: *const Self,
lba: Lba,
offset: usize,
num_bytes: *mut usize,
buffer: *mut u8,
) -> Status,
pub write: unsafe extern "efiapi" fn(
this: *const Self,
lba: Lba,
offset: usize,
num_bytes: *mut usize,
buffer: *mut u8,
) -> Status,
// TODO: Change to efiapi (https://github.com/rust-lang/rust/issues/100189)
pub erase_blocks: unsafe extern "C" fn(this: *const Self, ...) -> Status,
pub parent_handle: Handle,
}

impl FirmwareVolumeBlock2Protocol {
pub const GUID: Guid = guid!("8f644fa9-e850-4db1-9ce2-0b44698e8da4");
pub const LBA_LIST_TERMINATOR: u64 = u64::MAX;
}
1 change: 1 addition & 0 deletions uefi-raw/src/protocol/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ pub mod device_path;
pub mod disk;
pub mod driver;
pub mod file_system;
pub mod firmware_volume;
pub mod loaded_image;
pub mod media;
pub mod memory_protection;
Expand Down

0 comments on commit 21fabff

Please sign in to comment.