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