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