* [U-Boot] [PATCH 0/5] efi_loader: implement event groups
@ 2018-02-18 14:17 Heinrich Schuchardt
2018-02-18 14:17 ` [U-Boot] [PATCH 1/5] efi_loader: fix formatting errors Heinrich Schuchardt
` (4 more replies)
0 siblings, 5 replies; 8+ messages in thread
From: Heinrich Schuchardt @ 2018-02-18 14:17 UTC (permalink / raw)
To: u-boot
The patch series provides support for event groups. If any event of the
group is signaled all other events are signaled too.
The events are managed in a linked list instead of an array.
Some formatting errors are fixed.
Heinrich Schuchardt (5):
efi_loader: fix formatting errors
efi_loader: manage events in a linked list
efi_loader: define GUIDS for event groups
efi_loader: implement event groups
efi_selftest: unit test for event groups
include/efi_api.h | 21 ++
include/efi_loader.h | 28 ++-
lib/efi_loader/efi_boottime.c | 339 ++++++++++++++++-----------
lib/efi_loader/efi_console.c | 6 +-
lib/efi_loader/efi_net.c | 4 +-
lib/efi_loader/efi_runtime.c | 11 +
lib/efi_loader/efi_watchdog.c | 2 +-
lib/efi_selftest/Makefile | 1 +
lib/efi_selftest/efi_selftest_event_groups.c | 140 +++++++++++
9 files changed, 400 insertions(+), 152 deletions(-)
create mode 100644 lib/efi_selftest/efi_selftest_event_groups.c
--
2.14.2
^ permalink raw reply [flat|nested] 8+ messages in thread
* [U-Boot] [PATCH 1/5] efi_loader: fix formatting errors
2018-02-18 14:17 [U-Boot] [PATCH 0/5] efi_loader: implement event groups Heinrich Schuchardt
@ 2018-02-18 14:17 ` Heinrich Schuchardt
2018-02-18 14:17 ` [U-Boot] [PATCH 2/5] efi_loader: manage events in a linked list Heinrich Schuchardt
` (3 subsequent siblings)
4 siblings, 0 replies; 8+ messages in thread
From: Heinrich Schuchardt @ 2018-02-18 14:17 UTC (permalink / raw)
To: u-boot
Fix formatting errors in efi_boottime.c indicated by
scripts/checkpatch.py.
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
---
lib/efi_loader/efi_boottime.c | 48 +++++++++++++++++++++++--------------------
1 file changed, 26 insertions(+), 22 deletions(-)
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index 15235f6d07..75f7c50295 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -123,6 +123,7 @@ static const char *indent_string(int level)
{
const char *indent = " ";
const int max = strlen(indent);
+
level = min(max, level * 2);
return &indent[max - level];
}
@@ -257,7 +258,7 @@ static efi_status_t EFIAPI efi_free_pages_ext(uint64_t memory,
{
efi_status_t r;
- EFI_ENTRY("%"PRIx64", 0x%zx", memory, pages);
+ EFI_ENTRY("%" PRIx64 ", 0x%zx", memory, pages);
r = efi_free_pages(memory, pages);
return EFI_EXIT(r);
}
@@ -586,7 +587,6 @@ static efi_status_t EFIAPI efi_create_event_ext(
notify_context, event));
}
-
/*
* Check if a timer event has occurred or a queued notification function should
* be called.
@@ -688,7 +688,7 @@ static efi_status_t EFIAPI efi_set_timer_ext(struct efi_event *event,
enum efi_timer_delay type,
uint64_t trigger_time)
{
- EFI_ENTRY("%p, %d, %"PRIx64, event, type, trigger_time);
+ EFI_ENTRY("%p, %d, %" PRIx64, event, type, trigger_time);
return EFI_EXIT(efi_set_timer(event, type, trigger_time));
}
@@ -1264,7 +1264,7 @@ static efi_status_t efi_locate_handle(
/* Count how much space we need */
list_for_each_entry(efiobj, &efi_obj_list, link) {
if (!efi_search(search_type, protocol, search_key, efiobj))
- size += sizeof(void*);
+ size += sizeof(void *);
}
if (*buffer_size < size) {
@@ -1315,7 +1315,7 @@ static efi_status_t EFIAPI efi_locate_handle_ext(
static void efi_remove_configuration_table(int i)
{
struct efi_configuration_table *this = &efi_conf_table[i];
- struct efi_configuration_table *next = &efi_conf_table[i+1];
+ struct efi_configuration_table *next = &efi_conf_table[i + 1];
struct efi_configuration_table *end = &efi_conf_table[systab.nr_tables];
memmove(this, next, (ulong)end - (ulong)next);
@@ -1332,7 +1332,8 @@ static void efi_remove_configuration_table(int i)
* @table table to be installed
* @return status code
*/
-efi_status_t efi_install_configuration_table(const efi_guid_t *guid, void *table)
+efi_status_t efi_install_configuration_table(const efi_guid_t *guid,
+ void *table)
{
int i;
@@ -1638,8 +1639,9 @@ static efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle,
* @return status code
*/
static efi_status_t EFIAPI efi_exit(efi_handle_t image_handle,
- efi_status_t exit_status, unsigned long exit_data_size,
- int16_t *exit_data)
+ efi_status_t exit_status,
+ unsigned long exit_data_size,
+ int16_t *exit_data)
{
/*
* We require that the handle points to the original loaded
@@ -1652,7 +1654,7 @@ static efi_status_t EFIAPI efi_exit(efi_handle_t image_handle,
* TODO: We should call the unload procedure of the loaded
* image protocol.
*/
- struct efi_loaded_image *loaded_image_info = (void*)image_handle;
+ struct efi_loaded_image *loaded_image_info = (void *)image_handle;
EFI_ENTRY("%p, %ld, %ld, %p", image_handle, exit_status,
exit_data_size, exit_data);
@@ -1789,7 +1791,8 @@ static efi_status_t EFIAPI efi_exit_boot_services(efi_handle_t image_handle,
*/
static efi_status_t EFIAPI efi_get_next_monotonic_count(uint64_t *count)
{
- static uint64_t mono = 0;
+ static uint64_t mono;
+
EFI_ENTRY("%p", count);
*count = mono++;
return EFI_EXIT(EFI_SUCCESS);
@@ -1830,7 +1833,7 @@ static efi_status_t EFIAPI efi_set_watchdog_timer(unsigned long timeout,
unsigned long data_size,
uint16_t *watchdog_data)
{
- EFI_ENTRY("%ld, 0x%"PRIx64", %ld, %p", timeout, watchdog_code,
+ EFI_ENTRY("%ld, 0x%" PRIx64 ", %ld, %p", timeout, watchdog_code,
data_size, watchdog_data);
return EFI_EXIT(efi_set_watchdog(timeout));
}
@@ -1895,8 +1898,8 @@ out:
* @entry_count number of entries available in the buffer
* @return status code
*/
-static efi_status_t EFIAPI efi_open_protocol_information(efi_handle_t handle,
- const efi_guid_t *protocol,
+static efi_status_t EFIAPI efi_open_protocol_information(
+ efi_handle_t handle, const efi_guid_t *protocol,
struct efi_open_protocol_info_entry **entry_buffer,
efi_uintn_t *entry_count)
{
@@ -2881,15 +2884,16 @@ static const struct efi_boot_services efi_boot_services = {
.protocols_per_handle = efi_protocols_per_handle,
.locate_handle_buffer = efi_locate_handle_buffer,
.locate_protocol = efi_locate_protocol,
- .install_multiple_protocol_interfaces = efi_install_multiple_protocol_interfaces,
- .uninstall_multiple_protocol_interfaces = efi_uninstall_multiple_protocol_interfaces,
+ .install_multiple_protocol_interfaces =
+ efi_install_multiple_protocol_interfaces,
+ .uninstall_multiple_protocol_interfaces =
+ efi_uninstall_multiple_protocol_interfaces,
.calculate_crc32 = efi_calculate_crc32,
.copy_mem = efi_copy_mem,
.set_mem = efi_set_mem,
.create_event_ex = efi_create_event_ex,
};
-
static uint16_t __efi_runtime_data firmware_vendor[] = L"Das U-Boot";
struct efi_system_table __efi_runtime_data systab = {
@@ -2899,11 +2903,11 @@ struct efi_system_table __efi_runtime_data systab = {
.headersize = sizeof(struct efi_table_hdr),
},
.fw_vendor = (long)firmware_vendor,
- .con_in = (void*)&efi_con_in,
- .con_out = (void*)&efi_con_out,
- .std_err = (void*)&efi_con_out,
- .runtime = (void*)&efi_runtime_services,
- .boottime = (void*)&efi_boot_services,
+ .con_in = (void *)&efi_con_in,
+ .con_out = (void *)&efi_con_out,
+ .std_err = (void *)&efi_con_out,
+ .runtime = (void *)&efi_runtime_services,
+ .boottime = (void *)&efi_boot_services,
.nr_tables = 0,
- .tables = (void*)efi_conf_table,
+ .tables = (void *)efi_conf_table,
};
--
2.14.2
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [U-Boot] [PATCH 2/5] efi_loader: manage events in a linked list
2018-02-18 14:17 [U-Boot] [PATCH 0/5] efi_loader: implement event groups Heinrich Schuchardt
2018-02-18 14:17 ` [U-Boot] [PATCH 1/5] efi_loader: fix formatting errors Heinrich Schuchardt
@ 2018-02-18 14:17 ` Heinrich Schuchardt
2018-02-18 14:17 ` [U-Boot] [PATCH 3/5] efi_loader: define GUIDS for event groups Heinrich Schuchardt
` (2 subsequent siblings)
4 siblings, 0 replies; 8+ messages in thread
From: Heinrich Schuchardt @ 2018-02-18 14:17 UTC (permalink / raw)
To: u-boot
Lift the limit on the number of events by using a linked list.
This also allows to have events with type == 0.
This patch is based on Rob's patch
efi_loader: fix events
https://lists.denx.de/pipermail/u-boot/2017-October/309348.html
Suggested-by: Rob Clark <robdclark@gmail.com>
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
---
include/efi_loader.h | 11 +--
lib/efi_loader/efi_boottime.c | 192 +++++++++++++++++++-----------------------
2 files changed, 93 insertions(+), 110 deletions(-)
diff --git a/include/efi_loader.h b/include/efi_loader.h
index 3ccbb98aaf..7f703c6ef7 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -146,17 +146,19 @@ struct efi_object {
/**
* struct efi_event
*
+ * @link: Link to list of all events
* @type: Type of event, see efi_create_event
* @notify_tpl: Task priority level of notifications
- * @trigger_time: Period of the timer
- * @trigger_next: Next time to trigger the timer
* @nofify_function: Function to call when the event is triggered
* @notify_context: Data to be passed to the notify function
+ * @trigger_time: Period of the timer
+ * @trigger_next: Next time to trigger the timer
* @trigger_type: Type of timer, see efi_set_timer
- * @queued: The notification function is queued
- * @signaled: The event occurred. The event is in the signaled state.
+ * @is_queued: The notification function is queued
+ * @is_signaled: The event occurred. The event is in the signaled state.
*/
struct efi_event {
+ struct list_head link;
uint32_t type;
efi_uintn_t notify_tpl;
void (EFIAPI *notify_function)(struct efi_event *event, void *context);
@@ -168,7 +170,6 @@ struct efi_event {
bool is_signaled;
};
-
/* This list contains all UEFI objects we know of */
extern struct list_head efi_obj_list;
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index 75f7c50295..4acb1e092a 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -26,6 +26,9 @@ static efi_uintn_t efi_tpl = TPL_APPLICATION;
/* This list contains all the EFI objects our payload has access to */
LIST_HEAD(efi_obj_list);
+/* List of all events */
+static LIST_HEAD(efi_events);
+
/*
* If we're running on nasty systems (32bit ARM booting into non-EFI Linux)
* we need to do trickery with caches. Since we don't want to break the EFI
@@ -473,10 +476,23 @@ void efi_delete_handle(struct efi_object *obj)
}
/*
- * Our event capabilities are very limited. Only a small limited
- * number of events is allowed to coexist.
+ * Check if a pointer is a valid event.
+ *
+ * @event pointer to check
+ * @return status code
*/
-static struct efi_event efi_events[16];
+static efi_status_t efi_is_event(const struct efi_event *event)
+{
+ const struct efi_event *evt;
+
+ if (!event)
+ return EFI_INVALID_PARAMETER;
+ list_for_each_entry(evt, &efi_events, link) {
+ if (evt == event)
+ return EFI_SUCCESS;
+ }
+ return EFI_INVALID_PARAMETER;
+}
/*
* Create an event.
@@ -499,7 +515,7 @@ efi_status_t efi_create_event(uint32_t type, efi_uintn_t notify_tpl,
void *context),
void *notify_context, struct efi_event **event)
{
- int i;
+ struct efi_event *evt;
if (event == NULL)
return EFI_INVALID_PARAMETER;
@@ -507,25 +523,24 @@ efi_status_t efi_create_event(uint32_t type, efi_uintn_t notify_tpl,
if ((type & EVT_NOTIFY_SIGNAL) && (type & EVT_NOTIFY_WAIT))
return EFI_INVALID_PARAMETER;
- if ((type & (EVT_NOTIFY_SIGNAL|EVT_NOTIFY_WAIT)) &&
+ if ((type & (EVT_NOTIFY_SIGNAL | EVT_NOTIFY_WAIT)) &&
notify_function == NULL)
return EFI_INVALID_PARAMETER;
- for (i = 0; i < ARRAY_SIZE(efi_events); ++i) {
- if (efi_events[i].type)
- continue;
- efi_events[i].type = type;
- efi_events[i].notify_tpl = notify_tpl;
- efi_events[i].notify_function = notify_function;
- efi_events[i].notify_context = notify_context;
- /* Disable timers on bootup */
- efi_events[i].trigger_next = -1ULL;
- efi_events[i].is_queued = false;
- efi_events[i].is_signaled = false;
- *event = &efi_events[i];
- return EFI_SUCCESS;
- }
- return EFI_OUT_OF_RESOURCES;
+ evt = calloc(1, sizeof(struct efi_event));
+ if (!evt)
+ return EFI_OUT_OF_RESOURCES;
+ evt->type = type;
+ evt->notify_tpl = notify_tpl;
+ evt->notify_function = notify_function;
+ evt->notify_context = notify_context;
+ /* Disable timers on bootup */
+ evt->trigger_next = -1ULL;
+ evt->is_queued = false;
+ evt->is_signaled = false;
+ list_add_tail(&evt->link, &efi_events);
+ *event = evt;
+ return EFI_SUCCESS;
}
/*
@@ -596,30 +611,26 @@ static efi_status_t EFIAPI efi_create_event_ext(
*/
void efi_timer_check(void)
{
- int i;
+ struct efi_event *evt;
u64 now = timer_get_us();
- for (i = 0; i < ARRAY_SIZE(efi_events); ++i) {
- if (!efi_events[i].type)
+ list_for_each_entry(evt, &efi_events, link) {
+ if (evt->is_queued)
+ efi_signal_event(evt, true);
+ if (!(evt->type & EVT_TIMER) || now < evt->trigger_next)
continue;
- if (efi_events[i].is_queued)
- efi_signal_event(&efi_events[i], true);
- if (!(efi_events[i].type & EVT_TIMER) ||
- now < efi_events[i].trigger_next)
- continue;
- switch (efi_events[i].trigger_type) {
+ switch (evt->trigger_type) {
case EFI_TIMER_RELATIVE:
- efi_events[i].trigger_type = EFI_TIMER_STOP;
+ evt->trigger_type = EFI_TIMER_STOP;
break;
case EFI_TIMER_PERIODIC:
- efi_events[i].trigger_next +=
- efi_events[i].trigger_time;
+ evt->trigger_next += evt->trigger_time;
break;
default:
continue;
}
- efi_events[i].is_signaled = true;
- efi_signal_event(&efi_events[i], true);
+ evt->is_signaled = true;
+ efi_signal_event(evt, true);
}
WATCHDOG_RESET();
}
@@ -638,7 +649,9 @@ void efi_timer_check(void)
efi_status_t efi_set_timer(struct efi_event *event, enum efi_timer_delay type,
uint64_t trigger_time)
{
- int i;
+ /* Check that the event is valid */
+ if (efi_is_event(event) != EFI_SUCCESS || !(event->type & EVT_TIMER))
+ return EFI_INVALID_PARAMETER;
/*
* The parameter defines a multiple of 100ns.
@@ -646,30 +659,21 @@ efi_status_t efi_set_timer(struct efi_event *event, enum efi_timer_delay type,
*/
do_div(trigger_time, 10);
- for (i = 0; i < ARRAY_SIZE(efi_events); ++i) {
- if (event != &efi_events[i])
- continue;
-
- if (!(event->type & EVT_TIMER))
- break;
- switch (type) {
- case EFI_TIMER_STOP:
- event->trigger_next = -1ULL;
- break;
- case EFI_TIMER_PERIODIC:
- case EFI_TIMER_RELATIVE:
- event->trigger_next =
- timer_get_us() + trigger_time;
- break;
- default:
- return EFI_INVALID_PARAMETER;
- }
- event->trigger_type = type;
- event->trigger_time = trigger_time;
- event->is_signaled = false;
- return EFI_SUCCESS;
+ switch (type) {
+ case EFI_TIMER_STOP:
+ event->trigger_next = -1ULL;
+ break;
+ case EFI_TIMER_PERIODIC:
+ case EFI_TIMER_RELATIVE:
+ event->trigger_next = timer_get_us() + trigger_time;
+ break;
+ default:
+ return EFI_INVALID_PARAMETER;
}
- return EFI_INVALID_PARAMETER;
+ event->trigger_type = type;
+ event->trigger_time = trigger_time;
+ event->is_signaled = false;
+ return EFI_SUCCESS;
}
/*
@@ -708,7 +712,7 @@ static efi_status_t EFIAPI efi_wait_for_event(efi_uintn_t num_events,
struct efi_event **event,
efi_uintn_t *index)
{
- int i, j;
+ int i;
EFI_ENTRY("%zd, %p, %p", num_events, event, index);
@@ -719,12 +723,8 @@ static efi_status_t EFIAPI efi_wait_for_event(efi_uintn_t num_events,
if (efi_tpl != TPL_APPLICATION)
return EFI_EXIT(EFI_UNSUPPORTED);
for (i = 0; i < num_events; ++i) {
- for (j = 0; j < ARRAY_SIZE(efi_events); ++j) {
- if (event[i] == &efi_events[j])
- goto known_event;
- }
- return EFI_EXIT(EFI_INVALID_PARAMETER);
-known_event:
+ if (efi_is_event(event[i]) != EFI_SUCCESS)
+ return EFI_EXIT(EFI_INVALID_PARAMETER);
if (!event[i]->type || event[i]->type & EVT_NOTIFY_SIGNAL)
return EFI_EXIT(EFI_INVALID_PARAMETER);
if (!event[i]->is_signaled)
@@ -768,18 +768,13 @@ out:
*/
static efi_status_t EFIAPI efi_signal_event_ext(struct efi_event *event)
{
- int i;
-
EFI_ENTRY("%p", event);
- for (i = 0; i < ARRAY_SIZE(efi_events); ++i) {
- if (event != &efi_events[i])
- continue;
- if (event->is_signaled)
- break;
+ if (efi_is_event(event) != EFI_SUCCESS)
+ return EFI_EXIT(EFI_INVALID_PARAMETER);
+ if (!event->is_signaled) {
event->is_signaled = true;
if (event->type & EVT_NOTIFY_SIGNAL)
efi_signal_event(event, true);
- break;
}
return EFI_EXIT(EFI_SUCCESS);
}
@@ -796,19 +791,12 @@ static efi_status_t EFIAPI efi_signal_event_ext(struct efi_event *event)
*/
static efi_status_t EFIAPI efi_close_event(struct efi_event *event)
{
- int i;
-
EFI_ENTRY("%p", event);
- for (i = 0; i < ARRAY_SIZE(efi_events); ++i) {
- if (event == &efi_events[i]) {
- event->type = 0;
- event->trigger_next = -1ULL;
- event->is_queued = false;
- event->is_signaled = false;
- return EFI_EXIT(EFI_SUCCESS);
- }
- }
- return EFI_EXIT(EFI_INVALID_PARAMETER);
+ if (efi_is_event(event) != EFI_SUCCESS)
+ return EFI_EXIT(EFI_INVALID_PARAMETER);
+ list_del(&event->link);
+ free(event);
+ return EFI_EXIT(EFI_SUCCESS);
}
/*
@@ -826,24 +814,18 @@ static efi_status_t EFIAPI efi_close_event(struct efi_event *event)
*/
static efi_status_t EFIAPI efi_check_event(struct efi_event *event)
{
- int i;
-
EFI_ENTRY("%p", event);
efi_timer_check();
- for (i = 0; i < ARRAY_SIZE(efi_events); ++i) {
- if (event != &efi_events[i])
- continue;
- if (!event->type || event->type & EVT_NOTIFY_SIGNAL)
- break;
- if (!event->is_signaled)
- efi_signal_event(event, true);
- if (event->is_signaled) {
- event->is_signaled = false;
- return EFI_EXIT(EFI_SUCCESS);
- }
- return EFI_EXIT(EFI_NOT_READY);
+ if (efi_is_event(event) != EFI_SUCCESS ||
+ event->type & EVT_NOTIFY_SIGNAL)
+ return EFI_EXIT(EFI_INVALID_PARAMETER);
+ if (!event->is_signaled)
+ efi_signal_event(event, true);
+ if (event->is_signaled) {
+ event->is_signaled = false;
+ return EFI_EXIT(EFI_SUCCESS);
}
- return EFI_EXIT(EFI_INVALID_PARAMETER);
+ return EFI_EXIT(EFI_NOT_READY);
}
/*
@@ -1729,7 +1711,7 @@ static void efi_exit_caches(void)
static efi_status_t EFIAPI efi_exit_boot_services(efi_handle_t image_handle,
unsigned long map_key)
{
- int i;
+ struct efi_event *evt;
EFI_ENTRY("%p, %ld", image_handle, map_key);
@@ -1741,11 +1723,11 @@ static efi_status_t EFIAPI efi_exit_boot_services(efi_handle_t image_handle,
return EFI_EXIT(EFI_SUCCESS);
/* Notify that ExitBootServices is invoked. */
- for (i = 0; i < ARRAY_SIZE(efi_events); ++i) {
- if (efi_events[i].type != EVT_SIGNAL_EXIT_BOOT_SERVICES)
+ list_for_each_entry(evt, &efi_events, link) {
+ if (evt->type != EVT_SIGNAL_EXIT_BOOT_SERVICES)
continue;
- efi_events[i].is_signaled = true;
- efi_signal_event(&efi_events[i], false);
+ evt->is_signaled = true;
+ efi_signal_event(evt, false);
}
/* TODO Should persist EFI variables here */
--
2.14.2
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [U-Boot] [PATCH 3/5] efi_loader: define GUIDS for event groups
2018-02-18 14:17 [U-Boot] [PATCH 0/5] efi_loader: implement event groups Heinrich Schuchardt
2018-02-18 14:17 ` [U-Boot] [PATCH 1/5] efi_loader: fix formatting errors Heinrich Schuchardt
2018-02-18 14:17 ` [U-Boot] [PATCH 2/5] efi_loader: manage events in a linked list Heinrich Schuchardt
@ 2018-02-18 14:17 ` Heinrich Schuchardt
2018-02-18 14:17 ` [U-Boot] [PATCH 4/5] efi_loader: implement " Heinrich Schuchardt
2018-02-18 14:17 ` [U-Boot] [PATCH 5/5] efi_selftest: unit test for " Heinrich Schuchardt
4 siblings, 0 replies; 8+ messages in thread
From: Heinrich Schuchardt @ 2018-02-18 14:17 UTC (permalink / raw)
To: u-boot
Event groups are used to signal multiple events at the same time.
They are identified by GUIDs. This patch provided the predefined
GUIDs of UEFI specification 2.7.
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
---
include/efi_api.h | 21 +++++++++++++++++++++
include/efi_loader.h | 10 ++++++++++
lib/efi_loader/efi_boottime.c | 16 ++++++++++++++++
3 files changed, 47 insertions(+)
diff --git a/include/efi_api.h b/include/efi_api.h
index 13ed80ac97..d20058540a 100644
--- a/include/efi_api.h
+++ b/include/efi_api.h
@@ -244,6 +244,27 @@ struct efi_runtime_services {
u64 maximum_variable_size);
};
+/* 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_VIRTUAL_ADDRESS_CHANGE \
+ EFI_GUID(0x13fa7698, 0xc831, 0x49c7, 0x87, 0xea, \
+ 0x8f, 0x43, 0xfc, 0xc2, 0x51, 0x96)
+
+#define EFI_EVENT_GROUP_MEMORY_MAP_CHANGE \
+ EFI_GUID(0x78bee926, 0x692f, 0x48fd, 0x9e, 0xdb, \
+ 0x01, 0x42, 0x2e, 0xf0, 0xd7, 0xab)
+
+#define EFI_EVENT_GROUP_READY_TO_BOOT \
+ EFI_GUID(0x7ce88fb3, 0x4bd7, 0x4679, 0x87, 0xa8, \
+ 0xa8, 0xd8, 0xde, 0xe5, 0x0d, 0x2b)
+
+#define EFI_EVENT_GROUP_RESET_SYSTEM \
+ EFI_GUID(0x62da6a56, 0x13fb, 0x485a, 0xa8, 0xda, \
+ 0xa3, 0xdd, 0x79, 0x12, 0xcb, 0x6b)
+
/* EFI Configuration Table and GUID definitions */
#define NULL_GUID \
EFI_GUID(0x00000000, 0x0000, 0x0000, 0x00, 0x00, \
diff --git a/include/efi_loader.h b/include/efi_loader.h
index 7f703c6ef7..e2cd249171 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -93,6 +93,16 @@ extern const efi_guid_t efi_guid_console_control;
extern const efi_guid_t efi_guid_device_path;
/* GUID of the EFI_DRIVER_BINDING_PROTOCOL */
extern const efi_guid_t efi_guid_driver_binding_protocol;
+/* event group ExitBootServices() invoked */
+extern const efi_guid_t efi_guid_event_group_exit_boot_services;
+/* event group SetVirtualAddressMap() invoked */
+extern const efi_guid_t efi_guid_event_group_virtual_address_change;
+/* event group memory map changed */
+extern const efi_guid_t efi_guid_event_group_memory_map_change;
+/* event group boot manager about to boot */
+extern const efi_guid_t efi_guid_event_group_ready_to_boot;
+/* event group ResetSystem() invoked (before ExitBootServices) */
+extern const efi_guid_t efi_guid_event_group_reset_system;
/* GUID of the device tree table */
extern const efi_guid_t efi_guid_fdt;
extern const efi_guid_t efi_guid_loaded_image;
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index 4acb1e092a..da3c852b44 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -65,6 +65,22 @@ const efi_guid_t efi_guid_fdt = EFI_FDT_GUID;
const efi_guid_t efi_guid_driver_binding_protocol =
EFI_DRIVER_BINDING_PROTOCOL_GUID;
+/* event group ExitBootServices() invoked */
+const efi_guid_t efi_guid_event_group_exit_boot_services =
+ EFI_EVENT_GROUP_EXIT_BOOT_SERVICES;
+/* event group SetVirtualAddressMap() invoked */
+const efi_guid_t efi_guid_event_group_virtual_address_change =
+ EFI_EVENT_GROUP_VIRTUAL_ADDRESS_CHANGE;
+/* event group memory map changed */
+const efi_guid_t efi_guid_event_group_memory_map_change =
+ EFI_EVENT_GROUP_MEMORY_MAP_CHANGE;
+/* event group boot manager about to boot */
+const efi_guid_t efi_guid_event_group_ready_to_boot =
+ EFI_EVENT_GROUP_READY_TO_BOOT;
+/* event group ResetSystem() invoked (before ExitBootServices) */
+const efi_guid_t efi_guid_event_group_reset_system =
+ EFI_EVENT_GROUP_RESET_SYSTEM;
+
static efi_status_t EFIAPI efi_disconnect_controller(
efi_handle_t controller_handle,
efi_handle_t driver_image_handle,
--
2.14.2
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [U-Boot] [PATCH 4/5] efi_loader: implement event groups
2018-02-18 14:17 [U-Boot] [PATCH 0/5] efi_loader: implement event groups Heinrich Schuchardt
` (2 preceding siblings ...)
2018-02-18 14:17 ` [U-Boot] [PATCH 3/5] efi_loader: define GUIDS for event groups Heinrich Schuchardt
@ 2018-02-18 14:17 ` Heinrich Schuchardt
2018-02-18 14:17 ` [U-Boot] [PATCH 5/5] efi_selftest: unit test for " Heinrich Schuchardt
4 siblings, 0 replies; 8+ messages in thread
From: Heinrich Schuchardt @ 2018-02-18 14:17 UTC (permalink / raw)
To: u-boot
If an event of a group event is signaled all other events of the same
group are signaled too.
Function efi_signal_event is renamed to efi_queue_event.
A new function efi_signal_event is introduced that checks if an event
belongs to a group and than signals all events of the group.
Event group notifciation is implemented for ExitBootServices,
InstallConfigurationTable, and ResetSystem.
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
---
include/efi_loader.h | 7 ++-
lib/efi_loader/efi_boottime.c | 99 ++++++++++++++++++++++++++++++++++---------
lib/efi_loader/efi_console.c | 6 +--
lib/efi_loader/efi_net.c | 4 +-
lib/efi_loader/efi_runtime.c | 11 +++++
lib/efi_loader/efi_watchdog.c | 2 +-
6 files changed, 101 insertions(+), 28 deletions(-)
diff --git a/include/efi_loader.h b/include/efi_loader.h
index e2cd249171..b1999f08c6 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -161,6 +161,7 @@ struct efi_object {
* @notify_tpl: Task priority level of notifications
* @nofify_function: Function to call when the event is triggered
* @notify_context: Data to be passed to the notify function
+ * @group: Event group
* @trigger_time: Period of the timer
* @trigger_next: Next time to trigger the timer
* @trigger_type: Type of timer, see efi_set_timer
@@ -173,6 +174,7 @@ struct efi_event {
efi_uintn_t notify_tpl;
void (EFIAPI *notify_function)(struct efi_event *event, void *context);
void *notify_context;
+ const efi_guid_t *group;
u64 trigger_next;
u64 trigger_time;
enum efi_timer_delay trigger_type;
@@ -182,6 +184,8 @@ struct efi_event {
/* This list contains all UEFI objects we know of */
extern struct list_head efi_obj_list;
+/* List of all events */
+extern struct list_head efi_events;
/* Called by bootefi to make console interface available */
int efi_console_register(void);
@@ -248,7 +252,8 @@ efi_status_t efi_create_event(uint32_t type, efi_uintn_t notify_tpl,
void (EFIAPI *notify_function) (
struct efi_event *event,
void *context),
- void *notify_context, struct efi_event **event);
+ void *notify_context, efi_guid_t *group,
+ struct efi_event **event);
/* Call this to set a timer */
efi_status_t efi_set_timer(struct efi_event *event, enum efi_timer_delay type,
uint64_t trigger_time);
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index da3c852b44..32b8149fe7 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -27,7 +27,7 @@ static efi_uintn_t efi_tpl = TPL_APPLICATION;
LIST_HEAD(efi_obj_list);
/* List of all events */
-static LIST_HEAD(efi_events);
+LIST_HEAD(efi_events);
/*
* If we're running on nasty systems (32bit ARM booting into non-EFI Linux)
@@ -176,7 +176,7 @@ const char *__efi_nesting_dec(void)
* @event event to signal
* @check_tpl check the TPL level
*/
-void efi_signal_event(struct efi_event *event, bool check_tpl)
+static void efi_queue_event(struct efi_event *event, bool check_tpl)
{
if (event->notify_function) {
event->is_queued = true;
@@ -189,6 +189,50 @@ void efi_signal_event(struct efi_event *event, bool check_tpl)
event->is_queued = false;
}
+/*
+ * Signal an EFI event.
+ *
+ * This function signals an event. If the event belongs to an event group
+ * all events of the group are signaled. If they are of type EVT_NOTIFY_SIGNAL
+ * their notification function is queued.
+ *
+ * For the SignalEvent service see efi_signal_event_ext.
+ *
+ * @event event to signal
+ * @check_tpl check the TPL level
+ */
+void efi_signal_event(struct efi_event *event, bool check_tpl)
+{
+ if (event->group) {
+ struct efi_event *evt;
+
+ /*
+ * The signaled state has to set before executing any
+ * notification function
+ */
+ list_for_each_entry(evt, &efi_events, link) {
+ if (!evt->group || guidcmp(evt->group, event->group))
+ continue;
+ if (evt->is_signaled)
+ continue;
+ evt->is_signaled = true;
+ if (evt->type & EVT_NOTIFY_SIGNAL &&
+ evt->notify_function)
+ evt->is_queued = true;
+ }
+ list_for_each_entry(evt, &efi_events, link) {
+ if (!evt->group || guidcmp(evt->group, event->group))
+ continue;
+ if (evt->is_queued)
+ efi_queue_event(evt, check_tpl);
+ }
+ } else if (!event->is_signaled) {
+ event->is_signaled = true;
+ if (event->type & EVT_NOTIFY_SIGNAL)
+ efi_queue_event(event, check_tpl);
+ }
+}
+
/*
* Raise the task priority level.
*
@@ -529,7 +573,8 @@ efi_status_t efi_create_event(uint32_t type, efi_uintn_t notify_tpl,
void (EFIAPI *notify_function) (
struct efi_event *event,
void *context),
- void *notify_context, struct efi_event **event)
+ void *notify_context, efi_guid_t *group,
+ struct efi_event **event)
{
struct efi_event *evt;
@@ -550,6 +595,7 @@ efi_status_t efi_create_event(uint32_t type, efi_uintn_t notify_tpl,
evt->notify_tpl = notify_tpl;
evt->notify_function = notify_function;
evt->notify_context = notify_context;
+ evt->group = group;
/* Disable timers on bootup */
evt->trigger_next = -1ULL;
evt->is_queued = false;
@@ -585,10 +631,8 @@ efi_status_t EFIAPI efi_create_event_ex(uint32_t type, efi_uintn_t notify_tpl,
{
EFI_ENTRY("%d, 0x%zx, %p, %p, %pUl", type, notify_tpl, notify_function,
notify_context, event_group);
- if (event_group)
- return EFI_EXIT(EFI_UNSUPPORTED);
return EFI_EXIT(efi_create_event(type, notify_tpl, notify_function,
- notify_context, event));
+ notify_context, event_group, event));
}
/*
@@ -615,7 +659,7 @@ static efi_status_t EFIAPI efi_create_event_ext(
EFI_ENTRY("%d, 0x%zx, %p, %p", type, notify_tpl, notify_function,
notify_context);
return EFI_EXIT(efi_create_event(type, notify_tpl, notify_function,
- notify_context, event));
+ notify_context, NULL, event));
}
/*
@@ -632,7 +676,7 @@ void efi_timer_check(void)
list_for_each_entry(evt, &efi_events, link) {
if (evt->is_queued)
- efi_signal_event(evt, true);
+ efi_queue_event(evt, true);
if (!(evt->type & EVT_TIMER) || now < evt->trigger_next)
continue;
switch (evt->trigger_type) {
@@ -645,7 +689,7 @@ void efi_timer_check(void)
default:
continue;
}
- evt->is_signaled = true;
+ evt->is_signaled = false;
efi_signal_event(evt, true);
}
WATCHDOG_RESET();
@@ -744,7 +788,7 @@ static efi_status_t EFIAPI efi_wait_for_event(efi_uintn_t num_events,
if (!event[i]->type || event[i]->type & EVT_NOTIFY_SIGNAL)
return EFI_EXIT(EFI_INVALID_PARAMETER);
if (!event[i]->is_signaled)
- efi_signal_event(event[i], true);
+ efi_queue_event(event[i], true);
}
/* Wait for signal */
@@ -787,11 +831,7 @@ static efi_status_t EFIAPI efi_signal_event_ext(struct efi_event *event)
EFI_ENTRY("%p", event);
if (efi_is_event(event) != EFI_SUCCESS)
return EFI_EXIT(EFI_INVALID_PARAMETER);
- if (!event->is_signaled) {
- event->is_signaled = true;
- if (event->type & EVT_NOTIFY_SIGNAL)
- efi_signal_event(event, true);
- }
+ efi_signal_event(event, true);
return EFI_EXIT(EFI_SUCCESS);
}
@@ -836,7 +876,7 @@ static efi_status_t EFIAPI efi_check_event(struct efi_event *event)
event->type & EVT_NOTIFY_SIGNAL)
return EFI_EXIT(EFI_INVALID_PARAMETER);
if (!event->is_signaled)
- efi_signal_event(event, true);
+ efi_queue_event(event, true);
if (event->is_signaled) {
event->is_signaled = false;
return EFI_EXIT(EFI_SUCCESS);
@@ -1333,6 +1373,7 @@ static void efi_remove_configuration_table(int i)
efi_status_t efi_install_configuration_table(const efi_guid_t *guid,
void *table)
{
+ struct efi_event *evt;
int i;
if (!guid)
@@ -1345,7 +1386,7 @@ efi_status_t efi_install_configuration_table(const efi_guid_t *guid,
efi_conf_table[i].table = table;
else
efi_remove_configuration_table(i);
- return EFI_SUCCESS;
+ goto out;
}
}
@@ -1361,6 +1402,15 @@ efi_status_t efi_install_configuration_table(const efi_guid_t *guid,
efi_conf_table[i].table = table;
systab.nr_tables = i + 1;
+out:
+ /* Notify that the configuration table was changed */
+ list_for_each_entry(evt, &efi_events, link) {
+ if (evt->group && !guidcmp(evt->group, guid)) {
+ efi_signal_event(evt, false);
+ break;
+ }
+ }
+
return EFI_SUCCESS;
}
@@ -1738,12 +1788,19 @@ static efi_status_t EFIAPI efi_exit_boot_services(efi_handle_t image_handle,
if (!systab.boottime)
return EFI_EXIT(EFI_SUCCESS);
+ /* Add related events to the event group */
+ list_for_each_entry(evt, &efi_events, link) {
+ if (evt->type == 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->type != EVT_SIGNAL_EXIT_BOOT_SERVICES)
- continue;
- evt->is_signaled = true;
- efi_signal_event(evt, false);
+ if (evt->group &&
+ !guidcmp(evt->group,
+ &efi_guid_event_group_exit_boot_services)) {
+ efi_signal_event(evt, false);
+ break;
+ }
}
/* TODO Should persist EFI variables here */
diff --git a/lib/efi_loader/efi_console.c b/lib/efi_loader/efi_console.c
index 3cb580e3ed..d35893dc2a 100644
--- a/lib/efi_loader/efi_console.c
+++ b/lib/efi_loader/efi_console.c
@@ -488,14 +488,14 @@ int efi_console_register(void)
goto out_of_memory;
/* Create console events */
- r = efi_create_event(EVT_NOTIFY_WAIT, TPL_CALLBACK,
- efi_key_notify, NULL, &efi_con_in.wait_for_key);
+ r = efi_create_event(EVT_NOTIFY_WAIT, TPL_CALLBACK, efi_key_notify,
+ NULL, NULL, &efi_con_in.wait_for_key);
if (r != EFI_SUCCESS) {
printf("ERROR: Failed to register WaitForKey event\n");
return r;
}
r = efi_create_event(EVT_TIMER | EVT_NOTIFY_SIGNAL, TPL_CALLBACK,
- efi_console_timer_notify, NULL,
+ efi_console_timer_notify, NULL, NULL,
&console_timer_event);
if (r != EFI_SUCCESS) {
printf("ERROR: Failed to register console event\n");
diff --git a/lib/efi_loader/efi_net.c b/lib/efi_loader/efi_net.c
index e7fed79450..b88dc91f58 100644
--- a/lib/efi_loader/efi_net.c
+++ b/lib/efi_loader/efi_net.c
@@ -341,7 +341,7 @@ efi_status_t efi_net_register(void)
* Create WaitForPacket event.
*/
r = efi_create_event(EVT_NOTIFY_WAIT, TPL_CALLBACK,
- efi_network_timer_notify, NULL,
+ efi_network_timer_notify, NULL, NULL,
&wait_for_packet);
if (r != EFI_SUCCESS) {
printf("ERROR: Failed to register network event\n");
@@ -355,7 +355,7 @@ efi_status_t efi_net_register(void)
* has been received.
*/
r = efi_create_event(EVT_TIMER | EVT_NOTIFY_SIGNAL, TPL_CALLBACK,
- efi_network_timer_notify, NULL,
+ efi_network_timer_notify, NULL, NULL,
&network_timer_event);
if (r != EFI_SUCCESS) {
printf("ERROR: Failed to register network event\n");
diff --git a/lib/efi_loader/efi_runtime.c b/lib/efi_loader/efi_runtime.c
index e2b86828cd..d0f213ea4f 100644
--- a/lib/efi_loader/efi_runtime.c
+++ b/lib/efi_loader/efi_runtime.c
@@ -78,9 +78,20 @@ static void EFIAPI efi_reset_system_boottime(
efi_status_t reset_status,
unsigned long data_size, void *reset_data)
{
+ struct efi_event *evt;
+
EFI_ENTRY("%d %lx %lx %p", reset_type, reset_status, data_size,
reset_data);
+ /* Notify reset */
+ list_for_each_entry(evt, &efi_events, link) {
+ if (evt->group &&
+ !guidcmp(evt->group,
+ &efi_guid_event_group_reset_system)) {
+ efi_signal_event(evt, false);
+ break;
+ }
+ }
switch (reset_type) {
case EFI_RESET_COLD:
case EFI_RESET_WARM:
diff --git a/lib/efi_loader/efi_watchdog.c b/lib/efi_loader/efi_watchdog.c
index b1c35a8e29..d12e51da0a 100644
--- a/lib/efi_loader/efi_watchdog.c
+++ b/lib/efi_loader/efi_watchdog.c
@@ -67,7 +67,7 @@ efi_status_t efi_watchdog_register(void)
* Create a timer event.
*/
r = efi_create_event(EVT_TIMER | EVT_NOTIFY_SIGNAL, TPL_CALLBACK,
- efi_watchdog_timer_notify, NULL,
+ efi_watchdog_timer_notify, NULL, NULL,
&watchdog_timer_event);
if (r != EFI_SUCCESS) {
printf("ERROR: Failed to register watchdog event\n");
--
2.14.2
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [U-Boot] [PATCH 5/5] efi_selftest: unit test for event groups
2018-02-18 14:17 [U-Boot] [PATCH 0/5] efi_loader: implement event groups Heinrich Schuchardt
` (3 preceding siblings ...)
2018-02-18 14:17 ` [U-Boot] [PATCH 4/5] efi_loader: implement " Heinrich Schuchardt
@ 2018-02-18 14:17 ` Heinrich Schuchardt
2018-03-12 17:59 ` Heinrich Schuchardt
4 siblings, 1 reply; 8+ messages in thread
From: Heinrich Schuchardt @ 2018-02-18 14:17 UTC (permalink / raw)
To: u-boot
Supply a unit test for event groups.
Create multiple events in an event group. Signal each event once and check
that all events are notified once in each round.
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
---
lib/efi_selftest/Makefile | 1 +
lib/efi_selftest/efi_selftest_event_groups.c | 140 +++++++++++++++++++++++++++
2 files changed, 141 insertions(+)
create mode 100644 lib/efi_selftest/efi_selftest_event_groups.c
diff --git a/lib/efi_selftest/Makefile b/lib/efi_selftest/Makefile
index b975da2955..51af1055e9 100644
--- a/lib/efi_selftest/Makefile
+++ b/lib/efi_selftest/Makefile
@@ -19,6 +19,7 @@ efi_selftest_controllers.o \
efi_selftest_console.o \
efi_selftest_devicepath.o \
efi_selftest_events.o \
+efi_selftest_event_groups.o \
efi_selftest_exitbootservices.o \
efi_selftest_fdt.o \
efi_selftest_gop.o \
diff --git a/lib/efi_selftest/efi_selftest_event_groups.c b/lib/efi_selftest/efi_selftest_event_groups.c
new file mode 100644
index 0000000000..79e4ea1ce2
--- /dev/null
+++ b/lib/efi_selftest/efi_selftest_event_groups.c
@@ -0,0 +1,140 @@
+/*
+ * efi_selftest_event_groups
+ *
+ * Copyright (c) 2018 Heinrich Schuchardt <xypron.glpk@gmx.de>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+ * This test checks the notification of group events and the
+ * following services:
+ * CreateEventEx, CloseEvent, SignalEvent, CheckEvent.
+ */
+
+#include <efi_selftest.h>
+
+#define GROUP_SIZE 16
+
+static struct efi_boot_services *boottime;
+static efi_guid_t event_group =
+ EFI_GUID(0x2335905b, 0xc3b9, 0x4221, 0xa3, 0x71,
+ 0x0e, 0x5b, 0x45, 0xc0, 0x56, 0x91);
+
+/*
+ * Notification function, increments the notfication count if parameter
+ * context is provided.
+ *
+ * @event notified event
+ * @context pointer to the notification count
+ */
+static void EFIAPI notify(struct efi_event *event, void *context)
+{
+ unsigned int *count = context;
+
+ if (count)
+ ++*count;
+}
+
+/*
+ * Setup unit test.
+ *
+ * @handle: handle of the loaded image
+ * @systable: system table
+ * @return: EFI_ST_SUCCESS for success
+ */
+static int setup(const efi_handle_t handle,
+ const struct efi_system_table *systable)
+{
+ boottime = systable->boottime;
+
+ return EFI_ST_SUCCESS;
+}
+
+/*
+ * Execute unit test.
+ *
+ * Create multiple events in an event group. Signal each event once and check
+ * that all events are notified once in each round.
+ *
+ * @return: EFI_ST_SUCCESS for success
+ */
+static int execute(void)
+{
+ unsigned int counter[GROUP_SIZE] = {0};
+ struct efi_event *events[GROUP_SIZE];
+ size_t i, j;
+ efi_status_t ret;
+
+ for (i = 0; i < GROUP_SIZE; ++i) {
+ ret = boottime->create_event_ex(0, TPL_NOTIFY,
+ notify, (void *)&counter[i],
+ &event_group, &events[i]);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Failed to create event\n");
+ return EFI_ST_FAILURE;
+ }
+ }
+
+ for (i = 0; i < GROUP_SIZE; ++i) {
+ ret = boottime->signal_event(events[i]);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Failed to signal event\n");
+ return EFI_ST_FAILURE;
+ }
+ for (j = 0; j < GROUP_SIZE; ++j) {
+ if (counter[j] != i) {
+ efi_st_printf("i %u, j %u, count %u\n",
+ (unsigned int)i, (unsigned int)j,
+ (unsigned int)counter[j]);
+ efi_st_error(
+ "Notification function was called\n");
+ return EFI_ST_FAILURE;
+ }
+ /* Clear signaled state */
+ ret = boottime->check_event(events[j]);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Event was not signaled\n");
+ return EFI_ST_FAILURE;
+ }
+ if (counter[j] != i) {
+ efi_st_printf("i %u, j %u, count %u\n",
+ (unsigned int)i, (unsigned int)j,
+ (unsigned int)counter[j]);
+ efi_st_error(
+ "Notification function was called\n");
+ return EFI_ST_FAILURE;
+ }
+ /* Call notification function */
+ ret = boottime->check_event(events[j]);
+ if (ret != EFI_NOT_READY) {
+ efi_st_error(
+ "Signaled state not cleared\n");
+ return EFI_ST_FAILURE;
+ }
+ if (counter[j] != i + 1) {
+ efi_st_printf("i %u, j %u, count %u\n",
+ (unsigned int)i, (unsigned int)j,
+ (unsigned int)counter[j]);
+ efi_st_error(
+ "Nofification function not called\n");
+ return EFI_ST_FAILURE;
+ }
+ }
+ }
+
+ for (i = 0; i < GROUP_SIZE; ++i) {
+ ret = boottime->close_event(events[i]);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Failed to close event\n");
+ return EFI_ST_FAILURE;
+ }
+ }
+
+ return EFI_ST_SUCCESS;
+}
+
+EFI_UNIT_TEST(eventgoups) = {
+ .name = "event groups",
+ .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
+ .setup = setup,
+ .execute = execute,
+};
--
2.14.2
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [U-Boot] [PATCH 5/5] efi_selftest: unit test for event groups
2018-02-18 14:17 ` [U-Boot] [PATCH 5/5] efi_selftest: unit test for " Heinrich Schuchardt
@ 2018-03-12 17:59 ` Heinrich Schuchardt
2018-03-12 19:50 ` Alexander Graf
0 siblings, 1 reply; 8+ messages in thread
From: Heinrich Schuchardt @ 2018-03-12 17:59 UTC (permalink / raw)
To: u-boot
On 02/18/2018 03:17 PM, Heinrich Schuchardt wrote:
> Supply a unit test for event groups.
>
> Create multiple events in an event group. Signal each event once and check
> that all events are notified once in each round.
>
> Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Hello Alex,
you merged patch 1-4 of this series. Is there a problem with this patch
providing a unit test?
Regards
Heinrich
^ permalink raw reply [flat|nested] 8+ messages in thread
* [U-Boot] [PATCH 5/5] efi_selftest: unit test for event groups
2018-03-12 17:59 ` Heinrich Schuchardt
@ 2018-03-12 19:50 ` Alexander Graf
0 siblings, 0 replies; 8+ messages in thread
From: Alexander Graf @ 2018-03-12 19:50 UTC (permalink / raw)
To: u-boot
On 12.03.18 18:59, Heinrich Schuchardt wrote:
> On 02/18/2018 03:17 PM, Heinrich Schuchardt wrote:
>> Supply a unit test for event groups.
>>
>> Create multiple events in an event group. Signal each event once and check
>> that all events are notified once in each round.
>>
>> Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
>
> Hello Alex,
>
> you merged patch 1-4 of this series. Is there a problem with this patch
> providing a unit test?
Not at all, it probably just slipped through :)
Alex
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2018-03-12 19:50 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-02-18 14:17 [U-Boot] [PATCH 0/5] efi_loader: implement event groups Heinrich Schuchardt
2018-02-18 14:17 ` [U-Boot] [PATCH 1/5] efi_loader: fix formatting errors Heinrich Schuchardt
2018-02-18 14:17 ` [U-Boot] [PATCH 2/5] efi_loader: manage events in a linked list Heinrich Schuchardt
2018-02-18 14:17 ` [U-Boot] [PATCH 3/5] efi_loader: define GUIDS for event groups Heinrich Schuchardt
2018-02-18 14:17 ` [U-Boot] [PATCH 4/5] efi_loader: implement " Heinrich Schuchardt
2018-02-18 14:17 ` [U-Boot] [PATCH 5/5] efi_selftest: unit test for " Heinrich Schuchardt
2018-03-12 17:59 ` Heinrich Schuchardt
2018-03-12 19:50 ` Alexander Graf
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.