mirror of
https://github.com/acidanthera/OpenCorePkg.git
synced 2025-12-08 19:25:01 +00:00
Updated minimal EFI Event support in userspace (#577)
This commit is contained in:
parent
849b04fdf4
commit
7897c1e039
1
.gitignore
vendored
1
.gitignore
vendored
@ -90,6 +90,7 @@ Utilities/TestProcessKernel/ProcessKernel
|
||||
Utilities/TestNtfsDxe/TestNtfsDxe
|
||||
Utilities/TestExt4Dxe/TestExt4Dxe
|
||||
Utilities/TestFatDxe/TestFatDxe
|
||||
Utilities/TestEvent/TestEvent
|
||||
Utilities/LegacyBoot/ROOT*
|
||||
Utilities/LegacyBoot/OpenCore*
|
||||
Utilities/LegacyBoot/boot*
|
||||
|
||||
@ -45,9 +45,9 @@ EFIAPI
|
||||
UserCreateEventEx (
|
||||
IN UINT32 Type,
|
||||
IN EFI_TPL NotifyTpl,
|
||||
IN EFI_EVENT_NOTIFY NotifyFunction,
|
||||
IN CONST VOID *NotifyContext,
|
||||
IN CONST EFI_GUID *EventGroup,
|
||||
IN EFI_EVENT_NOTIFY NotifyFunction OPTIONAL,
|
||||
IN CONST VOID *NotifyContext OPTIONAL,
|
||||
IN CONST EFI_GUID *EventGroup OPTIONAL,
|
||||
OUT EFI_EVENT *Event
|
||||
);
|
||||
|
||||
@ -77,8 +77,8 @@ EFIAPI
|
||||
UserCreateEvent (
|
||||
IN UINT32 Type,
|
||||
IN EFI_TPL NotifyTpl,
|
||||
IN EFI_EVENT_NOTIFY NotifyFunction,
|
||||
IN VOID *NotifyContext,
|
||||
IN EFI_EVENT_NOTIFY NotifyFunction OPTIONAL,
|
||||
IN VOID *NotifyContext OPTIONAL,
|
||||
OUT EFI_EVENT *Event
|
||||
);
|
||||
|
||||
|
||||
@ -15,43 +15,52 @@
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
// Event Descriptor
|
||||
struct USER_EVENT {
|
||||
// It is unused descriptor?
|
||||
/**
|
||||
Event descriptor
|
||||
|
||||
IsClosed Is it an unused descriptor?
|
||||
Signaled Is it a signaled event?
|
||||
Type The type of Event
|
||||
TplLevel The TPL Level of Event
|
||||
NotifyFn A callback function
|
||||
NotifyCtx A callback context
|
||||
TimerEmit The timer trigger time
|
||||
TimerDelta The timer triger delta
|
||||
**/
|
||||
typedef struct {
|
||||
BOOLEAN IsClosed;
|
||||
// Event is signaled?
|
||||
BOOLEAN Signaled;
|
||||
|
||||
// Event type
|
||||
UINT32 Type;
|
||||
// Event TPL Level
|
||||
EFI_TPL TplLevel;
|
||||
|
||||
// Callback function
|
||||
EFI_EVENT_NOTIFY NotifyFn;
|
||||
// Callback context
|
||||
VOID *NotifyCtx;
|
||||
|
||||
// Timer trigger time
|
||||
UINT64 TimerEmit;
|
||||
// Timer trigger delta
|
||||
UINT64 TimerDelta;
|
||||
};
|
||||
} USER_EVENT;
|
||||
|
||||
// for once init event subsystem
|
||||
static BOOLEAN event_need_init = 1;
|
||||
// current TPL level
|
||||
static EFI_TPL CurTPL = 0;
|
||||
// event descriptor's array
|
||||
static struct USER_EVENT events[USER_EVENT_MAXNUM];
|
||||
/**
|
||||
Local variables
|
||||
|
||||
mEventNeedInit Do we need to initialize the event subsystem?
|
||||
mCurTPL The current TPL value
|
||||
mEvents The static array of Event descriptor
|
||||
**/
|
||||
STATIC BOOLEAN mEventNeedInit = TRUE;
|
||||
STATIC EFI_TPL mCurTPL = 0;
|
||||
STATIC USER_EVENT mEvents[USER_EVENT_MAXNUM];
|
||||
|
||||
/**
|
||||
Returns current time in nanoseconds
|
||||
**/
|
||||
STATIC
|
||||
UINT64
|
||||
UserEventGetTimeNow (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
UINT64 TimeNow = 0;
|
||||
UINT64 TimeNow;
|
||||
|
||||
TimeNow = 0;
|
||||
|
||||
#if defined (_WIN32)
|
||||
|
||||
@ -65,47 +74,50 @@ UserEventGetTimeNow (
|
||||
TimeNow = TimeNow*1000000000;
|
||||
|
||||
#elif defined (__MACH__)
|
||||
clock_serv_t cclock;
|
||||
mach_timespec_t now;
|
||||
clock_serv_t Cclock;
|
||||
mach_timespec_t Now;
|
||||
|
||||
host_get_clock_service (mach_host_self (), SYSTEM_CLOCK, &cclock);
|
||||
clock_get_time (cclock, &now);
|
||||
mach_port_deallocate (mach_task_self (), cclock);
|
||||
host_get_clock_service (mach_host_self (), SYSTEM_CLOCK, &Cclock);
|
||||
clock_get_time (Cclock, &Now);
|
||||
mach_port_deallocate (mach_task_self (), Cclock);
|
||||
|
||||
TimeNow = (UINT64)now.tv_sec*1000000000 + now.tv_nsec;
|
||||
TimeNow = (UINT64)Now.tv_sec*1000000000 + Now.tv_nsec;
|
||||
|
||||
#else
|
||||
struct timespec now;
|
||||
struct timespec Now;
|
||||
|
||||
clock_gettime (CLOCK_MONOTONIC, &now);
|
||||
TimeNow = (UINT64)now.tv_sec*1000000000 + now.tv_nsec;
|
||||
clock_gettime (CLOCK_MONOTONIC, &Now);
|
||||
TimeNow = (UINT64)Now.tv_sec*1000000000 + Now.tv_nsec;
|
||||
|
||||
#endif
|
||||
|
||||
return TimeNow;
|
||||
}
|
||||
|
||||
// event allocator
|
||||
/**
|
||||
Allocates an Event descriptor
|
||||
**/
|
||||
STATIC
|
||||
struct USER_EVENT *
|
||||
USER_EVENT *
|
||||
UserEventAlloc (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
struct USER_EVENT *res = NULL;
|
||||
INTN Index;
|
||||
|
||||
for (INTN I = 0; I < USER_EVENT_MAXNUM; I++) {
|
||||
if (events[I].IsClosed) {
|
||||
events[I].IsClosed = 0;
|
||||
res = &(events[I]);
|
||||
break;
|
||||
for (Index = 0; Index < USER_EVENT_MAXNUM; Index++) {
|
||||
if (mEvents[Index].IsClosed == TRUE) {
|
||||
mEvents[Index].IsClosed = 0;
|
||||
return (&(mEvents[Index]));
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// internal event dispatcher
|
||||
/**
|
||||
Dispatches signaled events and triggers active timers
|
||||
**/
|
||||
STATIC
|
||||
VOID
|
||||
UserEventDispatch (
|
||||
@ -113,71 +125,97 @@ UserEventDispatch (
|
||||
)
|
||||
{
|
||||
UINT64 TimeNow;
|
||||
INTN Index;
|
||||
|
||||
TimeNow = UserEventGetTimeNow ();
|
||||
|
||||
for (INTN I = 0; I < USER_EVENT_MAXNUM; I++) {
|
||||
if (events[I].IsClosed) {
|
||||
// skip unused decriptors
|
||||
for (Index = 0; Index < USER_EVENT_MAXNUM; Index++) {
|
||||
if (mEvents[Index].IsClosed == TRUE) {
|
||||
//
|
||||
// Skip unused descriptors
|
||||
//
|
||||
continue;
|
||||
}
|
||||
|
||||
// it is an active timer?
|
||||
if ((events[I].Type & EVT_TIMER) && events[I].TimerEmit) {
|
||||
if (TimeNow >= events[I].TimerEmit) {
|
||||
// set signaled!
|
||||
events[I].Signaled = 1;
|
||||
//
|
||||
// Is it an active timer?
|
||||
//
|
||||
if (((mEvents[Index].Type & EVT_TIMER) != 0) && (mEvents[Index].TimerEmit != 0)) {
|
||||
if (TimeNow >= mEvents[Index].TimerEmit) {
|
||||
//
|
||||
// Signal Event
|
||||
//
|
||||
mEvents[Index].Signaled = TRUE;
|
||||
|
||||
// it is an periodic?
|
||||
if (events[I].TimerDelta) {
|
||||
// set new time for trigger
|
||||
events[I].TimerEmit += events[I].TimerDelta;
|
||||
//
|
||||
// Is it a periodic timer?
|
||||
//
|
||||
if (mEvents[Index].TimerDelta != 0) {
|
||||
//
|
||||
// Update trigger time
|
||||
//
|
||||
mEvents[Index].TimerEmit += mEvents[Index].TimerDelta;
|
||||
} else {
|
||||
events[I].TimerEmit = 0;
|
||||
mEvents[Index].TimerEmit = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// signal?
|
||||
if (events[I].Signaled && (events[I].Type & EVT_NOTIFY_SIGNAL)) {
|
||||
// valid TPL?
|
||||
if (CurTPL <= events[I].TplLevel) {
|
||||
// clear state
|
||||
events[I].Signaled = 0;
|
||||
// emit handler
|
||||
events[I].NotifyFn ((EFI_EVENT)&events[I], events[I].NotifyCtx);
|
||||
//
|
||||
// Is it a signaled event?
|
||||
//
|
||||
if ((mEvents[Index].Signaled == TRUE) && ((mEvents[Index].Type & EVT_NOTIFY_SIGNAL) != 0)) {
|
||||
//
|
||||
// Is TPL of Event valid?
|
||||
//
|
||||
if (mCurTPL <= mEvents[Index].TplLevel) {
|
||||
//
|
||||
// Reset state
|
||||
//
|
||||
mEvents[Index].Signaled = FALSE;
|
||||
//
|
||||
// Call handler
|
||||
//
|
||||
mEvents[Index].NotifyFn ((EFI_EVENT)&mEvents[Index], mEvents[Index].NotifyCtx);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// init event subsystem
|
||||
/**
|
||||
Inits the Event subsystem
|
||||
**/
|
||||
STATIC
|
||||
VOID
|
||||
UserEventInitializer (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
for (INTN I = 0; I < USER_EVENT_MAXNUM; I++) {
|
||||
// set unused state
|
||||
events[I].IsClosed = 1;
|
||||
events[I].TplLevel = 0;
|
||||
events[I].TimerEmit = 0;
|
||||
INTN Index;
|
||||
|
||||
for (Index = 0; Index < USER_EVENT_MAXNUM; Index++) {
|
||||
mEvents[Index].IsClosed = TRUE;
|
||||
mEvents[Index].TplLevel = 0;
|
||||
mEvents[Index].TimerEmit = 0;
|
||||
}
|
||||
|
||||
// init current TPL level
|
||||
CurTPL = TPL_APPLICATION;
|
||||
//
|
||||
// Init current TPL
|
||||
//
|
||||
mCurTPL = TPL_APPLICATION;
|
||||
}
|
||||
|
||||
// wrap around pthread_once() call
|
||||
/**
|
||||
Calls UserEventInitializer() if needed
|
||||
**/
|
||||
STATIC
|
||||
VOID
|
||||
UserEventInit (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
if (event_need_init) {
|
||||
event_need_init = 0;
|
||||
if (mEventNeedInit == TRUE) {
|
||||
mEventNeedInit = FALSE;
|
||||
UserEventInitializer ();
|
||||
}
|
||||
}
|
||||
@ -210,58 +248,66 @@ EFIAPI
|
||||
UserCreateEventEx (
|
||||
IN UINT32 Type,
|
||||
IN EFI_TPL NotifyTpl,
|
||||
IN EFI_EVENT_NOTIFY NotifyFunction,
|
||||
IN CONST VOID *NotifyContext,
|
||||
IN CONST EFI_GUID *EventGroup,
|
||||
IN EFI_EVENT_NOTIFY NotifyFunction OPTIONAL,
|
||||
IN CONST VOID *NotifyContext OPTIONAL,
|
||||
IN CONST EFI_GUID *EventGroup OPTIONAL,
|
||||
OUT EFI_EVENT *Event
|
||||
)
|
||||
{
|
||||
struct USER_EVENT *ev = NULL;
|
||||
USER_EVENT *Ev;
|
||||
|
||||
// init event subsystem
|
||||
UserEventInit ();
|
||||
|
||||
// check input params
|
||||
//
|
||||
// Check input params
|
||||
//
|
||||
if (Event == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if ((Type & EVT_NOTIFY_SIGNAL) && (Type & EVT_NOTIFY_WAIT)) {
|
||||
if (((Type & EVT_NOTIFY_SIGNAL) != 0) && ((Type & EVT_NOTIFY_WAIT) != 0)) {
|
||||
//
|
||||
// The Type param can't combine EVT_NOTIFY_SIGNAL and EVT_NOTIFY_WAIT flags
|
||||
//
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (Type & (EVT_NOTIFY_SIGNAL | EVT_NOTIFY_WAIT)) {
|
||||
// is signal or wait emit type
|
||||
if ((Type & (EVT_NOTIFY_SIGNAL | EVT_NOTIFY_WAIT)) != 0) {
|
||||
//
|
||||
// Event type is signal or event
|
||||
//
|
||||
if (NotifyFunction == NULL) {
|
||||
//
|
||||
// callback function isn't set
|
||||
//
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (!(NotifyTpl < USER_EVENT_MAXTPL)) {
|
||||
// invalid required TPL
|
||||
if (NotifyTpl >= USER_EVENT_MAXTPL) {
|
||||
//
|
||||
// Required TPL is invalid
|
||||
//
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
|
||||
// try alloc event descriptor
|
||||
ev = UserEventAlloc ();
|
||||
|
||||
if (ev == NULL) {
|
||||
// have no mem
|
||||
//
|
||||
// Try to allocate an Event descriptor
|
||||
//
|
||||
Ev = UserEventAlloc ();
|
||||
if (Ev == NULL) {
|
||||
*Event = NULL;
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
// set event descriptor fields
|
||||
ev->Type = Type;
|
||||
ev->TplLevel = NotifyTpl;
|
||||
ev->Signaled = 0;
|
||||
ev->NotifyFn = NotifyFunction;
|
||||
ev->NotifyCtx = (VOID *)NotifyContext;
|
||||
ev->TimerEmit = 0;
|
||||
Ev->Type = Type;
|
||||
Ev->TplLevel = NotifyTpl;
|
||||
Ev->Signaled = 0;
|
||||
Ev->NotifyFn = NotifyFunction;
|
||||
Ev->NotifyCtx = (VOID *)NotifyContext;
|
||||
Ev->TimerEmit = 0;
|
||||
|
||||
*Event = (EFI_EVENT)ev;
|
||||
*Event = (EFI_EVENT)Ev;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
@ -291,8 +337,8 @@ EFIAPI
|
||||
UserCreateEvent (
|
||||
IN UINT32 Type,
|
||||
IN EFI_TPL NotifyTpl,
|
||||
IN EFI_EVENT_NOTIFY NotifyFunction,
|
||||
IN VOID *NotifyContext,
|
||||
IN EFI_EVENT_NOTIFY NotifyFunction OPTIONAL,
|
||||
IN VOID *NotifyContext OPTIONAL,
|
||||
OUT EFI_EVENT *Event
|
||||
)
|
||||
{
|
||||
@ -319,19 +365,17 @@ UserCloseEvent (
|
||||
IN EFI_EVENT Event
|
||||
)
|
||||
{
|
||||
struct USER_EVENT *ev = NULL;
|
||||
USER_EVENT *Ev;
|
||||
|
||||
// init event subsystem
|
||||
UserEventInit ();
|
||||
|
||||
ASSERT (Event != NULL);
|
||||
// type cast
|
||||
ev = (struct USER_EVENT *)Event;
|
||||
|
||||
// clear event state
|
||||
ev->IsClosed = 1;
|
||||
ev->TimerEmit = 0;
|
||||
ev->TplLevel = 0;
|
||||
Ev = (USER_EVENT *)Event;
|
||||
|
||||
Ev->IsClosed = TRUE;
|
||||
Ev->TimerEmit = 0;
|
||||
Ev->TplLevel = 0;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
@ -349,18 +393,17 @@ UserSignalEvent (
|
||||
IN EFI_EVENT Event
|
||||
)
|
||||
{
|
||||
struct USER_EVENT *ev = NULL;
|
||||
USER_EVENT *Ev;
|
||||
|
||||
// init event subsystem
|
||||
UserEventInit ();
|
||||
|
||||
ASSERT (Event != NULL);
|
||||
|
||||
ev = (struct USER_EVENT *)Event;
|
||||
ASSERT (!(ev->IsClosed));
|
||||
Ev = (USER_EVENT *)Event;
|
||||
ASSERT (Ev->IsClosed == FALSE);
|
||||
|
||||
if (!(ev->IsClosed)) {
|
||||
ev->Signaled = 1;
|
||||
if (Ev->IsClosed == FALSE) {
|
||||
Ev->Signaled = TRUE;
|
||||
}
|
||||
|
||||
UserEventDispatch ();
|
||||
@ -383,32 +426,35 @@ UserCheckEvent (
|
||||
IN EFI_EVENT Event
|
||||
)
|
||||
{
|
||||
struct USER_EVENT *ev = NULL;
|
||||
EFI_STATUS Status;
|
||||
USER_EVENT *Ev;
|
||||
EFI_STATUS Status;
|
||||
|
||||
// init event subsystem
|
||||
UserEventInit ();
|
||||
|
||||
ASSERT (Event != NULL);
|
||||
|
||||
ev = (struct USER_EVENT *)Event;
|
||||
ASSERT (!(ev->IsClosed));
|
||||
Ev = (USER_EVENT *)Event;
|
||||
ASSERT (Ev->IsClosed == FALSE);
|
||||
|
||||
if (ev->Type & EVT_NOTIFY_SIGNAL) {
|
||||
if ((Ev->Type & EVT_NOTIFY_SIGNAL) != 0) {
|
||||
//
|
||||
// The Event can't have the EVT_NOTIFY_SIGNAL type
|
||||
//
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
UserEventDispatch ();
|
||||
|
||||
if (ev->Signaled) {
|
||||
// Signaled?
|
||||
ev->Signaled = 0;
|
||||
if (Ev->Signaled == TRUE) {
|
||||
Ev->Signaled = FALSE;
|
||||
Status = EFI_SUCCESS;
|
||||
} else {
|
||||
// It isn't signaled event, but can be EVT_NOTIFY_WAIT type
|
||||
// then we need emit callback function if TPL is valid
|
||||
if ((ev->Type & EVT_NOTIFY_WAIT) && (CurTPL <= ev->TplLevel)) {
|
||||
ev->NotifyFn ((EFI_EVENT)ev, ev->NotifyCtx);
|
||||
//
|
||||
// It isn't signaled event, but it can have the EVT_NOTIFY_WAIT type
|
||||
// In that case, we need to emit callback function if TPL is valid
|
||||
//
|
||||
if (((Ev->Type & EVT_NOTIFY_WAIT) != 0) && (mCurTPL <= Ev->TplLevel)) {
|
||||
Ev->NotifyFn ((EFI_EVENT)Ev, Ev->NotifyCtx);
|
||||
}
|
||||
|
||||
Status = EFI_NOT_READY;
|
||||
@ -438,58 +484,59 @@ UserWaitForEvent (
|
||||
OUT UINTN *Index
|
||||
)
|
||||
{
|
||||
struct USER_EVENT **evs = NULL;
|
||||
struct USER_EVENT *ev = NULL;
|
||||
USER_EVENT **Evs;
|
||||
USER_EVENT *Ev;
|
||||
UINTN Jndex;
|
||||
|
||||
UserEventInit ();
|
||||
|
||||
if (CurTPL != TPL_APPLICATION) {
|
||||
if (mCurTPL != TPL_APPLICATION) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
ASSERT (Events != NULL);
|
||||
ASSERT (Index != NULL);
|
||||
|
||||
evs = (struct USER_EVENT **)Events;
|
||||
Evs = (USER_EVENT **)Events;
|
||||
|
||||
if (!NumberOfEvents) {
|
||||
// check input param
|
||||
if (NumberOfEvents == 0) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
WAIT_LOOP:
|
||||
while (TRUE) {
|
||||
//
|
||||
// Blocking wait
|
||||
//
|
||||
|
||||
UserEventDispatch ();
|
||||
UserEventDispatch ();
|
||||
|
||||
for (UINTN I = 0; I < NumberOfEvents; I++) {
|
||||
ev = evs[I];
|
||||
for (Jndex = 0; Jndex < NumberOfEvents; Jndex++) {
|
||||
Ev = Evs[Jndex];
|
||||
|
||||
if (ev == NULL) {
|
||||
continue;
|
||||
}
|
||||
if (Ev == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ev->IsClosed) {
|
||||
continue;
|
||||
}
|
||||
if (Ev->IsClosed == TRUE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ev->Type & EVT_NOTIFY_SIGNAL) {
|
||||
*Index = I;
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
if ((Ev->Type & EVT_NOTIFY_SIGNAL) != 0) {
|
||||
*Index = Jndex;
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (ev->Signaled) {
|
||||
*Index = I;
|
||||
ev->Signaled = 0;
|
||||
return EFI_SUCCESS;
|
||||
} else {
|
||||
if ((ev->Type & EVT_NOTIFY_WAIT) && (CurTPL <= ev->TplLevel)) {
|
||||
ev->NotifyFn ((EFI_EVENT)ev, ev->NotifyCtx);
|
||||
if (Ev->Signaled == TRUE) {
|
||||
*Index = Jndex;
|
||||
Ev->Signaled = FALSE;
|
||||
return EFI_SUCCESS;
|
||||
} else {
|
||||
if (((Ev->Type & EVT_NOTIFY_WAIT) != 0) && (mCurTPL <= Ev->TplLevel)) {
|
||||
Ev->NotifyFn ((EFI_EVENT)Ev, Ev->NotifyCtx);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// blocking wait
|
||||
goto WAIT_LOOP;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -512,17 +559,17 @@ UserSetTimer (
|
||||
IN UINT64 TriggerTime
|
||||
)
|
||||
{
|
||||
UINT64 TimeNow = 0;
|
||||
struct USER_EVENT *ev = NULL;
|
||||
UINT64 TimeNow;
|
||||
USER_EVENT *Ev;
|
||||
|
||||
UserEventInit ();
|
||||
|
||||
// check input params
|
||||
ASSERT (Event != NULL);
|
||||
ev = (struct USER_EVENT *)Event;
|
||||
ASSERT (!(ev->IsClosed));
|
||||
Ev = (USER_EVENT *)Event;
|
||||
ASSERT (Ev->IsClosed == FALSE);
|
||||
|
||||
if (!(ev->Type & EVT_TIMER)) {
|
||||
if ((Ev->Type & EVT_TIMER) == 0) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
@ -530,17 +577,17 @@ UserSetTimer (
|
||||
|
||||
switch (Type) {
|
||||
case TimerCancel:
|
||||
ev->TimerEmit = 0;
|
||||
Ev->TimerEmit = 0;
|
||||
break;
|
||||
|
||||
case TimerRelative:
|
||||
ev->TimerEmit = TimeNow + TriggerTime * 100;
|
||||
ev->TimerDelta = 0;
|
||||
Ev->TimerEmit = TimeNow + TriggerTime * 100;
|
||||
Ev->TimerDelta = 0;
|
||||
break;
|
||||
|
||||
case TimerPeriodic:
|
||||
ev->TimerEmit = TimeNow + TriggerTime * 100;
|
||||
ev->TimerDelta = TriggerTime * 100;
|
||||
Ev->TimerEmit = TimeNow + TriggerTime * 100;
|
||||
Ev->TimerDelta = TriggerTime * 100;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -565,18 +612,18 @@ UserRaiseTPL (
|
||||
IN EFI_TPL NewTpl
|
||||
)
|
||||
{
|
||||
EFI_TPL old;
|
||||
EFI_TPL Old;
|
||||
|
||||
UserEventInit ();
|
||||
|
||||
UserEventDispatch ();
|
||||
|
||||
old = CurTPL;
|
||||
if ((NewTpl >= old) && (NewTpl < USER_EVENT_MAXTPL)) {
|
||||
CurTPL = NewTpl;
|
||||
Old = mCurTPL;
|
||||
if ((NewTpl >= Old) && (NewTpl < USER_EVENT_MAXTPL)) {
|
||||
mCurTPL = NewTpl;
|
||||
}
|
||||
|
||||
return old;
|
||||
return Old;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -591,10 +638,10 @@ UserRestoreTPL (
|
||||
)
|
||||
{
|
||||
UserEventInit ();
|
||||
ASSERT (OldTpl <= CurTPL);
|
||||
ASSERT (OldTpl <= mCurTPL);
|
||||
|
||||
if (OldTpl < USER_EVENT_MAXTPL) {
|
||||
CurTPL = OldTpl;
|
||||
mCurTPL = OldTpl;
|
||||
}
|
||||
|
||||
UserEventDispatch ();
|
||||
@ -612,36 +659,38 @@ UserEventDispatchNow (
|
||||
)
|
||||
{
|
||||
UINT64 TimeNow;
|
||||
BOOLEAN res = FALSE;
|
||||
BOOLEAN Res;
|
||||
INTN Index;
|
||||
|
||||
UserEventInit ();
|
||||
|
||||
TimeNow = UserEventGetTimeNow ();
|
||||
|
||||
for (INTN I = 0; I < USER_EVENT_MAXNUM; I++) {
|
||||
if (events[I].IsClosed) {
|
||||
Res = FALSE;
|
||||
for (Index = 0; Index < USER_EVENT_MAXNUM; Index++) {
|
||||
if (mEvents[Index].IsClosed == TRUE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
res = TRUE;
|
||||
if ((events[I].Type & EVT_TIMER) && events[I].TimerEmit) {
|
||||
if (TimeNow >= events[I].TimerEmit) {
|
||||
events[I].Signaled = 1;
|
||||
if (events[I].TimerDelta) {
|
||||
events[I].TimerEmit += events[I].TimerDelta;
|
||||
Res = TRUE;
|
||||
if (((mEvents[Index].Type & EVT_TIMER) != 0) && (mEvents[Index].TimerEmit != 0)) {
|
||||
if (TimeNow >= mEvents[Index].TimerEmit) {
|
||||
mEvents[Index].Signaled = TRUE;
|
||||
if (mEvents[Index].TimerDelta != 0) {
|
||||
mEvents[Index].TimerEmit += mEvents[Index].TimerDelta;
|
||||
} else {
|
||||
events[I].TimerEmit = 0;
|
||||
mEvents[Index].TimerEmit = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (events[I].Signaled && (events[I].Type & EVT_NOTIFY_SIGNAL)) {
|
||||
if (CurTPL <= events[I].TplLevel) {
|
||||
events[I].Signaled = 0;
|
||||
events[I].NotifyFn ((EFI_EVENT)&events[I], events[I].NotifyCtx);
|
||||
if ((mEvents[Index].Signaled == TRUE) && ((mEvents[Index].Type & EVT_NOTIFY_SIGNAL) != 0)) {
|
||||
if (mCurTPL <= mEvents[Index].TplLevel) {
|
||||
mEvents[Index].Signaled = FALSE;
|
||||
mEvents[Index].NotifyFn ((EFI_EVENT)&mEvents[Index], mEvents[Index].NotifyCtx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
return Res;
|
||||
}
|
||||
|
||||
@ -5,116 +5,135 @@
|
||||
|
||||
#include <Uefi.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/UefiLib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// context for callback functions
|
||||
struct NOTIFY_CONTEXT1 {
|
||||
/**
|
||||
The context for callback functions
|
||||
**/
|
||||
typedef struct {
|
||||
EFI_EVENT LinkedEvent;
|
||||
UINTN Counter;
|
||||
};
|
||||
} NOTIFY_CONTEXT1;
|
||||
|
||||
// callback-functions for signal
|
||||
/**
|
||||
The callback function for a simple signal
|
||||
**/
|
||||
STATIC
|
||||
VOID
|
||||
SignalNotify1 (
|
||||
IN EFI_EVENT Event,
|
||||
IN VOID *Context
|
||||
)
|
||||
{
|
||||
struct NOTIFY_CONTEXT1 *ctx = (struct NOTIFY_CONTEXT1 *)Context;
|
||||
NOTIFY_CONTEXT1 *Ctx;
|
||||
|
||||
printf ("SignalNotify1()\n");
|
||||
(ctx->Counter)++;
|
||||
DEBUG ((DEBUG_INFO, "SignalNotify1()\n"));
|
||||
Ctx = (NOTIFY_CONTEXT1 *)Context;
|
||||
++(Ctx->Counter);
|
||||
}
|
||||
|
||||
/**
|
||||
The callback function for a self-destroy signal
|
||||
**/
|
||||
STATIC
|
||||
VOID
|
||||
SelfDestroyNotify1 (
|
||||
IN EFI_EVENT Event,
|
||||
IN VOID *Context
|
||||
)
|
||||
{
|
||||
struct NOTIFY_CONTEXT1 *ctx = (struct NOTIFY_CONTEXT1 *)Context;
|
||||
NOTIFY_CONTEXT1 *Ctx;
|
||||
|
||||
printf ("@@@@ SelfDestroyNotify1()\n");
|
||||
(ctx->Counter)++;
|
||||
DEBUG ((DEBUG_INFO, "@@@@ SelfDestroyNotify1()\n"));
|
||||
Ctx = (NOTIFY_CONTEXT1 *)Context;
|
||||
++(Ctx->Counter);
|
||||
gBS->CloseEvent (Event);
|
||||
}
|
||||
|
||||
/**
|
||||
The callback function for linked signals
|
||||
**/
|
||||
STATIC
|
||||
VOID
|
||||
SignalNotify2 (
|
||||
IN EFI_EVENT Event,
|
||||
IN VOID *Context
|
||||
)
|
||||
{
|
||||
struct NOTIFY_CONTEXT1 *ctx = (struct NOTIFY_CONTEXT1 *)Context;
|
||||
EFI_STATUS Status;
|
||||
NOTIFY_CONTEXT1 *Ctx;
|
||||
|
||||
// printf("SignalNotify2() %lu\n", ctx->Counter);
|
||||
Status = gBS->SignalEvent (ctx->LinkedEvent);
|
||||
|
||||
// if (EFI_ERROR(Status)) {
|
||||
// printf("SignalNotify2() %lu Error emited %d\n", ctx->Counter, Status);
|
||||
// } else {
|
||||
// printf("SignalNotify2() %lu Success Emited\n", ctx->Counter);
|
||||
// }
|
||||
(ctx->Counter)++;
|
||||
Ctx = (NOTIFY_CONTEXT1 *)Context;
|
||||
gBS->SignalEvent (Ctx->LinkedEvent);
|
||||
++(Ctx->Counter);
|
||||
}
|
||||
|
||||
/**
|
||||
The callback function for a last-linked signal
|
||||
**/
|
||||
STATIC
|
||||
VOID
|
||||
SignalNotify3 (
|
||||
IN EFI_EVENT Event,
|
||||
IN VOID *Context
|
||||
)
|
||||
{
|
||||
struct NOTIFY_CONTEXT1 *ctx = (struct NOTIFY_CONTEXT1 *)Context;
|
||||
NOTIFY_CONTEXT1 *Ctx;
|
||||
|
||||
// printf("SignalNotify3() %lu\n", ctx->Counter);
|
||||
(ctx->Counter)++;
|
||||
Ctx = (NOTIFY_CONTEXT1 *)Context;
|
||||
++(Ctx->Counter);
|
||||
}
|
||||
|
||||
/**
|
||||
The callback function for a linked wait signal
|
||||
**/
|
||||
STATIC
|
||||
VOID
|
||||
WaitNotify1 (
|
||||
IN EFI_EVENT Event,
|
||||
IN VOID *Context
|
||||
)
|
||||
{
|
||||
struct NOTIFY_CONTEXT1 *ctx = (struct NOTIFY_CONTEXT1 *)Context;
|
||||
EFI_STATUS Status;
|
||||
NOTIFY_CONTEXT1 *Ctx;
|
||||
|
||||
// printf("WaitNotify1() %lu\n", ctx->Counter);
|
||||
Status = gBS->SignalEvent (ctx->LinkedEvent);
|
||||
|
||||
// if (EFI_ERROR(Status)) {
|
||||
// printf("WaitNotify1() %lu Error emited %d\n", ctx->Counter, Status);
|
||||
// } else {
|
||||
// printf("WaitNotify1() %lu Success Emited\n", ctx->Counter);
|
||||
// }
|
||||
(ctx->Counter)++;
|
||||
Ctx = (NOTIFY_CONTEXT1 *)Context;
|
||||
gBS->SignalEvent (Ctx->LinkedEvent);
|
||||
++(Ctx->Counter);
|
||||
}
|
||||
|
||||
int
|
||||
main (
|
||||
ENTRY_POINT (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
struct NOTIFY_CONTEXT1 SignalNotifyContext1 = { 0, };
|
||||
struct NOTIFY_CONTEXT1 SignalNotifyContext2 = { 0, };
|
||||
struct NOTIFY_CONTEXT1 SignalNotifyContext3 = { 0, };
|
||||
struct NOTIFY_CONTEXT1 WaitNotifyContext1 = { 0, };
|
||||
struct NOTIFY_CONTEXT1 SelfDestroyContext1 = { 0, };
|
||||
EFI_EVENT Signal1;
|
||||
EFI_EVENT Signal2;
|
||||
EFI_EVENT Signal3;
|
||||
EFI_EVENT Wait1;
|
||||
EFI_EVENT Timer1;
|
||||
EFI_EVENT SelfD1;
|
||||
UINTN TimerCounter1 = 0;
|
||||
UINTN Index;
|
||||
EFI_STATUS Status;
|
||||
NOTIFY_CONTEXT1 SignalNotifyContext1 = { 0, };
|
||||
NOTIFY_CONTEXT1 SignalNotifyContext2 = { 0, };
|
||||
NOTIFY_CONTEXT1 SignalNotifyContext3 = { 0, };
|
||||
NOTIFY_CONTEXT1 WaitNotifyContext1 = { 0, };
|
||||
NOTIFY_CONTEXT1 SelfDestroyContext1 = { 0, };
|
||||
EFI_EVENT Signal1;
|
||||
EFI_EVENT Signal2;
|
||||
EFI_EVENT Signal3;
|
||||
EFI_EVENT Wait1;
|
||||
EFI_EVENT Timer1;
|
||||
EFI_EVENT SelfD1;
|
||||
UINTN TimerCounter1 = 0;
|
||||
UINTN Index;
|
||||
INTN Jndex;
|
||||
EFI_TPL OriginalTPL;
|
||||
//
|
||||
// Array for waiting events
|
||||
//
|
||||
EFI_EVENT Events[2];
|
||||
|
||||
printf ("=== Test UEFI Event System ===\n");
|
||||
DEBUG ((DEBUG_INFO, "=== Test UEFI Event System ===\n"));
|
||||
|
||||
// create events
|
||||
//
|
||||
// Create events
|
||||
//
|
||||
Status = gBS->CreateEvent (
|
||||
EVT_NOTIFY_SIGNAL,
|
||||
TPL_CALLBACK,
|
||||
@ -124,9 +143,9 @@ main (
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status) || (Signal1 == NULL)) {
|
||||
printf ("FAIL: Signal1 event creation (Status: %lu)\n", Status);
|
||||
DEBUG ((DEBUG_INFO, "FAIL: Signal1 event creation (Status: %r)\n", Status));
|
||||
} else {
|
||||
printf ("PASS: Signal1 event created\n");
|
||||
DEBUG ((DEBUG_INFO, "PASS: Signal1 event created\n"));
|
||||
}
|
||||
|
||||
Status = gBS->CreateEvent (
|
||||
@ -138,9 +157,9 @@ main (
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status) || (Signal2 == NULL)) {
|
||||
printf ("FAIL: Signal2 event creation (Status: %lu)\n", Status);
|
||||
DEBUG ((DEBUG_INFO, "FAIL: Signal2 event creation (Status: %r)\n", Status));
|
||||
} else {
|
||||
printf ("PASS: Signal2 event created\n");
|
||||
DEBUG ((DEBUG_INFO, "PASS: Signal2 event created\n"));
|
||||
}
|
||||
|
||||
Status = gBS->CreateEvent (
|
||||
@ -152,9 +171,9 @@ main (
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status) || (Signal3 == NULL)) {
|
||||
printf ("FAIL: Signal3 event creation (Status: %lu)\n", Status);
|
||||
DEBUG ((DEBUG_INFO, "FAIL: Signal3 event creation (Status: %r)\n", Status));
|
||||
} else {
|
||||
printf ("PASS: Signal3 event created\n");
|
||||
DEBUG ((DEBUG_INFO, "PASS: Signal3 event created\n"));
|
||||
}
|
||||
|
||||
Status = gBS->CreateEvent (
|
||||
@ -166,9 +185,9 @@ main (
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status) || (Wait1 == NULL)) {
|
||||
printf ("FAIL: Wait1 event creation (Status: %lu)\n", Status);
|
||||
DEBUG ((DEBUG_INFO, "FAIL: Wait1 event creation (Status: %r)\n", Status));
|
||||
} else {
|
||||
printf ("PASS: Wait1 event created\n");
|
||||
DEBUG ((DEBUG_INFO, "PASS: Wait1 event created\n"));
|
||||
}
|
||||
|
||||
Status = gBS->CreateEvent (
|
||||
@ -180,9 +199,9 @@ main (
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status) || (Timer1 == NULL)) {
|
||||
printf ("FAIL: Timer1 event creation (Status: %lu)\n", Status);
|
||||
DEBUG ((DEBUG_INFO, "FAIL: Timer1 event creation (Status: %r)\n", Status));
|
||||
} else {
|
||||
printf ("PASS: Timer1 event created\n");
|
||||
DEBUG ((DEBUG_INFO, "PASS: Timer1 event created\n"));
|
||||
}
|
||||
|
||||
Status = gBS->CreateEvent (
|
||||
@ -194,94 +213,111 @@ main (
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status) || (SelfD1 == NULL)) {
|
||||
printf ("FAIL: SelfD1 event creation (Status: %lu)\n", Status);
|
||||
DEBUG ((DEBUG_INFO, "FAIL: SelfD1 event creation (Status: %r)\n", Status));
|
||||
} else {
|
||||
printf ("PASS: SelfD event created\n");
|
||||
DEBUG ((DEBUG_INFO, "PASS: SelfD event created\n"));
|
||||
}
|
||||
|
||||
// links events
|
||||
// signal2 with signal3
|
||||
//
|
||||
// Link events
|
||||
// Signal2 --> Signal3
|
||||
// Wait1 --> Signal2
|
||||
//
|
||||
SignalNotifyContext2.LinkedEvent = Signal3;
|
||||
// wait1 with signal 2
|
||||
WaitNotifyContext1.LinkedEvent = Signal2;
|
||||
WaitNotifyContext1.LinkedEvent = Signal2;
|
||||
|
||||
// try sets timers
|
||||
//
|
||||
// Try to set timers
|
||||
//
|
||||
Status = gBS->SetTimer (Wait1, TimerPeriodic, 100*10000);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
printf ("FAIL: Set timer for Wait1 (Status: %lu)\n", Status);
|
||||
DEBUG ((DEBUG_INFO, "FAIL: Set timer for Wait1 (Status: %r)\n", Status));
|
||||
} else {
|
||||
printf ("PASS: Wait1 set to 100*10000 periodic\n");
|
||||
DEBUG ((DEBUG_INFO, "PASS: Wait1 set to 100*10000 periodic\n"));
|
||||
}
|
||||
|
||||
Status = gBS->SetTimer (Timer1, TimerPeriodic, 10*10000);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
printf ("FAIL: Set timer for Timer1 (Status: %lu)\n", Status);
|
||||
DEBUG ((DEBUG_INFO, "FAIL: Set timer for Timer1 (Status: %r)\n", Status));
|
||||
} else {
|
||||
printf ("PASS: Timer1 set to 10*10000 periodic\n");
|
||||
DEBUG ((DEBUG_INFO, "PASS: Timer1 set to 10*10000 periodic\n"));
|
||||
}
|
||||
|
||||
Status = gBS->SetTimer (SelfD1, TimerRelative, 30*10000);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
printf ("FAIL: Set timer for SelfD1 (Status: %lu)\n", Status);
|
||||
DEBUG ((DEBUG_INFO, "FAIL: Set timer for SelfD1 (Status: %r)\n", Status));
|
||||
} else {
|
||||
printf ("PASS: SelfD1 set to 30*10000 relative\n");
|
||||
DEBUG ((DEBUG_INFO, "PASS: SelfD1 set to 30*10000 relative\n"));
|
||||
}
|
||||
|
||||
// try emit signal1
|
||||
//
|
||||
// Try to emit Signal1
|
||||
//
|
||||
gBS->SignalEvent (Signal1);
|
||||
|
||||
// try wait events
|
||||
EFI_EVENT Events[] = { Timer1, Wait1 };
|
||||
//
|
||||
// Try to wait events
|
||||
//
|
||||
Events[0] = Timer1;
|
||||
Events[1] = Wait1;
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
for (Jndex = 0; Jndex < 10; Jndex++) {
|
||||
Status = gBS->WaitForEvent (2, Events, &Index);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
printf ("Event %lu triggered\n", Index);
|
||||
DEBUG ((DEBUG_INFO, "Event %u triggered\n", Index));
|
||||
if (Index == 0) {
|
||||
printf ("PASS: Timer1 event wait succeeded\n");
|
||||
DEBUG ((DEBUG_INFO, "PASS: Timer1 event wait succeeded\n"));
|
||||
TimerCounter1++;
|
||||
}
|
||||
} else {
|
||||
printf ("Event Error %lu (Status: %lu)\n", Index, Status);
|
||||
DEBUG ((DEBUG_INFO, "Event Error %u (Status: %r)\n", Index, Status));
|
||||
}
|
||||
}
|
||||
|
||||
// try check event
|
||||
//
|
||||
// Try to check event
|
||||
//
|
||||
Status = gBS->CheckEvent (Signal1);
|
||||
if (Status == EFI_SUCCESS) {
|
||||
printf ("FAIL: Event check succeeded\n");
|
||||
DEBUG ((DEBUG_INFO, "FAIL: Event check succeeded\n"));
|
||||
} else {
|
||||
printf ("PASS: Event check error (Status: %lu)\n", Status);
|
||||
DEBUG ((DEBUG_INFO, "PASS: Event check error (Status: %r)\n", Status));
|
||||
}
|
||||
|
||||
// TPL Test
|
||||
EFI_TPL OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);
|
||||
//
|
||||
// The TPL test
|
||||
//
|
||||
OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);
|
||||
|
||||
printf ("TPL raised from %lu to %d\n", OriginalTPL, TPL_HIGH_LEVEL);
|
||||
DEBUG ((DEBUG_INFO, "TPL raised from %u to %d\n", OriginalTPL, TPL_HIGH_LEVEL));
|
||||
|
||||
gBS->SignalEvent (Signal1);
|
||||
printf ("EVENT SIGANL1 NEED PRINTF AFTER THIS LINE:\n");
|
||||
DEBUG ((DEBUG_INFO, "EVENT SIGANL1 NEED PRINTF AFTER THIS LINE:\n"));
|
||||
|
||||
gBS->RestoreTPL (OriginalTPL);
|
||||
printf ("TPL restored to %lu\n", OriginalTPL);
|
||||
DEBUG ((DEBUG_INFO, "TPL restored to %u\n", OriginalTPL));
|
||||
|
||||
// test close event
|
||||
//
|
||||
// Try to close event
|
||||
//
|
||||
gBS->CloseEvent (Signal1);
|
||||
gBS->CloseEvent (Timer1);
|
||||
|
||||
// try signal closed event
|
||||
//
|
||||
// Try to signal a closed event. Need to trigger ASSERT()
|
||||
//
|
||||
// gBS->SignalEvent (Signal1);
|
||||
|
||||
printf ("\n=== Test Summary ===\n");
|
||||
printf ("Signal1 callbacks: %ld\n", SignalNotifyContext1.Counter);
|
||||
printf ("Signal2 callbacks: %ld\n", SignalNotifyContext2.Counter);
|
||||
printf ("Signal3 callbacks: %ld\n", SignalNotifyContext3.Counter);
|
||||
printf ("Wait1 callbacks: %ld\n", WaitNotifyContext1.Counter);
|
||||
printf ("SelfD1 callbacks: %ld\n", SelfDestroyContext1.Counter);
|
||||
printf ("Timer1 callbacks: %ld\n", TimerCounter1);
|
||||
DEBUG ((DEBUG_INFO, "\n=== Test Summary ===\n"));
|
||||
DEBUG ((DEBUG_INFO, "Signal1 callbacks: %u\n", SignalNotifyContext1.Counter));
|
||||
DEBUG ((DEBUG_INFO, "Signal2 callbacks: %u\n", SignalNotifyContext2.Counter));
|
||||
DEBUG ((DEBUG_INFO, "Signal3 callbacks: %u\n", SignalNotifyContext3.Counter));
|
||||
DEBUG ((DEBUG_INFO, "Wait1 callbacks: %u\n", WaitNotifyContext1.Counter));
|
||||
DEBUG ((DEBUG_INFO, "SelfD1 callbacks: %u\n", SelfDestroyContext1.Counter));
|
||||
DEBUG ((DEBUG_INFO, "Timer1 callbacks: %u\n", TimerCounter1));
|
||||
|
||||
gBS->CloseEvent (Signal2);
|
||||
gBS->CloseEvent (Signal3);
|
||||
|
||||
@ -29,6 +29,7 @@ buildutil() {
|
||||
"TestExt4Dxe"
|
||||
"TestFatDxe"
|
||||
"TestNtfsDxe"
|
||||
"TestEvent"
|
||||
"TestPeCoff"
|
||||
"TestProcessKernel"
|
||||
"TestRsaPreprocess"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user