uboot/lib/efi_selftest/efi_selftest_exitbootservices.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * efi_selftest_exitbootservices
   4 *
   5 * Copyright (c) 2017 Heinrich Schuchardt <xypron.glpk@gmx.de>
   6 *
   7 * This unit test checks that the notification function of an
   8 * EVT_SIGNAL_EXIT_BOOT_SERVICES event is called exactly once.
   9 */
  10
  11#include <efi_selftest.h>
  12
  13static struct efi_boot_services *boottime;
  14static struct efi_event *event_notify;
  15static unsigned int notification_count;
  16
  17/*
  18 * Notification function, increments the notification count.
  19 *
  20 * @event       notified event
  21 * @context     pointer to the notification count
  22 */
  23static void EFIAPI notify(struct efi_event *event, void *context)
  24{
  25        unsigned int *count = context;
  26
  27        ++*count;
  28}
  29
  30/*
  31 * Setup unit test.
  32 *
  33 * Create an EVT_SIGNAL_EXIT_BOOT_SERVICES event.
  34 *
  35 * @handle:     handle of the loaded image
  36 * @systable:   system table
  37 * @return:     EFI_ST_SUCCESS for success
  38 */
  39static int setup(const efi_handle_t handle,
  40                 const struct efi_system_table *systable)
  41{
  42        efi_status_t ret;
  43
  44        boottime = systable->boottime;
  45
  46        notification_count = 0;
  47        ret = boottime->create_event(EVT_SIGNAL_EXIT_BOOT_SERVICES,
  48                                     TPL_CALLBACK, notify,
  49                                     (void *)&notification_count,
  50                                     &event_notify);
  51        if (ret != EFI_SUCCESS) {
  52                efi_st_error("could not create event\n");
  53                return EFI_ST_FAILURE;
  54        }
  55        return EFI_ST_SUCCESS;
  56}
  57
  58/*
  59 * Execute unit test.
  60 *
  61 * Check that the notification function of the EVT_SIGNAL_EXIT_BOOT_SERVICES
  62 * event has been called.
  63 *
  64 * Call ExitBootServices again and check that the notification function is
  65 * not called again.
  66 *
  67 * @return:     EFI_ST_SUCCESS for success
  68 */
  69static int execute(void)
  70{
  71        if (notification_count != 1) {
  72                efi_st_error("ExitBootServices was not notified\n");
  73                return EFI_ST_FAILURE;
  74        }
  75        efi_st_exit_boot_services();
  76        if (notification_count != 1) {
  77                efi_st_error("ExitBootServices was notified twice\n");
  78                return EFI_ST_FAILURE;
  79        }
  80        return EFI_ST_SUCCESS;
  81}
  82
  83EFI_UNIT_TEST(exitbootservices) = {
  84        .name = "ExitBootServices",
  85        .phase = EFI_SETUP_BEFORE_BOOTTIME_EXIT,
  86        .setup = setup,
  87        .execute = execute,
  88};
  89