On May 30, 2014, at 11:51 AM, Andrew Fish <af...@apple.com> wrote:

> 
> On May 30, 2014, at 11:00 AM, justin_johns...@dell.com wrote:
> 
>> Hello all,
>> I’m working with the DXE core event services and am not sure that the code 
>> in MdeModulePkg agrees with the UEFI spec.
>> The situation is this: in several modules I have created an event using the 
>> CreateEventEx() method, with an EventGroup GUID. Later, I want to signal the 
>> event group, but the module which does the signaling does not have any work 
>> to do in response to the event. It would seem that I can signal the event by 
>> doing as indicated in the UEFI spec:
>> gBS->CreateEventEx (
>>   0,
>>   0,
>>   NULL,
>>   NULL,
>>   &gMyEventGroupGuid,
>>   &Event);
>> gBS->SignalEvent(Event);
>>  
>> However, this does not work with EDKII. I see in Event.c :
>> if ((Event->Type & EVT_NOTIFY_SIGNAL) != 0) {
>>       if (Event->ExFlag) {
>>         //
>>         // The CreateEventEx() style requires all members of the Event Group
>>         //  to be signaled.
>>         //
>>         CoreReleaseEventLock ();
>>         CoreNotifySignalList (&Event->EventGroup);
>>         CoreAcquireEventLock ();
>>  
>> Which seems to indicate that the event group is only signaled if the event 
>> being signaled is of type EVT_NOTIFY_SIGNAL. In order to get my event group 
>> signaled, I must create an event with a dummy callback and give it type 
>> EVT_NOTIFY_SIGNAL, even though I do not have any work to do in response to 
>> the event.
>>  
>> Is this an error in MdeModulePkg’s implementation? Or is the spec incomplete?
>>  

Justin,

I think the logic in the DXE Core should look like this:

  if (Event->SignalCount == 0x00000000) {
    Event->SignalCount++;

    if  (Event->ExFlag) {
        //
        // The CreateEventEx() style requires all members of the Event Group
        //  to be signaled.
        //
        CoreReleaseEventLock ();
        CoreNotifySignalList (&Event->EventGroup);
        CoreAcquireEventLock ();
    } else if ((Event->Type & EVT_NOTIFY_SIGNAL) != 0) {
        //
        // If signalling type is a notify function, queue it
        //
        CoreNotifyEvent (Event);
    }
  }

So always walk the List for an Ex event, but only notify the event if it is the 
right type. And the check should be in CoreNotifySignalList()

VOID
CoreNotifySignalList (
  IN EFI_GUID     *EventGroup
  )
{
  LIST_ENTRY              *Link;
  LIST_ENTRY              *Head;
  IEVENT                  *Event;

  CoreAcquireEventLock ();

  Head = &gEventSignalQueue;
  for (Link = Head->ForwardLink; Link != Head; Link = Link->ForwardLink) {
    Event = CR (Link, IEVENT, SignalLink, EVENT_SIGNATURE);
    if (CompareGuid (&Event->EventGroup, EventGroup)) {
       if ((Event->Type & EVT_NOTIFY_SIGNAL) != 0) {
        CoreNotifyEvent (Event);
      }
    }
  }

  CoreReleaseEventLock ();
}


Man, this code has been busted for a long time…. This bug predates the edk2!

The edk2 UefiLib even has a Dummy event and tries to hide the need for it from 
the caller….

https://svn.code.sf.net/p/edk2/code/trunk/edk2/MdePkg/Library/UefiLib/UefiNotTiano.c
/**
  An empty function to pass error checking of CreateEventEx ().

  This empty function ensures that EVT_NOTIFY_SIGNAL_ALL is error
  checked correctly since it is now mapped into CreateEventEx() in UEFI 2.0.
 
  @param  Event                 Event whose notification function is being 
invoked.
  @param  Context               The pointer to the notification function's 
context,
                                which is implementation-dependent.

**/
VOID
EFIAPI
InternalEmptyFunction (
  IN EFI_EVENT                Event,
  IN VOID                     *Context
  )
{
  return;
}

EFI_STATUS
EFIAPI
EfiCreateEventReadyToBootEx (
  IN  EFI_TPL           NotifyTpl,
  IN  EFI_EVENT_NOTIFY  NotifyFunction,  OPTIONAL
  IN  VOID              *NotifyContext,  OPTIONAL
  OUT EFI_EVENT         *ReadyToBootEvent
  )
{
  EFI_STATUS        Status;
  EFI_EVENT_NOTIFY  WorkerNotifyFunction;

  ASSERT (ReadyToBootEvent != NULL);

  if (gST->Hdr.Revision < EFI_2_00_SYSTEM_TABLE_REVISION) {
    DEBUG ((EFI_D_ERROR, "EFI1.1 can't support ReadyToBootEvent!"));
    ASSERT (FALSE);

    return EFI_UNSUPPORTED;
  } else {
    //
    // For UEFI 2.0 and the future use an Event Group
    //
    if (NotifyFunction == NULL) {
      //
      // CreateEventEx will check NotifyFunction is NULL or not and return 
error.
      // Use dummy routine for the case NotifyFunction is NULL.
      //
      WorkerNotifyFunction = InternalEmptyFunction;
    } else {
      WorkerNotifyFunction = NotifyFunction;
    }
    Status = gBS->CreateEventEx (
                    EVT_NOTIFY_SIGNAL,
                    NotifyTpl,
                    WorkerNotifyFunction,
                    NotifyContext,
                    &gEfiEventReadyToBootGuid,
                    ReadyToBootEvent
                    );
  }

  return Status;
}



Thanks,

Andrew Fish


>> Thanks.
>>  
>> --
>> Justin Johnson
>> Platform Software Engineer
>> Dell, Inc.
>>  
>> ------------------------------------------------------------------------------
>> Time is money. Stop wasting it! Get your web API in 5 minutes.
>> www.restlet.com/download
>> http://p.sf.net/sfu/restlet_______________________________________________
>> edk2-devel mailing list
>> edk2-devel@lists.sourceforge.net
>> https://lists.sourceforge.net/lists/listinfo/edk2-devel
> 
> ------------------------------------------------------------------------------
> Time is money. Stop wasting it! Get your web API in 5 minutes.
> www.restlet.com/download
> http://p.sf.net/sfu/restlet_______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/edk2-devel


------------------------------------------------------------------------------
Time is money. Stop wasting it! Get your web API in 5 minutes.
www.restlet.com/download
http://p.sf.net/sfu/restlet
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel

Reply via email to