]> git.proxmox.com Git - mirror_edk2.git/blame - EdkCompatibilityPkg/Foundation/Library/Pei/PeiLib/PeiLib.c
1) Sync EdkCompatibilityPkg with EDK 1.04. The changes includes:
[mirror_edk2.git] / EdkCompatibilityPkg / Foundation / Library / Pei / PeiLib / PeiLib.c
CommitLineData
3eb9473e 1/*++\r
2\r
3Copyright (c) 2004 - 2007, 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 PeiLib.c\r
15\r
16Abstract:\r
17\r
18 PEI Library Functions\r
19 \r
20--*/\r
21\r
22#include "TianoCommon.h"\r
23#include "PeiHob.h"\r
24#include "Pei.h"\r
25#include "PeiLib.h"\r
26\r
27\r
28VOID\r
29PeiCopyMem (\r
30 IN VOID *Destination,\r
31 IN VOID *Source,\r
32 IN UINTN Length\r
33 );\r
34\r
35VOID\r
36ZeroMem (\r
37 IN VOID *Buffer,\r
38 IN UINTN Size\r
39 )\r
40/*++\r
41\r
42Routine Description:\r
43\r
44 Set Buffer to zero for Size bytes.\r
45\r
46Arguments:\r
47\r
48 Buffer - Memory to set.\r
49\r
50 Size - Number of bytes to set\r
51\r
52Returns:\r
53\r
54 None\r
55\r
56--*/\r
57{\r
58 INT8 *Ptr;\r
59\r
60 Ptr = Buffer;\r
61 while (Size--) {\r
62 *(Ptr++) = 0;\r
63 }\r
64}\r
65\r
66VOID\r
67PeiCopyMem (\r
68 IN VOID *Destination,\r
69 IN VOID *Source,\r
70 IN UINTN Length\r
71 )\r
72/*++\r
73\r
74Routine Description:\r
75\r
76 Copy Length bytes from Source to Destination.\r
77\r
78Arguments:\r
79\r
80 Destination - Target of copy\r
81\r
82 Source - Place to copy from\r
83\r
84 Length - Number of bytes to copy\r
85\r
86Returns:\r
87\r
88 None\r
89\r
90--*/\r
91{\r
92 CHAR8 *Destination8;\r
93 CHAR8 *Source8;\r
94\r
95 Destination8 = Destination;\r
96 Source8 = Source;\r
97 if (((Source8 + Length) <= Destination8) || (Source8 >= Destination8)) {\r
98 while (Length--) {\r
99 *(Destination8++) = *(Source8++);\r
100 }\r
101 } else {\r
102 while (Length--) {\r
103 *(Destination8 + Length) = *(Source8 + Length);\r
104 }\r
105 }\r
106}\r
107\r
108VOID\r
109CopyMem (\r
110 IN VOID *Destination,\r
111 IN VOID *Source,\r
112 IN UINTN Length\r
113 )\r
114/*++\r
115\r
116Routine Description:\r
117\r
118 Copy Length bytes from Source to Destination.\r
119\r
120Arguments:\r
121\r
122 Destination - Target of copy\r
123\r
124 Source - Place to copy from\r
125\r
126 Length - Number of bytes to copy\r
127\r
128Returns:\r
129\r
130 None\r
131\r
132--*/\r
133{\r
134 CHAR8 *Destination8;\r
135 CHAR8 *Source8;\r
136\r
137 Destination8 = Destination;\r
138 Source8 = Source;\r
139 if (((Source8 + Length) <= Destination8) || (Source8 >= Destination8)) {\r
140 while (Length--) {\r
141 *(Destination8++) = *(Source8++);\r
142 }\r
143 } else {\r
144 while (Length--) {\r
145 *(Destination8 + Length) = *(Source8 + Length);\r
146 }\r
147 }\r
148}\r
149\r
150\r
151BOOLEAN\r
152CompareGuid (\r
153 IN EFI_GUID *Guid1,\r
154 IN EFI_GUID *Guid2\r
155 )\r
156/*++\r
157\r
158Routine Description:\r
159\r
160 Compares two GUIDs\r
161\r
162Arguments:\r
163\r
164 Guid1 - guid to compare\r
165 Guid2 - guid to compare\r
166\r
167Returns:\r
168 = TRUE if Guid1 == Guid2\r
169 = FALSE if Guid1 != Guid2 \r
170\r
171--*/\r
172{\r
173 if ((((INT32 *) Guid1)[0] - ((INT32 *) Guid2)[0]) == 0) {\r
174 if ((((INT32 *) Guid1)[1] - ((INT32 *) Guid2)[1]) == 0) {\r
175 if ((((INT32 *) Guid1)[2] - ((INT32 *) Guid2)[2]) == 0) {\r
176 if ((((INT32 *) Guid1)[3] - ((INT32 *) Guid2)[3]) == 0) {\r
177 return TRUE;\r
178 }\r
179 }\r
180 }\r
181 }\r
182\r
183 return FALSE;\r
184}\r
185\r
186\r
187#if (PI_SPECIFICATION_VERSION >= 0x00010000)\r
188\r
189VOID *\r
190EFIAPI\r
191ScanGuid (\r
192 IN VOID *Buffer,\r
193 IN UINTN Length,\r
194 IN EFI_GUID *Guid\r
195 )\r
196/*++\r
197\r
198Routine Description:\r
199\r
200 Scans a target buffer for a GUID, and returns a pointer to the matching GUID\r
201 in the target buffer.\r
202\r
203 This function searches target the buffer specified by Buffer and Length from\r
204 the lowest address to the highest address at 128-bit increments for the 128-bit\r
205 GUID value that matches Guid. If a match is found, then a pointer to the matching\r
206 GUID in the target buffer is returned. If no match is found, then NULL is returned.\r
207 If Length is 0, then NULL is returned.\r
208 If Length > 0 and Buffer is NULL, then ASSERT().\r
209 If Buffer is not aligned on a 32-bit boundary, then ASSERT().\r
210 If Length is not aligned on a 128-bit boundary, then ASSERT().\r
211 If Length is greater than (EFI_MAX_ADDRESS ?Buffer + 1), then ASSERT(). \r
212\r
213Arguments:\r
214\r
215 Buffer - Pointer to the target buffer to scan.\r
216 Length - Number of bytes in Buffer to scan.\r
217 Guid - Value to search for in the target buffer.\r
218 \r
219Returns:\r
220 A pointer to the matching Guid in the target buffer or NULL otherwise.\r
221\r
222--*/\r
223{\r
224 EFI_GUID *GuidPtr;\r
225 EFI_PEI_SERVICES **PeiServices;\r
226 \r
227 PeiServices = GetPeiServicesTablePointer();\r
228 PEI_ASSERT(PeiServices, (((UINTN)Buffer & (sizeof (Guid->Data1) - 1)) == 0));\r
229 PEI_ASSERT(PeiServices, (Length <= (EFI_MAX_ADDRESS - (UINTN)Buffer + 1)));\r
230 PEI_ASSERT(PeiServices, ((Length & (sizeof (*GuidPtr) - 1)) == 0));\r
231\r
232 GuidPtr = (EFI_GUID*)Buffer;\r
233 Buffer = GuidPtr + Length / sizeof (*GuidPtr);\r
234 while (GuidPtr < (EFI_GUID*)Buffer) {\r
235 if (CompareGuid (GuidPtr, Guid)) {\r
236 return (VOID*)GuidPtr;\r
237 }\r
238 GuidPtr++;\r
239 }\r
240 return NULL;\r
241}\r
242\r
243\r
244VOID *\r
245EFIAPI\r
246InvalidateInstructionCacheRange (\r
247 IN VOID *Address,\r
248 IN UINTN Length\r
249 )\r
250/*++\r
251\r
252Routine Description:\r
253\r
254 Invalidates a range of instruction cache lines in the cache coherency domain\r
255 of the calling CPU.\r
256\r
257 Invalidates the instruction cache lines specified by Address and Length. If\r
258 Address is not aligned on a cache line boundary, then entire instruction\r
259 cache line containing Address is invalidated. If Address + Length is not\r
260 aligned on a cache line boundary, then the entire instruction cache line\r
261 containing Address + Length -1 is invalidated. This function may choose to\r
262 invalidate the entire instruction cache if that is more efficient than\r
263 invalidating the specified range. If Length is 0, the no instruction cache\r
264 lines are invalidated. Address is returned.\r
265\r
266 If Length is greater than (EFI_MAX_ADDRESS - Address + 1), then ASSERT().\r
267\r
268Arguments:\r
269\r
270 Address - The base address of the instruction cache lines to\r
271 invalidate. If the CPU is in a physical addressing mode, then\r
272 Address is a physical address. If the CPU is in a virtual\r
273 addressing mode, then Address is a virtual address.\r
274\r
275 Length - The number of bytes to invalidate from the instruction cache.\r
276\r
277 Returns:\r
278 Address\r
279\r
280**/\r
281{\r
282 PEI_ASSERT(GetPeiServicesTablePointer() , (Length <= EFI_MAX_ADDRESS - (UINTN)Address + 1));\r
283 return Address;\r
284}\r
285\r
286\r
287EFI_STATUS\r
288EFIAPI\r
289PeiLibFfsFindNextVolume (\r
290 IN UINTN Instance,\r
291 IN OUT EFI_PEI_FV_HANDLE *VolumeHandle\r
292 )\r
293/*++\r
294\r
295Routine Description:\r
296\r
297 The wrapper of Pei Core Service function FfsFindNextVolume.\r
298\r
299Arguments:\r
300\r
301 Instance - The Fv Volume Instance.\r
302 VolumeHandle - Pointer to the current Fv Volume to search.\r
303\r
304Returns:\r
305 EFI_STATUS\r
306 \r
307--*/\r
308 \r
309{\r
310 EFI_PEI_SERVICES **PeiServices;\r
311 \r
312 PeiServices = GetPeiServicesTablePointer();\r
313 return (*PeiServices)->FfsFindNextVolume (PeiServices, Instance, VolumeHandle);\r
314}\r
315\r
316EFI_STATUS\r
317EFIAPI\r
318PeiLibFfsFindNextFile (\r
319 IN EFI_FV_FILETYPE SearchType,\r
320 IN EFI_PEI_FV_HANDLE FwVolHeader,\r
321 IN OUT EFI_PEI_FILE_HANDLE *FileHeader\r
322 )\r
323/*++\r
324\r
325Routine Description:\r
326\r
327 The wrapper of Pei Core Service function FfsFindNextFile.\r
328\r
329Arguments:\r
330\r
331 SearchType - Filter to find only file of this type.\r
332 FwVolHeader - Pointer to the current FV to search.\r
333 FileHandle - Pointer to the file matching SearchType in FwVolHeader.\r
334 - NULL if file not found\r
335\r
336Returns:\r
337 EFI_STATUS\r
338 \r
339--*/ \r
340{\r
341 EFI_PEI_SERVICES **PeiServices;\r
342 \r
343 PeiServices = GetPeiServicesTablePointer();\r
344 return (*PeiServices)->FfsFindNextFile (PeiServices, SearchType, &FwVolHeader, &FileHeader);\r
345}\r
346\r
347\r
348EFI_STATUS\r
349EFIAPI\r
350PeiLibFfsFindFileByName (\r
351 IN EFI_GUID *FileName,\r
352 IN EFI_PEI_FV_HANDLE VolumeHandle,\r
353 OUT EFI_PEI_FILE_HANDLE *FileHandle\r
354 )\r
355/*++\r
356\r
357Routine Description:\r
358\r
359 The wrapper of Pei Core Service function FfsFindFileByName.\r
360\r
361Arguments:\r
362\r
363 FileName - File name to search.\r
364 VolumeHandle - The current FV to search.\r
365 FileHandle - Pointer to the file matching name in VolumeHandle.\r
366 - NULL if file not found\r
367\r
368Returns:\r
369 EFI_STATUS\r
370 \r
371--*/ \r
372{\r
373 EFI_PEI_SERVICES **PeiServices;\r
374 \r
375 PeiServices = GetPeiServicesTablePointer();\r
376 return (*PeiServices)->FfsFindFileByName (FileName, VolumeHandle, FileHandle);\r
377}\r
378\r
379\r
380\r
381EFI_STATUS\r
382EFIAPI\r
383PeiLibFfsFindSectionData (\r
384 IN EFI_SECTION_TYPE SectionType,\r
385 IN EFI_FFS_FILE_HEADER *FfsFileHeader,\r
386 IN OUT VOID **SectionData\r
387 )\r
388/*++\r
389\r
390Routine Description:\r
391\r
392 The wrapper of Pei Core Service function FfsFindSectionData.\r
393\r
394Arguments:\r
395\r
396 SearchType - Filter to find only sections of this type.\r
397 FileHandle - Pointer to the current file to search.\r
398 SectionData - Pointer to the Section matching SectionType in FfsFileHeader.\r
399 - NULL if section not found\r
400\r
401Returns:\r
402 EFI_STATUS\r
403--*/\r
404{\r
405 EFI_PEI_SERVICES **PeiServices;\r
406 \r
407 PeiServices = GetPeiServicesTablePointer();\r
408 return (*PeiServices)->FfsFindSectionData (PeiServices, SectionType, &FfsFileHeader, SectionData);\r
409}\r
410\r
411EFI_STATUS\r
412EFIAPI\r
413PeiLibFfsGetVolumeInfo (\r
414 IN EFI_PEI_FV_HANDLE *VolumeHandle,\r
415 OUT EFI_FV_INFO *VolumeInfo\r
416 )\r
417/*++\r
418\r
419Routine Description:\r
420\r
421 The wrapper of Pei Core Service function FfsGetVolumeInfo.\r
422\r
423Arguments:\r
424\r
425 VolumeHandle - The handle to Fv Volume.\r
426 VolumeInfo - The pointer to volume information.\r
427 \r
428Returns:\r
429 EFI_STATUS\r
430--*/ \r
431{\r
432 EFI_PEI_SERVICES **PeiServices;\r
433 \r
434 PeiServices = GetPeiServicesTablePointer();\r
435 return (*PeiServices)->FfsGetVolumeInfo (VolumeHandle, VolumeInfo);\r
436}\r
437\r
438\r
439\r
440VOID\r
441EFIAPI\r
442BuildFvHob (\r
443 IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
444 IN UINT64 Length\r
445 )\r
446/*++\r
447\r
448Routine Description:\r
449\r
450 Build FvHob.\r
451\r
452Arguments:\r
453\r
454 BaseAddress - Fv base address.\r
455 Length - Fv Length.\r
456\r
457Returns:\r
458 NONE.\r
459--*/ \r
460{\r
461\r
462 EFI_STATUS Status; \r
463 EFI_HOB_FIRMWARE_VOLUME *Hob;\r
464 EFI_PEI_SERVICES **PeiServices;\r
465\r
466 PeiServices = GetPeiServicesTablePointer();\r
467\r
468 //\r
469 // Check FV Signature\r
470 //\r
471 PEI_ASSERT (PeiServices, ((EFI_FIRMWARE_VOLUME_HEADER*)((UINTN)BaseAddress))->Signature == EFI_FVH_SIGNATURE);\r
472\r
473\r
474 Status = (*PeiServices)->CreateHob (\r
475 PeiServices,\r
476 EFI_HOB_TYPE_FV,\r
477 sizeof (EFI_HOB_FIRMWARE_VOLUME),\r
478 &Hob\r
479 );\r
480 Hob->BaseAddress = BaseAddress;\r
481 Hob->Length = Length;\r
482}\r
483\r
484VOID\r
485EFIAPI\r
486BuildFvHob2 (\r
487 IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
488 IN UINT64 Length,\r
489 IN EFI_GUID *FvNameGuid,\r
490 IN EFI_GUID *FileNameGuid\r
491 )\r
492/*++\r
493\r
494Routine Description:\r
495\r
496 Build FvHob2.\r
497\r
498Arguments:\r
499\r
500 BaseAddress - Fv base address.\r
501 Length - Fv length.\r
502 FvNameGuid - Fv name.\r
503 FileNameGuid - File name which contians encapsulated Fv.\r
504\r
505Returns:\r
506 NONE.\r
507--*/ \r
508{\r
509\r
510 EFI_STATUS Status; \r
511 EFI_HOB_FIRMWARE_VOLUME2 *Hob;\r
512 EFI_PEI_SERVICES **PeiServices;\r
513\r
514 PeiServices = GetPeiServicesTablePointer();\r
515\r
516 //\r
517 // Check FV Signature\r
518 //\r
519 PEI_ASSERT (PeiServices, ((EFI_FIRMWARE_VOLUME_HEADER*)((UINTN)BaseAddress))->Signature == EFI_FVH_SIGNATURE);\r
520\r
521 Status = (*PeiServices)->CreateHob (\r
522 PeiServices,\r
523 EFI_HOB_TYPE_FV2,\r
524 sizeof (EFI_HOB_FIRMWARE_VOLUME2),\r
525 &Hob\r
526 );\r
527 Hob->BaseAddress = BaseAddress;\r
528 Hob->Length = Length;\r
529 CopyMem ((VOID*)&Hob->FvName, FvNameGuid, sizeof(EFI_GUID));\r
530 CopyMem ((VOID*)&Hob->FileName, FileNameGuid, sizeof(EFI_GUID));\r
531}\r
532\r
533EFI_STATUS\r
534EFIAPI\r
535PeiServicesLocatePpi (\r
536 IN EFI_GUID *Guid,\r
537 IN UINTN Instance,\r
538 IN OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor,\r
539 IN OUT VOID **Ppi\r
540 )\r
541/*++\r
542\r
543Routine Description:\r
544\r
545 The wrapper of Pei Core Service function LocatePpi.\r
546\r
547Arguments:\r
548\r
549 Guid - Pointer to GUID of the PPI.\r
550 Instance - Instance Number to discover.\r
551 PpiDescriptor - Pointer to reference the found descriptor. If not NULL,\r
552 returns a pointer to the descriptor (includes flags, etc)\r
553 Ppi - Pointer to reference the found PPI\r
554\r
555Returns:\r
556\r
557 Status - EFI_SUCCESS if the PPI is in the database \r
558 EFI_NOT_FOUND if the PPI is not in the database\r
559--*/ \r
560{\r
561 EFI_PEI_SERVICES **PeiServices;\r
562 \r
563 PeiServices = GetPeiServicesTablePointer();\r
564 return (*PeiServices)->LocatePpi (PeiServices, Guid, Instance, PpiDescriptor, Ppi);\r
565}\r
566\r
567\r
568VOID \r
569EFIAPI\r
570BuildGuidDataHob (\r
571 IN EFI_GUID *Guid,\r
572 IN VOID *Data,\r
573 IN UINTN DataLength\r
574 )\r
575/*++\r
576\r
577Routine Description:\r
578\r
579 Build Guid data Hob.\r
580\r
581Arguments:\r
582\r
583 Guid - guid to build data hob.\r
584 Data - data to build data hob.\r
585 DataLength - the length of data.\r
586\r
587Returns:\r
588 NONE\r
589--*/ \r
590{\r
591 VOID *HobData;\r
592 EFI_HOB_GUID_TYPE *Hob;\r
593 EFI_PEI_SERVICES **PeiServices;\r
594\r
595 PeiServices = GetPeiServicesTablePointer();\r
596 (*PeiServices)->CreateHob (\r
597 PeiServices,\r
598 EFI_HOB_TYPE_GUID_EXTENSION,\r
599 (UINT16) (sizeof (EFI_HOB_GUID_TYPE) + DataLength),\r
600 &Hob\r
601 );\r
602 CopyMem ((VOID*)&Hob->Name, (VOID*)Guid, sizeof(EFI_GUID));\r
603\r
604 HobData = Hob + 1;\r
605\r
606 CopyMem (HobData, Data, DataLength);\r
607}\r
608\r
609\r
610VOID *\r
611EFIAPI\r
612AllocatePages (\r
613 IN UINTN Pages\r
614 )\r
615/*++\r
616\r
617Routine Description:\r
618\r
619 Allocate Memory.\r
620\r
621Arguments:\r
622\r
623 Pages - Pages to allocate.\r
624\r
625Returns:\r
626 = Address if successful to allocate memory. \r
627 = NULL if fail to allocate memory.\r
628\r
629--*/ \r
630{\r
631 EFI_STATUS Status;\r
632 EFI_PHYSICAL_ADDRESS Memory; \r
633 EFI_PEI_SERVICES **PeiServices;\r
634\r
635 if (Pages == 0) {\r
636 return NULL;\r
637 }\r
638\r
639 PeiServices = GetPeiServicesTablePointer();\r
640 Status = (*PeiServices)->AllocatePages (PeiServices, EfiBootServicesData, Pages, &Memory);\r
641 if (EFI_ERROR (Status)) {\r
642 Memory = 0;\r
643 }\r
644 return (VOID *) (UINTN) Memory;\r
645\r
646}\r
647\r
648#endif\r