Skip to content

[major] Add Initial Patina UEFI Services [Rebase & FF] - #1743

Open
makubacki wants to merge 44 commits into
OpenDevicePartnership:majorfrom
makubacki:patina_uefi_services_major
Open

[major] Add Initial Patina UEFI Services [Rebase & FF]#1743
makubacki wants to merge 44 commits into
OpenDevicePartnership:majorfrom
makubacki:patina_uefi_services_major

Conversation

@makubacki

Copy link
Copy Markdown
Collaborator

Description

Includes an initial merge commit from the current main branch into major.

Adds a new set of Patina component services called "UEFI Services". These services are defined in the Patina SDK, produced by the Patina DXE Core, and used by Patina components.

Main changes:

  1. Add Patina UEFI Services trait and related definitions - see sdk\patina\src\component\service\uefi_services
  2. Produce Patina UEFI Services in the DXE Core - see patina_dxe_core\src\uefi_services
  3. Add Patina component samples using the services - see
    components\patina_samples\src\component\uefi_services
  4. Migration of existing components (mostly those in /components) to Patina UEFI Services from StandardBootServices.
  5. Various supporting changes for (4)
  6. Introduction of a new type called ServiceCell<T> for uses cases where Service<T>::new_unit() is used today + an additional case. Slightly controversial. Considered an incremental improvement in clarity and safety. See the commit message for reasoning.
  7. Removal of StandardBootServices and related changes to do so across the codebase
  8. Refactoring of several components to break apart monolithic implementations, reduce bloat, and make entry points cleaner, with a cleaner set of dependencies for given responsibilities.
  9. Documentation updates for various refactoring in components.
  10. Documentation for Patina service access and storage patterns. Useful even before this change, more useful now. See docs\src\component\storing_state.md.
  11. Documentation for when to use Patina UEFI Services - see docs\src\component\storing_state.md.
  • Impacts functionality?
  • Impacts security?
  • Breaking change?
  • Includes tests?
  • Includes documentation?

How This Was Tested

  • cargo make all
  • QEMU ArmVirt & Q35 boot to EFI shell with Patina samples included
    • Initial component dispatch (DXE core and sample components):

      INFO - Dispatching Drivers
      INFO - Dispatching patina_dxe_core::cpu::cpu_arch_protocol::CpuArchProtocolInstaller
      INFO - InstallProtocolInterface: 26BACCB1-6F42-11D4-BCE7-0080C73C8881 @ 0x000000007a1ff800
      INFO - installed EFI_CPU_ARCH_PROTOCOL_GUID
      INFO - Dispatching patina_dxe_core::systemtables::SystemTableChecksumInstaller
      INFO - Dispatching patina_dxe_core::decompress::DecompressProtocolInstaller
      INFO - InstallProtocolInterface: D8117CFE-94A6-11D4-9A3A-0090273FC14D @ 0x000000007a977700
      INFO - Dispatching patina_adv_logger::component::AdvancedLoggerComponent<patina::peripheral::serial::uart::uart_16550::Uart16550>
      INFO - InstallProtocolInterface: 434F695C-EF26-4A12-9EBA-DDEF0097497C @ 0x000000007a200220
      INFO - Advanced Logger protocol installed.
      INFO - Dispatching patina_samples::component::uefi_services::configuration_table::ConfigurationTableSample
      INFO - Installed SampleVendorTable v1
      INFO - Read back signature "PTNA", 0 entries
      INFO - Dispatching patina_samples::component::uefi_services::driver_connect::DriverConnectSample
      INFO - Dispatching patina_samples::component::uefi_services::protocol_publisher::ProtocolPublisherSample
      INFO - InstallProtocolInterface: A1B2C3D4-E5F6-4789-ABCD-EF0123456789 @ 0x000000007ad727c8
      INFO - published SampleVendorProtocol on handle Handle(0x688cdc10f3d4e4b5)
      INFO - Dispatching patina_samples::component::uefi_services::protocol_publisher::ProtocolConsumerSample
      INFO - SampleVendorProtocol rev 0x10000 returned status 0x12345678
      INFO - Dispatching patina_samples::component::uefi_services::protocol_consumer::ProtocolConsumerSample
      INFO - with_protocol() read status is 0x12345678
      INFO - open_protocol() revision is 0x10000
      INFO - open_protocol() status is 0x12345678
      INFO - Protocol token resolved, status is 0x12345678
      INFO - SampleVendorProtocol notification: Protocol is installed on Handle(0x688cdc10f3d4e4b5)
      INFO - Dispatching patina_samples::component::uefi_services::tpl_critical_section::TplCriticalSectionSample
      INFO - Counters were kept consistent under raised TPL
      INFO - Dispatching patina_samples::component::uefi_services::end_of_dxe_protocol_consumer::EndOfDxeProtocolConsumerSample
      INFO - Registered End-of-DXE callback for SampleVendorProtocol
      INFO - Dispatching qemu_resources::q35::component::service::mm_config_provider::MmConfigurationProvider
      INFO - ACPI I/O Port Address: 0xB00F8040
      INFO - ACPI (PMBASE) I/O Port: 0x600
      INFO - Found 1 MM Communicate Region HOBs
      INFO - Dispatching qemu_resources::q35::component::service::mm_control::QemuQ35PlatformMmControl
      INFO - Dispatching patina_mm::component::sw_mmi_manager::SwMmiManager
      INFO - Dispatching patina_mm::component::communicator::MmCommunicator
      INFO - Dispatching qemu_resources::q35::component::service::mm_test::QemuQ35MmTest
      INFO - MM Supervisor Version: 0x0, Patch Level: 0x0, Max Request Level: 0x3533715F756D6571
      INFO - Dispatching patina_performance::component::protocol::MeasurementProtocolPublisher
      INFO - InstallProtocolInterface: C85D06BE-5F75-48CE-A80F-1236BA3B87B1 @ 0x000000007ad715e8
      INFO - Dispatching patina_performance::component::property::PropertyPublisher
      INFO - Dispatching patina_performance::component::fbpt::FbptPublisher
      INFO - Dispatching patina_performance::component::mm_records::MmRecordCollector
      INFO - Dispatching patina_smbios::component::provider::SmbiosProvider
      INFO - Dispatching patina_smbios::component::protocol_publisher::SmbiosProtocolPublisher
      INFO - InstallProtocolInterface: 03583FF6-CB36-4940-947E-B9B39F4AFAF7 @ 0x000000007a973800
      INFO - Dispatching qemu_resources::q35::component::service::smbios_platform::Q35SmbiosPlatform
      INFO - Dispatching patina_acpi::component::AcpiComponent
      INFO - InstallProtocolInterface: FFE06BDD-6107-46A6-7BB2-5A9C7EC5275C @ 0x000000007ad35028
      INFO - InstallProtocolInterface: 7F3C1A92-8B4E-4D2F-A6C9-3E12F4B8D7C1 @ 0x000000007ad35010
      INFO - Depex evaluation complete, scheduled 2 drivers
      
    • Later after the Timer Architectural protocol is installed:

      INFO - Dispatching patina_samples::component::uefi_services::overview::UefiServicesSample
      INFO - Sample crc32 = 0x7c22221c
      INFO - Dispatching patina_samples::component::uefi_services::timers::TimerSample
      INFO - Armed one-shot (50 ms) and periodic (10 ms) timers
      INFO - Logged from the periodic timer event
      INFO - Logged from the one-shot timer event
      INFO - Logged from the periodic timer event
      INFO - Logged from the periodic timer event
      INFO - Logged from the periodic timer event
      INFO - Logged from the periodic timer event
      INFO - Logged from the periodic timer event
      
    • End of DXE messages:

      INFO - End of DXE: sample_get_status returned 0x12345678
      INFO - Logged from the periodic timer event
      All EndOfDxe callbacks have returned successfully
      
    • All Patina on-system tests pass:

      INFO - adv_logger_test: Direct log message!!!
      adv_logger_test: Logged through the protocol!!!
      INFO - Patina on-system unit-test results:
        patina_acpi::integration_test::acpi_protocol_test ... ok (1 passes)
        patina_acpi::integration_test::acpi_test ... ok (1 passes)
        patina_adv_logger::integration_test::adv_logger_test ... ok (1 passes)
        patina_dxe_core::core_patina_tests::audit_tests::gcd_free_memory_merged_test ... ok (1 passes)
        patina_dxe_core::core_patina_tests::stability_tests::page_table_tests_1gb_split ... ok (4 passes)
        patina_dxe_core::core_patina_tests::stability_tests::page_table_tests_1gb_unmap_2mb_remap ... ok (4 passes)
        patina_dxe_core::core_patina_tests::stability_tests::page_table_tests_1gb_unmap_4kb_remap ... ok (4 passes)
        patina_dxe_core::core_patina_tests::stability_tests::page_table_tests_2mb_split ... ok (4 passes)
        patina_dxe_core::core_patina_tests::stability_tests::page_table_tests_2mb_unmap ... ok (4 passes)
        patina_dxe_core::memory_manager::memory_manager_allocations_test ... ok (1 passes)
        patina_dxe_core::memory_manager::memory_manager_attributes_test ... ok (1 passes)
        qemu_resources::q35::component::service::smbios_test::q35_smbios_ffi_test ... ok (1 passes)
      Patina on-system unit-test result totals: 27 passes, 0 fails
      

Integration Instructions

  • See individual crate documentation samples. In addition, a patina-dxe-core-qemu PR will demonstrate the changes needed to integrate and use the new components.

@makubacki makubacki self-assigned this Aug 13, 2026
@github-actions github-actions Bot added impact:breaking-change Requires integration attention impact:testing Affects testing type:documentation Improvements or additions to documentation labels Aug 13, 2026
@makubacki

Copy link
Copy Markdown
Collaborator Author

I'm working on some changes to improve unit test coverage.

@patina-automation

patina-automation Bot commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

ℹ️ QEMU Validation Skipped - Unsupported Target Branch

The Patina QEMU PR validation workflow did not run because the PR targets an unsupported branch.

Workflow run: https://github.com/OpenDevicePartnership/patina/actions/runs/33698059661

Note: Previous results are available in this comment's edit history.

This comment was automatically generated by the Patina QEMU PR Validation Post workflow.

@makubacki
makubacki force-pushed the patina_uefi_services_major branch from f63f1af to 3e810b7 Compare August 14, 2026 20:08
@makubacki

Copy link
Copy Markdown
Collaborator Author

I'm working on some changes to improve unit test coverage.

Pushed. Also updated the major branch to include the clippy pedantic changes in main (merged at a1f6643) and rebased changes against those new lints.

@cfernald cfernald left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

just reviewed the SDK interface for now. Will review the full changes later.

Comment thread sdk/patina/src/component/service/uefi_services/timing.rs
Comment thread sdk/patina/src/component/service/uefi_services/timing.rs
Comment thread sdk/patina/src/component/service/uefi_services/timer_event.rs
Comment thread sdk/patina/src/component/service/uefi_services/protocol.rs
Comment thread sdk/patina/src/component/service/uefi_services/protocol.rs
Comment thread sdk/patina/src/component/service/uefi_services/protocol.rs
Comment thread sdk/patina/src/component/service/uefi_services/misc.rs Outdated
Comment thread sdk/patina/src/component/service/uefi_services/image.rs
Comment thread sdk/patina/src/component/service/uefi_services/config_table.rs Outdated
Comment thread sdk/patina/src/component/service/uefi_services/config_table.rs Outdated
Comment thread sdk/patina/src/component/service.rs Outdated
Comment thread sdk/patina/src/component/service/cell.rs Outdated
Comment thread sdk/patina/src/component/service/cell.rs

@kat-perez kat-perez left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I found several safety and contract issues in the new service layer that should be addressed before merge. The inline comments focus on callback lifetime, protocol reference lifetime, marker protocol compatibility, and duration conversion.

@kat-perez
kat-perez dismissed their stale review August 19, 2026 20:52

Withdrawn by reviewer for additional cross-checking before feedback is submitted.

Comment thread components/patina_smbios/src/manager.rs Outdated
@makubacki
makubacki force-pushed the patina_uefi_services_major branch 3 times, most recently from b9d0dbd to 75530e3 Compare August 20, 2026 20:19
@makubacki

Copy link
Copy Markdown
Collaborator Author

@Javagedes, @cfernald, @kat-perez, this is ready for you review again when you get time.

Splits MM performance record collection out of the monolithic
Performance component.

`mm_comm_service` is now a required `Service<dyn MmCommunication>`
rather than `Option<Service<...>>`, so the dispatcher itself skips
this component on platforms with no MM communication region instead
of branching on an `Option<Service<...>>` at runtime.

Also adds a `core::error::Error` `impl` for `MmPerformanceError`
while it is already being moved.

Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
The monolithic Performance component has now been split into separate
single-purpose components, each with its own responsibilities, so it
can be removed.

Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
Updates docs in the mdbook and the patina_performance component crate
to reflect the recent split of the monolithic patina_performance
component into separate components.

Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
Adds an `impl` of `TplController` for `Service<dyn TplServices>`
along with a small helper that converts a raw TPL level to the newer
`Tpl` enum. This lets any `TplMutex` use the trait object TPL service
instead of requiring a concrete `BootServices` implementation.

Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
Adds `SmbiosError::Busy` so lock contention can be reported as a
normal error. It maps to `EfiError::DeviceError`.

Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
…methods

Adds a couple of methods to the `Smbios` trait so the C protocol shim
will be able to look up the next record after a handle and the address
of a published record without touching the `SmbiosManager` or its
`TplMutex` directly.

Both return owned data instead of a borrowing iterator, since the
existing `SmbiosRecordsIter` cannot outlive a lock guard.

Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
`SmbiosImpl` no longer takes a generic `BootServices` parameter. Its
`TplMutex` now uses `Service<dyn TplServices>`. Every lock acquisition
goes through `try_lock`, returning `SmbiosError::Busy` on contention
instead of panicking. `SmbiosImpl` stores a
`Service<dyn ConfigurationTableServices>` and uses it to install the
SMBIOS configuration table entry.

`SmbiosProtocolInternal` now holds only the protocol struct and a
`Service<dyn Smbios>`, dropping the raw `TplMutex` reference.

The extern functions call through the service trait instead of locking
the manager directly, and the protocol is installed through
`ProtocolServices` instead of a raw unsafe boot services call.

component.rs is updated minimally to keep the crate compiling, still
fetching the newly needed services through `storage.get_service` in
the same style it already used. It will be split into two components
with typed parameters in a future change.

Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
…Publisher

Moves `SmbiosProvider` into component/provider.rs and migrates its
entry point to use typed service parameters for memory, configuration
table, and TPL services, plus `Commands` for registration, dropping
the `storage.get_service` and `storage.boot_services` calls this
replaces. Buffer allocation now uses `leak_as_slice` instead of
`into_raw_slice`.

Adds a new `SmbiosProtocolPublisher` component that installs the
protocol for C drivers depending only on `Service<dyn Smbios>` and
`Service<dyn ProtocolServices>`. This is the piece the earlier
`Smbios` trait extension made it possible to split out on its own.

Adds a new entry point test for each component, now that every
dependency is mockable.

Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
Updates the crate README and the patina_samples SMBIOS example to
register both `SmbiosProvider` and `SmbiosProtocolPublisher`, matching
the new split.

Updates the "Global State Justification" section, which described a
global manager that the crate no longer has. The C protocol shim now
reaches the `Smbios` service through a field on the leaked protocol
struct instead of any global state.

Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
Replaces boot services calls to `StandardBootServices` with calls to
the Patina UEFI Services.

Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
Updates the entry point to depend on `ProtocolServices`. Replaces raw
pointer handling with safe code using `on_protocol_installed()`.

Implements the `ProtocolInterface` trait for `MmCommBufferUpdateProtocol`
to allow safe access to the protocol's fields without unsafe pointer
casts.

Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
…ocking

Add a `mockall` and a `mockall-featured` patina dev-dependency to
`patina_test` so its tests can mock the sdk/patina `uefi_services`
traits (`EventServices`, `TimerEventServices`) instead of using a
raw `EFI_BOOT_SERVICES` table.

Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
Replaces every raw `StandardBootServices` call in the `TestRunner`
component with UEFI Services:

- `TestRecord::schedule_run` now takes `Service<dyn EventServices>`
  and `Service<dyn TimerEventServices>` instead of using `Storage` to
  get `StandardBootServices`. Event-triggered tests register through
  `EventServicesExt::on_event_group`. Timer-triggered tests register
  through `TimerEventServicesExt::on_timer_event` and
  `TimerEventServices::set_timer`. `Recorder::initialize` report
  callbacks are registered the same way.
- The extern "efiapi" `run_test`/`run_tests_and_report`/`disable_timer`
  callbacks and manual `Box::leak`'d context handling can be replaced
  with new `EventServicesExt`/`TimerEventServicesExt` closures that
  capture what they need directly and are boxed internally.

Note: `Service<dyn TimerEventServices>` is an interface, not necessarily
tied to any particular producer. patina_dxe_core's own implementation
happens to defer registration until the Timer Architectural Protocol
is installed, but that's not required by the trait. A different producer
could produce `Service<dyn TimerEventServices>` without a dependency
on the Timer Architectural Protocol in the future to reduce or eliminate
the dispatch delay this dependency implies for
`TestRunner::entry_point` today.

Tests that were previously ignored and removed in cb064c3 due to the
lack of UEFI service mocking have been re-enabled given the addition
of `MockEventServices` and `MockTimerEventServices`

Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
Improve the code coverage in this module by adding tests that cover
variants that are not currently covered.

Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
`StandardAcpiProvider` is about to stop depending on `BootServices`
entirely when it transitions to UEFI Services.

This renames the `BootServicesAlreadyInitialized` error variant to
`ConfigTableServicesAlreadyInitialized` so the next commit can focus
on behavioral changes.

Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
Updates the ACPI component to use the new UEFI Services instead of
`StandardBootServices`. Overall changes are relatively minimal to
focus on the transition itself and keeping in mind that more ACPI
component refactoring is expected in the future.

`StandardAcpiProvider` no longer needs to be generic over
`BootServices`.

Testing is simplified overall using `MockTplServices` and
`MockConfigurationTableServices` instead of `MockBootServices`.

Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
Updates `acpi_protocol_test` to use `ProtocolServices` instead of
`StandardBootServices` to locate the ACPI Table and ACPI Get protocols.

This allows two unsafe code blocks at the call sites to be removed.

This was the last `StandardBootServices` usage in the crate, so
`patina_acpi` no longer depends on it at all.

Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
`CpuArchProtocolInstaller`, `HwInterruptProtocolInstaller`,
`SystemTableChecksumInstaller`, and `DecompressProtocolInstaller`
were the last components in patina_dxe_core still depending on
`StandardBootServices` directly.

This change moves them onto `Service<dyn ProtocolServices>` so
`StandardBootServices` can be removed from the component model
in a follow up change.

Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
Now that no component in patina_dxe_core depends on `StandardBootServices`
directly, this drops `ComponentDispatcher::set_boot_services` and the code
in `Core::initialize_system_table` that constructed a `StandardBootServices`
for the component dispatcher. `StandardRuntimeServices` not modified.

Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
Removes the `StandardBootServices` param from the component benchmark
entrry points since `StandardBootServices` is about to be removed
from the component model.

Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
Removes the `StandardBootServices` `Param` implementation and all
references to it. Removes the `boot_services` field from `Storage`.

Removes logic in the `#[component]` parameter validation macro that
checked for duplicate `StandardBootServices` parameters.

In cases where `StandardBootServices` was used as an example type in
tests for `Option<T>` and tuple `Param` implementations, it was
replaced with `StandardRuntimeServices`.

Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
Provides a `locate_first_handle()` method to more conveniently find
a single handle that supports a given protocol.

Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
Adds a `DriverBinding` trait  that can be implemented and passed to
`install_driver_binding()` to produce a driver binding protocol in a
component.

Since components are all statically compiled with the DXE Core, they
cannot use image handles as agent handles as is common in C-based DXE
drivers. Therefore, a `register_agent()` function is added to
`ProtocolServices` that generates a unique agent handle for a component
to use when opening protocols. An example of using this API and opening
a protocol is added to `patina_samples`.

The `open_protocol()` interface is updated to accept an agent handle
and `OpenAttributes` that describe how the protocol is being opened.

Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
Straightforward update to docs that referenced `StandardBootServices`
to either drop the reference or replace it with the equivalent info
or example from UEFI Services.

Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
Adds a document that explains common scenario where services need
be shared and stored and patterns for those scenarios.

Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
Adds a document that explains when to use Patina UEFI Services and
links to individual service documentation.

Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
@makubacki
makubacki force-pushed the patina_uefi_services_major branch from 75530e3 to 1fed1b9 Compare September 2, 2026 23:53
@makubacki

Copy link
Copy Markdown
Collaborator Author

I've decided to spend a bit more time improving open protocol and driver binding since that might impact some other interfaces and there's no point having those in an intermediate state. Will push that update within a few days.

Merged main into the major branch (at commit 35f9055) and rebased the PR onto it. The main set of changes added are in commit 59cc862.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

impact:breaking-change Requires integration attention impact:testing Affects testing type:documentation Improvements or additions to documentation

Projects

None yet

4 participants