]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - MdeModulePkg/Core/Dxe/Library/Library.c
Add doxygen style comments for functions in DxeMain.
[mirror_edk2.git] / MdeModulePkg / Core / Dxe / Library / Library.c
... / ...
CommitLineData
1/** @file\r
2 DXE Core library services.\r
3 \r
4Copyright (c) 2006 - 2008, Intel Corporation\r
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
13**/\r
14\r
15#include <DxeMain.h>\r
16\r
17UINTN mErrorLevel = DEBUG_ERROR | DEBUG_LOAD;\r
18\r
19EFI_DXE_DEVICE_HANDLE_EXTENDED_DATA mStatusCodeData = {\r
20 {\r
21 sizeof (EFI_STATUS_CODE_DATA),\r
22 0,\r
23 EFI_STATUS_CODE_DXE_CORE_GUID\r
24 },\r
25 NULL\r
26};\r
27\r
28\r
29/**\r
30 Report status code of type EFI_PROGRESS_CODE by caller ID gEfiCallerIdGuid,\r
31 with a handle as additional information.\r
32\r
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
37\r
38**/\r
39VOID\r
40CoreReportProgressCodeSpecific (\r
41 IN EFI_STATUS_CODE_VALUE Value,\r
42 IN EFI_HANDLE Handle\r
43 )\r
44{\r
45 mStatusCodeData.DataHeader.Size = sizeof (EFI_DXE_DEVICE_HANDLE_EXTENDED_DATA) - sizeof (EFI_STATUS_CODE_DATA);\r
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
53 &gEfiCallerIdGuid,\r
54 (EFI_STATUS_CODE_DATA *) &mStatusCodeData\r
55 );\r
56 }\r
57}\r
58\r
59\r
60/**\r
61 Report status code of type EFI_PROGRESS_CODE by caller ID gEfiCallerIdGuid.\r
62\r
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
66\r
67**/\r
68VOID\r
69CoreReportProgressCode (\r
70 IN EFI_STATUS_CODE_VALUE Value\r
71 )\r
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
78 &gEfiCallerIdGuid,\r
79 NULL\r
80 );\r
81 }\r
82}\r
83\r
84\r
85\r
86/**\r
87 Allocate pool of type EfiBootServicesData, the size is specified with AllocationSize.\r
88\r
89 @param AllocationSize Size to allocate. \r
90\r
91 @return Pointer of the allocated pool.\r
92\r
93**/\r
94VOID *\r
95CoreAllocateBootServicesPool (\r
96 IN UINTN AllocationSize\r
97 )\r
98{\r
99 VOID *Memory;\r
100\r
101 CoreAllocatePool (EfiBootServicesData, AllocationSize, &Memory);\r
102 return Memory;\r
103}\r
104\r
105\r
106\r
107/**\r
108 Allocate pool of type EfiBootServicesData and zero it, the size is specified with AllocationSize.\r
109\r
110 @param AllocationSize Size to allocate. \r
111\r
112 @return Pointer of the allocated pool.\r
113\r
114**/\r
115VOID *\r
116CoreAllocateZeroBootServicesPool (\r
117 IN UINTN AllocationSize\r
118 )\r
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
128\r
129/**\r
130 Allocate pool of specified size with EfiBootServicesData type, and copy specified buffer to this pool.\r
131\r
132 @param AllocationSize Size to allocate. \r
133 @param Buffer Specified buffer that will be copy to the allocated \r
134 pool \r
135\r
136 @return Pointer of the allocated pool.\r
137\r
138**/\r
139VOID *\r
140CoreAllocateCopyPool (\r
141 IN UINTN AllocationSize,\r
142 IN VOID *Buffer\r
143 )\r
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
155\r
156/**\r
157 Allocate pool of type EfiRuntimeServicesData, the size is specified with AllocationSize.\r
158\r
159 @param AllocationSize Size to allocate. \r
160\r
161 @return Pointer of the allocated pool.\r
162\r
163**/\r
164VOID *\r
165CoreAllocateRuntimePool (\r
166 IN UINTN AllocationSize\r
167 )\r
168{\r
169 VOID *Memory;\r
170\r
171 CoreAllocatePool (EfiRuntimeServicesData, AllocationSize, &Memory);\r
172 return Memory;\r
173}\r
174\r
175\r
176/**\r
177 Allocate pool of specified size with EfiRuntimeServicesData type, and copy specified buffer to this pool.\r
178\r
179 @param AllocationSize Size to allocate. \r
180 @param Buffer Specified buffer that will be copy to the allocated \r
181 pool \r
182\r
183 @return Pointer of the allocated pool.\r
184\r
185**/\r
186VOID *\r
187CoreAllocateRuntimeCopyPool (\r
188 IN UINTN AllocationSize,\r
189 IN VOID *Buffer\r
190 )\r
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
207/**\r
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
214 @param Lock The EFI_LOCK structure to initialize \r
215\r
216 @retval EFI_SUCCESS Lock Owned. \r
217 @retval EFI_ACCESS_DENIED Reentrant Lock Acquisition, Lock not Owned.\r
218\r
219**/\r
220EFI_STATUS\r
221CoreAcquireLockOrFail (\r
222 IN EFI_LOCK *Lock\r
223 )\r
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
242\r
243/**\r
244 Raising to the task priority level of the mutual exclusion\r
245 lock, and then acquires ownership of the lock.\r
246\r
247 @param Lock The lock to acquire \r
248\r
249 @return Lock owned\r
250\r
251**/\r
252VOID\r
253CoreAcquireLock (\r
254 IN EFI_LOCK *Lock\r
255 )\r
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
265\r
266/**\r
267 Releases ownership of the mutual exclusion lock, and\r
268 restores the previous task priority level.\r
269\r
270 @param Lock The lock to release \r
271\r
272 @return Lock unowned\r
273\r
274**/\r
275VOID\r
276CoreReleaseLock (\r
277 IN EFI_LOCK *Lock\r
278 )\r
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
293\r
294/**\r
295 Calculate the size of a whole device path.\r
296\r
297 @param DevicePath The pointer to the device path data. \r
298\r
299 @return Size of device path data structure..\r
300\r
301**/\r
302UINTN\r
303CoreDevicePathSize (\r
304 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
305 )\r
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
328\r
329/**\r
330 Return TRUE is this is a multi instance device path.\r
331\r
332 @param DevicePath A pointer to a device path data structure. \r
333\r
334 @retval TRUE If DevicePath is multi instance. FALSE - If \r
335 DevicePath is not multi instance.\r
336\r
337**/\r
338BOOLEAN\r
339CoreIsDevicePathMultiInstance (\r
340 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
341 )\r
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
361\r
362/**\r
363 Duplicate a new device path data structure from the old one.\r
364\r
365 @param DevicePath A pointer to a device path data structure. \r
366\r
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
369\r
370**/\r
371EFI_DEVICE_PATH_PROTOCOL *\r
372CoreDuplicateDevicePath (\r
373 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
374 )\r
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
398\r
399/**\r
400 Function is used to append a Src1 and Src2 together.\r
401\r
402 @param Src1 A pointer to a device path data structure. \r
403 @param Src2 A pointer to a device path data structure. \r
404\r
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
408\r
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
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
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
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
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
514\r