From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by mx.groups.io with SMTP id smtpd.web11.13886.1594622340784645175 for ; Sun, 12 Jul 2020 23:39:01 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@intel.onmicrosoft.com header.s=selector2-intel-onmicrosoft-com header.b=IaRl+moB; spf=pass (domain: intel.com, ip: 192.55.52.88, mailfrom: jian.j.wang@intel.com) IronPort-SDR: xm65bUQjd6qMAnhRIT7Nt3jHsypbk7URrNd9dtRGM1V9xc2V5aYdHt/tNrbxel3AazoD9tVbTv LtxUy8tTs3Ww== X-IronPort-AV: E=McAfee;i="6000,8403,9680"; a="166675575" X-IronPort-AV: E=Sophos;i="5.75,346,1589266800"; d="scan'208";a="166675575" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Jul 2020 23:38:59 -0700 IronPort-SDR: t+TOS7say2DsR/pGcXp1A0FVEZcxcIhSat9j9rww1uX7XbkYmNgvwahV2IFWD92SlJKI+NpHcH AW6LOS8wU1sw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.75,346,1589266800"; d="scan'208";a="325404459" Received: from fmsmsx106.amr.corp.intel.com ([10.18.124.204]) by orsmga007.jf.intel.com with ESMTP; 12 Jul 2020 23:38:59 -0700 Received: from fmsmsx101.amr.corp.intel.com (10.18.124.199) by FMSMSX106.amr.corp.intel.com (10.18.124.204) with Microsoft SMTP Server (TLS) id 14.3.439.0; Sun, 12 Jul 2020 23:38:58 -0700 Received: from FMSEDG001.ED.cps.intel.com (10.1.192.133) by fmsmsx101.amr.corp.intel.com (10.18.124.199) with Microsoft SMTP Server (TLS) id 14.3.439.0; Sun, 12 Jul 2020 23:38:58 -0700 Received: from NAM10-BN7-obe.outbound.protection.outlook.com (104.47.70.106) by edgegateway.intel.com (192.55.55.68) with Microsoft SMTP Server (TLS) id 14.3.439.0; Sun, 12 Jul 2020 23:38:58 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=W04dlYykdy/ERuH1N7l45btc82tKwW7YABguvgRpCfAolSthQx+0umxKQAcPUnO/8X1YYNn+b63qDKqcVA5XkRMOfgv3Ndx2t+iPTwUJgfGRyLkwK+nB3Ewl7nUu2YFVSOOuw37TJi7Q7MFMhXJnaOidSXzD4w0pl4EgN9/An0I/hOMTbSbzbRLTTDW5Jiv4gMi8+xHohqRqEpG0s2BsxTR8tGfNOughSiEsMCL+IykrGf7tMjRMucspRGX+LbkceXjZKcrtkEDlSqaEE9C4JTbnHDvgq8g5a4G6sId6i1jQBsQ08qzj4OyignGFvSBv7At11ZKb16iFZdR26O1Gng== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=O4LGIMb0aFK/IJK/50oN34WyVqeNvBEugKUqK7E58eE=; b=mKsXB3XrJtu379+96ZaEy5mbLophSPmu93PPSSXsXmpEBz1bM1EpYfiEU7Gm21MeEvD2qoscHCBR4cCYGXjlUuJFm1JdOLagJ0ymkSpkRRETXJZVlzdQdZB+UXQuz1T90mbvCmFd7wBPaO4/wFo7sMOE2rh5wqEAc/ZXDXyCIgHagsVgOCpI1zT0ij25Qc0HQSLySSAzlD5jfhkiQlD4Vvh/H7uK4LrYmoFaZDyH0wAk02QHjyaMDUpqm5DHWR8xi2Vk1Y2fyODroJ/EPduJcESx+uxWZiEAgta8CNirmSWz6FBsMLRxgfgdMPNxwKhWOIW5A7whX8fHhvcchWVb2Q== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=intel.com; dmarc=pass action=none header.from=intel.com; dkim=pass header.d=intel.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=intel.onmicrosoft.com; s=selector2-intel-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=O4LGIMb0aFK/IJK/50oN34WyVqeNvBEugKUqK7E58eE=; b=IaRl+moBqbD9wYyQyJeZHPHQnmaY061Y+ERiD0v5lv0NRGvJAAJddUzdyRc0wFNCA13mIFsGs3w5xhjq6GbuFYET6CZQkJpTs6eBKbHf0rBsDiybpsDfXpcQdLMWXkfRtZ5+lcfartKSSGQ7KpGgBZD9VZ6sQelSwKPiUu/OciQ= Received: from SN6PR11MB3312.namprd11.prod.outlook.com (2603:10b6:805:c8::14) by SN6PR11MB2912.namprd11.prod.outlook.com (2603:10b6:805:cb::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3174.23; Mon, 13 Jul 2020 06:38:53 +0000 Received: from SN6PR11MB3312.namprd11.prod.outlook.com ([fe80::31f6:24c6:99f0:33d2]) by SN6PR11MB3312.namprd11.prod.outlook.com ([fe80::31f6:24c6:99f0:33d2%6]) with mapi id 15.20.3174.025; Mon, 13 Jul 2020 06:38:53 +0000 From: "Wang, Jian J" To: "devel@edk2.groups.io" , "Jiang, Guomin" CC: Michael Kubacki , "Wu, Hao A" , "Bi, Dandan" , "Gao, Liming" , "De, Debkumar" , "Han, Harry" , "West, Catharine" Subject: Re: [edk2-devel] [PATCH v5 2/9] MdeModulePkg/PeiCore: Enable T-RAM evacuation in PeiCore (CVE-2019-11098) Thread-Topic: [edk2-devel] [PATCH v5 2/9] MdeModulePkg/PeiCore: Enable T-RAM evacuation in PeiCore (CVE-2019-11098) Thread-Index: AQHWVZRBVBKjxfgWBU2kSduiBH7AvqkE1+cA Date: Mon, 13 Jul 2020 06:38:53 +0000 Message-ID: References: <20200709015645.336-1-guomin.jiang@intel.com> <20200709015645.336-3-guomin.jiang@intel.com> In-Reply-To: <20200709015645.336-3-guomin.jiang@intel.com> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-titus-metadata-40: eyJDYXRlZ29yeUxhYmVscyI6IiIsIk1ldGFkYXRhIjp7Im5zIjoiaHR0cDpcL1wvd3d3LnRpdHVzLmNvbVwvbnNcL0ludGVsMyIsImlkIjoiNDQ0ODhmNzItZjNhNi00NjVjLWJlZjQtMmY3MWMzOTExNWMyIiwicHJvcHMiOlt7Im4iOiJDVFBDbGFzc2lmaWNhdGlvbiIsInZhbHMiOlt7InZhbHVlIjoiQ1RQX05UIn1dfV19LCJTdWJqZWN0TGFiZWxzIjpbXSwiVE1DVmVyc2lvbiI6IjE3LjEwLjE4MDQuNDkiLCJUcnVzdGVkTGFiZWxIYXNoIjoiRmk1bkZabUZNVHgwMWNJaXFrdHNieWR1VXBGYmNTUk1wekVmaTdRYlZkTkVoZ05nYWw3XC9zeEY3SXFtTFhPZkEifQ== dlp-reaction: no-action dlp-version: 11.2.0.6 dlp-product: dlpe-windows x-ctpclassification: CTP_NT authentication-results: edk2.groups.io; dkim=none (message not signed) header.d=none;edk2.groups.io; dmarc=none action=none header.from=intel.com; x-originating-ip: [192.198.147.194] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 431d8f15-0b5c-4f5e-c736-08d826f7694d x-ms-traffictypediagnostic: SN6PR11MB2912: x-ms-exchange-transport-forked: True x-microsoft-antispam-prvs: x-ms-oob-tlc-oobclassifiers: OLM:569; x-ms-exchange-senderadcheck: 1 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: MrNrbqSY9C5Lo+HdXVtRLTqGSZvVEtlsta1SJivLIBiaURtCJZsY15AdOlFNclfJ84y8GNKHoTZ8FWeW1s74rD1RMClcgrs/xi0G3c2+i/Sl4f6zjgHMDCJUopKA1SGbHKSVrUhBPpZ/vWn4VE+p7rg+Pm3YZM0vfR7Fk9S/vyiK7pKESUlaD2E5MRdYlsnWm9WmkieN5XUkEtIx2OreoPF4BIjqMUakayaZLxM3ffwGsBtmI89LfPWpKcvo7IDSoyhbv7UEC/dTamfpz8tplrFKFtkRT4jVunIq0K1J5Benuh44G6t+yjH5nW4ZIJ+S6Lv9bzrcYMh6I+KNuEA99yHICLWVYs9jqlBu6u7Anl01vNacSlwbnkABwi7SIbMrPJb+QlKsjRfFD00Q1AoIHQ== x-forefront-antispam-report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:SN6PR11MB3312.namprd11.prod.outlook.com;PTR:;CAT:NONE;SFTY:;SFS:(4636009)(376002)(39860400002)(366004)(396003)(346002)(136003)(64756008)(7696005)(52536014)(86362001)(83380400001)(26005)(6636002)(5660300002)(186003)(2906002)(33656002)(107886003)(30864003)(66946007)(110136005)(54906003)(66476007)(478600001)(6506007)(53546011)(76116006)(8936002)(8676002)(66556008)(66446008)(9686003)(71200400001)(316002)(55016002)(19627235002)(966005)(4326008)(579004)(559001);DIR:OUT;SFP:1102; x-ms-exchange-antispam-messagedata: 8lEbdrhuPL45za3Q4cO2xQ9Bi3C5qKETKXeJJUCkYchs5U57gUrXk4c5gKD39iFSVQmwWsOUDwjjEg+UNq6dO6k5RjTYDgx2Ov7PwJCToQTW4RhxpepXYsXVN4BAwWhBWStsyIOaAIsyH/HmRU1DNthLfctwWx9n6bJ7CL5u70roZL9RjVc5TsNiXXypRdTmGeDxLxhjpcIMzNpsF/UIg2WH8x48Iv750Mpv23h1gq2fU/G+JHxIgOZVzsbefrFdC8gFIbf19vIhvR6k39ZgIeglTRuNi7L4AN+i7rvHaJ+QX+DoQ28bP3KwarvMoLQzrac3JFYxL2JtOpeitUPoql3HnQ4ZN9A4JxxllVpGB9pjwkmXE52BhTIGZp/uBRLdOj9QwraZ6344oq4eQ4ZiQ+NgBe3ORJRz8hnCMpEbWxfzujDzfPQCgj3jQE3d6bpisfE+3mA0GKTQJUUM9yKxeGMw4i0nIHfiNWOr4l2s+oS1FzS+BuOe8ntVDBmGIHH8 MIME-Version: 1.0 X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: SN6PR11MB3312.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 431d8f15-0b5c-4f5e-c736-08d826f7694d X-MS-Exchange-CrossTenant-originalarrivaltime: 13 Jul 2020 06:38:53.6388 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 46c98d88-e344-4ed4-8496-4ed7712e255d X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: cPEhtVuXUi1K0zcQev/2berkFijX+MOEUWQLl9EhzN2v6I0JkgO5Y1X+0BfwX2AOnogWGtpz8OELrU7nBLQF3Q== X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN6PR11MB2912 Return-Path: jian.j.wang@intel.com X-OriginatorOrg: intel.com Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Guomin, See my 16 comments embedded below. About PcdMigrateTemporaryRamFirmwareVolumes, I think we need more discussions on its use scenario along with PcdShadowPeimOnBoot and PcdShadowPeimOnS3Boot. Currently it need all of them enabled to make this solution work, which is a bit complex and confusion to me. > -----Original Message----- > From: devel@edk2.groups.io On Behalf Of Guomin > Jiang > Sent: Thursday, July 09, 2020 9:57 AM > To: devel@edk2.groups.io > Cc: Michael Kubacki ; Wang, Jian J > ; Wu, Hao A ; Bi, Dandan > ; Gao, Liming ; De, Debkumar > ; Han, Harry ; West, > Catharine > Subject: [edk2-devel] [PATCH v5 2/9] MdeModulePkg/PeiCore: Enable T-RAM > evacuation in PeiCore (CVE-2019-11098) >=20 > From: Michael Kubacki >=20 > REF:https://bugzilla.tianocore.org/show_bug.cgi?id=3D1614 >=20 > Introduces new changes to PeiCore to move the contents of temporary > RAM visible to the PeiCore to permanent memory. This expands on > pre-existing shadowing support in the PeiCore to perform the following > additional actions: >=20 > 1. Migrate pointers in PPIs installed in PeiCore to the permanent > memory copy of PeiCore. >=20 > 2. Copy all installed firmware volumes to permanent memory. >=20 > 3. Relocate and fix up the PEIMs within the firmware volumes. >=20 > 4. Convert all PPIs into the migrated firmware volume to the correspond= ing > PPI address in the permanent memory location. >=20 > This applies to PPIs and PEI notifications. >=20 > 5. Convert all status code callbacks in the migrated firmware volume to > the corresponding address in the permanent memory location. >=20 > 6. Update the FV HOB to the corresponding firmware volume in permanent > memory. >=20 > 7. Add PcdMigrateTemporaryRamFirmwareVolumes to control if enable the > feature or not. when the PCD disable, the EvacuateTempRam() will > never be called. >=20 > The function control flow as below: > PeiCore() > DumpPpiList() > EvacuateTempRam() > ConvertPeiCorePpiPointers() > ConvertPpiPointersFv() > MigratePeimsInFv() > MigratePeim() > PeiGetPe32Data() > LoadAndRelocatePeCoffImageInPlace() > MigrateSecModulesInFv() > ConvertPpiPointersFv() > ConvertStatusCodeCallbacks() > ConvertFvHob() > RemoveFvHobsInTemporaryMemory() > DumpPpiList() >=20 > Cc: Jian J Wang > Cc: Hao A Wu > Cc: Dandan Bi > Cc: Liming Gao > Cc: Debkumar De > Cc: Harry Han > Cc: Catharine West > Signed-off-by: Michael Kubacki > --- > MdeModulePkg/Core/Pei/PeiMain.inf | 2 + > MdeModulePkg/Core/Pei/PeiMain.h | 168 ++++++++ > MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c | 402 ++++++++++++++++++ > MdeModulePkg/Core/Pei/Image/Image.c | 115 +++++ > MdeModulePkg/Core/Pei/Memory/MemoryServices.c | 82 ++++ > MdeModulePkg/Core/Pei/PeiMain/PeiMain.c | 24 ++ > MdeModulePkg/Core/Pei/Ppi/Ppi.c | 287 +++++++++++++ > 7 files changed, 1080 insertions(+) >=20 > diff --git a/MdeModulePkg/Core/Pei/PeiMain.inf > b/MdeModulePkg/Core/Pei/PeiMain.inf > index 6e25cc40232a..5b36d516b3fa 100644 > --- a/MdeModulePkg/Core/Pei/PeiMain.inf > +++ b/MdeModulePkg/Core/Pei/PeiMain.inf > @@ -76,6 +76,7 @@ [Guids] > ## CONSUMES ## UNDEFINED # Locate PPI > ## CONSUMES ## GUID # Used to compare with FV's file system GU= ID and > get the FV's file system format > gEfiFirmwareFileSystem3Guid > + gStatusCodeCallbackGuid >=20 > [Ppis] > gEfiPeiStatusCodePpiGuid ## SOMETIMES_CONSUMES # > PeiReportStatusService is not ready if this PPI doesn't exist > @@ -109,6 +110,7 @@ [Pcd] > gEfiMdeModulePkgTokenSpaceGuid.PcdShadowPeimOnS3Boot = ## > CONSUMES > gEfiMdeModulePkgTokenSpaceGuid.PcdShadowPeimOnBoot = ## > CONSUMES > gEfiMdeModulePkgTokenSpaceGuid.PcdInitValueInTempStack = ## > CONSUMES > + > gEfiMdeModulePkgTokenSpaceGuid.PcdMigrateTemporaryRamFirmwareVolum > es ## CONSUMES >=20 > # [BootMode] > # S3_RESUME ## SOMETIMES_CONSUMES > diff --git a/MdeModulePkg/Core/Pei/PeiMain.h > b/MdeModulePkg/Core/Pei/PeiMain.h > index 56b3bd85793d..b0101dba5e30 100644 > --- a/MdeModulePkg/Core/Pei/PeiMain.h > +++ b/MdeModulePkg/Core/Pei/PeiMain.h > @@ -394,6 +394,41 @@ PeimDispatchReadiness ( > IN VOID *DependencyExpression > ); >=20 > +/** > + Migrate a PEIM from Temporary RAM to permanent memory. 1) 'Temporary' -> 'temporary' > + > + @param PeimFileHandle Pointer to the FFS file header of the ima= ge. > + @param MigratedFileHandle Pointer to the FFS file header of the mig= rated > image. > + > + @retval EFI_SUCCESS Sucessfully migrated the PEIM to permanen= t > memory. > + > +**/ > +EFI_STATUS > +EFIAPI > +MigratePeim ( > + IN EFI_PEI_FILE_HANDLE FileHandle, > + IN EFI_PEI_FILE_HANDLE MigratedFileHandle > + ); > + > +/** > + Migrate FVs out of Temporary RAM before the cache is flushed. 2) 'Temporary' -> 'temporary' > + > + @param Private PeiCore's private data structure > + @param SecCoreData Points to a data structure containing informat= ion > about the PEI core's operating > + environment, such as the size and location of = temporary RAM, > the stack location and > + the BFV location. > + > + @retval EFI_SUCCESS Succesfully migrated installed FVs from= Temporary > RAM to permanent memory. 3) 'Temporary' -> 'temporary' > + @retval EFI_OUT_OF_RESOURCES Insufficient memory exists to allocate > needed pages. > + > +**/ > +EFI_STATUS > +EFIAPI > +EvacuateTempRam ( > + IN PEI_CORE_INSTANCE *Private, > + IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData > + ); > + > /** > Conduct PEIM dispatch. >=20 > @@ -477,6 +512,50 @@ ConvertPpiPointers ( > IN PEI_CORE_INSTANCE *PrivateData > ); >=20 > +/** > + > + Migrate Notify Pointers inside an FV from temporary memory to permane= nt > memory. > + > + @param PrivateData Pointer to PeiCore's private data structure. > + @param OrgFvHandle Address of FV Handle in temporary memory. > + @param FvHandle Address of FV Handle in permanent memory. > + @param FvSize Size of the FV. > + > +**/ > +VOID > +ConvertPpiPointersFv ( > + IN PEI_CORE_INSTANCE *PrivateData, > + IN UINTN OrgFvHandle, > + IN UINTN FvHandle, > + IN UINTN FvSize > + ); > + > +/** > + > + Migrate PPI Pointers of PEI_CORE from temporary memory to permanent > memory. > + > + @param PrivateData Pointer to PeiCore's private data structure. > + @param CoreFvHandle Address of PEI_CORE FV Handle in temporary > memory. > + > +**/ > +VOID > +ConvertPeiCorePpiPointers ( > + IN PEI_CORE_INSTANCE *PrivateData, > + PEI_CORE_FV_HANDLE CoreFvHandle > + ); > + > +/** > + > + Dumps the PPI lists to debug output. > + > + @param PrivateData Points to PeiCore's private instance data. > + > +**/ > +VOID > +DumpPpiList ( > + IN PEI_CORE_INSTANCE *PrivateData > + ); > + > /** >=20 > Install PPI services. It is implementation of EFI_PEI_SERVICE.Install= Ppi. > @@ -808,6 +887,37 @@ PeiFfsFindNextFile ( > IN OUT EFI_PEI_FILE_HANDLE *FileHandle > ); >=20 > +/** > + Go through the file to search SectionType section. > + Search within encapsulation sections (compression and GUIDed) recursi= vely, > + until the match section is found. > + > + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES = table > published by the PEI Foundation. > + @param SectionType Filter to find only section of this type. > + @param SectionInstance Pointer to the filter to find the specific i= nstance of > section. > + @param Section From where to search. > + @param SectionSize The file size to search. > + @param OutputBuffer A pointer to the discovered section, if succ= essful. > + NULL if section not found 4) Missing '.' at the end > + @param AuthenticationStatus Updated upon return to point to the > authentication status for this section. 5) Please align the start of parameter description > + @param IsFfs3Fv Indicates the FV format. > + > + @return EFI_NOT_FOUND The match section is not found. > + @return EFI_SUCCESS The match section is found. > + > +**/ > +EFI_STATUS > +ProcessSection ( > + IN CONST EFI_PEI_SERVICES **PeiServices, > + IN EFI_SECTION_TYPE SectionType, > + IN OUT UINTN *SectionInstance, > + IN EFI_COMMON_SECTION_HEADER *Section, > + IN UINTN SectionSize, > + OUT VOID **OutputBuffer, > + OUT UINT32 *AuthenticationStatus, > + IN BOOLEAN IsFfs3Fv > + ); > + > /** > Searches for the next matching section within the specified file. >=20 > @@ -931,6 +1041,33 @@ MigrateMemoryPages ( > IN BOOLEAN TemporaryRamMigrated > ); >=20 > +/** > + Removes any FV HOBs whose base address is not in PEI installed memory= . > + > + @param[in] Private Pointer to PeiCore's private data structu= re. > + > +**/ > +VOID > +RemoveFvHobsInTemporaryMemory ( > + IN PEI_CORE_INSTANCE *Private > + ); > + > +/** > + Migrate the base address in firmware volume allocation HOBs > + from temporary memory to PEI installed memory. > + > + @param[in] PrivateData Pointer to PeiCore's private data structu= re. > + @param[in] OrgFvHandle Address of FV Handle in temporary memory. > + @param[in] FvHandle Address of FV Handle in permanent memory. > + > +**/ > +VOID > +ConvertFvHob ( > + IN PEI_CORE_INSTANCE *PrivateData, > + IN UINTN OrgFvHandle, > + IN UINTN FvHandle > + ); > + > /** > Migrate MemoryBaseAddress in memory allocation HOBs > from the temporary memory to PEI installed memory. > @@ -1249,6 +1386,37 @@ InitializeImageServices ( > IN PEI_CORE_INSTANCE *OldCoreData > ); >=20 > +/** > + Loads and relocates a PE/COFF image in place. > + > + @param Pe32Data The base address of the PE/COFF file that is = to be > loaded and relocated > + @param ImageAddress The base address of the relocated PE/COFF ima= ge > + > + @retval EFI_SUCCESS The file was loaded and relocated > + > +**/ > +EFI_STATUS > +LoadAndRelocatePeCoffImageInPlace ( > + IN VOID *Pe32Data, > + IN VOID *ImageAddress > + ); > + > +/** > + Find the PE32 Data for an FFS file. > + > + @param FileHandle Pointer to the FFS file header of the image. > + @param Pe32Data Pointer to a (VOID *) PE32 Data pointer. > + > + @retval EFI_SUCCESS Image is successfully loaded. > + @retval EFI_NOT_FOUND Fail to locate PE32 Data. > + > +**/ > +EFI_STATUS > +PeiGetPe32Data ( > + IN EFI_PEI_FILE_HANDLE FileHandle, > + OUT VOID **Pe32Data > + ); > + > /** > The wrapper function of PeiLoadImageLoadImage(). >=20 > diff --git a/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c > b/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c > index 4c2eac1384e8..ef88b3423376 100644 > --- a/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c > +++ b/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c > @@ -952,6 +952,408 @@ PeiCheckAndSwitchStack ( > } > } >=20 > +/** > + Migrate a PEIM from Temporary RAM to permanent memory. 6) 'Temporary' -> 'temporary' > + > + @param PeimFileHandle Pointer to the FFS file header of the ima= ge. > + @param MigratedFileHandle Pointer to the FFS file header of the mig= rated > image. > + > + @retval EFI_SUCCESS Sucessfully migrated the PEIM to permanen= t > memory. > + > +**/ > +EFI_STATUS > +EFIAPI > +MigratePeim ( > + IN EFI_PEI_FILE_HANDLE FileHandle, > + IN EFI_PEI_FILE_HANDLE MigratedFileHandle > + ) > +{ > + EFI_STATUS Status; > + EFI_FFS_FILE_HEADER *FileHeader; > + VOID *Pe32Data; > + VOID *ImageAddress; > + CHAR8 *AsciiString; > + UINTN Index; > + > + Status =3D EFI_SUCCESS; > + > + FileHeader =3D (EFI_FFS_FILE_HEADER *) FileHandle; > + ASSERT (!IS_FFS_FILE2 (FileHeader)); > + > + ImageAddress =3D NULL; > + PeiGetPe32Data (MigratedFileHandle, &ImageAddress); > + if (ImageAddress !=3D NULL) { > + AsciiString =3D PeCoffLoaderGetPdbPointer (ImageAddress); > + for (Index =3D 0; AsciiString[Index] !=3D 0; Index++) { > + if (AsciiString[Index] =3D=3D '\\' || AsciiString[Index] =3D=3D '= /') { > + AsciiString =3D AsciiString + Index + 1; > + Index =3D 0; > + } else if (AsciiString[Index] =3D=3D '.') { > + AsciiString[Index] =3D 0; > + } > + } > + DEBUG ((DEBUG_INFO, "%a", AsciiString)); 7) Above code (from the line below 'if' to 'DEBUG') are used for debug only. Suggest to put them into DEBUG_CODE(); > + > + Pe32Data =3D (VOID *) ((UINTN) ImageAddress - (UINTN) MigratedFileH= andle + > (UINTN) FileHandle); > + Status =3D LoadAndRelocatePeCoffImageInPlace (Pe32Data, ImageAddres= s); > + ASSERT_EFI_ERROR (Status); > + } > + > + return Status; > +} > + > +/** > + Migrate Status Code Callback function pointers inside an FV from temp= orary > memory to permanent memory. > + > + @param OrgFvHandle Address of FV Handle in temporary memory. 8) 'Handle' -> 'handle' > + @param FvHandle Address of FV Handle in permanent memory. 9) 'Handle' -> 'handle' > + @param FvSize Size of the FV. > + > +**/ > +VOID > +ConvertStatusCodeCallbacks ( > + IN UINTN OrgFvHandle, > + IN UINTN FvHandle, > + IN UINTN FvSize > + ) > +{ > + EFI_PEI_HOB_POINTERS Hob; > + UINTN *NumberOfEntries; > + UINTN *CallbackEntry; > + UINTN Index; > + > + Hob.Raw =3D GetFirstGuidHob (&gStatusCodeCallbackGuid); > + while (Hob.Raw !=3D NULL) { > + NumberOfEntries =3D GET_GUID_HOB_DATA (Hob); > + CallbackEntry =3D NumberOfEntries + 1; > + for (Index =3D 0; Index < *NumberOfEntries; Index++) { > + if (((VOID *) CallbackEntry[Index]) !=3D NULL) { > + if ((CallbackEntry[Index] >=3D OrgFvHandle) && (CallbackEntry[I= ndex] < > (OrgFvHandle + FvSize))) { > + DEBUG ((DEBUG_INFO, "Migrating CallbackEntry[%d] from 0x%08X = to ", > Index, CallbackEntry[Index])); CallbackEntry is defined as pointer to UINTN, which is 4-byte with 32-bit = PEI. Using %08X might be not a good idea. Suggest to use %p instead. > + if (OrgFvHandle > FvHandle) { > + CallbackEntry[Index] =3D CallbackEntry[Index] - (OrgFvHandl= e - FvHandle); > + } else { > + CallbackEntry[Index] =3D CallbackEntry[Index] + (FvHandle -= OrgFvHandle); > + } > + DEBUG ((DEBUG_INFO, "0x%08X\n", CallbackEntry[Index])); 10) The same as above. > + } > + } > + } > + Hob.Raw =3D GET_NEXT_HOB (Hob); > + Hob.Raw =3D GetNextGuidHob (&gStatusCodeCallbackGuid, Hob.Raw); > + } > +} > + > +/** > + Migrates SEC modules in the given firmware volume. > + > + Migrating SECURITY_CORE files requires special treatment since they a= re not > tracked for PEI dispatch. > + > + This functioun should be called after the FV has been copied to its p= ost- > memory location and the PEI Core FV list has > + been updated. > + > + @param Private Pointer to the PeiCore's private data structu= re. > + @param FvIndex The firmware volume index to migrate. > + @param OrgFvHandle The handle to the firmware volume in temporar= y > memory. > + > + @retval EFI_SUCCESS SEC modules were migrated successfull= y > + @retval EFI_INVALID_PARAMETER The Private pointer is NULL or FvCoun= t is 11) There's EFI_NOT_FOUND returned in the function body. > invalid. > + > +**/ > +EFI_STATUS > +EFIAPI > +MigrateSecModulesInFv ( > + IN PEI_CORE_INSTANCE *Private, > + IN UINTN FvIndex, > + IN UINTN OrgFvHandle > + ) > +{ > + EFI_STATUS Status; > + EFI_STATUS FindFileStatus; > + EFI_PEI_FILE_HANDLE MigratedFileHandle; > + EFI_PEI_FILE_HANDLE FileHandle; > + UINT32 SectionAuthenticationStatus; > + UINT32 FileSize; > + VOID *OrgPe32SectionData; > + VOID *Pe32SectionData; > + EFI_FFS_FILE_HEADER *FfsFileHeader; > + EFI_COMMON_SECTION_HEADER *Section; > + BOOLEAN IsFfs3Fv; > + UINTN SectionInstance; > + > + if (Private =3D=3D NULL || FvIndex >=3D Private->FvCount) { > + return EFI_INVALID_PARAMETER; > + } > + > + do { > + FindFileStatus =3D PeiFfsFindNextFile ( > + GetPeiServicesTablePointer (), > + EFI_FV_FILETYPE_SECURITY_CORE, > + Private->Fv[FvIndex].FvHandle, > + &MigratedFileHandle > + ); > + if (!EFI_ERROR (FindFileStatus ) && MigratedFileHandle !=3D NULL) { > + FileHandle =3D (EFI_PEI_FILE_HANDLE) ((UINTN) MigratedFileHandle = - (UINTN) > Private->Fv[FvIndex].FvHandle + OrgFvHandle); > + FfsFileHeader =3D (EFI_FFS_FILE_HEADER *) MigratedFileHandle; > + > + DEBUG ((DEBUG_VERBOSE, " Migrating SEC_CORE MigratedFileHandle= at > 0x%x.\n", (UINTN) MigratedFileHandle)); > + DEBUG ((DEBUG_VERBOSE, " FileHandle at 0x%x= .\n", (UINTN) > FileHandle)); > + > + IsFfs3Fv =3D CompareGuid (&Private->Fv[FvIndex].FvHeader->FileSys= temGuid, > &gEfiFirmwareFileSystem3Guid); > + if (IS_FFS_FILE2 (FfsFileHeader)) { > + ASSERT (FFS_FILE2_SIZE (FfsFileHeader) > 0x00FFFFFF); > + if (!IsFfs3Fv) { > + DEBUG ((DEBUG_ERROR, "It is a FFS3 formatted file: %g in a no= n-FFS3 > formatted FV.\n", &FfsFileHeader->Name)); > + return EFI_NOT_FOUND; > + } > + Section =3D (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) FfsFileHea= der + > sizeof (EFI_FFS_FILE_HEADER2)); > + FileSize =3D FFS_FILE2_SIZE (FfsFileHeader) - sizeof (EFI_FFS_F= ILE_HEADER2); > + } else { > + Section =3D (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) FfsFileHea= der + > sizeof (EFI_FFS_FILE_HEADER)); > + FileSize =3D FFS_FILE_SIZE (FfsFileHeader) - sizeof (EFI_FFS_FI= LE_HEADER); > + } > + > + SectionInstance =3D 1; > + SectionAuthenticationStatus =3D 0; > + Status =3D ProcessSection ( > + GetPeiServicesTablePointer (), > + EFI_SECTION_PE32, > + &SectionInstance, > + Section, > + FileSize, > + &Pe32SectionData, > + &SectionAuthenticationStatus, > + IsFfs3Fv > + ); > + > + if (!EFI_ERROR (Status)) { > + OrgPe32SectionData =3D (VOID *) ((UINTN) Pe32SectionData - (UIN= TN) > MigratedFileHandle + (UINTN) FileHandle); > + DEBUG ((DEBUG_VERBOSE, " PE32 section in migrated file at = 0x%x.\n", > (UINTN) Pe32SectionData)); > + DEBUG ((DEBUG_VERBOSE, " PE32 section in original file at = 0x%x.\n", > (UINTN) OrgPe32SectionData)); > + Status =3D LoadAndRelocatePeCoffImageInPlace (OrgPe32SectionDat= a, > Pe32SectionData); > + ASSERT_EFI_ERROR (Status); > + } > + } > + } while (!EFI_ERROR (FindFileStatus)); > + > + return EFI_SUCCESS; > +} > + > +/** > + Migrates PEIMs in the given firmware volume. > + > + @param Private Pointer to the PeiCore's private data structu= re. > + @param FvIndex The firmware volume index to migrate. > + @param OrgFvHandle The handle to the firmware volume in temporar= y > memory. > + @param FvHandle The handle to the firmware volume in permanen= t > memory. > + > + @retval EFI_SUCCESS The PEIMs in the FV were migrated suc= cessfully > + @retval EFI_INVALID_PARAMETER The Private pointer is NULL or FvCoun= t is > invalid. > + > +**/ > +EFI_STATUS > +EFIAPI > +MigratePeimsInFv ( > + IN PEI_CORE_INSTANCE *Private, > + IN UINTN FvIndex, > + IN UINTN OrgFvHandle, > + IN UINTN FvHandle > + ) > +{ > + EFI_STATUS Status; > + volatile UINTN FileIndex; > + EFI_PEI_FILE_HANDLE MigratedFileHandle; > + EFI_PEI_FILE_HANDLE FileHandle; > + > + if (Private =3D=3D NULL || FvIndex >=3D Private->FvCount) { > + return EFI_INVALID_PARAMETER; > + } > + > + if (Private->Fv[FvIndex].ScanFv) { > + for (FileIndex =3D 0; FileIndex < Private->Fv[FvIndex].PeimCount; F= ileIndex++) { > + if (Private->Fv[FvIndex].FvFileHandles[FileIndex] !=3D NULL) { > + FileHandle =3D Private->Fv[FvIndex].FvFileHandles[FileIndex]; > + > + MigratedFileHandle =3D (EFI_PEI_FILE_HANDLE) ((UINTN) FileHandl= e - > OrgFvHandle + FvHandle); > + > + DEBUG ((DEBUG_VERBOSE, " Migrating FileHandle %2d ", FileInd= ex)); > + Status =3D MigratePeim (FileHandle, MigratedFileHandle); > + DEBUG ((DEBUG_INFO, "\n")); DEBUG_VERBOSE is used line above but DEBUG_INFO here. > + ASSERT_EFI_ERROR (Status); > + > + if (!EFI_ERROR (Status)) { > + // if (Private->Fv[FvIndex].PeimState[FileIndex] =3D=3D > PEIM_STATE_REGISTER_FOR_SHADOW) { > + // Private->Fv[FvIndex].PeimState[FileIndex]++; > + // } 12) Remove the code which have been commented out. > + Private->Fv[FvIndex].FvFileHandles[FileIndex] =3D MigratedFil= eHandle; > + if (FvIndex =3D=3D Private->CurrentPeimFvCount) { > + Private->CurrentFvFileHandles[FileIndex] =3D MigratedFileHa= ndle; > + } > + } > + } > + } > + } > + > + return EFI_SUCCESS; > +} > + > +/** > + Migrate FVs out of temporary RAM before the cache is flushed. > + > + @param Private PeiCore's private data structure > + @param SecCoreData Points to a data structure containing informat= ion > about the PEI core's operating > + environment, such as the size and location of = temporary RAM, > the stack location and > + the BFV location. > + > + @retval EFI_SUCCESS Succesfully migrated installed FVs from= temporary > RAM to permanent memory. > + @retval EFI_OUT_OF_RESOURCES Insufficient memory exists to allocate > needed pages. > + > +**/ > +EFI_STATUS > +EFIAPI > +EvacuateTempRam ( > + IN PEI_CORE_INSTANCE *Private, > + IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData > + ) > +{ > + EFI_STATUS Status; > + volatile UINTN FvIndex; > + volatile UINTN FvChildIndex; > + UINTN ChildFvOffset; > + EFI_FIRMWARE_VOLUME_HEADER *FvHeader; > + EFI_FIRMWARE_VOLUME_HEADER *ChildFvHeader; > + EFI_FIRMWARE_VOLUME_HEADER *MigratedFvHeader; > + EFI_FIRMWARE_VOLUME_HEADER *MigratedChildFvHeader; > + > + PEI_CORE_FV_HANDLE PeiCoreFvHandle; > + EFI_PEI_CORE_FV_LOCATION_PPI *PeiCoreFvLocationPpi; > + > + ASSERT (Private->PeiMemoryInstalled); > + > + DEBUG ((DEBUG_VERBOSE, "Beginning evacuation of content in temporary > RAM.\n")); > + > + // > + // Migrate PPI Pointers of PEI_CORE from temporary memory to newly lo= aded > PEI_CORE in permanent memory. > + // > + Status =3D PeiLocatePpi ((CONST EFI_PEI_SERVICES **) &Private->Ps, > &gEfiPeiCoreFvLocationPpiGuid, 0, NULL, (VOID **) &PeiCoreFvLocationPpi)= ; > + if (!EFI_ERROR (Status) && (PeiCoreFvLocationPpi->PeiCoreFvLocation != = =3D > NULL)) { > + PeiCoreFvHandle.FvHandle =3D (EFI_PEI_FV_HANDLE) PeiCoreFvLocationP= pi- > >PeiCoreFvLocation; > + } else { > + PeiCoreFvHandle.FvHandle =3D (EFI_PEI_FV_HANDLE) SecCoreData- > >BootFirmwareVolumeBase; > + } > + for (FvIndex =3D 0; FvIndex < Private->FvCount; FvIndex++) { > + if (Private->Fv[FvIndex].FvHandle =3D=3D PeiCoreFvHandle.FvHandle) = { > + PeiCoreFvHandle =3D Private->Fv[FvIndex]; > + break; > + } > + } > + Status =3D EFI_SUCCESS; > + > + ConvertPeiCorePpiPointers (Private, PeiCoreFvHandle); > + > + for (FvIndex =3D 0; FvIndex < Private->FvCount; FvIndex++) { > + FvHeader =3D Private->Fv[FvIndex].FvHeader; > + ASSERT (FvHeader !=3D NULL); > + ASSERT (FvIndex < Private->FvCount); > + > + DEBUG ((DEBUG_VERBOSE, "FV[%02d] at 0x%x.\n", FvIndex, (UINTN) > FvHeader)); > + if ( > + !( > + ((EFI_PHYSICAL_ADDRESS)(UINTN) FvHeader >=3D Private- > >PhysicalMemoryBegin) && > + (((EFI_PHYSICAL_ADDRESS)(UINTN) FvHeader + (FvHeader->FvLength = - 1)) > < Private->FreePhysicalMemoryTop) > + ) > + ) { > + Status =3D PeiServicesAllocatePages ( > + EfiBootServicesCode, > + EFI_SIZE_TO_PAGES ((UINTN) FvHeader->FvLength), > + (EFI_PHYSICAL_ADDRESS *) &MigratedFvHeader > + ); > + ASSERT_EFI_ERROR (Status); > + > + DEBUG (( > + DEBUG_VERBOSE, > + " Migrating FV[%d] from 0x%08X to 0x%08X\n", > + FvIndex, > + (UINTN) FvHeader, > + (UINTN) MigratedFvHeader > + )); > + > + CopyMem (MigratedFvHeader, FvHeader, (UINTN) FvHeader->FvLength); > + > + // > + // Migrate any children for this FV now > + // > + for (FvChildIndex =3D FvIndex; FvChildIndex < Private->FvCount; > FvChildIndex++) { > + ChildFvHeader =3D Private->Fv[FvChildIndex].FvHeader; > + if ( > + ((UINTN) ChildFvHeader > (UINTN) FvHeader) && > + (((UINTN) ChildFvHeader + ChildFvHeader->FvLength) < ((UINTN) > FvHeader) + FvHeader->FvLength) > + ) { > + DEBUG ((DEBUG_VERBOSE, " Child FV[%02d] is being migrated.= \n", > FvChildIndex)); > + ChildFvOffset =3D (UINTN) ChildFvHeader - (UINTN) FvHeader; > + DEBUG ((DEBUG_VERBOSE, " Child FV offset =3D 0x%x.\n", Chi= ldFvOffset)); > + MigratedChildFvHeader =3D (EFI_FIRMWARE_VOLUME_HEADER *) ((UI= NTN) > MigratedFvHeader + ChildFvOffset); > + Private->Fv[FvChildIndex].FvHeader =3D MigratedChildFvHeader; > + Private->Fv[FvChildIndex].FvHandle =3D (EFI_PEI_FV_HANDLE) > MigratedChildFvHeader; > + DEBUG ((DEBUG_VERBOSE, " Child migrated FV header at 0x%x.= \n", > (UINTN) MigratedChildFvHeader)); > + > + // @todo: find issue with file and section alignment in SEC P= E32 images > for migration > + // (alignment in P32 is given as 32-bit when actual al= ignment is 16-bit) > + // SEC PPIs are currently re-installed with a dedicate= d PEIM > + // Status =3D MigrateSecModulesInFv (Private, FvChildIndex, (= UINTN) > ChildFvHeader); > + // ASSERT_EFI_ERROR (Status); 13) Remove the code which have been commented out. > + Status =3D MigratePeimsInFv (Private, FvChildIndex, (UINTN) = ChildFvHeader, > (UINTN) MigratedChildFvHeader); > + ASSERT_EFI_ERROR (Status); > + > + ConvertPpiPointersFv ( > + Private, > + (UINTN) ChildFvHeader, > + (UINTN) MigratedChildFvHeader, > + (UINTN) ChildFvHeader->FvLength - 1 > + ); > + > + ConvertStatusCodeCallbacks ( > + (UINTN) ChildFvHeader, > + (UINTN) MigratedChildFvHeader, > + (UINTN) ChildFvHeader->FvLength - 1 > + ); > + > + ConvertFvHob (Private, (UINTN) ChildFvHeader, (UINTN) > MigratedChildFvHeader); > + } > + } > + Private->Fv[FvIndex].FvHeader =3D MigratedFvHeader; > + Private->Fv[FvIndex].FvHandle =3D (EFI_PEI_FV_HANDLE) MigratedFvH= eader; > + > + // @todo: find issue with file and section alignment in SEC PE32 = images for > migration > + // (alignment in P32 is given as 32-bit when actual alignm= ent is 16-bit) > + // SEC PPIs are currently re-installed with a dedicated PE= IM > + // Status =3D MigrateSecModulesInFv (Private, FvIndex, (UINTN) Fv= Header); > + // ASSERT_EFI_ERROR (Status); 14) Remove the code which have been commented out. > + Status =3D MigratePeimsInFv (Private, FvIndex, (UINTN) FvHeader, = (UINTN) > MigratedFvHeader); > + ASSERT_EFI_ERROR (Status); > + > + ConvertPpiPointersFv ( > + Private, > + (UINTN) FvHeader, > + (UINTN) MigratedFvHeader, > + (UINTN) FvHeader->FvLength - 1 > + ); > + > + ConvertStatusCodeCallbacks ( > + (UINTN) FvHeader, > + (UINTN) MigratedFvHeader, > + (UINTN) FvHeader->FvLength - 1 > + ); > + > + ConvertFvHob (Private, (UINTN) FvHeader, (UINTN) MigratedFvHeader= ); > + } > + } > + > + RemoveFvHobsInTemporaryMemory (Private); > + > + return Status; > +} > + > /** > Conduct PEIM dispatch. >=20 > diff --git a/MdeModulePkg/Core/Pei/Image/Image.c > b/MdeModulePkg/Core/Pei/Image/Image.c > index e3ee3699337f..612797722a3e 100644 > --- a/MdeModulePkg/Core/Pei/Image/Image.c > +++ b/MdeModulePkg/Core/Pei/Image/Image.c > @@ -444,6 +444,121 @@ LoadAndRelocatePeCoffImage ( > return ReturnStatus; > } >=20 > +/** > + Loads and relocates a PE/COFF image in place. > + > + @param Pe32Data The base address of the PE/COFF file that is = to be > loaded and relocated > + @param ImageAddress The base address of the relocated PE/COFF ima= ge > + > + @retval EFI_SUCCESS The file was loaded and relocated 15) There're other return values from PeCoffLoaderLoadImage() and PeCoffLoaderRelocateImage(). > + > +**/ > +EFI_STATUS > +LoadAndRelocatePeCoffImageInPlace ( > + IN VOID *Pe32Data, > + IN VOID *ImageAddress > + ) > +{ > + EFI_STATUS Status; > + PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; > + > + ZeroMem (&ImageContext, sizeof (ImageContext)); > + ImageContext.Handle =3D Pe32Data; > + ImageContext.ImageRead =3D PeiImageRead; > + > + Status =3D PeCoffLoaderGetImageInfo (&ImageContext); > + if (EFI_ERROR (Status)) { > + ASSERT_EFI_ERROR (Status); > + return Status; > + } > + > + ImageContext.ImageAddress =3D (PHYSICAL_ADDRESS)(UINTN) ImageAddres= s; > + > + // > + // Load the image in place > + // > + Status =3D PeCoffLoaderLoadImage (&ImageContext); > + if (EFI_ERROR (Status)) { > + ASSERT_EFI_ERROR (Status); > + return Status; > + } > + > + // > + // Relocate the image in place > + // > + Status =3D PeCoffLoaderRelocateImage (&ImageContext); > + if (EFI_ERROR (Status)) { > + ASSERT_EFI_ERROR (Status); > + return Status; > + } > + > + // > + // Flush the instruction cache so the image data is written before we= execute > it > + // > + if (ImageContext.ImageAddress !=3D (EFI_PHYSICAL_ADDRESS)(UINTN) > Pe32Data) { > + InvalidateInstructionCacheRange ((VOID > *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize); > + } > + > + return Status; > +} > + > +/** > + Find the PE32 Data for an FFS file. > + > + @param FileHandle Pointer to the FFS file header of the image. > + @param Pe32Data Pointer to a (VOID *) PE32 Data pointer. > + > + @retval EFI_SUCCESS Image is successfully loaded. > + @retval EFI_NOT_FOUND Fail to locate PE32 Data. > + > +**/ > +EFI_STATUS > +PeiGetPe32Data ( > + IN EFI_PEI_FILE_HANDLE FileHandle, > + OUT VOID **Pe32Data > + ) > +{ > + EFI_STATUS Status; > + EFI_SECTION_TYPE SearchType1; > + EFI_SECTION_TYPE SearchType2; > + UINT32 AuthenticationState; > + > + *Pe32Data =3D NULL; > + > + if (FeaturePcdGet (PcdPeiCoreImageLoaderSearchTeSectionFirst)) { > + SearchType1 =3D EFI_SECTION_TE; > + SearchType2 =3D EFI_SECTION_PE32; > + } else { > + SearchType1 =3D EFI_SECTION_PE32; > + SearchType2 =3D EFI_SECTION_TE; > + } > + > + // > + // Try to find a first exe section (if > PcdPeiCoreImageLoaderSearchTeSectionFirst > + // is true, TE will be searched first). > + // > + Status =3D PeiServicesFfsFindSectionData3 ( > + SearchType1, > + 0, > + FileHandle, > + Pe32Data, > + &AuthenticationState > + ); > + // > + // If we didn't find a first exe section, try to find the second exe = section. > + // > + if (EFI_ERROR (Status)) { > + Status =3D PeiServicesFfsFindSectionData3 ( > + SearchType2, > + 0, > + FileHandle, > + Pe32Data, > + &AuthenticationState > + ); > + } > + return Status; > +} > + > /** > Loads a PEIM into memory for subsequent execution. If there are compr= essed > images or images that need to be relocated into memory for performanc= e > reasons, > diff --git a/MdeModulePkg/Core/Pei/Memory/MemoryServices.c > b/MdeModulePkg/Core/Pei/Memory/MemoryServices.c > index 6b3a64a811cd..9d933f0393a8 100644 > --- a/MdeModulePkg/Core/Pei/Memory/MemoryServices.c > +++ b/MdeModulePkg/Core/Pei/Memory/MemoryServices.c > @@ -166,6 +166,88 @@ MigrateMemoryPages ( > Private->FreePhysicalMemoryTop =3D NewMemPagesBase; > } >=20 > +/** > + Removes any FV HOBs whose base address is not in PEI installed memory= . > + > + @param[in] Private Pointer to PeiCore's private data structu= re. > + > +**/ > +VOID > +RemoveFvHobsInTemporaryMemory ( > + IN PEI_CORE_INSTANCE *Private > + ) > +{ > + EFI_PEI_HOB_POINTERS Hob; > + EFI_HOB_FIRMWARE_VOLUME *FirmwareVolumeHob; > + > + DEBUG ((DEBUG_INFO, "Removing FVs in FV HOB not already migrated to > permanent memory.\n")); > + > + for (Hob.Raw =3D GetHobList (); !END_OF_HOB_LIST (Hob); Hob.Raw =3D > GET_NEXT_HOB (Hob)) { > + if (GET_HOB_TYPE (Hob) =3D=3D EFI_HOB_TYPE_FV || GET_HOB_TYPE (Hob)= =3D=3D > EFI_HOB_TYPE_FV2 || GET_HOB_TYPE (Hob) =3D=3D EFI_HOB_TYPE_FV3) { > + FirmwareVolumeHob =3D Hob.FirmwareVolume; > + DEBUG ((DEBUG_INFO, " Found FV HOB.\n")); > + DEBUG (( > + DEBUG_INFO, > + " BA=3D%016lx L=3D%016lx\n", > + FirmwareVolumeHob->BaseAddress, > + FirmwareVolumeHob->Length > + )); > + if ( > + !( > + ((EFI_PHYSICAL_ADDRESS) (UINTN) FirmwareVolumeHob- > >BaseAddress >=3D Private->PhysicalMemoryBegin) && > + (((EFI_PHYSICAL_ADDRESS) (UINTN) FirmwareVolumeHob->BaseAddre= ss > + (FirmwareVolumeHob->Length - 1)) < Private->FreePhysicalMemoryTop) > + ) > + ) { > + DEBUG ((DEBUG_INFO, " Removing FV HOB to an FV in T-RAM (w= as not > migrated).\n")); > + Hob.Header->HobType =3D EFI_HOB_TYPE_UNUSED; > + } > + } > + } > +} > + > +/** > + Migrate the base address in firmware volume allocation HOBs > + from temporary memory to PEI installed memory. > + > + @param[in] PrivateData Pointer to PeiCore's private data structu= re. > + @param[in] OrgFvHandle Address of FV Handle in temporary memory. > + @param[in] FvHandle Address of FV Handle in permanent memory. > + > +**/ > +VOID > +ConvertFvHob ( > + IN PEI_CORE_INSTANCE *PrivateData, > + IN UINTN OrgFvHandle, > + IN UINTN FvHandle > + ) > +{ > + EFI_PEI_HOB_POINTERS Hob; > + EFI_HOB_FIRMWARE_VOLUME *FirmwareVolumeHob; > + EFI_HOB_FIRMWARE_VOLUME2 *FirmwareVolume2Hob; > + EFI_HOB_FIRMWARE_VOLUME3 *FirmwareVolume3Hob; > + > + DEBUG ((DEBUG_INFO, "Converting FVs in FV HOB.\n")); > + > + for (Hob.Raw =3D GetHobList (); !END_OF_HOB_LIST (Hob); Hob.Raw =3D > GET_NEXT_HOB (Hob)) { > + if (GET_HOB_TYPE (Hob) =3D=3D EFI_HOB_TYPE_FV) { > + FirmwareVolumeHob =3D Hob.FirmwareVolume; > + if (FirmwareVolumeHob->BaseAddress =3D=3D OrgFvHandle) { > + FirmwareVolumeHob->BaseAddress =3D FvHandle; > + } > + } else if (GET_HOB_TYPE (Hob) =3D=3D EFI_HOB_TYPE_FV2) { > + FirmwareVolume2Hob =3D Hob.FirmwareVolume2; > + if (FirmwareVolume2Hob->BaseAddress =3D=3D OrgFvHandle) { > + FirmwareVolume2Hob->BaseAddress =3D FvHandle; > + } > + } else if (GET_HOB_TYPE (Hob) =3D=3D EFI_HOB_TYPE_FV3) { > + FirmwareVolume3Hob =3D Hob.FirmwareVolume3; > + if (FirmwareVolume3Hob->BaseAddress =3D=3D OrgFvHandle) { > + FirmwareVolume3Hob->BaseAddress =3D FvHandle; > + } > + } > + } > +} > + > /** > Migrate MemoryBaseAddress in memory allocation HOBs > from the temporary memory to PEI installed memory. > diff --git a/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c > b/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c > index cca57c4c0686..4a0671f87604 100644 > --- a/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c > +++ b/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c > @@ -176,6 +176,9 @@ PeiCore ( > EFI_HOB_HANDOFF_INFO_TABLE *HandoffInformationTable; > EFI_PEI_TEMPORARY_RAM_DONE_PPI *TemporaryRamDonePpi; > UINTN Index; > + BOOLEAN Shadow; 16) Suggest to use different name other than Shadow. It's mainly for migra= te temporary ram, not exactly the same as PcdShadowPeimOnBoot. Regards, Jian > + > + Shadow =3D FALSE; >=20 > // > // Retrieve context passed into PEI Core > @@ -418,6 +421,27 @@ PeiCore ( > ProcessPpiListFromSec ((CONST EFI_PEI_SERVICES **) &PrivateData.P= s, > PpiList); > } > } else { > + if (PcdGetBool (PcdMigrateTemporaryRamFirmwareVolumes)) { > + if (PrivateData.HobList.HandoffInformationTable->BootMode =3D=3D > BOOT_ON_S3_RESUME) { > + Shadow =3D PcdGetBool (PcdShadowPeimOnS3Boot); > + } else { > + Shadow =3D PcdGetBool (PcdShadowPeimOnBoot); > + } > + } > + > + if (Shadow) { > + DEBUG ((DEBUG_VERBOSE, "PPI lists before temporary RAM > evacuation:\n")); > + DumpPpiList (&PrivateData); > + > + // > + // Migrate installed content from Temporary RAM to Permanent RAM > + // > + EvacuateTempRam (&PrivateData, SecCoreData); > + > + DEBUG ((DEBUG_VERBOSE, "PPI lists after temporary RAM evacuation:= \n")); > + DumpPpiList (&PrivateData); > + } > + > // > // Try to locate Temporary RAM Done Ppi. > // > diff --git a/MdeModulePkg/Core/Pei/Ppi/Ppi.c > b/MdeModulePkg/Core/Pei/Ppi/Ppi.c > index 1ffe718c4702..018b25f86470 100644 > --- a/MdeModulePkg/Core/Pei/Ppi/Ppi.c > +++ b/MdeModulePkg/Core/Pei/Ppi/Ppi.c > @@ -198,6 +198,227 @@ ConvertPpiPointers ( > } > } >=20 > +/** > + > + Migrate Notify Pointers inside an FV from temporary memory to permane= nt > memory. > + > + @param PrivateData Pointer to PeiCore's private data structure. > + @param OrgFvHandle Address of FV Handle in temporary memory. > + @param FvHandle Address of FV Handle in permanent memory. > + @param FvSize Size of the FV. > + > +**/ > +VOID > +ConvertPpiPointersFv ( > + IN PEI_CORE_INSTANCE *PrivateData, > + IN UINTN OrgFvHandle, > + IN UINTN FvHandle, > + IN UINTN FvSize > + ) > +{ > + UINT8 Index; > + UINTN Offset; > + BOOLEAN OffsetPositive; > + EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *FvInfoPpi; > + UINT8 GuidIndex; > + EFI_GUID *Guid; > + EFI_GUID *GuidCheckList[2]; > + > + GuidCheckList[0] =3D &gEfiPeiFirmwareVolumeInfoPpiGuid; > + GuidCheckList[1] =3D &gEfiPeiFirmwareVolumeInfo2PpiGuid; > + > + if (FvHandle > OrgFvHandle) { > + OffsetPositive =3D TRUE; > + Offset =3D FvHandle - OrgFvHandle; > + } else { > + OffsetPositive =3D FALSE; > + Offset =3D OrgFvHandle - FvHandle; > + } > + > + DEBUG ((DEBUG_VERBOSE, "Converting PPI pointers in FV.\n")); > + DEBUG (( > + DEBUG_VERBOSE, > + " OrgFvHandle at 0x%08x. FvHandle at 0x%08x. FvSize =3D 0x%x\n", > + (UINTN) OrgFvHandle, > + (UINTN) FvHandle, > + FvSize > + )); > + DEBUG (( > + DEBUG_VERBOSE, > + " OrgFvHandle range: 0x%08x - 0x%08x\n", > + OrgFvHandle, > + OrgFvHandle + FvSize > + )); > + > + for (Index =3D 0; Index < PrivateData->PpiData.CallbackNotifyList.Cur= rentCount; > Index++) { > + ConvertPointer ( > + (VOID **) &PrivateData- > >PpiData.CallbackNotifyList.NotifyPtrs[Index].Raw, > + OrgFvHandle, > + OrgFvHandle + FvSize, > + Offset, > + OffsetPositive > + ); > + ConvertPointer ( > + (VOID **) &PrivateData- > >PpiData.CallbackNotifyList.NotifyPtrs[Index].Notify->Guid, > + OrgFvHandle, > + OrgFvHandle + FvSize, > + Offset, > + OffsetPositive > + ); > + ConvertPointer ( > + (VOID **) &PrivateData- > >PpiData.CallbackNotifyList.NotifyPtrs[Index].Notify->Notify, > + OrgFvHandle, > + OrgFvHandle + FvSize, > + Offset, > + OffsetPositive > + ); > + } > + > + for (Index =3D 0; Index < PrivateData->PpiData.DispatchNotifyList.Cur= rentCount; > Index++) { > + ConvertPointer ( > + (VOID **) &PrivateData->PpiData.DispatchNotifyList.NotifyPtrs[Ind= ex].Raw, > + OrgFvHandle, > + OrgFvHandle + FvSize, > + Offset, > + OffsetPositive > + ); > + ConvertPointer ( > + (VOID **) &PrivateData- > >PpiData.DispatchNotifyList.NotifyPtrs[Index].Notify->Guid, > + OrgFvHandle, > + OrgFvHandle + FvSize, > + Offset, > + OffsetPositive > + ); > + ConvertPointer ( > + (VOID **) &PrivateData- > >PpiData.DispatchNotifyList.NotifyPtrs[Index].Notify->Notify, > + OrgFvHandle, > + OrgFvHandle + FvSize, > + Offset, > + OffsetPositive > + ); > + } > + > + for (Index =3D 0; Index < PrivateData->PpiData.PpiList.CurrentCount; = Index++) { > + ConvertPointer ( > + (VOID **) &PrivateData->PpiData.PpiList.PpiPtrs[Index].Raw, > + OrgFvHandle, > + OrgFvHandle + FvSize, > + Offset, > + OffsetPositive > + ); > + ConvertPointer ( > + (VOID **) &PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi->Guid, > + OrgFvHandle, > + OrgFvHandle + FvSize, > + Offset, > + OffsetPositive > + ); > + ConvertPointer ( > + (VOID **) &PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi->Ppi, > + OrgFvHandle, > + OrgFvHandle + FvSize, > + Offset, > + OffsetPositive > + ); > + > + Guid =3D PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi->Guid; > + for (GuidIndex =3D 0; GuidIndex < ARRAY_SIZE (GuidCheckList); ++Gui= dIndex) { > + // > + // Don't use CompareGuid function here for performance reasons. > + // Instead we compare the GUID as INT32 at a time and branch > + // on the first failed comparison. > + // > + if ((((INT32 *)Guid)[0] =3D=3D ((INT32 *)GuidCheckList[GuidIndex]= )[0]) && > + (((INT32 *)Guid)[1] =3D=3D ((INT32 *)GuidCheckList[GuidIndex]= )[1]) && > + (((INT32 *)Guid)[2] =3D=3D ((INT32 *)GuidCheckList[GuidIndex]= )[2]) && > + (((INT32 *)Guid)[3] =3D=3D ((INT32 *)GuidCheckList[GuidIndex]= )[3])) { > + FvInfoPpi =3D PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi->= Ppi; > + DEBUG ((DEBUG_VERBOSE, " FvInfo: %p -> ", FvInfoPpi->FvInf= o)); > + if ((UINTN)FvInfoPpi->FvInfo =3D=3D OrgFvHandle) { > + ConvertPointer ( > + (VOID **)&FvInfoPpi->FvInfo, > + OrgFvHandle, > + OrgFvHandle + FvSize, > + Offset, > + OffsetPositive > + ); > + DEBUG ((DEBUG_VERBOSE, "%p", FvInfoPpi->FvInfo)); > + } > + DEBUG ((DEBUG_VERBOSE, "\n")); > + break; > + } > + } > + } > +} > + > +/** > + > + Dumps the PPI lists to debug output. > + > + @param PrivateData Points to PeiCore's private instance data. > + > +**/ > +VOID > +DumpPpiList ( > + IN PEI_CORE_INSTANCE *PrivateData > + ) > +{ > + DEBUG_CODE_BEGIN (); > + UINTN Index; > + > + if (PrivateData =3D=3D NULL) { > + return; > + } > + > + for (Index =3D 0; Index < PrivateData->PpiData.CallbackNotifyList.Cur= rentCount; > Index++) { > + DEBUG (( > + DEBUG_VERBOSE, > + "CallbackNotify[%2d] {%g} at 0x%x (%a)\n", > + Index, > + PrivateData->PpiData.CallbackNotifyList.NotifyPtrs[Index].Notify-= >Guid, > + (UINTN) PrivateData->PpiData.CallbackNotifyList.NotifyPtrs[Index]= .Raw, > + ( > + !( > + ((EFI_PHYSICAL_ADDRESS) (UINTN) PrivateData- > >PpiData.CallbackNotifyList.NotifyPtrs[Index].Raw >=3D PrivateData- > >PhysicalMemoryBegin) && > + (((EFI_PHYSICAL_ADDRESS) ((UINTN) PrivateData- > >PpiData.CallbackNotifyList.NotifyPtrs[Index].Raw) + sizeof > (EFI_PEI_NOTIFY_DESCRIPTOR)) < PrivateData->FreePhysicalMemoryTop) > + ) > + ? "CAR" : "Post-Memory" > + ) > + )); > + } > + for (Index =3D 0; Index < PrivateData->PpiData.DispatchNotifyList.Cur= rentCount; > Index++) { > + DEBUG ((DEBUG_VERBOSE, > + "DispatchNotify[%2d] {%g} at 0x%x (%a)\n", > + Index, > + PrivateData->PpiData.DispatchNotifyList.NotifyPtrs[Index].Notify->G= uid, > + (UINTN) PrivateData->PpiData.DispatchNotifyList.NotifyPtrs[Index].R= aw, > + ( > + !( > + ((EFI_PHYSICAL_ADDRESS) (UINTN) PrivateData- > >PpiData.DispatchNotifyList.NotifyPtrs[Index].Raw >=3DPrivateData- > >PhysicalMemoryBegin) && > + (((EFI_PHYSICAL_ADDRESS) ((UINTN) PrivateData- > >PpiData.DispatchNotifyList.NotifyPtrs[Index].Raw) + sizeof > (EFI_PEI_NOTIFY_DESCRIPTOR)) < PrivateData->FreePhysicalMemoryTop) > + ) > + ? "CAR" : "Post-Memory" > + ) > + )); > + } > + for (Index =3D 0; Index < PrivateData->PpiData.PpiList.CurrentCount; = Index++) { > + DEBUG ((DEBUG_VERBOSE, > + "PPI[%2d] {%g} at 0x%x (%a)\n", > + Index, > + PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi->Guid, > + (UINTN) PrivateData->PpiData.PpiList.PpiPtrs[Index].Raw, > + ( > + !( > + ((EFI_PHYSICAL_ADDRESS) (UINTN) PrivateData- > >PpiData.PpiList.PpiPtrs[Index].Raw >=3D PrivateData->PhysicalMemoryBegi= n) && > + (((EFI_PHYSICAL_ADDRESS) ((UINTN) PrivateData- > >PpiData.PpiList.PpiPtrs[Index].Raw) + sizeof (EFI_PEI_PPI_DESCRIPTOR)) = < > PrivateData->FreePhysicalMemoryTop) > + ) > + ? "CAR" : "Post-Memory" > + ) > + )); > + } > + DEBUG_CODE_END (); > +} > + > /** >=20 > This function installs an interface in the PEI PPI database by GUID. > @@ -830,3 +1051,69 @@ ProcessPpiListFromSec ( > } > } >=20 > +/** > + > + Migrate PPI Pointers of PEI_CORE from temporary memory to permanent > memory. > + > + @param PrivateData Pointer to PeiCore's private data structure. > + @param CoreFvHandle Address of PEI_CORE FV Handle in temporary > memory. > + > +**/ > + > +VOID > +ConvertPeiCorePpiPointers ( > + IN PEI_CORE_INSTANCE *PrivateData, > + PEI_CORE_FV_HANDLE CoreFvHandle > + ) > +{ > + EFI_FV_FILE_INFO FileInfo; > + EFI_PHYSICAL_ADDRESS OrgImageBase; > + EFI_PHYSICAL_ADDRESS MigratedImageBase; > + UINTN PeiCoreModuleSize; > + EFI_PEI_FILE_HANDLE PeiCoreFileHandle; > + VOID *PeiCoreImageBase; > + VOID *PeiCoreEntryPoint; > + EFI_STATUS Status; > + > + PeiCoreFileHandle =3D NULL; > + > + // > + // Find the PEI Core in the BFV in temporary memory. > + // > + Status =3D CoreFvHandle.FvPpi->FindFileByType ( > + CoreFvHandle.FvPpi, > + EFI_FV_FILETYPE_PEI_CORE, > + CoreFvHandle.FvHandle, > + &PeiCoreFileHandle > + ); > + ASSERT_EFI_ERROR (Status); > + > + if (!EFI_ERROR (Status)) { > + Status =3D CoreFvHandle.FvPpi->GetFileInfo (CoreFvHandle.FvPpi, > PeiCoreFileHandle, &FileInfo); > + ASSERT_EFI_ERROR (Status); > + > + Status =3D PeiGetPe32Data (PeiCoreFileHandle, &PeiCoreImageBase); > + ASSERT_EFI_ERROR (Status); > + > + // > + // Find PEI Core EntryPoint in the BFV in temporary memory. > + // > + Status =3D PeCoffLoaderGetEntryPoint ((VOID *) (UINTN) PeiCoreImage= Base, > &PeiCoreEntryPoint); > + ASSERT_EFI_ERROR (Status); > + > + OrgImageBase =3D (UINTN) PeiCoreImageBase; > + MigratedImageBase =3D (UINTN) _ModuleEntryPoint - ((UINTN) > PeiCoreEntryPoint - (UINTN) PeiCoreImageBase); > + > + // > + // Size of loaded PEI_CORE in permanent memory. > + // > + PeiCoreModuleSize =3D (UINTN)FileInfo.BufferSize - ((UINTN) OrgImag= eBase - > (UINTN) FileInfo.Buffer); > + > + // > + // Migrate PEI_CORE PPI pointers from temporary memory to newly > + // installed PEI_CORE in permanent memory. > + // > + ConvertPpiPointersFv (PrivateData, (UINTN) OrgImageBase, (UINTN) > MigratedImageBase, PeiCoreModuleSize); > + } > +} > + > -- > 2.25.1.windows.1 >=20 >=20 >=20