Home | History | Annotate | Download | only in EfiRuntimeLib
      1 /*++
      2 
      3 Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
      4 This program and the accompanying materials
      5 are licensed and made available under the terms and conditions of the BSD License
      6 which accompanies this distribution.  The full text of the license may be found at
      7 http://opensource.org/licenses/bsd-license.php
      8 
      9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     11 
     12 Module Name:
     13 
     14   Event.c
     15 
     16 Abstract:
     17 
     18   Support for Event lib fucntions.
     19 
     20 --*/
     21 
     22 #include "Tiano.h"
     23 #include "EfiRuntimeLib.h"
     24 
     25 EFI_EVENT
     26 RtEfiLibCreateProtocolNotifyEvent (
     27   IN EFI_GUID             *ProtocolGuid,
     28   IN EFI_TPL              NotifyTpl,
     29   IN EFI_EVENT_NOTIFY     NotifyFunction,
     30   IN VOID                 *NotifyContext,
     31   OUT VOID                **Registration
     32   )
     33 /*++
     34 
     35 Routine Description:
     36 
     37   Create a protocol notification event and return it.
     38 
     39 Arguments:
     40 
     41   ProtocolGuid    - Protocol to register notification event on.
     42 
     43   NotifyTpl       - Maximum TPL to single the NotifyFunction.
     44 
     45   NotifyFunction  - EFI notification routine.
     46 
     47   NotifyContext   - Context passed into Event when it is created.
     48 
     49   Registration    - Registration key returned from RegisterProtocolNotify().
     50 
     51 Returns:
     52 
     53   The EFI_EVENT that has been registered to be signaled when a ProtocolGuid
     54   is added to the system.
     55 
     56 --*/
     57 {
     58   EFI_STATUS  Status;
     59   EFI_EVENT   Event;
     60 
     61   //
     62   // Create the event
     63   //
     64   Status = gBS->CreateEvent (
     65                   EFI_EVENT_NOTIFY_SIGNAL,
     66                   NotifyTpl,
     67                   NotifyFunction,
     68                   NotifyContext,
     69                   &Event
     70                   );
     71   ASSERT (!EFI_ERROR (Status));
     72 
     73   //
     74   // Register for protocol notifactions on this event
     75   //
     76   Status = gBS->RegisterProtocolNotify (
     77                   ProtocolGuid,
     78                   Event,
     79                   Registration
     80                   );
     81 
     82   ASSERT (!EFI_ERROR (Status));
     83 
     84   //
     85   // Kick the event so we will perform an initial pass of
     86   // current installed drivers
     87   //
     88   gBS->SignalEvent (Event);
     89   return Event;
     90 }
     91 
     92 EFI_STATUS
     93 EfiLibGetSystemConfigurationTable (
     94   IN EFI_GUID *TableGuid,
     95   IN OUT VOID **Table
     96   )
     97 /*++
     98 
     99 Routine Description:
    100 
    101   Return the EFI 1.0 System Tabl entry with TableGuid
    102 
    103 Arguments:
    104 
    105   TableGuid - Name of entry to return in the system table
    106   Table     - Pointer in EFI system table associated with TableGuid
    107 
    108 Returns:
    109 
    110   EFI_SUCCESS - Table returned;
    111   EFI_NOT_FOUND - TableGuid not in EFI system table
    112 
    113 --*/
    114 {
    115   UINTN Index;
    116 
    117   for (Index = 0; Index < gST->NumberOfTableEntries; Index++) {
    118     if (EfiCompareGuid (TableGuid, &(gST->ConfigurationTable[Index].VendorGuid))) {
    119       *Table = gST->ConfigurationTable[Index].VendorTable;
    120       return EFI_SUCCESS;
    121     }
    122   }
    123 
    124   return EFI_NOT_FOUND;
    125 }
    126 
    127 EFI_STATUS
    128 EfiConvertList (
    129   IN UINTN                DebugDisposition,
    130   IN OUT EFI_LIST_ENTRY   *ListHead
    131   )
    132 /*++
    133 
    134 Routine Description:
    135 
    136   Conver the standard Lib double linked list to a virtual mapping.
    137 
    138 Arguments:
    139 
    140   DebugDisposition - Argument to EfiConvertPointer (EFI 1.0 API)
    141 
    142   ListHead         - Head of linked list to convert
    143 
    144 Returns:
    145 
    146   EFI_SUCCESS
    147 
    148 --*/
    149 {
    150   EFI_LIST_ENTRY  *Link;
    151   EFI_LIST_ENTRY  *NextLink;
    152 
    153   //
    154   // Convert all the ForwardLink & BackLink pointers in the list
    155   //
    156   Link = ListHead;
    157   do {
    158     NextLink = Link->ForwardLink;
    159 
    160     EfiConvertPointer (
    161       Link->ForwardLink == ListHead ? DebugDisposition : 0,
    162       (VOID **) &Link->ForwardLink
    163       );
    164 
    165     EfiConvertPointer (
    166       Link->BackLink == ListHead ? DebugDisposition : 0,
    167       (VOID **) &Link->BackLink
    168       );
    169 
    170     Link = NextLink;
    171   } while (Link != ListHead);
    172   return EFI_SUCCESS;
    173 }
    174 
    175 #if (EFI_SPECIFICATION_VERSION >= 0x00020000)
    176 
    177 STATIC
    178 VOID
    179 EFIAPI
    180 EventNotifySignalAllNullEvent (
    181   IN EFI_EVENT                Event,
    182   IN VOID                     *Context
    183   )
    184 {
    185   //
    186   // This null event is a size efficent way to enusre that
    187   // EFI_EVENT_NOTIFY_SIGNAL_ALL is error checked correctly.
    188   // EFI_EVENT_NOTIFY_SIGNAL_ALL is now mapped into
    189   // CreateEventEx() and this function is used to make the
    190   // old error checking in CreateEvent() for Tiano extensions
    191   // function.
    192   //
    193   return;
    194 }
    195 
    196 #endif
    197 
    198 EFI_STATUS
    199 EFIAPI
    200 RtEfiCreateEventLegacyBoot (
    201   IN EFI_TPL                      NotifyTpl,
    202   IN EFI_EVENT_NOTIFY             NotifyFunction,
    203   IN VOID                         *NotifyContext,
    204   OUT EFI_EVENT                   *LegacyBootEvent
    205   )
    206 /*++
    207 
    208 Routine Description:
    209   Create a Legacy Boot Event.
    210   Tiano extended the CreateEvent Type enum to add a legacy boot event type.
    211   This was bad as Tiano did not own the enum. In UEFI 2.0 CreateEventEx was
    212   added and now it's possible to not voilate the UEFI specification by
    213   declaring a GUID for the legacy boot event class. This library supports
    214   the EFI 1.10 form and UEFI 2.0 form and allows common code to work both ways.
    215 
    216 Arguments:
    217   LegacyBootEvent  Returns the EFI event returned from gBS->CreateEvent(Ex)
    218 
    219 Returns:
    220   EFI_SUCCESS   Event was created.
    221   Other         Event was not created.
    222 
    223 --*/
    224 {
    225   EFI_STATUS        Status;
    226   UINT32            EventType;
    227   EFI_EVENT_NOTIFY  WorkerNotifyFunction;
    228 
    229 #if (EFI_SPECIFICATION_VERSION < 0x00020000)
    230 
    231   if (NotifyFunction == NULL) {
    232     EventType = EFI_EVENT_SIGNAL_LEGACY_BOOT | EFI_EVENT_NOTIFY_SIGNAL_ALL;
    233   } else {
    234     EventType = EFI_EVENT_SIGNAL_LEGACY_BOOT;
    235   }
    236   WorkerNotifyFunction = NotifyFunction;
    237 
    238   //
    239   // prior to UEFI 2.0 use Tiano extension to EFI
    240   //
    241   Status = gBS->CreateEvent (
    242                   EventType,
    243                   NotifyTpl,
    244                   WorkerNotifyFunction,
    245                   NotifyContext,
    246                   LegacyBootEvent
    247                   );
    248 #else
    249 
    250   EventType = EFI_EVENT_NOTIFY_SIGNAL;
    251   if (NotifyFunction == NULL) {
    252     //
    253     // CreatEventEx will check NotifyFunction is NULL or not
    254     //
    255     WorkerNotifyFunction = EventNotifySignalAllNullEvent;
    256   } else {
    257     WorkerNotifyFunction = NotifyFunction;
    258   }
    259 
    260   //
    261   // For UEFI 2.0 and the future use an Event Group
    262   //
    263   Status = gBS->CreateEventEx (
    264                   EventType,
    265                   NotifyTpl,
    266                   WorkerNotifyFunction,
    267                   NotifyContext,
    268                   &gEfiEventLegacyBootGuid,
    269                   LegacyBootEvent
    270                   );
    271 #endif
    272   return Status;
    273 }
    274 
    275 EFI_STATUS
    276 EFIAPI
    277 RtEfiCreateEventReadyToBoot (
    278   IN EFI_TPL                      NotifyTpl,
    279   IN EFI_EVENT_NOTIFY             NotifyFunction,
    280   IN VOID                         *NotifyContext,
    281   OUT EFI_EVENT                   *ReadyToBootEvent
    282   )
    283 /*++
    284 
    285 Routine Description:
    286   Create a Read to Boot Event.
    287 
    288   Tiano extended the CreateEvent Type enum to add a ready to boot event type.
    289   This was bad as Tiano did not own the enum. In UEFI 2.0 CreateEventEx was
    290   added and now it's possible to not voilate the UEFI specification and use
    291   the ready to boot event class defined in UEFI 2.0. This library supports
    292   the EFI 1.10 form and UEFI 2.0 form and allows common code to work both ways.
    293 
    294 Arguments:
    295   ReadyToBootEvent  Returns the EFI event returned from gBS->CreateEvent(Ex)
    296 
    297 Return:
    298   EFI_SUCCESS   - Event was created.
    299   Other         - Event was not created.
    300 
    301 --*/
    302 {
    303   EFI_STATUS        Status;
    304   UINT32            EventType;
    305   EFI_EVENT_NOTIFY  WorkerNotifyFunction;
    306 
    307 #if (EFI_SPECIFICATION_VERSION < 0x00020000)
    308 
    309   if (NotifyFunction == NULL) {
    310     EventType = EFI_EVENT_SIGNAL_READY_TO_BOOT | EFI_EVENT_NOTIFY_SIGNAL_ALL;
    311   } else {
    312     EventType = EFI_EVENT_SIGNAL_READY_TO_BOOT;
    313   }
    314   WorkerNotifyFunction = NotifyFunction;
    315 
    316   //
    317   // prior to UEFI 2.0 use Tiano extension to EFI
    318   //
    319   Status = gBS->CreateEvent (
    320                   EventType,
    321                   NotifyTpl,
    322                   WorkerNotifyFunction,
    323                   NotifyContext,
    324                   ReadyToBootEvent
    325                   );
    326 #else
    327 
    328   EventType = EFI_EVENT_NOTIFY_SIGNAL;
    329   if (NotifyFunction == NULL) {
    330     //
    331     // CreatEventEx will check NotifyFunction is NULL or not
    332     //
    333     WorkerNotifyFunction = EventNotifySignalAllNullEvent;
    334   } else {
    335     WorkerNotifyFunction = NotifyFunction;
    336   }
    337 
    338   //
    339   // For UEFI 2.0 and the future use an Event Group
    340   //
    341   Status = gBS->CreateEventEx (
    342                   EventType,
    343                   NotifyTpl,
    344                   WorkerNotifyFunction,
    345                   NotifyContext,
    346                   &gEfiEventReadyToBootGuid,
    347                   ReadyToBootEvent
    348                   );
    349 #endif
    350   return Status;
    351 }
    352