efi_selftest_event_groups.c 3.3 KB

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