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