xref: /DragonStub/lib/event.c (revision 8071303f52f376de3357b223ce8905598de1f913)
1 /*++
2 
3 Copyright (c) 1998  Intel Corporation
4 
5 Module Name:
6 
7     event.c
8 
9 Abstract:
10 
11 
12 
13 
14 Revision History
15 
16 --*/
17 
18 #include "lib.h"
19 
20 
21 EFI_EVENT
22 LibCreateProtocolNotifyEvent (
23     IN EFI_GUID             *ProtocolGuid,
24     IN EFI_TPL              NotifyTpl,
25     IN EFI_EVENT_NOTIFY     NotifyFunction,
26     IN VOID                 *NotifyContext,
27     OUT VOID                *Registration
28     )
29 {
30     EFI_STATUS              Status;
31     EFI_EVENT               Event;
32 
33     //
34     // Create the event
35     //
36 
37     Status = uefi_call_wrapper(
38 		    BS->CreateEvent,
39 			5,
40 		    EVT_NOTIFY_SIGNAL,
41 		    NotifyTpl,
42 		    NotifyFunction,
43 		    NotifyContext,
44 		    &Event
45 		    );
46     if ( EFI_ERROR( Status ) ) return NULL ;
47     ASSERT (!EFI_ERROR(Status));
48 
49     //
50     // Register for protocol notifactions on this event
51     //
52 
53     Status = uefi_call_wrapper(
54 		    BS->RegisterProtocolNotify,
55 			3,
56                     ProtocolGuid,
57                     Event,
58                     Registration
59                     );
60     if ( EFI_ERROR( Status ) ) return NULL ;
61     ASSERT (!EFI_ERROR(Status));
62 
63     //
64     // Kick the event so we will perform an initial pass of
65     // current installed drivers
66     //
67 
68     uefi_call_wrapper(BS->SignalEvent, 1, Event);
69     return Event;
70 }
71 
72 
73 EFI_STATUS
74 WaitForSingleEvent (
75     IN EFI_EVENT        Event,
76     IN UINT64           Timeout OPTIONAL
77     )
78 {
79     EFI_STATUS          Status;
80     UINTN               Index;
81     EFI_EVENT           TimerEvent;
82     EFI_EVENT           WaitList[2];
83 
84     if (Timeout) {
85         //
86         // Create a timer event
87         //
88 
89         Status = uefi_call_wrapper(BS->CreateEvent, 5, EVT_TIMER, 0, NULL, NULL, &TimerEvent);
90         if (!EFI_ERROR(Status)) {
91 
92             //
93             // Set the timer event
94             //
95 
96             uefi_call_wrapper(BS->SetTimer, 3, TimerEvent, TimerRelative, Timeout);
97 
98             //
99             // Wait for the original event or the timer
100             //
101 
102             WaitList[0] = Event;
103             WaitList[1] = TimerEvent;
104             Status = uefi_call_wrapper(BS->WaitForEvent, 3, 2, WaitList, &Index);
105             uefi_call_wrapper(BS->CloseEvent, 1, TimerEvent);
106 
107             //
108             // If the timer expired, change the return to timed out
109             //
110 
111             if (!EFI_ERROR(Status)  &&  Index == 1) {
112                 Status = EFI_TIMEOUT;
113             }
114         }
115 
116     } else {
117 
118         //
119         // No timeout... just wait on the event
120         //
121 
122         Status = uefi_call_wrapper(BS->WaitForEvent, 3, 1, &Event, &Index);
123         ASSERT (!EFI_ERROR(Status));
124         ASSERT (Index == 0);
125     }
126 
127     return Status;
128 }
129 
130 VOID
131 WaitForEventWithTimeout (
132     IN  EFI_EVENT       Event,
133     IN  UINTN           Timeout,
134     IN  UINTN           Row,
135     IN  UINTN           Column,
136     IN  CHAR16          *String,
137     IN  EFI_INPUT_KEY   TimeoutKey,
138     OUT EFI_INPUT_KEY   *Key
139     )
140 {
141     EFI_STATUS      Status;
142 
143     do {
144         PrintAt (Column, Row, String, Timeout);
145         Status = WaitForSingleEvent (Event, 10000000);
146         if (Status == EFI_SUCCESS) {
147             if (!EFI_ERROR(uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2, ST->ConIn, Key))) {
148                 return;
149             }
150         }
151     } while (Timeout > 0);
152     CopyMem(Key, &TimeoutKey, sizeof(EFI_INPUT_KEY));
153 }
154 
155