1 /*	$NetBSD: event.c,v 1.1.1.1 2014/04/01 16:16:06 jakllsch 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     EFI_STATUS              Status;
33     EFI_EVENT               Event;
34 
35     //
36     // Create the event
37     //
38 
39     Status = uefi_call_wrapper(
40 		    BS->CreateEvent,
41 			5,
42 		    EVT_NOTIFY_SIGNAL,
43 		    NotifyTpl,
44 		    NotifyFunction,
45 		    NotifyContext,
46 		    &Event
47 		    );
48     ASSERT (!EFI_ERROR(Status));
49 
50     //
51     // Register for protocol notifactions on this event
52     //
53 
54     Status = uefi_call_wrapper(
55 		    BS->RegisterProtocolNotify,
56 			3,
57                     ProtocolGuid,
58                     Event,
59                     Registration
60                     );
61 
62     ASSERT (!EFI_ERROR(Status));
63 
64     //
65     // Kick the event so we will perform an initial pass of
66     // current installed drivers
67     //
68 
69     uefi_call_wrapper(BS->SignalEvent, 1, Event);
70     return Event;
71 }
72 
73 
74 EFI_STATUS
WaitForSingleEvent(IN EFI_EVENT Event,IN UINT64 Timeout OPTIONAL)75 WaitForSingleEvent (
76     IN EFI_EVENT        Event,
77     IN UINT64           Timeout OPTIONAL
78     )
79 {
80     EFI_STATUS          Status;
81     UINTN               Index;
82     EFI_EVENT           TimerEvent;
83     EFI_EVENT           WaitList[2];
84 
85     if (Timeout) {
86         //
87         // Create a timer event
88         //
89 
90         Status = uefi_call_wrapper(BS->CreateEvent, 5, EVT_TIMER, 0, NULL, NULL, &TimerEvent);
91         if (!EFI_ERROR(Status)) {
92 
93             //
94             // Set the timer event
95             //
96 
97             uefi_call_wrapper(BS->SetTimer, 3, TimerEvent, TimerRelative, Timeout);
98 
99             //
100             // Wait for the original event or the timer
101             //
102 
103             WaitList[0] = Event;
104             WaitList[1] = TimerEvent;
105             Status = uefi_call_wrapper(BS->WaitForEvent, 3, 2, WaitList, &Index);
106             uefi_call_wrapper(BS->CloseEvent, 1, TimerEvent);
107 
108             //
109             // If the timer expired, change the return to timed out
110             //
111 
112             if (!EFI_ERROR(Status)  &&  Index == 1) {
113                 Status = EFI_TIMEOUT;
114             }
115         }
116 
117     } else {
118 
119         //
120         // No timeout... just wait on the event
121         //
122 
123         Status = uefi_call_wrapper(BS->WaitForEvent, 3, 1, &Event, &Index);
124         ASSERT (!EFI_ERROR(Status));
125         ASSERT (Index == 0);
126     }
127 
128     return Status;
129 }
130 
131 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)132 WaitForEventWithTimeout (
133     IN  EFI_EVENT       Event,
134     IN  UINTN           Timeout,
135     IN  UINTN           Row,
136     IN  UINTN           Column,
137     IN  CHAR16          *String,
138     IN  EFI_INPUT_KEY   TimeoutKey,
139     OUT EFI_INPUT_KEY   *Key
140     )
141 {
142     EFI_STATUS      Status;
143 
144     do {
145         PrintAt (Column, Row, String, Timeout);
146         Status = WaitForSingleEvent (Event, 10000000);
147         if (Status == EFI_SUCCESS) {
148             if (!EFI_ERROR(uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2, ST->ConIn, Key))) {
149                 return;
150             }
151         }
152     } while (Timeout > 0);
153     *Key = TimeoutKey;
154 }
155 
156