]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/PCD/Pei/Pcd.c
MdeModulePkg PCD: Reinstall PCD service PPIS when memory available
[mirror_edk2.git] / MdeModulePkg / Universal / PCD / Pei / Pcd.c
CommitLineData
d1102dba 1/** @file\r
5944a83b 2 All Pcd Ppi services are implemented here.\r
d1102dba 3\r
6fdd1c13 4Copyright (c) 2006 - 2021, Intel Corporation. All rights reserved.<BR>\r
bfb4c2ba 5(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>\r
9d510e61 6SPDX-License-Identifier: BSD-2-Clause-Patent\r
80408db0 7\r
80408db0 8**/\r
9\r
80408db0 10#include "Service.h"\r
11\r
17e7fa8f 12///\r
13/// Instance of PCD_PPI protocol is EDKII native implementation.\r
14/// This protocol instance support dynamic and dynamicEx type PCDs.\r
15///\r
80408db0 16PCD_PPI mPcdPpiInstance = {\r
17 PeiPcdSetSku,\r
18\r
19 PeiPcdGet8,\r
d1102dba
LG
20 PeiPcdGet16,\r
21 PeiPcdGet32,\r
22 PeiPcdGet64,\r
23 PeiPcdGetPtr,\r
24 PeiPcdGetBool,\r
80408db0 25 PeiPcdGetSize,\r
26\r
27 PeiPcdGet8Ex,\r
d1102dba
LG
28 PeiPcdGet16Ex,\r
29 PeiPcdGet32Ex,\r
30 PeiPcdGet64Ex,\r
31 PeiPcdGetPtrEx,\r
32 PeiPcdGetBoolEx,\r
80408db0 33 PeiPcdGetSizeEx,\r
d1102dba 34\r
80408db0 35 PeiPcdSet8,\r
d1102dba
LG
36 PeiPcdSet16,\r
37 PeiPcdSet32,\r
38 PeiPcdSet64,\r
39 PeiPcdSetPtr,\r
40 PeiPcdSetBool,\r
80408db0 41\r
42 PeiPcdSet8Ex,\r
d1102dba
LG
43 PeiPcdSet16Ex,\r
44 PeiPcdSet32Ex,\r
45 PeiPcdSet64Ex,\r
46 PeiPcdSetPtrEx,\r
80408db0 47 PeiPcdSetBoolEx,\r
48\r
49 PeiRegisterCallBackOnSet,\r
50 PcdUnRegisterCallBackOnSet,\r
51 PeiPcdGetNextToken,\r
52 PeiPcdGetNextTokenSpace\r
53};\r
54\r
17e7fa8f 55///\r
56/// Instance of EFI_PEI_PCD_PPI which is defined in PI 1.2 Vol 3.\r
57/// This PPI instance only support dyanmicEx type PCD.\r
58///\r
c896d682 59EFI_PEI_PCD_PPI mEfiPcdPpiInstance = {\r
60 PeiPcdSetSku,\r
d1102dba 61\r
c896d682 62 PeiPcdGet8Ex,\r
63 PeiPcdGet16Ex,\r
64 PeiPcdGet32Ex,\r
65 PeiPcdGet64Ex,\r
66 PeiPcdGetPtrEx,\r
67 PeiPcdGetBoolEx,\r
68 PeiPcdGetSizeEx,\r
69 PeiPcdSet8Ex,\r
70 PeiPcdSet16Ex,\r
71 PeiPcdSet32Ex,\r
72 PeiPcdSet64Ex,\r
73 PeiPcdSetPtrEx,\r
74 PeiPcdSetBoolEx,\r
75 (EFI_PEI_PCD_PPI_CALLBACK_ON_SET) PeiRegisterCallBackOnSet,\r
76 (EFI_PEI_PCD_PPI_CANCEL_CALLBACK) PcdUnRegisterCallBackOnSet,\r
77 PeiPcdGetNextToken,\r
78 PeiPcdGetNextTokenSpace\r
79};\r
80\r
96d6d004
SZ
81///\r
82/// Instance of GET_PCD_INFO_PPI protocol is EDKII native implementation.\r
83/// This protocol instance support dynamic and dynamicEx type PCDs.\r
84///\r
85GET_PCD_INFO_PPI mGetPcdInfoInstance = {\r
86 PeiGetPcdInfoGetInfo,\r
87 PeiGetPcdInfoGetInfoEx,\r
88 PeiGetPcdInfoGetSku\r
89};\r
90\r
91///\r
92/// Instance of EFI_GET_PCD_INFO_PPI which is defined in PI 1.2.1 Vol 3.\r
93/// This PPI instance only support dyanmicEx type PCD.\r
94///\r
95EFI_GET_PCD_INFO_PPI mEfiGetPcdInfoInstance = {\r
96 PeiGetPcdInfoGetInfoEx,\r
97 PeiGetPcdInfoGetSku\r
98};\r
99\r
17e7fa8f 100EFI_PEI_PPI_DESCRIPTOR mPpiList[] = {\r
101 {\r
102 EFI_PEI_PPI_DESCRIPTOR_PPI,\r
103 &gPcdPpiGuid,\r
104 &mPcdPpiInstance\r
105 },\r
106 {\r
107 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
108 &gEfiPeiPcdPpiGuid,\r
109 &mEfiPcdPpiInstance\r
110 }\r
c896d682 111};\r
112\r
96d6d004
SZ
113EFI_PEI_PPI_DESCRIPTOR mPpiList2[] = {\r
114 {\r
115 EFI_PEI_PPI_DESCRIPTOR_PPI,\r
116 &gGetPcdInfoPpiGuid,\r
117 &mGetPcdInfoInstance\r
118 },\r
119 {\r
120 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
121 &gEfiGetPcdInfoPpiGuid,\r
122 &mEfiGetPcdInfoInstance\r
123 }\r
124};\r
125\r
219247e1
LG
126/**\r
127 Callback on SET PcdSetNvStoreDefaultId\r
128\r
129 Once PcdSetNvStoreDefaultId is set, the default NV storage will be found from\r
130 PcdNvStoreDefaultValueBuffer, and built into VariableHob.\r
131\r
132 @param[in] CallBackGuid The PCD token GUID being set.\r
133 @param[in] CallBackToken The PCD token number being set.\r
134 @param[in, out] TokenData A pointer to the token data being set.\r
135 @param[in] TokenDataSize The size, in bytes, of the data being set.\r
136\r
137**/\r
138VOID\r
139EFIAPI\r
140PcdSetNvStoreDefaultIdCallBack (\r
141 IN CONST EFI_GUID *CallBackGuid, OPTIONAL\r
142 IN UINTN CallBackToken,\r
143 IN OUT VOID *TokenData,\r
144 IN UINTN TokenDataSize\r
145 )\r
146{\r
147 EFI_STATUS Status;\r
148 UINT16 DefaultId;\r
149 SKU_ID SkuId;\r
150 UINTN FullSize;\r
151 UINTN Index;\r
152 UINT8 *DataBuffer;\r
153 UINT8 *VarStoreHobData;\r
154 UINT8 *BufferEnd;\r
155 BOOLEAN IsFound;\r
156 VARIABLE_STORE_HEADER *NvStoreBuffer;\r
157 PCD_DEFAULT_DATA *DataHeader;\r
158 PCD_DEFAULT_INFO *DefaultInfo;\r
159 PCD_DATA_DELTA *DeltaData;\r
160\r
161 DefaultId = *(UINT16 *) TokenData;\r
162 SkuId = GetPcdDatabase()->SystemSkuId;\r
163 IsFound = FALSE;\r
164\r
165 if (PeiPcdGetSizeEx (&gEfiMdeModulePkgTokenSpaceGuid, PcdToken (PcdNvStoreDefaultValueBuffer)) > sizeof (PCD_NV_STORE_DEFAULT_BUFFER_HEADER)) {\r
166 DataBuffer = (UINT8 *) PeiPcdGetPtrEx (&gEfiMdeModulePkgTokenSpaceGuid, PcdToken (PcdNvStoreDefaultValueBuffer));\r
167 FullSize = ((PCD_NV_STORE_DEFAULT_BUFFER_HEADER *) DataBuffer)->Length;\r
168 DataHeader = (PCD_DEFAULT_DATA *) (DataBuffer + sizeof (PCD_NV_STORE_DEFAULT_BUFFER_HEADER));\r
169 //\r
170 // The first section data includes NV storage default setting.\r
171 //\r
172 NvStoreBuffer = (VARIABLE_STORE_HEADER *) ((UINT8 *) DataHeader + sizeof (DataHeader->DataSize) + DataHeader->HeaderSize);\r
173 VarStoreHobData = (UINT8 *) BuildGuidHob (&NvStoreBuffer->Signature, NvStoreBuffer->Size);\r
174 ASSERT (VarStoreHobData != NULL);\r
175 CopyMem (VarStoreHobData, NvStoreBuffer, NvStoreBuffer->Size);\r
176 //\r
177 // Find the matched SkuId and DefaultId in the first section\r
178 //\r
179 DefaultInfo = &(DataHeader->DefaultInfo[0]);\r
180 BufferEnd = (UINT8 *) DataHeader + sizeof (DataHeader->DataSize) + DataHeader->HeaderSize;\r
181 while ((UINT8 *) DefaultInfo < BufferEnd) {\r
182 if (DefaultInfo->DefaultId == DefaultId && DefaultInfo->SkuId == SkuId) {\r
183 IsFound = TRUE;\r
184 break;\r
185 }\r
186 DefaultInfo ++;\r
187 }\r
188 //\r
189 // Find the matched SkuId and DefaultId in the remaining section\r
190 //\r
191 Index = sizeof (PCD_NV_STORE_DEFAULT_BUFFER_HEADER) + ((DataHeader->DataSize + 7) & (~7));\r
192 DataHeader = (PCD_DEFAULT_DATA *) (DataBuffer + Index);\r
193 while (!IsFound && Index < FullSize && DataHeader->DataSize != 0xFFFFFFFF) {\r
194 DefaultInfo = &(DataHeader->DefaultInfo[0]);\r
195 BufferEnd = (UINT8 *) DataHeader + sizeof (DataHeader->DataSize) + DataHeader->HeaderSize;\r
196 while ((UINT8 *) DefaultInfo < BufferEnd) {\r
197 if (DefaultInfo->DefaultId == DefaultId && DefaultInfo->SkuId == SkuId) {\r
198 IsFound = TRUE;\r
199 break;\r
200 }\r
201 DefaultInfo ++;\r
202 }\r
203 if (IsFound) {\r
204 DeltaData = (PCD_DATA_DELTA *) BufferEnd;\r
205 BufferEnd = (UINT8 *) DataHeader + DataHeader->DataSize;\r
206 while ((UINT8 *) DeltaData < BufferEnd) {\r
207 *(VarStoreHobData + DeltaData->Offset) = (UINT8) DeltaData->Value;\r
208 DeltaData ++;\r
209 }\r
210 break;\r
211 }\r
212 Index = (Index + DataHeader->DataSize + 7) & (~7) ;\r
213 DataHeader = (PCD_DEFAULT_DATA *) (DataBuffer + Index);\r
214 }\r
215 }\r
216\r
217 Status = PcdUnRegisterCallBackOnSet (\r
218 &gEfiMdeModulePkgTokenSpaceGuid,\r
219 PcdToken(PcdSetNvStoreDefaultId),\r
220 PcdSetNvStoreDefaultIdCallBack\r
221 );\r
222 ASSERT_EFI_ERROR (Status);\r
223}\r
224\r
7c736265
LG
225/**\r
226 Report Pei PCD database of all SKUs as Guid HOB so that DxePcd can access it.\r
227\r
228 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation\r
229 @param NotifyDescriptor Address of the notification descriptor data structure.\r
230 @param Ppi Address of the PPI that was installed.\r
231\r
232 @retval EFI_SUCCESS Successfully update the Boot records.\r
233**/\r
234EFI_STATUS\r
235EFIAPI\r
236EndOfPeiSignalPpiNotifyCallback (\r
237 IN EFI_PEI_SERVICES **PeiServices,\r
238 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,\r
239 IN VOID *Ppi\r
240 )\r
241{\r
242 PEI_PCD_DATABASE *Database;\r
243 EFI_BOOT_MODE BootMode;\r
244 EFI_STATUS Status;\r
245 UINTN Instance;\r
246 EFI_PEI_FV_HANDLE VolumeHandle;\r
247 EFI_PEI_FILE_HANDLE FileHandle;\r
248 VOID *PcdDb;\r
249 UINT32 Length;\r
250 PEI_PCD_DATABASE *PeiPcdDb;\r
251\r
252 Status = PeiServicesGetBootMode(&BootMode);\r
253 ASSERT_EFI_ERROR (Status);\r
254\r
255 //\r
256 // Don't need to report it on S3 boot.\r
257 //\r
258 if (BootMode == BOOT_ON_S3_RESUME) {\r
259 return EFI_SUCCESS;\r
260 }\r
261\r
262 PeiPcdDb = GetPcdDatabase();\r
263 if (PeiPcdDb->SystemSkuId != (SKU_ID) 0) {\r
264 //\r
265 // SkuId has been set. Don't need to report it to DXE phase.\r
266 //\r
267 return EFI_SUCCESS;\r
268 }\r
269\r
270 //\r
271 // Get full PCD database from PcdPeim FileHandle\r
272 //\r
273 Instance = 0;\r
274 FileHandle = NULL;\r
275 while (TRUE) {\r
276 //\r
277 // Traverse all firmware volume instances\r
278 //\r
279 Status = PeiServicesFfsFindNextVolume (Instance, &VolumeHandle);\r
280 //\r
281 // Error should not happen\r
282 //\r
283 ASSERT_EFI_ERROR (Status);\r
284\r
285 //\r
286 // Find PcdDb file from the beginning in this firmware volume.\r
287 //\r
288 FileHandle = NULL;\r
289 Status = PeiServicesFfsFindFileByName (&gEfiCallerIdGuid, VolumeHandle, &FileHandle);\r
290 if (!EFI_ERROR (Status)) {\r
291 //\r
292 // Find PcdPeim FileHandle in this volume\r
293 //\r
294 break;\r
295 }\r
296 //\r
297 // We cannot find PcdPeim in this firmware volume, then search the next volume.\r
298 //\r
299 Instance++;\r
300 }\r
301\r
302 //\r
303 // Find PEI PcdDb and Build second PcdDB GuidHob\r
304 //\r
305 Status = PeiServicesFfsFindSectionData (EFI_SECTION_RAW, FileHandle, &PcdDb);\r
306 ASSERT_EFI_ERROR (Status);\r
307 Length = PeiPcdDb->LengthForAllSkus;\r
308 Database = BuildGuidHob (&gPcdDataBaseHobGuid, Length);\r
309 CopyMem (Database, PcdDb, Length);\r
310\r
311 return EFI_SUCCESS;\r
312}\r
313\r
314EFI_PEI_NOTIFY_DESCRIPTOR mEndOfPeiSignalPpiNotifyList[] = {\r
315 {\r
316 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
317 &gEfiEndOfPeiSignalPpiGuid,\r
318 EndOfPeiSignalPpiNotifyCallback\r
319 }\r
320};\r
321\r
fc547e08 322/**\r
323 Main entry for PCD PEIM driver.\r
d1102dba 324\r
8a541f0a 325 This routine initialize the PCD database for PEI phase and install PCD_PPI/EFI_PEI_PCD_PPI.\r
80408db0 326\r
8bd22b8a
LG
327 @param FileHandle Handle of the file being invoked.\r
328 @param PeiServices Describes the list of possible PEI Services.\r
80408db0 329\r
fc547e08 330 @return Status of install PCD_PPI\r
331\r
332**/\r
80408db0 333EFI_STATUS\r
334EFIAPI\r
335PcdPeimInit (\r
8bd22b8a
LG
336 IN EFI_PEI_FILE_HANDLE FileHandle,\r
337 IN CONST EFI_PEI_SERVICES **PeiServices\r
80408db0 338 )\r
339{\r
a78d3a27 340 EFI_STATUS Status;\r
96d6d004 341\r
6fdd1c13
YG
342 Status = PeiServicesRegisterForShadow (FileHandle);\r
343 if (Status == EFI_ALREADY_STARTED) {\r
344 //\r
345 // This is now starting in memory, the second time starting.\r
346 //\r
347 EFI_PEI_PPI_DESCRIPTOR *OldPpiList;\r
348 EFI_PEI_PPI_DESCRIPTOR *OldPpiList2;\r
349 VOID *Ppi;\r
350 VOID *Ppi2;\r
351\r
352 OldPpiList = NULL;\r
353 Status = PeiServicesLocatePpi (\r
354 &gPcdPpiGuid,\r
355 0,\r
356 &OldPpiList,\r
357 &Ppi\r
358 );\r
359 ASSERT_EFI_ERROR (Status);\r
360\r
361 if (OldPpiList != NULL) {\r
362 Status = PeiServicesReInstallPpi (OldPpiList, &mPpiList[0]);\r
363 ASSERT_EFI_ERROR (Status);\r
364 }\r
365\r
366 OldPpiList2 = NULL;\r
367 Status = PeiServicesLocatePpi (\r
368 &gGetPcdInfoPpiGuid,\r
369 0,\r
370 &OldPpiList2,\r
371 &Ppi2\r
372 );\r
373 ASSERT_EFI_ERROR (Status);\r
374\r
375 if (OldPpiList2 != NULL) {\r
376 Status = PeiServicesReInstallPpi (OldPpiList2, &mPpiList2[0]);\r
377 ASSERT_EFI_ERROR (Status);\r
378 }\r
379\r
380 OldPpiList = NULL;\r
381 Status = PeiServicesLocatePpi (\r
382 &gEfiPeiPcdPpiGuid,\r
383 0,\r
384 &OldPpiList,\r
385 &Ppi\r
386 );\r
387 ASSERT_EFI_ERROR (Status);\r
388\r
389 if (OldPpiList != NULL) {\r
390 Status = PeiServicesReInstallPpi (OldPpiList, &mPpiList[1]);\r
391 ASSERT_EFI_ERROR (Status);\r
392 }\r
393\r
394 OldPpiList2 = NULL;\r
395 Status = PeiServicesLocatePpi (\r
396 &gEfiGetPcdInfoPpiGuid,\r
397 0,\r
398 &OldPpiList2,\r
399 &Ppi2\r
400 );\r
401 ASSERT_EFI_ERROR (Status);\r
402\r
403 if (OldPpiList2 != NULL) {\r
404 Status = PeiServicesReInstallPpi (OldPpiList2, &mPpiList2[1]);\r
405 ASSERT_EFI_ERROR (Status);\r
406 }\r
407\r
408 return Status;\r
409 }\r
410\r
a78d3a27 411 BuildPcdDatabase (FileHandle);\r
80408db0 412\r
8a541f0a 413 //\r
17e7fa8f 414 // Install PCD_PPI and EFI_PEI_PCD_PPI.\r
8a541f0a 415 //\r
17e7fa8f 416 Status = PeiServicesInstallPpi (&mPpiList[0]);\r
8a541f0a 417 ASSERT_EFI_ERROR (Status);\r
96d6d004
SZ
418\r
419 //\r
85d0b97d 420 // Install GET_PCD_INFO_PPI and EFI_GET_PCD_INFO_PPI.\r
96d6d004 421 //\r
85d0b97d
SZ
422 Status = PeiServicesInstallPpi (&mPpiList2[0]);\r
423 ASSERT_EFI_ERROR (Status);\r
96d6d004 424\r
7c736265
LG
425 Status = PeiServicesNotifyPpi (&mEndOfPeiSignalPpiNotifyList[0]);\r
426 ASSERT_EFI_ERROR (Status);\r
427\r
219247e1
LG
428 Status = PeiRegisterCallBackOnSet (\r
429 &gEfiMdeModulePkgTokenSpaceGuid,\r
430 PcdToken(PcdSetNvStoreDefaultId),\r
431 PcdSetNvStoreDefaultIdCallBack\r
432 );\r
433 ASSERT_EFI_ERROR (Status);\r
434\r
8a541f0a 435 return Status;\r
80408db0 436}\r
437\r
96d6d004
SZ
438/**\r
439 Retrieve additional information associated with a PCD token in the default token space.\r
440\r
441 This includes information such as the type of value the TokenNumber is associated with as well as possible\r
442 human readable name that is associated with the token.\r
443\r
444 @param[in] TokenNumber The PCD token number.\r
445 @param[out] PcdInfo The returned information associated with the requested TokenNumber.\r
446 The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.\r
447\r
448 @retval EFI_SUCCESS The PCD information was returned successfully.\r
449 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.\r
450**/\r
451EFI_STATUS\r
452EFIAPI\r
453PeiGetPcdInfoGetInfo (\r
454 IN UINTN TokenNumber,\r
455 OUT EFI_PCD_INFO *PcdInfo\r
456 )\r
457{\r
458 return PeiGetPcdInfo (NULL, TokenNumber, PcdInfo);\r
459}\r
460\r
461/**\r
462 Retrieve additional information associated with a PCD token.\r
463\r
464 This includes information such as the type of value the TokenNumber is associated with as well as possible\r
465 human readable name that is associated with the token.\r
466\r
467 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.\r
468 @param[in] TokenNumber The PCD token number.\r
469 @param[out] PcdInfo The returned information associated with the requested TokenNumber.\r
470 The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.\r
471\r
472 @retval EFI_SUCCESS The PCD information was returned successfully.\r
473 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.\r
474**/\r
475EFI_STATUS\r
476EFIAPI\r
477PeiGetPcdInfoGetInfoEx (\r
478 IN CONST EFI_GUID *Guid,\r
479 IN UINTN TokenNumber,\r
480 OUT EFI_PCD_INFO *PcdInfo\r
481 )\r
482{\r
483 return PeiGetPcdInfo (Guid, TokenNumber, PcdInfo);\r
484}\r
485\r
486/**\r
487 Retrieve the currently set SKU Id.\r
488\r
489 @return The currently set SKU Id. If the platform has not set at a SKU Id, then the\r
490 default SKU Id value of 0 is returned. If the platform has set a SKU Id, then the currently set SKU\r
491 Id is returned.\r
492**/\r
493UINTN\r
494EFIAPI\r
495PeiGetPcdInfoGetSku (\r
496 VOID\r
497 )\r
498{\r
b6e89910 499 return (UINTN) GetPcdDatabase()->SystemSkuId;\r
96d6d004
SZ
500}\r
501\r
fc547e08 502/**\r
503 Sets the SKU value for subsequent calls to set or get PCD token values.\r
504\r
d1102dba 505 SetSku() sets the SKU Id to be used for subsequent calls to set or get PCD values.\r
fc547e08 506 SetSku() is normally called only once by the system.\r
507\r
d1102dba
LG
508 For each item (token), the database can hold a single value that applies to all SKUs,\r
509 or multiple values, where each value is associated with a specific SKU Id. Items with multiple,\r
510 SKU-specific values are called SKU enabled.\r
511\r
120ca3ce 512 The SKU Id of zero is reserved as a default.\r
d1102dba
LG
513 For tokens that are not SKU enabled, the system ignores any set SKU Id and works with the\r
514 single value for that token. For SKU-enabled tokens, the system will use the SKU Id set by the\r
515 last call to SetSku(). If no SKU Id is set or the currently set SKU Id isn't valid for the specified token,\r
516 the system uses the default SKU Id. If the system attempts to use the default SKU Id and no value has been\r
fc547e08 517 set for that Id, the results are unpredictable.\r
518\r
d1102dba 519 @param[in] SkuId The SKU value that will be used when the PCD service will retrieve and\r
fc547e08 520 set values associated with a PCD token.\r
521\r
fc547e08 522**/\r
80408db0 523VOID\r
524EFIAPI\r
525PeiPcdSetSku (\r
526 IN UINTN SkuId\r
527 )\r
528{\r
85d0b97d
SZ
529 PEI_PCD_DATABASE *PeiPcdDb;\r
530 SKU_ID *SkuIdTable;\r
531 UINTN Index;\r
7c736265
LG
532 EFI_STATUS Status;\r
533 UINTN Instance;\r
534 EFI_PEI_FV_HANDLE VolumeHandle;\r
535 EFI_PEI_FILE_HANDLE FileHandle;\r
536 VOID *PcdDb;\r
537 UINT32 Length;\r
538 PCD_DATABASE_SKU_DELTA *SkuDelta;\r
539 PCD_DATA_DELTA *SkuDeltaData;\r
85d0b97d 540\r
f71503c3
LG
541 DEBUG ((DEBUG_INFO, "PcdPei - SkuId 0x%lx is to be set.\n", (SKU_ID) SkuId));\r
542\r
85d0b97d 543 PeiPcdDb = GetPcdDatabase();\r
2db48a1f
SZ
544\r
545 if (SkuId == PeiPcdDb->SystemSkuId) {\r
546 //\r
547 // The input SKU Id is equal to current SKU Id, return directly.\r
548 //\r
f71503c3 549 DEBUG ((DEBUG_INFO, "PcdPei - SkuId is same to current system Sku.\n"));\r
2db48a1f
SZ
550 return;\r
551 }\r
552\r
553 if (PeiPcdDb->SystemSkuId != (SKU_ID) 0) {\r
554 DEBUG ((DEBUG_ERROR, "PcdPei - The SKU Id could be changed only once."));\r
555 DEBUG ((\r
556 DEBUG_ERROR,\r
557 "PcdPei - The SKU Id was set to 0x%lx already, it could not be set to 0x%lx any more.",\r
558 PeiPcdDb->SystemSkuId,\r
559 (SKU_ID) SkuId\r
560 ));\r
561 ASSERT (FALSE);\r
562 return;\r
563 }\r
564\r
85d0b97d
SZ
565 SkuIdTable = (SKU_ID *) ((UINT8 *) PeiPcdDb + PeiPcdDb->SkuIdTableOffset);\r
566 for (Index = 0; Index < SkuIdTable[0]; Index++) {\r
567 if (SkuId == SkuIdTable[Index + 1]) {\r
f71503c3 568 DEBUG ((DEBUG_INFO, "PcdPei - SkuId is found in SkuId table.\n"));\r
7c736265
LG
569 break;\r
570 }\r
571 }\r
572\r
573 if (Index < SkuIdTable[0]) {\r
574 //\r
575 // Get full PCD database from PcdPeim FileHandle\r
576 //\r
577 Instance = 0;\r
578 FileHandle = NULL;\r
579 while (TRUE) {\r
580 //\r
581 // Traverse all firmware volume instances\r
582 //\r
583 Status = PeiServicesFfsFindNextVolume (Instance, &VolumeHandle);\r
584 //\r
585 // Error should not happen\r
586 //\r
587 ASSERT_EFI_ERROR (Status);\r
588\r
589 //\r
590 // Find PcdDb file from the beginning in this firmware volume.\r
591 //\r
592 FileHandle = NULL;\r
593 Status = PeiServicesFfsFindFileByName (&gEfiCallerIdGuid, VolumeHandle, &FileHandle);\r
594 if (!EFI_ERROR (Status)) {\r
595 //\r
596 // Find PcdPeim FileHandle in this volume\r
597 //\r
598 break;\r
599 }\r
600 //\r
601 // We cannot find PcdPeim in this firmware volume, then search the next volume.\r
602 //\r
603 Instance++;\r
604 }\r
605\r
606 //\r
607 // Find the delta data between the different Skus\r
608 //\r
609 Status = PeiServicesFfsFindSectionData (EFI_SECTION_RAW, FileHandle, &PcdDb);\r
610 ASSERT_EFI_ERROR (Status);\r
611 Length = PeiPcdDb->LengthForAllSkus;\r
612 Index = (PeiPcdDb->Length + 7) & (~7);\r
613 SkuDelta = NULL;\r
614 while (Index < Length) {\r
615 SkuDelta = (PCD_DATABASE_SKU_DELTA *) ((UINT8 *) PcdDb + Index);\r
616 if (SkuDelta->SkuId == SkuId && SkuDelta->SkuIdCompared == 0) {\r
617 break;\r
618 }\r
619 Index = (Index + SkuDelta->Length + 7) & (~7);\r
620 }\r
621\r
622 //\r
623 // Patch the delta data into current PCD database\r
624 //\r
625 if (Index < Length && SkuDelta != NULL) {\r
626 SkuDeltaData = (PCD_DATA_DELTA *) (SkuDelta + 1);\r
627 while ((UINT8 *) SkuDeltaData < (UINT8 *) SkuDelta + SkuDelta->Length) {\r
628 *((UINT8 *) PeiPcdDb + SkuDeltaData->Offset) = (UINT8) SkuDeltaData->Value;\r
629 SkuDeltaData ++;\r
630 }\r
85d0b97d 631 PeiPcdDb->SystemSkuId = (SKU_ID) SkuId;\r
7c736265 632 DEBUG ((DEBUG_INFO, "PcdPei - Set current SKU Id to 0x%lx.\n", (SKU_ID) SkuId));\r
85d0b97d
SZ
633 return;\r
634 }\r
635 }\r
80408db0 636\r
85d0b97d 637 //\r
2db48a1f 638 // Invalid input SkuId, the default SKU Id will be still used for the system.\r
85d0b97d 639 //\r
f71503c3 640 DEBUG ((DEBUG_ERROR, "PcdPei - Invalid input SkuId, the default SKU Id will be still used.\n"));\r
7c736265 641\r
80408db0 642 return;\r
643}\r
644\r
fc547e08 645/**\r
646 Retrieves an 8-bit value for a given PCD token.\r
80408db0 647\r
d1102dba 648 Retrieves the current byte-sized value for a PCD token number.\r
fc547e08 649 If the TokenNumber is invalid, the results are unpredictable.\r
d1102dba
LG
650\r
651 @param[in] TokenNumber The PCD token number.\r
80408db0 652\r
fc547e08 653 @return The UINT8 value.\r
d1102dba 654\r
fc547e08 655**/\r
80408db0 656UINT8\r
657EFIAPI\r
658PeiPcdGet8 (\r
659 IN UINTN TokenNumber\r
660 )\r
661{\r
662 return *((UINT8 *) GetWorker (TokenNumber, sizeof (UINT8)));\r
663}\r
664\r
fc547e08 665/**\r
666 Retrieves an 16-bit value for a given PCD token.\r
80408db0 667\r
d1102dba 668 Retrieves the current 16-bits value for a PCD token number.\r
fc547e08 669 If the TokenNumber is invalid, the results are unpredictable.\r
d1102dba
LG
670\r
671 @param[in] TokenNumber The PCD token number.\r
80408db0 672\r
fc547e08 673 @return The UINT16 value.\r
d1102dba 674\r
fc547e08 675**/\r
80408db0 676UINT16\r
677EFIAPI\r
678PeiPcdGet16 (\r
679 IN UINTN TokenNumber\r
680 )\r
681{\r
682 return ReadUnaligned16 (GetWorker (TokenNumber, sizeof (UINT16)));\r
683}\r
684\r
fc547e08 685/**\r
686 Retrieves an 32-bit value for a given PCD token.\r
80408db0 687\r
d1102dba 688 Retrieves the current 32-bits value for a PCD token number.\r
fc547e08 689 If the TokenNumber is invalid, the results are unpredictable.\r
d1102dba
LG
690\r
691 @param[in] TokenNumber The PCD token number.\r
80408db0 692\r
fc547e08 693 @return The UINT32 value.\r
d1102dba 694\r
fc547e08 695**/\r
80408db0 696UINT32\r
697EFIAPI\r
698PeiPcdGet32 (\r
699 IN UINTN TokenNumber\r
700 )\r
701{\r
702 return ReadUnaligned32 (GetWorker (TokenNumber, sizeof (UINT32)));\r
703}\r
704\r
fc547e08 705/**\r
706 Retrieves an 64-bit value for a given PCD token.\r
80408db0 707\r
d1102dba 708 Retrieves the current 64-bits value for a PCD token number.\r
fc547e08 709 If the TokenNumber is invalid, the results are unpredictable.\r
d1102dba
LG
710\r
711 @param[in] TokenNumber The PCD token number.\r
80408db0 712\r
fc547e08 713 @return The UINT64 value.\r
d1102dba 714\r
fc547e08 715**/\r
80408db0 716UINT64\r
717EFIAPI\r
718PeiPcdGet64 (\r
719 IN UINTN TokenNumber\r
720 )\r
721{\r
722 return ReadUnaligned64 (GetWorker (TokenNumber, sizeof (UINT64)));\r
723}\r
724\r
fc547e08 725/**\r
726 Retrieves a pointer to a value for a given PCD token.\r
727\r
d1102dba
LG
728 Retrieves the current pointer to the buffer for a PCD token number.\r
729 Do not make any assumptions about the alignment of the pointer that\r
730 is returned by this function call. If the TokenNumber is invalid,\r
fc547e08 731 the results are unpredictable.\r
80408db0 732\r
d1102dba 733 @param[in] TokenNumber The PCD token number.\r
80408db0 734\r
3fd8027e 735 @return The pointer to the buffer to be retrieved.\r
d1102dba 736\r
fc547e08 737**/\r
80408db0 738VOID *\r
739EFIAPI\r
740PeiPcdGetPtr (\r
741 IN UINTN TokenNumber\r
742 )\r
743{\r
744 return GetWorker (TokenNumber, 0);\r
745}\r
746\r
fc547e08 747/**\r
748 Retrieves a Boolean value for a given PCD token.\r
80408db0 749\r
d1102dba
LG
750 Retrieves the current boolean value for a PCD token number.\r
751 Do not make any assumptions about the alignment of the pointer that\r
752 is returned by this function call. If the TokenNumber is invalid,\r
fc547e08 753 the results are unpredictable.\r
80408db0 754\r
d1102dba 755 @param[in] TokenNumber The PCD token number.\r
fc547e08 756\r
757 @return The Boolean value.\r
d1102dba 758\r
fc547e08 759**/\r
80408db0 760BOOLEAN\r
761EFIAPI\r
762PeiPcdGetBool (\r
763 IN UINTN TokenNumber\r
764 )\r
765{\r
766 return *((BOOLEAN *) GetWorker (TokenNumber, sizeof (BOOLEAN)));\r
767}\r
768\r
fc547e08 769/**\r
770 Retrieves the size of the value for a given PCD token.\r
771\r
d1102dba 772 Retrieves the current size of a particular PCD token.\r
fc547e08 773 If the TokenNumber is invalid, the results are unpredictable.\r
80408db0 774\r
d1102dba 775 @param[in] TokenNumber The PCD token number.\r
80408db0 776\r
fc547e08 777 @return The size of the value for the PCD token.\r
d1102dba 778\r
fc547e08 779**/\r
80408db0 780UINTN\r
781EFIAPI\r
782PeiPcdGetSize (\r
783 IN UINTN TokenNumber\r
784 )\r
785{\r
786 PEI_PCD_DATABASE *PeiPcdDb;\r
787 UINTN Size;\r
788 UINTN MaxSize;\r
419db80b 789 UINT32 LocalTokenCount;\r
80408db0 790\r
419db80b
BF
791 PeiPcdDb = GetPcdDatabase ();\r
792 LocalTokenCount = PeiPcdDb->LocalTokenCount;\r
80408db0 793 //\r
794 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
795 // We have to decrement TokenNumber by 1 to make it usable\r
796 // as the array index.\r
797 //\r
798 TokenNumber--;\r
799\r
800 // EBC compiler is very choosy. It may report warning about comparison\r
d1102dba 801 // between UINTN and 0 . So we add 1 in each size of the\r
80408db0 802 // comparison.\r
419db80b 803 ASSERT (TokenNumber + 1 < (LocalTokenCount + 1));\r
80408db0 804\r
419db80b 805 Size = (*((UINT32 *)((UINT8 *)PeiPcdDb + PeiPcdDb->LocalTokenNumberTableOffset) + TokenNumber) & PCD_DATUM_TYPE_ALL_SET) >> PCD_DATUM_TYPE_SHIFT;\r
80408db0 806\r
807 if (Size == 0) {\r
808 //\r
809 // For pointer type, we need to scan the SIZE_TABLE to get the current size.\r
810 //\r
811 return GetPtrTypeSize (TokenNumber, &MaxSize, PeiPcdDb);\r
812 } else {\r
813 return Size;\r
814 }\r
815\r
816}\r
817\r
fc547e08 818/**\r
819 Retrieves an 8-bit value for a given PCD token.\r
80408db0 820\r
d1102dba 821 Retrieves the 8-bit value of a particular PCD token.\r
fc547e08 822 If the TokenNumber is invalid or the token space\r
d1102dba 823 specified by Guid does not exist, the results are\r
fc547e08 824 unpredictable.\r
80408db0 825\r
fc547e08 826 @param[in] Guid The token space for the token number.\r
d1102dba 827 @param[in] ExTokenNumber The PCD token number.\r
fc547e08 828\r
829 @return The size 8-bit value for the PCD token.\r
d1102dba 830\r
fc547e08 831**/\r
80408db0 832UINT8\r
833EFIAPI\r
834PeiPcdGet8Ex (\r
835 IN CONST EFI_GUID *Guid,\r
836 IN UINTN ExTokenNumber\r
837 )\r
838{\r
839 return *((UINT8 *) ExGetWorker (Guid, ExTokenNumber, sizeof (UINT8)));\r
840}\r
841\r
fc547e08 842/**\r
843 Retrieves an 16-bit value for a given PCD token.\r
80408db0 844\r
d1102dba 845 Retrieves the 16-bit value of a particular PCD token.\r
fc547e08 846 If the TokenNumber is invalid or the token space\r
d1102dba 847 specified by Guid does not exist, the results are\r
fc547e08 848 unpredictable.\r
80408db0 849\r
fc547e08 850 @param[in] Guid The token space for the token number.\r
d1102dba 851 @param[in] ExTokenNumber The PCD token number.\r
fc547e08 852\r
853 @return The size 16-bit value for the PCD token.\r
d1102dba 854\r
fc547e08 855**/\r
80408db0 856UINT16\r
857EFIAPI\r
858PeiPcdGet16Ex (\r
859 IN CONST EFI_GUID *Guid,\r
860 IN UINTN ExTokenNumber\r
861 )\r
862{\r
863 return ReadUnaligned16 (ExGetWorker (Guid, ExTokenNumber, sizeof (UINT16)));\r
864}\r
865\r
fc547e08 866/**\r
867 Retrieves an 32-bit value for a given PCD token.\r
868\r
d1102dba 869 Retrieves the 32-bit value of a particular PCD token.\r
fc547e08 870 If the TokenNumber is invalid or the token space\r
d1102dba 871 specified by Guid does not exist, the results are\r
fc547e08 872 unpredictable.\r
80408db0 873\r
fc547e08 874 @param[in] Guid The token space for the token number.\r
d1102dba 875 @param[in] ExTokenNumber The PCD token number.\r
80408db0 876\r
fc547e08 877 @return The size 32-bit value for the PCD token.\r
d1102dba 878\r
fc547e08 879**/\r
80408db0 880UINT32\r
881EFIAPI\r
882PeiPcdGet32Ex (\r
883 IN CONST EFI_GUID *Guid,\r
884 IN UINTN ExTokenNumber\r
885 )\r
886{\r
887 return ReadUnaligned32 (ExGetWorker (Guid, ExTokenNumber, sizeof (UINT32)));\r
888}\r
889\r
fc547e08 890/**\r
891 Retrieves an 64-bit value for a given PCD token.\r
892\r
d1102dba 893 Retrieves the 64-bit value of a particular PCD token.\r
fc547e08 894 If the TokenNumber is invalid or the token space\r
d1102dba 895 specified by Guid does not exist, the results are\r
fc547e08 896 unpredictable.\r
80408db0 897\r
fc547e08 898 @param[in] Guid The token space for the token number.\r
d1102dba 899 @param[in] ExTokenNumber The PCD token number.\r
80408db0 900\r
fc547e08 901 @return The size 64-bit value for the PCD token.\r
d1102dba 902\r
fc547e08 903**/\r
80408db0 904UINT64\r
905EFIAPI\r
906PeiPcdGet64Ex (\r
907 IN CONST EFI_GUID *Guid,\r
908 IN UINTN ExTokenNumber\r
909 )\r
910{\r
911 return ReadUnaligned64 (ExGetWorker (Guid, ExTokenNumber, sizeof (UINT64)));\r
912}\r
913\r
fc547e08 914/**\r
915 Retrieves a pointer to a value for a given PCD token.\r
80408db0 916\r
d1102dba
LG
917 Retrieves the current pointer to the buffer for a PCD token number.\r
918 Do not make any assumptions about the alignment of the pointer that\r
919 is returned by this function call. If the TokenNumber is invalid,\r
fc547e08 920 the results are unpredictable.\r
80408db0 921\r
fc547e08 922 @param[in] Guid The token space for the token number.\r
d1102dba 923 @param[in] ExTokenNumber The PCD token number.\r
fc547e08 924\r
3fd8027e 925 @return The pointer to the buffer to be retrieved.\r
d1102dba 926\r
fc547e08 927**/\r
80408db0 928VOID *\r
929EFIAPI\r
930PeiPcdGetPtrEx (\r
931 IN CONST EFI_GUID *Guid,\r
932 IN UINTN ExTokenNumber\r
933 )\r
934{\r
935 return ExGetWorker (Guid, ExTokenNumber, 0);\r
936}\r
937\r
fc547e08 938/**\r
939 Retrieves an Boolean value for a given PCD token.\r
940\r
d1102dba 941 Retrieves the Boolean value of a particular PCD token.\r
fc547e08 942 If the TokenNumber is invalid or the token space\r
d1102dba 943 specified by Guid does not exist, the results are\r
fc547e08 944 unpredictable.\r
80408db0 945\r
fc547e08 946 @param[in] Guid The token space for the token number.\r
d1102dba 947 @param[in] ExTokenNumber The PCD token number.\r
80408db0 948\r
fc547e08 949 @return The size Boolean value for the PCD token.\r
d1102dba 950\r
fc547e08 951**/\r
80408db0 952BOOLEAN\r
953EFIAPI\r
954PeiPcdGetBoolEx (\r
955 IN CONST EFI_GUID *Guid,\r
956 IN UINTN ExTokenNumber\r
957 )\r
958{\r
959 return *((BOOLEAN *) ExGetWorker (Guid, ExTokenNumber, sizeof (BOOLEAN)));\r
960}\r
961\r
fc547e08 962/**\r
963 Retrieves the size of the value for a given PCD token.\r
964\r
d1102dba 965 Retrieves the current size of a particular PCD token.\r
fc547e08 966 If the TokenNumber is invalid, the results are unpredictable.\r
80408db0 967\r
fc547e08 968 @param[in] Guid The token space for the token number.\r
d1102dba 969 @param[in] ExTokenNumber The PCD token number.\r
80408db0 970\r
fc547e08 971 @return The size of the value for the PCD token.\r
d1102dba 972\r
fc547e08 973**/\r
80408db0 974UINTN\r
975EFIAPI\r
976PeiPcdGetSizeEx (\r
977 IN CONST EFI_GUID *Guid,\r
978 IN UINTN ExTokenNumber\r
979 )\r
980{\r
80408db0 981 return PeiPcdGetSize (GetExPcdTokenNumber (Guid, ExTokenNumber));\r
982}\r
983\r
fc547e08 984/**\r
985 Sets an 8-bit value for a given PCD token.\r
80408db0 986\r
d1102dba
LG
987 When the PCD service sets a value, it will check to ensure that the\r
988 size of the value being set is compatible with the Token's existing definition.\r
fc547e08 989 If it is not, an error will be returned.\r
80408db0 990\r
d1102dba 991 @param[in] TokenNumber The PCD token number.\r
fc547e08 992 @param[in] Value The value to set for the PCD token.\r
993\r
994 @retval EFI_SUCCESS Procedure returned successfully.\r
d1102dba
LG
995 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data\r
996 being set was incompatible with a call to this function.\r
fc547e08 997 Use GetSize() to retrieve the size of the target data.\r
998 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.\r
d1102dba 999\r
fc547e08 1000**/\r
80408db0 1001EFI_STATUS\r
1002EFIAPI\r
1003PeiPcdSet8 (\r
1004 IN UINTN TokenNumber,\r
1005 IN UINT8 Value\r
1006 )\r
1007{\r
1008 return SetValueWorker (TokenNumber, &Value, sizeof (Value));\r
1009}\r
1010\r
fc547e08 1011/**\r
1012 Sets an 16-bit value for a given PCD token.\r
1013\r
d1102dba
LG
1014 When the PCD service sets a value, it will check to ensure that the\r
1015 size of the value being set is compatible with the Token's existing definition.\r
fc547e08 1016 If it is not, an error will be returned.\r
80408db0 1017\r
d1102dba 1018 @param[in] TokenNumber The PCD token number.\r
fc547e08 1019 @param[in] Value The value to set for the PCD token.\r
80408db0 1020\r
fc547e08 1021 @retval EFI_SUCCESS Procedure returned successfully.\r
d1102dba
LG
1022 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data\r
1023 being set was incompatible with a call to this function.\r
fc547e08 1024 Use GetSize() to retrieve the size of the target data.\r
1025 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.\r
d1102dba 1026\r
fc547e08 1027**/\r
80408db0 1028EFI_STATUS\r
1029EFIAPI\r
1030PeiPcdSet16 (\r
1031 IN UINTN TokenNumber,\r
1032 IN UINT16 Value\r
1033 )\r
1034{\r
1035 return SetValueWorker (TokenNumber, &Value, sizeof (Value));\r
1036}\r
1037\r
fc547e08 1038/**\r
1039 Sets an 32-bit value for a given PCD token.\r
80408db0 1040\r
d1102dba
LG
1041 When the PCD service sets a value, it will check to ensure that the\r
1042 size of the value being set is compatible with the Token's existing definition.\r
fc547e08 1043 If it is not, an error will be returned.\r
80408db0 1044\r
d1102dba 1045 @param[in] TokenNumber The PCD token number.\r
fc547e08 1046 @param[in] Value The value to set for the PCD token.\r
1047\r
1048 @retval EFI_SUCCESS Procedure returned successfully.\r
d1102dba
LG
1049 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data\r
1050 being set was incompatible with a call to this function.\r
fc547e08 1051 Use GetSize() to retrieve the size of the target data.\r
1052 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.\r
d1102dba 1053\r
fc547e08 1054**/\r
80408db0 1055EFI_STATUS\r
1056EFIAPI\r
1057PeiPcdSet32 (\r
1058 IN UINTN TokenNumber,\r
1059 IN UINT32 Value\r
1060 )\r
1061{\r
1062 return SetValueWorker (TokenNumber, &Value, sizeof (Value));\r
1063}\r
1064\r
fc547e08 1065/**\r
1066 Sets an 64-bit value for a given PCD token.\r
1067\r
d1102dba
LG
1068 When the PCD service sets a value, it will check to ensure that the\r
1069 size of the value being set is compatible with the Token's existing definition.\r
fc547e08 1070 If it is not, an error will be returned.\r
80408db0 1071\r
d1102dba 1072 @param[in] TokenNumber The PCD token number.\r
fc547e08 1073 @param[in] Value The value to set for the PCD token.\r
80408db0 1074\r
fc547e08 1075 @retval EFI_SUCCESS Procedure returned successfully.\r
d1102dba
LG
1076 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data\r
1077 being set was incompatible with a call to this function.\r
fc547e08 1078 Use GetSize() to retrieve the size of the target data.\r
1079 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.\r
d1102dba 1080\r
fc547e08 1081**/\r
80408db0 1082EFI_STATUS\r
1083EFIAPI\r
1084PeiPcdSet64 (\r
1085 IN UINTN TokenNumber,\r
1086 IN UINT64 Value\r
1087 )\r
1088{\r
1089 return SetValueWorker (TokenNumber, &Value, sizeof (Value));\r
1090}\r
1091\r
fc547e08 1092/**\r
1093 Sets a value of a specified size for a given PCD token.\r
1094\r
d1102dba
LG
1095 When the PCD service sets a value, it will check to ensure that the\r
1096 size of the value being set is compatible with the Token's existing definition.\r
fc547e08 1097 If it is not, an error will be returned.\r
1098\r
d1102dba
LG
1099 @param[in] TokenNumber The PCD token number.\r
1100 @param[in, out] SizeOfBuffer A pointer to the length of the value being set for the PCD token.\r
1101 On input, if the SizeOfValue is greater than the maximum size supported\r
1102 for this TokenNumber then the output value of SizeOfValue will reflect\r
fc547e08 1103 the maximum size supported for this TokenNumber.\r
1104 @param[in] Buffer The buffer to set for the PCD token.\r
1105\r
1106 @retval EFI_SUCCESS Procedure returned successfully.\r
d1102dba
LG
1107 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data\r
1108 being set was incompatible with a call to this function.\r
fc547e08 1109 Use GetSize() to retrieve the size of the target data.\r
1110 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.\r
d1102dba 1111\r
fc547e08 1112**/\r
80408db0 1113EFI_STATUS\r
1114EFIAPI\r
1115PeiPcdSetPtr (\r
1116 IN UINTN TokenNumber,\r
1117 IN OUT UINTN *SizeOfBuffer,\r
1118 IN VOID *Buffer\r
1119 )\r
1120{\r
1121 return SetWorker (TokenNumber, Buffer, SizeOfBuffer, TRUE);\r
1122}\r
1123\r
fc547e08 1124/**\r
1125 Sets an Boolean value for a given PCD token.\r
80408db0 1126\r
d1102dba
LG
1127 When the PCD service sets a value, it will check to ensure that the\r
1128 size of the value being set is compatible with the Token's existing definition.\r
fc547e08 1129 If it is not, an error will be returned.\r
80408db0 1130\r
d1102dba 1131 @param[in] TokenNumber The PCD token number.\r
fc547e08 1132 @param[in] Value The value to set for the PCD token.\r
1133\r
1134 @retval EFI_SUCCESS Procedure returned successfully.\r
d1102dba
LG
1135 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data\r
1136 being set was incompatible with a call to this function.\r
fc547e08 1137 Use GetSize() to retrieve the size of the target data.\r
1138 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.\r
d1102dba 1139\r
fc547e08 1140**/\r
80408db0 1141EFI_STATUS\r
1142EFIAPI\r
1143PeiPcdSetBool (\r
1144 IN UINTN TokenNumber,\r
1145 IN BOOLEAN Value\r
1146 )\r
1147{\r
1148 return SetValueWorker (TokenNumber, &Value, sizeof (Value));\r
1149}\r
1150\r
fc547e08 1151/**\r
1152 Sets an 8-bit value for a given PCD token.\r
80408db0 1153\r
d1102dba
LG
1154 When the PCD service sets a value, it will check to ensure that the\r
1155 size of the value being set is compatible with the Token's existing definition.\r
fc547e08 1156 If it is not, an error will be returned.\r
80408db0 1157\r
fc547e08 1158 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.\r
d1102dba 1159 @param[in] ExTokenNumber The PCD token number.\r
fc547e08 1160 @param[in] Value The value to set for the PCD token.\r
1161\r
1162 @retval EFI_SUCCESS Procedure returned successfully.\r
d1102dba
LG
1163 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data\r
1164 being set was incompatible with a call to this function.\r
fc547e08 1165 Use GetSize() to retrieve the size of the target data.\r
1166 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.\r
d1102dba 1167\r
fc547e08 1168**/\r
80408db0 1169EFI_STATUS\r
1170EFIAPI\r
1171PeiPcdSet8Ex (\r
1172 IN CONST EFI_GUID *Guid,\r
1173 IN UINTN ExTokenNumber,\r
1174 IN UINT8 Value\r
1175 )\r
1176{\r
1177 return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value));\r
1178}\r
1179\r
fc547e08 1180/**\r
1181 Sets an 16-bit value for a given PCD token.\r
1182\r
d1102dba
LG
1183 When the PCD service sets a value, it will check to ensure that the\r
1184 size of the value being set is compatible with the Token's existing definition.\r
fc547e08 1185 If it is not, an error will be returned.\r
80408db0 1186\r
fc547e08 1187 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.\r
d1102dba 1188 @param[in] ExTokenNumber The PCD token number.\r
fc547e08 1189 @param[in] Value The value to set for the PCD token.\r
80408db0 1190\r
fc547e08 1191 @retval EFI_SUCCESS Procedure returned successfully.\r
d1102dba
LG
1192 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data\r
1193 being set was incompatible with a call to this function.\r
fc547e08 1194 Use GetSize() to retrieve the size of the target data.\r
1195 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.\r
d1102dba 1196\r
fc547e08 1197**/\r
80408db0 1198EFI_STATUS\r
1199EFIAPI\r
1200PeiPcdSet16Ex (\r
1201 IN CONST EFI_GUID *Guid,\r
1202 IN UINTN ExTokenNumber,\r
1203 IN UINT16 Value\r
1204 )\r
1205{\r
1206 return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value));\r
1207}\r
1208\r
fc547e08 1209/**\r
1210 Sets an 32-bit value for a given PCD token.\r
1211\r
d1102dba
LG
1212 When the PCD service sets a value, it will check to ensure that the\r
1213 size of the value being set is compatible with the Token's existing definition.\r
fc547e08 1214 If it is not, an error will be returned.\r
80408db0 1215\r
fc547e08 1216 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.\r
d1102dba 1217 @param[in] ExTokenNumber The PCD token number.\r
fc547e08 1218 @param[in] Value The value to set for the PCD token.\r
80408db0 1219\r
fc547e08 1220 @retval EFI_SUCCESS Procedure returned successfully.\r
d1102dba
LG
1221 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data\r
1222 being set was incompatible with a call to this function.\r
fc547e08 1223 Use GetSize() to retrieve the size of the target data.\r
1224 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.\r
d1102dba 1225\r
fc547e08 1226**/\r
80408db0 1227EFI_STATUS\r
1228EFIAPI\r
1229PeiPcdSet32Ex (\r
1230 IN CONST EFI_GUID *Guid,\r
1231 IN UINTN ExTokenNumber,\r
1232 IN UINT32 Value\r
1233 )\r
1234{\r
1235 return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value));\r
1236}\r
1237\r
fc547e08 1238/**\r
1239 Sets an 64-bit value for a given PCD token.\r
80408db0 1240\r
d1102dba
LG
1241 When the PCD service sets a value, it will check to ensure that the\r
1242 size of the value being set is compatible with the Token's existing definition.\r
fc547e08 1243 If it is not, an error will be returned.\r
80408db0 1244\r
fc547e08 1245 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.\r
d1102dba 1246 @param[in] ExTokenNumber The PCD token number.\r
fc547e08 1247 @param[in] Value The value to set for the PCD token.\r
1248\r
1249 @retval EFI_SUCCESS Procedure returned successfully.\r
d1102dba
LG
1250 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data\r
1251 being set was incompatible with a call to this function.\r
fc547e08 1252 Use GetSize() to retrieve the size of the target data.\r
1253 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.\r
d1102dba 1254\r
fc547e08 1255**/\r
80408db0 1256EFI_STATUS\r
1257EFIAPI\r
1258PeiPcdSet64Ex (\r
1259 IN CONST EFI_GUID *Guid,\r
1260 IN UINTN ExTokenNumber,\r
1261 IN UINT64 Value\r
1262 )\r
1263{\r
1264 return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value));\r
1265}\r
1266\r
fc547e08 1267/**\r
1268 Sets a value of a specified size for a given PCD token.\r
1269\r
d1102dba
LG
1270 When the PCD service sets a value, it will check to ensure that the\r
1271 size of the value being set is compatible with the Token's existing definition.\r
fc547e08 1272 If it is not, an error will be returned.\r
1273\r
1274 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.\r
d1102dba
LG
1275 @param[in] ExTokenNumber The PCD token number.\r
1276 @param[in, out] SizeOfBuffer A pointer to the length of the value being set for the PCD token.\r
1277 On input, if the SizeOfValue is greater than the maximum size supported\r
1278 for this TokenNumber then the output value of SizeOfValue will reflect\r
fc547e08 1279 the maximum size supported for this TokenNumber.\r
1280 @param[in] Value The buffer to set for the PCD token.\r
1281\r
1282 @retval EFI_SUCCESS Procedure returned successfully.\r
d1102dba
LG
1283 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data\r
1284 being set was incompatible with a call to this function.\r
fc547e08 1285 Use GetSize() to retrieve the size of the target data.\r
1286 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.\r
d1102dba 1287\r
fc547e08 1288**/\r
80408db0 1289EFI_STATUS\r
1290EFIAPI\r
1291PeiPcdSetPtrEx (\r
fc547e08 1292 IN CONST EFI_GUID *Guid,\r
1293 IN UINTN ExTokenNumber,\r
1294 IN OUT UINTN *SizeOfBuffer,\r
1295 IN VOID *Value\r
80408db0 1296 )\r
1297{\r
1298 return ExSetWorker (ExTokenNumber, Guid, Value, SizeOfBuffer, TRUE);\r
1299}\r
1300\r
fc547e08 1301/**\r
1302 Sets an Boolean value for a given PCD token.\r
1303\r
d1102dba
LG
1304 When the PCD service sets a value, it will check to ensure that the\r
1305 size of the value being set is compatible with the Token's existing definition.\r
fc547e08 1306 If it is not, an error will be returned.\r
80408db0 1307\r
fc547e08 1308 @param [in] Guid The 128-bit unique value that designates the namespace from which to extract the value.\r
d1102dba 1309 @param [in] ExTokenNumber The PCD token number.\r
fc547e08 1310 @param [in] Value The value to set for the PCD token.\r
80408db0 1311\r
fc547e08 1312 @retval EFI_SUCCESS Procedure returned successfully.\r
d1102dba
LG
1313 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data\r
1314 being set was incompatible with a call to this function.\r
fc547e08 1315 Use GetSize() to retrieve the size of the target data.\r
1316 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.\r
d1102dba 1317\r
fc547e08 1318**/\r
80408db0 1319EFI_STATUS\r
1320EFIAPI\r
1321PeiPcdSetBoolEx (\r
1322 IN CONST EFI_GUID *Guid,\r
1323 IN UINTN ExTokenNumber,\r
1324 IN BOOLEAN Value\r
1325 )\r
1326{\r
1327 return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value));\r
1328}\r
1329\r
fc547e08 1330/**\r
1331 Specifies a function to be called anytime the value of a designated token is changed.\r
80408db0 1332\r
fc547e08 1333 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.\r
d1102dba
LG
1334 @param[in] ExTokenNumber The PCD token number.\r
1335 @param[in] CallBackFunction The function prototype called when the value associated with the CallBackToken is set.\r
80408db0 1336\r
d1102dba 1337 @retval EFI_SUCCESS The PCD service has successfully established a call event\r
fc547e08 1338 for the CallBackToken requested.\r
1339 @retval EFI_NOT_FOUND The PCD service could not find the referenced token number.\r
80408db0 1340\r
fc547e08 1341**/\r
80408db0 1342EFI_STATUS\r
1343EFIAPI\r
1344PeiRegisterCallBackOnSet (\r
1345 IN CONST EFI_GUID *Guid, OPTIONAL\r
1346 IN UINTN ExTokenNumber,\r
1347 IN PCD_PPI_CALLBACK CallBackFunction\r
1348 )\r
1349{\r
f806dd27 1350 if (!FeaturePcdGet(PcdPeiFullPcdDatabaseEnable)) {\r
80408db0 1351 return EFI_UNSUPPORTED;\r
1352 }\r
1353\r
e4a3922f 1354 if (CallBackFunction == NULL) {\r
1355 return EFI_INVALID_PARAMETER;\r
1356 }\r
1357\r
80408db0 1358 return PeiRegisterCallBackWorker (ExTokenNumber, Guid, CallBackFunction, TRUE);\r
1359}\r
1360\r
fc547e08 1361/**\r
1362 Cancels a previously set callback function for a particular PCD token number.\r
80408db0 1363\r
fc547e08 1364 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.\r
d1102dba
LG
1365 @param[in] ExTokenNumber The PCD token number.\r
1366 @param[in] CallBackFunction The function prototype called when the value associated with the CallBackToken is set.\r
80408db0 1367\r
d1102dba 1368 @retval EFI_SUCCESS The PCD service has successfully established a call event\r
fc547e08 1369 for the CallBackToken requested.\r
1370 @retval EFI_NOT_FOUND The PCD service could not find the referenced token number.\r
1371\r
1372**/\r
80408db0 1373EFI_STATUS\r
1374EFIAPI\r
1375PcdUnRegisterCallBackOnSet (\r
1376 IN CONST EFI_GUID *Guid, OPTIONAL\r
1377 IN UINTN ExTokenNumber,\r
1378 IN PCD_PPI_CALLBACK CallBackFunction\r
1379 )\r
1380{\r
f806dd27 1381 if (!FeaturePcdGet(PcdPeiFullPcdDatabaseEnable)) {\r
80408db0 1382 return EFI_UNSUPPORTED;\r
1383 }\r
1384\r
e4a3922f 1385 if (CallBackFunction == NULL) {\r
1386 return EFI_INVALID_PARAMETER;\r
1387 }\r
1388\r
80408db0 1389 return PeiRegisterCallBackWorker (ExTokenNumber, Guid, CallBackFunction, FALSE);\r
1390}\r
1391\r
fc547e08 1392/**\r
d1102dba
LG
1393 Retrieves the next valid token number in a given namespace.\r
1394\r
1395 This is useful since the PCD infrastructure contains a sparse list of token numbers,\r
1396 and one cannot a priori know what token numbers are valid in the database.\r
1397\r
1398 If TokenNumber is 0 and Guid is not NULL, then the first token from the token space specified by Guid is returned.\r
1399 If TokenNumber is not 0 and Guid is not NULL, then the next token in the token space specified by Guid is returned.\r
1400 If TokenNumber is 0 and Guid is NULL, then the first token in the default token space is returned.\r
1401 If TokenNumber is not 0 and Guid is NULL, then the next token in the default token space is returned.\r
1402 The token numbers in the default token space may not be related to token numbers in token spaces that are named by Guid.\r
1403 If the next token number can be retrieved, then it is returned in TokenNumber, and EFI_SUCCESS is returned.\r
1404 If TokenNumber represents the last token number in the token space specified by Guid, then EFI_NOT_FOUND is returned.\r
90e06556 1405 If TokenNumber is not present in the token space specified by Guid, then EFI_NOT_FOUND is returned.\r
1406\r
1407\r
d1102dba
LG
1408 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.\r
1409 This is an optional parameter that may be NULL. If this parameter is NULL, then a request\r
90e06556 1410 is being made to retrieve tokens from the default token space.\r
1411 @param[in, out] TokenNumber A pointer to the PCD token number to use to find the subsequent token number.\r
d1102dba 1412\r
419db80b
BF
1413 @retval EFI_SUCCESS The PCD service has retrieved the next valid token number.\r
1414 @retval EFI_NOT_FOUND The PCD service could not find data from the requested token number.\r
fc547e08 1415\r
1416**/\r
80408db0 1417EFI_STATUS\r
1418EFIAPI\r
1419PeiPcdGetNextToken (\r
1420 IN CONST EFI_GUID *Guid, OPTIONAL\r
1421 IN OUT UINTN *TokenNumber\r
1422 )\r
1423{\r
1424 UINTN GuidTableIdx;\r
1425 PEI_PCD_DATABASE *PeiPcdDb;\r
1426 EFI_GUID *MatchGuid;\r
419db80b 1427 EFI_GUID *GuidTable;\r
80408db0 1428 DYNAMICEX_MAPPING *ExMapTable;\r
fc547e08 1429 UINTN Index;\r
80408db0 1430 BOOLEAN Found;\r
1431 BOOLEAN PeiExMapTableEmpty;\r
d1102dba 1432 UINTN PeiNexTokenNumber;\r
80408db0 1433\r
f806dd27 1434 if (!FeaturePcdGet (PcdPeiFullPcdDatabaseEnable)) {\r
80408db0 1435 return EFI_UNSUPPORTED;\r
1436 }\r
1437\r
419db80b
BF
1438 PeiPcdDb = GetPcdDatabase ();\r
1439 PeiNexTokenNumber = PeiPcdDb->LocalTokenCount - PeiPcdDb->ExTokenCount;\r
1440 GuidTable = (EFI_GUID *)((UINT8 *)PeiPcdDb + PeiPcdDb->GuidTableOffset);\r
80408db0 1441\r
419db80b
BF
1442 if (PeiPcdDb->ExTokenCount == 0) {\r
1443 PeiExMapTableEmpty = TRUE;\r
1444 } else {\r
1445 PeiExMapTableEmpty = FALSE;\r
1446 }\r
80408db0 1447 if (Guid == NULL) {\r
419db80b 1448 if (*TokenNumber > PeiNexTokenNumber) {\r
80408db0 1449 return EFI_NOT_FOUND;\r
1450 }\r
1451 (*TokenNumber)++;\r
419db80b 1452 if (*TokenNumber > PeiNexTokenNumber) {\r
80408db0 1453 *TokenNumber = PCD_INVALID_TOKEN_NUMBER;\r
419db80b 1454 return EFI_NOT_FOUND;\r
80408db0 1455 }\r
1456 return EFI_SUCCESS;\r
1457 } else {\r
1458 if (PeiExMapTableEmpty) {\r
419db80b 1459 return EFI_NOT_FOUND;\r
80408db0 1460 }\r
419db80b
BF
1461\r
1462 MatchGuid = ScanGuid (GuidTable, PeiPcdDb->GuidTableCount * sizeof(EFI_GUID), Guid);\r
80408db0 1463\r
1464 if (MatchGuid == NULL) {\r
80408db0 1465 return EFI_NOT_FOUND;\r
1466 }\r
1467\r
419db80b 1468 GuidTableIdx = MatchGuid - GuidTable;\r
80408db0 1469\r
419db80b 1470 ExMapTable = (DYNAMICEX_MAPPING *)((UINT8 *)PeiPcdDb + PeiPcdDb->ExMapTableOffset);\r
80408db0 1471\r
1472 Found = FALSE;\r
1473 //\r
1474 // Locate the GUID in ExMapTable first.\r
1475 //\r
419db80b 1476 for (Index = 0; Index < PeiPcdDb->ExTokenCount; Index++) {\r
fc547e08 1477 if (ExMapTable[Index].ExGuidIndex == GuidTableIdx) {\r
80408db0 1478 Found = TRUE;\r
1479 break;\r
1480 }\r
1481 }\r
1482\r
1483 if (Found) {\r
bfb4c2ba
CS
1484 //\r
1485 // If given token number is PCD_INVALID_TOKEN_NUMBER, then return the first\r
1486 // token number in found token space.\r
1487 //\r
80408db0 1488 if (*TokenNumber == PCD_INVALID_TOKEN_NUMBER) {\r
fc547e08 1489 *TokenNumber = ExMapTable[Index].ExTokenNumber;\r
80408db0 1490 return EFI_SUCCESS;\r
1491 }\r
1492\r
419db80b 1493 for ( ; Index < PeiPcdDb->ExTokenCount; Index++) {\r
bfb4c2ba 1494 if ((ExMapTable[Index].ExTokenNumber == *TokenNumber) && (ExMapTable[Index].ExGuidIndex == GuidTableIdx)) {\r
419db80b
BF
1495 break;\r
1496 }\r
1497 }\r
1498\r
1499 while (Index < PeiPcdDb->ExTokenCount) {\r
1500 Index++;\r
1501 if (Index == PeiPcdDb->ExTokenCount) {\r
1502 //\r
1503 // Exceed the length of ExMap Table\r
1504 //\r
1505 *TokenNumber = PCD_INVALID_TOKEN_NUMBER;\r
1506 return EFI_NOT_FOUND;\r
1507 } else if (ExMapTable[Index].ExGuidIndex == GuidTableIdx) {\r
1508 //\r
1509 // Found the next match\r
1510 //\r
1511 *TokenNumber = ExMapTable[Index].ExTokenNumber;\r
1512 return EFI_SUCCESS;\r
80408db0 1513 }\r
1514 }\r
80408db0 1515 }\r
1516 }\r
1517\r
1518 return EFI_NOT_FOUND;\r
1519}\r
1520\r
fc547e08 1521/**\r
1522 Retrieves the next valid PCD token namespace for a given namespace.\r
1523\r
419db80b
BF
1524 Gets the next valid token namespace for a given namespace. This is useful to traverse the valid\r
1525 token namespaces on a platform.\r
1526\r
1527 @param[in, out] Guid An indirect pointer to EFI_GUID. On input it designates a known token\r
1528 namespace from which the search will start. On output, it designates the next valid\r
1529 token namespace on the platform. If *Guid is NULL, then the GUID of the first token\r
1530 space of the current platform is returned. If the search cannot locate the next valid\r
1531 token namespace, an error is returned and the value of *Guid is undefined.\r
d1102dba 1532\r
419db80b
BF
1533 @retval EFI_SUCCESS The PCD service retrieved the value requested.\r
1534 @retval EFI_NOT_FOUND The PCD service could not find the next valid token namespace.\r
80408db0 1535\r
fc547e08 1536**/\r
80408db0 1537EFI_STATUS\r
1538EFIAPI\r
1539PeiPcdGetNextTokenSpace (\r
1540 IN OUT CONST EFI_GUID **Guid\r
1541 )\r
1542{\r
1543 UINTN GuidTableIdx;\r
1544 EFI_GUID *MatchGuid;\r
1545 PEI_PCD_DATABASE *PeiPcdDb;\r
1546 DYNAMICEX_MAPPING *ExMapTable;\r
fc547e08 1547 UINTN Index;\r
419db80b 1548 UINTN Index2;\r
80408db0 1549 BOOLEAN Found;\r
1550 BOOLEAN PeiExMapTableEmpty;\r
419db80b 1551 EFI_GUID *GuidTable;\r
80408db0 1552\r
f806dd27 1553 if (!FeaturePcdGet (PcdPeiFullPcdDatabaseEnable)) {\r
80408db0 1554 return EFI_UNSUPPORTED;\r
1555 }\r
1556\r
1557 ASSERT (Guid != NULL);\r
1558\r
419db80b 1559 PeiPcdDb = GetPcdDatabase ();\r
80408db0 1560\r
419db80b
BF
1561 if (PeiPcdDb->ExTokenCount == 0) {\r
1562 PeiExMapTableEmpty = TRUE;\r
1563 } else {\r
1564 PeiExMapTableEmpty = FALSE;\r
1565 }\r
d1102dba 1566\r
80408db0 1567 if (PeiExMapTableEmpty) {\r
419db80b 1568 return EFI_NOT_FOUND;\r
80408db0 1569 }\r
1570\r
419db80b
BF
1571 ExMapTable = (DYNAMICEX_MAPPING *)((UINT8 *)PeiPcdDb + PeiPcdDb->ExMapTableOffset);\r
1572 GuidTable = (EFI_GUID *)((UINT8 *)PeiPcdDb + PeiPcdDb->GuidTableOffset);\r
d1102dba 1573\r
80408db0 1574 if (*Guid == NULL) {\r
1575 //\r
1576 // return the first Token Space Guid.\r
1577 //\r
419db80b 1578 *Guid = GuidTable + ExMapTable[0].ExGuidIndex;\r
80408db0 1579 return EFI_SUCCESS;\r
1580 }\r
1581\r
419db80b 1582 MatchGuid = ScanGuid (GuidTable, PeiPcdDb->GuidTableCount * sizeof(GuidTable[0]), *Guid);\r
80408db0 1583\r
1584 if (MatchGuid == NULL) {\r
1585 return EFI_NOT_FOUND;\r
1586 }\r
d1102dba 1587\r
419db80b 1588 GuidTableIdx = MatchGuid - GuidTable;\r
80408db0 1589\r
1590 Found = FALSE;\r
419db80b 1591 for (Index = 0; Index < PeiPcdDb->ExTokenCount; Index++) {\r
fc547e08 1592 if (ExMapTable[Index].ExGuidIndex == GuidTableIdx) {\r
80408db0 1593 Found = TRUE;\r
1594 break;\r
1595 }\r
1596 }\r
1597\r
1598 if (Found) {\r
fc547e08 1599 Index++;\r
419db80b
BF
1600 for ( ; Index < PeiPcdDb->ExTokenCount; Index++ ) {\r
1601 if (ExMapTable[Index].ExGuidIndex != GuidTableIdx) {\r
1602 Found = FALSE;\r
1603 for (Index2 = 0 ; Index2 < Index; Index2++) {\r
1604 if (ExMapTable[Index2].ExGuidIndex == ExMapTable[Index].ExGuidIndex) {\r
1605 //\r
1606 // This token namespace should have been found and output at preceding getting.\r
1607 //\r
1608 Found = TRUE;\r
1609 break;\r
1610 }\r
1611 }\r
1612 if (!Found) {\r
1613 *Guid = (EFI_GUID *)((UINT8 *)PeiPcdDb + PeiPcdDb->GuidTableOffset) + ExMapTable[Index].ExGuidIndex;\r
1614 return EFI_SUCCESS;\r
1615 }\r
80408db0 1616 }\r
1617 }\r
1618 *Guid = NULL;\r
80408db0 1619 }\r
1620\r
1621 return EFI_NOT_FOUND;\r
1622\r
1623}\r
1624\r
fc547e08 1625/**\r
1626 Get PCD value's size for POINTER type PCD.\r
d1102dba 1627\r
419db80b 1628 The POINTER type PCD's value will be stored into a buffer in specified size.\r
fc547e08 1629 The max size of this PCD's value is described in PCD's definition in DEC file.\r
1630\r
1631 @param LocalTokenNumberTableIdx Index of PCD token number in PCD token table\r
3fd8027e 1632 @param MaxSize Maximum size of PCD's value\r
fc547e08 1633 @param Database Pcd database in PEI phase.\r
1634\r
1635 @return PCD value's size for POINTER type PCD.\r
1636\r
1637**/\r
80408db0 1638UINTN\r
1639GetPtrTypeSize (\r
1640 IN UINTN LocalTokenNumberTableIdx,\r
1641 OUT UINTN *MaxSize,\r
1642 IN PEI_PCD_DATABASE *Database\r
1643 )\r
1644{\r
1645 INTN SizeTableIdx;\r
1646 UINTN LocalTokenNumber;\r
80408db0 1647 SIZE_INFO *SizeTable;\r
80408db0 1648\r
1649 SizeTableIdx = GetSizeTableIndex (LocalTokenNumberTableIdx, Database);\r
1650\r
419db80b 1651 LocalTokenNumber = *((UINT32 *)((UINT8 *)Database + Database->LocalTokenNumberTableOffset) + LocalTokenNumberTableIdx);\r
80408db0 1652\r
1653 ASSERT ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER);\r
d1102dba 1654\r
419db80b 1655 SizeTable = (SIZE_INFO *)((UINT8 *)Database + Database->SizeTableOffset);\r
80408db0 1656\r
1657 *MaxSize = SizeTable[SizeTableIdx];\r
1658 //\r
d1102dba 1659 // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type\r
80408db0 1660 // PCD entry.\r
1661 //\r
fc547e08 1662 if ((LocalTokenNumber & PCD_TYPE_VPD) != 0) {\r
80408db0 1663 //\r
419db80b 1664 // We have only two entry for VPD enabled PCD entry:\r
80408db0 1665 // 1) MAX Size.\r
419db80b 1666 // 2) Current Size\r
80408db0 1667 // We consider current size is equal to MAX size.\r
1668 //\r
1669 return *MaxSize;\r
1670 } else {\r
7c736265
LG
1671 //\r
1672 // We have only two entry for Non-Sku enabled PCD entry:\r
1673 // 1) MAX SIZE\r
1674 // 2) Current Size\r
1675 //\r
1676 return SizeTable[SizeTableIdx + 1];\r
80408db0 1677 }\r
1678}\r
1679\r
fc547e08 1680/**\r
1681 Set PCD value's size for POINTER type PCD.\r
d1102dba 1682\r
419db80b 1683 The POINTER type PCD's value will be stored into a buffer in specified size.\r
fc547e08 1684 The max size of this PCD's value is described in PCD's definition in DEC file.\r
1685\r
1686 @param LocalTokenNumberTableIdx Index of PCD token number in PCD token table\r
3fd8027e 1687 @param CurrentSize Maximum size of PCD's value\r
fc547e08 1688 @param Database Pcd database in PEI phase.\r
80408db0 1689\r
3fd8027e 1690 @retval TRUE Success to set PCD's value size, which is not exceed maximum size\r
1691 @retval FALSE Fail to set PCD's value size, which maybe exceed maximum size\r
80408db0 1692\r
fc547e08 1693**/\r
80408db0 1694BOOLEAN\r
1695SetPtrTypeSize (\r
1696 IN UINTN LocalTokenNumberTableIdx,\r
1697 IN OUT UINTN *CurrentSize,\r
1698 IN PEI_PCD_DATABASE *Database\r
1699 )\r
1700{\r
1701 INTN SizeTableIdx;\r
1702 UINTN LocalTokenNumber;\r
80408db0 1703 SIZE_INFO *SizeTable;\r
80408db0 1704 UINTN MaxSize;\r
d1102dba 1705\r
80408db0 1706 SizeTableIdx = GetSizeTableIndex (LocalTokenNumberTableIdx, Database);\r
1707\r
419db80b 1708 LocalTokenNumber = *((UINT32 *)((UINT8 *)Database + Database->LocalTokenNumberTableOffset) + LocalTokenNumberTableIdx);\r
80408db0 1709\r
1710 ASSERT ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER);\r
419db80b
BF
1711\r
1712 SizeTable = (SIZE_INFO *)((UINT8 *)Database + Database->SizeTableOffset);\r
80408db0 1713\r
1714 MaxSize = SizeTable[SizeTableIdx];\r
1715 //\r
d1102dba 1716 // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type\r
80408db0 1717 // PCD entry.\r
1718 //\r
fc547e08 1719 if ((LocalTokenNumber & PCD_TYPE_VPD) != 0) {\r
80408db0 1720 //\r
1721 // We shouldn't come here as we don't support SET for VPD\r
1722 //\r
1723 ASSERT (FALSE);\r
1724 return FALSE;\r
1725 } else {\r
1726 if ((*CurrentSize > MaxSize) ||\r
1727 (*CurrentSize == MAX_ADDRESS)) {\r
1728 *CurrentSize = MaxSize;\r
1729 return FALSE;\r
5944a83b 1730 }\r
d1102dba 1731\r
7c736265
LG
1732 //\r
1733 // We have only two entry for Non-Sku enabled PCD entry:\r
1734 // 1) MAX SIZE\r
1735 // 2) Current Size\r
1736 //\r
1737 SizeTable[SizeTableIdx + 1] = (SIZE_INFO) *CurrentSize;\r
1738 return TRUE;\r
80408db0 1739 }\r
1740\r
1741}\r