\r
#include "Service.h"\r
\r
+/**\r
+ Get Local Token Number by Token Number.\r
+\r
+ @param[in] Database PCD database.\r
+ @param[in] TokenNumber The PCD token number.\r
+\r
+ @return Local Token Number.\r
+**/\r
+UINT32\r
+GetLocalTokenNumber (\r
+ IN PEI_PCD_DATABASE *Database,\r
+ IN UINTN TokenNumber\r
+ )\r
+{\r
+ UINT32 LocalTokenNumber;\r
+ UINTN Size;\r
+ UINTN MaxSize;\r
+\r
+ //\r
+ // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
+ // We have to decrement TokenNumber by 1 to make it usable\r
+ // as the array index.\r
+ //\r
+ TokenNumber--;\r
+\r
+ LocalTokenNumber = *((UINT32 *)((UINT8 *)Database + Database->LocalTokenNumberTableOffset) + TokenNumber);\r
+\r
+ Size = (LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) >> PCD_DATUM_TYPE_SHIFT;\r
+\r
+ if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {\r
+ if (Size == 0) {\r
+ GetPtrTypeSize (TokenNumber, &MaxSize, Database);\r
+ } else {\r
+ MaxSize = Size;\r
+ }\r
+ LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize);\r
+ }\r
+\r
+ return LocalTokenNumber;\r
+}\r
+\r
+/**\r
+ Get PCD type by Local Token Number.\r
+\r
+ @param[in] LocalTokenNumber The PCD local token number.\r
+\r
+ @return PCD type.\r
+**/\r
+EFI_PCD_TYPE\r
+GetPcdType (\r
+ IN UINT32 LocalTokenNumber\r
+ )\r
+{\r
+ switch (LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) {\r
+ case PCD_DATUM_TYPE_POINTER:\r
+ return EFI_PCD_TYPE_PTR;\r
+ case PCD_DATUM_TYPE_UINT8:\r
+ if (LocalTokenNumber & PCD_DATUM_TYPE_UINT8_BOOLEAN) {\r
+ return EFI_PCD_TYPE_BOOL;\r
+ } else {\r
+ return EFI_PCD_TYPE_8;\r
+ }\r
+ case PCD_DATUM_TYPE_UINT16:\r
+ return EFI_PCD_TYPE_16;\r
+ case PCD_DATUM_TYPE_UINT32:\r
+ return EFI_PCD_TYPE_32;\r
+ case PCD_DATUM_TYPE_UINT64:\r
+ return EFI_PCD_TYPE_64;\r
+ default:\r
+ ASSERT (FALSE);\r
+ return EFI_PCD_TYPE_8;\r
+ }\r
+}\r
+\r
+/**\r
+ Get PCD name.\r
+\r
+ @param[in] OnlyTokenSpaceName If TRUE, only need to get the TokenSpaceCName.\r
+ If FALSE, need to get the full PCD name.\r
+ @param[in] Database PCD database.\r
+ @param[in] TokenNumber The PCD token number.\r
+\r
+ @return The TokenSpaceCName or full PCD name.\r
+**/\r
+CHAR8 *\r
+GetPcdName (\r
+ IN BOOLEAN OnlyTokenSpaceName,\r
+ IN PEI_PCD_DATABASE *Database,\r
+ IN UINTN TokenNumber\r
+ )\r
+{\r
+ UINT8 *StringTable;\r
+ PCD_NAME_INDEX *PcdNameIndex;\r
+ CHAR8 *TokenSpaceName;\r
+ CHAR8 *PcdName;\r
+ CHAR8 *Name;\r
+\r
+ //\r
+ // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
+ // We have to decrement TokenNumber by 1 to make it usable\r
+ // as the array index.\r
+ //\r
+ TokenNumber--;\r
+\r
+ StringTable = (UINT8 *) Database + Database->StringTableOffset;\r
+\r
+ //\r
+ // Get the PCD name index.\r
+ //\r
+ PcdNameIndex = (PCD_NAME_INDEX *)((UINT8 *) Database + Database->PcdNameTableOffset) + TokenNumber;\r
+ TokenSpaceName = (CHAR8 *)&StringTable[PcdNameIndex->TokenSpaceCNameIndex];\r
+ PcdName = (CHAR8 *)&StringTable[PcdNameIndex->PcdCNameIndex];\r
+\r
+ if (OnlyTokenSpaceName) {\r
+ //\r
+ // Only need to get the TokenSpaceCName.\r
+ //\r
+ Name = AllocateCopyPool (AsciiStrSize (TokenSpaceName), TokenSpaceName);\r
+ } else {\r
+ //\r
+ // Need to get the full PCD name.\r
+ //\r
+ Name = AllocateZeroPool (AsciiStrSize (TokenSpaceName) + AsciiStrSize (PcdName));\r
+ //\r
+ // Catenate TokenSpaceCName and PcdCName with a '.' to form the full PCD name.\r
+ //\r
+ AsciiStrCat (Name, TokenSpaceName);\r
+ Name[AsciiStrSize (TokenSpaceName) - sizeof (CHAR8)] = '.';\r
+ AsciiStrCat (Name, PcdName); \r
+ }\r
+\r
+ return Name;\r
+}\r
+\r
+/**\r
+ Retrieve additional information associated with a PCD token.\r
+\r
+ This includes information such as the type of value the TokenNumber is associated with as well as possible\r
+ human readable name that is associated with the token.\r
+\r
+ @param[in] Database PCD database.\r
+ @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.\r
+ @param[in] TokenNumber The PCD token number.\r
+ @param[out] PcdInfo The returned information associated with the requested TokenNumber.\r
+ The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName. \r
+\r
+ @retval EFI_SUCCESS The PCD information was returned successfully\r
+ @retval EFI_NOT_FOUND The PCD service could not find the requested token number.\r
+**/\r
+EFI_STATUS\r
+ExGetPcdInfo (\r
+ IN PEI_PCD_DATABASE *Database,\r
+ IN CONST EFI_GUID *Guid,\r
+ IN UINTN TokenNumber,\r
+ OUT EFI_PCD_INFO *PcdInfo\r
+ )\r
+{\r
+ UINTN GuidTableIdx;\r
+ EFI_GUID *MatchGuid;\r
+ EFI_GUID *GuidTable;\r
+ DYNAMICEX_MAPPING *ExMapTable;\r
+ UINTN Index;\r
+ UINT32 LocalTokenNumber;\r
+\r
+ GuidTable = (EFI_GUID *)((UINT8 *)Database + Database->GuidTableOffset);\r
+ MatchGuid = ScanGuid (GuidTable, Database->GuidTableCount * sizeof(EFI_GUID), Guid);\r
+\r
+ if (MatchGuid == NULL) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ GuidTableIdx = MatchGuid - GuidTable;\r
+\r
+ ExMapTable = (DYNAMICEX_MAPPING *)((UINT8 *)Database + Database->ExMapTableOffset);\r
+\r
+ //\r
+ // Find the PCD by GuidTableIdx and ExTokenNumber in ExMapTable.\r
+ //\r
+ for (Index = 0; Index < Database->ExTokenCount; Index++) {\r
+ if (ExMapTable[Index].ExGuidIndex == GuidTableIdx) {\r
+ if (TokenNumber == PCD_INVALID_TOKEN_NUMBER) {\r
+ //\r
+ // TokenNumber is 0, follow spec to set PcdType to EFI_PCD_TYPE_8,\r
+ // PcdSize to 0 and PcdName to the null-terminated ASCII string\r
+ // associated with the token's namespace Guid.\r
+ //\r
+ PcdInfo->PcdType = EFI_PCD_TYPE_8;\r
+ PcdInfo->PcdSize = 0;\r
+ //\r
+ // Here use one representative in the token space to get the TokenSpaceCName.\r
+ // \r
+ PcdInfo->PcdName = GetPcdName (TRUE, Database, ExMapTable[Index].TokenNumber);\r
+ return EFI_SUCCESS;\r
+ } else if (ExMapTable[Index].ExTokenNumber == TokenNumber) {\r
+ PcdInfo->PcdSize = PeiPcdGetSize (ExMapTable[Index].TokenNumber);\r
+ LocalTokenNumber = GetLocalTokenNumber (Database, ExMapTable[Index].TokenNumber);\r
+ PcdInfo->PcdType = GetPcdType (LocalTokenNumber);\r
+ PcdInfo->PcdName = GetPcdName (FALSE, Database, ExMapTable[Index].TokenNumber);\r
+ return EFI_SUCCESS;\r
+ }\r
+ }\r
+ }\r
+\r
+ return EFI_NOT_FOUND;\r
+}\r
+\r
+/**\r
+ Retrieve additional information associated with a PCD token.\r
+\r
+ This includes information such as the type of value the TokenNumber is associated with as well as possible\r
+ human readable name that is associated with the token.\r
+\r
+ @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.\r
+ @param[in] TokenNumber The PCD token number.\r
+ @param[out] PcdInfo The returned information associated with the requested TokenNumber.\r
+ The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.\r
+\r
+ @retval EFI_SUCCESS The PCD information was returned successfully.\r
+ @retval EFI_NOT_FOUND The PCD service could not find the requested token number.\r
+**/\r
+EFI_STATUS\r
+PeiGetPcdInfo (\r
+ IN CONST EFI_GUID *Guid,\r
+ IN UINTN TokenNumber,\r
+ OUT EFI_PCD_INFO *PcdInfo\r
+ )\r
+{\r
+ PEI_PCD_DATABASE *PeiPcdDb;\r
+ BOOLEAN PeiExMapTableEmpty;\r
+ UINTN PeiNexTokenNumber;\r
+ UINT32 LocalTokenNumber;\r
+\r
+ if (!FeaturePcdGet (PcdPcdInfoGeneration)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ ASSERT (PcdInfo != NULL);\r
+\r
+ PeiPcdDb = GetPcdDatabase ();\r
+ PeiNexTokenNumber = PeiPcdDb->LocalTokenCount - PeiPcdDb->ExTokenCount;\r
+\r
+ if (PeiPcdDb->ExTokenCount == 0) {\r
+ PeiExMapTableEmpty = TRUE;\r
+ } else {\r
+ PeiExMapTableEmpty = FALSE;\r
+ }\r
+\r
+ if (Guid == NULL) {\r
+ if (TokenNumber > PeiNexTokenNumber) {\r
+ return EFI_NOT_FOUND;\r
+ } else if (TokenNumber == PCD_INVALID_TOKEN_NUMBER) {\r
+ //\r
+ // TokenNumber is 0, follow spec to set PcdType to EFI_PCD_TYPE_8,\r
+ // PcdSize to 0 and PcdName to NULL for default Token Space.\r
+ //\r
+ PcdInfo->PcdType = EFI_PCD_TYPE_8;\r
+ PcdInfo->PcdSize = 0;\r
+ PcdInfo->PcdName = NULL;\r
+ } else {\r
+ PcdInfo->PcdSize = PeiPcdGetSize (TokenNumber);\r
+ LocalTokenNumber = GetLocalTokenNumber (PeiPcdDb, TokenNumber);\r
+ PcdInfo->PcdType = GetPcdType (LocalTokenNumber);\r
+ PcdInfo->PcdName = GetPcdName (FALSE, PeiPcdDb, TokenNumber);\r
+ }\r
+ return EFI_SUCCESS;\r
+ } else {\r
+ if (PeiExMapTableEmpty) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+ return ExGetPcdInfo (\r
+ PeiPcdDb,\r
+ Guid,\r
+ TokenNumber,\r
+ PcdInfo\r
+ );\r
+ }\r
+}\r
+\r
/**\r
The function registers the CallBackOnSet fucntion\r
according to TokenNumber and EFI_GUID space.\r
\r
@param FileHandle Handle of the file the external PCD database binary located.\r
\r
+ @return Pointer to PCD database.\r
**/\r
-VOID\r
+PEI_PCD_DATABASE *\r
BuildPcdDatabase (\r
IN EFI_PEI_FILE_HANDLE FileHandle\r
)\r
CallbackFnTable = BuildGuidHob (&gEfiCallerIdGuid, SizeOfCallbackFnTable);\r
\r
ZeroMem (CallbackFnTable, SizeOfCallbackFnTable);\r
+\r
+ return Database;\r
}\r
\r
/**\r
// comparison.\r
ASSERT (TokenNumber + 1 < (LocalTokenCount + 1));\r
\r
- LocalTokenNumber = *((UINT32 *)((UINT8 *)PeiPcdDb + PeiPcdDb->LocalTokenNumberTableOffset) + TokenNumber);\r
-\r
if (PtrType) {\r
//\r
// Get MaxSize first, then check new size with max buffer size.\r
InvokeCallbackOnSet (0, NULL, TokenNumber + 1, Data, *Size);\r
}\r
\r
- if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {\r
- if (PtrType) {\r
- GetPtrTypeSize (TokenNumber, &MaxSize, PeiPcdDb);\r
- } else {\r
- MaxSize = *Size;\r
- }\r
- LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize);\r
- }\r
+ LocalTokenNumber = GetLocalTokenNumber (PeiPcdDb, TokenNumber + 1);\r
\r
Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;\r
InternalData = (VOID *) ((UINT8 *) PeiPcdDb + Offset);\r
STRING_HEAD StringTableIdx;\r
PEI_PCD_DATABASE *PeiPcdDb;\r
UINT32 LocalTokenNumber;\r
- UINTN MaxSize;\r
UINT32 LocalTokenCount;\r
\r
//\r
\r
ASSERT ((GetSize == PeiPcdGetSize(TokenNumber + 1)) || (GetSize == 0));\r
\r
- LocalTokenNumber = *((UINT32 *)((UINT8 *)PeiPcdDb + PeiPcdDb->LocalTokenNumberTableOffset) + TokenNumber);\r
-\r
- if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {\r
- if (GetSize == 0) {\r
- GetPtrTypeSize (TokenNumber, &MaxSize, PeiPcdDb);\r
- } else {\r
- MaxSize = GetSize;\r
- }\r
- LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize);\r
- }\r
+ LocalTokenNumber = GetLocalTokenNumber (PeiPcdDb, TokenNumber + 1);\r
\r
Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;\r
StringTable = (UINT8 *)PeiPcdDb + PeiPcdDb->StringTableOffset;\r