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