From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail.byosoft.com.cn (mail.byosoft.com.cn [58.240.74.242]) by mx.groups.io with SMTP id smtpd.web10.8894.1607050128075666418 for ; Thu, 03 Dec 2020 18:48:49 -0800 Authentication-Results: mx.groups.io; dkim=missing; spf=none, err=permanent DNS error (domain: byosoft.com.cn, ip: 58.240.74.242, mailfrom: gaoliming@byosoft.com.cn) Received: from localhost.localdomain ([58.246.60.130]) (envelope-sender ) by 192.168.6.13 with ESMTP for ; Fri, 04 Dec 2020 10:48:44 +0800 X-WM-Sender: gaoliming@byosoft.com.cn X-WM-AuthFlag: YES X-WM-AuthUser: gaoliming@byosoft.com.cn From: "gaoliming" To: devel@edk2.groups.io Cc: zengzhi , Jian J Wang , Hao A Wu , Dandan Bi Subject: [PATCH] MdeModulePkg/Pcdpeim: Fixed PcdGetPtr() caused memory wasting. Date: Fri, 4 Dec 2020 10:48:32 +0800 Message-Id: <20201204024832.1384-1-gaoliming@byosoft.com.cn> X-Mailer: git-send-email 2.27.0.windows.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: zengzhi REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2964 GuidHob was added to cache the VariableGuid,VariableName,VariableData. Cc: Jian J Wang Cc: Hao A Wu Cc: Dandan Bi Cc: Liming Gao Signed-off-by: zengzhi --- MdeModulePkg/Universal/PCD/Pei/Service.c | 55 ++++++++++++++++++++---- 1 file changed, 46 insertions(+), 9 deletions(-) diff --git a/MdeModulePkg/Universal/PCD/Pei/Service.c b/MdeModulePkg/Universal/PCD/Pei/Service.c index 5b037353ad..c13be25a31 100644 --- a/MdeModulePkg/Universal/PCD/Pei/Service.c +++ b/MdeModulePkg/Universal/PCD/Pei/Service.c @@ -452,6 +452,7 @@ BuildPcdDatabase ( return Database; } +EFI_GUID mGetVariableGuid = { 0x2f5a9b0e, 0xc338, 0x4f95, { 0xa8, 0x39, 0xf3, 0x8d, 0x27, 0xa2, 0x80, 0xc2 } }; /** The function is provided by PCD PEIM and PCD DXE driver to do the work of reading a HII variable from variable service. @@ -474,13 +475,36 @@ GetHiiVariable ( { UINTN Size; EFI_STATUS Status; - VOID *Buffer; + UINTN DataLength; + VOID *HobData; + UINT8 *GetGuidHobData; + EFI_HOB_GUID_TYPE *GuidHob; EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariablePpi; - + // Get the variable from the Guid Hob first, return it if found, + // and use the getVarible() function if not found. + GuidHob = GetFirstGuidHob (&mGetVariableGuid); + while (GuidHob != NULL) { + GetGuidHobData = GET_GUID_HOB_DATA (GuidHob); + if (CompareGuid((EFI_GUID *) (GetGuidHobData + sizeof(UINT32)), VariableGuid) && + StrnCmp((VOID *) (GetGuidHobData + sizeof(UINT32) + sizeof(EFI_GUID)), VariableName, StrLen(VariableName)) == 0){ + // If the variableGuid and variableName in the HOB are the same as + // the input variableGuid and variableName, the VariableData and Size + // in the HOB are returned as output values. + *VariableSize = *((UINT32 *) GetGuidHobData); + *VariableData = (VOID *) (GetGuidHobData + sizeof(UINT32) + sizeof(EFI_GUID) + StrSize(VariableName)); + return EFI_SUCCESS; + } else { + GuidHob = GetNextGuidHob (&mGetVariableGuid, GET_NEXT_HOB (GuidHob)); + } + } + // Load the PeiReadOnlyVariable2 PPI, which provides a service to read EFI Variable. + // If the load is unsuccessful, the function cannot be continued. Status = PeiServicesLocatePpi (&gEfiPeiReadOnlyVariable2PpiGuid, 0, NULL, (VOID **) &VariablePpi); ASSERT_EFI_ERROR (Status); Size = 0; + // EFI Variable is read with an empty Buffer, and if an EFI Variable exists, + // it returns the actual required Buffer size. Status = VariablePpi->GetVariable ( VariablePpi, VariableName, @@ -491,22 +515,35 @@ GetHiiVariable ( ); if (Status == EFI_BUFFER_TOO_SMALL) { - Status = PeiServicesAllocatePool (Size, &Buffer); - ASSERT_EFI_ERROR (Status); - + // DataLength + // ------------------------------------------------------------- + // | VariableSize | VariableGuid | VariableName | VariableData | + // ------------------------------------------------------------- + DataLength = sizeof(UINT32) + sizeof(EFI_GUID) + StrSize(VariableName) + Size; + HobData = BuildGuidHob( + &mGetVariableGuid, + DataLength + ); + // The VariableSize VariableGuid, VariableName, VariableData copy to GuidHob in turn. + CopyMem (HobData, (VOID *) &Size, sizeof(Size)); + HobData = (VOID *) ((UINT8 *) HobData + sizeof(UINT32)); + CopyMem (HobData, VariableGuid, sizeof(EFI_GUID)); + HobData = (VOID *) ((UINT8 *) HobData + sizeof (EFI_GUID)); + CopyMem (HobData, VariableName, StrSize(VariableName)); + HobData = (VOID *) ((UINT8 *) HobData + StrSize(VariableName)); + // Read EFI Variable into Guidhob. After a successful read, + // the read data is returned as the output value. Status = VariablePpi->GetVariable ( VariablePpi, (UINT16 *) VariableName, (EFI_GUID *) VariableGuid, NULL, &Size, - Buffer + HobData ); ASSERT_EFI_ERROR (Status); - *VariableSize = Size; - *VariableData = Buffer; - + *VariableData = HobData; return EFI_SUCCESS; } -- 2.26.2.windows.1