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