xref: /netbsd-src/sys/external/bsd/gnu-efi/dist/lib/event.c (revision bdc22b2e01993381dcefeff2bc9b56ca75a4235c)
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