1 /* $NetBSD: event.c,v 1.2 2017/02/04 18:08:29 mlelstv Exp $ */ 2 3 /*++ 4 5 Copyright (c) 1998 Intel Corporation 6 7 Module Name: 8 9 event.c 10 11 Abstract: 12 13 14 15 16 Revision History 17 18 --*/ 19 20 #include "lib.h" 21 22 23 EFI_EVENT 24 LibCreateProtocolNotifyEvent ( 25 IN EFI_GUID *ProtocolGuid, 26 IN EFI_TPL NotifyTpl, 27 IN EFI_EVENT_NOTIFY NotifyFunction, 28 IN VOID *NotifyContext, 29 OUT VOID *Registration 30 ) 31 { 32 #ifdef EFI_DEBUG 33 EFI_STATUS Status; 34 #else 35 EFI_STATUS Status __unused; 36 #endif 37 EFI_EVENT Event; 38 39 // 40 // Create the event 41 // 42 43 Status = uefi_call_wrapper( 44 BS->CreateEvent, 45 5, 46 EVT_NOTIFY_SIGNAL, 47 NotifyTpl, 48 NotifyFunction, 49 NotifyContext, 50 &Event 51 ); 52 ASSERT (!EFI_ERROR(Status)); 53 54 // 55 // Register for protocol notifactions on this event 56 // 57 58 Status = uefi_call_wrapper( 59 BS->RegisterProtocolNotify, 60 3, 61 ProtocolGuid, 62 Event, 63 Registration 64 ); 65 66 ASSERT (!EFI_ERROR(Status)); 67 68 // 69 // Kick the event so we will perform an initial pass of 70 // current installed drivers 71 // 72 73 uefi_call_wrapper(BS->SignalEvent, 1, Event); 74 return Event; 75 } 76 77 78 EFI_STATUS 79 WaitForSingleEvent ( 80 IN EFI_EVENT Event, 81 IN UINT64 Timeout OPTIONAL 82 ) 83 { 84 EFI_STATUS Status; 85 UINTN Index; 86 EFI_EVENT TimerEvent; 87 EFI_EVENT WaitList[2]; 88 89 if (Timeout) { 90 // 91 // Create a timer event 92 // 93 94 Status = uefi_call_wrapper(BS->CreateEvent, 5, EVT_TIMER, 0, NULL, NULL, &TimerEvent); 95 if (!EFI_ERROR(Status)) { 96 97 // 98 // Set the timer event 99 // 100 101 uefi_call_wrapper(BS->SetTimer, 3, TimerEvent, TimerRelative, Timeout); 102 103 // 104 // Wait for the original event or the timer 105 // 106 107 WaitList[0] = Event; 108 WaitList[1] = TimerEvent; 109 Status = uefi_call_wrapper(BS->WaitForEvent, 3, 2, WaitList, &Index); 110 uefi_call_wrapper(BS->CloseEvent, 1, TimerEvent); 111 112 // 113 // If the timer expired, change the return to timed out 114 // 115 116 if (!EFI_ERROR(Status) && Index == 1) { 117 Status = EFI_TIMEOUT; 118 } 119 } 120 121 } else { 122 123 // 124 // No timeout... just wait on the event 125 // 126 127 Status = uefi_call_wrapper(BS->WaitForEvent, 3, 1, &Event, &Index); 128 ASSERT (!EFI_ERROR(Status)); 129 ASSERT (Index == 0); 130 } 131 132 return Status; 133 } 134 135 VOID 136 WaitForEventWithTimeout ( 137 IN EFI_EVENT Event, 138 IN UINTN Timeout, 139 IN UINTN Row, 140 IN UINTN Column, 141 IN CHAR16 *String, 142 IN EFI_INPUT_KEY TimeoutKey, 143 OUT EFI_INPUT_KEY *Key 144 ) 145 { 146 EFI_STATUS Status; 147 148 do { 149 PrintAt (Column, Row, String, Timeout); 150 Status = WaitForSingleEvent (Event, 10000000); 151 if (Status == EFI_SUCCESS) { 152 if (!EFI_ERROR(uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2, ST->ConIn, Key))) { 153 return; 154 } 155 } 156 } while (Timeout > 0); 157 *Key = TimeoutKey; 158 } 159 160