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