[PATCH 0/3] efi_loader: EFI_EVENT_GROUP_BEFORE_EXIT_BOOT_SERVICES

* implement EFI_EVENT_GROUP_BEFORE_EXIT_BOOT_SERVICES * provide a unit test for it * bump supported UEFI specification number to 2.9
Heinrich Schuchardt (3): efi_loader: EFI_EVENT_GROUP_BEFORE_EXIT_BOOT_SERVICES efi_selftest: unit test for EFI_GROUP_BEFORE_EXIT_BOOT_SERVICE efi_loader: bump EFI_SPECIFICATION_VERSION to 2.9
include/efi_api.h | 13 +++- lib/efi_loader/efi_boottime.c | 13 ++++ .../efi_selftest_exitbootservices.c | 65 +++++++++++++++---- 3 files changed, 78 insertions(+), 13 deletions(-)

Implement the EFI_EVENT_GROUP_BEFORE_EXIT_BOOT_SERVICES event group handling.
Add the definition of EFI_EVENT_GROUP_AFTER_READY_TO_BOOT.
Signed-off-by: Heinrich Schuchardt heinrich.schuchardt@canonical.com --- include/efi_api.h | 9 +++++++++ lib/efi_loader/efi_boottime.c | 13 +++++++++++++ 2 files changed, 22 insertions(+)
diff --git a/include/efi_api.h b/include/efi_api.h index 0accad08c8..bba2f8144a 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -360,10 +360,15 @@ struct efi_runtime_services { };
/* EFI event group GUID definitions */ + #define EFI_EVENT_GROUP_EXIT_BOOT_SERVICES \ EFI_GUID(0x27abf055, 0xb1b8, 0x4c26, 0x80, 0x48, \ 0x74, 0x8f, 0x37, 0xba, 0xa2, 0xdf)
+#define EFI_EVENT_GROUP_BEFORE_EXIT_BOOT_SERVICES \ + EFI_GUID(0x8be0e274, 0x3970, 0x4b44, 0x80, 0xc5, \ + 0x1a, 0xb9, 0x50, 0x2f, 0x3b, 0xfc) + #define EFI_EVENT_GROUP_VIRTUAL_ADDRESS_CHANGE \ EFI_GUID(0x13fa7698, 0xc831, 0x49c7, 0x87, 0xea, \ 0x8f, 0x43, 0xfc, 0xc2, 0x51, 0x96) @@ -376,6 +381,10 @@ struct efi_runtime_services { EFI_GUID(0x7ce88fb3, 0x4bd7, 0x4679, 0x87, 0xa8, \ 0xa8, 0xd8, 0xde, 0xe5, 0x0d, 0x2b)
+#define EFI_EVENT_GROUP_AFTER_READY_TO_BOOT \ + EFI_GUID(0x3a2a00ad, 0x98b9, 0x4cdf, 0xa4, 0x78, \ + 0x70, 0x27, 0x77, 0xf1, 0xc1, 0xb) + #define EFI_EVENT_GROUP_RESET_SYSTEM \ EFI_GUID(0x62da6a56, 0x13fb, 0x485a, 0xa8, 0xda, \ 0xa3, 0xdd, 0x79, 0x12, 0xcb, 0x6b) diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index 1823990d9b..6fdd0ef77a 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -71,6 +71,9 @@ const efi_guid_t efi_guid_driver_binding_protocol = /* event group ExitBootServices() invoked */ const efi_guid_t efi_guid_event_group_exit_boot_services = EFI_EVENT_GROUP_EXIT_BOOT_SERVICES; +/* event group before ExitBootServices() invoked */ +const efi_guid_t efi_guid_event_group_before_exit_boot_services = + EFI_EVENT_GROUP_BEFORE_EXIT_BOOT_SERVICES; /* event group SetVirtualAddressMap() invoked */ const efi_guid_t efi_guid_event_group_virtual_address_change = EFI_EVENT_GROUP_VIRTUAL_ADDRESS_CHANGE; @@ -2123,6 +2126,16 @@ static efi_status_t EFIAPI efi_exit_boot_services(efi_handle_t image_handle, 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 && + !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 a test for the EFI_GROUP_BEFORE_EXIT_BOOT_SERVICE event group.
Signed-off-by: Heinrich Schuchardt heinrich.schuchardt@canonical.com --- .../efi_selftest_exitbootservices.c | 67 ++++++++++++++++--- 1 file changed, 56 insertions(+), 11 deletions(-)
diff --git a/lib/efi_selftest/efi_selftest_exitbootservices.c b/lib/efi_selftest/efi_selftest_exitbootservices.c index 4fecd1b415..59ab15407a 100644 --- a/lib/efi_selftest/efi_selftest_exitbootservices.c +++ b/lib/efi_selftest/efi_selftest_exitbootservices.c @@ -10,9 +10,34 @@
#include <efi_selftest.h>
+static efi_guid_t guid_before_exit_boot_services = + EFI_GUID(0x8be0e274, 0x3970, 0x4b44, 0x80, 0xc5, + 0x1a, 0xb9, 0x50, 0x2f, 0x3b, 0xfc); +#define CAPACITY 4 + +struct notification_record { + unsigned int count; + unsigned int type[CAPACITY]; +}; + +struct notification_context { + struct notification_record *record; + unsigned int type; +}; + static struct efi_boot_services *boottime; static struct efi_event *event_notify; -static unsigned int notification_count; +struct notification_record record; + +struct notification_context context_before = { + .record = &record, + .type = 1, +}; + +struct notification_context context = { + .record = &record, + .type = 2, +};
/* * Notification function, increments the notification count. @@ -20,11 +45,15 @@ static unsigned int notification_count; * @event notified event * @context pointer to the notification count */ -static void EFIAPI notify(struct efi_event *event, void *context) +static void EFIAPI ebs_notify(struct efi_event *event, void *context) { - unsigned int *count = context; + struct notification_context *ctx = context; + + if (ctx->record->count >= CAPACITY) + return;
- ++*count; + ctx->record->type[ctx->record->count] = ctx->type; + ctx->record->count++; }
/* @@ -43,15 +72,23 @@ static int setup(const efi_handle_t handle,
boottime = systable->boottime;
- notification_count = 0; ret = boottime->create_event(EVT_SIGNAL_EXIT_BOOT_SERVICES, - TPL_CALLBACK, notify, - (void *)¬ification_count, + TPL_CALLBACK, ebs_notify, + &context, &event_notify); if (ret != EFI_SUCCESS) { efi_st_error("could not create event\n"); return EFI_ST_FAILURE; } + ret = boottime->create_event_ex(0, TPL_CALLBACK, ebs_notify, + &context_before, + &guid_before_exit_boot_services, + &event_notify); + if (ret != EFI_SUCCESS) { + efi_st_error("could not create event\n"); + return EFI_ST_FAILURE; + } + return EFI_ST_SUCCESS; }
@@ -68,13 +105,21 @@ static int setup(const efi_handle_t handle, */ static int execute(void) { - if (notification_count != 1) { - efi_st_error("ExitBootServices was not notified\n"); + if (record.count != 2) { + efi_st_error("Incorrect event count %u\n", record.count); + return EFI_ST_FAILURE; + } + if (record.type[0] != 1) { + efi_st_error("EFI_GROUP_BEFORE_EXIT_BOOT_SERVICE not notified\n"); + return EFI_ST_FAILURE; + } + if (record.type[1] != 2) { + efi_st_error("EVT_SIGNAL_EXIT_BOOT_SERVICES was not notified\n"); return EFI_ST_FAILURE; } efi_st_exit_boot_services(); - if (notification_count != 1) { - efi_st_error("ExitBootServices was notified twice\n"); + if (record.count != 2) { + efi_st_error("Incorrect event count %u\n", record.count); return EFI_ST_FAILURE; } return EFI_ST_SUCCESS;

We have implemented all what is new in UEFI specification 2.9 and relevant for U-Boot.
Signed-off-by: Heinrich Schuchardt heinrich.schuchardt@canonical.com --- include/efi_api.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/efi_api.h b/include/efi_api.h index bba2f8144a..276c7a3e85 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -20,8 +20,8 @@ #include <charset.h> #include <pe.h>
-/* UEFI spec version 2.8 */ -#define EFI_SPECIFICATION_VERSION (2 << 16 | 80) +/* UEFI spec version 2.9 */ +#define EFI_SPECIFICATION_VERSION (2 << 16 | 90)
/* Types and defines for EFI CreateEvent */ enum efi_timer_delay {
participants (1)
-
Heinrich Schuchardt