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