Intel Extensible Firmware Interface User Manual
Page 105

Services — Boot Services
Version 1.10
12/01/02
5-7
//*******************************************************
// EFI_EVENT_NOTIFY
//*******************************************************
typedef
VOID
(EFIAPI *EFI_EVENT_NOTIFY) (
IN EFI_EVENT
Event,
IN VOID
*Context
);
Event
Event whose notification function is being invoked.
Context
Pointer to the notification function’s context, which is
implementation-dependent.
Context
corresponds to
NotifyContext
in
Description
The
CreateEvent()
function creates a new event of type
Type
and returns it in the location
referenced by
Event
. The event’s notification function, context, and task priority level are
specified by
NotifyFunction
,
NotifyContext
, and
NotifyTpl
, respectively.
Events exist in one of two states, “waiting” or “signaled.” When an event is created, firmware puts
it in the “waiting” state. When the event is signaled, firmware changes its state to “signaled” and, if
EVT_NOTIFY_SIGNAL
is specified, places a call to its notification function in a FIFO queue.
There is a queue for each of the “basic” task priority levels defined in Section 5.1
(
TPL_APPLICATION
,
TPL_CALLBACK
, and
TPL_NOTIFY
). The functions in these queues are
invoked in FIFO order, starting with the highest priority level queue and proceeding to the lowest
priority queue that is unmasked by the current TPL. If the current TPL is equal to or greater than
the queued notification, it will wait until the TPL is lowered via
In a general sense, there are two “types” of events, synchronous and asynchronous. Asynchronous
events are closely related to timers and are used to support periodic or timed interruption of
program execution. This capability is typically used with device drivers. For example, a network
device driver that needs to poll for the presence of new packets could create an event whose type
includes
EVT_TIMER
and then call the
function. When the timer expires, the
firmware signals the event.
Synchronous events have no particular relationship to timers. Instead, they are used to ensure that
certain activities occur following a call to a specific interface function. One example of this is the
cleanup that needs to be performed in response to a call to the
function.
ExitBootServices()
can clean up the firmware since it understands firmware internals, but it
cannot clean up on behalf of drivers that have been loaded into the system. The drivers have to do
that themselves by creating an event whose type is
EVT_SIGNAL_EXIT_BOOT_SERVICES
and
whose notification function is a function within the driver itself. Then, when
ExitBootServices()
has finished its cleanup, it signals each event of type
EVT_SIGNAL_EXIT_BOOT_SERVICES
.
Another example of the use of synchronous events occurs when an event of type
EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE
is used in conjunction with the
function in Chapter 6.