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