-/** @file\r
-Private functions used by PCD PEIM.\r
-\r
-Copyright (c) 2006, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-\r
-Module Name: Service.c\r
-\r
-**/\r
-#include "Service.h"\r
-\r
-/**\r
- The function registers the CallBackOnSet fucntion\r
- according to TokenNumber and EFI_GUID space.\r
-\r
- @param TokenNumber The token number.\r
- @param Guid The GUID space.\r
- @param CallBackFunction The Callback function to be registered.\r
- @param Register To register or unregister the callback function.\r
-\r
- @retval EFI_SUCCESS If the Callback function is registered.\r
- @retval EFI_NOT_FOUND If the PCD Entry is not found according to Token Number and GUID space.\r
- @retval EFI_OUT_OF_RESOURCES If the callback function can't be registered because there is not free\r
- slot left in the CallbackFnTable.\r
---*/\r
-EFI_STATUS\r
-PeiRegisterCallBackWorker (\r
- IN UINTN ExTokenNumber,\r
- IN CONST EFI_GUID *Guid, OPTIONAL\r
- IN PCD_PPI_CALLBACK CallBackFunction,\r
- IN BOOLEAN Register\r
-)\r
-{\r
- EFI_HOB_GUID_TYPE *GuidHob;\r
- PCD_PPI_CALLBACK *CallbackTable;\r
- PCD_PPI_CALLBACK Compare;\r
- PCD_PPI_CALLBACK Assign;\r
- UINT32 LocalTokenNumber;\r
- UINTN TokenNumber;\r
- UINTN Idx;\r
-\r
- if (Guid == NULL) {\r
- TokenNumber = ExTokenNumber;\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
- ASSERT (TokenNumber + 1 < PEI_NEX_TOKEN_NUMBER + 1);\r
- } else {\r
- TokenNumber = GetExPcdTokenNumber (Guid, ExTokenNumber);\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
- // EBC compiler is very choosy. It may report warning about comparison\r
- // between UINTN and 0 . So we add 1 in each size of the \r
- // comparison.\r
- ASSERT (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);\r
- }\r
-\r
-\r
- LocalTokenNumber = GetPcdDatabase()->Init.LocalTokenNumberTable[TokenNumber];\r
-\r
- //\r
- // We don't support SET for HII and VPD type PCD entry in PEI phase.\r
- // So we will assert if any register callback for such PCD entry.\r
- //\r
- ASSERT ((LocalTokenNumber & PCD_TYPE_HII) == 0);\r
- ASSERT ((LocalTokenNumber & PCD_TYPE_VPD) == 0);\r
-\r
- GuidHob = GetFirstGuidHob (&gPcdPeiCallbackFnTableHobGuid);\r
- ASSERT (GuidHob != NULL);\r
- \r
- CallbackTable = GET_GUID_HOB_DATA (GuidHob);\r
- CallbackTable = CallbackTable + (TokenNumber * FixedPcdGet32(PcdMaxPeiPcdCallBackNumberPerPcdEntry));\r
-\r
- Compare = Register? NULL: CallBackFunction;\r
- Assign = Register? CallBackFunction: NULL;\r
-\r
-\r
- for (Idx = 0; Idx < FixedPcdGet32(PcdMaxPeiPcdCallBackNumberPerPcdEntry); Idx++) {\r
- if (CallbackTable[Idx] == Compare) {\r
- CallbackTable[Idx] = Assign;\r
- return EFI_SUCCESS;\r
- }\r
- }\r
-\r
- return Register? EFI_OUT_OF_RESOURCES : EFI_NOT_FOUND;\r
-\r
-}\r
-\r
-\r
-\r
-\r
-/**\r
- The function builds the PCD database.\r
-\r
- @param VOID\r
-\r
- @retval VOID\r
---*/\r
-VOID\r
-BuildPcdDatabase (\r
- VOID\r
- )\r
-{\r
- PEI_PCD_DATABASE *Database;\r
- VOID *CallbackFnTable;\r
- UINTN SizeOfCallbackFnTable;\r
- \r
- Database = BuildGuidHob (&gPcdDataBaseHobGuid, sizeof (PEI_PCD_DATABASE));\r
-\r
- ZeroMem (Database, sizeof (PEI_PCD_DATABASE));\r
-\r
- //\r
- // gPEIPcdDbInit is smaller than PEI_PCD_DATABASE\r
- //\r
- \r
- CopyMem (&Database->Init, &gPEIPcdDbInit, sizeof (gPEIPcdDbInit));\r
-\r
- SizeOfCallbackFnTable = PEI_LOCAL_TOKEN_NUMBER * sizeof (PCD_PPI_CALLBACK) * FixedPcdGet32(PcdMaxPeiPcdCallBackNumberPerPcdEntry);\r
-\r
- CallbackFnTable = BuildGuidHob (&gPcdPeiCallbackFnTableHobGuid, SizeOfCallbackFnTable);\r
- \r
- ZeroMem (CallbackFnTable, SizeOfCallbackFnTable);\r
- \r
- return;\r
-}\r
-\r
-\r
-\r
-/**\r
- The function is provided by PCD PEIM and PCD DXE driver to\r
- do the work of reading a HII variable from variable service.\r
-\r
- @param VariableGuid The Variable GUID.\r
- @param VariableName The Variable Name.\r
- @param VariableData The output data.\r
- @param VariableSize The size of the variable.\r
-\r
- @retval EFI_SUCCESS Operation successful.\r
- @retval EFI_NOT_FOUND Variablel not found.\r
---*/\r
-STATIC\r
-EFI_STATUS\r
-GetHiiVariable (\r
- IN CONST EFI_GUID *VariableGuid,\r
- IN UINT16 *VariableName,\r
- OUT VOID **VariableData,\r
- OUT UINTN *VariableSize\r
- )\r
-{\r
- UINTN Size;\r
- EFI_STATUS Status;\r
- VOID *Buffer;\r
- EFI_PEI_READ_ONLY_VARIABLE_PPI *VariablePpi;\r
-\r
- Status = PeiServicesLocatePpi (&gEfiPeiReadOnlyVariablePpiGuid, 0, NULL, (VOID **) &VariablePpi);\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- Size = 0;\r
- Status = VariablePpi->PeiGetVariable (\r
- GetPeiServicesTablePointer (),\r
- VariableName,\r
- (EFI_GUID *) VariableGuid,\r
- NULL,\r
- &Size,\r
- NULL\r
- );\r
- if (Status == EFI_BUFFER_TOO_SMALL) {\r
-\r
-\r
- Status = PeiServicesAllocatePool (Size, &Buffer);\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- Status = VariablePpi->PeiGetVariable (\r
- GetPeiServicesTablePointer (),\r
- (UINT16 *) VariableName,\r
- (EFI_GUID *) VariableGuid,\r
- NULL,\r
- &Size,\r
- Buffer\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- *VariableSize = Size;\r
- *VariableData = Buffer;\r
-\r
- return EFI_SUCCESS;\r
- } else {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
-}\r
-\r
-STATIC\r
-UINT32\r
-GetSkuEnabledTokenNumber (\r
- UINT32 LocalTokenNumber,\r
- UINTN Size\r
- ) \r
-{\r
- PEI_PCD_DATABASE *PeiPcdDb;\r
- SKU_HEAD *SkuHead;\r
- SKU_ID *SkuIdTable;\r
- INTN i;\r
- UINT8 *Value;\r
-\r
- PeiPcdDb = GetPcdDatabase ();\r
-\r
- ASSERT ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0);\r
-\r
- SkuHead = (SKU_HEAD *) ((UINT8 *)PeiPcdDb + (LocalTokenNumber & PCD_DATABASE_OFFSET_MASK));\r
- Value = (UINT8 *) ((UINT8 *)PeiPcdDb + (SkuHead->SkuDataStartOffset));\r
- SkuIdTable = (SKU_ID *) ((UINT8 *)PeiPcdDb + (SkuHead->SkuIdTableOffset));\r
- \r
- for (i = 0; i < SkuIdTable[0]; i++) {\r
- if (PeiPcdDb->Init.SystemSkuId == SkuIdTable[i + 1]) {\r
- break;\r
- }\r
- }\r
-\r
- switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {\r
- case PCD_TYPE_VPD:\r
- Value = (UINT8 *) &(((VPD_HEAD *) Value)[i]);\r
- return (UINT32) ((Value - (UINT8 *) PeiPcdDb) | PCD_TYPE_VPD);\r
-\r
- case PCD_TYPE_HII:\r
- Value = (UINT8 *) &(((VARIABLE_HEAD *) Value)[i]);\r
- return (UINT32) ((Value - (UINT8 *) PeiPcdDb) | PCD_TYPE_HII);\r
- \r
- case PCD_TYPE_STRING:\r
- Value = (UINT8 *) &(((STRING_HEAD *) Value)[i]);\r
- return (UINT32) ((Value - (UINT8 *) PeiPcdDb) | PCD_TYPE_STRING);\r
-\r
- case PCD_TYPE_DATA:\r
- Value += Size * i;\r
- return (UINT32) (Value - (UINT8 *) PeiPcdDb);\r
-\r
- default:\r
- ASSERT (FALSE);\r
- }\r
-\r
- ASSERT (FALSE);\r
-\r
- return 0;\r
- \r
-}\r
-\r
-\r
-\r
-STATIC\r
-VOID\r
-InvokeCallbackOnSet (\r
- UINTN ExTokenNumber,\r
- CONST EFI_GUID *Guid, OPTIONAL\r
- UINTN TokenNumber,\r
- VOID *Data,\r
- UINTN Size\r
- )\r
-{\r
- EFI_HOB_GUID_TYPE *GuidHob;\r
- PCD_PPI_CALLBACK *CallbackTable;\r
- UINTN Idx;\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
- if (Guid == NULL) {\r
- // EBC compiler is very choosy. It may report warning about comparison\r
- // between UINTN and 0 . So we add 1 in each size of the \r
- // comparison.\r
- ASSERT (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);\r
- }\r
-\r
- GuidHob = GetFirstGuidHob (&gPcdPeiCallbackFnTableHobGuid);\r
- ASSERT (GuidHob != NULL);\r
- \r
- CallbackTable = GET_GUID_HOB_DATA (GuidHob);\r
-\r
- CallbackTable += (TokenNumber * FixedPcdGet32(PcdMaxPeiPcdCallBackNumberPerPcdEntry));\r
-\r
- for (Idx = 0; Idx < FixedPcdGet32(PcdMaxPeiPcdCallBackNumberPerPcdEntry); Idx++) {\r
- if (CallbackTable[Idx] != NULL) {\r
- CallbackTable[Idx] (Guid,\r
- (Guid == NULL)? TokenNumber: ExTokenNumber,\r
- Data,\r
- Size\r
- );\r
- }\r
- }\r
- \r
-}\r
-\r
-\r
-\r
-EFI_STATUS\r
-SetValueWorker (\r
- IN UINTN TokenNumber,\r
- IN VOID *Data,\r
- IN UINTN Size\r
- )\r
-{\r
- return SetWorker (TokenNumber, Data, &Size, FALSE);\r
-}\r
-\r
-\r
-\r
-EFI_STATUS\r
-SetWorker (\r
- IN UINTN TokenNumber,\r
- IN OUT VOID *Data,\r
- IN OUT UINTN *Size,\r
- IN BOOLEAN PtrType\r
- )\r
-{\r
- UINT32 LocalTokenNumber;\r
- PEI_PCD_DATABASE *PeiPcdDb;\r
- UINT16 StringTableIdx;\r
- UINTN Offset;\r
- VOID *InternalData;\r
- UINTN MaxSize;\r
-\r
- if (!FeaturePcdGet(PcdPeiPcdDatabaseSetEnabled)) {\r
- return EFI_UNSUPPORTED;\r
- }\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
- // EBC compiler is very choosy. It may report warning about comparison\r
- // between UINTN and 0 . So we add 1 in each size of the \r
- // comparison.\r
- ASSERT (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);\r
- \r
- PeiPcdDb = GetPcdDatabase ();\r
-\r
- LocalTokenNumber = PeiPcdDb->Init.LocalTokenNumberTable[TokenNumber];\r
-\r
- if (!PtrType) {\r
- ASSERT (PeiPcdGetSize(TokenNumber + 1) == *Size);\r
- }\r
-\r
- //\r
- // We only invoke the callback function for Dynamic Type PCD Entry.\r
- // For Dynamic EX PCD entry, we have invoked the callback function for Dynamic EX\r
- // type PCD entry in ExSetWorker.\r
- //\r
- if (TokenNumber + 1 < PEI_NEX_TOKEN_NUMBER + 1) {\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
- MaxSize = GetPtrTypeSize (TokenNumber, &MaxSize, PeiPcdDb);\r
- } else {\r
- MaxSize = *Size;\r
- }\r
- LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize);\r
- }\r
-\r
- Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;\r
- InternalData = (VOID *) ((UINT8 *) PeiPcdDb + Offset);\r
- \r
- switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {\r
- case PCD_TYPE_VPD:\r
- case PCD_TYPE_HII:\r
- {\r
- ASSERT (FALSE);\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- case PCD_TYPE_STRING:\r
- if (SetPtrTypeSize (TokenNumber, Size, PeiPcdDb)) {\r
- StringTableIdx = *((UINT16 *)InternalData);\r
- CopyMem (&PeiPcdDb->Init.StringTable[StringTableIdx], Data, *Size);\r
- return EFI_SUCCESS;\r
- } else {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- case PCD_TYPE_DATA:\r
- {\r
- if (PtrType) {\r
- if (SetPtrTypeSize (TokenNumber, Size, PeiPcdDb)) {\r
- CopyMem (InternalData, Data, *Size);\r
- return EFI_SUCCESS;\r
- } else {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- }\r
-\r
- switch (*Size) {\r
- case sizeof(UINT8):\r
- *((UINT8 *) InternalData) = *((UINT8 *) Data);\r
- return EFI_SUCCESS;\r
-\r
- case sizeof(UINT16):\r
- *((UINT16 *) InternalData) = *((UINT16 *) Data);\r
- return EFI_SUCCESS;\r
-\r
- case sizeof(UINT32):\r
- *((UINT32 *) InternalData) = *((UINT32 *) Data);\r
- return EFI_SUCCESS;\r
-\r
- case sizeof(UINT64):\r
- *((UINT64 *) InternalData) = *((UINT64 *) Data);\r
- return EFI_SUCCESS;\r
-\r
- default:\r
- ASSERT (FALSE);\r
- return EFI_NOT_FOUND;\r
- }\r
- }\r
- \r
- }\r
-\r
- ASSERT (FALSE);\r
- return EFI_NOT_FOUND;\r
-\r
-}\r
-\r
-\r
-\r
-EFI_STATUS\r
-ExSetValueWorker (\r
- IN UINTN ExTokenNumber,\r
- IN CONST EFI_GUID *Guid,\r
- IN VOID *Data,\r
- IN UINTN Size\r
- )\r
-{\r
- return ExSetWorker (ExTokenNumber, Guid, Data, &Size, FALSE);\r
-}\r
-\r
-\r
-\r
-EFI_STATUS\r
-ExSetWorker (\r
- IN UINTN ExTokenNumber,\r
- IN CONST EFI_GUID *Guid,\r
- IN VOID *Data,\r
- IN OUT UINTN *Size,\r
- IN BOOLEAN PtrType\r
- )\r
-{\r
- UINTN TokenNumber;\r
-\r
- if (!FeaturePcdGet(PcdPeiPcdDatabaseSetEnabled)) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- TokenNumber = GetExPcdTokenNumber (Guid, ExTokenNumber);\r
-\r
- InvokeCallbackOnSet (ExTokenNumber, Guid, TokenNumber, Data, *Size);\r
-\r
- return SetWorker (TokenNumber, Data, Size, PtrType);\r
-\r
-}\r
-\r
-\r
-\r
-\r
-VOID *\r
-ExGetWorker (\r
- IN CONST EFI_GUID *Guid,\r
- IN UINTN ExTokenNumber,\r
- IN UINTN GetSize\r
- )\r
-{\r
- if (!FeaturePcdGet (PcdPeiPcdDatabaseExEnabled)) {\r
- ASSERT (FALSE);\r
- return 0;\r
- }\r
- \r
- return GetWorker (GetExPcdTokenNumber (Guid, ExTokenNumber), GetSize);\r
-}\r
-\r
-\r
-\r
-\r
-VOID *\r
-GetWorker (\r
- UINTN TokenNumber,\r
- UINTN GetSize\r
- )\r
-{\r
- UINT32 Offset;\r
- EFI_GUID *Guid;\r
- UINT16 *Name;\r
- VARIABLE_HEAD *VariableHead;\r
- EFI_STATUS Status;\r
- UINTN DataSize;\r
- VOID *Data;\r
- UINT16 *StringTable;\r
- UINT16 StringTableIdx;\r
- PEI_PCD_DATABASE *PeiPcdDb;\r
- UINT32 LocalTokenNumber;\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
- // EBC compiler is very choosy. It may report warning about comparison\r
- // between UINTN and 0 . So we add 1 in each size of the \r
- // comparison.\r
- ASSERT (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);\r
-\r
- ASSERT ((GetSize == PeiPcdGetSize(TokenNumber + 1)) || (GetSize == 0));\r
-\r
- PeiPcdDb = GetPcdDatabase ();\r
-\r
- LocalTokenNumber = PeiPcdDb->Init.LocalTokenNumberTable[TokenNumber];\r
-\r
- if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {\r
- if (GetSize == 0) {\r
- MaxSize = GetPtrTypeSize (TokenNumber, &MaxSize, PeiPcdDb);\r
- } else {\r
- MaxSize = GetSize;\r
- }\r
- LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize);\r
- }\r
-\r
- Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;\r
- StringTable = PeiPcdDb->Init.StringTable;\r
- \r
- switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {\r
- case PCD_TYPE_VPD:\r
- {\r
- VPD_HEAD *VpdHead;\r
- VpdHead = (VPD_HEAD *) ((UINT8 *)PeiPcdDb + Offset);\r
- return (VOID *) (UINTN) (FixedPcdGet32(PcdVpdBaseAddress) + VpdHead->Offset);\r
- }\r
- \r
- case PCD_TYPE_HII:\r
- {\r
- VariableHead = (VARIABLE_HEAD *) ((UINT8 *)PeiPcdDb + Offset);\r
- \r
- Guid = &(PeiPcdDb->Init.GuidTable[VariableHead->GuidTableIndex]);\r
- Name = &StringTable[VariableHead->StringIndex];\r
-\r
- Status = GetHiiVariable (Guid, Name, &Data, &DataSize);\r
-\r
- if (Status == EFI_SUCCESS) {\r
- return (VOID *) ((UINT8 *) Data + VariableHead->Offset);\r
- } else {\r
- //\r
- // Return the default value specified by Platform Integrator \r
- //\r
- return (VOID *) ((UINT8 *) PeiPcdDb + VariableHead->DefaultValueOffset);\r
- }\r
- }\r
-\r
- case PCD_TYPE_DATA:\r
- return (VOID *) ((UINT8 *)PeiPcdDb + Offset);\r
-\r
- case PCD_TYPE_STRING:\r
- StringTableIdx = (UINT16) *((UINT8 *) PeiPcdDb + Offset);\r
- return (VOID *) (&StringTable[StringTableIdx]);\r
-\r
- default:\r
- ASSERT (FALSE);\r
- break;\r
- \r
- }\r
-\r
- ASSERT (FALSE);\r
- \r
- return NULL;\r
- \r
-}\r
-\r
-\r
-\r
-UINTN \r
-GetExPcdTokenNumber (\r
- IN CONST EFI_GUID *Guid,\r
- IN UINTN ExTokenNumber\r
- )\r
-{\r
- UINT32 i;\r
- DYNAMICEX_MAPPING *ExMap;\r
- EFI_GUID *GuidTable;\r
- EFI_GUID *MatchGuid;\r
- UINTN MatchGuidIdx;\r
- PEI_PCD_DATABASE *PeiPcdDb;\r
-\r
- PeiPcdDb = GetPcdDatabase();\r
- \r
- ExMap = PeiPcdDb->Init.ExMapTable;\r
- GuidTable = PeiPcdDb->Init.GuidTable;\r
-\r
- MatchGuid = ScanGuid (GuidTable, sizeof(PeiPcdDb->Init.GuidTable), Guid);\r
- //\r
- // We need to ASSERT here. If GUID can't be found in GuidTable, this is a\r
- // error in the BUILD system.\r
- //\r
- ASSERT (MatchGuid != NULL);\r
- \r
- MatchGuidIdx = MatchGuid - GuidTable;\r
- \r
- for (i = 0; i < PEI_EXMAPPING_TABLE_SIZE; i++) {\r
- if ((ExTokenNumber == ExMap[i].ExTokenNumber) && \r
- (MatchGuidIdx == ExMap[i].ExGuidIndex)) {\r
- return ExMap[i].LocalTokenNumber;\r
- }\r
- }\r
- \r
- ASSERT (FALSE);\r
- \r
- return 0;\r
-}\r
-\r
-\r
-\r
-PEI_PCD_DATABASE *\r
-GetPcdDatabase (\r
- VOID\r
- )\r
-{\r
- EFI_HOB_GUID_TYPE *GuidHob;\r
-\r
- GuidHob = GetFirstGuidHob (&gPcdDataBaseHobGuid);\r
- ASSERT (GuidHob != NULL);\r
- \r
- return (PEI_PCD_DATABASE *) GET_GUID_HOB_DATA (GuidHob);\r
-}\r
-\r
-\r
-\r
-SKU_ID *\r
-GetSkuIdArray (\r
- IN UINTN LocalTokenNumberTableIdx,\r
- IN PEI_PCD_DATABASE *Database\r
- )\r
-{\r
- SKU_HEAD *SkuHead;\r
- UINTN LocalTokenNumber;\r
-\r
- LocalTokenNumber = Database->Init.LocalTokenNumberTable[LocalTokenNumberTableIdx];\r
-\r
- ASSERT ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) != 0);\r
-\r
- SkuHead = (SKU_HEAD *) ((UINT8 *)Database + (LocalTokenNumber & PCD_DATABASE_OFFSET_MASK));\r
-\r
- return (SKU_ID *) ((UINT8 *)Database + SkuHead->SkuIdTableOffset);\r
- \r
-}\r
-\r
-\r
-\r
-UINTN\r
-GetSizeTableIndex (\r
- IN UINTN LocalTokenNumberTableIdx,\r
- IN PEI_PCD_DATABASE *Database\r
- )\r
-{\r
- UINTN i;\r
- UINTN SizeTableIdx;\r
- UINTN LocalTokenNumber;\r
- SKU_ID *SkuIdTable;\r
- \r
- SizeTableIdx = 0;\r
-\r
- for (i=0; i<LocalTokenNumberTableIdx; i++) {\r
- LocalTokenNumber = Database->Init.LocalTokenNumberTable[i];\r
-\r
- if ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER) {\r
- //\r
- // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type \r
- // PCD entry.\r
- //\r
- if (LocalTokenNumber & PCD_TYPE_VPD) {\r
- //\r
- // We have only one entry for VPD enabled PCD entry:\r
- // 1) MAX Size.\r
- // We consider current size is equal to MAX size.\r
- //\r
- SizeTableIdx++;\r
- } else {\r
- if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0) {\r
- //\r
- // We have only two entry for Non-Sku enabled PCD entry:\r
- // 1) MAX SIZE\r
- // 2) Current Size\r
- //\r
- SizeTableIdx += 2;\r
- } else {\r
- //\r
- // We have these entry for SKU enabled PCD entry\r
- // 1) MAX SIZE\r
- // 2) Current Size for each SKU_ID (It is equal to MaxSku).\r
- //\r
- SkuIdTable = GetSkuIdArray (i, Database);\r
- SizeTableIdx += (UINTN)*SkuIdTable + 1;\r
- }\r
- }\r
- }\r
-\r
- }\r
-\r
- return SizeTableIdx;\r
-}\r