Skip to content
Closed
9 changes: 7 additions & 2 deletions uefi/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
# uefi - [Unreleased]

## Added
- Added `ConfigTableEntry::MEMORY_ATTRIBUTES_GUID` and `ConfigTableEntry::IMAGE_SECURITY_DATABASE_GUID`.

## Changed
- **Breaking:** `boot::stall` now take `Duration` instead of
`usize`.
- **Breaking:** `boot::stall` now take `core::time::Duration` instead of `usize`.
- `table::cfg::*_GUID` constants now deprecated. Use `ConfigTableEntry::*_GUID` instead.
- `system::with_config_table`, `system::with_stdin`, `system::with_stdout` and `system::with_stderr`
now take mutably closure.


# uefi - 0.35.0 (2025-05-04)
Expand Down
57 changes: 49 additions & 8 deletions uefi/src/system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,26 @@ pub fn uefi_revision() -> Revision {

/// Call `f` with a slice of [`ConfigTableEntry`]. Each entry provides access to
/// a vendor-specific table.
pub fn with_config_table<F, R>(f: F) -> R
///
/// # Example
///
/// ```rust,no_run
/// use uefi::system::with_config_table;
/// use uefi::table::cfg::ConfigTableEntry;
///
/// with_config_table(|slice| {
/// for i in slice {
/// match i.guid {
/// ConfigTableEntry::ACPI_GUID => println!("Found ACPI1"),
/// ConfigTableEntry::ACPI2_GUID => println!("Found ACPI2"),
/// guid => println!("Found {}", guid),
/// }
/// }
/// });
/// ```
pub fn with_config_table<F, R>(mut f: F) -> R
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please document these changes in the changelog

where
F: Fn(&[ConfigTableEntry]) -> R,
F: FnMut(&[ConfigTableEntry]) -> R,
{
let st = table::system_table_raw_panicking();
// SAFETY: valid per requirements of `set_system_table`.
Expand All @@ -75,9 +92,9 @@ where
///
/// This function will panic if called after exiting boot services, or if stdin
/// is not available.
pub fn with_stdin<F, R>(f: F) -> R
pub fn with_stdin<F, R>(mut f: F) -> R
where
F: Fn(&mut Input) -> R,
F: FnMut(&mut Input) -> R,
{
let st = table::system_table_raw_panicking();
// SAFETY: valid per requirements of `set_system_table`.
Expand All @@ -101,9 +118,9 @@ where
///
/// This function will panic if called after exiting boot services, or if stdout
/// is not available.
pub fn with_stdout<F, R>(f: F) -> R
pub fn with_stdout<F, R>(mut f: F) -> R
where
F: Fn(&mut Output) -> R,
F: FnMut(&mut Output) -> R,
{
let st = table::system_table_raw_panicking();
// SAFETY: valid per requirements of `set_system_table`.
Expand All @@ -127,9 +144,9 @@ where
///
/// This function will panic if called after exiting boot services, or if stderr
/// is not available.
pub fn with_stderr<F, R>(f: F) -> R
pub fn with_stderr<F, R>(mut f: F) -> R
where
F: Fn(&mut Output) -> R,
F: FnMut(&mut Output) -> R,
{
let st = table::system_table_raw_panicking();
// SAFETY: valid per requirements of `set_system_table`.
Expand All @@ -146,3 +163,27 @@ where

f(stderr)
}

#[cfg(test)]
mod tests {
use super::*;
use crate::table::cfg::ACPI2_GUID;

#[allow(dead_code)]
#[allow(clippy::assertions_on_constants)]
fn with_config_table_compile_test() {
assert!(false, "compile test only");
let mut acpi2_address = None;
with_config_table(|slice| {
for i in slice {
match i.guid {
ACPI2_GUID => {
acpi2_address = Some(i.address);
break;
}
_ => {}
}
}
});
}
}
143 changes: 127 additions & 16 deletions uefi/src/table/cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
//!
//! This module contains the actual entries of the configuration table,
//! as well as GUIDs for many known vendor tables.
//!
//! See <https://uefi.org/specs/UEFI/2.10/04_EFI_System_Table.html#efi-configuration-table-properties-table>.

use crate::{guid, Guid};
use bitflags::bitflags;
Expand All @@ -16,6 +18,8 @@ use core::ffi::c_void;
/// Contains a set of GUID / pointer for a vendor-specific table.
///
/// The UEFI standard guarantees each entry is unique.
///
/// See <https://uefi.org/specs/UEFI/2.10/04_EFI_System_Table.html#efi-configuration-table>.
#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[repr(C)]
pub struct ConfigTableEntry {
Expand All @@ -26,26 +30,106 @@ pub struct ConfigTableEntry {
/// Whether this is a physical or virtual address depends on the table.
pub address: *const c_void,
}
/// Entry pointing to the old ACPI 1 RSDP.
pub const ACPI_GUID: Guid = guid!("eb9d2d30-2d88-11d3-9a16-0090273fc14d");

///Entry pointing to the ACPI 2 RSDP.
pub const ACPI2_GUID: Guid = guid!("8868e871-e4f1-11d3-bc22-0080c73c8881");
impl ConfigTableEntry {
/// Entry pointing to the old ACPI 1 RSDP.
pub const ACPI_GUID: Guid = guid!("eb9d2d30-2d88-11d3-9a16-0090273fc14d");

/// Entry pointing to the ACPI 2 RSDP.
pub const ACPI2_GUID: Guid = guid!("8868e871-e4f1-11d3-bc22-0080c73c8881");

/// Entry pointing to the SMBIOS 1.0 table.
pub const SMBIOS_GUID: Guid = guid!("eb9d2d31-2d88-11d3-9a16-0090273fc14d");

/// Entry pointing to the SMBIOS 3.0 table.
pub const SMBIOS3_GUID: Guid = guid!("f2fd1544-9794-4a2c-992e-e5bbcf20e394");

/// Entry pointing to the EFI System Resource table (ESRT).
pub const ESRT_GUID: Guid = guid!("b122a263-3661-4f68-9929-78f8b0d62180");

/// Hand-off Blocks are used to pass data from the early pre-UEFI environment to the UEFI drivers.
///
/// Most OS loaders or applications should not mess with this.
pub const HAND_OFF_BLOCK_LIST_GUID: Guid = guid!("7739f24c-93d7-11d4-9a3a-0090273fc14d");

/// Table used in the early boot environment to record memory ranges.
pub const MEMORY_TYPE_INFORMATION_GUID: Guid = guid!("4c19049f-4137-4dd3-9c10-8b97a83ffdfa");

/// Used to identify Hand-off Blocks which store
/// status codes reported during the pre-UEFI environment.
pub const MEMORY_STATUS_CODE_RECORD_GUID: Guid = guid!("060cc026-4c0d-4dda-8f41-595fef00a502");

/// Provides additional information about regions within the run-time memory blocks.
/// See <https://uefi.org/specs/UEFI/2.10/04_EFI_System_Table.html#efi-memory-attributes-table>.
pub const MEMORY_ATTRIBUTES_GUID: Guid = guid!("dcfa911d-26eb-469f-a220-38b7dc461220");

/// Constants used for UEFI signature database variable access.
/// See <https://uefi.org/specs/UEFI/2.11/32_Secure_Boot_and_Driver_Signing.html#uefi-image-variable-guid-variable-name>.
pub const IMAGE_SECURITY_DATABASE_GUID: Guid = guid!("d719b2cb-3d3a-4596-a3bc-dad00e67656f");

/// Table which provides Driver eXecution Environment services.
pub const DXE_SERVICES_GUID: Guid = guid!("05ad34ba-6f02-4214-952e-4da0398e2bb9");

/// LZMA-compressed filesystem.
pub const LZMA_COMPRESS_GUID: Guid = guid!("ee4e5898-3914-4259-9d6e-dc7bd79403cf");

/// A custom compressed filesystem used by the Tiano UEFI implementation.
pub const TIANO_COMPRESS_GUID: Guid = guid!("a31280ad-481e-41b6-95e8-127f4c984779");

/// Pointer to the debug image info table.
pub const DEBUG_IMAGE_INFO_GUID: Guid = guid!("49152e77-1ada-4764-b7a2-7afefed95e8b");

/// GUID of the UEFI properties table.
///
/// The properties table is used to provide additional info
/// about the UEFI implementation.
pub const PROPERTIES_TABLE_GUID: Guid = guid!("880aaca3-4adc-4a04-9079-b747340825e5");
}

/// Entry pointing to the old ACPI 1 RSDP.
#[deprecated(
since = "0.35.1",
note = "please use `ConfigTableEntry::ACPI_GUID` instead"
)]
pub const ACPI_GUID: Guid = ConfigTableEntry::ACPI_GUID;

/// Entry pointing to the ACPI 2 RSDP.
#[deprecated(
since = "0.35.1",
note = "please use `ConfigTableEntry::ACPI2_GUID` instead"
)]
pub const ACPI2_GUID: Guid = ConfigTableEntry::ACPI2_GUID;

/// Entry pointing to the SMBIOS 1.0 table.
pub const SMBIOS_GUID: Guid = guid!("eb9d2d31-2d88-11d3-9a16-0090273fc14d");
#[deprecated(
since = "0.35.1",
note = "please use `ConfigTableEntry::SMBIOS_GUID` instead"
)]
pub const SMBIOS_GUID: Guid = ConfigTableEntry::SMBIOS_GUID;

/// Entry pointing to the SMBIOS 3.0 table.
pub const SMBIOS3_GUID: Guid = guid!("f2fd1544-9794-4a2c-992e-e5bbcf20e394");
#[deprecated(
since = "0.35.1",
note = "please use `ConfigTableEntry::SMBIOS3_GUID` instead"
)]
pub const SMBIOS3_GUID: Guid = ConfigTableEntry::SMBIOS3_GUID;

/// Entry pointing to the EFI System Resource table (ESRT).
pub const ESRT_GUID: Guid = guid!("b122a263-3661-4f68-9929-78f8b0d62180");
#[deprecated(
since = "0.35.1",
note = "please use `ConfigTableEntry::ESRT_GUID` instead"
)]
pub const ESRT_GUID: Guid = ConfigTableEntry::ESRT_GUID;

/// GUID of the UEFI properties table.
///
/// The properties table is used to provide additional info
/// about the UEFI implementation.
pub const PROPERTIES_TABLE_GUID: Guid = guid!("880aaca3-4adc-4a04-9079-b747340825e5");
#[deprecated(
since = "0.35.1",
note = "please use `ConfigTableEntry::PROPERTIES_TABLE_GUID` instead"
)]
pub const PROPERTIES_TABLE_GUID: Guid = ConfigTableEntry::PROPERTIES_TABLE_GUID;

/// This table contains additional information about the UEFI implementation.
#[repr(C)]
Expand Down Expand Up @@ -77,23 +161,50 @@ bitflags! {
/// Hand-off Blocks are used to pass data from the early pre-UEFI environment to the UEFI drivers.
///
/// Most OS loaders or applications should not mess with this.
pub const HAND_OFF_BLOCK_LIST_GUID: Guid = guid!("7739f24c-93d7-11d4-9a3a-0090273fc14d");
#[deprecated(
since = "0.35.1",
note = "please use `ConfigTableEntry::HAND_OFF_BLOCK_LIST_GUID` instead"
)]
pub const HAND_OFF_BLOCK_LIST_GUID: Guid = ConfigTableEntry::HAND_OFF_BLOCK_LIST_GUID;

/// Table used in the early boot environment to record memory ranges.
pub const MEMORY_TYPE_INFORMATION_GUID: Guid = guid!("4c19049f-4137-4dd3-9c10-8b97a83ffdfa");
#[deprecated(
since = "0.35.1",
note = "please use `ConfigTableEntry::MEMORY_TYPE_INFORMATION_GUID` instead"
)]
pub const MEMORY_TYPE_INFORMATION_GUID: Guid = ConfigTableEntry::MEMORY_TYPE_INFORMATION_GUID;

/// Used to identify Hand-off Blocks which store
/// status codes reported during the pre-UEFI environment.
pub const MEMORY_STATUS_CODE_RECORD_GUID: Guid = guid!("060cc026-4c0d-4dda-8f41-595fef00a502");
#[deprecated(
since = "0.35.1",
note = "please use `ConfigTableEntry::MEMORY_STATUS_CODE_RECORD_GUID` instead"
)]
pub const MEMORY_STATUS_CODE_RECORD_GUID: Guid = ConfigTableEntry::MEMORY_STATUS_CODE_RECORD_GUID;

/// Table which provides Driver eXecution Environment services.
pub const DXE_SERVICES_GUID: Guid = guid!("05ad34ba-6f02-4214-952e-4da0398e2bb9");
#[deprecated(
since = "0.35.1",
note = "please use `ConfigTableEntry::DXE_SERVICES_GUID` instead"
)]
pub const DXE_SERVICES_GUID: Guid = ConfigTableEntry::DXE_SERVICES_GUID;

/// LZMA-compressed filesystem.
pub const LZMA_COMPRESS_GUID: Guid = guid!("ee4e5898-3914-4259-9d6e-dc7bd79403cf");
#[deprecated(
since = "0.35.1",
note = "please use `ConfigTableEntry::LZMA_COMPRESS_GUID` instead"
)]
pub const LZMA_COMPRESS_GUID: Guid = ConfigTableEntry::LZMA_COMPRESS_GUID;

/// A custom compressed filesystem used by the Tiano UEFI implementation.
pub const TIANO_COMPRESS_GUID: Guid = guid!("a31280ad-481e-41b6-95e8-127f4c984779");

#[deprecated(
since = "0.35.1",
note = "please use `ConfigTableEntry::TIANO_COMPRESS_GUID` instead"
)]
pub const TIANO_COMPRESS_GUID: Guid = ConfigTableEntry::TIANO_COMPRESS_GUID;
/// Pointer to the debug image info table.
pub const DEBUG_IMAGE_INFO_GUID: Guid = guid!("49152e77-1ada-4764-b7a2-7afefed95e8b");
#[deprecated(
since = "0.35.1",
note = "please use `ConfigTableEntry::DEBUG_IMAGE_INFO_GUID` instead"
)]
pub const DEBUG_IMAGE_INFO_GUID: Guid = ConfigTableEntry::DEBUG_IMAGE_INFO_GUID;
43 changes: 38 additions & 5 deletions xtask/src/check_raw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,28 @@ use syn::{
};
use walkdir::WalkDir;

/// Type of an `Item`.
#[derive(Debug, Eq, PartialEq)]
enum ItemKind {
Enum,
Other,
}

impl From<&Item> for ItemKind {
fn from(item: &Item) -> Self {
match item {
Item::Enum(_) => Self::Enum,
_ => Self::Other,
}
}
}

/// All possible validation error kinds.
#[derive(Debug, Eq, PartialEq)]
enum ErrorKind {
ForbiddenAbi,
ForbiddenAttr,
ForbiddenItemKind,
ForbiddenItemKind(ItemKind),
ForbiddenRepr,
ForbiddenType,
MalformedAttrs,
Expand All @@ -47,7 +63,9 @@ impl Display for ErrorKind {
match self {
Self::ForbiddenAbi => "forbidden ABI",
Self::ForbiddenAttr => "forbidden attribute",
Self::ForbiddenItemKind => "forbidden type of item",
Self::ForbiddenItemKind(ItemKind::Enum) =>
"forbidden use of enum; use the `newtype_enum!` macro instead",
Self::ForbiddenItemKind(_) => "forbidden type of item",
Self::ForbiddenRepr => "forbidden repr",
Self::ForbiddenType => "forbidden type",
Self::MalformedAttrs => "malformed attribute contents",
Expand Down Expand Up @@ -364,7 +382,11 @@ fn check_item(item: &Item, src: &Path) -> Result<(), Error> {
// Allow.
}
item => {
return Err(Error::new(ErrorKind::ForbiddenItemKind, src, item));
return Err(Error::new(
ErrorKind::ForbiddenItemKind(item.into()),
src,
item,
));
}
}

Expand Down Expand Up @@ -424,15 +446,26 @@ mod tests {
}

#[test]
fn test_invalid_item() {
fn test_invalid_item_enum() {
// Rust enums are not allowed.
check_item_err(
parse_quote! {
pub enum E {
A
}
},
ErrorKind::ForbiddenItemKind,
ErrorKind::ForbiddenItemKind(ItemKind::Enum),
);
}

#[test]
fn test_invalid_item_other() {
// Top-level functions are not allowed.
check_item_err(
parse_quote! {
pub fn x() {}
},
ErrorKind::ForbiddenItemKind(ItemKind::Other),
);
}

Expand Down