From: "gaoliming" <gaoliming@byosoft.com.cn>
To: devel@edk2.groups.io
Cc: zengzhi <zengzhi@byosoft.com.cn>,
Jian J Wang <jian.j.wang@intel.com>,
Hao A Wu <hao.a.wu@intel.com>, Dandan Bi <dandan.bi@intel.com>
Subject: [PATCH] MdeModulePkg/Pcdpeim: Fixed PcdGetPtr() caused memory wasting.
Date: Fri, 4 Dec 2020 10:48:32 +0800 [thread overview]
Message-ID: <20201204024832.1384-1-gaoliming@byosoft.com.cn> (raw)
From: zengzhi <zengzhi@byosoft.com.cn>
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2964
GuidHob was added to cache the VariableGuid,VariableName,VariableData.
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Hao A Wu <hao.a.wu@intel.com>
Cc: Dandan Bi <dandan.bi@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Signed-off-by: zengzhi <zengzhi@byosoft.com.cn>
---
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
reply other threads:[~2020-12-04 2:48 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20201204024832.1384-1-gaoliming@byosoft.com.cn \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox