Skip to content
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
796dd66
SDK: SerDe HOB: Add FV2 and FV3 Support
os-d Sep 2, 2026
b2933e8
Chore: Update crate versions to 23.1.1 (#1766)
patina-automation[bot] Sep 3, 2026
bca86a2
SDK: SerDe HOB: Implement Interval for FvHobSerDe (#1769)
vineelko Sep 8, 2026
8c9d81a
Merge branch 'main' at bca86a23 into major
makubacki Sep 8, 2026
8757b07
sdk: Allow char16!/char8! to be used inside const and static items
makubacki Aug 28, 2026
b6f3ff4
sdk: Add a dedicated CRC-32 module for Patina
makubacki Aug 20, 2026
483a774
patina_dxe_core: Use the Patina SDK CRC-32 implementation
makubacki Aug 20, 2026
99da72f
sdk: Implement ProtocolInterface for TimerProtocol
makubacki Aug 10, 2026
5f0e005
sdk: Add Patina UEFI Services
makubacki Jul 21, 2026
84fe40d
Implement the ConfigTable trait on config table types
makubacki Aug 20, 2026
06301ea
patina_dxe_core/misc_boot_services: Treat protocol pointer as static …
makubacki Aug 14, 2026
2c4652e
patina_dxe_core: Produce UEFI Services
makubacki Jul 23, 2026
8e5d257
components/patina_samples: Add UEFI Services sample components
makubacki Jul 24, 2026
cf9f6d7
sdk: Add ServiceCell<T> for bridging services to context-free callbacks
makubacki Aug 8, 2026
5f27114
sdk: Impl Debug for Service<T>
makubacki Aug 12, 2026
6c01742
Swap Service::new_unit() usage to ServiceCell<T>
makubacki Aug 12, 2026
a017d52
sdk: Drop Service::new_uninit()
makubacki Aug 12, 2026
aa8e1ff
Remove clone calls on Service<T> instances
makubacki Aug 20, 2026
c80959a
patina_performance: Migrate protocol.rs to MeasurementProtocolPublisher
makubacki Aug 8, 2026
34487de
patina_performance: Add PropertyPublisher component
makubacki Aug 8, 2026
3574fd1
patina_performance: Fix get_variable() call
makubacki Aug 12, 2026
04ddc70
patina_performance: Add FbptPublisher component
makubacki Aug 3, 2026
bbfbf43
patina_performance: Add MmRecordCollector component
makubacki Aug 3, 2026
89c4490
patina_performance: Remove the monolithic Performance component
makubacki Aug 3, 2026
f8f5086
Update docs for the patina_performance component split
makubacki Aug 3, 2026
eca798d
sdk: Implement TplController for Service<dyn TplServices>
makubacki Aug 3, 2026
6ea17a5
components/patina_smbios: Add a Busy error for SMBIOS lock contention
makubacki Aug 3, 2026
5064a7a
components/patina_smbios: Extend the Smbios trait with record lookup …
makubacki Jul 31, 2026
eb88c32
components/patina_smbios: Move SMBIOS service off raw BootServices
makubacki Jul 31, 2026
49fb559
components/patina_smbios: Split SmbiosProvider and add SmbiosProtocol…
makubacki Aug 4, 2026
e98fa22
Update SMBIOS docs for the two component split
makubacki Aug 4, 2026
869e9e8
components/patina_adv_logger: Update to use UEFI Services
makubacki Aug 4, 2026
6e95b4a
components/patina_mm: Replace StandardBootServices with UEFI Services
makubacki Aug 5, 2026
93aeede
components/patina_test: Add mockall dev-dependency for UEFI service m…
makubacki Aug 5, 2026
d292dc8
components/patina_test: Migrate TestRunner to UEFI Services
makubacki Aug 5, 2026
bce65f3
components/patina_acpi: Cover all AcpiError enum variants with tests
makubacki Aug 14, 2026
17060f7
components/patina_acpi: Rename BootServicesAlreadyInitialized
makubacki Aug 5, 2026
81dd029
components/patina_acpi: Use UEFI Services in the ACPI component
makubacki Aug 5, 2026
829dee5
components/patina_acpi: Use ProtocolServices in acpi_protocol_test
makubacki Aug 6, 2026
69e4282
patina_dxe_core: Migrate internal components off StandardBootServices
makubacki Aug 6, 2026
be7e28c
patina_dxe_core: Remove StandardBootServices from the dispatcher
makubacki Aug 6, 2026
35fe018
sdk: Update component benchmark to drop StandardBootServices
makubacki Aug 6, 2026
f681148
sdk: Remove StandardBootServices from the Patina SDK component model
makubacki Aug 7, 2026
d5fce5b
docs: Account for StandardBootServices removal
makubacki Aug 10, 2026
c4bc4e6
sdk: Add locate_first_handle() to Protocol Services
makubacki Sep 1, 2026
c6d07f2
Add UEFI Driver Binding support to UEFI Services
makubacki Sep 2, 2026
8f48934
Group UEFI driver model services under a driver_model module
makubacki Sep 3, 2026
ae0bacb
sdk: Add a language table for driver model name protocols
makubacki Sep 3, 2026
7ddf94c
sdk: Add a temporary Component Name protocol definition (until in r-efi)
makubacki Sep 4, 2026
c805123
sdk: Add a temporary EFI Driver Supported EFI Version protocol defini…
makubacki Sep 2, 2026
97461c1
sdk: Add UefiDriverModelComponentName to publish component name proto…
makubacki Sep 3, 2026
3368d18
components: Add a UEFI Driver Model component name producer sample
makubacki Sep 3, 2026
84aa3ee
sdk: Add support for EFI Driver Supported EFI Version protocol to UEF…
makubacki Sep 2, 2026
257740d
components: Add EFI Driver Supported EFI Version protocol sample
makubacki Sep 2, 2026
ef6de6d
Add Protocol<P> component dependency parameter
makubacki Sep 2, 2026
beb6497
components/patina_samples: Add a protocol dispatch dependency sample
makubacki Sep 4, 2026
0d7893c
sdk/pi: Add PCD Protocol definition
makubacki Sep 3, 2026
979d61f
sdk: Add the PcdServices trait
makubacki Sep 3, 2026
a8f0061
Add PCD (Platform Configuration Database) component
makubacki Sep 4, 2026
22aaaf0
components: Add patina_graphics_console
makubacki Sep 4, 2026
9cc7b5b
components/patina_graphics_console: Add default font data
makubacki Sep 4, 2026
dd8b933
docs: Add component state storage docs
makubacki Aug 12, 2026
89f426b
docs: Add Patina UEFI Services documentation
makubacki Aug 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 13 additions & 13 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ resolver = "3"
members = ["components/*", "core/*", "sdk/*", "patina_dxe_core"]

[workspace.package]
version = "23.1.0"
version = "23.1.1"
license = "Apache-2.0"
edition = "2024"
rust-version = "1.90"
Expand Down Expand Up @@ -34,21 +34,21 @@ linkme = { version = "0.3.36" }
log = { version = "0.4", default-features = false }
memoffset = {version = "0.9.1" }
num-traits = { version = "0.2", default-features = false }
patina = { version = "23.1.0", path = "sdk/patina" }
patina_debugger = { version = "23.1.0", path = "core/patina_debugger" }
patina_ffs = { version = "23.1.0", path = "sdk/patina_ffs" }
patina_ffs_extractors = { version = "23.1.0", path = "sdk/patina_ffs_extractors" }
patina_internal_core = { version = "23.1.0", path = "core/patina_internal_core", default-features = false }
patina_internal_cpu = { version = "23.1.0", path = "core/patina_internal_cpu" }
patina = { version = "23.1.1", path = "sdk/patina" }
patina_debugger = { version = "23.1.1", path = "core/patina_debugger" }
patina_ffs = { version = "23.1.1", path = "sdk/patina_ffs" }
patina_ffs_extractors = { version = "23.1.1", path = "sdk/patina_ffs_extractors" }
patina_internal_core = { version = "23.1.1", path = "core/patina_internal_core", default-features = false }
patina_internal_cpu = { version = "23.1.1", path = "core/patina_internal_cpu" }
lzma-rust2 = { version = "0.16", default-features = false }
patina_macro = { version = "23.1.0", path = "sdk/patina_macro" }
patina_mm = { version = "23.1.0", path = "components/patina_mm" }
patina_macro = { version = "23.1.1", path = "sdk/patina_macro" }
patina_mm = { version = "23.1.1", path = "components/patina_mm" }
patina_mtrr = { version = "1.1.9" }
patina_paging = { version = "11.0.4" }
patina_performance = { version = "23.1.0", path = "components/patina_performance" }
patina_smbios = { version = "23.1.0", path = "components/patina_smbios" }
patina_stacktrace = { version = "23.1.0", path = "core/patina_stacktrace" }
patina_test = { version = "23.1.0", path = "components/patina_test" }
patina_performance = { version = "23.1.1", path = "components/patina_performance" }
patina_smbios = { version = "23.1.1", path = "components/patina_smbios" }
patina_stacktrace = { version = "23.1.1", path = "core/patina_stacktrace" }
patina_test = { version = "23.1.1", path = "components/patina_test" }
proc-macro2 = { version = "1" }
quote = { version = "1" }
scroll = { version = "0.13", default-features = false, features = ["derive"]}
Expand Down
1 change: 0 additions & 1 deletion patina_dxe_core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ workspace = true
[dependencies]
bitfield-struct = { workspace = true }
cfg-if = { workspace = true }
crc32fast = { workspace = true }
goblin = { workspace = true, features = ["pe32", "pe64", "te"] }
linked_list_allocator = { workspace = true }
log = { workspace = true }
Expand Down
5 changes: 3 additions & 2 deletions patina_dxe_core/src/dxe_services.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use core::{
mem,
slice::{self, from_raw_parts},
};
use patina::crc32;
use patina::error::EfiError;
use patina_ffs::volume::VolumeRef;

Expand Down Expand Up @@ -397,7 +398,7 @@ impl<P: PlatformInfo> Core<P> {
let dxe_services_system_table_ptr = &raw const dxe_services_system_table;
// SAFETY: dxe_services_system_table is a local value, its byte representation is valid for hashing.
let crc32 = unsafe {
crc32fast::hash(from_raw_parts(
crc32::calculate_crc32(from_raw_parts(
dxe_services_system_table_ptr as *const u8,
mem::size_of::<dxe_services::DxeServicesTable>(),
))
Expand Down Expand Up @@ -2318,7 +2319,7 @@ mod tests {
let mut copy = unsafe { core::ptr::read(dxe_tbl) };
copy.header.crc32 = 0;
// SAFETY: copy is a local value. Creating a slice from its pointer and size is valid.
let crc = crc32fast::hash(unsafe {
let crc = patina::crc32::calculate_crc32(unsafe {
core::slice::from_raw_parts(
(&raw const copy) as *const u8,
core::mem::size_of::<dxe_services::DxeServicesTable>(),
Expand Down
4 changes: 2 additions & 2 deletions patina_dxe_core/src/gcd/spin_locked_gcd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
use crate::pecoff::UefiPeInfo;
use alloc::{boxed::Box, slice, vec, vec::Vec};
use core::{fmt::Display, ptr};
use patina::{DEFAULT_CACHE_ATTR, error::EfiError, log_debug_assert};
use patina::{DEFAULT_CACHE_ATTR, crc32, error::EfiError, log_debug_assert};

use patina::standard::efi;
use patina::{
Expand Down Expand Up @@ -2972,7 +2972,7 @@ impl SpinLockedGcd {
///
/// * `memory_map_bytes` - The byte slice representing the EFI memory map
pub fn set_last_efi_memory_map_key(&self, memory_map_bytes: &[u8]) {
let key = crc32fast::hash(memory_map_bytes) as usize;
let key = crc32::calculate_crc32(memory_map_bytes) as usize;
*self.last_efi_memory_map_key.lock() = Some(key);
}
}
Expand Down
5 changes: 3 additions & 2 deletions patina_dxe_core/src/misc_boot_services.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use core::{ffi::c_void, slice::from_raw_parts, sync::atomic::Ordering};
use patina::arch as interrupts;
use patina::standard::efi;
use patina::{
crc32,
guid as base_guids, log_debug_assert,
pi::{protocol, status_code},
uefi::event::EXIT_BOOT_SERVICES_FAILED_EVENT_GROUP_GUID,
Expand Down Expand Up @@ -78,7 +79,7 @@ unsafe extern "efiapi" fn calculate_crc32(data: *mut c_void, data_size: usize, c
// SAFETY: caller must ensure that data and crc_32 are valid pointers. They are null-checked above.
unsafe {
let buffer = from_raw_parts(data as *mut u8, data_size);
crc_32.write_unaligned(crc32fast::hash(buffer));
crc_32.write_unaligned(crc32::calculate_crc32(buffer));
}

efi::Status::SUCCESS
Expand Down Expand Up @@ -366,7 +367,7 @@ mod tests {
};
// Verify the function succeeded and CRC32 was calculated correctly for zero buffer
if status == efi::Status::SUCCESS {
let expected_crc = crc32fast::hash(&BUFFER);
let expected_crc = crc32::calculate_crc32(&BUFFER);
if data_crc == expected_crc {
log::debug!("CRC32 calculation successful: {data_crc:#x}");
} else {
Expand Down
7 changes: 5 additions & 2 deletions patina_dxe_core/src/pi_dispatcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ use patina::standard::efi;
use patina::{
BinaryGuid, Char16Str, OwnedGuid,
component::service::Service,
crc32,
error::EfiError,
pi::{
fw_fs::ffs,
Expand Down Expand Up @@ -241,8 +242,10 @@ impl<P: PlatformInfo> PiDispatcher<P> {
},
);

let crc32 =
crc32fast::hash(alloc::slice::from_raw_parts(ptr as *const u8, size_of::<efi::SystemTablePointer>()));
let crc32 = crc32::calculate_crc32(alloc::slice::from_raw_parts(
ptr as *const u8,
size_of::<efi::SystemTablePointer>(),
));

core::ptr::write_volatile(&raw mut (*ptr).crc32, crc32);
}
Expand Down
8 changes: 4 additions & 4 deletions patina_dxe_core/src/systemtables.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use core::{ffi::c_void, mem::size_of, slice::from_raw_parts};

use alloc::boxed::Box;
use patina::standard::efi;
use patina::{component::component, pi::error_codes::EFI_NOT_AVAILABLE_YET, uefi::boot_services::BootServices};
use patina::{component::component, crc32, pi::error_codes::EFI_NOT_AVAILABLE_YET, uefi::boot_services::BootServices};

use crate::{allocator::EFI_RUNTIME_SERVICES_DATA_ALLOCATOR, tpl_mutex};

Expand Down Expand Up @@ -50,7 +50,7 @@ impl EfiRuntimeServicesTable {
// SAFETY: table_copy is a valid, initialized RuntimeServices value on the stack.
let tbl_slice =
unsafe { from_raw_parts(&raw const table_copy as *const u8, size_of::<efi::RuntimeServices>()) };
table_copy.hdr.crc32 = crc32fast::hash(tbl_slice);
table_copy.hdr.crc32 = crc32::calculate_crc32(tbl_slice);

// SAFETY: structure construction ensures pointer is valid.
unsafe { self.runtime_services.write(table_copy) }
Expand Down Expand Up @@ -250,7 +250,7 @@ impl EfiBootServicesTable {

// SAFETY: table_copy is a valid, initialized BootServices value on the stack.
let tbl_slice = unsafe { from_raw_parts(&raw const table_copy as *const u8, size_of::<efi::BootServices>()) };
table_copy.hdr.crc32 = crc32fast::hash(tbl_slice);
table_copy.hdr.crc32 = crc32::calculate_crc32(tbl_slice);

// SAFETY: structure construction ensures pointer is valid.
unsafe { self.boot_services.write(table_copy) }
Expand Down Expand Up @@ -740,7 +740,7 @@ impl EfiSystemTable {

// SAFETY: table_copy is a valid, initialized SystemTable value on the stack.
let st_slice = unsafe { from_raw_parts(&raw const table_copy as *const u8, size_of::<efi::SystemTable>()) };
table_copy.hdr.crc32 = crc32fast::hash(st_slice);
table_copy.hdr.crc32 = crc32::calculate_crc32(st_slice);

// SAFETY: structure construction ensures pointer is valid.
unsafe { self.system_table.write(table_copy) }
Expand Down
1 change: 1 addition & 0 deletions sdk/patina/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ fixedbitset = { workspace = true, optional = true }
bitvec = { workspace = true }
cfg-if = { workspace = true }
compile-time = { workspace = true }
crc32fast = { workspace = true }
goblin = { workspace = true, features = ["pe32", "pe64", "te", "alloc"], optional = true }
log = { workspace = true }
r-efi = { version = "7.1", default-features = false }
Expand Down
1 change: 1 addition & 0 deletions sdk/patina/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use crate::base::error::EfiError;
use crate::standard::efi;

pub mod c_ptr;
pub mod crc32;
pub mod error;
pub mod guid;
pub mod hash;
Expand Down
46 changes: 46 additions & 0 deletions sdk/patina/src/base/crc32.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//! CRC-32 checksum calculation for Patina.
//!
//! Provides a general-purpose CRC-32 checksum function for use across Patina.
//!
//! ## License
//!
//! Copyright (c) Microsoft Corporation.
//!
//! SPDX-License-Identifier: Apache-2.0

/// Computes the CRC-32 of `data`, matching the UEFI `CalculateCrc32` boot service.
///
/// # Examples
///
/// ```rust,no_run
/// use patina::crc32::calculate_crc32;
///
/// let checksum = calculate_crc32(b"hello");
/// log::info!("crc32 = {checksum:#x}");
/// ```
pub fn calculate_crc32(data: &[u8]) -> u32 {
crc32fast::hash(data)
}

#[cfg(test)]
#[cfg_attr(coverage, coverage(off))]
mod tests {
use super::*;

#[test]
fn test_calculate_crc32_empty_slice() {
assert_eq!(calculate_crc32(&[]), crc32fast::hash(&[]));
}

#[test]
fn test_calculate_crc32_known_vector() {
// "123456789" is the standard CRC-32 check-value test vector.
let data = b"123456789";
assert_eq!(calculate_crc32(data), crc32fast::hash(data));
}

#[test]
fn test_calculate_crc32_different_inputs_produce_different_hashes() {
assert_ne!(calculate_crc32(b"abc"), calculate_crc32(b"abd"));
}
}
8 changes: 6 additions & 2 deletions sdk/patina/src/base/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,9 @@ macro_rules! char16 {
($s:literal) => {{
static CHAR16_LITERAL: $crate::string::Char16Array<{ $crate::string::ucs2_capacity($s) }> =
$crate::string::Char16Array::from_str($s);
CHAR16_LITERAL.as_char16_str()
// SAFETY: `ucs2_capacity($s)` is exactly the encoded length plus one for the NUL terminator, so
// the array has no padding and its only NUL is the final element.
unsafe { $crate::string::Char16Str::from_units_with_nul_unchecked(CHAR16_LITERAL.as_array()) }
}};
}

Expand All @@ -238,7 +240,9 @@ macro_rules! char8 {
($s:literal) => {{
static CHAR8_LITERAL: $crate::string::Char8Array<{ $crate::string::latin1_capacity($s) }> =
$crate::string::Char8Array::from_str($s);
CHAR8_LITERAL.as_char8_str()
// SAFETY: `latin1_capacity($s)` is exactly the encoded length plus one for the NUL terminator, so
// the array has no padding and its only NUL is the final element.
unsafe { $crate::string::Char8Str::from_bytes_with_nul_unchecked(CHAR8_LITERAL.as_array()) }
}};
}

Expand Down
1 change: 1 addition & 0 deletions sdk/patina/src/component/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ pub mod dxe_dispatch;
pub mod memory;
pub mod perf_timer;
pub mod performance;
pub mod uefi_services;

pub use patina_macro::IntoService;

Expand Down
53 changes: 53 additions & 0 deletions sdk/patina/src/component/service/uefi_services.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
//! UEFI Services for Patina components.
//!
//! This module defines a set of service traits that expose UEFI Boot Services (and,
//! over time, Runtime Services) to Patina components as Rust APIs.
//!
//! These services are the recommended way for components to consume UEFI functionality.
//! Unlike the raw [`crate::uefi::boot_services`] abstractions, which wrap the C
//! `EFI_BOOT_SERVICES` function-pointer table, these services are implemented by the
//! Patina DXE Core directly against its internal Rust APIs. Components therefore do not
//! interact with C-style constructs such as the boot services table or raw pointers until
//! they go down an unavoidable path into C code, such as calling a protocol function
//! pointer when the protocol is produced by a C driver.
//!
//! # Design
//!
//! Each service group is defined as a trait in this module and implemented by the core.
//! Components declare a dependency on a service by adding a [`Service<dyn Trait>`] parameter
//! to their entry point. The trait is only made available once the core registers its
//! implementation, so a component depending on a service is guaranteed the service is ready.
//! Some services may be deferred until underlying dependencies such as an architectural protocol
//! or other platform-dependent service is available.
//!
//! Services are split into cohesive functional groups so that a component can declare a more
//! granular dependency on the functionality it needs:
//!
//! - [`config_table::ConfigurationTableServices`] - Configuration table installation and lookup.
//! - [`driver::DriverServices`] - Connecting and disconnecting drivers to controllers.
//! - [`event::EventServices`] - Events, using Rust closures for notifications.
//! - [`image::ImageServices`] - Loading, starting, and unloading UEFI images.
//! - [`protocol::ProtocolServices`] - Typed protocol installation and discovery.
//! - [`timer_event::TimerEventServices`] - Timer events, available once the Timer Architectural
//! Protocol is installed.
//! - [`timing::TimingServices`] - Delays and the Watchdog timer.
//! - [`tpl::TplServices`] - Raising and restoring the Task Priority Level (TPL).
//!
//! [`Service<dyn Trait>`]: crate::component::service::Service
//!
//! ## License
//!
//! Copyright (c) Microsoft Corporation.
//!
//! SPDX-License-Identifier: Apache-2.0
//!

pub mod config_table;
pub mod driver;
pub mod event;
pub mod handle;
pub mod image;
pub mod protocol;
pub mod timer_event;
pub mod timing;
pub mod tpl;
Loading