X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=EdkModulePkg%2FUniversal%2FPCD%2FPei%2FService.c;h=e705c283cb8be05db457c158abd2cd2edd823400;hp=a85d1d1786a22d3bea2c179cacce6531f27014a5;hb=3401c092e4e98b97bcf86d9aa2500d5ee7b3b8cf;hpb=1eb73ab57aa6d49cd82eb2b3305ec39bba591d1f diff --git a/EdkModulePkg/Universal/PCD/Pei/Service.c b/EdkModulePkg/Universal/PCD/Pei/Service.c index a85d1d1786..e705c283cb 100644 --- a/EdkModulePkg/Universal/PCD/Pei/Service.c +++ b/EdkModulePkg/Universal/PCD/Pei/Service.c @@ -20,12 +20,15 @@ Module Name: Service.c The function registers the CallBackOnSet fucntion according to TokenNumber and EFI_GUID space. - @param[in] TokenNumber The token number. - @param[in] Guid The GUID space. - @param[in] CallBackFunction The Callback function to be registered. + @param TokenNumber The token number. + @param Guid The GUID space. + @param CallBackFunction The Callback function to be registered. + @param Register To register or unregister the callback function. @retval EFI_SUCCESS If the Callback function is registered. @retval EFI_NOT_FOUND If the PCD Entry is not found according to Token Number and GUID space. + @retval EFI_OUT_OF_RESOURCES If the callback function can't be registered because there is not free + slot left in the CallbackFnTable. --*/ EFI_STATUS PeiRegisterCallBackWorker ( @@ -52,7 +55,7 @@ PeiRegisterCallBackWorker ( // as the array index. // TokenNumber--; - ASSERT (TokenNumber < PEI_NEX_TOKEN_NUMBER); + ASSERT (TokenNumber + 1 < PEI_NEX_TOKEN_NUMBER + 1); } else { TokenNumber = GetExPcdTokenNumber (Guid, ExTokenNumber); @@ -62,12 +65,19 @@ PeiRegisterCallBackWorker ( // as the array index. // TokenNumber--; - ASSERT (TokenNumber < PEI_LOCAL_TOKEN_NUMBER); + // EBC compiler is very choosy. It may report warning about comparison + // between UINTN and 0 . So we add 1 in each size of the + // comparison. + ASSERT (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1); } LocalTokenNumber = GetPcdDatabase()->Init.LocalTokenNumberTable[TokenNumber]; + // + // We don't support SET for HII and VPD type PCD entry in PEI phase. + // So we will assert if any register callback for such PCD entry. + // ASSERT ((LocalTokenNumber & PCD_TYPE_HII) == 0); ASSERT ((LocalTokenNumber & PCD_TYPE_VPD) == 0); @@ -96,10 +106,9 @@ PeiRegisterCallBackWorker ( /** - The function builds the PCD database based on the - PCD_IMAGE on the flash. + The function builds the PCD database. - @param[in] PcdImageOnFlash The PCD image on flash. + @param VOID @retval VOID --*/ @@ -137,14 +146,15 @@ BuildPcdDatabase ( The function is provided by PCD PEIM and PCD DXE driver to do the work of reading a HII variable from variable service. - @param[in] VariableGuid The Variable GUID. - @param[in] VariableName The Variable Name. - @param[out] VariableData The output data. - @param[out] VariableSize The size of the variable. + @param VariableGuid The Variable GUID. + @param VariableName The Variable Name. + @param VariableData The output data. + @param VariableSize The size of the variable. @retval EFI_SUCCESS Operation successful. - @retval EFI_SUCCESS Variablel not found. + @retval EFI_NOT_FOUND Variablel not found. --*/ +STATIC EFI_STATUS GetHiiVariable ( IN CONST EFI_GUID *VariableGuid, @@ -196,7 +206,7 @@ GetHiiVariable ( } - +STATIC UINT32 GetSkuEnabledTokenNumber ( UINT32 LocalTokenNumber, @@ -223,19 +233,23 @@ GetSkuEnabledTokenNumber ( } } - switch (LocalTokenNumber & ~PCD_DATABASE_OFFSET_MASK) { + switch (LocalTokenNumber & PCD_TYPE_ALL_SET) { case PCD_TYPE_VPD: - Value += sizeof(VPD_HEAD) * i; - return ((Value - (UINT8 *) PeiPcdDb) | PCD_TYPE_VPD); + Value = (UINT8 *) &(((VPD_HEAD *) Value)[i]); + return (UINT32) ((Value - (UINT8 *) PeiPcdDb) | PCD_TYPE_VPD); case PCD_TYPE_HII: - Value += sizeof(VARIABLE_HEAD) * i; - return ((Value - (UINT8 *) PeiPcdDb) | PCD_TYPE_HII); + Value = (UINT8 *) &(((VARIABLE_HEAD *) Value)[i]); + return (UINT32) ((Value - (UINT8 *) PeiPcdDb) | PCD_TYPE_HII); + case PCD_TYPE_STRING: + Value = (UINT8 *) &(((STRING_HEAD *) Value)[i]); + return (UINT32) ((Value - (UINT8 *) PeiPcdDb) | PCD_TYPE_STRING); + case PCD_TYPE_DATA: Value += Size * i; - return (Value - (UINT8 *) PeiPcdDb); - + return (UINT32) (Value - (UINT8 *) PeiPcdDb); + default: ASSERT (FALSE); } @@ -248,10 +262,10 @@ GetSkuEnabledTokenNumber ( - +STATIC VOID InvokeCallbackOnSet ( - UINT32 ExTokenNumber, + UINTN ExTokenNumber, CONST EFI_GUID *Guid, OPTIONAL UINTN TokenNumber, VOID *Data, @@ -269,8 +283,12 @@ InvokeCallbackOnSet ( // TokenNumber--; - if (Guid == NULL) - ASSERT (TokenNumber < PEI_LOCAL_TOKEN_NUMBER); + if (Guid == NULL) { + // EBC compiler is very choosy. It may report warning about comparison + // between UINTN and 0 . So we add 1 in each size of the + // comparison. + ASSERT (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1); + } GuidHob = GetFirstGuidHob (&gPcdPeiCallbackFnTableHobGuid); ASSERT (GuidHob != NULL); @@ -293,13 +311,24 @@ InvokeCallbackOnSet ( +EFI_STATUS +SetValueWorker ( + IN UINTN TokenNumber, + IN VOID *Data, + IN UINTN Size + ) +{ + return SetWorker (TokenNumber, Data, &Size, FALSE); +} + + EFI_STATUS SetWorker ( - UINTN TokenNumber, - VOID *Data, - UINTN Size, - BOOLEAN PtrType + IN UINTN TokenNumber, + IN OUT VOID *Data, + IN OUT UINTN *Size, + IN BOOLEAN PtrType ) { UINT32 LocalTokenNumber; @@ -307,7 +336,12 @@ SetWorker ( UINT16 StringTableIdx; UINTN Offset; VOID *InternalData; + UINTN MaxSize; + if (!FeaturePcdGet(PcdPeiPcdDatabaseSetEnabled)) { + return EFI_UNSUPPORTED; + } + // // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER. // We have to decrement TokenNumber by 1 to make it usable @@ -315,16 +349,17 @@ SetWorker ( // TokenNumber--; - ASSERT (TokenNumber < PEI_LOCAL_TOKEN_NUMBER); + // EBC compiler is very choosy. It may report warning about comparison + // between UINTN and 0 . So we add 1 in each size of the + // comparison. + ASSERT (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1); PeiPcdDb = GetPcdDatabase (); LocalTokenNumber = PeiPcdDb->Init.LocalTokenNumberTable[TokenNumber]; - if (PtrType) { - ASSERT (PeiPcdDb->Init.SizeTable[TokenNumber] >= Size); - } else { - ASSERT (PeiPcdDb->Init.SizeTable[TokenNumber] == Size); + if (!PtrType) { + ASSERT (PeiPcdGetSize(TokenNumber + 1) == *Size); } // @@ -332,18 +367,23 @@ SetWorker ( // For Dynamic EX PCD entry, we have invoked the callback function for Dynamic EX // type PCD entry in ExSetWorker. // - if (TokenNumber < PEI_NEX_TOKEN_NUMBER) { - InvokeCallbackOnSet (0, NULL, TokenNumber + 1, Data, Size); + if (TokenNumber + 1 < PEI_NEX_TOKEN_NUMBER + 1) { + InvokeCallbackOnSet (0, NULL, TokenNumber + 1, Data, *Size); } if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) { - LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, Size); + if (PtrType) { + MaxSize = GetPtrTypeSize (TokenNumber, &MaxSize, PeiPcdDb); + } else { + MaxSize = *Size; + } + LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize); } Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK; InternalData = (VOID *) ((UINT8 *) PeiPcdDb + Offset); - switch (LocalTokenNumber & ~PCD_DATABASE_OFFSET_MASK) { + switch (LocalTokenNumber & PCD_TYPE_ALL_SET) { case PCD_TYPE_VPD: case PCD_TYPE_HII: { @@ -352,19 +392,26 @@ SetWorker ( } case PCD_TYPE_STRING: - StringTableIdx = *((UINT16 *)InternalData); - CopyMem (&PeiPcdDb->Init.StringTable[StringTableIdx], Data, Size); - return EFI_SUCCESS; + if (SetPtrTypeSize (TokenNumber, Size, PeiPcdDb)) { + StringTableIdx = *((UINT16 *)InternalData); + CopyMem (&PeiPcdDb->Init.StringTable[StringTableIdx], Data, *Size); + return EFI_SUCCESS; + } else { + return EFI_INVALID_PARAMETER; + } case PCD_TYPE_DATA: { - if (PtrType) { - CopyMem (InternalData, Data, Size); - return EFI_SUCCESS; + if (SetPtrTypeSize (TokenNumber, Size, PeiPcdDb)) { + CopyMem (InternalData, Data, *Size); + return EFI_SUCCESS; + } else { + return EFI_INVALID_PARAMETER; + } } - switch (Size) { + switch (*Size) { case sizeof(UINT8): *((UINT8 *) InternalData) = *((UINT8 *) Data); return EFI_SUCCESS; @@ -396,26 +443,40 @@ SetWorker ( +EFI_STATUS +ExSetValueWorker ( + IN UINTN ExTokenNumber, + IN CONST EFI_GUID *Guid, + IN VOID *Data, + IN UINTN Size + ) +{ + return ExSetWorker (ExTokenNumber, Guid, Data, &Size, FALSE); +} + + EFI_STATUS ExSetWorker ( - IN UINTN ExTokenNumber, - IN CONST EFI_GUID *Guid, - VOID *Data, - UINTN Size, - BOOLEAN PtrType + IN UINTN ExTokenNumber, + IN CONST EFI_GUID *Guid, + IN VOID *Data, + IN OUT UINTN *Size, + IN BOOLEAN PtrType ) { UINTN TokenNumber; + if (!FeaturePcdGet(PcdPeiPcdDatabaseSetEnabled)) { + return EFI_UNSUPPORTED; + } + TokenNumber = GetExPcdTokenNumber (Guid, ExTokenNumber); - InvokeCallbackOnSet (ExTokenNumber, Guid, TokenNumber, Data, Size); + InvokeCallbackOnSet (ExTokenNumber, Guid, TokenNumber, Data, *Size); - SetWorker (TokenNumber, Data, Size, PtrType); + return SetWorker (TokenNumber, Data, Size, PtrType); - return EFI_SUCCESS; - } @@ -428,6 +489,11 @@ ExGetWorker ( IN UINTN GetSize ) { + if (!FeaturePcdGet (PcdPeiPcdDatabaseExEnabled)) { + ASSERT (FALSE); + return 0; + } + return GetWorker (GetExPcdTokenNumber (Guid, ExTokenNumber), GetSize); } @@ -451,7 +517,7 @@ GetWorker ( UINT16 StringTableIdx; PEI_PCD_DATABASE *PeiPcdDb; UINT32 LocalTokenNumber; - UINTN Size; + UINTN MaxSize; // // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER. @@ -460,29 +526,35 @@ GetWorker ( // TokenNumber--; - ASSERT (TokenNumber < PEI_LOCAL_TOKEN_NUMBER); + // EBC compiler is very choosy. It may report warning about comparison + // between UINTN and 0 . So we add 1 in each size of the + // comparison. + ASSERT (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1); - Size = PeiPcdGetSize(TokenNumber + 1); - - ASSERT (GetSize == Size || GetSize == 0); + ASSERT ((GetSize == PeiPcdGetSize(TokenNumber + 1)) || (GetSize == 0)); PeiPcdDb = GetPcdDatabase (); LocalTokenNumber = PeiPcdDb->Init.LocalTokenNumberTable[TokenNumber]; if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) { - LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, Size); + if (GetSize == 0) { + MaxSize = GetPtrTypeSize (TokenNumber, &MaxSize, PeiPcdDb); + } else { + MaxSize = GetSize; + } + LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize); } Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK; StringTable = PeiPcdDb->Init.StringTable; - switch (LocalTokenNumber & ~PCD_DATABASE_OFFSET_MASK) { + switch (LocalTokenNumber & PCD_TYPE_ALL_SET) { case PCD_TYPE_VPD: { VPD_HEAD *VpdHead; VpdHead = (VPD_HEAD *) ((UINT8 *)PeiPcdDb + Offset); - return (VOID *) (FixedPcdGet32(PcdVpdBaseAddress) + VpdHead->Offset); + return (VOID *) (UINTN) (FixedPcdGet32(PcdVpdBaseAddress) + VpdHead->Offset); } case PCD_TYPE_HII: @@ -524,10 +596,11 @@ GetWorker ( } + UINTN GetExPcdTokenNumber ( IN CONST EFI_GUID *Guid, - IN UINT32 ExTokenNumber + IN UINTN ExTokenNumber ) { UINT32 i; @@ -578,3 +651,78 @@ GetPcdDatabase ( return (PEI_PCD_DATABASE *) GET_GUID_HOB_DATA (GuidHob); } + + +SKU_ID * +GetSkuIdArray ( + IN UINTN LocalTokenNumberTableIdx, + IN PEI_PCD_DATABASE *Database + ) +{ + SKU_HEAD *SkuHead; + UINTN LocalTokenNumber; + + LocalTokenNumber = Database->Init.LocalTokenNumberTable[LocalTokenNumberTableIdx]; + + ASSERT ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) != 0); + + SkuHead = (SKU_HEAD *) ((UINT8 *)Database + (LocalTokenNumber & PCD_DATABASE_OFFSET_MASK)); + + return (SKU_ID *) ((UINT8 *)Database + SkuHead->SkuIdTableOffset); + +} + + + +UINTN +GetSizeTableIndex ( + IN UINTN LocalTokenNumberTableIdx, + IN PEI_PCD_DATABASE *Database + ) +{ + UINTN i; + UINTN SizeTableIdx; + UINTN LocalTokenNumber; + SKU_ID *SkuIdTable; + + SizeTableIdx = 0; + + for (i=0; iInit.LocalTokenNumberTable[i]; + + if ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER) { + // + // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type + // PCD entry. + // + if (LocalTokenNumber & PCD_TYPE_VPD) { + // + // We have only one entry for VPD enabled PCD entry: + // 1) MAX Size. + // We consider current size is equal to MAX size. + // + SizeTableIdx++; + } else { + if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0) { + // + // We have only two entry for Non-Sku enabled PCD entry: + // 1) MAX SIZE + // 2) Current Size + // + SizeTableIdx += 2; + } else { + // + // We have these entry for SKU enabled PCD entry + // 1) MAX SIZE + // 2) Current Size for each SKU_ID (It is equal to MaxSku). + // + SkuIdTable = GetSkuIdArray (i, Database); + SizeTableIdx += (UINTN)*SkuIdTable + 1; + } + } + } + + } + + return SizeTableIdx; +}