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