Skip to content

Add patina_sre crate (System Recovery Environment boot orchestrator)#97

Open
kat-perez wants to merge 4 commits into
OpenDevicePartnership:mainfrom
kat-perez:feature/patina-sre-crate
Open

Add patina_sre crate (System Recovery Environment boot orchestrator)#97
kat-perez wants to merge 4 commits into
OpenDevicePartnership:mainfrom
kat-perez:feature/patina-sre-crate

Conversation

@kat-perez

@kat-perez kat-perez commented May 27, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds patina_sre at uefi/crates/patina_sre/ — a patina_boot::BootOrchestrator for platforms shipping a System Recovery Environment alongside the main OS.

SreBootManager runs the full BDS phase: interleave connect+dispatch → EndOfDxe → gMsStartOfBdsNotifyGuid → console discovery → discover_boot_options → try each Boot####, fall back to the constructor-provided main_os_path on empty/failed discovery. On Vol-Up + Power it dispatches a configured SRE app FwFile path (or falls back to the in-Rust bp_recovery::run_sre_flow: NVMe LID 0x15 read of BP1 → RAM disk → chainload \EFI\Boot\bootx64.efi). On Vol-Down + Power it tries USB-first via live SimpleFileSystem handle enumeration, then a configured fallback app.

Builder surface (additive — base constructor unchanged):

  • with_sre_app_path(DevicePathBuf) — wire Vol-Up to a platform-specific recovery app
  • with_frontpage_app_path(DevicePathBuf) — wire Vol-Down + no-USB to a fallback settings/menu app
  • fv_file_device_path / fv_volume_file_device_path helpers for caller-side path construction

gDfciStartOfBdsNotifyGuid is intentionally not signaled — triggers a DfciManager null-deref under Patina dispatch order (the static apply-protocol pointers stay NULL because IdentityAndAuthManager hasn't installed them by callback time). Re-enable after the DFCI driver chain (Project MU DfciPkg) is ported to Patina components.

Hotkey detection uses MS_BUTTON_SERVICES_PROTOCOL (a publicly-known vendor convention). Platforms without a button-services producer cleanly return SreHotkey::None and fall through to normal Boot#### discovery.

Re-exports DevicePathBuf + EndEntire + SreHotkey + device-path helpers from the crate's own patina source so callers construct constructor arguments without picking up a different patina (trait-coherence safety).

Verification

End-to-end on a real platform (Intel host, NVMe SSD with CAP.BPS=1, MS_BUTTON_SERVICES-publishing EC) via a paired downstream consumer:

  • BootDispatcher dispatches; SreBootManager::execute() runs the full BDS phase
  • Normal: discover_boot_options → Windows Boot Manager → bootmgfw.efiWindows boots
  • Vol-Up + Power → configured sre_app_path dispatches the SRE recovery app → BP1 payload load → WinVOS boots
  • Vol-Down + USB → SFS enumeration finds the stick → LoadImage auto-resolves \EFI\Boot\BOOTX64.EFI → boots from USB
  • DfciManager null-deref no longer reproducible (DFCI signal off)

cargo test: 17/17 passing in bp_recovery, 6/6 in sre_boot_manager.

Test plan

  • Unit tests pass on host (cargo test)
  • Compiles for x86_64-unknown-uefi
  • End-to-end Windows boot on real hardware
  • Vol-Up + Power → SRE entry verified end-to-end
  • Vol-Down + USB → live SFS enumeration verified
  • CI on this branch (will run on PR creation)

Follow-ups

  • Add partition write-lock helper to patina-boot #61 patina_boot::partition::lock_partition_write so the write-lock stub becomes a real call
  • Wire static boot-partition + main-OS device paths via PeiPatinaConfigLib HOB #96 PCD/HOB-driven static device-path wiring (so main_os_path doesn't rely on discovery fallback)
  • Port the MU DFCI driver chain (DfciManager, IdentityAndAuthManager, SettingsManager) to Patina components so gDfciStartOfBdsNotifyGuid can be re-enabled without null-derefs, unblocking DFCI-dependent settings UIs
  • Dynamic FV-name resolution via LoadedImage(image_handle).DeviceHandle so callers don't have to hardcode a platform-specific DXE FV GUID
  • Extract HotkeyProvider trait so OEM platforms using a different button-detection mechanism can plug in without modifying patina_sre

Closes #91.

Copilot AI 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.

Pull request overview

Adds a new patina_sre crate that implements patina_boot::BootOrchestrator to drive the normal boot path on platforms that ship a System Recovery Environment. The crate covers controller-connect/dispatch interleaving, EndOfDxe + ReadyToBoot signalling, console discovery, Boot#### enumeration with a main_os_path fallback, and a stub for the boot-partition write-lock pending issue #61. Re-exports DevicePathBuf/EndEntire ensure callers share trait coherence with the patina source used internally.

Changes:

  • Introduce SreBootManager orchestrator with interleaved connect+dispatch, BDS signalling, Boot#### iteration, and main_os_path fallback.
  • Re-export DevicePathBuf/EndEntire from patina_sre so downstream consumers stay on the same patina source.
  • Add crate scaffolding (Cargo.toml, README, rust-toolchain.toml, rustfmt.toml, .gitignore) and host-side unit tests for the interleave loop and trait bounds.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated no comments.

Show a summary per file
File Description
uefi/crates/patina_sre/src/sre_boot_manager.rs Core orchestrator implementation + unit tests for interleave loop and trait conformance.
uefi/crates/patina_sre/src/lib.rs Crate root with no_std/feature flags and re-exports.
uefi/crates/patina_sre/README.md Crate description and usage snippet.
uefi/crates/patina_sre/Cargo.toml Package manifest with git deps for patina/patina_boot.
uefi/crates/patina_sre/rust-toolchain.toml Pinned nightly-2025-12-12 with UEFI targets.
uefi/crates/patina_sre/rustfmt.toml max_width = 120.
uefi/crates/patina_sre/.gitignore Ignore target/ and Cargo.lock.

rogurr
rogurr previously approved these changes Jun 5, 2026
Adds patina_sre at uefi/crates/patina_sre/ — implements
patina_boot::BootOrchestrator for platforms shipping a System Recovery
Environment alongside the main OS. The skeleton implements the normal
boot path:

  1. interleave connect+dispatch (10-round cap)
  2. extra connect_all before EndOfDxe so PartitionDxe can bind GPT
     child handles during the open driver-binding window
  3. signal EndOfDxe
  4. discover console devices
  5. boot-partition write-lock (currently a log::warn! stub pending
     odp-platform-common#61's patina_boot::partition helper)
  6. discover_boot_options + iterate each Boot#### entry through
     signal_ready_to_boot + boot_from_device_path; logs the device path
     and underlying error on each failure
  7. fall back to the constructor-provided main_os_path if discovery
     yields no entries OR fails
  8. return EfiError::NotFound once every attempt is exhausted

The crate re-exports DevicePathBuf + EndEntire from its own patina
source so callers (e.g. surface_patina_intel/patina_bin) can construct
the constructor's device-path arguments without picking up a different
patina (which would break trait coherence).

Hotkey-to-SRE entry, WIM-to-RAM-disk boot, and capsule pre-boot hook
are tracked separately and will layer onto this skeleton.

Verified end-to-end on Maa Intel Surface hardware (Kioxia KBG8 NVMe,
NVMe 2.0, CAP.BPS=1) via the paired surface_patina_intel feature
branch: BootDispatcher dispatches, SreBootManager.execute() runs the
full BDS phase, discover_boot_options finds the Windows Boot Manager
Boot####, expand_device_path resolves the short-form HD(GPT,GUID) path
against the live device topology, and bootmgfw.efi loads + starts
cleanly.

Closes OpenDevicePartnership#91.
… -> RAM disk -> chainload)

Layers the SRE entry path onto the existing normal-boot skeleton. When the
Vol-Up + Power chord is registered at power-on (read via Surface
MS_BUTTON_SERVICES_PROTOCOL), SreBootManager::execute branches into the
BP recovery flow:

  1. ConnectAll (priority-boot dispatch may run before BdsConnectAll)
  2. Locate EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL
  3. Probe Identify Controller MDTS to size LID 0x15 chunks; clamp to
     [64 KiB, 512 KiB]; fall back to 64 KiB on probe failure
  4. Read 1 GiB of BP1 via chunked Get Log Page LID=0x15 into a fresh
     DRAM allocation (LPOL = 16 + bp_offset to skip the controller's
     header preamble)
  5. Register the allocation as a RAM disk via EFI_RAM_DISK_PROTOCOL
     (VIRTUAL_DISK_GUID)
  6. Connect the RAM disk handle so PartitionDxe/FAT bind
  7. Build a full device path = RAM disk DP + FilePath(\EFI\Boot\bootx64.efi)
     + END, LoadImage + StartImage

On any failure the flow returns and execute falls through to the
existing normal boot path. BP write protection (lock/unlock) is
intentionally not touched; that's owned by the FMP capsule update flow.

The three protocol FFI shims (NvmExpressPassThru, RamDisk,
MsButtonServices) are inlined in bp_recovery.rs rather than pulled
from patina_boot helpers that aren't yet published (issues OpenDevicePartnership#63
HotkeySource trait, OpenDevicePartnership#65 RAM-disk binding, OpenDevicePartnership#66 partition file-read,
OpenDevicePartnership#67 install_ram_disk). The intent is to extract these into
patina_boot once the API shape is proven on hardware.

Tests: existing 6 unit tests still pass; both x86_64-unknown-uefi
and host builds compile clean.

Mirrors the hardware-validated C-side SRE flow shipped via Devices
PR 392564 (commit 48a7a6159c on platform/maa_900/sre).
… testability

- 2 pure-function tests for build_file_path_node (byte layout) and
  device_path_size (END_ENTIRE walk).
- 3 tests for detect_sre_hotkey covering protocol-absent (outer) and
  pressed / not-pressed / check-errors (inner via synthetic button protocol).
- 4 tests for probe_max_transfer covering MDTS=7 -> 512 KiB cap,
  MDTS=0 -> READ_CHUNK_MAX, MDTS too low -> READ_CHUNK_MIN clamp,
  Identify failure -> READ_CHUNK_DEFAULT.
- 2 tests for read_bp_via_log_page: single-chunk LPOL=header-offset
  + LSP/LID layout, and pass-thru failure propagation.
- 3 tests for register_ram_disk: outer locate failure, inner success
  (base/size captured + sentinel DP returned), inner register failure.

To make the protocol-touching functions testable, split detect_sre_hotkey
and register_ram_disk into outer (BootServices-based locate) + inner
(takes raw protocol pointer) functions. Mirrors the pattern already
used in patina_boot::partition for the lock_partition_write helpers.

All 23 tests pass; both x86_64-unknown-uefi and host targets compile.
Port of Surface's C-side SRE entry behavior (DeviceBootManagerLib.c
SrePriorityBoot) onto the Patina-native BootOrchestrator. Lets a
Patina-BDS-equipped platform reproduce the Vol-Up -> SRE app and
Vol-Down -> USB-first / FrontPage hotkey semantics that C BdsDxe
provided.

What lands:

- MS_BUTTON_SERVICES_PROTOCOL FFI module + probe_sre_hotkey helper.
  Locates the Surface vendor button-services protocol at BDS entry
  and reads the SAM-latched Vol-Up + Power / Vol-Down + Power
  states. Falls back to SreHotkey::None when the protocol isn't
  published, preserving "no Surface buttons" platform behavior.

- SreHotkey { None, VolumeUp, VolumeDown } public enum.

- SreBootManager builder additions:
    - with_sre_app_path(DevicePathBuf)
    - with_frontpage_app_path(DevicePathBuf)
  Both optional; constructor surface stays additive per the
  existing crate contract.

- Vol-Up dispatch: when sre_app_path is set, signal ReadyToBoot
  then boot_from_device_path on the configured path. Falls through
  to normal Boot#### discovery on failure.

- Vol-Down dispatch: SimpleFileSystem-based USB enumeration in
  find_first_usb_block_io_device_path (name kept for legibility;
  semantics are "first SFS handle whose device path contains a
  USB messaging node"). Falls through to frontpage_app_path when
  no USB is present. SFS is required, not raw BlockIo: LoadImage
  auto-resolves \EFI\Boot\BOOTX64.EFI only when the device path
  terminates at a mounted FAT volume, and picking a whole-device
  BlockIo handle gives a path ending at the USB messaging node
  which LoadImage rejects with NotFound.

- Device-path helpers:
    - fv_file_device_path(file_guid) -> FvFile(...)/End
    - fv_volume_file_device_path(fv_guid, file_guid) ->
      Fv(...)/FvFile(...)/End
  Patina's LoadImage requires the explicit FV node to expand an
  FvFile reference -- bare FvFile returns NotFound. Hardware
  verification on Maa confirmed this.

- gMsStartOfBdsNotifyGuid signal added in execute() after
  signal_bds_phase_entry. Surface boot-policy components subscribe
  to it; matches C BdsDxe's DeviceBootManagerBdsEntry order.

- gDfciStartOfBdsNotifyGuid intentionally NOT signaled (see long
  comment in execute()). When fired, SettingsManagerDxe installs
  gDfciSettingAccessProtocolGuid which triggers DfciManager's
  SettingAccessCallback -> ProcessMailBoxes, which null-derefs
  because mApplyIdentityProtocol / mApplyPermissionsProtocol /
  mApplySettingsProtocol stayed NULL at DfciManager entry (the
  producer IdentityAndAuthManager hadn't installed them yet).
  Replicating the C BdsDxe ordering from a Patina BootOrchestrator
  without porting DfciManager + IdentityAndAuthManager +
  SettingsManager to Patina components is brittle. Until those
  are ported the signal stays off; DFCI-dependent UI
  (SurfaceFrontPage) won't function on Patina builds. Tracked as
  a follow-up.

End-to-end verified on a Maa 900 unit:
- Vol-Up + Power -> SRE app (BpRecoveryLoaderApp) launches.
- Vol-Down + USB -> SFS enumeration finds the stick and LoadImage
  hands off to \EFI\Boot\BOOTX64.EFI (when BOOT_ON_FLASH_UPDATE
  PEI state doesn't disable USB ports first - unrelated PEI issue).
- Plain power-on -> normal Boot#### dispatch, no regression.
- DfciManager null-deref no longer reproducible (signal removed).
@kat-perez kat-perez force-pushed the feature/patina-sre-crate branch from c9ba21f to f7c00ba Compare June 16, 2026 23:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants