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