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