uboot/lib/efi_selftest/efi_selftest_event_groups.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * efi_selftest_event_groups
   4 *
   5 * Copyright (c) 2018 Heinrich Schuchardt <xypron.glpk@gmx.de>
   6 *
   7 * This test checks the notification of group events and the
   8 * following services:
   9 * CreateEventEx, CloseEvent, SignalEvent, CheckEvent.
  10 */
  11
  12#include <efi_selftest.h>
  13
  14#define GROUP_SIZE 16
  15
  16static struct efi_boot_services *boottime;
  17static efi_guid_t event_group =
  18        EFI_GUID(0x2335905b, 0xc3b9, 0x4221, 0xa3, 0x71,
  19                 0x0e, 0x5b, 0x45, 0xc0, 0x56, 0x91);
  20
  21/*
  22 * Notification function, increments the notification count if parameter
  23 * context is provided.
  24 *
  25 * @event       notified event
  26 * @context     pointer to the notification count
  27 */
  28static void EFIAPI notify(struct efi_event *event, void *context)
  29{
  30        unsigned int *count = context;
  31
  32        if (count)
  33                ++*count;
  34}
  35
  36/*
  37 * Setup unit test.
  38 *
  39 * @handle:     handle of the loaded image
  40 * @systable:   system table
  41 * @return:     EFI_ST_SUCCESS for success
  42 */
  43static int setup(const efi_handle_t handle,
  44                 const struct efi_system_table *systable)
  45{
  46        boottime = systable->boottime;
  47
  48        return EFI_ST_SUCCESS;
  49}
  50
  51/*
  52 * Execute unit test.
  53 *
  54 * Create multiple events in an event group. Signal each event once and check
  55 * that all events are notified once in each round.
  56 *
  57 * @return:     EFI_ST_SUCCESS for success
  58 */
  59static int execute(void)
  60{
  61        unsigned int counter[GROUP_SIZE] = {0};
  62        struct efi_event *events[GROUP_SIZE];
  63        size_t i, j;
  64        efi_status_t ret;
  65
  66        for (i = 0; i < GROUP_SIZE; ++i) {
  67                ret = boottime->create_event_ex(0, TPL_NOTIFY,
  68                                                notify, (void *)&counter[i],
  69                                                &event_group, &events[i]);
  70                if (ret != EFI_SUCCESS) {
  71                        efi_st_error("Failed to create event\n");
  72                        return EFI_ST_FAILURE;
  73                }
  74        }
  75
  76        for (i = 0; i < GROUP_SIZE; ++i) {
  77                ret = boottime->signal_event(events[i]);
  78                if (ret != EFI_SUCCESS) {
  79                        efi_st_error("Failed to signal event\n");
  80                        return EFI_ST_FAILURE;
  81                }
  82                for (j = 0; j < GROUP_SIZE; ++j) {
  83                        if (counter[j] != 2 * i + 1) {
  84                                efi_st_printf("i %u, j %u, count %u\n",
  85                                              (unsigned int)i, (unsigned int)j,
  86                                              (unsigned int)counter[j]);
  87                                efi_st_error("Notification function was not called\n");
  88                                return EFI_ST_FAILURE;
  89                        }
  90                        /* Clear signaled state */
  91                        ret = boottime->check_event(events[j]);
  92                        if (ret != EFI_SUCCESS) {
  93                                efi_st_error("Event was not signaled\n");
  94                                return EFI_ST_FAILURE;
  95                        }
  96                        if (counter[j] != 2 * i + 1) {
  97                                efi_st_printf("i %u, j %u, count %u\n",
  98                                              (unsigned int)i, (unsigned int)j,
  99                                              (unsigned int)counter[j]);
 100                                efi_st_error(
 101                                        "Notification function was called\n");
 102                                return EFI_ST_FAILURE;
 103                        }
 104                        /* Call notification function  */
 105                        ret = boottime->check_event(events[j]);
 106                        if (ret != EFI_NOT_READY) {
 107                                efi_st_error(
 108                                        "Signaled state not cleared\n");
 109                                return EFI_ST_FAILURE;
 110                        }
 111                        if (counter[j] != 2 * i + 2) {
 112                                efi_st_printf("i %u, j %u, count %u\n",
 113                                              (unsigned int)i, (unsigned int)j,
 114                                              (unsigned int)counter[j]);
 115                                efi_st_error(
 116                                        "Notification function not called\n");
 117                                return EFI_ST_FAILURE;
 118                        }
 119                }
 120        }
 121
 122        for (i = 0; i < GROUP_SIZE; ++i) {
 123                ret = boottime->close_event(events[i]);
 124                if (ret != EFI_SUCCESS) {
 125                        efi_st_error("Failed to close event\n");
 126                        return EFI_ST_FAILURE;
 127                }
 128        }
 129
 130        return EFI_ST_SUCCESS;
 131}
 132
 133EFI_UNIT_TEST(eventgoups) = {
 134        .name = "event groups",
 135        .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
 136        .setup = setup,
 137        .execute = execute,
 138};
 139