xref: /DragonStub/lib/event.c (revision b5b6a81af07a3dfded64bd9a806fcdec46a8203c)
1530d68baSNigel Croxon /*++
2530d68baSNigel Croxon 
3530d68baSNigel Croxon Copyright (c) 1998  Intel Corporation
4530d68baSNigel Croxon 
5530d68baSNigel Croxon Module Name:
6530d68baSNigel Croxon 
7530d68baSNigel Croxon     event.c
8530d68baSNigel Croxon 
9530d68baSNigel Croxon Abstract:
10530d68baSNigel Croxon 
11530d68baSNigel Croxon 
12530d68baSNigel Croxon 
13530d68baSNigel Croxon 
14530d68baSNigel Croxon Revision History
15530d68baSNigel Croxon 
16530d68baSNigel Croxon --*/
17530d68baSNigel Croxon 
18530d68baSNigel Croxon #include "lib.h"
19530d68baSNigel Croxon 
20530d68baSNigel Croxon 
21530d68baSNigel Croxon EFI_EVENT
LibCreateProtocolNotifyEvent(IN EFI_GUID * ProtocolGuid,IN EFI_TPL NotifyTpl,IN EFI_EVENT_NOTIFY NotifyFunction,IN VOID * NotifyContext,OUT VOID * Registration)22530d68baSNigel Croxon LibCreateProtocolNotifyEvent (
23530d68baSNigel Croxon     IN EFI_GUID             *ProtocolGuid,
24530d68baSNigel Croxon     IN EFI_TPL              NotifyTpl,
25530d68baSNigel Croxon     IN EFI_EVENT_NOTIFY     NotifyFunction,
26530d68baSNigel Croxon     IN VOID                 *NotifyContext,
27530d68baSNigel Croxon     OUT VOID                *Registration
28530d68baSNigel Croxon     )
29530d68baSNigel Croxon {
30530d68baSNigel Croxon     EFI_STATUS              Status;
31530d68baSNigel Croxon     EFI_EVENT               Event;
32530d68baSNigel Croxon 
33530d68baSNigel Croxon     //
34530d68baSNigel Croxon     // Create the event
35530d68baSNigel Croxon     //
36530d68baSNigel Croxon 
37530d68baSNigel Croxon     Status = uefi_call_wrapper(
38530d68baSNigel Croxon 		    BS->CreateEvent,
39530d68baSNigel Croxon 			5,
40530d68baSNigel Croxon 		    EVT_NOTIFY_SIGNAL,
41530d68baSNigel Croxon 		    NotifyTpl,
42530d68baSNigel Croxon 		    NotifyFunction,
43530d68baSNigel Croxon 		    NotifyContext,
44530d68baSNigel Croxon 		    &Event
45530d68baSNigel Croxon 		    );
46530d68baSNigel Croxon     if ( EFI_ERROR( Status ) ) return NULL ;
47530d68baSNigel Croxon     ASSERT (!EFI_ERROR(Status));
48530d68baSNigel Croxon 
49530d68baSNigel Croxon     //
50530d68baSNigel Croxon     // Register for protocol notifactions on this event
51530d68baSNigel Croxon     //
52530d68baSNigel Croxon 
53530d68baSNigel Croxon     Status = uefi_call_wrapper(
54530d68baSNigel Croxon 		    BS->RegisterProtocolNotify,
55530d68baSNigel Croxon 			3,
56530d68baSNigel Croxon                     ProtocolGuid,
57530d68baSNigel Croxon                     Event,
58530d68baSNigel Croxon                     Registration
59530d68baSNigel Croxon                     );
60530d68baSNigel Croxon     if ( EFI_ERROR( Status ) ) return NULL ;
61530d68baSNigel Croxon     ASSERT (!EFI_ERROR(Status));
62530d68baSNigel Croxon 
63530d68baSNigel Croxon     //
64530d68baSNigel Croxon     // Kick the event so we will perform an initial pass of
65530d68baSNigel Croxon     // current installed drivers
66530d68baSNigel Croxon     //
67530d68baSNigel Croxon 
68530d68baSNigel Croxon     uefi_call_wrapper(BS->SignalEvent, 1, Event);
69530d68baSNigel Croxon     return Event;
70530d68baSNigel Croxon }
71530d68baSNigel Croxon 
72530d68baSNigel Croxon 
73530d68baSNigel Croxon EFI_STATUS
WaitForSingleEvent(IN EFI_EVENT Event,IN UINT64 Timeout OPTIONAL)74530d68baSNigel Croxon WaitForSingleEvent (
75530d68baSNigel Croxon     IN EFI_EVENT        Event,
76530d68baSNigel Croxon     IN UINT64           Timeout OPTIONAL
77530d68baSNigel Croxon     )
78530d68baSNigel Croxon {
79530d68baSNigel Croxon     EFI_STATUS          Status;
80530d68baSNigel Croxon     UINTN               Index;
81530d68baSNigel Croxon     EFI_EVENT           TimerEvent;
82530d68baSNigel Croxon     EFI_EVENT           WaitList[2];
83530d68baSNigel Croxon 
84530d68baSNigel Croxon     if (Timeout) {
85530d68baSNigel Croxon         //
86530d68baSNigel Croxon         // Create a timer event
87530d68baSNigel Croxon         //
88530d68baSNigel Croxon 
89530d68baSNigel Croxon         Status = uefi_call_wrapper(BS->CreateEvent, 5, EVT_TIMER, 0, NULL, NULL, &TimerEvent);
90530d68baSNigel Croxon         if (!EFI_ERROR(Status)) {
91530d68baSNigel Croxon 
92530d68baSNigel Croxon             //
93530d68baSNigel Croxon             // Set the timer event
94530d68baSNigel Croxon             //
95530d68baSNigel Croxon 
96530d68baSNigel Croxon             uefi_call_wrapper(BS->SetTimer, 3, TimerEvent, TimerRelative, Timeout);
97530d68baSNigel Croxon 
98530d68baSNigel Croxon             //
99530d68baSNigel Croxon             // Wait for the original event or the timer
100530d68baSNigel Croxon             //
101530d68baSNigel Croxon 
102530d68baSNigel Croxon             WaitList[0] = Event;
103530d68baSNigel Croxon             WaitList[1] = TimerEvent;
104530d68baSNigel Croxon             Status = uefi_call_wrapper(BS->WaitForEvent, 3, 2, WaitList, &Index);
105530d68baSNigel Croxon             uefi_call_wrapper(BS->CloseEvent, 1, TimerEvent);
106530d68baSNigel Croxon 
107530d68baSNigel Croxon             //
108530d68baSNigel Croxon             // If the timer expired, change the return to timed out
109530d68baSNigel Croxon             //
110530d68baSNigel Croxon 
111530d68baSNigel Croxon             if (!EFI_ERROR(Status)  &&  Index == 1) {
112530d68baSNigel Croxon                 Status = EFI_TIMEOUT;
113530d68baSNigel Croxon             }
114530d68baSNigel Croxon         }
115530d68baSNigel Croxon 
116530d68baSNigel Croxon     } else {
117530d68baSNigel Croxon 
118530d68baSNigel Croxon         //
119530d68baSNigel Croxon         // No timeout... just wait on the event
120530d68baSNigel Croxon         //
121530d68baSNigel Croxon 
122530d68baSNigel Croxon         Status = uefi_call_wrapper(BS->WaitForEvent, 3, 1, &Event, &Index);
123530d68baSNigel Croxon         ASSERT (!EFI_ERROR(Status));
124530d68baSNigel Croxon         ASSERT (Index == 0);
125530d68baSNigel Croxon     }
126530d68baSNigel Croxon 
127530d68baSNigel Croxon     return Status;
128530d68baSNigel Croxon }
129530d68baSNigel Croxon 
130530d68baSNigel Croxon 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)131530d68baSNigel Croxon WaitForEventWithTimeout (
132530d68baSNigel Croxon     IN  EFI_EVENT       Event,
133530d68baSNigel Croxon     IN  UINTN           Timeout,
134530d68baSNigel Croxon     IN  UINTN           Row,
135530d68baSNigel Croxon     IN  UINTN           Column,
136530d68baSNigel Croxon     IN  CHAR16          *String,
137530d68baSNigel Croxon     IN  EFI_INPUT_KEY   TimeoutKey,
138530d68baSNigel Croxon     OUT EFI_INPUT_KEY   *Key
139530d68baSNigel Croxon     )
140530d68baSNigel Croxon {
141530d68baSNigel Croxon     EFI_STATUS      Status;
142530d68baSNigel Croxon 
143530d68baSNigel Croxon     do {
144530d68baSNigel Croxon         PrintAt (Column, Row, String, Timeout);
145530d68baSNigel Croxon         Status = WaitForSingleEvent (Event, 10000000);
146530d68baSNigel Croxon         if (Status == EFI_SUCCESS) {
147530d68baSNigel Croxon             if (!EFI_ERROR(uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2, ST->ConIn, Key))) {
148530d68baSNigel Croxon                 return;
149530d68baSNigel Croxon             }
150530d68baSNigel Croxon         }
151530d68baSNigel Croxon     } while (Timeout > 0);
152*b5b6a81aSNigel Croxon     CopyMem(Key, &TimeoutKey, sizeof(EFI_INPUT_KEY));
153530d68baSNigel Croxon }
154530d68baSNigel Croxon 
155