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