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