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