]> git.proxmox.com Git - mirror_edk2.git/blame - EdkModulePkg/Universal/PCD/Pei/Service.c
1) Fix bug reported on the PcdSetEx* Macro.
[mirror_edk2.git] / EdkModulePkg / Universal / PCD / Pei / Service.c
CommitLineData
878ddf1f 1/** @file\r
2Private functions used by PCD PEIM.\r
3\r
4Copyright (c) 2006, 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
14Module Name: Service.c\r
15\r
16**/\r
17#include "../Common/PcdCommon.h"\r
18#include "Service.h"\r
19\r
20\r
21\r
22\r
23/**\r
24 This function expand the StateByte\r
25\r
26 @param[out] StateByte The output StateByte information.\r
27 @param[in] Byte The StateByte.\r
28\r
29 @retval VOID\r
30--*/\r
31VOID\r
32PcdImageExpandStateByte (\r
33 OUT PCD_STATEBYTE *StateByte,\r
34 IN UINT8 Byte\r
35)\r
36{\r
37 switch (Byte & PCD_STATEBYTE_DATUMTYPE) {\r
38 case PCD_BYTE8:\r
39 StateByte->DataType = PcdByte8;\r
40 break;\r
41 case PCD_BYTE16:\r
42 StateByte->DataType = PcdByte16;\r
43 break;\r
44 case PCD_BYTE32:\r
45 StateByte->DataType = PcdByte32;\r
46 break;\r
47 case PCD_BYTE64:\r
48 StateByte->DataType = PcdByte64;\r
49 break;\r
50 case PCD_POINTER:\r
51 StateByte->DataType = PcdPointer;\r
52 break;\r
53 case PCD_BOOLEAN:\r
54 StateByte->DataType = PcdBoolean;\r
55 break;\r
56 default:\r
57 ASSERT (FALSE);\r
58 }\r
59\r
60 StateByte->ExtendedGuidPresent = (BOOLEAN) ((Byte & PCD_STATEBYTE_EXTENDEDGUIDPRESENT) != 0);\r
61 StateByte->HiiEnable = (BOOLEAN) ((Byte & PCD_STATEBYTE_HIIENABLE) != 0);\r
62 StateByte->SkuDataArrayEnable = (BOOLEAN) ((Byte & PCD_STATEBYTE_SKUDATAARRAYENABLE) != 0);\r
63 StateByte->SkuEnable = (BOOLEAN) ((Byte & PCD_STATEBYTE_SKUENABLE) != 0);\r
64 StateByte->VpdEnable = (BOOLEAN) ((Byte & PCD_STATEBYTE_VPDENABLE) != 0);\r
65\r
66}\r
67\r
68\r
69\r
70/**\r
71 This function locates the <PCD_IMAGE> on the flash and \r
72 return a pointer to the Section Data on flash.\r
73\r
74 @param[in] VOID\r
75\r
76 @retval VOID\r
77--*/\r
78UINT8 *\r
79LocatePcdImage (\r
80 VOID\r
81)\r
82{\r
83 EFI_STATUS Status;\r
84 EFI_FIRMWARE_VOLUME_HEADER *FvHdr;\r
85 EFI_FFS_FILE_HEADER *FfsHdr;\r
86 VOID *SectionData;\r
87\r
88 Status = PeiCoreFfsFindNextVolume (0, &FvHdr);\r
89 ASSERT_EFI_ERROR (Status);\r
90\r
91 do {\r
92 FfsHdr = NULL;\r
93 Status = PeiCoreFfsFindNextFile (EFI_FV_FILETYPE_FREEFORM, FvHdr, &FfsHdr);\r
94 if (Status == EFI_SUCCESS) {\r
95 if (CompareGuid (&gPcdImageFileGuid, &FfsHdr->Name)) {\r
96\r
97 Status = PeiCoreFfsFindSectionData (EFI_SECTION_RAW, FfsHdr, &SectionData);\r
98 ASSERT_EFI_ERROR (Status);\r
99\r
100 return (UINT8 *)SectionData;\r
101 }\r
102 }\r
103 } while (Status == EFI_SUCCESS);\r
104\r
105 ASSERT (FALSE);\r
106\r
107 return NULL;\r
108}\r
109\r
110/**\r
111 The function retrieves the PCD data value according to\r
112 TokenNumber and Guid space given.\r
113\r
114 @param[in] TokenNumber The token number.\r
115 @param[in] Guid The Guid space.\r
116 @param[in] Type The storage type.\r
117 @param[out] Data The output data.\r
118\r
119\r
120 @retval EFI_SUCESS If data value is found according to SKU_ID.\r
121 @retval EFI_NOT_FOUND If not such a value is found.\r
122\r
123--*/\r
124VOID\r
125PeiGetPcdEntryWorker (\r
126 IN UINTN TokenNumber,\r
127 IN CONST EFI_GUID *Guid, OPTIONAL\r
128 IN PCD_DATA_TYPE Type,\r
129 OUT VOID *Data\r
130 )\r
131{\r
132 PCD_DATABASE *Database;\r
133 EFI_HOB_GUID_TYPE *GuidHob;\r
134\r
135 ASSERT (Data != NULL);\r
136\r
137 GuidHob = GetFirstGuidHob (&gPcdDataBaseHobGuid);\r
138 ASSERT (GuidHob != NULL);\r
139\r
140 Database = GET_GUID_HOB_DATA (GuidHob);\r
141\r
142 GetPcdEntryWorker ( &Database->Info,\r
143 TokenNumber,\r
144 Guid,\r
145 Type,\r
146 Data\r
147 );\r
148\r
149\r
150 return;\r
151}\r
152\r
153\r
154/**\r
155 The function set the PCD data value according to\r
156 TokenNumber and Guid space given.\r
157\r
158 @param[in] Database The PCD Database Instance.\r
159 @param[in] TokenNumber The token number.\r
160 @param[in] Guid The Guid space.\r
161 @param[in] Type The storage type.\r
162 @param[in] Data The output data.\r
163\r
164\r
165 @retval EFI_SUCESS If data value is found according to SKU_ID.\r
166 @retval EFI_NOT_FOUND If not such a value is found.\r
167\r
168--*/\r
169EFI_STATUS\r
170SetPcdEntryWorker (\r
171 IN CONST PCD_DATABASE *Database,\r
172 IN UINTN TokenNumber,\r
173 IN CONST EFI_GUID *Guid, OPTIONAL\r
174 IN PCD_DATA_TYPE Type,\r
175 IN VOID *Data\r
176 )\r
177{\r
178 PCD_INDEX *PcdIndex;\r
179 EFI_STATUS Status;\r
180 PCD_PPI_CALLBACK *CallbackTable;\r
181 UINTN Idx;\r
182\r
183 ASSERT (Data != NULL);\r
184\r
185 //\r
186 // Find the PCD entry in list in memory first\r
187 //\r
188 PcdIndex = FindPcdIndex (TokenNumber, Guid, &Database->Info, &Idx);\r
189\r
190 ASSERT (PcdIndex != NULL);\r
191\r
192 ASSERT (PcdIndex->StateByte.DataType == Type);\r
193\r
194 //\r
195 // Invoke the callback function.\r
196 //\r
197 CallbackTable = (PCD_PPI_CALLBACK *)\r
198 GetAbsoluteAddress (Idx * Database->Info.MaxCallbackNum * sizeof(PCD_PPI_CALLBACK),\r
199 Database->Info.CallbackTableOffset,\r
200 &Database->Info\r
201 );\r
202 \r
203 for (Idx = 0; Idx < Database->Info.MaxCallbackNum; Idx++) {\r
204 if (CallbackTable[Idx] != NULL) {\r
205 CallbackTable[Idx] (Guid,\r
206 PcdIndex->TokenNumber,\r
207 Data,\r
208 PcdIndex->DatumSize\r
209 );\r
210 }\r
211 }\r
212\r
213 Status = SetPcdData (PcdIndex, &Database->Info, Data);\r
214\r
215 return Status;\r
216}\r
217\r
218\r
219\r
220/**\r
221 (reviewed) The function set the PCD data value according to\r
222 TokenNumber and Guid space given.\r
223\r
224 @param[in] TokenNumber The token number.\r
225 @param[in] Guid The Guid space.\r
226 @param[in] Type The storage type.\r
227 @param[in] Data The output data.\r
228\r
229\r
230 @retval EFI_SUCESS If data value is found according to SKU_ID.\r
231 @retval EFI_NOT_FOUND If not such a value is found.\r
232\r
233--*/\r
234EFI_STATUS\r
235PeiSetPcdEntryWorker (\r
236 IN UINTN TokenNumber,\r
237 IN CONST EFI_GUID *Guid, OPTIONAL\r
238 IN PCD_DATA_TYPE Type,\r
239 IN VOID *Data\r
240 )\r
241{\r
242 PCD_DATABASE *Database;\r
243 EFI_HOB_GUID_TYPE *GuidHob;\r
244\r
245 ASSERT (Data != NULL);\r
246\r
247 GuidHob = GetFirstGuidHob (&gPcdDataBaseHobGuid);\r
248 ASSERT (GuidHob != NULL);\r
249 \r
250 Database = GET_GUID_HOB_DATA (GuidHob);\r
251\r
252 SetPcdEntryWorker (Database,\r
253 TokenNumber,\r
254 Guid,\r
255 Type,\r
256 Data\r
257 );\r
258\r
259 return EFI_SUCCESS;\r
260}\r
261\r
262\r
263\r
264UINTN\r
265PeiGetPcdEntrySizeWorker (\r
266 IN UINTN TokenNumber,\r
267 IN CONST EFI_GUID *Guid OPTIONAL\r
268 )\r
269{\r
270 PCD_DATABASE *Database;\r
271 EFI_HOB_GUID_TYPE *GuidHob;\r
272\r
273 GuidHob = GetFirstGuidHob (&gPcdDataBaseHobGuid);\r
274 ASSERT (GuidHob != NULL);\r
275\r
276 Database = GET_GUID_HOB_DATA (GuidHob);\r
277\r
278 return GetPcdEntrySizeWorker (&Database->Info,\r
279 TokenNumber,\r
280 Guid\r
281 );\r
282\r
283}\r
284\r
285\r
286\r
287/**\r
288 The function registers the CallBackOnSet fucntion\r
289 according to TokenNumber and EFI_GUID space.\r
290\r
291 @param[in] TokenNumber The token number.\r
292 @param[in] Guid The GUID space.\r
293 @param[in] CallBackFunction The Callback function to be registered.\r
294\r
295 @retval EFI_SUCCESS If the Callback function is registered.\r
296 @retval EFI_NOT_FOUND If the PCD Entry is not found according to Token Number and GUID space.\r
297--*/\r
298EFI_STATUS\r
299PeiRegisterCallBackWorker (\r
300 IN UINTN TokenNumber,\r
301 IN CONST EFI_GUID *Guid, OPTIONAL\r
302 IN PCD_PPI_CALLBACK CallBackFunction,\r
303 IN BOOLEAN Register\r
304)\r
305{\r
306 PCD_DATABASE *Database;\r
307 EFI_HOB_GUID_TYPE *GuidHob;\r
308 PCD_INDEX *PcdIndex;\r
309 UINTN Idx;\r
310 PCD_PPI_CALLBACK *CallbackTable;\r
311 PCD_PPI_CALLBACK Compare;\r
312 PCD_PPI_CALLBACK Assign;\r
313\r
314 GuidHob = GetFirstGuidHob (&gPcdDataBaseHobGuid);\r
315 ASSERT (GuidHob != NULL);\r
316 \r
317 Database = GET_GUID_HOB_DATA (GuidHob);\r
318\r
319 PcdIndex = FindPcdIndex (TokenNumber, Guid, &Database->Info, NULL);\r
320\r
321 ASSERT (PcdIndex != NULL);\r
322\r
323 if (PcdIndex->StateByte.VpdEnable) {\r
324 return EFI_INVALID_PARAMETER;\r
325 }\r
326\r
327 Idx = ((UINTN) PcdIndex - Database->Info.CallbackTableOffset) / sizeof(PCD_INDEX);\r
328\r
329 CallbackTable = (PCD_PPI_CALLBACK *) GetAbsoluteAddress (\r
330 sizeof (PCD_PPI_CALLBACK) * Idx * Database->Info.MaxCallbackNum,\r
331 Database->Info.CallbackTableOffset,\r
332 &Database->Info\r
333 );\r
334\r
335 Compare = Register? NULL: CallBackFunction;\r
336 Assign = Register? CallBackFunction: NULL;\r
337\r
338 for (Idx = 0; Idx < Database->Info.MaxCallbackNum; Idx++) {\r
339 if (CallbackTable[Idx] == Compare) {\r
340 CallbackTable[Idx] = Assign;\r
341 return EFI_SUCCESS;\r
342 }\r
343 }\r
344\r
345 return Register? EFI_OUT_OF_RESOURCES : EFI_NOT_FOUND;\r
346\r
347}\r
348\r
349\r
350\r
351EFI_STATUS\r
352PeiGetNextTokenWorker (\r
353 IN OUT UINTN *TokenNumber,\r
354 IN CONST EFI_GUID *Guid OPTIONAL\r
355 )\r
356{\r
357 PCD_DATABASE *Database;\r
358 EFI_HOB_GUID_TYPE *GuidHob;\r
359\r
360 GuidHob = GetFirstGuidHob (&gPcdDataBaseHobGuid);\r
361 ASSERT (GuidHob != NULL);\r
362 \r
363 Database = GET_GUID_HOB_DATA (GuidHob);\r
364\r
365 return GetNextTokenWorker (&Database->Info,\r
366 TokenNumber,\r
367 Guid\r
368 );\r
369\r
370}\r
371\r
372\r
373\r
374VOID\r
375GetPcdImageInfo (\r
376 IN CONST UINT8 *PcdImageOnFlash,\r
377 OUT PCD_IMAGE_RECORD *ImageInfo\r
378)\r
379{\r
380 PCD_FFS_ENCODING *PcdFfsHdr;\r
381\r
382 PcdFfsHdr = (PCD_FFS_ENCODING *) PcdImageOnFlash;\r
383\r
384 ZeroMem (ImageInfo, sizeof (*ImageInfo));\r
385\r
386 ImageInfo->ImageStart = PcdImageOnFlash;\r
387\r
388 CopyMem (&ImageInfo->EntryCount, PcdFfsHdr->EntryCount, 3);\r
389 \r
390 CopyMem (&ImageInfo->GlobalDatumLength, PcdFfsHdr->GlobalDatumLength, 1);\r
391 ASSERT (ImageInfo->GlobalDatumLength <= 3);\r
392 \r
393 CopyMem (&ImageInfo->GlobalOffsetLength, PcdFfsHdr->GlobalOffsetLength, 1);\r
394 ASSERT (ImageInfo->GlobalOffsetLength <= 3);\r
395 \r
396 CopyMem (&ImageInfo->GlobalTokenLength, PcdFfsHdr->GlobalTokenLength, 1);\r
397 ASSERT (ImageInfo->GlobalTokenLength <= 4);\r
398\r
399 CopyMem (&ImageInfo->GlobalGuidTabIdxLength, PcdFfsHdr->GuidLength, 1);\r
400 ASSERT (ImageInfo->GlobalGuidTabIdxLength <= 2);\r
401\r
402 CopyMem (&ImageInfo->GlobalStrTabIdxLength, PcdFfsHdr->GlobalStrTabIdxLength, 1);\r
403 ASSERT (ImageInfo->GlobalStrTabIdxLength <= 2);\r
404\r
405 CopyMem (&ImageInfo->ImageLength, PcdFfsHdr->ImageLength, 3);\r
406 CopyMem (&ImageInfo->IndexLength, PcdFfsHdr->PcdIndexLength, 3);\r
407 CopyMem (&ImageInfo->WholeDataDefaultLength, PcdFfsHdr->WholeDataBufferLength, 3);\r
408 CopyMem (&ImageInfo->DataDefaultLength, PcdFfsHdr->DataBufferLength, 3);\r
409 CopyMem (&ImageInfo->GuidTableLength, PcdFfsHdr->GuidTableLength, 3);\r
410\r
411 ImageInfo->StringTableLength = ImageInfo->ImageLength\r
412 - sizeof (PCD_FFS_ENCODING)\r
413 - ImageInfo->DataDefaultLength\r
414 - ImageInfo->IndexLength\r
415 - ImageInfo->GuidTableLength;\r
416\r
417 ImageInfo->DataDefaultStart = PcdImageOnFlash + sizeof (PCD_FFS_ENCODING);\r
418 ImageInfo->IndexStart = ImageInfo->DataDefaultStart + ImageInfo->DataDefaultLength;\r
419 ImageInfo->GuidTableStart = (CONST EFI_GUID *)(ImageInfo->IndexStart + ImageInfo->IndexLength);\r
420 ImageInfo->StringTableStart = (CONST UINT16 *) ((UINT8 *) ImageInfo->GuidTableStart + ImageInfo->GuidTableLength);\r
421 \r
422 return;\r
423}\r
424\r
425\r
426\r
427/**\r
428 The function builds the PCD database based on the\r
429 PCD_IMAGE on the flash.\r
430\r
431 The layout of the PCD_DATABASE is as follows:\r
432\r
433 ---------------------------\r
434 | PCD_DATABASE_HEADER |\r
435 ---------------------------\r
436 | GUID_TABLE | Aligned on GUID (128 bits)\r
437 ---------------------------\r
438 | PCD_CALL_BACK_TABLE | Aligned on Pointer (32 bits or 64 bits)\r
439 ---------------------------\r
440 | PCD_INDEX_TABLE | Aligned on PCD_INDEX (see PCD_INDEX's declaration)\r
441 ---------------------------\r
442 | IMAGE_STRING_TABLE | Aligned on 16 Bits\r
443 ---------------------------\r
444 | IMAGE_PCD_INDEX | Unaligned\r
445 ---------------------------\r
446 | Data Defaults | Unaligned\r
447 ---------------------------\r
448 | Data Buffer |\r
449 | for entries without |\r
450 | defaults |\r
451 ---------------------------\r
452\r
453 @param[in] PcdImageOnFlash The PCD image on flash.\r
454\r
455 @retval VOID\r
456--*/\r
457UINTN\r
458GetPcdDatabaseLen (\r
459 IN CONST UINT8 *PcdImageOnFlash,\r
460 OUT PCD_DATABASE_HEADER *Info,\r
461 OUT PCD_IMAGE_RECORD *ImageInfo\r
462 )\r
463{\r
464 UINTN DatabaseLen;\r
465 UINTN DatabaseHeaderLength;\r
466 UINTN PcdIndexLength;\r
467 UINTN CallbackBufferLength;\r
468\r
469\r
470 GetPcdImageInfo (PcdImageOnFlash, ImageInfo);\r
471\r
472 Info->MaxCallbackNum = FixedPcdGet32(PcdMaxPcdCallBackNumber) ;\r
473\r
474 DatabaseHeaderLength = sizeof (PCD_DATABASE) - sizeof(UINT8);\r
475\r
476 PcdIndexLength = sizeof (PCD_INDEX) * ImageInfo->EntryCount;\r
477 CallbackBufferLength = sizeof (PCD_PPI_CALLBACK) * Info->MaxCallbackNum * ImageInfo->EntryCount;\r
478\r
479 Info->EntryCount = ImageInfo->EntryCount;\r
480 Info->GuidTableOffset = DatabaseHeaderLength;\r
481 Info->CallbackTableOffset = Info->GuidTableOffset + ImageInfo->GuidTableLength;\r
482 Info->PcdIndexOffset = Info->PcdIndexOffset + PcdIndexLength;\r
483 Info->ImageIndexOffset = Info->CallbackTableOffset + CallbackBufferLength;\r
484 Info->DataBufferOffset = Info->ImageIndexOffset + ImageInfo->DataDefaultLength;\r
485\r
486 Info->HiiGuidOffsetLength = ImageInfo->GlobalGuidTabIdxLength;\r
487 Info->HiiVariableOffsetLength = ImageInfo->GlobalStrTabIdxLength;\r
488 Info->ExtendedOffsetLength = ImageInfo->GlobalOffsetLength;\r
489\r
490 Info->SkuId = 0;\r
491\r
492 DatabaseLen = DatabaseHeaderLength\r
493 + ImageInfo->GuidTableLength\r
494 + PcdIndexLength\r
495 + CallbackBufferLength\r
496 + ImageInfo->IndexLength\r
497 + ImageInfo->WholeDataDefaultLength;\r
498\r
499 Info->DatabaseLen = DatabaseLen;\r
500\r
501 return DatabaseLen;\r
502}\r
503\r
504\r
505/**\r
506 The function constructs a single PCD_INDEX according a index in\r
507 <PCD_IMAGE>.\r
508\r
509 @param[in] ImageIndex The starting address of a PCD index defined in PCD spec 0.51.\r
510 @param[in] Index The output PCD_INDEX. \r
511 @param[in] ImageInfo The attributes of the PCD_IMAGE as this binary stream is highly\r
512 optimized for size.\r
513\r
514 @retval UINTN The length of the current PCD index.\r
515**/\r
516UINTN\r
517BuildPcdIndex (\r
518 IN CONST UINT8 *ImageIndex,\r
519 OUT PCD_INDEX *Index,\r
520 IN CONST PCD_IMAGE_RECORD *ImageInfo\r
521)\r
522{\r
523 UINTN SkuCount;\r
524 CONST UINT8 *ImageIndexBackUp;\r
525\r
526 ImageIndexBackUp = ImageIndex;\r
527 \r
528 //\r
529 // Token Number\r
530 //\r
531 CopyMem (&Index->TokenNumber,\r
532 ImageIndex,\r
533 ImageInfo->GlobalTokenLength\r
534 );\r
535\r
536 ImageIndex += ImageInfo->GlobalTokenLength;\r
537 \r
538 //\r
539 // State Byte\r
540 //\r
541 PcdImageExpandStateByte (&Index->StateByte,\r
542 *ImageIndex\r
543 );\r
544\r
545 ImageIndex += 1;\r
546 \r
547 //\r
548 // Dataum Size\r
549 //\r
550 CopyMem (&Index->DatumSize,\r
551 ImageIndex,\r
552 ImageInfo->GlobalDatumLength\r
553 );\r
554\r
555 ImageIndex += ImageInfo->GlobalDatumLength;\r
556\r
557 //\r
558 // SKU_DATA\r
559 //\r
560 if (Index->StateByte.SkuEnable) {\r
561 Index->SkuCount = *ImageIndex;\r
562 SkuCount = *ImageIndex;\r
563 ImageIndex++;\r
564 Index->SkuIdArray = (UINT32) ImageIndex - (UINT32) ImageInfo->IndexStart;\r
565 ImageIndex += Index->SkuCount;\r
566 } else {\r
567 //\r
568 // There is always a default SKU_ID of zero even \r
569 // if SKU is not enabled for this PCD entry.\r
570 // \r
571 //\r
572 SkuCount = 1;\r
573 }\r
574\r
575 //\r
576 // Extended Offset\r
577 //\r
578 CopyMem (&Index->ExtendedDataOffset,\r
579 ImageIndex,\r
580 ImageInfo->GlobalOffsetLength\r
581 );\r
582\r
583 ImageIndex += ImageInfo->GlobalOffsetLength * SkuCount;\r
584\r
585 //\r
586 // DynamicEX Guid Offset\r
587 //\r
588 if (Index->StateByte.ExtendedGuidPresent) {\r
589 CopyMem (&Index->DynamicExGuid,\r
590 ImageIndex,\r
591 ImageInfo->GlobalGuidTabIdxLength\r
592 );\r
593\r
594 ImageIndex += ImageInfo->GlobalGuidTabIdxLength;\r
595 }\r
596\r
597 //\r
598 // HII_DATA\r
599 //\r
600 if (Index->StateByte.HiiEnable) {\r
601 Index->HiiData = (UINT32) ImageIndex - (UINT32) ImageInfo->IndexStart;\r
602 ImageIndex += ((ImageInfo->GlobalStrTabIdxLength + ImageInfo->GlobalGuidTabIdxLength) * SkuCount);\r
603 }\r
604\r
605 return (UINTN) (ImageIndex - ImageIndexBackUp);\r
606}\r
607\r
608\r
609\r
610\r
611/**\r
612 The function builds the PCD database based on the\r
613 PCD_IMAGE on the flash.\r
614\r
615 @param[in] Database The database instance.\r
616 @param[in] ImageIndex The starting address of a PCD index defined in PCD spec 0.51.\r
617 @param[in] ImageInfo The attributes of the PCD_IMAGE as this binary stream is highly\r
618 optimized for size.\r
619\r
620 @retval VOID\r
621**/\r
622VOID\r
623BuildPcdDatabaseIndex (\r
624 PCD_DATABASE *Database,\r
625 UINT8 *ImageIndex,\r
626 PCD_IMAGE_RECORD *ImageInfo\r
627 )\r
628{\r
629 UINTN Idx;\r
630 UINTN Len;\r
631 PCD_INDEX *IndexTable;\r
632\r
633 IndexTable = (PCD_INDEX *) GetAbsoluteAddress (0, Database->Info.PcdIndexOffset, Database);\r
634\r
635 for (Idx = 0; Idx < Database->Info.EntryCount; Idx++) {\r
636 Len = BuildPcdIndex (ImageIndex, &IndexTable[Idx], ImageInfo);\r
637 ImageIndex += Len;\r
638 }\r
639\r
640 return;\r
641}\r
642\r
643\r
644/**\r
645 The function builds the PCD database based on the\r
646 PCD_IMAGE on the flash.\r
647\r
648 @param[in] PcdImageOnFlash The PCD image on flash.\r
649\r
650 @retval VOID\r
651--*/\r
652VOID\r
653BuildPcdDatabase (\r
654 UINT8 *PcdImageOnFlash\r
655 )\r
656{\r
657 PCD_DATABASE *Database;\r
658 UINTN Len;\r
659 PCD_IMAGE_RECORD ImageInfo;\r
660 UINT8 *ImageIndex;\r
661 PCD_DATABASE_HEADER DatabaseHeader;\r
662\r
663 Len = GetPcdDatabaseLen(PcdImageOnFlash, &DatabaseHeader, &ImageInfo);\r
664\r
665 Database = BuildGuidHob (&gPcdDataBaseHobGuid, Len);\r
666 ASSERT (Database != NULL);\r
667\r
668 ZeroMem (Database, Len);\r
669\r
670 //\r
671 // Update Database header\r
672 //\r
673 CopyMem (&Database->Info, &DatabaseHeader, sizeof (DatabaseHeader));\r
674\r
675 //\r
676 // I need this to get the GuidTableOffset as we don't\r
677 // know if Database field of PCD_DATABASE starts from an aligned\r
678 // address. The compilor may add padding after PCD_DATABASE_HEADER field.\r
679 //\r
680 Database->Info.GuidTableOffset = ((UINTN) &Database->GuidTable) - (UINTN)Database;\r
681 \r
682 //\r
683 // Copy Guid Table from Flash\r
684 //\r
685 CopyMem ((UINT8 *) Database + Database->Info.GuidTableOffset,\r
686 ImageInfo.GuidTableStart,\r
687 ImageInfo.GuidTableLength\r
688 );\r
689\r
690 //\r
691 // Copy ImageIndex from Flash\r
692 //\r
693 CopyMem ((UINT8 *) Database + Database->Info.ImageIndexOffset,\r
694 ImageInfo.IndexStart,\r
695 ImageInfo.IndexLength\r
696 );\r
697\r
698 //\r
699 // Copy Default Value\r
700 //\r
701 CopyMem ((UINT8 *) Database + Database->Info.DataBufferOffset,\r
702 ImageInfo.DataDefaultStart,\r
703 ImageInfo.DataDefaultLength\r
704 );\r
705\r
706 //\r
707 // Copy String Table\r
708 //\r
709 CopyMem ((UINT8 *) Database + Database->Info.StringTableOffset,\r
710 ImageInfo.StringTableStart,\r
711 ImageInfo.StringTableLength\r
712 );\r
713\r
714 ImageIndex = GetAbsoluteAddress (0, Database->Info.ImageIndexOffset, Database);\r
715\r
716 BuildPcdDatabaseIndex (Database, ImageIndex, &ImageInfo);\r
717\r
718 return;\r
719}\r
720\r
721\r
722\r
723/**\r
724 The function is provided by PCD PEIM and PCD DXE driver to\r
725 do the work of reading a HII variable from variable service.\r
726\r
727 @param[in] VariableGuid The Variable GUID.\r
728 @param[in] VariableName The Variable Name.\r
729 @param[out] VariableData The output data.\r
730 @param[out] VariableSize The size of the variable.\r
731\r
732 @retval EFI_SUCCESS Operation successful.\r
733 @retval EFI_SUCCESS Variablel not found.\r
734--*/\r
735EFI_STATUS\r
736GetHiiVariable (\r
737 IN EFI_GUID *VariableGuid,\r
738 IN UINT16 *VariableName,\r
739 OUT VOID **VariableData,\r
740 OUT UINTN *VariableSize\r
741 )\r
742{\r
743 UINTN Size;\r
744 EFI_STATUS Status;\r
745 VOID *Buffer;\r
746 EFI_PEI_READ_ONLY_VARIABLE_PPI *VariablePpi;\r
747\r
748 Status = PeiCoreLocatePpi (&gEfiPeiReadOnlyVariablePpiGuid, 0, NULL, &VariablePpi);\r
749 ASSERT_EFI_ERROR (Status);\r
750\r
751 Size = 0;\r
752\r
753 Status = VariablePpi->PeiGetVariable (\r
754 GetPeiServicesTablePointer (),\r
755 VariableName,\r
756 VariableGuid,\r
757 NULL,\r
758 &Size,\r
759 NULL\r
760 );\r
761 ASSERT (Status == EFI_BUFFER_TOO_SMALL);\r
762\r
763 Status = PeiCoreAllocatePool (Size, &Buffer);\r
764 ASSERT_EFI_ERROR (Status);\r
765\r
766 // declare a local for STP.\r
767 //\r
768 Status = VariablePpi->PeiGetVariable (\r
769 GetPeiServicesTablePointer (),\r
770 (UINT16 *) VariableName,\r
771 VariableGuid,\r
772 NULL,\r
773 &Size,\r
774 Buffer\r
775 );\r
776 ASSERT_EFI_ERROR (Status);\r
777\r
778 *VariableSize = Size;\r
779 *VariableData = Buffer;\r
780\r
781 return EFI_SUCCESS;\r
782}\r
783\r
784\r
785\r
786/**\r
787 The function is provided by PCD PEIM and PCD DXE driver to\r
788 do the work of reading a HII variable from variable service.\r
789\r
790 @param[in] VariableGuid The Variable GUID.\r
791 @param[in] VariableName The Variable Name.\r
792 @param[in] Data The input data.\r
793 @param[out] VariableSize The size of the variable.\r
794 @param[in] Offset The offset of the variable data that a PCD entry will starts from.\r
795\r
796 @retval EFI_SUCCESS Operation successful.\r
797 @retval EFI_SUCCESS Variablel not found.\r
798--*/\r
799EFI_STATUS\r
800SetHiiVariable (\r
801 IN EFI_GUID *VariableGuid,\r
802 IN UINT16 *VariableName,\r
803 IN CONST VOID *Data,\r
804 IN UINTN VariableSize,\r
805 IN UINTN Offset\r
806 )\r
807{\r
808 ASSERT (FALSE);\r
809 return EFI_INVALID_PARAMETER;\r
810}\r
811\r
812\r