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