EFI Group Event Callback Order


Li, Walon <walon.li@...>
 

Hi edk2,

 

As UEFI event group mechanism, we can register callbacks under event group. For example, register two event callbacks and will be signal in ReadyToBoot.

  Status = gBS->CreateEventEx (

                  EVT_NOTIFY_SIGNAL,

                  TPL_CALLBACK,

                  TestCallback1,

                  NULL,

                  &gEfiEventReadyToBootGuid,

                  &ReadyToBootEvent

                  );

  Status = gBS->CreateEventEx (

                  EVT_NOTIFY_SIGNAL,

                  TPL_CALLBACK,

                  TestCallback2,

                  NULL,

                  &gEfiEventReadyToBootGuid,

                  &ReadyToBootEvent

                  );

I'm curious the order of callback. In this case, the order is LIFO and TestCallback2 will be executed than TestCallback1.

As the UEFI spec page 152, only said "If the supplied Event is a part of an event group, then all of the events in the event group are also signaled and their notification functions are scheduled." It doesn't define order clearly.

 

However, edk2 has different implementation in EVT_RUNTIME / EVT_NOTIFY_SIGNAL attribute of group event. In Event.c, it inserts new event to Head in EVT_NOTIFY_SIGNAL queue (LIFO) and inserts to Tail in EVT_RUNTIME queue (FIFO).

I know the programmer shouldn't assume any order but want to know why is different implementation in group event. Have any history reason or limitation?

 

  if ((Type & EVT_RUNTIME) != 0) {

    //

    // Keep a list of all RT events so we can tell the RT AP.

    //

    IEvent->RuntimeData.Type           = Type;

    IEvent->RuntimeData.NotifyTpl      = NotifyTpl;

    IEvent->RuntimeData.NotifyFunction = NotifyFunction;

    IEvent->RuntimeData.NotifyContext  = (VOID *) NotifyContext;

    //

    // Work around the bug in the Platform Init specification (v1.7), reported

    // as Mantis#2017: "EFI_RUNTIME_EVENT_ENTRY.Event" should have type

    // EFI_EVENT, not (EFI_EVENT*). The PI spec documents the field correctly

    // as "The EFI_EVENT returned by CreateEvent()", but the type of the field

    // doesn't match the natural language description. Therefore we need an

    // explicit cast here.

    //

   IEvent->RuntimeData.Event          = (EFI_EVENT *) IEvent;

    InsertTailList (&gRuntime->EventHead, &IEvent->RuntimeData.Link);

  }

 

  CoreAcquireEventLock ();

 

  if ((Type & EVT_NOTIFY_SIGNAL) != 0x00000000) {

    //

    // The Event's NotifyFunction must be queued whenever the event is signaled

    //

    InsertHeadList (&gEventSignalQueue, &IEvent->SignalLink);

  }

 

Thank you,

Walon

Join discuss@edk2.groups.io to automatically receive all group messages.