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