patina-v21.1.0
What's Changed
-
[REBASE \& FF] Use CRLF for Log Messages @os-d (#1520)
Change Details
## Description
Currently Patina only uses LF for log message line endings. In some terminal emulators, the implicit CR is not added and so the logs look stilted, e.g.
INFO - Some Log Message INFO - Oops, no CRThis contains two commits to fix that. One is in the SDK to convert strings printed with log::!() to have CRLF as the line ending. The other is use write!() with CRLF explicitly stated instead of writeln!() as that only does LF.
Note: This matches edk2 behavior and C drivers using DEBUG(()) already get CRLF as their line ending: https://github.com/tianocore/edk2/blob/b03a21a63e3bd001f52c527e5a57feddb53a690b/MdePkg/Library/BasePrintLib/PrintLibInternal.c#L1107-L1136
- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
On a physical ARM64 platform where the terminal emulator does not implicitly add CR.
Integration Instructions
N/A.
-
patina\_test: Gate component doctest on the test-runner feature (MSRV 1.89.0 compat) @makubacki (#1533)
Change Details
## Description
The
componentmodule is only public whenfeature = "test-runner"is enabled (or when rustdoc is generating docs withcfg(doc)).The
Filterdoctest in components/patina_test/src/component.rs imports from it.cargo test --docfails prior to 1.92.0 with: "E0603: modulecomponentis private"The behavior appears to have changed somewhere between the 2025-09-16 (fail) and 2025-12-04 (pass) nightly releases specifically.
It appears the logic to discover what's reachable changed such that rustdoc only extracts doctests from items that are reachable in the same configuration the library is built with.
The current MSRV is 1.89.0, so this change uses
cfg_attrto ignore the test when thetest-runnerfeature is not enabled this allows the doctest to be compiled and run when the feature is enabled and gives compatibility with older toolchains.- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
BEFORE
-
cargo +nightly-2025-09-19 test -p patina_test---- components\patina_test\src\component.rs - component::Filter (line 26) stdout ---- error[E0603]: module `component` is private --> components\patina_test\src\component.rs:28:18 | 5 | use patina_test::component::{TestRunner, Filter}; | ^^^^^^^^^ private module | note: the module `component` is defined here --> C:\src\patina\components\patina_test\src\lib.rs:21:1 | 21 | mod component; | ^^^^^^^^^^^^^ error[E0603]: module `component` is private --> components\patina_test\src\component.rs:28:18 | 5 | use patina_test::component::{TestRunner, Filter}; | ^^^^^^^^^ ------ enum `Filter` is not publicly re-exported | | | private module | note: the module `component` is defined here --> C:\src\patina\components\patina_test\src\lib.rs:21:1 | 21 | mod component; | ^^^^^^^^^^^^^ -
cargo +nightly-2025-12-12 test -p patina_test
all doctests ran in 1.15s; merged doctests compilation took 1.05s
AFTER
Both commands pass.
Integration Instructions
- N/A
-
component: Normalize core::any::type\_name output (1.89.0 MSRV compat) @makubacki (#1531)
Change Details
## Description
Resolves #1530
The strings emitted by
core::any::type_name::<T>()are explicitly best-effort and documented to vary between rustc releases. Per the official documentation:This is intended for diagnostic use. The exact contents and format
of the string returned are not specified, other than being
best-effort description of the type. For example, amongst the
strings that type_name::<Option>() might return are
"Option" and "std::option::Optionstd::string::String".The returned string must not be considered to be a unique
identifier of a type as multiple types may map to the same type
name. Similarly, there is no guarantee that all parts of a type
will appear in the returned string. In addition, the output may
change between versions of the compiler. For example, lifetime
specifiers were omitted in some earlier versions.The current implementation uses the same infrastructure as
compiler diagnostics and debuginfo, but this is not guaranteed.https://doc.rust-lang.org/beta/core/any/fn.type_name.html
The component infrastructure embeds those strings directly in user-visible diagnostics (error messages, panic payloads,
MetaData::name) and a handful of unit tests assert against their exact form. These unit tests currently fail on the MSRV 1.89.0 (which means consumers on 1.89.0) also see different strings.For example, recent/current toolchains render lifetime-parameterized generics as
Config<'_, u32>while older ones render the same type asConfig<u32>, and three tests incomponent::paramsandcomponent::struct_componenthardcode the more recent rendered form.This change introduces a small internal helper,
component::type_name, that wrapscore::any::type_nameand strips anonymous lifetime tokens before returning the string.This stabilizes user-visible diagnostics, which always read
Config<T>regardless of which toolchain compiled the build.- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
- 1.89.0 equivalent:
cargo +nightly-2025-06-23 test -p patina
- Current (1.93.1):
cargo test -p patina
Integration Instructions
- N/A
-
pi\_dispatcher: Add UI Names to Prints @os-d (#1514)
Change Details
## Description
Currently when various states occur, such as drivers not dispatched, only the GUID of the driver is printed. This is useful, but also it is nicer to have the UI name printed so the GUID does not have to be cross-referenced.
This parses the UI name from the FV, if present, and also prints it.
- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
N/A.
Integration Instructions
N/A.
-
patina\_dxe\_core: Drop alloc\_error\_handler feature @os-d (#1525)
Change Details
## Description
The unstable alloc_error_handler feature is no longer required as the default_alloc_error_handler is stabilized. Patina is not doing anything special in this case, just panicking, so drop the unstable feature.
Closes #807
- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
Booting Q35 to shell.
Integration Instructions
N/A.
-
patina\_dxe\_core: Fix test check for new goblin @cfernald (#1527)
Change Details
## Description
The updated goblin added some internal checks for PE consistency that is failing for aarch64 with our test binary. This commit updates the check to allow for either the patina or the goblin failures to be accepted.
- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
Local test execution
Integration Instructions
N/A
-
patina\_dxe\_core: install always-enabled silent logger for tests @makubacki (#1521)
Change Details
## Description
init_test_logger()is used by various modules to set up logging during tests.This was originally setup to use
env_loggerwhenRUST_LOGis set allowing simple control of log messages during interactive test runs and providing partial coverage of log messages in tests with the following description given (#1093):Since Patina relies on the
log::*API for logging, not
configuring a default logger can causelog::*calls to appear
completely uncovered in llvm-cov reports, slightly reducing
overall coverage. Adding a simple environment based logger avoids
this issue.Although this change enables coverage for
log::*,
there are still cases that cannot be covered. For example, in the
function below, there is no way to get coverage for lines 6 and 7.1 1 fn print() { 2 1 let mut i = 0; 3 11 for _ in 0..10 { 4 10 log::info!( 5 10 "This will be covered {} {}", 6 i, 7 "This and the above line will not be covered." 8 ); 9 10 i = i + 1; 10 } 11 1 }This commit adds coverage of the log lines.
init_test_loggerpreviously defaultedenv_loggertoLevelFilter::OffwhenRUST_LOGwas unset. That setsSTATIC_MAX_LEVELtoOffand installs a logger whoseenabled()returns false, so everylog::*!macro short-circuits before it gets to the formatting and dispatch logic. Undercargo-llvm-covthis leaves log call sites flagged as uncovered, even though the surrounding code is exercised by tests.This change switches the unset-
RUST_LOGpath to a tiny customlog::Logimplementation that reports every record as enabled but discards it, combined withset_max_level(Trace).This allows tests to stay silent, but
log_enabled!()now returns true so the formatting branch of eachlog::*!invocation actually runs and gets counted by coverage.The
RUST_LOG-set path is unchanged and still routes throughenv_loggerfor real output during interactive debugging.
This change alone improved existing code coverage by:
- Line Coverage: 85.72% -> 85.95%
- Region Coverage: 84.47% -> 85.33%
Before (Left). After (Right).
- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
cargo make coveragebefore and after
Integration Instructions
- N/A
-
Improve local mdbook testing [Rebase \& FF] @makubacki (#1518)
Change Details
## Description
Changes to simplify testing mdbooks.
Simplify local mdbook testing
Today, trying to run mdbook tests locally is a bit of a pain because:
- The
devprofile is used to build dependencies used by code in the mdbook, and it has LTO enabled. This means that the resulting rlibs don't contain machine code and can't be linked byrustdoc --testwhen running the doctests embedded in the mdbook. This results in link errors. - mdbook defaults to using the stable toolchain ignoring the
rust-toolchain.tomlfile, which means that you have to manually switch to the nightly toolchain before running the tests. - The dependencies have to be built separately (
cargo make build-lib). which are built using the toolchain inrust-toolchain.toml.
This is accounted for in CI with manual steps:
This commit simplifies all of this by introducing a new profile specifically for mdbook that inherits from
devbut disables LTO and adding acargo-maketask to build the dependencies using this profile and runmdbook testusing the toolchain specified inrust-toolchain.toml.Another task was added called
serve-mdbookto make it easier to open the mdbook locally similar todoc-openfor the docs.- Test mdbook code:
cargo make test-mdbook - Serve mdbook locally:
cargo make serve-mdbook
This also has the advantage that mdbook tests are checked during
cargo make allnow.
book.toml: Change playpen to playground
I could not find "playpen" in the mdbook documentation:
https://rust-lang.github.io/mdBook/
As far as I can tell, "playpen" is a deprecated name for "playground".
This changes the name of the section in book.toml to align with current mdbook documentation.
Note: I kept the dedicated job in ci-workflow.yml that calls to patina-devops/MdbookWorkflow.yml since
allis not run in CI and having it in a separate job still seems reasonable even though the job itself has some redundancies now. I'll probably make some changes to MdbookWorkflow.yml in a patina-devops PR to remove complexity now handled by the make task.
- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
cargo make test-mdbookcargo make serve-mdbook
Integration Instructions
- N/A
- The
-
mdbook: Update dependencies @makubacki (#1512)
Change Details
## Description
Updates dependencies to the latest compatible versions. The latest mdbook release is 0.5.2 but the latest mdbook-admonish release 1.20.0 is not compatible with mdbook 0.5.x. So, mdbook is updated to the latest 0.4.x release, which is 0.4.52.
The CSS file for mdbook-admonish is checked into the repo, per the admonish documentation for compatibility and reproducible builds.
The
multilingualkey is removed frombook.tomlsince it will be deprecated in mdbook 0.5.x.- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
- Install mdbook related crates
mdbook build ./docsmdbook serve ./docs
Integration Instructions
- N/A
-
gcd: Move mapping memory range message prior to adding memory space @makubacki (#1509)
Change Details
## Description
Allows the memory range details to be visible if the call to
GCD.add_memory_space()fails.- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
cargo make all- Boot and examine when the message is printed.
Integration Instructions
- N/A
🚀 Features & ✨ Enhancements
-
[x64] Do not issue `cli` if interrupt is not enabled @kuqin12 (#1524)
Change Details
## Description
The module could be used in the user environment, and
cliwill cause #GP.This change will check on the interrupt state and opt out the
cliif it is already disabled.- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
This was tested for building the uart module for ring 3 module and booted to OS desktop properly.
Integration Instructions
N/A
🐛 Bug Fixes
-
[AArch64] Fix unable to unregister handlers @kuqin12 (#1523)
Change Details
## Description
The current handler unregister logic was broken because the null check will never hit. This is because the
extern "efiapi" fnwill not be null pointer and the casting to c_void will just be optimized out.The change moves the hosted handler type to an option to check the validity of the incoming parameters.
- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
This was tested on physical hardware and can unregister handler successfully.
Integration Instructions
N/A
-
Small Set of FFI Safety Improvements [Rebase \& FF] @makubacki (#1515)
Change Details
## Description
Makes a few changes to improve FFI safety noticed while reviewing the r-efi v6.0.0 PR (pre-existing problems that can be fixed in this PR before v6.0.0 integration).
I tried to find places where null checks and unaligned pointer accesses were not used and should be. Some places may have been missed if they didn't match a search pattern used.
Also, I added tests within reason. In particular, there is a large code coverage gap in
components/patina_acpi/src/acpi_protocol.rsandpatina_dxe_core/src/protocols.rswhich I did not address since the lines modified are insignificant relative to the surrounding code already lacking coverage.
Treat C FFI pointers as unaligned consistently
Several UEFI protocol entry points dereference caller-supplied
pointers directly (*ptrorptr.as_mut()). This can be undefined
behavior when the C caller passes an unaligned address.The UEFI ABI does not guarantee that out-parameters or input
structures meet Rust's natural alignment for the pointee type, so
most loads and stores through a raw FFI pointer must go through
read_unaligned()/write_unaligned().While we've followed this pattern in the past, some cases were missed
that are updated in this change.Also adds a Pointer Alignment section to the FFI Authoring doc (ffi.md)
that describes the rationale along with a few examples.
Improve FFI pointer validation in a couple of places
Two FFI entry points dereferenced caller-supplied pointers without
validating them:- patina_dxe_core:
copy_mem()andset_mem()called
core::ptr::copy()/slice::from_raw_parts_mut()on a null
pointer, if the caller passed one, with a non-zero length. - patina_adv_logger:
adv_log_write()constructed a slice from
bufferand a reference fromthiswith no validation.
The boot services functions now
debug_assert!()on null with a
non-zero length to catch caller bugs clearly in debug builds, then
fall through to a safe early return in release. Since the function
does not return a value, this prevents a panic from propagating across
the FFI boundary.adv_log_write()now returnsEFI_INVALID_PARAMETERwhenthisis
null or whenbufferis null. The SAFETY comments are updated to reflect
the new invariants.
cpu_arch_protocol: Prevent panic on null
thispointersCPU Arch Protocol functions call a common helper to convert the raw
thispointer to a reference. Before, the helper panicked on null
pointers. This commit changes the helper to returnNoneon null
pointers, so that the FFI entry points can return
EFI_INVALID_PARAMETERinstead of panicking across the FFI
boundary.
patina_adv_logger: Add unit tests to components.rs
There are currently no unit tests for this module. Though the test
support needed to write tests without much overhead are in place,
such as UartNull.This commit adds some basic tests for
adv_log_writethat verify the
pointer validation logic and calls to write the message when
expectations are valid.
- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
cargo make all- QEMU platform boot to EFI shell
Integration Instructions
- N/A
- patina_dxe_core:
-
patina\_internal\_cpu: Serialize a missed unit test @makubacki (#1516)
Change Details
## Description
Adds the
#[serial]attribute to thetest_uefi_routine()unit test since it modifies the globalEXCEPTION_HANDLERSarray (matching neighboring functions that register exception handlers) and theCALLBACK_INVOKEDglobal (which is only in thetestsmodule), which might be used by other tests in the future.Also sets
CALLBACK_INVOKEDtofalseat the start of the test so that the test can assert that the callback was flipped to true by the test. Sets it back tofalsewhen done for clean exit state. This is currently the only test using it, so it's more for future-proofing than anything else.- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
cargo make all
Integration Instructions
- N/A
📖 Documentation Updates
-
Small Set of FFI Safety Improvements [Rebase \& FF] @makubacki (#1515)
Change Details
## Description
Makes a few changes to improve FFI safety noticed while reviewing the r-efi v6.0.0 PR (pre-existing problems that can be fixed in this PR before v6.0.0 integration).
I tried to find places where null checks and unaligned pointer accesses were not used and should be. Some places may have been missed if they didn't match a search pattern used.
Also, I added tests within reason. In particular, there is a large code coverage gap in
components/patina_acpi/src/acpi_protocol.rsandpatina_dxe_core/src/protocols.rswhich I did not address since the lines modified are insignificant relative to the surrounding code already lacking coverage.
Treat C FFI pointers as unaligned consistently
Several UEFI protocol entry points dereference caller-supplied
pointers directly (*ptrorptr.as_mut()). This can be undefined
behavior when the C caller passes an unaligned address.The UEFI ABI does not guarantee that out-parameters or input
structures meet Rust's natural alignment for the pointee type, so
most loads and stores through a raw FFI pointer must go through
read_unaligned()/write_unaligned().While we've followed this pattern in the past, some cases were missed
that are updated in this change.Also adds a Pointer Alignment section to the FFI Authoring doc (ffi.md)
that describes the rationale along with a few examples.
Improve FFI pointer validation in a couple of places
Two FFI entry points dereferenced caller-supplied pointers without
validating them:- patina_dxe_core:
copy_mem()andset_mem()called
core::ptr::copy()/slice::from_raw_parts_mut()on a null
pointer, if the caller passed one, with a non-zero length. - patina_adv_logger:
adv_log_write()constructed a slice from
bufferand a reference fromthiswith no validation.
The boot services functions now
debug_assert!()on null with a
non-zero length to catch caller bugs clearly in debug builds, then
fall through to a safe early return in release. Since the function
does not return a value, this prevents a panic from propagating across
the FFI boundary.adv_log_write()now returnsEFI_INVALID_PARAMETERwhenthisis
null or whenbufferis null. The SAFETY comments are updated to reflect
the new invariants.
cpu_arch_protocol: Prevent panic on null
thispointersCPU Arch Protocol functions call a common helper to convert the raw
thispointer to a reference. Before, the helper panicked on null
pointers. This commit changes the helper to returnNoneon null
pointers, so that the FFI entry points can return
EFI_INVALID_PARAMETERinstead of panicking across the FFI
boundary.
patina_adv_logger: Add unit tests to components.rs
There are currently no unit tests for this module. Though the test
support needed to write tests without much overhead are in place,
such as UartNull.This commit adds some basic tests for
adv_log_writethat verify the
pointer validation logic and calls to write the message when
expectations are valid.
- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
cargo make all- QEMU platform boot to EFI shell
Integration Instructions
- N/A
- patina_dxe_core:
-
docs: Add FFI docs @os-d (#1511)
Change Details
## Description
This adds a doc for guidance on writing C FFIs.
Note: I wrote this document to have a place to document no VA_LIST across an FFI because there wasn't a good other place I could find. So, I added a small amount of other FFI guidance; if there is another spot folks want this, happy to move it, or if folks have suggestions for what else to add to this section, happy to add.
- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
N/A.
Integration Instructions
N/A.
-
Add Code First Files [Rebase \& FF] @makubacki (#1510)
Change Details
## Description
These are changes to the repo as a follow up to the Code First RFC being merged.
.github: Add Code First issue template
Adds a GitHub issue template that is used to submit code first
tracking issues.The template and how it is used is described in the Patina Code First
RFC:https://github.com/OpenDevicePartnership/patina/blob/HEAD/docs/src/rfc/text/0027-code-first.md
mdbook: Add Code First Process page
Adds a page to give a high-level intro to the Patina Code First
process and link to the RFC.This page is meant to serve as a place in the book to get a quick
understanding of when the process applies and how it used with the
formal definition being maintained in the RFC.Also updates text in code_first/template.md to escape square brackets
so they might not be interpreted as a markdown link.
Example of the Code First GitHub issue form:
- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
cargo make cspellmdbook build ./docs
Integration Instructions
N/A
-
RFC: Code First Process [Approved] @makubacki (#1491)
Change Details
## Description
Status: Approved
Closes #1487
Defines a code first process for Patina. At this time, the focus is on UEFI Forum specifications with the expectation that the process can be adapted for other standards bodies and specifications as needed in the future.
- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
- cspell and markdownlint
Integration Instructions
- N/A
Full Changelog: patina-v21.0.4...v21.1.0