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