1/*++
2
3Copyright (c) 1998  Intel Corporation
4
5Module Name:
6
7    event.c
8
9Abstract:
10
11
12
13
14Revision History
15
16--*/
17
18#include "lib.h"
19
20
21EFI_EVENT
22LibCreateProtocolNotifyEvent (
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
72EFI_STATUS
73WaitForSingleEvent (
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
129VOID
130WaitForEventWithTimeout (
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
154