[U-Boot] [PATCH 1/2] efi_loader: EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE
Heinrich Schuchardt
xypron.glpk at gmx.de
Sat Jul 13 06:05:41 UTC 2019
Implement the EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.
This requires allocating the event and the event list from runtime data.
Signed-off-by: Heinrich Schuchardt <xypron.glpk at gmx.de>
---
lib/efi_loader/efi_boottime.c | 25 +++++++++++++++++++------
lib/efi_loader/efi_runtime.c | 14 ++++++++++++--
2 files changed, 31 insertions(+), 8 deletions(-)
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index c2f89805c7..62e4994671 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -25,7 +25,7 @@ static efi_uintn_t efi_tpl = TPL_APPLICATION;
LIST_HEAD(efi_obj_list);
/* List of all events */
-LIST_HEAD(efi_events);
+__efi_runtime_data LIST_HEAD(efi_events);
/* List of queued events */
LIST_HEAD(efi_event_queue);
@@ -650,6 +650,8 @@ efi_status_t efi_create_event(uint32_t type, efi_uintn_t notify_tpl,
struct efi_event **event)
{
struct efi_event *evt;
+ efi_status_t ret;
+ int pool_type;
if (event == NULL)
return EFI_INVALID_PARAMETER;
@@ -662,7 +664,10 @@ efi_status_t efi_create_event(uint32_t type, efi_uintn_t notify_tpl,
case EVT_NOTIFY_WAIT:
case EVT_TIMER | EVT_NOTIFY_WAIT:
case EVT_SIGNAL_EXIT_BOOT_SERVICES:
+ pool_type = EFI_BOOT_SERVICES_DATA;
+ break;
case EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE:
+ pool_type = EFI_RUNTIME_SERVICES_DATA;
break;
default:
return EFI_INVALID_PARAMETER;
@@ -672,9 +677,11 @@ efi_status_t efi_create_event(uint32_t type, efi_uintn_t notify_tpl,
(!notify_function || is_valid_tpl(notify_tpl) != EFI_SUCCESS))
return EFI_INVALID_PARAMETER;
- evt = calloc(1, sizeof(struct efi_event));
- if (!evt)
- return EFI_OUT_OF_RESOURCES;
+ ret = efi_allocate_pool(pool_type, sizeof(struct efi_event),
+ (void **)&evt);
+ if (ret != EFI_SUCCESS)
+ return ret;
+ memset(evt, 0, sizeof(struct efi_event));
evt->type = type;
evt->notify_tpl = notify_tpl;
evt->notify_function = notify_function;
@@ -982,7 +989,7 @@ static efi_status_t EFIAPI efi_close_event(struct efi_event *event)
list_del(&event->queue_link);
list_del(&event->link);
- free(event);
+ efi_free_pool(event);
return EFI_EXIT(EFI_SUCCESS);
}
@@ -1932,7 +1939,7 @@ static void efi_exit_caches(void)
static efi_status_t EFIAPI efi_exit_boot_services(efi_handle_t image_handle,
efi_uintn_t map_key)
{
- struct efi_event *evt;
+ struct efi_event *evt, *next_event;
efi_status_t ret = EFI_SUCCESS;
EFI_ENTRY("%p, %zx", image_handle, map_key);
@@ -1971,6 +1978,12 @@ static efi_status_t EFIAPI efi_exit_boot_services(efi_handle_t image_handle,
/* Notify variable services */
efi_variables_boot_exit_notify();
+ /* Remove all events except EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE */
+ list_for_each_entry_safe(evt, next_event, &efi_events, link) {
+ if (evt->type != EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE)
+ list_del(&evt->link);
+ }
+
board_quiesce_devices();
/* Patch out unsupported runtime function */
diff --git a/lib/efi_loader/efi_runtime.c b/lib/efi_loader/efi_runtime.c
index 94765569b6..9f4ba2f977 100644
--- a/lib/efi_loader/efi_runtime.c
+++ b/lib/efi_loader/efi_runtime.c
@@ -391,8 +391,10 @@ efi_status_t __weak __efi_runtime EFIAPI efi_set_time(struct efi_time *time)
*/
static bool efi_is_runtime_service_pointer(void *p)
{
- return p >= (void *)&efi_runtime_services.get_time &&
- p <= (void *)&efi_runtime_services.query_variable_info;
+ return (p >= (void *)&efi_runtime_services.get_time &&
+ p <= (void *)&efi_runtime_services.query_variable_info) ||
+ p == (void *)&efi_events.prev ||
+ p == (void *)&efi_events.next;
}
/**
@@ -577,6 +579,7 @@ static efi_status_t EFIAPI efi_set_virtual_address_map(
int n = memory_map_size / descriptor_size;
int i;
int rt_code_sections = 0;
+ struct efi_event *event;
EFI_ENTRY("%lx %lx %x %p", memory_map_size, descriptor_size,
descriptor_version, virtmap);
@@ -610,6 +613,13 @@ static efi_status_t EFIAPI efi_set_virtual_address_map(
return EFI_EXIT(EFI_INVALID_PARAMETER);
}
+ /* Notify EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE */
+ list_for_each_entry(event, &efi_events, link) {
+ if (event->notify_function)
+ EFI_CALL_VOID(event->notify_function(
+ event, event->notify_context));
+ }
+
/* Rebind mmio pointers */
for (i = 0; i < n; i++) {
struct efi_mem_desc *map = (void*)virtmap +
--
2.20.1
More information about the U-Boot
mailing list