2 DXE Core library services.
4 Copyright (c) 2006 - 2008, Intel Corporation. <BR>
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 UINTN mErrorLevel
= DEBUG_ERROR
| DEBUG_LOAD
;
19 EFI_DXE_DEVICE_HANDLE_EXTENDED_DATA mStatusCodeData
= {
21 sizeof (EFI_STATUS_CODE_DATA
),
23 EFI_STATUS_CODE_DXE_CORE_GUID
30 Report status code of type EFI_PROGRESS_CODE by caller ID gEfiCallerIdGuid,
31 with a handle as additional information.
33 @param Value Describes the class/subclass/operation of the
34 hardware or software entity that the Status Code
36 @param Handle Additional information.
40 CoreReportProgressCodeSpecific (
41 IN EFI_STATUS_CODE_VALUE Value
,
45 mStatusCodeData
.DataHeader
.Size
= sizeof (EFI_DXE_DEVICE_HANDLE_EXTENDED_DATA
) - sizeof (EFI_STATUS_CODE_DATA
);
46 mStatusCodeData
.Handle
= Handle
;
48 if ((gStatusCode
!= NULL
) && (gStatusCode
->ReportStatusCode
!= NULL
) ) {
49 gStatusCode
->ReportStatusCode (
54 (EFI_STATUS_CODE_DATA
*) &mStatusCodeData
61 Report status code of type EFI_PROGRESS_CODE by caller ID gEfiCallerIdGuid.
63 @param Value Describes the class/subclass/operation of the
64 hardware or software entity that the Status Code
69 CoreReportProgressCode (
70 IN EFI_STATUS_CODE_VALUE Value
73 if ((gStatusCode
!= NULL
) && (gStatusCode
->ReportStatusCode
!= NULL
) ) {
74 gStatusCode
->ReportStatusCode (
87 Allocate pool of type EfiBootServicesData, the size is specified with AllocationSize.
89 @param AllocationSize Size to allocate.
91 @return Pointer of the allocated pool.
95 CoreAllocateBootServicesPool (
96 IN UINTN AllocationSize
101 CoreAllocatePool (EfiBootServicesData
, AllocationSize
, &Memory
);
108 Allocate pool of type EfiBootServicesData and zero it, the size is specified with AllocationSize.
110 @param AllocationSize Size to allocate.
112 @return Pointer of the allocated pool.
116 CoreAllocateZeroBootServicesPool (
117 IN UINTN AllocationSize
122 Memory
= CoreAllocateBootServicesPool (AllocationSize
);
123 SetMem (Memory
, (Memory
== NULL
) ? 0 : AllocationSize
, 0);
130 Allocate pool of specified size with EfiBootServicesData type, and copy specified buffer to this pool.
132 @param AllocationSize Size to allocate.
133 @param Buffer Specified buffer that will be copy to the allocated
136 @return Pointer of the allocated pool.
140 CoreAllocateCopyPool (
141 IN UINTN AllocationSize
,
147 Memory
= CoreAllocateBootServicesPool (AllocationSize
);
148 CopyMem (Memory
, Buffer
, (Memory
== NULL
) ? 0 : AllocationSize
);
157 Allocate pool of type EfiRuntimeServicesData, the size is specified with AllocationSize.
159 @param AllocationSize Size to allocate.
161 @return Pointer of the allocated pool.
165 CoreAllocateRuntimePool (
166 IN UINTN AllocationSize
171 CoreAllocatePool (EfiRuntimeServicesData
, AllocationSize
, &Memory
);
177 Allocate pool of specified size with EfiRuntimeServicesData type, and copy specified buffer to this pool.
179 @param AllocationSize Size to allocate.
180 @param Buffer Specified buffer that will be copy to the allocated
183 @return Pointer of the allocated pool.
187 CoreAllocateRuntimeCopyPool (
188 IN UINTN AllocationSize
,
194 Memory
= CoreAllocateRuntimePool (AllocationSize
);
195 CopyMem (Memory
, Buffer
, (Memory
== NULL
) ? 0 : AllocationSize
);
208 Initialize a basic mutual exclusion lock. Each lock
209 provides mutual exclusion access at it's task priority
210 level. Since there is no-premption (at any TPL) or
211 multiprocessor support, acquiring the lock only consists
212 of raising to the locks TPL.
214 @param Lock The EFI_LOCK structure to initialize
216 @retval EFI_SUCCESS Lock Owned.
217 @retval EFI_ACCESS_DENIED Reentrant Lock Acquisition, Lock not Owned.
221 CoreAcquireLockOrFail (
225 ASSERT (Lock
!= NULL
);
226 ASSERT (Lock
->Lock
!= EfiLockUninitialized
);
228 if (Lock
->Lock
== EfiLockAcquired
) {
230 // Lock is already owned, so bail out
232 return EFI_ACCESS_DENIED
;
235 Lock
->OwnerTpl
= CoreRaiseTpl (Lock
->Tpl
);
237 Lock
->Lock
= EfiLockAcquired
;
244 Raising to the task priority level of the mutual exclusion
245 lock, and then acquires ownership of the lock.
247 @param Lock The lock to acquire
257 ASSERT (Lock
!= NULL
);
258 ASSERT (Lock
->Lock
== EfiLockReleased
);
260 Lock
->OwnerTpl
= CoreRaiseTpl (Lock
->Tpl
);
261 Lock
->Lock
= EfiLockAcquired
;
267 Releases ownership of the mutual exclusion lock, and
268 restores the previous task priority level.
270 @param Lock The lock to release
282 ASSERT (Lock
!= NULL
);
283 ASSERT (Lock
->Lock
== EfiLockAcquired
);
285 Tpl
= Lock
->OwnerTpl
;
287 Lock
->Lock
= EfiLockReleased
;
289 CoreRestoreTpl (Tpl
);
295 Calculate the size of a whole device path.
297 @param DevicePath The pointer to the device path data.
299 @return Size of device path data structure..
304 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
307 EFI_DEVICE_PATH_PROTOCOL
*Start
;
309 if (DevicePath
== NULL
) {
314 // Search for the end of the device path structure
317 while (!EfiIsDevicePathEnd (DevicePath
)) {
318 DevicePath
= EfiNextDevicePathNode (DevicePath
);
322 // Compute the size and add back in the size of the end device path structure
324 return ((UINTN
)DevicePath
- (UINTN
)Start
) + sizeof(EFI_DEVICE_PATH_PROTOCOL
);
330 Return TRUE is this is a multi instance device path.
332 @param DevicePath A pointer to a device path data structure.
334 @retval TRUE If DevicePath is multi instance. FALSE - If
335 DevicePath is not multi instance.
339 CoreIsDevicePathMultiInstance (
340 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
343 EFI_DEVICE_PATH_PROTOCOL
*Node
;
345 if (DevicePath
== NULL
) {
350 while (!EfiIsDevicePathEnd (Node
)) {
351 if (EfiIsDevicePathEndInstance (Node
)) {
354 Node
= EfiNextDevicePathNode (Node
);
363 Duplicate a new device path data structure from the old one.
365 @param DevicePath A pointer to a device path data structure.
367 @return A pointer to the new allocated device path data.
368 @return Caller must free the memory used by DevicePath if it is no longer needed.
371 EFI_DEVICE_PATH_PROTOCOL
*
372 CoreDuplicateDevicePath (
373 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
376 EFI_DEVICE_PATH_PROTOCOL
*NewDevicePath
;
379 if (DevicePath
== NULL
) {
386 Size
= CoreDevicePathSize (DevicePath
);
389 // Allocate space for duplicate device path
391 NewDevicePath
= CoreAllocateCopyPool (Size
, DevicePath
);
393 return NewDevicePath
;
400 Function is used to append a Src1 and Src2 together.
402 @param Src1 A pointer to a device path data structure.
403 @param Src2 A pointer to a device path data structure.
405 @return A pointer to the new device path is returned.
406 @return NULL is returned if space for the new device path could not be allocated from pool.
407 @return It is up to the caller to free the memory used by Src1 and Src2 if they are no longer needed.
410 EFI_DEVICE_PATH_PROTOCOL
*
411 CoreAppendDevicePath (
412 IN EFI_DEVICE_PATH_PROTOCOL
*Src1
,
413 IN EFI_DEVICE_PATH_PROTOCOL
*Src2
419 EFI_DEVICE_PATH_PROTOCOL
*NewDevicePath
;
420 EFI_DEVICE_PATH_PROTOCOL
*SecondDevicePath
;
422 if (Src1
== NULL
&& Src2
== NULL
) {
427 // Allocate space for the combined device path. It only has one end node of
428 // length EFI_DEVICE_PATH_PROTOCOL
430 Size1
= CoreDevicePathSize (Src1
);
431 Size2
= CoreDevicePathSize (Src2
);
432 Size
= Size1
+ Size2
- sizeof(EFI_DEVICE_PATH_PROTOCOL
);
434 NewDevicePath
= CoreAllocateCopyPool (Size
, Src1
);
435 if (NewDevicePath
!= NULL
) {
438 // Over write Src1 EndNode and do the copy
440 SecondDevicePath
= (EFI_DEVICE_PATH_PROTOCOL
*)((CHAR8
*)NewDevicePath
+ (Size1
- sizeof(EFI_DEVICE_PATH_PROTOCOL
)));
441 CopyMem (SecondDevicePath
, Src2
, Size2
);
444 return NewDevicePath
;
451 Create a protocol notification event and return it.
453 @param ProtocolGuid Protocol to register notification event on.
454 @param NotifyTpl Maximum TPL to signal the NotifyFunction.
455 @param NotifyFunction EFI notification routine.
456 @param NotifyContext Context passed into Event when it is created.
457 @param Registration Registration key returned from
458 RegisterProtocolNotify().
459 @param SignalFlag Boolean value to decide whether kick the event after
462 @return The EFI_EVENT that has been registered to be signaled when a ProtocolGuid
463 is added to the system.
467 CoreCreateProtocolNotifyEvent (
468 IN EFI_GUID
*ProtocolGuid
,
469 IN EFI_TPL NotifyTpl
,
470 IN EFI_EVENT_NOTIFY NotifyFunction
,
471 IN VOID
*NotifyContext
,
472 OUT VOID
**Registration
,
473 IN BOOLEAN SignalFlag
483 Status
= CoreCreateEvent (
490 ASSERT_EFI_ERROR (Status
);
493 // Register for protocol notifactions on this event
496 Status
= CoreRegisterProtocolNotify (
501 ASSERT_EFI_ERROR (Status
);
505 // Kick the event so we will perform an initial pass of
506 // current installed drivers
508 CoreSignalEvent (Event
);