Skip to content

[feature/patina-boot] patina_boot: Add NVMe boot-partition write-lock helper#1488

Closed
kat-perez wants to merge 9 commits into
OpenDevicePartnership:feature/patina-bootfrom
kat-perez:kat-perez/issue-61-partition-write-lock
Closed

[feature/patina-boot] patina_boot: Add NVMe boot-partition write-lock helper#1488
kat-perez wants to merge 9 commits into
OpenDevicePartnership:feature/patina-bootfrom
kat-perez:kat-perez/issue-61-partition-write-lock

Conversation

@kat-perez
Copy link
Copy Markdown
Contributor

@kat-perez kat-perez commented Apr 30, 2026

Description

Adds lock_partition_write(boot_services, device_path) to a new patina_boot::partition module. Looks up the NVMe Pass-Thru protocol on the device path and sets the Boot Partition Write Protection feature to "Write Protect Until Power Cycle" on both boot partitions. Lock clears on controller reset or power cycle.

Partition-I/O helpers live in their own module (partition.rs) rather than the existing helpers.rs so that file doesn't accumulate disparate concerns.

Closes OpenDevicePartnership/odp-platform-common#61.

  • Impacts functionality?
  • Impacts security?
  • Breaking change?
  • Includes tests?
  • Includes documentation?

How This Was Tested

  • cargo make all

Integration Instructions

  • N/A

…DevicePartnership#1225)

Adds BootOrchestration component, simple console discovery, simple
BootOption Config

- [x] Impacts functionality?
- [ ] Impacts security?
- [ ] Breaking change?
- [x] Includes tests?
- [x] Includes documentation?

QEMU Platform Integration:
- Q35
- SBSA

N/A
… boot options (OpenDevicePartnership#1272)

## Description

Add hotkey detection support to the boot orchestrator, allowing
platforms to configure
alternate boot options that are used when a hotkey (e.g., F12) is
pressed during boot.

Changes:
- Add `detect_hotkey()` helper function to check for hotkey press via
SimpleTextInput protocol
- Add `hotkey_devices` field and `with_hotkey_device()` builder to
`BootOptions`
- Update `BootOrchestrator` to use alternate boot options when hotkey is
detected

---

- [x] Impacts functionality?
- [ ] Impacts security?
- [ ] Breaking change?
- [x] Includes tests?
- [ ] Includes documentation?

## How This Was Tested

- Unit tests for `detect_hotkey()` (no input handles case)
- Unit tests for `hotkey_devices` config (single device, multiple
devices, combined with hotkey)
- `cargo test -p patina_boot` passes

## Integration Instructions

Platforms can configure hotkey boot options:

```rust
BootOptions::new()
    .with_device(primary_device)
    .with_hotkey(0x16) // F12 scancode
    .with_hotkey_device(alternate_device)
```

Closes OpenDevicePartnership#1228
…e_system_table (OpenDevicePartnership#1284)

Release SYSTEM_TABLE lock (TPL_NOTIFY) before accessing
ComponentDispatcher (TPL_APPLICATION) to avoid TPL violation.

PR OpenDevicePartnership#1225 lowered ComponentDispatcher from TPL_NOTIFY to TPL_APPLICATION
to allow components to use boot services, but this created a conflict
when initialize_system_table held SYSTEM_TABLE while setting
boot/runtime services on ComponentDispatcher.

Fix: Extract boot/runtime services pointers while holding SYSTEM_TABLE
lock, then release it before accessing ComponentDispatcher.

- [x] Impacts functionality?
- [ ] Impacts security?
- [ ] Breaking change?
- [ ] Includes tests?
- [ ] Includes documentation?

- Unit tests pass
- QEMU Q35 boots without TPL violation panic

N/A
…ion (OpenDevicePartnership#1290)

Add support for expanding partial (short-form) device paths to full device paths by matching against the device topology.

- Add `is_partial_device_path()` to detect partial paths (start with
Media/Messaging nodes instead of Hardware/ACPI)
- Add `expand_device_path()` to find matching full paths by enumerating
device handles
- Wire expansion into `boot_from_device_path()` for transparent handling
- Currently supports HardDrive nodes with GPT partition signature
matching

This enables booting from Boot#### variables containing partial device paths like `HD(1,GPT,<GUID>)\EFI\BOOT\BOOTX64.EFI`.

- [x] Impacts functionality?
- [ ] Impacts security?
- [ ] Breaking change?
- [x] Includes tests?
- [ ] Includes documentation?

- Unit tests for `is_partial_device_path()`, `expand_device_path()`, and
signature matching
- `cargo test -p patina_boot` passes (32 tests)
- QEMU Q35 platform test passes

N/A

Closes OpenDevicePartnership#1280
…stration design (OpenDevicePartnership#1333)

## Description

Refactors `patina_boot` from a monolithic `BootOrchestrator` component +
`Config<BootOptions>` pattern to a trait-based design:

- **`BootOrchestrator` trait** — defines the boot flow interface with
`execute() -> Result<!, EfiError>`, enforcing at the type level that
successful boot never returns
- **`BootDispatcher`** — the Patina component that installs the BDS
architectural protocol and delegates to a `BootOrchestrator`
implementation
- **`SimpleBootManager`** — a default `BootOrchestrator` implementation
for platforms with straightforward boot topologies
- **`BootConfig`** — unified boot configuration (replaces previous
`BootOptions` + `SimpleBootConfig` split), requires at least one device
at construction (compile-time enforcement)

Also updates `helpers.rs` imports from removed
`uefi_protocol::device_path` to
`device_path::paths`/`device_path::node_defs`.

`patina_dxe_core` changes (image handle plumbing) split out to OpenDevicePartnership#1374.

- [x] Impacts functionality?
- [ ] Impacts security?
- [x] Breaking change?
- [x] Includes tests?
- [ ] Includes documentation?

## How This Was Tested

1. Unit tests: 35 pass (`cargo test -p patina_boot`)
2. Integration tested on QEMU Q35 — all components dispatched, BDS phase
ran, boot options attempted, failure handler fired correctly
3. CI: fmt, clippy, all platforms pass

## Integration Instructions

Update boot orchestration usage from:
```rust
use patina_boot::{component::BootOrchestrator, config::BootOptions};
// In configs():
add.config(BootOptions::new()...);
// In components():
add.component(BootOrchestrator);
```

To:
```rust
use patina_boot::{BootDispatcher, SimpleBootManager, config::BootConfig};

add.component(BootDispatcher::new(SimpleBootManager::new(
    BootConfig::new(primary_device_path())
        .with_device(fallback_device_path())
        .with_hotkey(0x16)
        .with_hotkey_device(usb_device_path())
        .with_failure_handler(|| { /* ... */ }),
)));
```
…penDevicePartnership#1375)

## Description

Rewrite `discover_console_devices()` from a stub into a full
implementation that enumerates console protocol handles, builds
multi-instance device paths, and writes `ConIn`, `ConOut`, and `ErrOut`
UEFI global variables via `SetVariable`.

- Adds `EFI_GLOBAL_VARIABLE` GUID to `patina::guids`
- Adds `build_multi_instance_device_path()` helper for constructing
multi-instance device paths from protocol handles
- Updates `is_partial_device_path()` to recognize FV/FvFile paths as
non-partial
- Includes get_variable readback verification with device path display
logging

Depends on OpenDevicePartnership#1333. Closes OpenDevicePartnership#1230

- [x] Impacts functionality?
- [ ] Impacts security?
- [ ] Breaking change?
- [ ] Includes tests?
- [ ] Includes documentation?

## How This Was Tested

Verified on QEMU Q35 with VGA enabled. Console variables written and
read back successfully:
- ConIn: 24 bytes (SimpleTextInput)
- ConOut: 60 bytes (SimpleTextOutput + GOP)
- ErrOut: 30 bytes (SimpleTextOutput)

## Integration Instructions

N/A
…with DxeServices (OpenDevicePartnership#1422)

## Description

Interleave controller connection with DXE driver dispatch during device
enumeration. Connecting controllers can discover new firmware volumes
(e.g., PCI option ROMs) that contain drivers for devices behind that
controller. Those drivers must be dispatched before the next round of
enumeration, otherwise the devices they serve will not be found.

`SimpleBootManager` uses `interleave_connect_and_dispatch()` to
alternate
between connecting controllers and dispatching newly-discovered drivers
until both stabilize. The `DxeDispatch` service trait (from OpenDevicePartnership#1421) is
consumed via dependency injection.

Note: `interleave_connect_and_dispatch()` currently uses `connect_all()`
which connects every controller on every round. This is functional but
inefficient for platforms with large device topologies — a future
optimization could connect only newly-discovered controllers.

- [x] Impacts functionality?
- [ ] Impacts security?
- [ ] Breaking change?
- [x] Includes tests?
- [ ] Includes documentation?

## How This Was Tested

- Built SBSA DXE core binary with `BootDispatcher` + `SimpleBootManager`
replacing TianoCore BdsDxe
- Booted Windows ARM64 under QEMU SBSA-ref emulation with Patina BDS
handling the full boot flow
- Verified interleaving: controller connection discovered AHCI device,
partial device path expanded to full path, Windows bootloader loaded,
ExitBootServices completed

## Integration Instructions

Depends on OpenDevicePartnership#1421 (`DxeDispatch` service trait) for platform binary
integration.

Remove TianoCore `BdsDxe.inf` from platform DSC/FDF since the
`BootDispatcher` provides the BDS architectural protocol.
…penDevicePartnership#1447)

## Description

Add `discover_boot_options()` helper to `patina_boot::helpers` that
reads UEFI `BootOrder` and `Boot####` variables to build a `BootConfig`
from standard UEFI boot options.

This enables any `BootOrchestrator` implementation that consumes
`BootConfig` to use UEFI-compliant boot variables instead of requiring
platforms to hardcode device paths. The function:

- Reads `BootOrder` to determine boot attempt order
- Parses each `Boot####` `EFI_LOAD_OPTION` structure to extract device
paths
- Filters out inactive boot options (`LOAD_OPTION_ACTIVE`)
- Gracefully skips unreadable or malformed entries
- Returns a populated `BootConfig` with discovered devices in priority
order
---

- [ ] Impacts functionality?
- [ ] Impacts security?
- [ ] Breaking change?
- [x] Includes tests?
- [ ] Includes documentation?

## How This Was Tested

- Unit tests covering: single/multiple boot options, inactive option
filtering, unreadable variable handling, truncated load option data,
empty BootOrder, and hex variable name generation
- Integration tested with patina-dxe-core-qemu `feature/patina-boot` on
QEMU Q35 — full boot to UEFI Shell 2.0

## Integration Instructions

Platforms can call `discover_boot_options()` with runtime services to
automatically populate a `BootConfig` from UEFI boot variables instead
of constructing device paths manually. This works with any
`BootOrchestrator` implementation that accepts a `BootConfig`:

```rust
let config = discover_boot_options(&runtime_services)?;
add.component(BootDispatcher::new(SimpleBootManager::new(config)));
```
@patina-automation
Copy link
Copy Markdown
Contributor

patina-automation Bot commented Apr 30, 2026

✅ QEMU Validation Passed

All QEMU validation jobs completed successfully.

Note: Q35 is only built on Windows hosts (QEMU boot is disabled due to a QEMU vfat issue).

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

Boot Time to EFI Shell

Platform Elapsed
Q35 (Linux Host) 26.0s
SBSA (Linux Host) 1m 1s

Dependencies

Repository Ref
patina f057b48
patina-dxe-core-qemu af6b280
patina-fw-patcher 3960603
patina-qemu firmware v3.0.0
patina-qemu build script b64f358

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

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 30, 2026

Codecov Report

❌ Patch coverage is 98.70130% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
components/patina_boot/src/partition.rs 98.70% 2 Missing ⚠️

📢 Thoughts on this report? Let us know!

@kat-perez kat-perez force-pushed the kat-perez/issue-61-partition-write-lock branch from a824d17 to d747c08 Compare May 1, 2026 00:10
kat-perez added a commit to kat-perez/patina that referenced this pull request May 1, 2026
Adds SreBootManager implementing BootOrchestrator for platforms shipping
a System Recovery Environment alongside the main OS. Skeleton — normal
boot path only:

  1. Interleave controller connection with DXE driver dispatch
  2. Signal EndOfDxe (security lockdown)
  3. Discover console devices
  4. Write-lock the NVMe boot partition (lock_partition_write)
  5. Signal ReadyToBoot
  6. Boot the main OS device

Hotkey detection (Power+Vol-Up to SRE), SRE WIM RAM-disk boot, and
capsule-update pre-boot hook are tracked separately and will layer on
top of this skeleton via subsequent issues.

Adds six unit tests covering construction, the connect+dispatch
interleave loop in three modes (single-round, dispatch error, max-rounds),
type-level BootOrchestrator conformance, and Arc<dyn BootOrchestrator>
construction.

Stacked on the partition write-lock helper from OpenDevicePartnership#61 (PR OpenDevicePartnership#1488). Once
that lands, this PR rebases trivially onto feature/patina-boot.

Closes OpenDevicePartnership#62.
@github-actions github-actions Bot added the impact:testing Affects testing label May 1, 2026
@kat-perez kat-perez force-pushed the kat-perez/issue-61-partition-write-lock branch from d747c08 to b040aff Compare May 1, 2026 13:40
kat-perez added a commit to kat-perez/patina that referenced this pull request May 1, 2026
Adds SreBootManager implementing BootOrchestrator for platforms shipping
a System Recovery Environment alongside the main OS. Skeleton — normal
boot path only:

  1. Interleave controller connection with DXE driver dispatch
  2. Signal EndOfDxe (security lockdown)
  3. Discover console devices
  4. Write-lock the NVMe boot partition (lock_partition_write)
  5. Signal ReadyToBoot
  6. Boot the main OS device

Hotkey detection (Power+Vol-Up to SRE), SRE WIM RAM-disk boot, and
capsule-update pre-boot hook are tracked separately and will layer on
top of this skeleton via subsequent issues.

Adds six unit tests covering construction, the connect+dispatch
interleave loop in three modes (single-round, dispatch error, max-rounds),
type-level BootOrchestrator conformance, and Arc<dyn BootOrchestrator>
construction.

Stacked on the partition write-lock helper from OpenDevicePartnership#61 (PR OpenDevicePartnership#1488). Once
that lands, this PR rebases trivially onto feature/patina-boot.

Closes OpenDevicePartnership#62.
@kat-perez kat-perez force-pushed the kat-perez/issue-61-partition-write-lock branch from b040aff to de50509 Compare May 1, 2026 15:00
kat-perez added a commit to kat-perez/patina that referenced this pull request May 1, 2026
Adds SreBootManager implementing BootOrchestrator for platforms shipping
a System Recovery Environment alongside the main OS. Skeleton — normal
boot path only:

  1. Interleave controller connection with DXE driver dispatch
  2. Signal EndOfDxe (security lockdown)
  3. Discover console devices
  4. Write-lock the NVMe boot partition (lock_partition_write)
  5. Signal ReadyToBoot
  6. Boot the main OS device

Hotkey detection (Power+Vol-Up to SRE), SRE WIM RAM-disk boot, and
capsule-update pre-boot hook are tracked separately and will layer on
top of this skeleton via subsequent issues.

Adds six unit tests covering construction, the connect+dispatch
interleave loop in three modes (single-round, dispatch error, max-rounds),
type-level BootOrchestrator conformance, and Arc<dyn BootOrchestrator>
construction.

Stacked on the partition write-lock helper from OpenDevicePartnership#61 (PR OpenDevicePartnership#1488). Once
that lands, this PR rebases trivially onto feature/patina-boot.

Closes OpenDevicePartnership#62.
@kat-perez kat-perez force-pushed the kat-perez/issue-61-partition-write-lock branch from de50509 to 50adbf2 Compare May 1, 2026 15:15
kat-perez added a commit to kat-perez/patina that referenced this pull request May 1, 2026
Adds SreBootManager implementing BootOrchestrator for platforms shipping
a System Recovery Environment alongside the main OS. Skeleton — normal
boot path only:

  1. Interleave controller connection with DXE driver dispatch
  2. Signal EndOfDxe (security lockdown)
  3. Discover console devices
  4. Write-lock the NVMe boot partition (lock_partition_write)
  5. Signal ReadyToBoot
  6. Boot the main OS device

Hotkey detection (Power+Vol-Up to SRE), SRE WIM RAM-disk boot, and
capsule-update pre-boot hook are tracked separately and will layer on
top of this skeleton via subsequent issues.

Adds six unit tests covering construction, the connect+dispatch
interleave loop in three modes (single-round, dispatch error, max-rounds),
type-level BootOrchestrator conformance, and Arc<dyn BootOrchestrator>
construction.

Stacked on the partition write-lock helper from OpenDevicePartnership#61 (PR OpenDevicePartnership#1488). Once
that lands, this PR rebases trivially onto feature/patina-boot.

Closes OpenDevicePartnership#62.
@kat-perez kat-perez force-pushed the kat-perez/issue-61-partition-write-lock branch from 50adbf2 to 3e78f33 Compare May 1, 2026 15:58
kat-perez added a commit to kat-perez/patina that referenced this pull request May 1, 2026
Adds SreBootManager implementing BootOrchestrator for platforms shipping
a System Recovery Environment alongside the main OS. Skeleton — normal
boot path only:

  1. Interleave controller connection with DXE driver dispatch
  2. Signal EndOfDxe (security lockdown)
  3. Discover console devices
  4. Write-lock the NVMe boot partition (lock_partition_write)
  5. Signal ReadyToBoot
  6. Boot the main OS device

Hotkey detection (Power+Vol-Up to SRE), SRE WIM RAM-disk boot, and
capsule-update pre-boot hook are tracked separately and will layer on
top of this skeleton via subsequent issues.

Adds six unit tests covering construction, the connect+dispatch
interleave loop in three modes (single-round, dispatch error, max-rounds),
type-level BootOrchestrator conformance, and Arc<dyn BootOrchestrator>
construction.

Stacked on the partition write-lock helper from OpenDevicePartnership#61 (PR OpenDevicePartnership#1488). Once
that lands, this PR rebases trivially onto feature/patina-boot.

Closes OpenDevicePartnership#62.
kat-perez added a commit to kat-perez/patina that referenced this pull request May 1, 2026
Adds SreBootManager implementing BootOrchestrator for platforms shipping
a System Recovery Environment alongside the main OS. Skeleton — normal
boot path only:

  1. Interleave controller connection with DXE driver dispatch
  2. Signal EndOfDxe (security lockdown)
  3. Discover console devices
  4. Write-lock the NVMe boot partition (lock_partition_write)
  5. Signal ReadyToBoot
  6. Boot the main OS device

Hotkey detection (Power+Vol-Up to SRE), SRE WIM RAM-disk boot, and
capsule-update pre-boot hook are tracked separately and will layer on
top of this skeleton via subsequent issues.

Adds six unit tests covering construction, the connect+dispatch
interleave loop in three modes (single-round, dispatch error, max-rounds),
type-level BootOrchestrator conformance, and Arc<dyn BootOrchestrator>
construction.

Stacked on the partition write-lock helper from OpenDevicePartnership#61 (PR OpenDevicePartnership#1488). Once
that lands, this PR rebases trivially onto feature/patina-boot.

Closes OpenDevicePartnership#62.
Introduces lock_partition_write() in helpers.rs. Resolves the NVMe
controller via locate_device_path against EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL
and issues NVMe Set Features FID 0x11 (Boot Partition Write Protection
Configuration), placing both BP0 and BP1 in "Write Protect Until Power
Cycle" state per NVMe Base Spec section 5.27.1.17.

Inner FFI dispatch is split into an unsafe helper following the existing
detect_hotkey_from_handles pattern; the raw-pointer path is integration-
tested rather than mocked. Adds three unit tests covering locate_device_path
failure, handle_protocol failure, and the CDW10/CDW11 encoding contract.

Closes OpenDevicePartnership#61.
@kat-perez kat-perez force-pushed the kat-perez/issue-61-partition-write-lock branch from 3e78f33 to f057b48 Compare May 1, 2026 16:17
kat-perez added a commit to kat-perez/patina that referenced this pull request May 1, 2026
Adds SreBootManager implementing BootOrchestrator for platforms shipping
a System Recovery Environment alongside the main OS. Skeleton — normal
boot path only:

  1. Interleave controller connection with DXE driver dispatch
  2. Signal EndOfDxe (security lockdown)
  3. Discover console devices
  4. Write-lock the NVMe boot partition (lock_partition_write)
  5. Signal ReadyToBoot
  6. Boot the main OS device

Hotkey detection (Power+Vol-Up to SRE), SRE WIM RAM-disk boot, and
capsule-update pre-boot hook are tracked separately and will layer on
top of this skeleton via subsequent issues.

Adds six unit tests covering construction, the connect+dispatch
interleave loop in three modes (single-round, dispatch error, max-rounds),
type-level BootOrchestrator conformance, and Arc<dyn BootOrchestrator>
construction.

Stacked on the partition write-lock helper from OpenDevicePartnership#61 (PR OpenDevicePartnership#1488). Once
that lands, this PR rebases trivially onto feature/patina-boot.

Closes OpenDevicePartnership#62.
@kat-perez kat-perez marked this pull request as ready for review May 1, 2026 16:27
@kat-perez kat-perez requested a review from makubacki May 1, 2026 16:28
@kat-perez kat-perez requested review from Javagedes and os-d May 1, 2026 16:28
@kat-perez kat-perez changed the title patina_boot: Add NVMe boot-partition write-lock helper [feature/patina-boot] patina_boot: Add NVMe boot-partition write-lock helper May 1, 2026
/// `protocol` must be a valid, non-null pointer to an `EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL`
/// instance owned by an NVMe controller for the duration of this call.
unsafe fn lock_partition_write_inner(protocol: *mut nvme_pass_thru::Protocol) -> Result<()> {
use nvme_pass_thru::{
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 would like to wait to check this in until we’ve had a discussion on using protocols from Patina boot. It may be a necessary intermediate step, but we should consider what the right abstraction is, whether to accept using the protocol directly or have a service Patina boot consumes (which for now gets the protocol). Can we discuss in the next Patina meeting?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

We can discuss in the Patina meeting. However, I don't think we want patina_boot to directly implement storage abstraction details regardless of the underlying mechanism to do so (protocol or service).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Setting the implementation in this PR, what is the underlying assumption when adding this to patina_boot on when the boot partition will be locked in the overall boot flow?

kat-perez added a commit to kat-perez/patina that referenced this pull request May 4, 2026
Adds SreBootManager implementing BootOrchestrator for platforms shipping
a System Recovery Environment alongside the main OS. Skeleton — normal
boot path only:

  1. Interleave controller connection with DXE driver dispatch
  2. Signal EndOfDxe (security lockdown)
  3. Discover console devices
  4. Write-lock the NVMe boot partition (lock_partition_write)
  5. Signal ReadyToBoot
  6. Boot the main OS device

Hotkey detection (Power+Vol-Up to SRE), SRE WIM RAM-disk boot, and
capsule-update pre-boot hook are tracked separately and will layer on
top of this skeleton via subsequent issues.

Adds six unit tests covering construction, the connect+dispatch
interleave loop in three modes (single-round, dispatch error, max-rounds),
type-level BootOrchestrator conformance, and Arc<dyn BootOrchestrator>
construction.

Stacked on the partition write-lock helper from OpenDevicePartnership#61 (PR OpenDevicePartnership#1488). Once
that lands, this PR rebases trivially onto feature/patina-boot.

Closes OpenDevicePartnership#62.
@kat-perez kat-perez force-pushed the feature/patina-boot branch from d9c454f to adc19cd Compare May 6, 2026 15:40
@kat-perez
Copy link
Copy Markdown
Contributor Author

Closing in favor of OpenDevicePartnership/patina-components#11, which moves this helper into the new patina_nvme crate per the reviewer thread on this PR (patina_boot shouldn't implement storage abstraction details).

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

Labels

impact:testing Affects testing

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants