[PATCH v1 52/54] efi: loader: support ExitBootServices
Ahmad Fatoum
a.fatoum at pengutronix.de
Thu Dec 18 02:38:12 PST 2025
With everything now in place, let's support ExitBootServices, so a
kernel can startup and communicate to barebox acting as EFI runtime.
Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
---
efi/loader/boot.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 66 insertions(+), 1 deletion(-)
diff --git a/efi/loader/boot.c b/efi/loader/boot.c
index 29cab7acd1c0..93a3412f5794 100644
--- a/efi/loader/boot.c
+++ b/efi/loader/boot.c
@@ -27,7 +27,9 @@
#include <efi/error.h>
#include <efi/variable.h>
#include <efi/devicepath.h>
+#include <efi/mode.h>
#include <efi/loader/trace.h>
+#include <efi/runtime.h>
#include <malloc.h>
#include <pe.h>
#include <asm/cache.h>
@@ -2049,9 +2051,72 @@ efi_status_t EFIAPI efiloader_load_image(bool boot_policy,
static efi_status_t EFIAPI efi_exit_boot_services(efi_handle_t image_handle,
efi_uintn_t map_key)
{
+ struct efi_event *evt, *next_event;
+ efi_status_t ret = EFI_SUCCESS;
+
EFI_ENTRY("%p, %zx", image_handle, map_key);
- return EFI_EXIT(EFI_UNSUPPORTED);
+ /* Check that the caller has read the current memory map */
+ if (map_key != efi_memory_map_key) {
+ ret = EFI_INVALID_PARAMETER;
+ goto out;
+ }
+
+ /* Check if ExitBootServices has already been called */
+ if (!systab.boottime)
+ goto out;
+
+ /* Notify EFI_EVENT_GROUP_BEFORE_EXIT_BOOT_SERVICES event group. */
+ list_for_each_entry(evt, &efi_events, link) {
+ if (evt->group &&
+ !efi_guidcmp(*evt->group,
+ efi_guid_event_group_before_exit_boot_services)) {
+ efi_signal_event(evt);
+ break;
+ }
+ }
+
+ /* Stop all timer related activities */
+ timers_enabled = false;
+
+ /* Add related events to the event group */
+ list_for_each_entry(evt, &efi_events, link) {
+ if (evt->type == EFI_EVT_SIGNAL_EXIT_BOOT_SERVICES)
+ evt->group = &efi_guid_event_group_exit_boot_services;
+ }
+ /* Notify that ExitBootServices is invoked. */
+ list_for_each_entry(evt, &efi_events, link) {
+ if (evt->group &&
+ !efi_guidcmp(*evt->group,
+ efi_guid_event_group_exit_boot_services)) {
+ efi_signal_event(evt);
+ break;
+ }
+ }
+
+ /* Make sure that notification functions are not called anymore */
+ efi_tpl = EFI_TPL_HIGH_LEVEL;
+
+ /* Remove all events except EFI_EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE */
+ list_for_each_entry_safe(evt, next_event, &efi_events, link) {
+ if (evt->type != EFI_EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE)
+ list_del(&evt->link);
+ }
+
+ /* Patch out unsupported runtime function */
+ efi_runtime_detach(&systab);
+
+ efi_loader_set_state(EFI_LOADER_RUNTIME);
+
+ resched();
+
+ shutdown_barebox();
+
+ /* Give the payload some time to boot */
+ efi_set_watchdog(0);
+out:
+
+ return EFI_EXIT(ret);
}
/**
--
2.47.3
More information about the barebox
mailing list