]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/PCD/Pei/Service.c
MdeModulePkg: Apply uncrustify changes
[mirror_edk2.git] / MdeModulePkg / Universal / PCD / Pei / Service.c
CommitLineData
80408db0 1/** @file\r
5944a83b
LG
2 The driver internal functions are implmented here.\r
3 They build Pei PCD database, and provide access service to PCD database.\r
80408db0 4\r
d1102dba 5Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
9d510e61 6SPDX-License-Identifier: BSD-2-Clause-Patent\r
80408db0 7\r
80408db0 8**/\r
80408db0 9\r
10#include "Service.h"\r
11\r
96d6d004
SZ
12/**\r
13 Get Local Token Number by Token Number.\r
14\r
15 @param[in] Database PCD database.\r
16 @param[in] TokenNumber The PCD token number.\r
17\r
18 @return Local Token Number.\r
19**/\r
20UINT32\r
21GetLocalTokenNumber (\r
1436aea4
MK
22 IN PEI_PCD_DATABASE *Database,\r
23 IN UINTN TokenNumber\r
96d6d004
SZ
24 )\r
25{\r
1436aea4 26 UINT32 LocalTokenNumber;\r
96d6d004
SZ
27\r
28 //\r
29 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
30 // We have to decrement TokenNumber by 1 to make it usable\r
31 // as the array index.\r
32 //\r
33 TokenNumber--;\r
34\r
35 LocalTokenNumber = *((UINT32 *)((UINT8 *)Database + Database->LocalTokenNumberTableOffset) + TokenNumber);\r
36\r
96d6d004
SZ
37 return LocalTokenNumber;\r
38}\r
39\r
40/**\r
41 Get PCD type by Local Token Number.\r
42\r
43 @param[in] LocalTokenNumber The PCD local token number.\r
44\r
45 @return PCD type.\r
46**/\r
47EFI_PCD_TYPE\r
48GetPcdType (\r
1436aea4 49 IN UINT32 LocalTokenNumber\r
96d6d004
SZ
50 )\r
51{\r
52 switch (LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) {\r
53 case PCD_DATUM_TYPE_POINTER:\r
54 return EFI_PCD_TYPE_PTR;\r
55 case PCD_DATUM_TYPE_UINT8:\r
b5bd21b0 56 if ((LocalTokenNumber & PCD_DATUM_TYPE_UINT8_BOOLEAN) == PCD_DATUM_TYPE_UINT8_BOOLEAN) {\r
96d6d004
SZ
57 return EFI_PCD_TYPE_BOOL;\r
58 } else {\r
59 return EFI_PCD_TYPE_8;\r
60 }\r
1436aea4 61\r
96d6d004
SZ
62 case PCD_DATUM_TYPE_UINT16:\r
63 return EFI_PCD_TYPE_16;\r
64 case PCD_DATUM_TYPE_UINT32:\r
65 return EFI_PCD_TYPE_32;\r
66 case PCD_DATUM_TYPE_UINT64:\r
67 return EFI_PCD_TYPE_64;\r
68 default:\r
69 ASSERT (FALSE);\r
70 return EFI_PCD_TYPE_8;\r
71 }\r
72}\r
73\r
74/**\r
75 Get PCD name.\r
76\r
77 @param[in] OnlyTokenSpaceName If TRUE, only need to get the TokenSpaceCName.\r
78 If FALSE, need to get the full PCD name.\r
79 @param[in] Database PCD database.\r
80 @param[in] TokenNumber The PCD token number.\r
81\r
82 @return The TokenSpaceCName or full PCD name.\r
83**/\r
84CHAR8 *\r
85GetPcdName (\r
1436aea4
MK
86 IN BOOLEAN OnlyTokenSpaceName,\r
87 IN PEI_PCD_DATABASE *Database,\r
88 IN UINTN TokenNumber\r
96d6d004
SZ
89 )\r
90{\r
1436aea4
MK
91 UINT8 *StringTable;\r
92 UINTN NameSize;\r
93 PCD_NAME_INDEX *PcdNameIndex;\r
94 CHAR8 *TokenSpaceName;\r
95 CHAR8 *PcdName;\r
96 CHAR8 *Name;\r
96d6d004 97\r
85d0b97d 98 //\r
d1102dba 99 // Return NULL when PCD name table is absent.\r
85d0b97d
SZ
100 //\r
101 if (Database->PcdNameTableOffset == 0) {\r
102 return NULL;\r
103 }\r
104\r
96d6d004
SZ
105 //\r
106 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
107 // We have to decrement TokenNumber by 1 to make it usable\r
108 // as the array index.\r
109 //\r
110 TokenNumber--;\r
111\r
1436aea4 112 StringTable = (UINT8 *)Database + Database->StringTableOffset;\r
96d6d004
SZ
113\r
114 //\r
115 // Get the PCD name index.\r
116 //\r
1436aea4 117 PcdNameIndex = (PCD_NAME_INDEX *)((UINT8 *)Database + Database->PcdNameTableOffset) + TokenNumber;\r
96d6d004 118 TokenSpaceName = (CHAR8 *)&StringTable[PcdNameIndex->TokenSpaceCNameIndex];\r
1436aea4 119 PcdName = (CHAR8 *)&StringTable[PcdNameIndex->PcdCNameIndex];\r
96d6d004
SZ
120\r
121 if (OnlyTokenSpaceName) {\r
122 //\r
123 // Only need to get the TokenSpaceCName.\r
124 //\r
125 Name = AllocateCopyPool (AsciiStrSize (TokenSpaceName), TokenSpaceName);\r
126 } else {\r
127 //\r
128 // Need to get the full PCD name.\r
129 //\r
e85e284e 130 NameSize = AsciiStrSize (TokenSpaceName) + AsciiStrSize (PcdName);\r
1436aea4 131 Name = AllocateZeroPool (NameSize);\r
f47fc1cb 132 ASSERT (Name != NULL);\r
96d6d004
SZ
133 //\r
134 // Catenate TokenSpaceCName and PcdCName with a '.' to form the full PCD name.\r
135 //\r
e85e284e 136 AsciiStrCatS (Name, NameSize, TokenSpaceName);\r
96d6d004 137 Name[AsciiStrSize (TokenSpaceName) - sizeof (CHAR8)] = '.';\r
d1102dba 138 AsciiStrCatS (Name, NameSize, PcdName);\r
96d6d004
SZ
139 }\r
140\r
141 return Name;\r
142}\r
143\r
144/**\r
145 Retrieve additional information associated with a PCD token.\r
146\r
147 This includes information such as the type of value the TokenNumber is associated with as well as possible\r
148 human readable name that is associated with the token.\r
149\r
150 @param[in] Database PCD database.\r
151 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.\r
152 @param[in] TokenNumber The PCD token number.\r
153 @param[out] PcdInfo The returned information associated with the requested TokenNumber.\r
d1102dba 154 The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.\r
96d6d004
SZ
155\r
156 @retval EFI_SUCCESS The PCD information was returned successfully\r
157 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.\r
158**/\r
159EFI_STATUS\r
160ExGetPcdInfo (\r
1436aea4
MK
161 IN PEI_PCD_DATABASE *Database,\r
162 IN CONST EFI_GUID *Guid,\r
163 IN UINTN TokenNumber,\r
164 OUT EFI_PCD_INFO *PcdInfo\r
96d6d004
SZ
165 )\r
166{\r
1436aea4
MK
167 UINTN GuidTableIdx;\r
168 EFI_GUID *MatchGuid;\r
169 EFI_GUID *GuidTable;\r
170 DYNAMICEX_MAPPING *ExMapTable;\r
171 UINTN Index;\r
172 UINT32 LocalTokenNumber;\r
96d6d004
SZ
173\r
174 GuidTable = (EFI_GUID *)((UINT8 *)Database + Database->GuidTableOffset);\r
1436aea4 175 MatchGuid = ScanGuid (GuidTable, Database->GuidTableCount * sizeof (EFI_GUID), Guid);\r
96d6d004
SZ
176\r
177 if (MatchGuid == NULL) {\r
178 return EFI_NOT_FOUND;\r
179 }\r
180\r
181 GuidTableIdx = MatchGuid - GuidTable;\r
182\r
183 ExMapTable = (DYNAMICEX_MAPPING *)((UINT8 *)Database + Database->ExMapTableOffset);\r
184\r
185 //\r
186 // Find the PCD by GuidTableIdx and ExTokenNumber in ExMapTable.\r
187 //\r
188 for (Index = 0; Index < Database->ExTokenCount; Index++) {\r
189 if (ExMapTable[Index].ExGuidIndex == GuidTableIdx) {\r
190 if (TokenNumber == PCD_INVALID_TOKEN_NUMBER) {\r
191 //\r
192 // TokenNumber is 0, follow spec to set PcdType to EFI_PCD_TYPE_8,\r
193 // PcdSize to 0 and PcdName to the null-terminated ASCII string\r
194 // associated with the token's namespace Guid.\r
195 //\r
196 PcdInfo->PcdType = EFI_PCD_TYPE_8;\r
197 PcdInfo->PcdSize = 0;\r
198 //\r
199 // Here use one representative in the token space to get the TokenSpaceCName.\r
d1102dba 200 //\r
96d6d004
SZ
201 PcdInfo->PcdName = GetPcdName (TRUE, Database, ExMapTable[Index].TokenNumber);\r
202 return EFI_SUCCESS;\r
203 } else if (ExMapTable[Index].ExTokenNumber == TokenNumber) {\r
204 PcdInfo->PcdSize = PeiPcdGetSize (ExMapTable[Index].TokenNumber);\r
205 LocalTokenNumber = GetLocalTokenNumber (Database, ExMapTable[Index].TokenNumber);\r
206 PcdInfo->PcdType = GetPcdType (LocalTokenNumber);\r
207 PcdInfo->PcdName = GetPcdName (FALSE, Database, ExMapTable[Index].TokenNumber);\r
208 return EFI_SUCCESS;\r
209 }\r
210 }\r
211 }\r
212\r
213 return EFI_NOT_FOUND;\r
214}\r
215\r
216/**\r
217 Retrieve additional information associated with a PCD token.\r
218\r
219 This includes information such as the type of value the TokenNumber is associated with as well as possible\r
220 human readable name that is associated with the token.\r
221\r
222 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.\r
223 @param[in] TokenNumber The PCD token number.\r
224 @param[out] PcdInfo The returned information associated with the requested TokenNumber.\r
225 The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.\r
226\r
227 @retval EFI_SUCCESS The PCD information was returned successfully.\r
228 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.\r
229**/\r
230EFI_STATUS\r
231PeiGetPcdInfo (\r
1436aea4
MK
232 IN CONST EFI_GUID *Guid,\r
233 IN UINTN TokenNumber,\r
234 OUT EFI_PCD_INFO *PcdInfo\r
96d6d004
SZ
235 )\r
236{\r
1436aea4
MK
237 PEI_PCD_DATABASE *PeiPcdDb;\r
238 BOOLEAN PeiExMapTableEmpty;\r
239 UINTN PeiNexTokenNumber;\r
240 UINT32 LocalTokenNumber;\r
96d6d004 241\r
96d6d004
SZ
242 ASSERT (PcdInfo != NULL);\r
243\r
244 PeiPcdDb = GetPcdDatabase ();\r
245 PeiNexTokenNumber = PeiPcdDb->LocalTokenCount - PeiPcdDb->ExTokenCount;\r
246\r
247 if (PeiPcdDb->ExTokenCount == 0) {\r
248 PeiExMapTableEmpty = TRUE;\r
249 } else {\r
250 PeiExMapTableEmpty = FALSE;\r
251 }\r
252\r
253 if (Guid == NULL) {\r
254 if (TokenNumber > PeiNexTokenNumber) {\r
255 return EFI_NOT_FOUND;\r
256 } else if (TokenNumber == PCD_INVALID_TOKEN_NUMBER) {\r
257 //\r
258 // TokenNumber is 0, follow spec to set PcdType to EFI_PCD_TYPE_8,\r
259 // PcdSize to 0 and PcdName to NULL for default Token Space.\r
260 //\r
261 PcdInfo->PcdType = EFI_PCD_TYPE_8;\r
262 PcdInfo->PcdSize = 0;\r
263 PcdInfo->PcdName = NULL;\r
264 } else {\r
265 PcdInfo->PcdSize = PeiPcdGetSize (TokenNumber);\r
266 LocalTokenNumber = GetLocalTokenNumber (PeiPcdDb, TokenNumber);\r
267 PcdInfo->PcdType = GetPcdType (LocalTokenNumber);\r
268 PcdInfo->PcdName = GetPcdName (FALSE, PeiPcdDb, TokenNumber);\r
269 }\r
1436aea4 270\r
96d6d004
SZ
271 return EFI_SUCCESS;\r
272 } else {\r
273 if (PeiExMapTableEmpty) {\r
274 return EFI_NOT_FOUND;\r
275 }\r
1436aea4 276\r
96d6d004
SZ
277 return ExGetPcdInfo (\r
278 PeiPcdDb,\r
279 Guid,\r
280 TokenNumber,\r
281 PcdInfo\r
282 );\r
283 }\r
284}\r
285\r
80408db0 286/**\r
287 The function registers the CallBackOnSet fucntion\r
288 according to TokenNumber and EFI_GUID space.\r
289\r
fc547e08 290 @param ExTokenNumber The token number.\r
80408db0 291 @param Guid The GUID space.\r
292 @param CallBackFunction The Callback function to be registered.\r
293 @param Register To register or unregister the callback function.\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 @retval EFI_OUT_OF_RESOURCES If the callback function can't be registered because there is not free\r
298 slot left in the CallbackFnTable.\r
8ec8bed4 299 @retval EFI_INVALID_PARAMETER If the callback function want to be de-registered can not be found.\r
fc547e08 300**/\r
80408db0 301EFI_STATUS\r
302PeiRegisterCallBackWorker (\r
1436aea4
MK
303 IN UINTN ExTokenNumber,\r
304 IN CONST EFI_GUID *Guid OPTIONAL,\r
305 IN PCD_PPI_CALLBACK CallBackFunction,\r
306 IN BOOLEAN Register\r
307 )\r
80408db0 308{\r
1436aea4
MK
309 EFI_HOB_GUID_TYPE *GuidHob;\r
310 PCD_PPI_CALLBACK *CallbackTable;\r
311 PCD_PPI_CALLBACK Compare;\r
312 PCD_PPI_CALLBACK Assign;\r
313 UINT32 LocalTokenNumber;\r
314 UINT32 LocalTokenCount;\r
315 UINTN PeiNexTokenNumber;\r
316 UINTN TokenNumber;\r
317 UINTN Idx;\r
318 PEI_PCD_DATABASE *PeiPcdDb;\r
319\r
320 PeiPcdDb = GetPcdDatabase ();\r
419db80b
BF
321 LocalTokenCount = PeiPcdDb->LocalTokenCount;\r
322 PeiNexTokenNumber = PeiPcdDb->LocalTokenCount - PeiPcdDb->ExTokenCount;\r
80408db0 323\r
324 if (Guid == NULL) {\r
325 TokenNumber = ExTokenNumber;\r
80408db0 326 //\r
327 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
328 // We have to decrement TokenNumber by 1 to make it usable\r
329 // as the array index.\r
330 //\r
331 TokenNumber--;\r
419db80b 332 ASSERT (TokenNumber + 1 < (PeiNexTokenNumber + 1));\r
80408db0 333 } else {\r
334 TokenNumber = GetExPcdTokenNumber (Guid, ExTokenNumber);\r
86714ccd 335 if (TokenNumber == PCD_INVALID_TOKEN_NUMBER) {\r
336 return EFI_NOT_FOUND;\r
337 }\r
1436aea4 338\r
80408db0 339 //\r
340 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
341 // We have to decrement TokenNumber by 1 to make it usable\r
342 // as the array index.\r
343 //\r
344 TokenNumber--;\r
345 // EBC compiler is very choosy. It may report warning about comparison\r
d1102dba 346 // between UINTN and 0 . So we add 1 in each size of the\r
80408db0 347 // comparison.\r
419db80b 348 ASSERT ((TokenNumber + 1) < (LocalTokenCount + 1));\r
80408db0 349 }\r
350\r
419db80b 351 LocalTokenNumber = *((UINT32 *)((UINT8 *)PeiPcdDb + PeiPcdDb->LocalTokenNumberTableOffset) + TokenNumber);\r
80408db0 352\r
353 //\r
354 // We don't support SET for HII and VPD type PCD entry in PEI phase.\r
355 // So we will assert if any register callback for such PCD entry.\r
356 //\r
357 ASSERT ((LocalTokenNumber & PCD_TYPE_HII) == 0);\r
358 ASSERT ((LocalTokenNumber & PCD_TYPE_VPD) == 0);\r
359\r
96cb78a1 360 GuidHob = GetFirstGuidHob (&gEfiCallerIdGuid);\r
80408db0 361 ASSERT (GuidHob != NULL);\r
d1102dba 362\r
80408db0 363 CallbackTable = GET_GUID_HOB_DATA (GuidHob);\r
188e4e84 364 CallbackTable = CallbackTable + (TokenNumber * PcdGet32 (PcdMaxPeiPcdCallBackNumberPerPcdEntry));\r
80408db0 365\r
1436aea4
MK
366 Compare = Register ? NULL : CallBackFunction;\r
367 Assign = Register ? CallBackFunction : NULL;\r
80408db0 368\r
188e4e84 369 for (Idx = 0; Idx < PcdGet32 (PcdMaxPeiPcdCallBackNumberPerPcdEntry); Idx++) {\r
80408db0 370 if (CallbackTable[Idx] == Compare) {\r
371 CallbackTable[Idx] = Assign;\r
372 return EFI_SUCCESS;\r
373 }\r
374 }\r
375\r
1436aea4 376 return Register ? EFI_OUT_OF_RESOURCES : EFI_INVALID_PARAMETER;\r
80408db0 377}\r
378\r
419db80b 379/**\r
d1102dba 380 Find the Pcd database.\r
419db80b
BF
381\r
382 @param FileHandle Handle of the file the external PCD database binary located.\r
383\r
384 @retval The base address of external PCD database binary.\r
385 @retval NULL Return NULL if not find.\r
386**/\r
387VOID *\r
388LocateExPcdBinary (\r
1436aea4 389 IN EFI_PEI_FILE_HANDLE FileHandle\r
419db80b
BF
390 )\r
391{\r
1436aea4
MK
392 EFI_STATUS Status;\r
393 VOID *PcdDb;\r
419db80b 394\r
1436aea4 395 PcdDb = NULL;\r
419db80b
BF
396\r
397 ASSERT (FileHandle != NULL);\r
398\r
399 Status = PeiServicesFfsFindSectionData (EFI_SECTION_RAW, FileHandle, &PcdDb);\r
400 ASSERT_EFI_ERROR (Status);\r
401\r
402 //\r
403 // Check the first bytes (Header Signature Guid) and build version.\r
404 //\r
405 if (!CompareGuid (PcdDb, &gPcdDataBaseSignatureGuid) ||\r
1436aea4
MK
406 (((PEI_PCD_DATABASE *)PcdDb)->BuildVersion != PCD_SERVICE_PEIM_VERSION))\r
407 {\r
419db80b
BF
408 ASSERT (FALSE);\r
409 }\r
1436aea4 410\r
419db80b
BF
411 return PcdDb;\r
412}\r
413\r
80408db0 414/**\r
415 The function builds the PCD database.\r
419db80b
BF
416\r
417 @param FileHandle Handle of the file the external PCD database binary located.\r
418\r
96d6d004 419 @return Pointer to PCD database.\r
fc547e08 420**/\r
96d6d004 421PEI_PCD_DATABASE *\r
80408db0 422BuildPcdDatabase (\r
1436aea4 423 IN EFI_PEI_FILE_HANDLE FileHandle\r
80408db0 424 )\r
425{\r
1436aea4
MK
426 PEI_PCD_DATABASE *Database;\r
427 PEI_PCD_DATABASE *PeiPcdDbBinary;\r
428 VOID *CallbackFnTable;\r
429 UINTN SizeOfCallbackFnTable;\r
419db80b
BF
430\r
431 //\r
432 // Locate the external PCD database binary for one section of current FFS\r
433 //\r
434 PeiPcdDbBinary = LocateExPcdBinary (FileHandle);\r
80408db0 435\r
1436aea4 436 ASSERT (PeiPcdDbBinary != NULL);\r
419db80b
BF
437\r
438 Database = BuildGuidHob (&gPcdDataBaseHobGuid, PeiPcdDbBinary->Length + PeiPcdDbBinary->UninitDataBaseSize);\r
439\r
440 ZeroMem (Database, PeiPcdDbBinary->Length + PeiPcdDbBinary->UninitDataBaseSize);\r
80408db0 441\r
442 //\r
419db80b 443 // PeiPcdDbBinary is smaller than Database\r
80408db0 444 //\r
419db80b 445 CopyMem (Database, PeiPcdDbBinary, PeiPcdDbBinary->Length);\r
80408db0 446\r
419db80b 447 SizeOfCallbackFnTable = Database->LocalTokenCount * sizeof (PCD_PPI_CALLBACK) * PcdGet32 (PcdMaxPeiPcdCallBackNumberPerPcdEntry);\r
80408db0 448\r
96cb78a1 449 CallbackFnTable = BuildGuidHob (&gEfiCallerIdGuid, SizeOfCallbackFnTable);\r
d1102dba 450\r
80408db0 451 ZeroMem (CallbackFnTable, SizeOfCallbackFnTable);\r
96d6d004
SZ
452\r
453 return Database;\r
80408db0 454}\r
455\r
80408db0 456/**\r
457 The function is provided by PCD PEIM and PCD DXE driver to\r
458 do the work of reading a HII variable from variable service.\r
459\r
460 @param VariableGuid The Variable GUID.\r
461 @param VariableName The Variable Name.\r
462 @param VariableData The output data.\r
463 @param VariableSize The size of the variable.\r
464\r
465 @retval EFI_SUCCESS Operation successful.\r
466 @retval EFI_NOT_FOUND Variablel not found.\r
fc547e08 467**/\r
80408db0 468EFI_STATUS\r
469GetHiiVariable (\r
1436aea4
MK
470 IN CONST EFI_GUID *VariableGuid,\r
471 IN UINT16 *VariableName,\r
472 OUT VOID **VariableData,\r
473 OUT UINTN *VariableSize\r
80408db0 474 )\r
475{\r
1436aea4
MK
476 UINTN Size;\r
477 EFI_STATUS Status;\r
478 VOID *Buffer;\r
479 EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariablePpi;\r
80408db0 480\r
1436aea4 481 Status = PeiServicesLocatePpi (&gEfiPeiReadOnlyVariable2PpiGuid, 0, NULL, (VOID **)&VariablePpi);\r
80408db0 482 ASSERT_EFI_ERROR (Status);\r
483\r
1436aea4 484 Size = 0;\r
97a079ed
A
485 Status = VariablePpi->GetVariable (\r
486 VariablePpi,\r
80408db0 487 VariableName,\r
1436aea4 488 (EFI_GUID *)VariableGuid,\r
80408db0 489 NULL,\r
490 &Size,\r
491 NULL\r
97a079ed 492 );\r
80408db0 493\r
e5618791 494 if (Status == EFI_BUFFER_TOO_SMALL) {\r
80408db0 495 Status = PeiServicesAllocatePool (Size, &Buffer);\r
496 ASSERT_EFI_ERROR (Status);\r
497\r
97a079ed 498 Status = VariablePpi->GetVariable (\r
1436aea4
MK
499 VariablePpi,\r
500 (UINT16 *)VariableName,\r
501 (EFI_GUID *)VariableGuid,\r
502 NULL,\r
503 &Size,\r
504 Buffer\r
505 );\r
80408db0 506 ASSERT_EFI_ERROR (Status);\r
507\r
508 *VariableSize = Size;\r
509 *VariableData = Buffer;\r
510\r
511 return EFI_SUCCESS;\r
e5618791 512 }\r
80408db0 513\r
fc547e08 514 return EFI_NOT_FOUND;\r
80408db0 515}\r
516\r
fc547e08 517/**\r
d1102dba 518 Invoke the callback function when dynamic PCD entry was set, if this PCD entry\r
fc547e08 519 has registered callback function.\r
80408db0 520\r
fc547e08 521 @param ExTokenNumber DynamicEx PCD's token number, if this PCD entry is dyanmicEx\r
522 type PCD.\r
523 @param Guid DynamicEx PCD's guid, if this PCD entry is dynamicEx type\r
524 PCD.\r
525 @param TokenNumber PCD token number generated by build tools.\r
526 @param Data Value want to be set for this PCD entry\r
527 @param Size The size of value\r
80408db0 528\r
fc547e08 529**/\r
80408db0 530VOID\r
531InvokeCallbackOnSet (\r
1436aea4
MK
532 UINTN ExTokenNumber,\r
533 CONST EFI_GUID *Guid OPTIONAL,\r
534 UINTN TokenNumber,\r
535 VOID *Data,\r
536 UINTN Size\r
80408db0 537 )\r
538{\r
1436aea4
MK
539 EFI_HOB_GUID_TYPE *GuidHob;\r
540 PCD_PPI_CALLBACK *CallbackTable;\r
541 UINTN Idx;\r
542 PEI_PCD_DATABASE *PeiPcdDb;\r
543 UINT32 LocalTokenCount;\r
80408db0 544\r
545 //\r
546 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
547 // We have to decrement TokenNumber by 1 to make it usable\r
548 // as the array index.\r
549 //\r
550 TokenNumber--;\r
419db80b
BF
551\r
552 PeiPcdDb = GetPcdDatabase ();\r
553 LocalTokenCount = PeiPcdDb->LocalTokenCount;\r
554\r
80408db0 555 if (Guid == NULL) {\r
556 // EBC compiler is very choosy. It may report warning about comparison\r
d1102dba 557 // between UINTN and 0 . So we add 1 in each size of the\r
80408db0 558 // comparison.\r
419db80b 559 ASSERT (TokenNumber + 1 < (LocalTokenCount + 1));\r
80408db0 560 }\r
561\r
96cb78a1 562 GuidHob = GetFirstGuidHob (&gEfiCallerIdGuid);\r
80408db0 563 ASSERT (GuidHob != NULL);\r
d1102dba 564\r
80408db0 565 CallbackTable = GET_GUID_HOB_DATA (GuidHob);\r
566\r
188e4e84 567 CallbackTable += (TokenNumber * PcdGet32 (PcdMaxPeiPcdCallBackNumberPerPcdEntry));\r
80408db0 568\r
188e4e84 569 for (Idx = 0; Idx < PcdGet32 (PcdMaxPeiPcdCallBackNumberPerPcdEntry); Idx++) {\r
80408db0 570 if (CallbackTable[Idx] != NULL) {\r
1436aea4
MK
571 CallbackTable[Idx](Guid,\r
572 (Guid == NULL) ? (TokenNumber + 1) : ExTokenNumber,\r
573 Data,\r
574 Size\r
575 );\r
80408db0 576 }\r
577 }\r
80408db0 578}\r
579\r
fc547e08 580/**\r
581 Wrapper function for setting non-pointer type value for a PCD entry.\r
582\r
583 @param TokenNumber Pcd token number autogenerated by build tools.\r
584 @param Data Value want to be set for PCD entry\r
585 @param Size Size of value.\r
80408db0 586\r
fc547e08 587 @return status of SetWorker.\r
80408db0 588\r
fc547e08 589**/\r
80408db0 590EFI_STATUS\r
591SetValueWorker (\r
1436aea4
MK
592 IN UINTN TokenNumber,\r
593 IN VOID *Data,\r
594 IN UINTN Size\r
80408db0 595 )\r
596{\r
597 return SetWorker (TokenNumber, Data, &Size, FALSE);\r
598}\r
599\r
fc547e08 600/**\r
601 Set value for an PCD entry\r
602\r
603 @param TokenNumber Pcd token number autogenerated by build tools.\r
604 @param Data Value want to be set for PCD entry\r
605 @param Size Size of value.\r
606 @param PtrType If TRUE, the type of PCD entry's value is Pointer.\r
607 If False, the type of PCD entry's value is not Pointer.\r
608\r
609 @retval EFI_INVALID_PARAMETER If this PCD type is VPD, VPD PCD can not be set.\r
610 @retval EFI_INVALID_PARAMETER If Size can not be set to size table.\r
149fb6d6 611 @retval EFI_INVALID_PARAMETER If Size of non-Ptr type PCD does not match the size information in PCD database.\r
fc547e08 612 @retval EFI_NOT_FOUND If value type of PCD entry is intergrate, but not in\r
613 range of UINT8, UINT16, UINT32, UINT64\r
d1102dba 614 @retval EFI_NOT_FOUND Can not find the PCD type according to token number.\r
fc547e08 615**/\r
80408db0 616EFI_STATUS\r
617SetWorker (\r
1436aea4
MK
618 IN UINTN TokenNumber,\r
619 IN VOID *Data,\r
620 IN OUT UINTN *Size,\r
621 IN BOOLEAN PtrType\r
80408db0 622 )\r
623{\r
1436aea4
MK
624 UINT32 LocalTokenNumber;\r
625 UINTN PeiNexTokenNumber;\r
626 PEI_PCD_DATABASE *PeiPcdDb;\r
627 STRING_HEAD StringTableIdx;\r
628 UINTN Offset;\r
629 VOID *InternalData;\r
630 UINTN MaxSize;\r
631 UINT32 LocalTokenCount;\r
632\r
633 if (!FeaturePcdGet (PcdPeiFullPcdDatabaseEnable)) {\r
80408db0 634 return EFI_UNSUPPORTED;\r
635 }\r
d1102dba 636\r
80408db0 637 //\r
638 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
639 // We have to decrement TokenNumber by 1 to make it usable\r
640 // as the array index.\r
641 //\r
642 TokenNumber--;\r
419db80b
BF
643 PeiPcdDb = GetPcdDatabase ();\r
644 LocalTokenCount = PeiPcdDb->LocalTokenCount;\r
80408db0 645\r
646 // EBC compiler is very choosy. It may report warning about comparison\r
d1102dba 647 // between UINTN and 0 . So we add 1 in each size of the\r
80408db0 648 // comparison.\r
419db80b 649 ASSERT (TokenNumber + 1 < (LocalTokenCount + 1));\r
80408db0 650\r
8ec8bed4 651 if (PtrType) {\r
64894410
LG
652 //\r
653 // Get MaxSize first, then check new size with max buffer size.\r
654 //\r
655 GetPtrTypeSize (TokenNumber, &MaxSize, PeiPcdDb);\r
656 if (*Size > MaxSize) {\r
cb40609c 657 *Size = MaxSize;\r
8ec8bed4 658 return EFI_INVALID_PARAMETER;\r
659 }\r
660 } else {\r
661 if (*Size != PeiPcdGetSize (TokenNumber + 1)) {\r
662 return EFI_INVALID_PARAMETER;\r
663 }\r
80408db0 664 }\r
665\r
666 //\r
667 // We only invoke the callback function for Dynamic Type PCD Entry.\r
668 // For Dynamic EX PCD entry, we have invoked the callback function for Dynamic EX\r
669 // type PCD entry in ExSetWorker.\r
670 //\r
419db80b
BF
671 PeiNexTokenNumber = PeiPcdDb->LocalTokenCount - PeiPcdDb->ExTokenCount;\r
672 if (TokenNumber + 1 < PeiNexTokenNumber + 1) {\r
80408db0 673 InvokeCallbackOnSet (0, NULL, TokenNumber + 1, Data, *Size);\r
674 }\r
675\r
96d6d004 676 LocalTokenNumber = GetLocalTokenNumber (PeiPcdDb, TokenNumber + 1);\r
80408db0 677\r
1436aea4
MK
678 Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;\r
679 InternalData = (VOID *)((UINT8 *)PeiPcdDb + Offset);\r
d1102dba 680\r
80408db0 681 switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {\r
682 case PCD_TYPE_VPD:\r
683 case PCD_TYPE_HII:\r
6ac15f7c 684 case PCD_TYPE_HII|PCD_TYPE_STRING:\r
80408db0 685 {\r
686 ASSERT (FALSE);\r
687 return EFI_INVALID_PARAMETER;\r
688 }\r
689\r
690 case PCD_TYPE_STRING:\r
691 if (SetPtrTypeSize (TokenNumber, Size, PeiPcdDb)) {\r
6cfc7292 692 StringTableIdx = *((STRING_HEAD *)InternalData);\r
419db80b 693 CopyMem ((UINT8 *)PeiPcdDb + PeiPcdDb->StringTableOffset + StringTableIdx, Data, *Size);\r
80408db0 694 return EFI_SUCCESS;\r
695 } else {\r
696 return EFI_INVALID_PARAMETER;\r
697 }\r
698\r
699 case PCD_TYPE_DATA:\r
700 {\r
701 if (PtrType) {\r
702 if (SetPtrTypeSize (TokenNumber, Size, PeiPcdDb)) {\r
703 CopyMem (InternalData, Data, *Size);\r
704 return EFI_SUCCESS;\r
705 } else {\r
706 return EFI_INVALID_PARAMETER;\r
707 }\r
708 }\r
709\r
710 switch (*Size) {\r
1436aea4
MK
711 case sizeof (UINT8):\r
712 *((UINT8 *)InternalData) = *((UINT8 *)Data);\r
80408db0 713 return EFI_SUCCESS;\r
714\r
1436aea4
MK
715 case sizeof (UINT16):\r
716 *((UINT16 *)InternalData) = *((UINT16 *)Data);\r
80408db0 717 return EFI_SUCCESS;\r
718\r
1436aea4
MK
719 case sizeof (UINT32):\r
720 *((UINT32 *)InternalData) = *((UINT32 *)Data);\r
80408db0 721 return EFI_SUCCESS;\r
722\r
1436aea4
MK
723 case sizeof (UINT64):\r
724 *((UINT64 *)InternalData) = *((UINT64 *)Data);\r
80408db0 725 return EFI_SUCCESS;\r
726\r
727 default:\r
728 ASSERT (FALSE);\r
729 return EFI_NOT_FOUND;\r
730 }\r
731 }\r
80408db0 732 }\r
733\r
734 ASSERT (FALSE);\r
735 return EFI_NOT_FOUND;\r
80408db0 736}\r
737\r
fc547e08 738/**\r
739 Wrapper function for set PCD value for non-Pointer type dynamic-ex PCD.\r
80408db0 740\r
fc547e08 741 @param ExTokenNumber Token number for dynamic-ex PCD.\r
742 @param Guid Token space guid for dynamic-ex PCD.\r
743 @param Data Value want to be set.\r
744 @param SetSize The size of value.\r
80408db0 745\r
fc547e08 746 @return status of ExSetWorker().\r
747\r
748**/\r
80408db0 749EFI_STATUS\r
750ExSetValueWorker (\r
1436aea4
MK
751 IN UINTN ExTokenNumber,\r
752 IN CONST EFI_GUID *Guid,\r
753 IN VOID *Data,\r
754 IN UINTN Size\r
80408db0 755 )\r
756{\r
757 return ExSetWorker (ExTokenNumber, Guid, Data, &Size, FALSE);\r
758}\r
759\r
fc547e08 760/**\r
419db80b 761 Set value for a dynamic-ex PCD entry.\r
d1102dba
LG
762\r
763 This routine find the local token number according to dynamic-ex PCD's token\r
fc547e08 764 space guid and token number firstly, and invoke callback function if this PCD\r
765 entry registered callback function. Finally, invoken general SetWorker to set\r
766 PCD value.\r
d1102dba 767\r
fc547e08 768 @param ExTokenNumber Dynamic-ex PCD token number.\r
769 @param Guid Token space guid for dynamic-ex PCD.\r
770 @param Data PCD value want to be set\r
771 @param SetSize Size of value.\r
772 @param PtrType If TRUE, this PCD entry is pointer type.\r
773 If FALSE, this PCD entry is not pointer type.\r
80408db0 774\r
fc547e08 775 @return status of SetWorker().\r
80408db0 776\r
fc547e08 777**/\r
80408db0 778EFI_STATUS\r
779ExSetWorker (\r
1436aea4
MK
780 IN UINTN ExTokenNumber,\r
781 IN CONST EFI_GUID *Guid,\r
782 IN VOID *Data,\r
783 IN OUT UINTN *Size,\r
784 IN BOOLEAN PtrType\r
80408db0 785 )\r
786{\r
1436aea4 787 UINTN TokenNumber;\r
80408db0 788\r
1436aea4 789 if (!FeaturePcdGet (PcdPeiFullPcdDatabaseEnable)) {\r
80408db0 790 return EFI_UNSUPPORTED;\r
791 }\r
792\r
793 TokenNumber = GetExPcdTokenNumber (Guid, ExTokenNumber);\r
86714ccd 794 if (TokenNumber == PCD_INVALID_TOKEN_NUMBER) {\r
795 return EFI_NOT_FOUND;\r
796 }\r
d1102dba 797\r
80408db0 798 InvokeCallbackOnSet (ExTokenNumber, Guid, TokenNumber, Data, *Size);\r
799\r
800 return SetWorker (TokenNumber, Data, Size, PtrType);\r
80408db0 801}\r
802\r
fc547e08 803/**\r
804 Wrapper function for get PCD value for dynamic-ex PCD.\r
80408db0 805\r
fc547e08 806 @param Guid Token space guid for dynamic-ex PCD.\r
807 @param ExTokenNumber Token number for dyanmic-ex PCD.\r
808 @param GetSize The size of dynamic-ex PCD value.\r
80408db0 809\r
fc547e08 810 @return PCD entry in PCD database.\r
80408db0 811\r
fc547e08 812**/\r
80408db0 813VOID *\r
814ExGetWorker (\r
815 IN CONST EFI_GUID *Guid,\r
816 IN UINTN ExTokenNumber,\r
817 IN UINTN GetSize\r
818 )\r
d1102dba 819{\r
80408db0 820 return GetWorker (GetExPcdTokenNumber (Guid, ExTokenNumber), GetSize);\r
821}\r
822\r
fc547e08 823/**\r
824 Get the PCD entry pointer in PCD database.\r
d1102dba 825\r
fc547e08 826 This routine will visit PCD database to find the PCD entry according to given\r
d1102dba
LG
827 token number. The given token number is autogened by build tools and it will be\r
828 translated to local token number. Local token number contains PCD's type and\r
fc547e08 829 offset of PCD entry in PCD database.\r
80408db0 830\r
fc547e08 831 @param TokenNumber Token's number, it is autogened by build tools\r
832 @param GetSize The size of token's value\r
80408db0 833\r
fc547e08 834 @return PCD entry pointer in PCD database\r
80408db0 835\r
fc547e08 836**/\r
80408db0 837VOID *\r
838GetWorker (\r
1436aea4
MK
839 IN UINTN TokenNumber,\r
840 IN UINTN GetSize\r
80408db0 841 )\r
842{\r
1436aea4
MK
843 UINT32 Offset;\r
844 EFI_GUID *Guid;\r
845 UINT16 *Name;\r
846 VARIABLE_HEAD *VariableHead;\r
847 EFI_STATUS Status;\r
848 UINTN DataSize;\r
849 VOID *Data;\r
850 UINT8 *StringTable;\r
851 STRING_HEAD StringTableIdx;\r
852 PEI_PCD_DATABASE *PeiPcdDb;\r
853 UINT32 LocalTokenNumber;\r
854 UINT32 LocalTokenCount;\r
855 UINT8 *VaraiableDefaultBuffer;\r
856 UINTN VpdBaseAddress;\r
80408db0 857\r
858 //\r
859 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
860 // We have to decrement TokenNumber by 1 to make it usable\r
861 // as the array index.\r
862 //\r
863 TokenNumber--;\r
864\r
419db80b
BF
865 PeiPcdDb = GetPcdDatabase ();\r
866 LocalTokenCount = PeiPcdDb->LocalTokenCount;\r
867\r
80408db0 868 // EBC compiler is very choosy. It may report warning about comparison\r
d1102dba 869 // between UINTN and 0 . So we add 1 in each size of the\r
80408db0 870 // comparison.\r
419db80b 871 ASSERT (TokenNumber + 1 < (LocalTokenCount + 1));\r
80408db0 872\r
1436aea4 873 ASSERT ((GetSize == PeiPcdGetSize (TokenNumber + 1)) || (GetSize == 0));\r
80408db0 874\r
96d6d004 875 LocalTokenNumber = GetLocalTokenNumber (PeiPcdDb, TokenNumber + 1);\r
80408db0 876\r
877 Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;\r
419db80b
BF
878 StringTable = (UINT8 *)PeiPcdDb + PeiPcdDb->StringTableOffset;\r
879\r
80408db0 880 switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {\r
881 case PCD_TYPE_VPD:\r
882 {\r
1436aea4
MK
883 VPD_HEAD *VpdHead;\r
884 VpdHead = (VPD_HEAD *)((UINT8 *)PeiPcdDb + Offset);\r
534efca0
LG
885\r
886 //\r
887 // PcdVpdBaseAddress64 is DynamicEx PCD only. So, PeiPcdGet64Ex() is used to get its value.\r
888 //\r
1436aea4 889 VpdBaseAddress = (UINTN)PeiPcdGet64Ex (&gEfiMdeModulePkgTokenSpaceGuid, PcdToken (PcdVpdBaseAddress64));\r
534efca0
LG
890 if (VpdBaseAddress == 0) {\r
891 //\r
892 // PcdVpdBaseAddress64 is not set, get value from PcdVpdBaseAddress.\r
893 //\r
1436aea4 894 VpdBaseAddress = (UINTN)PcdGet32 (PcdVpdBaseAddress);\r
534efca0 895 }\r
1436aea4 896\r
534efca0
LG
897 ASSERT (VpdBaseAddress != 0);\r
898 return (VOID *)(VpdBaseAddress + VpdHead->Offset);\r
80408db0 899 }\r
d1102dba 900\r
6ac15f7c 901 case PCD_TYPE_HII|PCD_TYPE_STRING:\r
80408db0 902 case PCD_TYPE_HII:\r
903 {\r
1436aea4 904 VariableHead = (VARIABLE_HEAD *)((UINT8 *)PeiPcdDb + Offset);\r
d1102dba 905\r
1436aea4
MK
906 Guid = (EFI_GUID *)((UINT8 *)PeiPcdDb + PeiPcdDb->GuidTableOffset) + VariableHead->GuidTableIndex;\r
907 Name = (UINT16 *)&StringTable[VariableHead->StringIndex];\r
80408db0 908\r
553e8669 909 if ((LocalTokenNumber & PCD_TYPE_ALL_SET) == (PCD_TYPE_HII|PCD_TYPE_STRING)) {\r
80408db0 910 //\r
d1102dba 911 // If a HII type PCD's datum type is VOID*, the DefaultValueOffset is the index of\r
553e8669 912 // string array in string table.\r
80408db0 913 //\r
1436aea4 914 VaraiableDefaultBuffer = (UINT8 *)&StringTable[*(STRING_HEAD *)((UINT8 *)PeiPcdDb + VariableHead->DefaultValueOffset)];\r
553e8669 915 } else {\r
1436aea4 916 VaraiableDefaultBuffer = (UINT8 *)PeiPcdDb + VariableHead->DefaultValueOffset;\r
553e8669 917 }\r
1436aea4 918\r
553e8669
SZ
919 Status = GetHiiVariable (Guid, Name, &Data, &DataSize);\r
920 if ((Status == EFI_SUCCESS) && (DataSize >= (VariableHead->Offset + GetSize))) {\r
921 if (GetSize == 0) {\r
922 //\r
923 // It is a pointer type. So get the MaxSize reserved for\r
924 // this PCD entry.\r
925 //\r
926 GetPtrTypeSize (TokenNumber, &GetSize, PeiPcdDb);\r
927 if (GetSize > (DataSize - VariableHead->Offset)) {\r
928 //\r
929 // Use actual valid size.\r
930 //\r
931 GetSize = DataSize - VariableHead->Offset;\r
932 }\r
6ac15f7c 933 }\r
1436aea4 934\r
553e8669
SZ
935 //\r
936 // If the operation is successful, we copy the data\r
937 // to the default value buffer in the PCD Database.\r
938 //\r
1436aea4 939 CopyMem (VaraiableDefaultBuffer, (UINT8 *)Data + VariableHead->Offset, GetSize);\r
80408db0 940 }\r
1436aea4
MK
941\r
942 return (VOID *)VaraiableDefaultBuffer;\r
80408db0 943 }\r
944\r
945 case PCD_TYPE_DATA:\r
1436aea4 946 return (VOID *)((UINT8 *)PeiPcdDb + Offset);\r
80408db0 947\r
948 case PCD_TYPE_STRING:\r
1436aea4
MK
949 StringTableIdx = *(STRING_HEAD *)((UINT8 *)PeiPcdDb + Offset);\r
950 return (VOID *)(&StringTable[StringTableIdx]);\r
80408db0 951\r
952 default:\r
953 ASSERT (FALSE);\r
954 break;\r
80408db0 955 }\r
956\r
957 ASSERT (FALSE);\r
d1102dba 958\r
80408db0 959 return NULL;\r
80408db0 960}\r
961\r
fc547e08 962/**\r
419db80b 963 Get Token Number according to dynamic-ex PCD's {token space guid:token number}\r
fc547e08 964\r
965 A dynamic-ex type PCD, developer must provide pair of token space guid: token number\r
966 in DEC file. PCD database maintain a mapping table that translate pair of {token\r
419db80b 967 space guid: token number} to Token Number.\r
d1102dba 968\r
fc547e08 969 @param Guid Token space guid for dynamic-ex PCD entry.\r
419db80b 970 @param ExTokenNumber Dynamic-ex PCD token number.\r
80408db0 971\r
419db80b 972 @return Token Number for dynamic-ex PCD.\r
80408db0 973\r
fc547e08 974**/\r
d1102dba 975UINTN\r
80408db0 976GetExPcdTokenNumber (\r
1436aea4
MK
977 IN CONST EFI_GUID *Guid,\r
978 IN UINTN ExTokenNumber\r
80408db0 979 )\r
980{\r
1436aea4
MK
981 UINT32 Index;\r
982 DYNAMICEX_MAPPING *ExMap;\r
983 EFI_GUID *GuidTable;\r
984 EFI_GUID *MatchGuid;\r
985 UINTN MatchGuidIdx;\r
986 PEI_PCD_DATABASE *PeiPcdDb;\r
80408db0 987\r
1436aea4 988 PeiPcdDb = GetPcdDatabase ();\r
80408db0 989\r
1436aea4
MK
990 ExMap = (DYNAMICEX_MAPPING *)((UINT8 *)PeiPcdDb + PeiPcdDb->ExMapTableOffset);\r
991 GuidTable = (EFI_GUID *)((UINT8 *)PeiPcdDb + PeiPcdDb->GuidTableOffset);\r
419db80b 992\r
1436aea4 993 MatchGuid = ScanGuid (GuidTable, PeiPcdDb->GuidTableCount * sizeof (EFI_GUID), Guid);\r
80408db0 994 //\r
995 // We need to ASSERT here. If GUID can't be found in GuidTable, this is a\r
996 // error in the BUILD system.\r
997 //\r
998 ASSERT (MatchGuid != NULL);\r
d1102dba 999\r
80408db0 1000 MatchGuidIdx = MatchGuid - GuidTable;\r
d1102dba 1001\r
419db80b 1002 for (Index = 0; Index < PeiPcdDb->ExTokenCount; Index++) {\r
d1102dba 1003 if ((ExTokenNumber == ExMap[Index].ExTokenNumber) &&\r
1436aea4
MK
1004 (MatchGuidIdx == ExMap[Index].ExGuidIndex))\r
1005 {\r
419db80b 1006 return ExMap[Index].TokenNumber;\r
80408db0 1007 }\r
1008 }\r
d1102dba 1009\r
86714ccd 1010 return PCD_INVALID_TOKEN_NUMBER;\r
80408db0 1011}\r
1012\r
fc547e08 1013/**\r
1014 Get PCD database from GUID HOB in PEI phase.\r
80408db0 1015\r
fc547e08 1016 @return Pointer to PCD database.\r
80408db0 1017\r
fc547e08 1018**/\r
80408db0 1019PEI_PCD_DATABASE *\r
1020GetPcdDatabase (\r
1021 VOID\r
1022 )\r
1023{\r
1436aea4 1024 EFI_HOB_GUID_TYPE *GuidHob;\r
80408db0 1025\r
1026 GuidHob = GetFirstGuidHob (&gPcdDataBaseHobGuid);\r
1027 ASSERT (GuidHob != NULL);\r
d1102dba 1028\r
1436aea4 1029 return (PEI_PCD_DATABASE *)GET_GUID_HOB_DATA (GuidHob);\r
80408db0 1030}\r
1031\r
fc547e08 1032/**\r
1033 Get index of PCD entry in size table.\r
1034\r
1035 @param LocalTokenNumberTableIdx Index of this PCD in local token number table.\r
1036 @param Database Pointer to PCD database in PEI phase.\r
80408db0 1037\r
fc547e08 1038 @return index of PCD entry in size table.\r
80408db0 1039\r
fc547e08 1040**/\r
80408db0 1041UINTN\r
1042GetSizeTableIndex (\r
1043 IN UINTN LocalTokenNumberTableIdx,\r
1044 IN PEI_PCD_DATABASE *Database\r
1045 )\r
1046{\r
1436aea4
MK
1047 UINTN Index;\r
1048 UINTN SizeTableIdx;\r
1049 UINTN LocalTokenNumber;\r
7c736265 1050\r
80408db0 1051 SizeTableIdx = 0;\r
1052\r
419db80b
BF
1053 for (Index = 0; Index < LocalTokenNumberTableIdx; Index++) {\r
1054 LocalTokenNumber = *((UINT32 *)((UINT8 *)Database + Database->LocalTokenNumberTableOffset) + Index);\r
80408db0 1055\r
1056 if ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER) {\r
1057 //\r
d1102dba 1058 // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type\r
80408db0 1059 // PCD entry.\r
1060 //\r
fc547e08 1061 if ((LocalTokenNumber & PCD_TYPE_VPD) != 0) {\r
1436aea4
MK
1062 //\r
1063 // We have only two entry for VPD enabled PCD entry:\r
1064 // 1) MAX Size.\r
1065 // 2) Current Size\r
1066 // Current size is equal to MAX size.\r
1067 //\r
1068 SizeTableIdx += 2;\r
80408db0 1069 } else {\r
1436aea4
MK
1070 //\r
1071 // We have only two entry for Non-Sku enabled PCD entry:\r
1072 // 1) MAX SIZE\r
1073 // 2) Current Size\r
1074 //\r
1075 SizeTableIdx += 2;\r
80408db0 1076 }\r
1077 }\r
80408db0 1078 }\r
1079\r
1080 return SizeTableIdx;\r
1081}\r