]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/PCD/Dxe/Pcd.c
MdeModulePkg PCD: Add DynamicEx PcdVpdBaseAddress64 for non SPI platform
[mirror_edk2.git] / MdeModulePkg / Universal / PCD / Dxe / Pcd.c
CommitLineData
80408db0 1/** @file\r
2ab6330e 2 PCD DXE driver manage all PCD entry initialized in PEI phase and DXE phase, and\r
8a541f0a 3 produce the implementation of native PCD protocol and EFI_PCD_PROTOCOL defined in\r
120ca3ce 4 PI 1.4a Vol3.\r
80408db0 5\r
d1102dba 6Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
e5eed7d3 7This program and the accompanying materials\r
80408db0 8are licensed and made available under the terms and conditions of the BSD License\r
9which accompanies this distribution. The full text of the license may be found at\r
10http://opensource.org/licenses/bsd-license.php\r
11\r
12THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
13WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
14\r
80408db0 15**/\r
16\r
80408db0 17#include "Service.h"\r
18\r
2ab6330e 19///\r
20/// PCD database lock.\r
21///\r
6a429dfa 22EFI_LOCK mPcdDatabaseLock = EFI_INITIALIZE_LOCK_VARIABLE(TPL_NOTIFY);\r
80408db0 23\r
17e7fa8f 24///\r
d1102dba 25/// PCD_PROTOCOL the EDKII native implementation which support dynamic\r
17e7fa8f 26/// type and dynamicEx type PCDs.\r
27///\r
80408db0 28PCD_PROTOCOL mPcdInstance = {\r
29 DxePcdSetSku,\r
30\r
31 DxePcdGet8,\r
32 DxePcdGet16,\r
33 DxePcdGet32,\r
34 DxePcdGet64,\r
35 DxePcdGetPtr,\r
36 DxePcdGetBool,\r
37 DxePcdGetSize,\r
38\r
39 DxePcdGet8Ex,\r
40 DxePcdGet16Ex,\r
41 DxePcdGet32Ex,\r
42 DxePcdGet64Ex,\r
43 DxePcdGetPtrEx,\r
44 DxePcdGetBoolEx,\r
45 DxePcdGetSizeEx,\r
46\r
47 DxePcdSet8,\r
48 DxePcdSet16,\r
49 DxePcdSet32,\r
50 DxePcdSet64,\r
51 DxePcdSetPtr,\r
52 DxePcdSetBool,\r
53\r
54 DxePcdSet8Ex,\r
55 DxePcdSet16Ex,\r
56 DxePcdSet32Ex,\r
57 DxePcdSet64Ex,\r
58 DxePcdSetPtrEx,\r
59 DxePcdSetBoolEx,\r
60\r
61 DxeRegisterCallBackOnSet,\r
62 DxeUnRegisterCallBackOnSet,\r
63 DxePcdGetNextToken,\r
64 DxePcdGetNextTokenSpace\r
65};\r
66\r
17e7fa8f 67///\r
68/// EFI_PCD_PROTOCOL is defined in PI 1.2 Vol 3 which only support dynamicEx type\r
69/// PCD.\r
70///\r
c896d682 71EFI_PCD_PROTOCOL mEfiPcdInstance = {\r
72 DxePcdSetSku,\r
73 DxePcdGet8Ex,\r
74 DxePcdGet16Ex,\r
75 DxePcdGet32Ex,\r
76 DxePcdGet64Ex,\r
77 DxePcdGetPtrEx,\r
78 DxePcdGetBoolEx,\r
79 DxePcdGetSizeEx,\r
80 DxePcdSet8Ex,\r
81 DxePcdSet16Ex,\r
82 DxePcdSet32Ex,\r
83 DxePcdSet64Ex,\r
84 DxePcdSetPtrEx,\r
85 DxePcdSetBoolEx,\r
86 (EFI_PCD_PROTOCOL_CALLBACK_ON_SET) DxeRegisterCallBackOnSet,\r
87 (EFI_PCD_PROTOCOL_CANCEL_CALLBACK) DxeUnRegisterCallBackOnSet,\r
88 DxePcdGetNextToken,\r
89 DxePcdGetNextTokenSpace\r
90};\r
80408db0 91\r
96d6d004
SZ
92///\r
93/// Instance of GET_PCD_INFO_PROTOCOL protocol is EDKII native implementation.\r
94/// This protocol instance support dynamic and dynamicEx type PCDs.\r
95///\r
96GET_PCD_INFO_PROTOCOL mGetPcdInfoInstance = {\r
97 DxeGetPcdInfoGetInfo,\r
98 DxeGetPcdInfoGetInfoEx,\r
99 DxeGetPcdInfoGetSku\r
100};\r
101\r
102///\r
103/// Instance of EFI_GET_PCD_INFO_PROTOCOL which is defined in PI 1.2.1 Vol 3.\r
104/// This PPI instance only support dyanmicEx type PCD.\r
105///\r
106EFI_GET_PCD_INFO_PROTOCOL mEfiGetPcdInfoInstance = {\r
107 DxeGetPcdInfoGetInfoEx,\r
108 DxeGetPcdInfoGetSku\r
109};\r
110\r
17e7fa8f 111EFI_HANDLE mPcdHandle = NULL;\r
534efca0 112UINTN mVpdBaseAddress = 0;\r
80408db0 113\r
2ab6330e 114/**\r
115 Main entry for PCD DXE driver.\r
d1102dba 116\r
2ab6330e 117 This routine initialize the PCD database and install PCD_PROTOCOL.\r
d1102dba 118\r
2ab6330e 119 @param ImageHandle Image handle for PCD DXE driver.\r
120 @param SystemTable Pointer to SystemTable.\r
121\r
122 @return Status of gBS->InstallProtocolInterface()\r
123\r
124**/\r
80408db0 125EFI_STATUS\r
126EFIAPI\r
127PcdDxeInit (\r
128 IN EFI_HANDLE ImageHandle,\r
129 IN EFI_SYSTEM_TABLE *SystemTable\r
130 )\r
131{\r
8a541f0a 132 EFI_STATUS Status;\r
23f3e119
SZ
133 VOID *Registration;\r
134\r
80408db0 135 //\r
136 // Make sure the Pcd Protocol is not already installed in the system\r
137 //\r
138\r
139 ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gPcdProtocolGuid);\r
140\r
141 BuildPcdDxeDataBase ();\r
142\r
c896d682 143 //\r
8a541f0a 144 // Install PCD_PROTOCOL to handle dynamic type PCD\r
145 // Install EFI_PCD_PROTOCOL to handle dynamicEx type PCD\r
c896d682 146 //\r
8a541f0a 147 Status = gBS->InstallMultipleProtocolInterfaces (\r
17e7fa8f 148 &mPcdHandle,\r
149 &gPcdProtocolGuid, &mPcdInstance,\r
150 &gEfiPcdProtocolGuid, &mEfiPcdInstance,\r
151 NULL\r
c896d682 152 );\r
80408db0 153 ASSERT_EFI_ERROR (Status);\r
154\r
61d8989f 155 //\r
85d0b97d
SZ
156 // Install GET_PCD_INFO_PROTOCOL to handle dynamic type PCD\r
157 // Install EFI_GET_PCD_INFO_PROTOCOL to handle dynamicEx type PCD\r
61d8989f 158 //\r
85d0b97d
SZ
159 Status = gBS->InstallMultipleProtocolInterfaces (\r
160 &mPcdHandle,\r
161 &gGetPcdInfoProtocolGuid, &mGetPcdInfoInstance,\r
162 &gEfiGetPcdInfoProtocolGuid, &mEfiGetPcdInfoInstance,\r
163 NULL\r
164 );\r
165 ASSERT_EFI_ERROR (Status);\r
96d6d004 166\r
23f3e119
SZ
167 //\r
168 // Register callback function upon VariableLockProtocol\r
169 // to lock the variables referenced by DynamicHii PCDs with RO property set in *.dsc.\r
170 //\r
171 EfiCreateProtocolNotifyEvent (\r
172 &gEdkiiVariableLockProtocolGuid,\r
173 TPL_CALLBACK,\r
174 VariableLockCallBack,\r
175 NULL,\r
176 &Registration\r
177 );\r
178\r
534efca0
LG
179 //\r
180 // Cache VpdBaseAddress in entry point for the following usage.\r
181 //\r
182\r
183 //\r
184 // PcdVpdBaseAddress64 is DynamicEx PCD only. So, DxePcdGet64Ex() is used to get its value.\r
185 //\r
186 mVpdBaseAddress = (UINTN) DxePcdGet64Ex (&gEfiMdeModulePkgTokenSpaceGuid, PcdToken (PcdVpdBaseAddress64));\r
187 if (mVpdBaseAddress == 0) {\r
188 //\r
189 // PcdVpdBaseAddress64 is not set, get value from PcdVpdBaseAddress.\r
190 //\r
191 mVpdBaseAddress = (UINTN) PcdGet32 (PcdVpdBaseAddress);\r
192 }\r
193\r
17e7fa8f 194 return Status;\r
96d6d004
SZ
195}\r
196\r
197/**\r
198 Retrieve additional information associated with a PCD token in the default token space.\r
199\r
200 This includes information such as the type of value the TokenNumber is associated with as well as possible\r
201 human readable name that is associated with the token.\r
202\r
203 @param[in] TokenNumber The PCD token number.\r
204 @param[out] PcdInfo The returned information associated with the requested TokenNumber.\r
205 The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.\r
206\r
207 @retval EFI_SUCCESS The PCD information was returned successfully.\r
208 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.\r
209**/\r
210EFI_STATUS\r
211EFIAPI\r
212DxeGetPcdInfoGetInfo (\r
213 IN UINTN TokenNumber,\r
214 OUT EFI_PCD_INFO *PcdInfo\r
215 )\r
216{\r
217 return DxeGetPcdInfo (NULL, TokenNumber, PcdInfo);\r
218}\r
219\r
220/**\r
221 Retrieve additional information associated with a PCD token.\r
222\r
223 This includes information such as the type of value the TokenNumber is associated with as well as possible\r
224 human readable name that is associated with the token.\r
80408db0 225\r
96d6d004
SZ
226 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.\r
227 @param[in] TokenNumber The PCD token number.\r
228 @param[out] PcdInfo The returned information associated with the requested TokenNumber.\r
229 The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.\r
230\r
231 @retval EFI_SUCCESS The PCD information was returned successfully.\r
232 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.\r
233**/\r
234EFI_STATUS\r
235EFIAPI\r
236DxeGetPcdInfoGetInfoEx (\r
237 IN CONST EFI_GUID *Guid,\r
238 IN UINTN TokenNumber,\r
239 OUT EFI_PCD_INFO *PcdInfo\r
240 )\r
241{\r
242 return DxeGetPcdInfo (Guid, TokenNumber, PcdInfo);\r
243}\r
244\r
245/**\r
246 Retrieve the currently set SKU Id.\r
247\r
248 @return The currently set SKU Id. If the platform has not set at a SKU Id, then the\r
249 default SKU Id value of 0 is returned. If the platform has set a SKU Id, then the currently set SKU\r
250 Id is returned.\r
251**/\r
252UINTN\r
253EFIAPI\r
254DxeGetPcdInfoGetSku (\r
255 VOID\r
256 )\r
257{\r
b6e89910 258 return (UINTN) mPcdDatabase.DxeDb->SystemSkuId;\r
80408db0 259}\r
260\r
2ab6330e 261/**\r
262 Sets the SKU value for subsequent calls to set or get PCD token values.\r
263\r
d1102dba 264 SetSku() sets the SKU Id to be used for subsequent calls to set or get PCD values.\r
2ab6330e 265 SetSku() is normally called only once by the system.\r
266\r
d1102dba
LG
267 For each item (token), the database can hold a single value that applies to all SKUs,\r
268 or multiple values, where each value is associated with a specific SKU Id. Items with multiple,\r
269 SKU-specific values are called SKU enabled.\r
270\r
120ca3ce 271 The SKU Id of zero is reserved as a default.\r
d1102dba
LG
272 For tokens that are not SKU enabled, the system ignores any set SKU Id and works with the\r
273 single value for that token. For SKU-enabled tokens, the system will use the SKU Id set by the\r
274 last call to SetSku(). If no SKU Id is set or the currently set SKU Id isn't valid for the specified token,\r
275 the system uses the default SKU Id. If the system attempts to use the default SKU Id and no value has been\r
2ab6330e 276 set for that Id, the results are unpredictable.\r
277\r
d1102dba 278 @param[in] SkuId The SKU value that will be used when the PCD service will retrieve and\r
2ab6330e 279 set values associated with a PCD token.\r
280\r
2ab6330e 281**/\r
80408db0 282VOID\r
283EFIAPI\r
284DxePcdSetSku (\r
285 IN UINTN SkuId\r
286 )\r
287{\r
7c736265
LG
288 SKU_ID *SkuIdTable;\r
289 UINTN Index;\r
290 EFI_STATUS Status;\r
85d0b97d 291\r
f71503c3
LG
292 DEBUG ((DEBUG_INFO, "PcdDxe - SkuId 0x%lx is to be set.\n", (SKU_ID) SkuId));\r
293\r
2db48a1f
SZ
294 if (SkuId == mPcdDatabase.DxeDb->SystemSkuId) {\r
295 //\r
296 // The input SKU Id is equal to current SKU Id, return directly.\r
297 //\r
f71503c3 298 DEBUG ((DEBUG_INFO, "PcdDxe - SkuId is same to current system Sku.\n"));\r
2db48a1f
SZ
299 return;\r
300 }\r
301\r
302 if (mPcdDatabase.DxeDb->SystemSkuId != (SKU_ID) 0) {\r
303 DEBUG ((DEBUG_ERROR, "PcdDxe - The SKU Id could be changed only once."));\r
304 DEBUG ((\r
305 DEBUG_ERROR,\r
306 "PcdDxe - The SKU Id was set to 0x%lx already, it could not be set to 0x%lx any more.",\r
307 mPcdDatabase.DxeDb->SystemSkuId,\r
308 (SKU_ID) SkuId\r
309 ));\r
310 ASSERT (FALSE);\r
311 return;\r
312 }\r
313\r
85d0b97d
SZ
314 SkuIdTable = (SKU_ID *) ((UINT8 *) mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->SkuIdTableOffset);\r
315 for (Index = 0; Index < SkuIdTable[0]; Index++) {\r
316 if (SkuId == SkuIdTable[Index + 1]) {\r
f71503c3 317 DEBUG ((DEBUG_INFO, "PcdDxe - SkuId is found in SkuId table.\n"));\r
7c736265
LG
318 Status = UpdatePcdDatabase (SkuId, TRUE);\r
319 if (!EFI_ERROR (Status)) {\r
320 mPcdDatabase.DxeDb->SystemSkuId = (SKU_ID) SkuId;\r
321 DEBUG ((DEBUG_INFO, "PcdDxe - Set current SKU Id to 0x%lx.\n", (SKU_ID) SkuId));\r
322 return;\r
323 }\r
85d0b97d
SZ
324 }\r
325 }\r
326\r
327 //\r
2db48a1f 328 // Invalid input SkuId, the default SKU Id will be still used for the system.\r
85d0b97d 329 //\r
f71503c3 330 DEBUG ((DEBUG_ERROR, "PcdDxe - Invalid input SkuId, the default SKU Id will be still used.\n"));\r
80408db0 331 return;\r
332}\r
333\r
2ab6330e 334/**\r
335 Retrieves an 8-bit value for a given PCD token.\r
80408db0 336\r
d1102dba 337 Retrieves the current byte-sized value for a PCD token number.\r
2ab6330e 338 If the TokenNumber is invalid, the results are unpredictable.\r
d1102dba
LG
339\r
340 @param[in] TokenNumber The PCD token number.\r
80408db0 341\r
2ab6330e 342 @return The UINT8 value.\r
d1102dba 343\r
2ab6330e 344**/\r
80408db0 345UINT8\r
346EFIAPI\r
347DxePcdGet8 (\r
348 IN UINTN TokenNumber\r
349 )\r
350{\r
351 return *((UINT8 *) GetWorker (TokenNumber, sizeof (UINT8)));\r
352}\r
353\r
2ab6330e 354/**\r
355 Retrieves an 16-bit value for a given PCD token.\r
80408db0 356\r
d1102dba 357 Retrieves the current 16-bits value for a PCD token number.\r
2ab6330e 358 If the TokenNumber is invalid, the results are unpredictable.\r
d1102dba
LG
359\r
360 @param[in] TokenNumber The PCD token number.\r
80408db0 361\r
2ab6330e 362 @return The UINT16 value.\r
d1102dba 363\r
2ab6330e 364**/\r
80408db0 365UINT16\r
366EFIAPI\r
367DxePcdGet16 (\r
368 IN UINTN TokenNumber\r
369 )\r
370{\r
371 return ReadUnaligned16 (GetWorker (TokenNumber, sizeof (UINT16)));\r
372}\r
373\r
2ab6330e 374/**\r
375 Retrieves an 32-bit value for a given PCD token.\r
80408db0 376\r
d1102dba 377 Retrieves the current 32-bits value for a PCD token number.\r
2ab6330e 378 If the TokenNumber is invalid, the results are unpredictable.\r
d1102dba
LG
379\r
380 @param[in] TokenNumber The PCD token number.\r
80408db0 381\r
2ab6330e 382 @return The UINT32 value.\r
d1102dba 383\r
2ab6330e 384**/\r
80408db0 385UINT32\r
386EFIAPI\r
387DxePcdGet32 (\r
388 IN UINTN TokenNumber\r
389 )\r
390{\r
391 return ReadUnaligned32 (GetWorker (TokenNumber, sizeof (UINT32)));\r
392}\r
393\r
2ab6330e 394/**\r
395 Retrieves an 64-bit value for a given PCD token.\r
80408db0 396\r
d1102dba 397 Retrieves the current 64-bits value for a PCD token number.\r
2ab6330e 398 If the TokenNumber is invalid, the results are unpredictable.\r
d1102dba
LG
399\r
400 @param[in] TokenNumber The PCD token number.\r
80408db0 401\r
2ab6330e 402 @return The UINT64 value.\r
d1102dba 403\r
2ab6330e 404**/\r
80408db0 405UINT64\r
406EFIAPI\r
407DxePcdGet64 (\r
408 IN UINTN TokenNumber\r
409 )\r
410{\r
411 return ReadUnaligned64(GetWorker (TokenNumber, sizeof (UINT64)));\r
412}\r
413\r
2ab6330e 414/**\r
415 Retrieves a pointer to a value for a given PCD token.\r
80408db0 416\r
d1102dba
LG
417 Retrieves the current pointer to the buffer for a PCD token number.\r
418 Do not make any assumptions about the alignment of the pointer that\r
419 is returned by this function call. If the TokenNumber is invalid,\r
2ab6330e 420 the results are unpredictable.\r
80408db0 421\r
d1102dba 422 @param[in] TokenNumber The PCD token number.\r
2ab6330e 423\r
424 @return The pointer to the buffer to be retrived.\r
d1102dba 425\r
2ab6330e 426**/\r
80408db0 427VOID *\r
428EFIAPI\r
429DxePcdGetPtr (\r
430 IN UINTN TokenNumber\r
431 )\r
432{\r
433 return GetWorker (TokenNumber, 0);\r
434}\r
435\r
2ab6330e 436/**\r
437 Retrieves a Boolean value for a given PCD token.\r
438\r
d1102dba
LG
439 Retrieves the current boolean value for a PCD token number.\r
440 Do not make any assumptions about the alignment of the pointer that\r
441 is returned by this function call. If the TokenNumber is invalid,\r
2ab6330e 442 the results are unpredictable.\r
80408db0 443\r
d1102dba 444 @param[in] TokenNumber The PCD token number.\r
80408db0 445\r
2ab6330e 446 @return The Boolean value.\r
d1102dba 447\r
2ab6330e 448**/\r
80408db0 449BOOLEAN\r
450EFIAPI\r
451DxePcdGetBool (\r
452 IN UINTN TokenNumber\r
453 )\r
454{\r
455 return *((BOOLEAN *) GetWorker (TokenNumber, sizeof (BOOLEAN)));\r
456}\r
457\r
2ab6330e 458/**\r
459 Retrieves the size of the value for a given PCD token.\r
80408db0 460\r
d1102dba 461 Retrieves the current size of a particular PCD token.\r
2ab6330e 462 If the TokenNumber is invalid, the results are unpredictable.\r
80408db0 463\r
d1102dba 464 @param[in] TokenNumber The PCD token number.\r
2ab6330e 465\r
466 @return The size of the value for the PCD token.\r
d1102dba 467\r
2ab6330e 468**/\r
80408db0 469UINTN\r
470EFIAPI\r
471DxePcdGetSize (\r
472 IN UINTN TokenNumber\r
473 )\r
474{\r
475 UINTN Size;\r
476 UINT32 *LocalTokenNumberTable;\r
477 BOOLEAN IsPeiDb;\r
478 UINTN MaxSize;\r
479 UINTN TmpTokenNumber;\r
480 //\r
481 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
482 // We have to decrement TokenNumber by 1 to make it usable\r
483 // as the array index.\r
484 //\r
485 TokenNumber--;\r
486\r
487 //\r
488 // Backup the TokenNumber passed in as GetPtrTypeSize need the original TokenNumber\r
d1102dba 489 //\r
80408db0 490 TmpTokenNumber = TokenNumber;\r
491\r
492 // EBC compiler is very choosy. It may report warning about comparison\r
d1102dba 493 // between UINTN and 0 . So we add 1 in each size of the\r
80408db0 494 // comparison.\r
419db80b 495 ASSERT (TokenNumber + 1 < mPcdTotalTokenCount + 1);\r
80408db0 496\r
497 // EBC compiler is very choosy. It may report warning about comparison\r
d1102dba 498 // between UINTN and 0 . So we add 1 in each size of the\r
80408db0 499 // comparison.\r
419db80b 500 IsPeiDb = (BOOLEAN) (TokenNumber + 1 < mPeiLocalTokenCount + 1);\r
d1102dba
LG
501\r
502 TokenNumber = IsPeiDb ? TokenNumber :\r
419db80b 503 (TokenNumber - mPeiLocalTokenCount);\r
80408db0 504\r
d1102dba 505 LocalTokenNumberTable = IsPeiDb ? (UINT32 *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->LocalTokenNumberTableOffset)\r
419db80b 506 : (UINT32 *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->LocalTokenNumberTableOffset);\r
80408db0 507\r
508 Size = (LocalTokenNumberTable[TokenNumber] & PCD_DATUM_TYPE_ALL_SET) >> PCD_DATUM_TYPE_SHIFT;\r
509\r
510 if (Size == 0) {\r
511 //\r
512 // For pointer type, we need to scan the SIZE_TABLE to get the current size.\r
513 //\r
514 return GetPtrTypeSize (TmpTokenNumber, &MaxSize);\r
515 } else {\r
516 return Size;\r
517 }\r
518\r
519}\r
520\r
2ab6330e 521/**\r
522 Retrieves an 8-bit value for a given PCD token.\r
523\r
d1102dba 524 Retrieves the 8-bit value of a particular PCD token.\r
2ab6330e 525 If the TokenNumber is invalid or the token space\r
d1102dba 526 specified by Guid does not exist, the results are\r
2ab6330e 527 unpredictable.\r
80408db0 528\r
2ab6330e 529 @param[in] Guid The token space for the token number.\r
d1102dba 530 @param[in] ExTokenNumber The PCD token number.\r
80408db0 531\r
2ab6330e 532 @return The size 8-bit value for the PCD token.\r
d1102dba 533\r
2ab6330e 534**/\r
80408db0 535UINT8\r
536EFIAPI\r
537DxePcdGet8Ex (\r
538 IN CONST EFI_GUID *Guid,\r
2ab6330e 539 IN UINTN ExTokenNumber\r
80408db0 540 )\r
541{\r
542 return *((UINT8 *) ExGetWorker (Guid, ExTokenNumber, sizeof(UINT8)));\r
543}\r
544\r
2ab6330e 545/**\r
546 Retrieves an 16-bit value for a given PCD token.\r
547\r
d1102dba 548 Retrieves the 16-bit value of a particular PCD token.\r
2ab6330e 549 If the TokenNumber is invalid or the token space\r
d1102dba 550 specified by Guid does not exist, the results are\r
2ab6330e 551 unpredictable.\r
80408db0 552\r
2ab6330e 553 @param[in] Guid The token space for the token number.\r
d1102dba 554 @param[in] ExTokenNumber The PCD token number.\r
80408db0 555\r
2ab6330e 556 @return The size 16-bit value for the PCD token.\r
d1102dba 557\r
2ab6330e 558**/\r
80408db0 559UINT16\r
560EFIAPI\r
561DxePcdGet16Ex (\r
562 IN CONST EFI_GUID *Guid,\r
563 IN UINTN ExTokenNumber\r
564 )\r
565{\r
566 return ReadUnaligned16 (ExGetWorker (Guid, ExTokenNumber, sizeof(UINT16)));\r
567}\r
568\r
2ab6330e 569/**\r
570 Retrieves an 32-bit value for a given PCD token.\r
571\r
d1102dba 572 Retrieves the 32-bit value of a particular PCD token.\r
2ab6330e 573 If the TokenNumber is invalid or the token space\r
d1102dba 574 specified by Guid does not exist, the results are\r
2ab6330e 575 unpredictable.\r
80408db0 576\r
2ab6330e 577 @param[in] Guid The token space for the token number.\r
d1102dba 578 @param[in] ExTokenNumber The PCD token number.\r
80408db0 579\r
2ab6330e 580 @return The size 32-bit value for the PCD token.\r
d1102dba 581\r
2ab6330e 582**/\r
80408db0 583UINT32\r
584EFIAPI\r
585DxePcdGet32Ex (\r
586 IN CONST EFI_GUID *Guid,\r
587 IN UINTN ExTokenNumber\r
588 )\r
589{\r
590 return ReadUnaligned32 (ExGetWorker (Guid, ExTokenNumber, sizeof(UINT32)));\r
591}\r
592\r
2ab6330e 593/**\r
594 Retrieves an 64-bit value for a given PCD token.\r
80408db0 595\r
d1102dba 596 Retrieves the 64-bit value of a particular PCD token.\r
2ab6330e 597 If the TokenNumber is invalid or the token space\r
d1102dba 598 specified by Guid does not exist, the results are\r
2ab6330e 599 unpredictable.\r
80408db0 600\r
2ab6330e 601 @param[in] Guid The token space for the token number.\r
d1102dba 602 @param[in] ExTokenNumber The PCD token number.\r
2ab6330e 603\r
604 @return The size 64-bit value for the PCD token.\r
d1102dba 605\r
2ab6330e 606**/\r
80408db0 607UINT64\r
608EFIAPI\r
609DxePcdGet64Ex (\r
610 IN CONST EFI_GUID *Guid,\r
611 IN UINTN ExTokenNumber\r
612 )\r
613{\r
614 return ReadUnaligned64 (ExGetWorker (Guid, ExTokenNumber, sizeof(UINT64)));\r
615}\r
616\r
2ab6330e 617/**\r
618 Retrieves a pointer to a value for a given PCD token.\r
619\r
d1102dba
LG
620 Retrieves the current pointer to the buffer for a PCD token number.\r
621 Do not make any assumptions about the alignment of the pointer that\r
622 is returned by this function call. If the TokenNumber is invalid,\r
2ab6330e 623 the results are unpredictable.\r
80408db0 624\r
2ab6330e 625 @param[in] Guid The token space for the token number.\r
d1102dba 626 @param[in] ExTokenNumber The PCD token number.\r
80408db0 627\r
2ab6330e 628 @return The pointer to the buffer to be retrived.\r
d1102dba 629\r
2ab6330e 630**/\r
80408db0 631VOID *\r
632EFIAPI\r
633DxePcdGetPtrEx (\r
634 IN CONST EFI_GUID *Guid,\r
635 IN UINTN ExTokenNumber\r
636 )\r
637{\r
638 return ExGetWorker (Guid, ExTokenNumber, 0);\r
639}\r
640\r
2ab6330e 641/**\r
642 Retrieves an Boolean value for a given PCD token.\r
80408db0 643\r
d1102dba 644 Retrieves the Boolean value of a particular PCD token.\r
2ab6330e 645 If the TokenNumber is invalid or the token space\r
d1102dba 646 specified by Guid does not exist, the results are\r
2ab6330e 647 unpredictable.\r
80408db0 648\r
2ab6330e 649 @param[in] Guid The token space for the token number.\r
d1102dba 650 @param[in] ExTokenNumber The PCD token number.\r
2ab6330e 651\r
652 @return The size Boolean value for the PCD token.\r
d1102dba 653\r
2ab6330e 654**/\r
80408db0 655BOOLEAN\r
656EFIAPI\r
657DxePcdGetBoolEx (\r
658 IN CONST EFI_GUID *Guid,\r
659 IN UINTN ExTokenNumber\r
660 )\r
661{\r
662 return *((BOOLEAN *) ExGetWorker (Guid, ExTokenNumber, sizeof(BOOLEAN)));\r
663}\r
664\r
2ab6330e 665/**\r
666 Retrieves the size of the value for a given PCD token.\r
667\r
d1102dba 668 Retrieves the current size of a particular PCD token.\r
2ab6330e 669 If the TokenNumber is invalid, the results are unpredictable.\r
80408db0 670\r
2ab6330e 671 @param[in] Guid The token space for the token number.\r
d1102dba 672 @param[in] ExTokenNumber The PCD token number.\r
80408db0 673\r
2ab6330e 674 @return The size of the value for the PCD token.\r
d1102dba 675\r
2ab6330e 676**/\r
80408db0 677UINTN\r
678EFIAPI\r
679DxePcdGetSizeEx (\r
680 IN CONST EFI_GUID *Guid,\r
681 IN UINTN ExTokenNumber\r
682 )\r
683{\r
684 return DxePcdGetSize(GetExPcdTokenNumber (Guid, (UINT32) ExTokenNumber));\r
685}\r
686\r
2ab6330e 687/**\r
688 Sets an 8-bit value for a given PCD token.\r
689\r
d1102dba
LG
690 When the PCD service sets a value, it will check to ensure that the\r
691 size of the value being set is compatible with the Token's existing definition.\r
2ab6330e 692 If it is not, an error will be returned.\r
80408db0 693\r
d1102dba 694 @param[in] TokenNumber The PCD token number.\r
2ab6330e 695 @param[in] Value The value to set for the PCD token.\r
80408db0 696\r
2ab6330e 697 @retval EFI_SUCCESS Procedure returned successfully.\r
d1102dba
LG
698 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data\r
699 being set was incompatible with a call to this function.\r
2ab6330e 700 Use GetSize() to retrieve the size of the target data.\r
701 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.\r
d1102dba 702\r
2ab6330e 703**/\r
80408db0 704EFI_STATUS\r
705EFIAPI\r
706DxePcdSet8 (\r
707 IN UINTN TokenNumber,\r
708 IN UINT8 Value\r
709 )\r
710{\r
711 return SetValueWorker (TokenNumber, &Value, sizeof (Value));\r
712}\r
713\r
2ab6330e 714/**\r
715 Sets an 16-bit value for a given PCD token.\r
80408db0 716\r
d1102dba
LG
717 When the PCD service sets a value, it will check to ensure that the\r
718 size of the value being set is compatible with the Token's existing definition.\r
2ab6330e 719 If it is not, an error will be returned.\r
80408db0 720\r
d1102dba 721 @param[in] TokenNumber The PCD token number.\r
2ab6330e 722 @param[in] Value The value to set for the PCD token.\r
723\r
724 @retval EFI_SUCCESS Procedure returned successfully.\r
d1102dba
LG
725 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data\r
726 being set was incompatible with a call to this function.\r
2ab6330e 727 Use GetSize() to retrieve the size of the target data.\r
728 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.\r
d1102dba 729\r
2ab6330e 730**/\r
80408db0 731EFI_STATUS\r
732EFIAPI\r
733DxePcdSet16 (\r
734 IN UINTN TokenNumber,\r
735 IN UINT16 Value\r
736 )\r
737{\r
738 return SetValueWorker (TokenNumber, &Value, sizeof (Value));\r
739}\r
740\r
2ab6330e 741/**\r
742 Sets an 32-bit value for a given PCD token.\r
743\r
d1102dba
LG
744 When the PCD service sets a value, it will check to ensure that the\r
745 size of the value being set is compatible with the Token's existing definition.\r
2ab6330e 746 If it is not, an error will be returned.\r
80408db0 747\r
d1102dba 748 @param[in] TokenNumber The PCD token number.\r
2ab6330e 749 @param[in] Value The value to set for the PCD token.\r
80408db0 750\r
2ab6330e 751 @retval EFI_SUCCESS Procedure returned successfully.\r
d1102dba
LG
752 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data\r
753 being set was incompatible with a call to this function.\r
2ab6330e 754 Use GetSize() to retrieve the size of the target data.\r
755 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.\r
d1102dba 756\r
2ab6330e 757**/\r
80408db0 758EFI_STATUS\r
759EFIAPI\r
760DxePcdSet32 (\r
761 IN UINTN TokenNumber,\r
762 IN UINT32 Value\r
763 )\r
764{\r
765 return SetValueWorker (TokenNumber, &Value, sizeof (Value));\r
766}\r
767\r
2ab6330e 768/**\r
769 Sets an 64-bit value for a given PCD token.\r
80408db0 770\r
d1102dba
LG
771 When the PCD service sets a value, it will check to ensure that the\r
772 size of the value being set is compatible with the Token's existing definition.\r
2ab6330e 773 If it is not, an error will be returned.\r
80408db0 774\r
d1102dba 775 @param[in] TokenNumber The PCD token number.\r
2ab6330e 776 @param[in] Value The value to set for the PCD token.\r
777\r
778 @retval EFI_SUCCESS Procedure returned successfully.\r
d1102dba
LG
779 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data\r
780 being set was incompatible with a call to this function.\r
2ab6330e 781 Use GetSize() to retrieve the size of the target data.\r
782 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.\r
d1102dba 783\r
2ab6330e 784**/\r
80408db0 785EFI_STATUS\r
786EFIAPI\r
787DxePcdSet64 (\r
788 IN UINTN TokenNumber,\r
789 IN UINT64 Value\r
790 )\r
791{\r
792 return SetValueWorker (TokenNumber, &Value, sizeof (Value));\r
793}\r
794\r
2ab6330e 795/**\r
796 Sets a value of a specified size for a given PCD token.\r
797\r
d1102dba
LG
798 When the PCD service sets a value, it will check to ensure that the\r
799 size of the value being set is compatible with the Token's existing definition.\r
2ab6330e 800 If it is not, an error will be returned.\r
801\r
d1102dba
LG
802 @param[in] TokenNumber The PCD token number.\r
803 @param[in, out] SizeOfBuffer A pointer to the length of the value being set for the PCD token.\r
804 On input, if the SizeOfValue is greater than the maximum size supported\r
805 for this TokenNumber then the output value of SizeOfValue will reflect\r
2ab6330e 806 the maximum size supported for this TokenNumber.\r
807 @param[in] Buffer The buffer to set for the PCD token.\r
808\r
809 @retval EFI_SUCCESS Procedure returned successfully.\r
d1102dba
LG
810 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data\r
811 being set was incompatible with a call to this function.\r
2ab6330e 812 Use GetSize() to retrieve the size of the target data.\r
813 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.\r
d1102dba 814\r
2ab6330e 815**/\r
80408db0 816EFI_STATUS\r
817EFIAPI\r
818DxePcdSetPtr (\r
819 IN UINTN TokenNumber,\r
820 IN OUT UINTN *SizeOfBuffer,\r
821 IN VOID *Buffer\r
822 )\r
823{\r
824 return SetWorker (TokenNumber, Buffer, SizeOfBuffer, TRUE);\r
825}\r
826\r
2ab6330e 827/**\r
828 Sets an Boolean value for a given PCD token.\r
80408db0 829\r
d1102dba
LG
830 When the PCD service sets a value, it will check to ensure that the\r
831 size of the value being set is compatible with the Token's existing definition.\r
2ab6330e 832 If it is not, an error will be returned.\r
80408db0 833\r
d1102dba 834 @param[in] TokenNumber The PCD token number.\r
2ab6330e 835 @param[in] Value The value to set for the PCD token.\r
836\r
837 @retval EFI_SUCCESS Procedure returned successfully.\r
d1102dba
LG
838 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data\r
839 being set was incompatible with a call to this function.\r
2ab6330e 840 Use GetSize() to retrieve the size of the target data.\r
841 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.\r
d1102dba 842\r
2ab6330e 843**/\r
80408db0 844EFI_STATUS\r
845EFIAPI\r
846DxePcdSetBool (\r
847 IN UINTN TokenNumber,\r
848 IN BOOLEAN Value\r
849 )\r
850{\r
851 return SetValueWorker (TokenNumber, &Value, sizeof (Value));\r
852}\r
853\r
2ab6330e 854/**\r
855 Sets an 8-bit value for a given PCD token.\r
856\r
d1102dba
LG
857 When the PCD service sets a value, it will check to ensure that the\r
858 size of the value being set is compatible with the Token's existing definition.\r
2ab6330e 859 If it is not, an error will be returned.\r
80408db0 860\r
2ab6330e 861 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.\r
d1102dba 862 @param[in] ExTokenNumber The PCD token number.\r
2ab6330e 863 @param[in] Value The value to set for the PCD token.\r
80408db0 864\r
2ab6330e 865 @retval EFI_SUCCESS Procedure returned successfully.\r
d1102dba
LG
866 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data\r
867 being set was incompatible with a call to this function.\r
2ab6330e 868 Use GetSize() to retrieve the size of the target data.\r
869 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.\r
d1102dba 870\r
2ab6330e 871**/\r
80408db0 872EFI_STATUS\r
873EFIAPI\r
874DxePcdSet8Ex (\r
875 IN CONST EFI_GUID *Guid,\r
876 IN UINTN ExTokenNumber,\r
877 IN UINT8 Value\r
878 )\r
879{\r
880 return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value));\r
881}\r
882\r
2ab6330e 883/**\r
884 Sets an 16-bit value for a given PCD token.\r
80408db0 885\r
d1102dba
LG
886 When the PCD service sets a value, it will check to ensure that the\r
887 size of the value being set is compatible with the Token's existing definition.\r
2ab6330e 888 If it is not, an error will be returned.\r
80408db0 889\r
2ab6330e 890 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.\r
d1102dba 891 @param[in] ExTokenNumber The PCD token number.\r
2ab6330e 892 @param[in] Value The value to set for the PCD token.\r
893\r
894 @retval EFI_SUCCESS Procedure returned successfully.\r
d1102dba
LG
895 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data\r
896 being set was incompatible with a call to this function.\r
2ab6330e 897 Use GetSize() to retrieve the size of the target data.\r
898 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.\r
d1102dba 899\r
2ab6330e 900**/\r
80408db0 901EFI_STATUS\r
902EFIAPI\r
903DxePcdSet16Ex (\r
904 IN CONST EFI_GUID *Guid,\r
905 IN UINTN ExTokenNumber,\r
906 IN UINT16 Value\r
907 )\r
908{\r
425084cd
SZ
909 //\r
910 // PcdSetNvStoreDefaultId should be set in PEI phase to take effect.\r
911 //\r
912 ASSERT (!(CompareGuid (Guid, &gEfiMdeModulePkgTokenSpaceGuid) &&\r
913 (ExTokenNumber == PcdToken(PcdSetNvStoreDefaultId))));\r
80408db0 914 return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value));\r
915}\r
916\r
2ab6330e 917/**\r
918 Sets an 32-bit value for a given PCD token.\r
919\r
d1102dba
LG
920 When the PCD service sets a value, it will check to ensure that the\r
921 size of the value being set is compatible with the Token's existing definition.\r
2ab6330e 922 If it is not, an error will be returned.\r
80408db0 923\r
2ab6330e 924 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.\r
d1102dba 925 @param[in] ExTokenNumber The PCD token number.\r
2ab6330e 926 @param[in] Value The value to set for the PCD token.\r
80408db0 927\r
2ab6330e 928 @retval EFI_SUCCESS Procedure returned successfully.\r
d1102dba
LG
929 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data\r
930 being set was incompatible with a call to this function.\r
2ab6330e 931 Use GetSize() to retrieve the size of the target data.\r
932 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.\r
d1102dba 933\r
2ab6330e 934**/\r
80408db0 935EFI_STATUS\r
936EFIAPI\r
937DxePcdSet32Ex (\r
938 IN CONST EFI_GUID *Guid,\r
939 IN UINTN ExTokenNumber,\r
940 IN UINT32 Value\r
941 )\r
942{\r
943 return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value));\r
944}\r
945\r
2ab6330e 946/**\r
947 Sets an 64-bit value for a given PCD token.\r
948\r
d1102dba
LG
949 When the PCD service sets a value, it will check to ensure that the\r
950 size of the value being set is compatible with the Token's existing definition.\r
2ab6330e 951 If it is not, an error will be returned.\r
80408db0 952\r
2ab6330e 953 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.\r
d1102dba 954 @param[in] ExTokenNumber The PCD token number.\r
2ab6330e 955 @param[in] Value The value to set for the PCD token.\r
80408db0 956\r
2ab6330e 957 @retval EFI_SUCCESS Procedure returned successfully.\r
d1102dba
LG
958 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data\r
959 being set was incompatible with a call to this function.\r
2ab6330e 960 Use GetSize() to retrieve the size of the target data.\r
961 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.\r
d1102dba 962\r
2ab6330e 963**/\r
80408db0 964EFI_STATUS\r
965EFIAPI\r
966DxePcdSet64Ex (\r
967 IN CONST EFI_GUID *Guid,\r
968 IN UINTN ExTokenNumber,\r
969 IN UINT64 Value\r
970 )\r
971{\r
972 return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value));\r
973}\r
974\r
2ab6330e 975/**\r
976 Sets a value of a specified size for a given PCD token.\r
977\r
d1102dba
LG
978 When the PCD service sets a value, it will check to ensure that the\r
979 size of the value being set is compatible with the Token's existing definition.\r
2ab6330e 980 If it is not, an error will be returned.\r
981\r
982 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.\r
d1102dba
LG
983 @param[in] ExTokenNumber The PCD token number.\r
984 @param[in, out] SizeOfBuffer A pointer to the length of the value being set for the PCD token.\r
985 On input, if the SizeOfValue is greater than the maximum size supported\r
986 for this TokenNumber then the output value of SizeOfValue will reflect\r
2ab6330e 987 the maximum size supported for this TokenNumber.\r
988 @param[in] Buffer The buffer to set for the PCD token.\r
989\r
990 @retval EFI_SUCCESS Procedure returned successfully.\r
d1102dba
LG
991 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data\r
992 being set was incompatible with a call to this function.\r
2ab6330e 993 Use GetSize() to retrieve the size of the target data.\r
994 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.\r
d1102dba 995\r
2ab6330e 996**/\r
80408db0 997EFI_STATUS\r
998EFIAPI\r
999DxePcdSetPtrEx (\r
1000 IN CONST EFI_GUID *Guid,\r
1001 IN UINTN ExTokenNumber,\r
1002 IN OUT UINTN *SizeOfBuffer,\r
1003 IN VOID *Buffer\r
1004 )\r
1005{\r
1006 return ExSetWorker(ExTokenNumber, Guid, Buffer, SizeOfBuffer, TRUE);\r
1007}\r
1008\r
2ab6330e 1009/**\r
1010 Sets an Boolean value for a given PCD token.\r
80408db0 1011\r
d1102dba
LG
1012 When the PCD service sets a value, it will check to ensure that the\r
1013 size of the value being set is compatible with the Token's existing definition.\r
2ab6330e 1014 If it is not, an error will be returned.\r
80408db0 1015\r
2ab6330e 1016 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.\r
d1102dba 1017 @param[in] ExTokenNumber The PCD token number.\r
2ab6330e 1018 @param[in] Value The value to set for the PCD token.\r
1019\r
1020 @retval EFI_SUCCESS Procedure returned successfully.\r
d1102dba
LG
1021 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data\r
1022 being set was incompatible with a call to this function.\r
2ab6330e 1023 Use GetSize() to retrieve the size of the target data.\r
1024 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.\r
d1102dba 1025\r
2ab6330e 1026**/\r
80408db0 1027EFI_STATUS\r
1028EFIAPI\r
1029DxePcdSetBoolEx (\r
1030 IN CONST EFI_GUID *Guid,\r
1031 IN UINTN ExTokenNumber,\r
1032 IN BOOLEAN Value\r
1033 )\r
1034{\r
1035 return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value));\r
1036}\r
1037\r
2ab6330e 1038/**\r
1039 Specifies a function to be called anytime the value of a designated token is changed.\r
80408db0 1040\r
2ab6330e 1041 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.\r
d1102dba
LG
1042 @param[in] TokenNumber The PCD token number.\r
1043 @param[in] CallBackFunction The function prototype called when the value associated with the CallBackToken is set.\r
80408db0 1044\r
d1102dba 1045 @retval EFI_SUCCESS The PCD service has successfully established a call event\r
2ab6330e 1046 for the CallBackToken requested.\r
1047 @retval EFI_NOT_FOUND The PCD service could not find the referenced token number.\r
80408db0 1048\r
2ab6330e 1049**/\r
80408db0 1050EFI_STATUS\r
1051EFIAPI\r
1052DxeRegisterCallBackOnSet (\r
1053 IN CONST EFI_GUID *Guid, OPTIONAL\r
1054 IN UINTN TokenNumber,\r
1055 IN PCD_PROTOCOL_CALLBACK CallBackFunction\r
1056 )\r
1057{\r
1058 EFI_STATUS Status;\r
d1102dba 1059\r
e4a3922f 1060 if (CallBackFunction == NULL) {\r
1061 return EFI_INVALID_PARAMETER;\r
1062 }\r
80408db0 1063 //\r
1064 // Aquire lock to prevent reentrance from TPL_CALLBACK level\r
1065 //\r
1066 EfiAcquireLock (&mPcdDatabaseLock);\r
1067\r
1068 Status = DxeRegisterCallBackWorker (TokenNumber, Guid, CallBackFunction);\r
1069\r
1070 EfiReleaseLock (&mPcdDatabaseLock);\r
d1102dba 1071\r
80408db0 1072 return Status;\r
1073}\r
1074\r
2ab6330e 1075/**\r
1076 Cancels a previously set callback function for a particular PCD token number.\r
80408db0 1077\r
2ab6330e 1078 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.\r
d1102dba
LG
1079 @param[in] TokenNumber The PCD token number.\r
1080 @param[in] CallBackFunction The function prototype called when the value associated with the CallBackToken is set.\r
80408db0 1081\r
d1102dba 1082 @retval EFI_SUCCESS The PCD service has successfully established a call event\r
2ab6330e 1083 for the CallBackToken requested.\r
1084 @retval EFI_NOT_FOUND The PCD service could not find the referenced token number.\r
1085\r
1086**/\r
80408db0 1087EFI_STATUS\r
1088EFIAPI\r
1089DxeUnRegisterCallBackOnSet (\r
1090 IN CONST EFI_GUID *Guid, OPTIONAL\r
1091 IN UINTN TokenNumber,\r
1092 IN PCD_PROTOCOL_CALLBACK CallBackFunction\r
1093 )\r
1094{\r
1095 EFI_STATUS Status;\r
d1102dba 1096\r
e4a3922f 1097 if (CallBackFunction == NULL) {\r
1098 return EFI_INVALID_PARAMETER;\r
1099 }\r
80408db0 1100\r
1101 //\r
1102 // Aquire lock to prevent reentrance from TPL_CALLBACK level\r
1103 //\r
1104 EfiAcquireLock (&mPcdDatabaseLock);\r
d1102dba 1105\r
80408db0 1106 Status = DxeUnRegisterCallBackWorker (TokenNumber, Guid, CallBackFunction);\r
1107\r
1108 EfiReleaseLock (&mPcdDatabaseLock);\r
d1102dba 1109\r
80408db0 1110 return Status;\r
1111}\r
1112\r
2ab6330e 1113/**\r
d1102dba
LG
1114 Retrieves the next valid token number in a given namespace.\r
1115\r
1116 This is useful since the PCD infrastructure contains a sparse list of token numbers,\r
1117 and one cannot a priori know what token numbers are valid in the database.\r
1118\r
1119 If TokenNumber is 0 and Guid is not NULL, then the first token from the token space specified by Guid is returned.\r
1120 If TokenNumber is not 0 and Guid is not NULL, then the next token in the token space specified by Guid is returned.\r
1121 If TokenNumber is 0 and Guid is NULL, then the first token in the default token space is returned.\r
1122 If TokenNumber is not 0 and Guid is NULL, then the next token in the default token space is returned.\r
1123 The token numbers in the default token space may not be related to token numbers in token spaces that are named by Guid.\r
1124 If the next token number can be retrieved, then it is returned in TokenNumber, and EFI_SUCCESS is returned.\r
1125 If TokenNumber represents the last token number in the token space specified by Guid, then EFI_NOT_FOUND is returned.\r
90e06556 1126 If TokenNumber is not present in the token space specified by Guid, then EFI_NOT_FOUND is returned.\r
1127\r
1128\r
d1102dba
LG
1129 @param[in] Guid The 128-bit unique value that designates the namespace from which to retrieve the next token.\r
1130 This is an optional parameter that may be NULL. If this parameter is NULL, then a request is\r
90e06556 1131 being made to retrieve tokens from the default token space.\r
d1102dba
LG
1132 @param[in, out] TokenNumber\r
1133 A pointer to the PCD token number to use to find the subsequent token number.\r
90e06556 1134\r
419db80b
BF
1135 @retval EFI_SUCCESS The PCD service has retrieved the next valid token number.\r
1136 @retval EFI_NOT_FOUND The PCD service could not find data from the requested token number.\r
2ab6330e 1137\r
1138**/\r
80408db0 1139EFI_STATUS\r
1140EFIAPI\r
1141DxePcdGetNextToken (\r
1142 IN CONST EFI_GUID *Guid, OPTIONAL\r
1143 IN OUT UINTN *TokenNumber\r
1144 )\r
1145{\r
1146 EFI_STATUS Status;\r
1147 BOOLEAN PeiExMapTableEmpty;\r
1148 BOOLEAN DxeExMapTableEmpty;\r
1149\r
80408db0 1150 Status = EFI_NOT_FOUND;\r
419db80b
BF
1151 PeiExMapTableEmpty = mPeiExMapTableEmpty;\r
1152 DxeExMapTableEmpty = mDxeExMapTableEmpty;\r
80408db0 1153\r
1154 //\r
1155 // Scan the local token space\r
1156 //\r
1157 if (Guid == NULL) {\r
1158 // EBC compiler is very choosy. It may report warning about comparison\r
d1102dba 1159 // between UINTN and 0 . So we add 1 in each size of the\r
80408db0 1160 // comparison.\r
419db80b
BF
1161 if (((*TokenNumber + 1 > mPeiNexTokenCount + 1) && (*TokenNumber + 1 <= mPeiLocalTokenCount + 1)) ||\r
1162 ((*TokenNumber + 1 > (mPeiLocalTokenCount + mDxeNexTokenCount + 1)))) {\r
1163 return EFI_NOT_FOUND;\r
80408db0 1164 }\r
d1102dba 1165\r
80408db0 1166 (*TokenNumber)++;\r
419db80b
BF
1167 if ((*TokenNumber + 1 > mPeiNexTokenCount + 1) &&\r
1168 (*TokenNumber + 1 <= mPeiLocalTokenCount + 1)) {\r
80408db0 1169 //\r
d1102dba 1170 // The first Non-Ex type Token Number for DXE PCD\r
419db80b 1171 // database is mPeiLocalTokenCount + 1\r
80408db0 1172 //\r
419db80b
BF
1173 if (mDxeNexTokenCount > 0) {\r
1174 *TokenNumber = mPeiLocalTokenCount + 1;\r
1175 } else {\r
1176 *TokenNumber = PCD_INVALID_TOKEN_NUMBER;\r
1177 return EFI_NOT_FOUND;\r
1178 }\r
1179 } else if (*TokenNumber + 1 > mDxeNexTokenCount + mPeiLocalTokenCount + 1) {\r
80408db0 1180 *TokenNumber = PCD_INVALID_TOKEN_NUMBER;\r
419db80b 1181 return EFI_NOT_FOUND;\r
80408db0 1182 }\r
1183 return EFI_SUCCESS;\r
1184 }\r
1185\r
1186 if (PeiExMapTableEmpty && DxeExMapTableEmpty) {\r
80408db0 1187 return EFI_NOT_FOUND;\r
1188 }\r
1189\r
1190 if (!PeiExMapTableEmpty) {\r
1191 Status = ExGetNextTokeNumber (\r
1192 Guid,\r
1193 TokenNumber,\r
419db80b
BF
1194 (EFI_GUID *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->GuidTableOffset),\r
1195 mPeiGuidTableSize,\r
1196 (DYNAMICEX_MAPPING *)((UINT8 *) mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->ExMapTableOffset),\r
1197 mPeiExMapppingTableSize\r
80408db0 1198 );\r
1199 }\r
1200\r
1201 if (Status == EFI_SUCCESS) {\r
1202 return Status;\r
1203 }\r
1204\r
1205 if (!DxeExMapTableEmpty) {\r
1206 Status = ExGetNextTokeNumber (\r
1207 Guid,\r
1208 TokenNumber,\r
419db80b
BF
1209 (EFI_GUID *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->GuidTableOffset),\r
1210 mDxeGuidTableSize,\r
1211 (DYNAMICEX_MAPPING *)((UINT8 *) mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->ExMapTableOffset),\r
1212 mDxeExMapppingTableSize\r
80408db0 1213 );\r
1214 }\r
1215\r
1216 return Status;\r
1217}\r
1218\r
2ab6330e 1219/**\r
1220 Get all token space guid table which is different with given token space guid.\r
1221\r
419db80b 1222 @param ExMapTableSize The size of ExMapTable in item\r
2ab6330e 1223 @param ExMapTable Token space guid table that want to be scaned.\r
1224 @param GuidTable Guid table\r
1225\r
1226 @return all token space guid table which is different with given token space guid.\r
1227\r
1228**/\r
80408db0 1229EFI_GUID **\r
1230GetDistinctTokenSpace (\r
1231 IN OUT UINTN *ExMapTableSize,\r
1232 IN DYNAMICEX_MAPPING *ExMapTable,\r
1233 IN EFI_GUID *GuidTable\r
1234 )\r
1235{\r
1236 EFI_GUID **DistinctTokenSpace;\r
1237 UINTN OldGuidIndex;\r
1238 UINTN TsIdx;\r
419db80b 1239 UINTN TempTsIdx;\r
80408db0 1240 UINTN Idx;\r
419db80b 1241 BOOLEAN Match;\r
80408db0 1242\r
1243 DistinctTokenSpace = AllocateZeroPool (*ExMapTableSize * sizeof (EFI_GUID *));\r
1244 ASSERT (DistinctTokenSpace != NULL);\r
1245\r
1246 TsIdx = 0;\r
1247 OldGuidIndex = ExMapTable[0].ExGuidIndex;\r
1248 DistinctTokenSpace[TsIdx] = &GuidTable[OldGuidIndex];\r
1249 for (Idx = 1; Idx < *ExMapTableSize; Idx++) {\r
419db80b
BF
1250 Match = FALSE;\r
1251 OldGuidIndex = ExMapTable[Idx].ExGuidIndex;\r
1252 for (TempTsIdx = 0; TempTsIdx <= TsIdx; TempTsIdx++) {\r
1253 if (&GuidTable[OldGuidIndex] == DistinctTokenSpace[TempTsIdx]) {\r
1254 //\r
1255 // Have recorded this GUID.\r
1256 //\r
1257 Match = TRUE;\r
1258 break;\r
1259 }\r
1260 }\r
1261 if (!Match) {\r
80408db0 1262 DistinctTokenSpace[++TsIdx] = &GuidTable[OldGuidIndex];\r
1263 }\r
1264 }\r
1265\r
1266 //\r
1267 // The total number of Distinct Token Space\r
1268 // is TsIdx + 1 because we use TsIdx as a index\r
1269 // to the DistinctTokenSpace[]\r
1270 //\r
1271 *ExMapTableSize = TsIdx + 1;\r
1272 return DistinctTokenSpace;\r
d1102dba 1273\r
80408db0 1274}\r
d1102dba 1275\r
2ab6330e 1276/**\r
419db80b
BF
1277 Retrieves the next valid PCD token namespace for a given namespace.\r
1278\r
1279 Gets the next valid token namespace for a given namespace. This is useful to traverse the valid\r
1280 token namespaces on a platform.\r
1281\r
1282 @param[in, out] Guid An indirect pointer to EFI_GUID. On input it designates a known token\r
1283 namespace from which the search will start. On output, it designates the next valid\r
1284 token namespace on the platform. If *Guid is NULL, then the GUID of the first token\r
1285 space of the current platform is returned. If the search cannot locate the next valid\r
1286 token namespace, an error is returned and the value of *Guid is undefined.\r
d1102dba 1287\r
419db80b
BF
1288 @retval EFI_SUCCESS The PCD service retrieved the value requested.\r
1289 @retval EFI_NOT_FOUND The PCD service could not find the next valid token namespace.\r
1290\r
2ab6330e 1291**/\r
80408db0 1292EFI_STATUS\r
1293EFIAPI\r
1294DxePcdGetNextTokenSpace (\r
1295 IN OUT CONST EFI_GUID **Guid\r
1296 )\r
1297{\r
1298 UINTN Idx;\r
1299 UINTN Idx2;\r
1300 UINTN Idx3;\r
1301 UINTN PeiTokenSpaceTableSize;\r
1302 UINTN DxeTokenSpaceTableSize;\r
1303 EFI_GUID **PeiTokenSpaceTable;\r
1304 EFI_GUID **DxeTokenSpaceTable;\r
1305 BOOLEAN Match;\r
1306 BOOLEAN PeiExMapTableEmpty;\r
1307 BOOLEAN DxeExMapTableEmpty;\r
1308\r
80408db0 1309 ASSERT (Guid != NULL);\r
d1102dba 1310\r
419db80b
BF
1311 PeiExMapTableEmpty = mPeiExMapTableEmpty;\r
1312 DxeExMapTableEmpty = mDxeExMapTableEmpty;\r
80408db0 1313\r
1314 if (PeiExMapTableEmpty && DxeExMapTableEmpty) {\r
419db80b 1315 return EFI_NOT_FOUND;\r
80408db0 1316 }\r
d1102dba 1317\r
80408db0 1318 if (TmpTokenSpaceBuffer[0] == NULL) {\r
1319 PeiTokenSpaceTableSize = 0;\r
1320\r
1321 if (!PeiExMapTableEmpty) {\r
419db80b 1322 PeiTokenSpaceTableSize = mPeiExMapppingTableSize / sizeof(DYNAMICEX_MAPPING);\r
80408db0 1323 PeiTokenSpaceTable = GetDistinctTokenSpace (&PeiTokenSpaceTableSize,\r
419db80b
BF
1324 (DYNAMICEX_MAPPING *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->ExMapTableOffset),\r
1325 (EFI_GUID *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->GuidTableOffset)\r
80408db0 1326 );\r
1327 CopyMem (TmpTokenSpaceBuffer, PeiTokenSpaceTable, sizeof (EFI_GUID*) * PeiTokenSpaceTableSize);\r
da0df6ca 1328 TmpTokenSpaceBufferCount = PeiTokenSpaceTableSize;\r
419db80b 1329 FreePool (PeiTokenSpaceTable);\r
80408db0 1330 }\r
1331\r
1332 if (!DxeExMapTableEmpty) {\r
419db80b 1333 DxeTokenSpaceTableSize = mDxeExMapppingTableSize / sizeof(DYNAMICEX_MAPPING);\r
80408db0 1334 DxeTokenSpaceTable = GetDistinctTokenSpace (&DxeTokenSpaceTableSize,\r
419db80b
BF
1335 (DYNAMICEX_MAPPING *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->ExMapTableOffset),\r
1336 (EFI_GUID *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->GuidTableOffset)\r
80408db0 1337 );\r
1338\r
1339 //\r
1340 // Make sure EFI_GUID in DxeTokenSpaceTable does not exist in PeiTokenSpaceTable\r
1341 //\r
1342 for (Idx2 = 0, Idx3 = PeiTokenSpaceTableSize; Idx2 < DxeTokenSpaceTableSize; Idx2++) {\r
1343 Match = FALSE;\r
1344 for (Idx = 0; Idx < PeiTokenSpaceTableSize; Idx++) {\r
1345 if (CompareGuid (TmpTokenSpaceBuffer[Idx], DxeTokenSpaceTable[Idx2])) {\r
1346 Match = TRUE;\r
1347 break;\r
1348 }\r
1349 }\r
1350 if (!Match) {\r
1351 TmpTokenSpaceBuffer[Idx3++] = DxeTokenSpaceTable[Idx2];\r
1352 }\r
1353 }\r
419db80b
BF
1354\r
1355 TmpTokenSpaceBufferCount = Idx3;\r
1356 FreePool (DxeTokenSpaceTable);\r
80408db0 1357 }\r
1358 }\r
1359\r
1360 if (*Guid == NULL) {\r
1361 *Guid = TmpTokenSpaceBuffer[0];\r
1362 return EFI_SUCCESS;\r
1363 }\r
d1102dba 1364\r
419db80b
BF
1365 for (Idx = 0; Idx < TmpTokenSpaceBufferCount; Idx++) {\r
1366 if (CompareGuid (*Guid, TmpTokenSpaceBuffer[Idx])) {\r
1367 if (Idx == TmpTokenSpaceBufferCount - 1) {\r
1368 //\r
1369 // It has been the last token namespace.\r
1370 //\r
1371 *Guid = NULL;\r
1372 return EFI_NOT_FOUND;\r
1373 } else {\r
1374 Idx++;\r
1375 *Guid = TmpTokenSpaceBuffer[Idx];\r
1376 return EFI_SUCCESS;\r
1377 }\r
80408db0 1378 }\r
1379 }\r
1380\r
1381 return EFI_NOT_FOUND;\r
80408db0 1382}\r
1383\r
1384\r