patina-v16.0.0
What's Changed
-
PE Image Load: Include image name on failure @vineelko (#1069)
Change Details
## Description
PE Image Load: Include image name on failure
- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
Validated on Q35
Integration Instructions
NA
-
patina\_debugger: Switch breakpoint to be conditional @cfernald (#1087)
Change Details
## Description
The breakpoint always causing an exception may not be well understood and could lead to people leaving breakpoints in production code causing unexpected exceptions. This commit changes the existing
breakpointfunction to only trigger a breakpoint if the debugger is enabled, and renames the existingbreakpointfunction tobreakpoint_uncheckedto indicate that it will always trigger a breakpoint regardless of the debugger state.- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
Unit tests
Integration Instructions
N/A
</blockquote> <hr> </details>
-
Resolve issues with compiling on aarch64 hosts @cfernald (#1089)
Change Details
## Description
- Resolves non-comprehensive conditional compilation causing compilation errors on aarch64 hosts for test.
- Disables testing failing on aarch64 hosts due to issue #1071.
- Fixes compiler warnings due to unused includes in aarch64 test compilation.
- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
CI tested
Integration Instructions
N/A
</blockquote> <hr> </details>
⚠️ Breaking Changes
-
[REBASE\&FF] Move the `Core` to be 'static for the platform binary @Javagedes (#1049)
Change Details
## Description
This pull request implements the major breaking changes that will be introduced as a part of RFC #22. Overall, this pull request does the following things:
- This commit moves platform configuration of the core into the
PlatformInfotrait. This trait has multiple type associations for
configuring the different subsystems of the core. As of this commit
the following type associations exist:ComponentInfoused to attach and configure patina components to
be dispatched by the core.CpuInfoused to configure cpu releated functionality such as the
GIC Bases for AARCH64 systems.MemoryInfoused to configure memory related functionality such as
prioritizing 32 bit memory allocations.
- It requires the core to be
staticwithin the platform binary and simplifies the initialization process for the platform. - Updates all documentation to reflect the new interface
Side Effects
Due to the changes listed above, there are some minor side effects that have occurred:
- Initialization of the advanced logger (To get the address) is now implemented on the Logger itself, and not the component (and renamed to
init). - Patina component dispatch has been moved into its own subsystem with its own TPL Mutex
- The
Decompresstrait is no longer a service but rather specified as an associated type by thePlaformtrait.SectionExtractorNullhas been added back. GicBasesis no longer a config, but a requiredPlatformtrait method for AARCH64 systems that will cause a compilation error if not provided- The timer frequency is no longer a config, but an optional
Platformtrait method.
Reference Q35 / SBSA implementation: OpenDevicePartnership/patina-dxe-core-qemu#74
- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
Boot to Shell on Q35, SBSA
Integration Instructions
PlatformInfotraitPlatforms must now implement the
PlatformInfotrait which describes the platform customizations for the Core. This trait has multiple type associations to provide customizations to the different subsystems of the core. They can be implemented on the same type (example below), or implemented on separate types to support re-use for different platforms. See below:use patina_dxe_core::*; use patina_adv_logger::components struct Q35; impl ComponentInfo for Q35 { fn components(mut add: Add<Component>) { add.component(q35_services::mm_config_provider::MmConfigurationProvider); add.component(q35_services::mm_control::QemuQ35PlatformMmControl::new()); add.component(patina_mm::component::sw_mmi_manager::SwMmiManager::new()); } fn configs(mut add: Add<Config>) { add.config(patina_mm::config::MmCommunicationConfiguration { acpi_base: patina_mm::config::AcpiBase::Mmio(0x0), // Actual ACPI base address will be set during boot cmd_port: patina_mm::config::MmiPort::Smi(0xB2), data_port: patina_mm::config::MmiPort::Smi(0xB3), comm_buffers: vec![], }); } } impl MemoryInfo for Q35 { } impl CpuInfo for Q35 { } impl Platform for Q35 { type MemoryInfo = Self; type ComponentInfo = Self; type CpuInfo = Self; type Extractor = CompositeSectionExtractor; }
Coremust now be 'staticThe core must now be initialized as a static. Its interface has now also changed. Building off the above example, you would add:
static CORE: Core<Q35> = Core::new(CompositeSectionExtractor::new()); #[cfg_attr(target_os = "uefi", unsafe(export_name = "efi_main"))] pub extern "efiapi" fn _start(physical_hob_list: *const c_void) -> ! { CORE.entry_point(physical_hob_list) }
Advanced Logger init changes
The
init_advanced_loggermethod has moved to the static logger struct and is renamed toinit, rather than the component.static LOGGER: AdvancedLogger<Uart16550> = AdvancedLogger::new( Format::Standard, &[ ("goblin", log::LevelFilter::Off), ("gcd_measure", log::LevelFilter::Off), ("allocations", log::LevelFilter::Off), ("efi_memory_map", log::LevelFilter::Off), ], log::LevelFilter::Info, Uart16550::Io { base: 0x402 }, ); #[cfg_attr(target_os = "uefi", unsafe(export_name = "efi_main"))] pub extern "efiapi" fn _start(physical_hob_list: *const c_void) -> ! { // SAFETY: The physical_hob_list pointer is considered valid at this point as it's provided by the core // to the entry point. unsafe { LOGGER.init(physical_hob_list).unwrap(); } log::set_logger(&LOGGER).map(|()| log::set_max_level(log::LevelFilter::Trace)).unwrap(); CORE.entry_point(physical_hob_list) }
</blockquote> <hr> </details> - This commit moves platform configuration of the core into the
🐛 Bug Fixes
-
patina\_dxe\_core: Tests: Fix Intermittent Test Failure @os-d (#1094)
Change Details
## Description
Recent tests added a MockPageTable to the static GCD, but this is not cleaned up on GCD.reset(). As a result, there is a race condition where certain tests that expect there not to be a page table installed in the GCD can fail. This fixes that by removing the page table if installed in GCD.reset().
- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
Had a 100% repro with
cargo testafter this no repro. Confirmed this was the issue under the debugger.Integration Instructions
N/A.
</blockquote> <hr> </details>
📖 Documentation Updates
-
[REBASE\&FF] Move the `Core` to be 'static for the platform binary @Javagedes (#1049)
Change Details
## Description
This pull request implements the major breaking changes that will be introduced as a part of RFC #22. Overall, this pull request does the following things:
- This commit moves platform configuration of the core into the
PlatformInfotrait. This trait has multiple type associations for
configuring the different subsystems of the core. As of this commit
the following type associations exist:ComponentInfoused to attach and configure patina components to
be dispatched by the core.CpuInfoused to configure cpu releated functionality such as the
GIC Bases for AARCH64 systems.MemoryInfoused to configure memory related functionality such as
prioritizing 32 bit memory allocations.
- It requires the core to be
staticwithin the platform binary and simplifies the initialization process for the platform. - Updates all documentation to reflect the new interface
Side Effects
Due to the changes listed above, there are some minor side effects that have occurred:
- Initialization of the advanced logger (To get the address) is now implemented on the Logger itself, and not the component (and renamed to
init). - Patina component dispatch has been moved into its own subsystem with its own TPL Mutex
- The
Decompresstrait is no longer a service but rather specified as an associated type by thePlaformtrait.SectionExtractorNullhas been added back. GicBasesis no longer a config, but a requiredPlatformtrait method for AARCH64 systems that will cause a compilation error if not provided- The timer frequency is no longer a config, but an optional
Platformtrait method.
Reference Q35 / SBSA implementation: OpenDevicePartnership/patina-dxe-core-qemu#74
- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
Boot to Shell on Q35, SBSA
Integration Instructions
PlatformInfotraitPlatforms must now implement the
PlatformInfotrait which describes the platform customizations for the Core. This trait has multiple type associations to provide customizations to the different subsystems of the core. They can be implemented on the same type (example below), or implemented on separate types to support re-use for different platforms. See below:use patina_dxe_core::*; use patina_adv_logger::components struct Q35; impl ComponentInfo for Q35 { fn components(mut add: Add<Component>) { add.component(q35_services::mm_config_provider::MmConfigurationProvider); add.component(q35_services::mm_control::QemuQ35PlatformMmControl::new()); add.component(patina_mm::component::sw_mmi_manager::SwMmiManager::new()); } fn configs(mut add: Add<Config>) { add.config(patina_mm::config::MmCommunicationConfiguration { acpi_base: patina_mm::config::AcpiBase::Mmio(0x0), // Actual ACPI base address will be set during boot cmd_port: patina_mm::config::MmiPort::Smi(0xB2), data_port: patina_mm::config::MmiPort::Smi(0xB3), comm_buffers: vec![], }); } } impl MemoryInfo for Q35 { } impl CpuInfo for Q35 { } impl Platform for Q35 { type MemoryInfo = Self; type ComponentInfo = Self; type CpuInfo = Self; type Extractor = CompositeSectionExtractor; }
Coremust now be 'staticThe core must now be initialized as a static. Its interface has now also changed. Building off the above example, you would add:
static CORE: Core<Q35> = Core::new(CompositeSectionExtractor::new()); #[cfg_attr(target_os = "uefi", unsafe(export_name = "efi_main"))] pub extern "efiapi" fn _start(physical_hob_list: *const c_void) -> ! { CORE.entry_point(physical_hob_list) }
Advanced Logger init changes
The
init_advanced_loggermethod has moved to the static logger struct and is renamed toinit, rather than the component.static LOGGER: AdvancedLogger<Uart16550> = AdvancedLogger::new( Format::Standard, &[ ("goblin", log::LevelFilter::Off), ("gcd_measure", log::LevelFilter::Off), ("allocations", log::LevelFilter::Off), ("efi_memory_map", log::LevelFilter::Off), ], log::LevelFilter::Info, Uart16550::Io { base: 0x402 }, ); #[cfg_attr(target_os = "uefi", unsafe(export_name = "efi_main"))] pub extern "efiapi" fn _start(physical_hob_list: *const c_void) -> ! { // SAFETY: The physical_hob_list pointer is considered valid at this point as it's provided by the core // to the entry point. unsafe { LOGGER.init(physical_hob_list).unwrap(); } log::set_logger(&LOGGER).map(|()| log::set_max_level(log::LevelFilter::Trace)).unwrap(); CORE.entry_point(physical_hob_list) }
</blockquote> <hr> </details> - This commit moves platform configuration of the core into the
-
patina: test: Add test on event callback support @Javagedes (#927)
Change Details
Please Note: This PR is finished, and ready for review, however this is marked as draft, as some tests are disabled until RFC 0017 is completed.
Description
adds a new attribute for the
#[patina_test]attribute macro that allows the user to specify a UEFI event that the test should be executed on. When the UEFI event callback is fired, the patina_test will be executed.This new attribute is
#[on(event= <REAL_GUID>)]e.g.#[on(event = r_efi::efi::EVENT_GROUP_READY_TO_BOOT)].After this change, not all patina_tests are executed immediately during the
TestRunnercomponent. Due To this, test result reporting is delayed to two separate event callbacks. Test results are now reported once at READY_TO_BOOT and once at EXIT_BOOT_SERVICES.The
fail_fastconfig feature has been removed. This is because not all tests happen within the control of theTestRunnercomponent, and thus cannot fail if it wanted to. Instead, an optional callback can be registered by the platform to handle an error however the platform prefers, that is executed anytime a test fails.Example Test reporting:
INFO - INFO - Patina on-system unit-test results: INFO - patina_adv_logger::integration_test::adv_logger_test ... ok (1 passes) INFO - patina_dxe_core::memory_manager::memory_manager_allocations_test ... ok (1 passes) INFO - patina_dxe_core::memory_manager::memory_manager_attributes_test ... ok (1 passes) INFO - qemu_q35_dxe_core::my_test ... ok (413 passes) INFO - qemu_q35_dxe_core::ready_to_boot_test ... ok (1 passes)- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
Boot to QEMUQ35 with various tests that use the event callback logic.
Integration Instructions
- Developers can now edit or write patina_tests that use the newly created attribute macro. This attribute macro allows you to specify an event guid to have your test executed on. Example seen below. Please note that if an invalid guid is provided, or the event never fires, the test results will report the test as "not triggered"
#[patina_test] #[on(event = r_efi::efi::EVENT_GROUP_READY_TO_BOOT)] fn my_patina_test() -> Result { Ok(()) }
- Developers can now register a callback function that is executed if a test fails
let component = TestRunner::default().with_callback(|test_name, err_msg| { panic!("{test_name} errored with result {err_msg}); });
- Remove any configuration of
fail_faste.g.fail_fast(...). Replace with custom error handling when a patina test fails with.with_callback(fn(&'static str, &'static str))
Full Changelog: patina-v15.1.0...v16.0.0