]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Core/Dxe/Library/Library.c
Update to fix minor coding style issues.
[mirror_edk2.git] / MdeModulePkg / Core / Dxe / Library / Library.c
CommitLineData
162ed594 1/** @file\r
797a9d67 2 DXE Core library services.\r
23c98c94 3\r
4Copyright (c) 2006 - 2008, Intel Corporation. <BR>\r
28a00297 5All rights reserved. This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
797a9d67 13**/\r
28a00297 14\r
15#include <DxeMain.h>\r
16\r
162ed594 17UINTN mErrorLevel = DEBUG_ERROR | DEBUG_LOAD;\r
28a00297 18\r
797a9d67 19EFI_DXE_DEVICE_HANDLE_EXTENDED_DATA mStatusCodeData = {\r
28a00297 20 {\r
21 sizeof (EFI_STATUS_CODE_DATA),\r
22 0,\r
797a9d67 23 EFI_STATUS_CODE_DXE_CORE_GUID\r
28a00297 24 },\r
25 NULL\r
26};\r
27\r
28a00297 28\r
162ed594 29/**\r
eba54e17 30 Report status code of type EFI_PROGRESS_CODE by caller ID gEfiCallerIdGuid,\r
28a00297 31 with a handle as additional information.\r
32\r
162ed594 33 @param Value Describes the class/subclass/operation of the \r
34 hardware or software entity that the Status Code \r
35 relates to. \r
36 @param Handle Additional information.\r
28a00297 37\r
162ed594 38**/\r
39VOID\r
40CoreReportProgressCodeSpecific (\r
41 IN EFI_STATUS_CODE_VALUE Value,\r
42 IN EFI_HANDLE Handle\r
43 )\r
28a00297 44{\r
797a9d67 45 mStatusCodeData.DataHeader.Size = sizeof (EFI_DXE_DEVICE_HANDLE_EXTENDED_DATA) - sizeof (EFI_STATUS_CODE_DATA);\r
28a00297 46 mStatusCodeData.Handle = Handle;\r
47\r
48 if ((gStatusCode != NULL) && (gStatusCode->ReportStatusCode != NULL) ) {\r
49 gStatusCode->ReportStatusCode (\r
50 EFI_PROGRESS_CODE,\r
51 Value,\r
52 0,\r
eba54e17 53 &gEfiCallerIdGuid,\r
28a00297 54 (EFI_STATUS_CODE_DATA *) &mStatusCodeData\r
55 );\r
56 }\r
57}\r
58\r
28a00297 59\r
162ed594 60/**\r
eba54e17 61 Report status code of type EFI_PROGRESS_CODE by caller ID gEfiCallerIdGuid.\r
28a00297 62\r
162ed594 63 @param Value Describes the class/subclass/operation of the \r
64 hardware or software entity that the Status Code \r
65 relates to.\r
28a00297 66\r
162ed594 67**/\r
68VOID\r
69CoreReportProgressCode (\r
70 IN EFI_STATUS_CODE_VALUE Value\r
71 )\r
28a00297 72{\r
73 if ((gStatusCode != NULL) && (gStatusCode->ReportStatusCode != NULL) ) {\r
74 gStatusCode->ReportStatusCode (\r
75 EFI_PROGRESS_CODE,\r
76 Value,\r
77 0,\r
eba54e17 78 &gEfiCallerIdGuid,\r
28a00297 79 NULL\r
80 );\r
81 }\r
82}\r
83\r
84\r
28a00297 85\r
162ed594 86/**\r
28a00297 87 Allocate pool of type EfiBootServicesData, the size is specified with AllocationSize.\r
88\r
162ed594 89 @param AllocationSize Size to allocate. \r
28a00297 90\r
162ed594 91 @return Pointer of the allocated pool.\r
28a00297 92\r
162ed594 93**/\r
94VOID *\r
95CoreAllocateBootServicesPool (\r
96 IN UINTN AllocationSize\r
97 )\r
28a00297 98{\r
99 VOID *Memory;\r
100\r
101 CoreAllocatePool (EfiBootServicesData, AllocationSize, &Memory);\r
102 return Memory;\r
103}\r
104\r
105\r
28a00297 106\r
162ed594 107/**\r
28a00297 108 Allocate pool of type EfiBootServicesData and zero it, the size is specified with AllocationSize.\r
109\r
162ed594 110 @param AllocationSize Size to allocate. \r
28a00297 111\r
162ed594 112 @return Pointer of the allocated pool.\r
28a00297 113\r
162ed594 114**/\r
115VOID *\r
116CoreAllocateZeroBootServicesPool (\r
117 IN UINTN AllocationSize\r
118 )\r
28a00297 119{\r
120 VOID *Memory;\r
121\r
122 Memory = CoreAllocateBootServicesPool (AllocationSize);\r
123 SetMem (Memory, (Memory == NULL) ? 0 : AllocationSize, 0);\r
124 return Memory;\r
125}\r
126\r
127\r
28a00297 128\r
162ed594 129/**\r
28a00297 130 Allocate pool of specified size with EfiBootServicesData type, and copy specified buffer to this pool.\r
131\r
162ed594 132 @param AllocationSize Size to allocate. \r
133 @param Buffer Specified buffer that will be copy to the allocated \r
134 pool \r
28a00297 135\r
162ed594 136 @return Pointer of the allocated pool.\r
28a00297 137\r
162ed594 138**/\r
139VOID *\r
140CoreAllocateCopyPool (\r
141 IN UINTN AllocationSize,\r
142 IN VOID *Buffer\r
143 )\r
28a00297 144{\r
145 VOID *Memory;\r
146\r
147 Memory = CoreAllocateBootServicesPool (AllocationSize);\r
148 CopyMem (Memory, Buffer, (Memory == NULL) ? 0 : AllocationSize);\r
149\r
150 return Memory;\r
151}\r
152\r
153\r
154\r
28a00297 155\r
162ed594 156/**\r
28a00297 157 Allocate pool of type EfiRuntimeServicesData, the size is specified with AllocationSize.\r
158\r
162ed594 159 @param AllocationSize Size to allocate. \r
28a00297 160\r
162ed594 161 @return Pointer of the allocated pool.\r
28a00297 162\r
162ed594 163**/\r
164VOID *\r
165CoreAllocateRuntimePool (\r
166 IN UINTN AllocationSize\r
167 )\r
28a00297 168{\r
169 VOID *Memory;\r
170\r
171 CoreAllocatePool (EfiRuntimeServicesData, AllocationSize, &Memory);\r
172 return Memory;\r
173}\r
174\r
28a00297 175\r
162ed594 176/**\r
28a00297 177 Allocate pool of specified size with EfiRuntimeServicesData type, and copy specified buffer to this pool.\r
178\r
162ed594 179 @param AllocationSize Size to allocate. \r
180 @param Buffer Specified buffer that will be copy to the allocated \r
181 pool \r
28a00297 182\r
162ed594 183 @return Pointer of the allocated pool.\r
28a00297 184\r
162ed594 185**/\r
186VOID *\r
187CoreAllocateRuntimeCopyPool (\r
188 IN UINTN AllocationSize,\r
189 IN VOID *Buffer\r
190 )\r
28a00297 191{\r
192 VOID *Memory;\r
193\r
194 Memory = CoreAllocateRuntimePool (AllocationSize);\r
195 CopyMem (Memory, Buffer, (Memory == NULL) ? 0 : AllocationSize);\r
196\r
197 return Memory;\r
198}\r
199\r
200\r
201\r
202//\r
203// Lock Stuff\r
204//\r
205\r
206\r
162ed594 207/**\r
28a00297 208 Initialize a basic mutual exclusion lock. Each lock\r
209 provides mutual exclusion access at it's task priority\r
210 level. Since there is no-premption (at any TPL) or\r
211 multiprocessor support, acquiring the lock only consists\r
212 of raising to the locks TPL.\r
213\r
162ed594 214 @param Lock The EFI_LOCK structure to initialize \r
28a00297 215\r
162ed594 216 @retval EFI_SUCCESS Lock Owned. \r
217 @retval EFI_ACCESS_DENIED Reentrant Lock Acquisition, Lock not Owned.\r
28a00297 218\r
162ed594 219**/\r
220EFI_STATUS\r
221CoreAcquireLockOrFail (\r
222 IN EFI_LOCK *Lock\r
223 )\r
28a00297 224{\r
225 ASSERT (Lock != NULL);\r
226 ASSERT (Lock->Lock != EfiLockUninitialized);\r
227\r
228 if (Lock->Lock == EfiLockAcquired) {\r
229 //\r
230 // Lock is already owned, so bail out\r
231 //\r
232 return EFI_ACCESS_DENIED;\r
233 }\r
234\r
235 Lock->OwnerTpl = CoreRaiseTpl (Lock->Tpl);\r
236\r
237 Lock->Lock = EfiLockAcquired;\r
238 return EFI_SUCCESS;\r
239}\r
240\r
241\r
28a00297 242\r
162ed594 243/**\r
28a00297 244 Raising to the task priority level of the mutual exclusion\r
245 lock, and then acquires ownership of the lock.\r
246\r
162ed594 247 @param Lock The lock to acquire \r
28a00297 248\r
162ed594 249 @return Lock owned\r
28a00297 250\r
162ed594 251**/\r
252VOID\r
253CoreAcquireLock (\r
254 IN EFI_LOCK *Lock\r
255 )\r
28a00297 256{\r
257 ASSERT (Lock != NULL);\r
258 ASSERT (Lock->Lock == EfiLockReleased);\r
259\r
260 Lock->OwnerTpl = CoreRaiseTpl (Lock->Tpl);\r
261 Lock->Lock = EfiLockAcquired;\r
262}\r
263\r
264\r
28a00297 265\r
162ed594 266/**\r
267 Releases ownership of the mutual exclusion lock, and\r
268 restores the previous task priority level.\r
28a00297 269\r
162ed594 270 @param Lock The lock to release \r
28a00297 271\r
162ed594 272 @return Lock unowned\r
28a00297 273\r
162ed594 274**/\r
275VOID\r
276CoreReleaseLock (\r
277 IN EFI_LOCK *Lock\r
278 )\r
28a00297 279{\r
280 EFI_TPL Tpl;\r
281\r
282 ASSERT (Lock != NULL);\r
283 ASSERT (Lock->Lock == EfiLockAcquired);\r
284\r
285 Tpl = Lock->OwnerTpl;\r
286\r
287 Lock->Lock = EfiLockReleased;\r
288\r
289 CoreRestoreTpl (Tpl);\r
290}\r
291\r
292\r
28a00297 293\r
162ed594 294/**\r
28a00297 295 Calculate the size of a whole device path.\r
296\r
162ed594 297 @param DevicePath The pointer to the device path data. \r
28a00297 298\r
162ed594 299 @return Size of device path data structure..\r
28a00297 300\r
162ed594 301**/\r
302UINTN\r
303CoreDevicePathSize (\r
304 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
305 )\r
28a00297 306{\r
307 EFI_DEVICE_PATH_PROTOCOL *Start;\r
308\r
309 if (DevicePath == NULL) {\r
310 return 0;\r
311 }\r
312\r
313 //\r
314 // Search for the end of the device path structure\r
315 //\r
316 Start = DevicePath;\r
317 while (!EfiIsDevicePathEnd (DevicePath)) {\r
318 DevicePath = EfiNextDevicePathNode (DevicePath);\r
319 }\r
320\r
321 //\r
322 // Compute the size and add back in the size of the end device path structure\r
323 //\r
324 return ((UINTN)DevicePath - (UINTN)Start) + sizeof(EFI_DEVICE_PATH_PROTOCOL);\r
325}\r
326\r
327\r
28a00297 328\r
162ed594 329/**\r
28a00297 330 Return TRUE is this is a multi instance device path.\r
331\r
162ed594 332 @param DevicePath A pointer to a device path data structure. \r
28a00297 333\r
162ed594 334 @retval TRUE If DevicePath is multi instance. FALSE - If \r
335 DevicePath is not multi instance.\r
28a00297 336\r
162ed594 337**/\r
338BOOLEAN\r
339CoreIsDevicePathMultiInstance (\r
340 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
341 )\r
28a00297 342{\r
343 EFI_DEVICE_PATH_PROTOCOL *Node;\r
344\r
345 if (DevicePath == NULL) {\r
346 return FALSE;\r
347 }\r
348\r
349 Node = DevicePath;\r
350 while (!EfiIsDevicePathEnd (Node)) {\r
351 if (EfiIsDevicePathEndInstance (Node)) {\r
352 return TRUE;\r
353 }\r
354 Node = EfiNextDevicePathNode (Node);\r
355 }\r
356 return FALSE;\r
357}\r
358\r
359\r
360\r
28a00297 361\r
162ed594 362/**\r
28a00297 363 Duplicate a new device path data structure from the old one.\r
364\r
162ed594 365 @param DevicePath A pointer to a device path data structure. \r
28a00297 366\r
162ed594 367 @return A pointer to the new allocated device path data.\r
368 @return Caller must free the memory used by DevicePath if it is no longer needed.\r
28a00297 369\r
162ed594 370**/\r
371EFI_DEVICE_PATH_PROTOCOL *\r
372CoreDuplicateDevicePath (\r
373 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
374 )\r
28a00297 375{\r
376 EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;\r
377 UINTN Size;\r
378\r
379 if (DevicePath == NULL) {\r
380 return NULL;\r
381 }\r
382\r
383 //\r
384 // Compute the size\r
385 //\r
386 Size = CoreDevicePathSize (DevicePath);\r
387\r
388 //\r
389 // Allocate space for duplicate device path\r
390 //\r
391 NewDevicePath = CoreAllocateCopyPool (Size, DevicePath);\r
392\r
393 return NewDevicePath;\r
394}\r
395\r
396\r
397\r
28a00297 398\r
162ed594 399/**\r
28a00297 400 Function is used to append a Src1 and Src2 together.\r
401\r
162ed594 402 @param Src1 A pointer to a device path data structure. \r
403 @param Src2 A pointer to a device path data structure. \r
28a00297 404\r
162ed594 405 @return A pointer to the new device path is returned.\r
406 @return NULL is returned if space for the new device path could not be allocated from pool.\r
407 @return It is up to the caller to free the memory used by Src1 and Src2 if they are no longer needed.\r
28a00297 408\r
162ed594 409**/\r
410EFI_DEVICE_PATH_PROTOCOL *\r
411CoreAppendDevicePath (\r
412 IN EFI_DEVICE_PATH_PROTOCOL *Src1,\r
413 IN EFI_DEVICE_PATH_PROTOCOL *Src2\r
414 )\r
28a00297 415{\r
416 UINTN Size;\r
417 UINTN Size1;\r
418 UINTN Size2;\r
419 EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;\r
420 EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath;\r
421\r
422 if (Src1 == NULL && Src2 == NULL) {\r
423 return NULL;\r
424 }\r
425\r
426 //\r
427 // Allocate space for the combined device path. It only has one end node of\r
428 // length EFI_DEVICE_PATH_PROTOCOL\r
429 //\r
430 Size1 = CoreDevicePathSize (Src1);\r
431 Size2 = CoreDevicePathSize (Src2);\r
432 Size = Size1 + Size2 - sizeof(EFI_DEVICE_PATH_PROTOCOL);\r
433\r
434 NewDevicePath = CoreAllocateCopyPool (Size, Src1);\r
435 if (NewDevicePath != NULL) {\r
436\r
437 //\r
438 // Over write Src1 EndNode and do the copy\r
439 //\r
440 SecondDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)((CHAR8 *)NewDevicePath + (Size1 - sizeof(EFI_DEVICE_PATH_PROTOCOL)));\r
441 CopyMem (SecondDevicePath, Src2, Size2);\r
442 }\r
443\r
444 return NewDevicePath;\r
445}\r
446\r
447\r
448\r
162ed594 449\r
450/**\r
451 Create a protocol notification event and return it.\r
452\r
453 @param ProtocolGuid Protocol to register notification event on. \r
454 @param NotifyTpl Maximum TPL to signal the NotifyFunction. \r
455 @param NotifyFunction EFI notification routine. \r
456 @param NotifyContext Context passed into Event when it is created. \r
457 @param Registration Registration key returned from \r
458 RegisterProtocolNotify(). \r
459 @param SignalFlag Boolean value to decide whether kick the event after \r
460 register or not. \r
461\r
462 @return The EFI_EVENT that has been registered to be signaled when a ProtocolGuid\r
463 is added to the system.\r
464\r
465**/\r
28a00297 466EFI_EVENT\r
467CoreCreateProtocolNotifyEvent (\r
468 IN EFI_GUID *ProtocolGuid,\r
469 IN EFI_TPL NotifyTpl,\r
470 IN EFI_EVENT_NOTIFY NotifyFunction,\r
471 IN VOID *NotifyContext,\r
472 OUT VOID **Registration,\r
473 IN BOOLEAN SignalFlag\r
474 )\r
28a00297 475{\r
476 EFI_STATUS Status;\r
477 EFI_EVENT Event;\r
478\r
479 //\r
480 // Create the event\r
481 //\r
482\r
483 Status = CoreCreateEvent (\r
484 EVT_NOTIFY_SIGNAL,\r
485 NotifyTpl,\r
486 NotifyFunction,\r
487 NotifyContext,\r
488 &Event\r
489 );\r
490 ASSERT_EFI_ERROR (Status);\r
491\r
492 //\r
493 // Register for protocol notifactions on this event\r
494 //\r
495\r
496 Status = CoreRegisterProtocolNotify (\r
497 ProtocolGuid,\r
498 Event,\r
499 Registration\r
500 );\r
501 ASSERT_EFI_ERROR (Status);\r
502\r
503 if (SignalFlag) {\r
504 //\r
505 // Kick the event so we will perform an initial pass of\r
506 // current installed drivers\r
507 //\r
508 CoreSignalEvent (Event);\r
509 }\r
510\r
511 return Event;\r
512}\r
513\r
162ed594 514\r