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