1 /* $NetBSD: event.c,v 1.3 2018/08/16 18:22:05 jmcneill 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
LibCreateProtocolNotifyEvent(IN EFI_GUID * ProtocolGuid,IN EFI_TPL NotifyTpl,IN EFI_EVENT_NOTIFY NotifyFunction,IN VOID * NotifyContext,OUT VOID * Registration)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 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
79 EFI_STATUS
WaitForSingleEvent(IN EFI_EVENT Event,IN UINT64 Timeout OPTIONAL)80 WaitForSingleEvent (
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
136 VOID
WaitForEventWithTimeout(IN EFI_EVENT Event,IN UINTN Timeout,IN UINTN Row,IN UINTN Column,IN CHAR16 * String,IN EFI_INPUT_KEY TimeoutKey,OUT EFI_INPUT_KEY * Key)137 WaitForEventWithTimeout (
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