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