Skip to content

Releases: OpenDevicePartnership/patina

patina-v22.0.0

06 Jun 00:40
7d8c8d9

Choose a tag to compare

What's Changed

⚠️ Breaking Changes

  • [major] Simplify patina\_performance config, Add SMBIOS types to Patina, R-EFI 6.0 Migration @vineelko (#1548)
    Change Details
      ## Description

    1465: patina_performance: Simplify configuration

    patina_performance has a confusing configuration story. Prior to this change, configuration was done via patina Config, A platform could optionally register a secondary component that would read a HOB (if provided) and overwrite any Config with the HOB configuration.

    This commit works to simplify the configuration story by making a couple of changes:

    1. Removal of the Config object. As stated in documentation throughout patina, Config is meant for configuration that is expected to be shared between multiple components. This particular configuration does not need to be shared, so it is moved to be private configuration of the component.
    2. Removal of the optional HOB reader driver. Now, a private configuration of the component will allow you to specify if the HOB is able to override local configuration or not.

    This new story reduces patina_performance setup from three different definitions (Config, performance component, and hob component) to only one, the performance component.

    How This Was Tested

    Reading final configuration of the performance component on Q35 with various configuration settings both in the component and via the HOB

    Previous

    use patina_dxe_core::*;
    
    struct Q35;
    
    impl ComponentInfo for Q35 {
      fn configs(mut add: Add<Config>) {
        add.config(patina_performance::config::PerfConfig {
          enable_component: true,
          enabled_measurements: patina::performance::Measurement::LoadImage | patina::performance::Measurement::StartImage
        }
      }
      
      fn components(mut add: Add<Component>) {
        add.component(patina_performance::component::performance_config_provider::PerformanceConfigurationProvider);
        add.component(patina_performance::component::performance::Performance);
      }
    }

    After

    use patina_dxe_core::*;
    use patina_performance::component::*;
    
    struct Q35;
    
    impl ComponentInfo for Q35 {
      fn components(mut add: Add<Component>) {
        // Records LoadImage and StartImage measurements unless configuration is overwritten by a HOB
        add.component(Performance::new().with_measurements(Measurement::LoadImage | Measurement::StartImage));
        
        // Disabled. Enablement fully controlled by a HOB
        add.component(Performance::new());
    }

    1501: patina_smbios: Add SMBIOS types

    Define types for SMBIOS records according the SMBIOS specs 3.0+ and update records to use types. These structs/enums/bitfields force typing when creating SMBIOS records.

    How This Was Tested

    cargo make all, plus patina-dxe-core-qemu integration: ported the Q35 and
    SBSA SMBIOS platform components onto the new typed records, booted Q35 in
    QEMU, and confirmed q35_smbios_ffi_test passes against the published SMBIOS
    table.

    Integration Instructions

    Downstream consumers of patina_smbios Type 0 / 1 / 2 / 3 / 4 / 7 / 16 / 17 /
    19 records must construct fields with the new types instead of raw integers
    (e.g. BiosCharacteristics::from_bits(0x08), WakeUpType::PowerSwitch,
    BootUpState::Safe). For Type 4, set processor_family: u8 = 0xFE and put
    the typed value in processor_family2.

    Co-Authored-By: Ansley Thompson ansley.thompson@dell.com


    1480: Patina: R-EFI 6.0 migration

    R-EFI 6.0 Migration

    Upstream r-efi 6.0 marks all extern "efiapi" function pointers in EFI Boot
    Services, Runtime Services, and other protocols as unsafe, since their safety
    cannot be enforced by the Rust type system at compile time.

    This PR audits almost all usage of UEFI service function pointers across the Patina
    codebase for correctness and safety.

    • There are three primary areas where unsafe usage has been audited:

      1. The FFI boundary - all extern "efiapi" functions
      2. The Patina wrappers - all functions within the BootServices trait that
        eventually call into the FFI
      3. Core Patina routines that implement the FFI functions
    • Not all functions in the above categories need to be marked unsafe. For
      example, extern "efiapi" close_event is not marked unsafe because it can
      safely be called with an arbitrary event parameter without causing undefined
      behavior in the Patina implementation. The event parameter is treated as an
      opaque pointer and is never dereferenced.

      That said, any indirect caller that dereferences this Boot Services function
      pointer must still use an unsafe block, since the function pointer itself is
      defined as unsafe in r-efi 6.0. In addition, inherently unsafe Rust
      functions (such as core_free_pool()) are now explicitly marked unsafe.

    • Each inspected function or call site is documented with appropriate safety
      comments where necessary, and with explanations where unsafe is not
      required.

    • There are no functional changes.

    • Clippy flags public functions that accept raw pointer parameters and pass them
      across an FFI boundary without being marked unsafe, with the following
      warning:
      "this public function might dereference a raw pointer but is not marked unsafe"

      unsafe extern "C" {
          fn some_ffi_call(ptr: *mut i32);
      }
      
      // Triggers clippy::not_unsafe_ptr_arg_deref:
      // - public function
      // - not marked `unsafe`
      // - raw pointer parameter `ptr` is passed into an `unsafe` block
      pub fn example(ptr: *mut i32) {
          unsafe { some_ffi_call(ptr) };
      }
      

      In Patina, this pattern is common for functions that take efi::Event or
      efi::Handle parameters and call Boot Services function pointers. We
      explicitly suppress this lint for such functions because these types are
      treated as opaque pointers and are never dereferenced:
      #[allow(clippy::not_unsafe_ptr_arg_deref)]

    Geiger Unsafe Stats

    |             | x86_64-unknown-uefi(before) | x86_64-unknown-uefi(after) | aarch64-unknown-uefi(before) | aarch64-unknown-uefi(after) |
    |-------------|-----------------------------|----------------------------|------------------------------|-----------------------------|
    | overall     | 11.90% (yellow)             | 16.30% (red)               | 12.20% (yellow)              | 16.30% (red)                |
    | functions   | 2.60%  (green)              | 11.40% (yellow)            | 2.80%  (green)               | 11.40% (yellow)             |
    | exprs       | 12.40% (yellow)             | 17.00% (red)               | 12.60% (yellow)              | 17.00% (red)                |
    | item_impls  | 12.50% (yellow)             | 13.80% (yellow)            | 13.80% (yellow)              | 13.80% (yellow)             |
    | item_traits | 12.10% (yellow)             | 13.00% (yellow)            | 13.00% (yellow)              | 13.00% (yellow)             |
    | methods     | 5.60%  (green)              | 6.60%  (green)             | 5.60%  (green)               | 6.60%  (green)              |
    
    • Impacts functionality?
    • Impacts security?
    • Breaking change?
    • Includes tests?
    • Includes documentation?

    How this was tested

    Verified booting to UEFI shell from Q35, SBSA

    Integration Instructions

    All consumers of Patina will need to pick the newer Patina version when published and also should update their R-EFI version to 6.0.0.




Full Changelog: patina-v21.2.0...v22.0.0

patina-v21.2.0

05 Jun 20:17
a077cb7

Choose a tag to compare

What's Changed

  • [REBASE \& FF] Add Stack Overflow Hint in Exception Handlers @os-d (#1554)
    Change Details
      ## Description

    Stack overflows show up as page faults in the exception handler, which can be hard to distinguish from other kinds of page faults. This PR contains three commits to provide a hint that a stack overflow occurred.

    x64: IDT: Use a Separate Stack for Page Fault Exceptions

    Currently, only double faults use a separate stack. However, a stack overflow manifests as a page fault, so taking a stack overflow causes a double fault. This makes it harder to reason about what the fault was.

    This commit instead using a separate stack for x64 page faults, aligning with the aarch64 side. This is in preparation for giving better information about stack overflows in the exception handlers.

    exception handlers: Print Stack Overflow Hint

    Currently, stack overflows show up as page faults in the exception handlers. This can make it hard to identify when a different page fault has occurred.

    This commit introduces a heuristic to hint that a stack overflow likely occurred in the exception handler. It checks if the faulting address is on the same page as or one page lower than the stack pointer. In some cases, the stack pointer is incremented first, then data is written (in which case the faulting address is on the same page as the stack pointer) and in other cases the data is written before the stack pointer is decremented (so the faulting address is on the page below the stack pointer).

    A pretty message is then printed to indicate a stack overflow occurred.

    internal_cpu: Rename EfiExceptionStackTrace Trait

    The EfiExceptionStackTrace trait is an internal trait that originally was just used so the common exception handler can use arch specific stack trace dumping.

    However, this was expanded to also include dumping a page table walk, so the name is not accurate.

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

    How This Was Tested

    In Q35 and SBSA testing stack overflows which now look like:

    image image

    Integration Instructions

    N/A.




  • patina: Add Memory Type Information HOB serialization to the SDK @makubacki (#1556)
    Change Details
      ## Description

    Adds a HobSerDe::MemoryTypeInformation variant so that GUID extension HOBs matching MEMORY_TYPE_INFO_HOB_GUID are serialized with their parsed payload instead of being collapsed into a generic GuidExtension entry.

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

    How This Was Tested

    • cargo make all

    Integration Instructions

    • N/A


  • Move Patina QEMU PR Validation workflows to patina-devops main branch @makubacki (#1555)
    Change Details
      ## Description

    The workflows were previously using a branch dedicated to creating the workflow. All of the changes are in main now, so the workflows can use the main branch instead.

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

    How This Was Tested

    • All of the changes in the branch previously being used patina_e2e_plat_validation

    Integration Instructions

    • N/A


  • Minor Test Bug Fix: Initialize GCD before allocating SystemTable @vineelko (#1551)
    Change Details
      ## Description

    Initialize GCD before allocating SystemTable, otherwise below is the call flow causing stack corruption.

    test_init_driver_services()
        EfiSystemTable::allocate_new_table()
            EfiRuntimeServicesTable::allocate_new_table()
                Box::new_in(...)
                    Box::try_new_uninit_in(...)
                        uefi_allocator::...::allocate()
                            fixed_size_block_allocator::...::allocate()
                                self.allocate_from_gcd()
                                    // Attempts to allocate from uninitialized GCD!
    
    • Impacts functionality?
    • Impacts security?
    • Breaking change?
    • Includes tests?
    • Includes documentation?

    How This Was Tested

    cargo nextest run driver_services::tests::test_init_driver_services

    Integration Instructions

    NA




  • patina\_internal\_collections: Replace array\_windows with windows (MSRV 1.89.0 compat) @makubacki (#1547)
    Change Details
      ## Description

    array_windows was introduced in Rust 1.94 and to patina in commit 856bda1, our MSRV is 1.89.

    Replace array_windows with windows and adjust the loop body accordingly to pass the MSRV check.


    Issue before:

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

    How This Was Tested

    Integration Instructions

    • N/A


  • [mm] Do not introduce `talk_to_supervisor` bit @kuqin12 (#1544)
    Change Details
      ## Description

    Even the status buffer definition from basecore has this bit set:

    However, with the current usage of MM communicate, this bit is not needed for the proper communication invocation:

    In addition, the updated MM supervisor will no longer rely on this bit to differentiate the target channel, thus will not need this bit in the future, either.

    This change removes the bit definition and the associated usage.

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

    How This Was Tested

    This was tested locally and booted to Windows desktop. Pipeline should verify the same as well.

    Integration Instructions

    N/A

      </blockquote>
      <hr>
    </details>
    

🚀 Features & ✨ Enhancements

  • patina\_debugger: Do not initialize the transport by default @cfernald (#1550)
    Change Details
      ## Description

    This change removes the default behavior to initialize the debugger transport serial port. Most systems will use a shared transport, and so the re-initialization is at best unnecessary. In some scenarios the Patina serial transport initialization may stomp on the existing configuration. This has caused confusion on multiple platforms during enablement. It is best to just skip unless requested. This commit inverts the default, deprecates without_transport_init, and introduces with_transport_init for the rare platforms that require this.

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

    How This Was Tested

    Tested that Q35 & SBSA debuggers still function

    Integration Instructions

    Platforms using without_transport_init() may safely drop that function call. There are no known platforms that require transport initialization, but if so those should now call with_transport_init() as needed.

      </blockquote>
      <hr>
    </details>
    

🐛 Bug Fixes

  • Ensure cache consistency when changing to uncached memory [FF \& REBASE] @cfernald (#1540)
    Change Details
      ## Description

    patina_internal_cpu: Flush data cache which switching to uncached

    When switching memory from a cached normal memory to a uncached or device
    memory, the cache lines may stuill exist. Some platforms may snoop this
    cache, but this is not guaranteed. To ensure data consistency accross all
    platforms, the data cache should be explicitly cleaned.

    This commit adds a arc architectural callout for when...

Read more

patina-v21.1.1

29 May 22:07
e9d665e

Choose a tag to compare

What's Changed

  • Add PEI memory bin support [Rebase \& FF] @makubacki (#1486)
    Change Details
      ## Description

    Closes #1175

    A few small commits for miscellaneous changes followed by the main commit for PEI memory bins.


    sdk: Derive Clone and Copy for EFiMemoryTypeInformation

    Allow EfiMemoryTypeInformation to be easily duplicated, as it is a simple struct containing only Copy types.


    sdk: Add EFI_MAX_MEMORY_TYPE and INVALID_INFORMATION_INDEX constants

    Provide a stable constant to represent the maximum valid EFI memory instead of hardcoding the value based on the last valid memory type.

    INVALID_INFORMATION_INDEX is added as a sentinel value to indicate an invalid memory type index in the memory type information table.


    sdk: Add page_shift_from_alignment() to base.rs

    Adds the following helper for working with page operations:

    • page_shift_from_alignment(alignment) - Converts a page-aligned byte granularity to the corresponding bit shift value. This is useful for determining the shift needed to convert between addresses and page frame numbers.

    patina_dxe_core: Add PEI memory bin support

    Memory bins are pre-allocated, per-type regions of memory for EFI runtime memory types (ReservedMemory, RuntimeServicesCode, RuntimeServicesData, ACPIMemoryNVS, ACPIReclaimMemory). By over reserving these regions at a fixed size, the memory map presented to the OS has a much greater chance of remaining stable across boots, which is required for S4 (hibernate) resume.

    This commit adds support for PEI memory bins allocated prior to DXE, such as in PEI, where the bin information is given to the Patina DXE core via HOBs.

    A new module called MemoryBinManager is added. It tracks bin state: preferred ranges, allocation statistics, and the memory type information published to the EFI config table in addition to related bin logic for when producing the EFI memory map.

    Two initialization paths are supported:

    • Path A - PEI-provided bins: A Resource Descriptor HOB with owner GUID gEfiMemoryTypeInformationGuid describes a contiguous region PEI set aside for bins. Bins are divided within that region with per-type granularity. Free GCD pages within each bin range are claimed with ownership preservation so other allocators cannot expand into them.

    • Path B - DXE-allocated bins: If a PEI region HOB does not exist, each bin type is allocated directly from the GCD using allocate-then-free with ownership preservation.

    After bin initialization, seed_bin_statistics_from_hobs() scans Memory Allocation HOBs whose Name matches gEfiMemoryTypeInformationGuid to account for these potential PEI-phase allocations inside bin regions in initial bin statistics.

    On every AllocatePages()/FreePages() call, record_allocation() and record_free() update the bin statistics for the relevant type. On free, if the pages fall within a bin range, GCD ownership is re-established to prevent other allocators from reclaiming those pages.

    GetMemoryMap() calls apply_bin_descriptors() after populating the EFI memory map. This post-processing step converts EfiConventionalMemory entries that overlap bin ranges to the bin's memory type, splitting entries at bin boundaries as needed. The buffer-size calculation is updated to account for up to two extra descriptors per active bin.

    install_memory_type_info_table() is updated to use the bin manager's data.

    The previous reserve_memory_pages() API on PageAllocator and SpinLockedFixedSizeBlockAllocator is removed with logic moved into MemoryBinManager.


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

    How This Was Tested

    • PEI bins active and inactive on QEMU Q35
    • Boot to EFI shell with SBSA
    • Boot to OS on 64-bit Intel physical platform
    • Note: Some additional physical platform testing with various features such as performance enabled is still in progress (PR in draft until done)

    Integration Instructions

    • If using edk2, ensure edk2 PR 12086 is present
    • If using Mu, ensure mu_basecore PR 1759 is present
    • Set the Feature PCD gEfiMdeModulePkgTokenSpaceGuid.PcdPeiMemoryBinsEnable to TRUE
    • Refer to edk2 memory bin and Patina memory bin documentation for further details

    PEI Bins Active Example

    PEI Output: Bin allocation

    AllocateMemoryTypeInformationBins: Attempting to allocate 0xDBB000 bytes for all memory bins
    InitializeMemoryTypeInformationBins: Memory bins address range 0x7E233000 - 0x7EFEDFFF
    

    Patina DXE Output

    • memory_bin log target at trace
    Patina DXE Output: Init
    Found Memory Type Information HOB (48 bytes, 6 entries)
      MemTypeInfo: ACPIMemoryNVS pages=128 (GCD alloc will use 128)
      MemTypeInfo: ACPIReclaimMemory pages=43 (GCD alloc will use 43)
      MemTypeInfo: ReservedMemoryType pages=1296 (GCD alloc will use 1296)
      MemTypeInfo: RuntimeServicesCode pages=256 (GCD alloc will use 256)
      MemTypeInfo: RuntimeServicesData pages=1792 (GCD alloc will use 1792)
    Memory Type Information HOB found with 6 entries.
    Found MemoryTypeInformation Resource Descriptor HOB: base=0x7E233000 length=0xDBB000
    Found PEI bin region at 0x7E233000, length 0xDBB000.
    Initializing memory bins from PEI range: base=0x7E233000 length=0xDBB000 total_needed=0xDBB000
      Bin[10] ACPIMemoryNVS: base=0x7EF6E000 max=0x7EFEDFFF pages=0x80 (128 pages)
      Bin[9] ACPIReclaimMemory: base=0x7EF43000 max=0x7EF6DFFF pages=0x2B (43 pages)
      Bin[0] ReservedMemoryType: base=0x7EA33000 max=0x7EF42FFF pages=0x510 (1296 pages)
      Bin[5] RuntimeServicesCode: base=0x7E933000 max=0x7EA32FFF pages=0x100 (256 pages)
      Bin[6] RuntimeServicesData: base=0x7E233000 max=0x7E932FFF pages=0x700 (1792 pages)
    Memory bins initialized from pre-allocated range.
    Reserving bin[0] ReservedMemoryType range=[0x7EA33000..0x7EF42FFF] (1296 pages)
    Reserved bin[0] ReservedMemoryType: claimed=1296 pages, existing=0 pages, conflicting=0 pages (of 1296 total)
    Reserving bin[5] RuntimeServicesCode range=[0x7E933000..0x7EA32FFF] (256 pages)
    Reserved bin[5] RuntimeServicesCode: claimed=256 pages, existing=0 pages, conflicting=0 pages (of 256 total)
    Reserving bin[6] RuntimeServicesData range=[0x7E233000..0x7E932FFF] (1792 pages)
    Reserved bin[6] RuntimeServicesData: claimed=1663 pages, existing=129 pages, conflicting=0 pages (of 1792 total)
    Reserving bin[9] ACPIReclaimMemory range=[0x7EF43000..0x7EF6DFFF] (43 pages)
    Reserved bin[9] ACPIReclaimMemory: claimed=43 pages, existing=0 pages, conflicting=0 pages (of 43 total)
    Reserving bin[10] ACPIMemoryNVS range=[0x7EF6E000..0x7EFEDFFF] (128 pages)
    Reserved bin[10] ACPIMemoryNVS: claimed=128 pages, existing=0 pages, conflicting=0 pages (of 128 total)
     PEI seed: RuntimeServicesData +1 pages at 0x7E931000. total=1
     PEI seed: RuntimeServicesData +64 pages at 0x7E8F1000. total=65
     PEI seed: RuntimeServicesData +64 pages at 0x7E8B1000. total=129
    Seeded bin statistics from 3 PEI Memory Allocation HOBs.
    
    Patina DXE Output: Memory Map
    • Note: There are some expected EfiReservedMemoryType allocations of RT types intentionally outside bin ranges.
    DEBUG - GetMemoryMap: processing bin[0] ReservedMemoryType range=[0x7EA33000..0x7EF42FFF]
    DEBUG - GetMemoryMap: processing bin[5] RuntimeServicesCode range=[0x7E933000..0x7EA32FFF]
    DEBUG - GetMemoryMap: processing bin[6] RuntimeServicesData range=[0x7E233000..0x7E932FFF]
    DEBUG - GetMemoryMap: processing bin[9] ACPIReclaimMemory range=[0x7EF43000..0x7EF6DFFF]
    DEBUG - GetMemoryMap: processing bin[10] ACPIMemoryNVS range=[0x7EF6E000..0x7EFEDFFF]
    EfiReservedMemoryType       at 0 for 80 pages
    EfiBootServicesData         at 50000 for 1 pages
    EfiConventionalMemory       at 51000 for 54 pages
    EfiBootServicesData         at 87000 for 1 pages
    EfiConventionalMemory       at 88000 for 24 pages
    EfiConventionalMemory       at 100000 for 1856 pages
    EfiBootServicesData         at 840000 for 3520 pages
    EfiConventionalMemory       at 1600000 for 498110 pages
    EfiBootServicesData         at 7AFBE000 for 32 pages
    EfiConventionalMemory       at 7AFDE000 for 17 pages
    EfiBootServicesData         at 7AFEF000 for 96 pages
    EfiConventionalMemory       at 7B04F000 for 4353 pages
    EfiBootServicesData         at 7C150000 for 1848 pages
    EfiBootServicesCode         at 7C888000 for 27 pages
    EfiBootServicesData         at 7C8A3000 for 538 pages
    EfiBootServicesCode         at 7CABD000 for 1162 pages
    EfiBootServicesData         at 7CF47000 for 256 pages
    EfiBootServicesCode         at 7D047000 for 102 pages
    EfiBootServicesData         at 7D0AD000 for 42 pages
    EfiConventionalMemory       at 7D0D7000 for 1 pages
    EfiBootServicesData         at 7D0D8000 for 4 pages
    EfiBootServicesCode         at 7D0DC000 for 73 pages
    EfiBootServicesData         at 7D125000 for 5 pages
    EfiBootServicesCode         at 7D12A000 for 214 pages
    EfiBootServicesData         at 7D200000 for 2562 pages
    EfiBootServicesCode         at 7DC02000 for 28 pages
    EfiBootServicesData         at 7DC1E000 for 32 pages
    EfiBootServicesCode         at 7DC3E000 for 365 pages
    EfiBootServicesData         at 7DDAB000 for 5 pages
    EfiBootServicesCode         at 7DDB0000 for 19 pages
    EfiBootServicesData         at 7DDC3000 for 1 pages
    EfiBootServicesCode         at 7DDC4000 for 1 pages
    EfiBootServicesData         at 7DDC5000 for 5 pages
    EfiBootServicesCode         at 7DDCA000 for 1 pages
    EfiBootServicesData         at 7DDCB000 for 1 pages
    EfiBootServicesCode         at 7DDCC000 for 1 pages
    EfiBootServicesData         at 7DDCD000 for 41 pages
    EfiBootServicesCode         at 7DDF6000 for 16 pages
    EfiBootServicesData         at 7DE06000 ...
    
Read more

patina-v21.1.0

27 May 18:30

Choose a tag to compare

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 CR
    

    This 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.

      </blockquote>
      <hr>
    </details>
    
  • patina\_test: Gate component doctest on the test-runner feature (MSRV 1.89.0 compat) @makubacki (#1533)
    Change Details
      ## Description

    The component module is only public when feature = "test-runner" is enabled (or when rustdoc is generating docs with cfg(doc)).

    The Filter doctest in components/patina_test/src/component.rs imports from it.

    cargo test --doc fails prior to 1.92.0 with: "E0603: module component is 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_attr to ignore the test when the test-runner feature 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 as Config<u32>, and three tests in component::params and component::struct_component hardcode the more recent rendered form.

    This change introduces a small internal helper, component::type_name, that wraps core::any::type_name and 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_logger when RUST_LOG is 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 cause log::* calls ...

Read more

patina-v21.0.4

13 May 19:41
a0385a3

Choose a tag to compare

What's Changed

  • [REBASE \& FF] patina\_debugger: Don't Touch Uncached Memory By Default @os-d (#1503)
    Change Details
      ## Description

    This PR contains two commits:

    Debugger: Move to PatinaPageTable Trait

    Currently, the debugger uses the PageTable trait from patina_paging directly. On X64, this does not allow getting caching attributes since they are managed by MTRRs.

    In preparation for using caching attributes in the debugger, move to the PatinaPageTable trait from patina_internal_cpu to get caching attributes uniformly.

    This requires a new API in patina_internal_cpu to get the existing page table instead of creating a new one.

    patina_debugger: Don't Access Uncached Memory By Default

    It has been observed on physical platforms that WinDbg can request addresses in uncached memory. This results in the debugger attempting to read them. It uses the poke test to tell if this is safe. Sometimes the poke test works, but in one case, a machine check is generated to all cpus and the poke test cannot recover from this.

    This changes this to check if memory is uncached. If so, the debugger will fail to read it. A new monitor cmd will toggle the ability of the debugger to read uncached memory or not.

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

    How This Was Tested

    On a physical Intel platform that was getting a #MC when an uncached range was requested to be read by WinDbg and so the debugger read it because it was mapped. After this, the #MC doesn't occur.

    Integration Instructions

    If uncached memory must be touched from the debugger, call !uefiext.monitor toggle_uncached_access (or otherwise call the monitor command) to toggle the ability.




  • components: Fix grammatical error in patina\_adv\_logger code example @makubacki (#1504)
    Change Details
      ## Description

    Fixes duplicate articles ("a the") that has been observed in logs from a few platforms copying the example as-is.

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

    How This Was Tested

    • cargo make all

    Integration Instructions

    • N/A


📖 Documentation Updates

  • mdbook: Add training videos page @makubacki (#1507)
    Change Details
      ## Description

    Make Patina training video content conveniently accessible from the documentation by adding a training video page.

    Closes #1432
    Closes #1433
    Closes #1434


    If you're going to preview the page, view the rendered mdbook content locally with mdbook serve ./docs (not the GitHub markdown page).

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

    How This Was Tested

    • mdbook build ./docs

    Integration Instructions

    • N/A


  • mdbook: Update intro material, add mdbook-linkcheck, minor fixes [Rebase \& FF] @makubacki (#1499)
    Change Details
      ## Description

    mdbook updates that at a high-level:

    • Add mdbook-linkcheck as a backend
    • Update introduction material
    • Makes some miscellaneous fixes

    .github/workflows/publish-mdbook.yml: Do not attempt to deploy on forks

    Most forks are likely not intending to publish the Patina mdbook
    on their fork repository. Skip the deployment step on forks.


    docs: Sort links in SUMMARY.md

    Make links easier to find by sorting them alphabetically.


    mdbook: Update introduction material

    Moves content in the navigation bar to prioritize key information
    when less familiar with the project.

    Adds a new page on "Patina in the UEFI Rust Ecosystem" to provide more
    context on how Patina fits into the broader UEFI Rust ecosystem.

    Minor other edits in introduction material to improve flow and
    readability.


    mdbook: Minor fixes and updates

    • dxe_core/memory_management.md: Fixed a couple of typos
    • patina.md: Fixed trailing whitespace and updated current code
      coverage in the "Notable DXE Core Features" section

    mdbook: Add linkcheck backend

    Adds the mdbook-linkcheck backend to check for broken links in the
    book.

    https://github.com/Michael-F-Bryan/mdbook-linkcheck

    • mdbook-linkcheck added to rust-toolchain.toml
    • Configuration is added to book.toml
    • A few cases where square brackets were not escaped in md files
      are fixed
    • publish-mdbook.yml is updated to upload artifacts from docs/book/html
      instead of docs/book because when mdbook has multiple output backends
      ([output.html] and [output.linkcheck]), it nests output in
      subdirectories under the build dir (e.g., book/html/, book/linkcheck/)
      instead of writing directly to book/.

    Since mdbook-linkcheck can run after these changes without warnings,
    it is not marked as optional in the book.toml configuration and it is
    installed in the CI workflow, so it can run like the other mdbook
    tools.

    A broken link will fail mdbook build, with a clear error message
    about which link is broken:

    (mdbook::renderer): Invoking the "linkcheck" renderer
    error: File not found: todo!()
        ┌─ introduction.md:118:4
        │
    118 │ 4. [Contributing to Patina](todo!())
        │    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File not found: todo!()
    
    error: File not found: ../does_not_exist.md
      ┌─ dev/documenting/reference.md:15:1
      │
    15 │ [Test Broken Link](../does_not_exist.md)
      │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File not found: ../does_not_exist.md
    
    Error: One or more incorrect links
    

    Note: The follow-web-links default option is left to its default
    value of false to avoid linkcheck attempting to validate external
    links and potentially causing CI failures due to external sites being
    down or rate-limiting requests.


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

    How This Was Tested

    • mdbook build ./docs
    • Run cspell on ./docs

    Integration Instructions

    • N/A


Full Changelog: patina-v21.0.3...v21.0.4

patina-v21.0.3

06 May 23:20
e331673

Choose a tag to compare

What's Changed

  • [REBASE \& FF] Add Ability To Hide Debugger Monitor Commands @os-d (#1477)
    Change Details
      ## Description

    patina_debugger: Allow Hidden Monitor Cmds

    Patina adds some monitor cmds that are not intended to be run by a user, such as the reload cmd. UefiExt is expected to run this in response to the !loadcore cmd.

    However, the monitor help will show this as a valid command for a user to run, which is confusing. This hides that command as well as generically providing a mechanism to do so.

    Drop GCD Debugger Monitor Cmd

    A more advanced GCD command is available as of UefiExt v0.5.0. Drop the monitor cmd.

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

    How This Was Tested

    Tested by connecting Q35 and a physical Intel platform to the debugger and confirming the reload and gcd monitor cmds do not show up any longer but that !loadcore still works.

    Integration Instructions

    Upgrade to the latest UefiExt release to ensure the UefiExt GCD command is available.

      </blockquote>
      <hr>
    </details>
    
  • Drop abi\_x86\_interrupt Unstable Feature @os-d (#1478)
    Change Details
      ## Description

    The need for this feature was dropped in f0132a3, however, the feature was not removed. Remove it.

    Closes #812

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

    How This Was Tested

    N/A.

    Integration Instructions

    N/A.

      </blockquote>
      <hr>
    </details>
    
  • Updated EFI\_CPU\_ARCH\_PROTOCOL to provide DmaBufferAlignment @rogurr (#1468)
    Change Details
      * Updated CPU trait to provide cache granule size * Added granule size reporting to x86, arm, and stub components * Updated publishing of CPU architecture protocol to include granule size.

    Description

    Addressing Issue #1466

    Current Behavior: The code file patina_dxe_core\src\cpu\cpu_arch_protocol.rs is publishing an EFI_CPU_ARCH_PROTOCOL that has a field called DmaBufferAlignment to provide the size, in bytes, of the alignment required for DMA buffer allocations which is currently publishing a byte size of 0. The value should be the largest cache line size of any cache in the system per the UEFI PI spec, version 1.9, section II-12.3.1.

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

    How This Was Tested

    Found bug when porting Patina to a private build chipset reference and attempting to instantiate the NVME.

    Integration Instructions

    N/A

      </blockquote>
      <hr>
    </details>
    
  • Components: Print Before Dispatching Components @os-d (#1473)
    Change Details
      ## Description

    Currently, Patina only prints after dispatching a component. However, it is more valuable in debug logs to print before dispatching a component so that if it crashes or hangs, it is easy to tell from the log which component it was.

    This changes Patina to print before dispatching a component and to drop the print that prints after dispatching a component if it successfully returns and only log/debug_assert if the component returns with a failure.

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

    How This Was Tested

    Running Q35 and seeing the dispatch print occur before the component is dispatched:

    image

    and seeing the failure print/debug_assert when a component fails:

    image

    Previously this was seen:

    image

    Integration Instructions

    N/A.

      </blockquote>
      <hr>
    </details>
    

🐛 Bug Fixes

  • patina\_performance: Log cross-module phase markers @cfernald (#1476)
    Change Details
      ## Description

    The current implement does not log the cross-module markers for the transitions
    from PEI to DXE. In EDK2, these are logged by the DXE Core. Here we need
    to do this from the component because it initializes the underlying
    functionality. This is not ideal, but it is the best we can do without
    merging the performance component into the core.

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

    How This Was Tested

    Dumped the performance data using dp in the shell

    Integration Instructions

    N/A

      </blockquote>
      <hr>
    </details>
    

📖 Documentation Updates

  • [REBASE \& FF] Move Architectural Interfaces to SDK @os-d (#1475)
    Change Details
      ## Description

    This contains three commits:

    Drop x86_64 crate

    Patina has light usage of the x86_64 crate and the main usage is for the IDT and GDT, where a different, simplified design is desired.

    This updates all consumers to not use the crate and drops the crate.

    Use Standard Exception Handler for #DF

    Currently, a feature from x86_64 was being used to have special handling for a double fault. However, this is not required as we can use our standard exception handler and identify this is a double fault.

    This commit drops use of the feature and instead handles the #DF as we normally do.

    Move Architectural Interfaces to SDK's Arch Mod

    Centralize architectural interfaces in the SDK instead of sprinkling them around the code.

    As a result, the aarch64-cpu crate is no longer required.

    This also fixes hyperlinks in the copilot-instructions.md doc.

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

    How This Was Tested

    Booting to Windows and Linux on Q35 and SBSA. Booting to Windows on a physical Intel device. On Q35 and the physical Intel device, connecting the debugger to confirm the IDT changes are working correctly.

    Tested the #DF changes by generating a double fault on Q35 and a physical Intel platform by changing RSP to a bad value then generating a #PF.

    Integration Instructions

    N/A.




Full Changelog: patina-v21.0.2...v21.0.3

patina-v21.0.2

22 Apr 15:30

Choose a tag to compare

What's Changed

  • patina\_internal\_cpu: Remove redundant architecture cfg gates @makubacki (#1471)
    Change Details
      ## Description

    The aarch64 and x64 modules are already gated by target_arch at the parent module level, so the inner #[cfg(all(not(test), target_arch = "aarch64/x86_64"))] checks simplify to just #[cfg(not(test))].

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

    How This Was Tested

    • cargo make all

    Integration Instructions

    • N/A


  • Add AI code review customization files [Rebase \& FF] @makubacki (#1460)
    Change Details
      ## Description

    Closes #1453

    Adds project-level AI customization files to support AI-assisted code review.

    These files encode Patina's domain-specific conventions so that AI reviewers can flag violations locally, prior to human review.

    The files are layered:

    1. Always-on instructions (.github/copilot-instructions.md): Covers global conventions across the codebase.

    2. File-based instructions (.github/instructions/): Currently, provides component-specific instructions in components.instructions.md(applyTo: components/**) to supplement the global instructions. These load only when editing matching files to minimize token cost.

    3. Review prompt file (.github/prompts/review.prompt.md): A reusable /review slash command that defines a structured review checklist. This is to provide a convenient way to reliably perform the same set of review steps. Delegates convention details to the always-on instructions to avoid duplication.

    4. Reviewer agent (.github/agents/reviewer.agent.md): A read-only review persona restricted to search and read tool sets (no edit or execute tools). Includes a handoff to the default agent for implementing fixes after review.

    References:

    How This Was Tested

    • Use the "Patina Code Reviewer" locally

    Integration Instructions

    • N/A

    This PR is in draft as it serves as a starting open to changes from others before publishing for broader review.




  • Safety \& UB Updates [Rebase \& FF] @makubacki (#1470)
    Change Details
      ## Description

    Fixes some safety and undefined behavior (UB) issues.

    Reported by Claude with a UB/safety focused prompt. Manually filtered out less severe issues, false positives, and made fixes.


    boot_services: Fix UB in create_event_ex() Option transmute

    create_event_ex() transmuted Option to extern fn, dropping
    the Option wrapper. Passing None would produce a null function pointer
    typed as fn(...) which is instant UB since fn pointers are guaranteed
    non-null.

    Align create_event_ex() with create_event() by preserving the Option
    wrapper through the transmute chain. Update create_event_ex_unchecked()
    to accept Option matching create_event_unchecked().


    patina_dxe_core: Fix TplGuard Deref lifetime unsoundness

    TplGuard's Deref and DerefMut returned references with the mutex's
    lifetime ('a) instead of the guard's lifetime. This allowed extracting
    references that outlive the guard, accessing mutex-protected data
    without the lock held.

    Tie the returned reference lifetime to &self (the guard) instead of
    'a (the mutex), matching the correct pattern used in sdk/patina's
    TplMutexGuard.


    patina_macro: Reject records without #[string_pool] at compile time

    The SmbiosRecordStructure trait requires string_pool_mut() to return
    &mut Vec. Records without a #[string_pool] field previously
    used a static mut Vec which was mutable aliasing UB.

    Replace with a compile-time error requiring all records to declare a
    #[string_pool] field for trait conformance, even if never populated.
    This makes the invalid state unrepresentable rather than deferring to
    runtime.


    patina_sdk: Replace unreachable_unchecked() with unreachable in Service Deref

    The downcast failure path used unreachable_unchecked() which is UB if
    reached. While all intended construction paths guarantee correct types,
    the public From<&'static dyn Any> impl accepts any dyn Any, creating a
    reachable path to UB. Replace with unreachable! which provides a safe
    panic with a diagnostic message if the invariant is ever violated.


    boot_services: Use NonNull::dangling for ZST protocol references

    The ZST protocol path returned &'static mut T from a shared static (),
    creating aliasing &mut references across concurrent callers.

    Use NonNull::dangling() instead, which gives each caller a unique
    aligned pointer without shared state.


    runtime: Use raw pointers for linked list manipulation to avoid aliasing

    When the runtime image/event lists are empty, the previous code created
    two &mut references to the same image_head/event_head field on the same
    line.

    Follow the advice in https://rust-unofficial.github.io/too-many-lists/fifth-stacked-borrows.html#managing-stacked-borrows
    and use pointers with addr_of_mut! throughout the list code.


    fv: Use checked arithmetic for FV read address calculation

    saturating_add() silently produces usize::MAX on overflow instead of
    returning an error. A malformed FV with large LBA values could trigger
    this, leading to a wild pointer in from_raw_parts().

    Switch to checked_add and propagate InvalidParameter on overflow.


    fw_fs: Use read_unaligned() for FV header parsing from byte buffer

    The byte buffer has alignment 1 but fv::Header contains u32/u64 fields
    requiring higher alignment. Creating a reference via &*(ptr as *const
    fv::Header) is UB on unaligned data.

    Use ptr::read_unaligned() to safely copy the header out of the buffer,
    matching the approach used in patina_ffs.


    hob_list: Guard against zero-length or overflowing HOB entries

    A malformed HOB with length 0 causes an infinite loop, and a very
    large length can wrap the pointer on 32-bit targets. Break out of
    the parsing loop if the length is too small to contain a HOB header
    or if the pointer addition overflows.


    patina_mm: Use read_unaligned() for communicate buffer header parsing

    The communicate buffer header fields were read with ptr::read() which
    requires aligned pointers. The buffer comes from firmware memory that
    may not be aligned to BinaryGuid or usize requirements depending on
    the platform. Switch to ptr::read_unaligned() to be correct regardless
    of alignment.


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

    How This Was Tested

    • cargo make all

    Integration Instructions

    • N/A


  • Project convention updates [Rebase \& FF] @makubacki (#1469)
    Change Details
      ## Description

    A few miscellaneous changes to update code not complying with the project instructions in #1460.


    patina_stacktrace: Replace mod.rs with named module files

    Move x64/mod.rs to x64.rs and aarch64/mod.rs to aarch64.rs to follow
    the project convention of using named module files instead of mod.rs.


    patina_mm: Replace mod.rs in integration test with a named module file

    Rename mod.rs to tests_root.rs and update the test entry point to use
    a #[path] attribute redirect, eliminating mod.rs while preserving the
    existing module hierarchy and crate-level import paths.


    Replace unwrap() with expect() in a few locations

    We prefer expect() in production code to provide more context in the
    event of an error.

    Add descriptive messages to unwrap() calls in:

    • rbt.rs: RBT rebalancing where sibling/parent nodes are guaranteed
      to exist by the algorithm invariants
    • x64/runtime_function.rs: PE .pdata chunk reads validated by
      preceding size checks
    • aarch64/runtime_function.rs: same pattern for AArch64 .pdata parsing

    components: Enforce missing_docs lint in all component crates

    Add #![deny(missing_docs)] to component crate lib.rs files to enforce
    documentation requirements on public items.


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

    How This Was Tested

    • cargo make all

    Integration Instructions

    • N/A


  • Update rand crate dev dependency @cfernald (#1464)
    Change Details
    &...
Read more

patina-v21.0.1

01 Apr 23:08
74c7aff

Choose a tag to compare

What's Changed

  • [patina\_mm] refactor current folder structure to allow external consumption @kuqin12 (#1413)
    Change Details
      ## Description

    Current patina_mm carries some definitions that can be shared by external users (mm communication header, buffer status, etc).

    This change moves those files to a sub-module that does not require alloc.

    It also separates the supervisor related definitions into its own file.

    Resolves #1437.

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

    How This Was Tested

    This was tested with local builds and booted to UEFI shell.

    Integration Instructions

    N/A




📖 Documentation Updates

  • Add unsafe CPUID support for Rust `<=1.93` Toolchains @kouchekiniad (#1448)
    Change Details
      ## Description

    This change adds unsafe { } wrappers around the patina_dxe_core's use of __cpuid, adding back support for Rust <= 1.93 toolchains where these are considered unsafe calls. To prevent warnings about these wrappers being unnecessary on Rust >= 1.94 (or >= nightly-2025-12-27) toolchains, this change additionally adds #[allow(unused_unsafe)] declarations to the wrappers.

    This change additionally updates the patina-mtrr dependency to a version which adds these same wrappers to it's own usage.

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

    How This Was Tested

    Built x86_64 Patina binaries successfully with Rust 1.93 and Rust 1.94 toolchains.

    Integration Instructions

    N/A




Full Changelog: patina-v21.0.0...v21.0.1

patina-v21.0.0

31 Mar 17:40

Choose a tag to compare

What's Changed

⚠️ Breaking Changes

  • [CHERRY-PICK] Merge major branch into main @Javagedes (#1445)
    Change Details
      ## Description

    Cherry-pick of breaking changes from major branch into main.

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

    How This Was Tested

    N/A

    Integration Instructions

    Refer to Integration notes for:

    #1430




  • [CHERRY-PICK] Merge major branch into main. @Javagedes (#1440)
    Change Details
      ## Description

    Cherry-pick of breaking changes from major branch into main.

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

    How This Was Tested

    N/A

    Integration Instructions

    Refer to Integration notes for:

    #1324
    #1377

      </blockquote>
      <hr>
    </details>
    

📖 Documentation Updates

  • Update synchronization documentation. @joschock (#1439)
    Change Details
      ## Description

    Cleans up and clarifies some elements of existing docs, adds a new section for rules of thumb for synchronization within Patina.

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

    How This Was Tested

    Passes md lint.

    Integration Instructions

    N/A - documentation.




  • [CHERRY-PICK] Merge major branch into main. @Javagedes (#1440)
    Change Details
      ## Description

    Cherry-pick of breaking changes from major branch into main.

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

    How This Was Tested

    N/A

    Integration Instructions

    Refer to Integration notes for:

    #1324
    #1377

      </blockquote>
      <hr>
    </details>
    

Full Changelog: patina-v20.1.3...v21.0.0

patina-v20.1.3

27 Mar 20:39

Choose a tag to compare

What's Changed

  • pecoff: Miscellaneous fixes/updates for load\_resource\_section [Rebase \& FF] @makubacki (#1431)
    Change Details
      ## Description

    pecoff: Fix resource string offset and UTF-16LE comparison

    The HII string lookup in load_resource_section calculated the string
    data offset as name_offset + 1, but DirectoryString has a
    2-byte length field (followed by the string data), so the correct
    offset is name_offset + sizeof(DirectoryString).

    "Resource Directory String" is defined here in the PE/COFF spec:

    https://learn.microsoft.com/windows/win32/debug/pe-format#resource-directory-string

    The comparison constant used was [0x00, 0x48, 0x00, 0x49, 0x00, 0x49]
    which matched the shifted byte sequence from the wrong offset instead
    of the correct UTF-16LE bytes for "HII" which is:
    [0x48, 0x00, 0x49, 0x00, 0x49, 0x00].


    pecoff: Advance iteration in resource directory parsing

    Today, the code in load_resource_section iterates the number of
    named entry times but doesn't actually update the directory_entry
    to the offset for the current iteration. This change makes that
    adjustment.

    This worked before because images with HII resource sections either
    had a sinlge section or the HII section was the first section.

    I couldn't find any existing images that have more than one resource
    directory entry, so I had to create a simple section with two entries
    in the unit test.


    pecoff: Prevent potential overflow in load_resource_section

    Since resource_directory_string.length is a u16, a .length
    value of > 32767 could cause an overflow when multiplied by 2
    since the multiplication done before the cast to usize.

    This change updates the code to perform the multiplication after the
    cast to usize which is the type the result is assigned to
    (the type of name_end_offset).


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

    How This Was Tested

    • cargo make all
    • Q35 and SBSA boot to EFI shell

    Integration Instructions

    • N/A


  • [patina\_internal\_cpu] remove alloc usage @kuqin12 (#1423)
    Change Details
      ## Description

    Patina internal CPU hosts the interrupt manager and other fundamental functionalities, which should not work on top of the allocator.

    Admittedly, the current crate can support more advanced components that works on top of exception forwarding, but this should not be treated as a required dependency.

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

    How This Was Tested

    This was tested on QEMU Q35 and booted to UEFI shell.

    Integration Instructions

    N/A

      </blockquote>
      <hr>
    </details>
    
  • patina\_dxe\_core: Add DxeDispatch service for driver dispatch @kat-perez (#1421)
    Change Details
      ## Description

    Add a DxeDispatch service trait in the SDK and a CoreDxeDispatch
    implementation in patina_dxe_core that delegates to the PI dispatcher.
    The service is registered alongside other core services (MemoryManager,
    PerfTimer, etc.) and consumed via dependency injection by components
    that need to trigger driver dispatch passes.

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

    How This Was Tested

    • Built SBSA DXE core binary with BootDispatcher + SimpleBootManager consuming the service via DI
    • Booted Windows ARM64 under QEMU SBSA-ref with Patina BDS handling the full boot flow
    • Connect-dispatch interleaving discovered AHCI device, expanded partial device path, loaded Windows bootloader, ExitBootServices completed
    • 106 on-system unit tests passed (0 fails)

    Integration Instructions

    The DxeDispatch service is registered automatically by the DXE core.
    Components consume it via dependency injection:

    fn entry_point(self, dxe_dispatch: Service<dyn DxeDispatch>) -> Result<()> {
        dxe_dispatch.dispatch()?;
        Ok(())
    }
      </blockquote>
      <hr>
    </details>
    
  • patina\_mm: Make MmCommunicator::mm\_executor non-dyn [Rebase \& FF] @makubacki (#1428)
    Change Details
      ## Description

    Two commits to address backlog issues.


    patina_mm: Drop communicator pointer

    Removes the communicator pointer from the ProtocolNotifyContext
    struct and referencing code. This pointer has not been used since a
    refactor and is only used for a debug print.


    patina_mm: Make MmCommunicator::mm_executor non-dyn

    Closes #874

    Replaces Box<dyn MmExecutor> with a generic type parameter
    (E: MmExecutor + 'static) that defaults to RealMmExecutor. This
    keeps the expected default executor for non-test scenarios while
    allowing test code to specify other executor types without needing
    to box them.

    Generic methods (e.g. with_executor() and set_test_comm_buffers())
    are split into a separate impl<E> block since #[component] applies
    to the default-type impl only. Debug and MmCommunication impls are
    similarly updated to be generic over E.

    Unit and integration tests now use concrete executor types directly
    instead of boxing them.


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

    How This Was Tested

    • cargo make all
    • QEMU Q35 boot to EFI shell using patina_mm components

    Integration Instructions

    • Review the changes to the MmCommunicator public structure to determine if any code that might be using it needs to be updated.

    Note: This is not being marked as a breaking change per Patina "semantic preserving" guidelines.




  • perf: Simplify generic type parameters in performance entry points @makubacki (#1426)
    Change Details
      ## Description

    Closes #750

    Reduces the number of generic type parameters in performance component functions by dropping the BB/B and RR/R indirection pattern.

    That pattern used a wrapper type (BB: AsRef<B>) alongside its underlying trait (B: BootServices). The AsRef indirection is not needed since StandardBootServices and MockBootServices both implement BootServices + Clone.

    Generic reductions:

    • _entry_point() from 6 generics (BB, B, RR, R, P, F) to 4 (B, R, P, F)
    • report_fbpt_record_buffer() from 5 generics (BB, B, RR, R, F) to 3 (B, R, F)
    • fetch_and_add_mm_performance_records() from 3 generics (BB, B, F) to 2 (B, F)
    • MmPerformanceEventContext() from 3 generics (BB, B, F) to 2 (B, F)

    Also:

    • Replaces .as_ref().method() calls with direct .method() calls
    • Replaces BB::clone(&x) with x.clone()
    • Removes Rc wrapping from performance tests

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

    How This Was Tested

    • cargo make all
    • Q35 boot with performance component enabled

    Integration Instructions

    • N/A

    Note: This is to close an old backlog item as mentioned in the link GitHub issue.




  • .github: Pass head-sha to QEMU validation workflows @makubacki (#1425)
    Change Details
      ## Description

    A new head-sha input parameter was added to the QEMU validation workflows. This allows the workflow to have access to the head SHA of the PR, which is useful for applying status check results.

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

    How This Was Tested

    • patina fork

    Integration Instructions

    • N/A - Only impacts local workflows in repo CI

      </blockquote>
      <hr>
      
  • .github: Add integration changes for PR validation status check @makubacki (#1424)
    Change Details
      ## Description

    Contributes to OpenDevicePartnership/patina-devops#108

    Passes head-sha and conclusion args to the QEMU post-processing workflow.

    This allows the post-processing workflow to set commit status including cases like when the workflow is cancelled.

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

    How This Was Tested

    • Run success...
Read more