From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by mx.groups.io with SMTP id smtpd.web10.324.1686104975179226159 for ; Tue, 06 Jun 2023 19:29:35 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="unable to parse pub key" header.i=@intel.com header.s=intel header.b=HeoT+R2p; spf=pass (domain: intel.com, ip: 134.134.136.20, mailfrom: hongbin1.zhang@intel.com) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1686104975; x=1717640975; h=from:to:cc:subject:date:message-id:references: in-reply-to:content-transfer-encoding:mime-version; bh=UcxLHBMvgGfLkL0T+zGuI97byCIsPiZku8CnqYOG8qU=; b=HeoT+R2ppVugDafDdFunnOfQnwNPvG3+Ss5J2Si1Srt5dHxmzKTKZqZG p+SKPfY89wze1eZwKhop0vE4hmrvueGtTB2e1xg9NLxCL7wIKeOMO10fJ 6eOKVcbpIIQgI2LY/Bvm04XCe2zda/dv6yqqxYRX4m5ridWqP9PGn/z0v 11z+ui7wh4/1s++X0E1E6lrj5ePHjSAgcPf6pLafcAzngUKS0lIxHOsbR SZk6DhU0G6s2kKR9t2WCR967LW/P1uxhAS/v86fmNxydrlQ16J/mrWW5M 0YuMXzVM7GP+m00t9d+9VQFx1DMcMF08XyemH+SKhB4074s3hc13JfW1L A==; X-IronPort-AV: E=McAfee;i="6600,9927,10733"; a="346464621" X-IronPort-AV: E=Sophos;i="6.00,222,1681196400"; d="scan'208";a="346464621" Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Jun 2023 19:29:32 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10733"; a="833473199" X-IronPort-AV: E=Sophos;i="6.00,222,1681196400"; d="scan'208";a="833473199" Received: from fmsmsx602.amr.corp.intel.com ([10.18.126.82]) by orsmga004.jf.intel.com with ESMTP; 06 Jun 2023 19:29:29 -0700 Received: from fmsmsx610.amr.corp.intel.com (10.18.126.90) by fmsmsx602.amr.corp.intel.com (10.18.126.82) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.23; Tue, 6 Jun 2023 19:29:27 -0700 Received: from fmsedg602.ED.cps.intel.com (10.1.192.136) by fmsmsx610.amr.corp.intel.com (10.18.126.90) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.23 via Frontend Transport; Tue, 6 Jun 2023 19:29:27 -0700 Received: from NAM12-DM6-obe.outbound.protection.outlook.com (104.47.59.177) by edgegateway.intel.com (192.55.55.71) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.23; Tue, 6 Jun 2023 19:29:26 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=Dk/yBuirCBd642aFQosRVTA0tGLZ2efDBbuiU7NdxP/4KFKg13hsq8Vh3HAJPnjA2IR5Rmetx8yIDllRaC5klhrQz7P2HnCwPr0WppSbQMr4eP1W5nnYfvhlRLxrfGDvbiMSO/x9yqbVCCqq848DSUann3burzWWCLHsN12Fxarn3f2GWdVnkY6Lu5xB1uph1pZyfBniwk9oLA6Zg0DTkKKA6zQkd6JVPq0mClQEUwLZQWEqa5HNLDK23Eca0RlD3U30u/6t4/RlULn9BiT1Xlkb5gJWBO1jzBukqur60cnM4z58v7b6rf5j/rPj/cyA4tRXSY6f9jl7xsTLVg5iIg== 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-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=hekqPDu6SGbSMUR4njrkD59qYVxAWwigVVD0326dsI0=; b=FngwAEhFw2ghsFqeU5fT9W/APM84/E5M1TshqV1yqTmGeR1v4A0z8Gf4eYnQKu+1S5Mwnl8geQ3zFe7WjxalSYI2OjNxZEFaQRwv+CqWsKKF+CAdDZD4CGk2NiEvK/ASEL0m4VGMkxYBkRpGSBAgAtqYwfJx7n6q0ZGczrGWMCo+PMlyUKhgmzxTveNVrjskog4KM4e6QQ0VIfH/095Z1UfhvhTXRlWxDyb4rXcT95bbfbKb853KW1UPFKLIlFSdzA3NU31qL/UZXMg3J9zPnUFgYHyVVj6vSyNn8FiKNSohKlMdeEA4NHuWO6RlG7tB8F9bpbPl0E6YzdRdcOVj5g== 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 Received: from PH7PR11MB5820.namprd11.prod.outlook.com (2603:10b6:510:133::17) by DM4PR11MB6043.namprd11.prod.outlook.com (2603:10b6:8:62::8) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6455.32; Wed, 7 Jun 2023 02:29:18 +0000 Received: from PH7PR11MB5820.namprd11.prod.outlook.com ([fe80::84b2:b711:8939:b703]) by PH7PR11MB5820.namprd11.prod.outlook.com ([fe80::84b2:b711:8939:b703%7]) with mapi id 15.20.6411.027; Wed, 7 Jun 2023 02:29:18 +0000 From: "Zhang, Hongbin1" To: "Ni, Ray" , "devel@edk2.groups.io" , "Yao, Jiewen" CC: "Zeng, Star" , "Wu, Jiaxin" , Sami Mujawar , Ard Biesheuvel , Supreeth Venkatesh , "Bu, Daocheng" , "Chen, Bo" Subject: Re: [PATCH v1] StandaloneMmPkg: Add StandaloneMmIplPei driver. Thread-Topic: [PATCH v1] StandaloneMmPkg: Add StandaloneMmIplPei driver. Thread-Index: AQHZjG1FnvMlMw/W/EiIsybyYcM8V69+r8kAgAABHRA= Date: Wed, 7 Jun 2023 02:29:17 +0000 Message-ID: References: <20230522052105.1135-1-hongbin1.zhang@intel.com> In-Reply-To: Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=intel.com; x-ms-publictraffictype: Email x-ms-traffictypediagnostic: PH7PR11MB5820:EE_|DM4PR11MB6043:EE_ x-ms-office365-filtering-correlation-id: e33c4b7e-fddf-4234-4823-08db66fefe37 x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: fb7X6DBC9Gc3zzoMDpjju2LrR/S7UxqNEFqPkHoIG8vP6fNbmmwisrwsyWYLY06gDqHpNtO4qrYbJ8vKJh28zxVM1Ap4DHWfalcGQ3m9WmC4t3fwgJ+KgiPbFKxaTE/sF7Ygcm/o2ndv6UyKfV7uwj6vWTSXPmdNC42Cp9/hpTmsUJmj3NA27lMlhhWmj7HjAG2QpsGzPEOA1PRUS5lmt/8hj6tdTUZ14XEaQzwdSPd5wPfnj8k8naCAA2g+wxZPaqzNAz5ch/QM5ecdl6Ge5pXoKac+sko1iQJs37/2B8JsctQJirhiSTmyDxnzD+lZRXImh/Tv7mmkgaVL/Kif3hgO5u0HujFz8WPxZ/ZYAiVP1EQGHTuAQ2jfK9zPFySIa+Q+oLPrb7b9031H9sHmD86s3rzzhP3bDDMRddC2TQBrPVooJJPtq1jYj1IIdPe6cHwJetQvIUaNLqyI6kPHV4AMZnilJJqqN7sKENoB1T5CpJxT9VTzTD9ti+CUfxIMgHGG13WWHNuP2BWCALEL3cd33HDy4inPom5Is7iPY3unw5FDQIrkSQUM7LBP6fcVwmIgL1IKq68bLgARw7m6ZA5SH+eiAchigft4OQg7cNH0+DMvLDnje6xIm/vnwpRPf94iPUkRFsttqXgmw/8qTQ== x-forefront-antispam-report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:PH7PR11MB5820.namprd11.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230028)(6029001)(366004)(346002)(136003)(376002)(39860400002)(396003)(451199021)(8676002)(8936002)(19627235002)(7696005)(478600001)(54906003)(110136005)(107886003)(966005)(55016003)(41300700001)(52536014)(6506007)(5660300002)(316002)(26005)(66446008)(4326008)(66476007)(66556008)(76116006)(71200400001)(64756008)(6636002)(66946007)(9686003)(53546011)(186003)(83380400001)(2906002)(66574015)(30864003)(122000001)(38100700002)(82960400001)(33656002)(86362001)(38070700005)(579004)(559001);DIR:OUT;SFP:1102; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?us-ascii?Q?QTQzI3I3j05Kxx1mQf/ciln9dscC7W149ssARH0RQXnVD7cLlpbZ40rJqhxq?= =?us-ascii?Q?H7X14MaZ+8cptt5zY0Hb3Bqn898pL2CutHT71C0KPHtmQ6/CBmVet0LjbBIb?= =?us-ascii?Q?VhDWegOo2LUfuuASjfU4QAivc9cMsOXWNxuo6jPrpaWRSswVDs3MESp2LfEh?= =?us-ascii?Q?4UvbE4cte1Gmzq8DRLtEVJg5iI2ueAsiGQrsnjAKMXaDFQJpklT5/dDkchmk?= =?us-ascii?Q?atwwEktrdP3itbwxFks4iaopmJoP9DMUXOlntx248L8Q+5g9Jl8aqIcBXL/q?= =?us-ascii?Q?i7JuBONVc+Af20xCIg9mFLWOW3IpJsJDCH7ZRg/oJsk/6MDD4V+9QtP88T3T?= =?us-ascii?Q?FJkO59pTsvO+/0OL+xmMx9f6qAjpGArk8PAjuhxukEqg/uxYHpor/du0G1Dz?= =?us-ascii?Q?ESXuqZiI/JphR7wls8tPgIz6ksCsITyDf/B3Thm3JFjuyNF4NTwRYkim2u8f?= =?us-ascii?Q?hKOv8lXyaP1IAC+FtRgkcgU6Gdvby3wJMhYjzpLBPlI7U3Xm+hyCCYMLmK0b?= =?us-ascii?Q?Ksd6/fre0GQEJgK6sHL9uYrbPS2axKF1vIGCLDA2e7hiIo1UN70uSV/mqBq9?= =?us-ascii?Q?/DSSWT+x91lqq3BR8N9efp2Y7rcgIDRdZgxiOlWPfr41QHaCxNGe9dbnakhd?= =?us-ascii?Q?hgwlzFfhfh7ukcPYfZXcNIUgQ31HT57HH6LLevrdDI2Lu1MH5pu6aYtZTgnT?= =?us-ascii?Q?DGLljCGJ8ma9wB4Br5Yd9jvx3jdYYFjgqF8eQj8ybVCbxcoCGmpi+xngu8BR?= =?us-ascii?Q?tGF56M08T76a5c+2bEeMHBmUalC2iclb6bXB9LpMvds3PQM2NLa0m4Nt0gz4?= =?us-ascii?Q?TQt22s509FpV+X3USVAUKdy1P4yJLPedq+WRYuZ3YZrjVwm5rD1WlioT1+8U?= =?us-ascii?Q?bH0M64mMIRnJlL+geXrOVI4npo8b89fRGp1JOBZIJVHFBws3u/ScPGROJPBM?= =?us-ascii?Q?Q03KV6oG5Ah3mVBa0vnqwMCcrwMoKYKS+GXNfom9GmlI0FqxQpgos5A7hlg+?= =?us-ascii?Q?+eOVgFJMfSeVAFwjWWlcv2O0PwYT2VNl5S812WZCLLgrrQly/bBCSPmxVNod?= =?us-ascii?Q?9A5r/Nd6kBnFi9/WJN7PplM/HZeZihg6pCBUUx3s0mSnEKP0zwn9MsjYu3KR?= =?us-ascii?Q?I6xWEFwCMc8BYnSKiIhHY+IqA24p0RhUBx4d3Otb87/uBlrOw9eRP9lQrB7A?= =?us-ascii?Q?qBzRDnJamrW5zRe/zpF8/cdO/JnQXKlFdi2Qjkt6QXJA4LMOuvUmeGtsdJnk?= =?us-ascii?Q?vEN62NjAl9UHbDTOfuRh8KXMTL0EBwL/2lsaLjC0Gsn0ajwc7tPhDVL9LuLD?= =?us-ascii?Q?Xl1fRXdNZ1Qd9ULeyG0qBYmivzV/2VdrndKdwWUi9WLLCytH4dU+XXWPKkz6?= =?us-ascii?Q?mBJdKSfdZfa5MZL9VON5ckzyHRQRCW0hfTWlT0krs7NtLHd4zmV5Fg0qUqMV?= =?us-ascii?Q?rQY93/oHTVr2vmPc/cHd373pt2y73iU2aFhyU1nfyLOmvjCqBsxXwZ1SEItw?= =?us-ascii?Q?WvnH2JXxKb1+Gz9XBdtIKwC33XH1o1UH1POYTugnU6PDMQPYJJTfPQRGKGc1?= =?us-ascii?Q?dIhwV05luEkZ9/Ihj0l+cgHM021ImfzEcwWM9nQi?= MIME-Version: 1.0 X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: PH7PR11MB5820.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: e33c4b7e-fddf-4234-4823-08db66fefe37 X-MS-Exchange-CrossTenant-originalarrivaltime: 07 Jun 2023 02:29:17.5680 (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: U65K0neJ5wTvBhCauvX+nZMFwoPJLYe2Lk2DvZVBYdfkOCkY/sy2rdwxwtCfP9VEQttyyTK8F8BHrgfl/MC8bMuuIcEmowWQR3LeRCT42u0= X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM4PR11MB6043 Return-Path: hongbin1.zhang@intel.com X-OriginatorOrg: intel.com Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Thanks Ray. Replied your code comments with [Hongbin]. And I will split to several patches, it will be better for reviewing. -----Original Message----- From: Ni, Ray =20 Sent: Wednesday, June 7, 2023 10:04 AM To: Zhang, Hongbin1 ; devel@edk2.groups.io; Yao, = Jiewen Cc: Zeng, Star ; Wu, Jiaxin ; Sam= i Mujawar ; Ard Biesheuvel ; Supreeth Venkatesh Subject: RE: [PATCH v1] StandaloneMmPkg: Add StandaloneMmIplPei driver. Hongbin, The patch is so big. Can you please split the patch to small patches? For e= xample: 1st patch only implements the Ipl entrypoint to find the correct SMRAM rang= e and dump it 2nd patch loads SMM CORE without mode switch if sizeof (UINTN) matches SMM = core module type. 3rd patch loads SMM CORE with mode switch if sizeof (UINTN) =3D=3D 4 but SM= M core module type is 64bit. 4th patch Deadloop() when sizeof (UINTN) =3D=3D 8 but SMM core module type = is 32bit. 5th patch register ReadyToBoot callback. But is it too late from security p= erspective? Why not lock after SMM core exit? @Yao, Jiewen Back to the code content, 3 comments: 1. Have you tested the flow when LoadImageAtFixedAddress is enabled? If no,= I prefer you do not add the logic at all in the first version. We can enab= le that later. -- Yes, currently PcdLoadModuleAtFixAddressEnable was not used and ver= ified, I will add later [Hongbin]. 2. "EFIAPI" for GetSectionFromAnyFvByFileType should be removed. And the fu= nction prototype could be refined as below: EFI_STATUS LocateMmFvAndCore OUT EFI_PHYSICAL_ADDRESS *MmFvBaseAddress, OUT VOID **MmCoreImageAddress Please avoid directly modifying global variables inside this function. -- Ok, will change that [Hongbin]. 3. Can the StandaloneMmCore in open source be directly used with this IPL?= =20 -- I will think about this later [Hongbin]. Thanks, Ray > -----Original Message----- > From: Zhang, Hongbin1 > Sent: Monday, May 22, 2023 1:21 PM > To: devel@edk2.groups.io > Cc: Zhang, Hongbin1 ; Yao, Jiewen > ; Ni, Ray ; Zeng, Star > ; Wu, Jiaxin ; Sami Mujawar > ; Ard Biesheuvel ; > Supreeth Venkatesh > Subject: [PATCH v1] StandaloneMmPkg: Add StandaloneMmIplPei driver. >=20 > Add StandaloneMmIplPei IA32/X64 driver at PEI stage. > FSP will use this driver to load Standalone MM code > to dispatch other Standalone MM drivers. >=20 > Signed-off-by: Hongbin1 Zhang > Cc: Jiewen Yao > Cc: Ray Ni > Cc: Star Zeng > Cc: Jiaxin Wu > Cc: Sami Mujawar > Cc: Ard Biesheuvel > Cc: Supreeth Venkatesh > --- > StandaloneMmPkg/Drivers/StandaloneMmIplPei/Ia32/LoadSmmCore.c | 456 > ++++++++++++ > StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c | 787 > ++++++++++++++++++++ > StandaloneMmPkg/Drivers/StandaloneMmIplPei/X64/LoadSmmCore.c | 32 = + > StandaloneMmPkg/Drivers/StandaloneMmIplPei/Ia32/Thunk32To64.nasm | 148 > ++++ > StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h | 66 > ++ > StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf | 75 > ++ > StandaloneMmPkg/StandaloneMmPkg.ci.yaml | 4 = +- > StandaloneMmPkg/StandaloneMmPkg.dsc | 15 = +- > UefiPayloadPkg/UniversalPayloadBuild.sh | 34 = +- > edksetup.sh | 294 = ++++---- > 10 files changed, 1744 insertions(+), 167 deletions(-) >=20 > diff --git > a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/Ia32/LoadSmmCore.c > b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/Ia32/LoadSmmCore.c > new file mode 100644 > index 0000000000..d6174d73a3 > --- /dev/null > +++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/Ia32/LoadSmmCore.c > @@ -0,0 +1,456 @@ > +/** @file > + SMM IPL that load the SMM Core into SMRAM > + > + Copyright (c) 2023, Intel Corporation. All rights reserved.
> + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#pragma pack(1) > + > +// > +// Page-Map Level-4 Offset (PML4) and > +// Page-Directory-Pointer Offset (PDPE) entries 4K & 2MB > +// > + > +typedef union { > + struct { > + UINT64 Present : 1; // 0 =3D Not present in memory= , 1 =3D Present in > memory > + UINT64 ReadWrite : 1; // 0 =3D Read-Only, 1=3D Read/= Write > + UINT64 UserSupervisor : 1; // 0 =3D Supervisor, 1=3DUser > + UINT64 WriteThrough : 1; // 0 =3D Write-Back caching, 1= =3DWrite-Through > caching > + UINT64 CacheDisabled : 1; // 0 =3D Cached, 1=3DNon-Cache= d > + UINT64 Accessed : 1; // 0 =3D Not accessed, 1 =3D A= ccessed (set by CPU) > + UINT64 Reserved : 1; // Reserved > + UINT64 MustBeZero : 2; // Must Be Zero > + UINT64 Available : 3; // Available for use by system= software > + UINT64 PageTableBaseAddress : 40; // Page Table Base Address > + UINT64 AvailableHigh : 11; // Available for use by system= software > + UINT64 Nx : 1; // No Execute bit > + } Bits; > + UINT64 Uint64; > +} PAGE_MAP_AND_DIRECTORY_POINTER; > + > +// > +// Page Table Entry 2MB > +// > +typedef union { > + struct { > + UINT64 Present : 1; // 0 =3D Not present in memory= , 1 =3D Present in > memory > + UINT64 ReadWrite : 1; // 0 =3D Read-Only, 1=3D Read/= Write > + UINT64 UserSupervisor : 1; // 0 =3D Supervisor, 1=3DUser > + UINT64 WriteThrough : 1; // 0 =3D Write-Back caching, 1= =3DWrite-Through > caching > + UINT64 CacheDisabled : 1; // 0 =3D Cached, 1=3DNon-Cache= d > + UINT64 Accessed : 1; // 0 =3D Not accessed, 1 =3D A= ccessed (set by CPU) > + UINT64 Dirty : 1; // 0 =3D Not Dirty, 1 =3D writ= ten by processor on > access to page > + UINT64 MustBe1 : 1; // Must be 1 > + UINT64 Global : 1; // 0 =3D Not global page, 1 = =3D global page TLB not > cleared on CR3 write > + UINT64 Available : 3; // Available for use by system= software > + UINT64 Pat : 1; // > + UINT64 MustBeZero : 8; // Must be zero > + UINT64 PageTableBaseAddress : 31; // Page Table Base Address > + UINT64 AvailableHigh : 11; // Available for use by system= software > + UINT64 Nx : 1; // 0 =3D Execute Code, 1 =3D N= o Code Execution > + } Bits; > + UINT64 Uint64; > +} PAGE_TABLE_ENTRY; > + > +// > +// Page Table Entry 1GB > +// > +typedef union { > + struct { > + UINT64 Present : 1; // 0 =3D Not present in memory= , 1 =3D Present in > memory > + UINT64 ReadWrite : 1; // 0 =3D Read-Only, 1=3D Read/= Write > + UINT64 UserSupervisor : 1; // 0 =3D Supervisor, 1=3DUser > + UINT64 WriteThrough : 1; // 0 =3D Write-Back caching, 1= =3DWrite-Through > caching > + UINT64 CacheDisabled : 1; // 0 =3D Cached, 1=3DNon-Cache= d > + UINT64 Accessed : 1; // 0 =3D Not accessed, 1 =3D A= ccessed (set by CPU) > + UINT64 Dirty : 1; // 0 =3D Not Dirty, 1 =3D writ= ten by processor on > access to page > + UINT64 MustBe1 : 1; // Must be 1 > + UINT64 Global : 1; // 0 =3D Not global page, 1 = =3D global page TLB not > cleared on CR3 write > + UINT64 Available : 3; // Available for use by system= software > + UINT64 Pat : 1; // > + UINT64 MustBeZero : 17; // Must be zero; > + UINT64 PageTableBaseAddress : 22; // Page Table Base Address > + UINT64 AvailableHigh : 11; // Available for use by system= software > + UINT64 Nx : 1; // 0 =3D Execute Code, 1 =3D N= o Code Execution > + } Bits; > + UINT64 Uint64; > +} PAGE_TABLE_1G_ENTRY; > + > +#pragma pack() > + > +// > +// Global Descriptor Table (GDT) > +// > +GLOBAL_REMOVE_IF_UNREFERENCED IA32_SEGMENT_DESCRIPTOR > mGdtEntries[] =3D { > + /* selector { Global Segment Descriptor }= */ > + /* 0x00 */ { > + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } > + }, = // null descriptor > + /* 0x08 */ { > + { 0xffff, 0, 0, 0x3, 1, 0, 1, 0xf, 0, 0, 1, 1, 0 } > + }, = // linear data segment descriptor > + /* 0x10 */ { > + { 0xffff, 0, 0, 0xf, 1, 0, 1, 0xf, 0, 0, 1, 1, 0 } > + }, = // linear code segment descriptor > + /* 0x18 */ { > + { 0xffff, 0, 0, 0x3, 1, 0, 1, 0xf, 0, 0, 1, 1, 0 } > + }, = // system data segment descriptor > + /* 0x20 */ { > + { 0xffff, 0, 0, 0xb, 1, 0, 1, 0xf, 0, 0, 1, 1, 0 } > + }, = // system code segment descriptor > + /* 0x28 */ { > + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } > + }, = // spare segment descriptor > + /* 0x30 */ { > + { 0xffff, 0, 0, 0x3, 1, 0, 1, 0xf, 0, 0, 1, 1, 0 } > + }, = // system data segment descriptor > + /* 0x38 */ { > + { 0xffff, 0, 0, 0xb, 1, 0, 1, 0xf, 0, 1, 0, 1, 0 } > + }, = // system code segment descriptor > + /* 0x40 */ { > + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } > + }, = // spare segment descriptor > +}; > + > +// > +// IA32 Gdt register > +// > +GLOBAL_REMOVE_IF_UNREFERENCED CONST IA32_DESCRIPTOR mGdt =3D { > + sizeof (mGdtEntries) - 1, > + (UINTN)mGdtEntries > +}; > + > +/** > + Calculate the total size of page table. > + > + @return The size of page table. > + > +**/ > +UINTN > +CalculatePageTableSize ( > + VOID > + ) > +{ > + UINT32 RegEax; > + UINT32 RegEdx; > + UINTN TotalPagesNum; > + UINT8 PhysicalAddressBits; > + VOID *Hob; > + UINT32 NumberOfPml4EntriesNeeded; > + UINT32 NumberOfPdpEntriesNeeded; > + BOOLEAN Page1GSupport; > + > + Page1GSupport =3D FALSE; > + if (PcdGetBool (PcdUse1GPageTable)) { > + AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL); > + if (RegEax >=3D 0x80000001) { > + AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx); > + if ((RegEdx & BIT26) !=3D 0) { > + Page1GSupport =3D TRUE; > + } > + } > + } > + > + // > + // Get physical address bits supported. > + // > + Hob =3D GetFirstHob (EFI_HOB_TYPE_CPU); > + if (Hob !=3D NULL) { > + PhysicalAddressBits =3D ((EFI_HOB_CPU *)Hob)->SizeOfMemorySpace; > + } else { > + AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL); > + if (RegEax >=3D 0x80000008) { > + AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL); > + PhysicalAddressBits =3D (UINT8)RegEax; > + } else { > + PhysicalAddressBits =3D 36; > + } > + } > + > + // > + // IA-32e paging translates 48-bit linear addresses to 52-bit physical= addresses. > + // > + ASSERT (PhysicalAddressBits <=3D 52); > + if (PhysicalAddressBits > 48) { > + PhysicalAddressBits =3D 48; > + } > + > + // > + // Calculate the table entries needed. > + // > + if (PhysicalAddressBits <=3D 39 ) { > + NumberOfPml4EntriesNeeded =3D 1; > + NumberOfPdpEntriesNeeded =3D (UINT32)LShiftU64 (1, (PhysicalAddress= Bits - > 30)); > + } else { > + NumberOfPml4EntriesNeeded =3D (UINT32)LShiftU64 (1, (PhysicalAddress= Bits - > 39)); > + NumberOfPdpEntriesNeeded =3D 512; > + } > + > + if (!Page1GSupport) { > + TotalPagesNum =3D (NumberOfPdpEntriesNeeded + 1) * > NumberOfPml4EntriesNeeded + 1; > + } else { > + TotalPagesNum =3D NumberOfPml4EntriesNeeded + 1; > + } > + > + return EFI_PAGES_TO_SIZE (TotalPagesNum); > +} > + > +/** > + Allocates and fills in the Page Directory and Page Table Entries to > + establish a 1:1 Virtual to Physical mapping. > + > + @param[in] PageTablesAddress The base address of page table. > + > +**/ > +VOID > +CreateIdentityMappingPageTables ( > + IN EFI_PHYSICAL_ADDRESS PageTablesAddress > + ) > +{ > + UINT32 RegEax; > + UINT32 RegEdx; > + UINT8 PhysicalAddressBits; > + EFI_PHYSICAL_ADDRESS PageAddress; > + UINTN IndexOfPml4Entries; > + UINTN IndexOfPdpEntries; > + UINTN IndexOfPageDirectoryEntries; > + UINT32 NumberOfPml4EntriesNeeded; > + UINT32 NumberOfPdpEntriesNeeded; > + PAGE_MAP_AND_DIRECTORY_POINTER *PageMapLevel4Entry; > + PAGE_MAP_AND_DIRECTORY_POINTER *PageMap; > + PAGE_MAP_AND_DIRECTORY_POINTER *PageDirectoryPointerEntry; > + PAGE_TABLE_ENTRY *PageDirectoryEntry; > + UINTN BigPageAddress; > + VOID *Hob; > + BOOLEAN Page1GSupport; > + PAGE_TABLE_1G_ENTRY *PageDirectory1GEntry; > + > + Page1GSupport =3D FALSE; > + AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL); > + if (RegEax >=3D 0x80000001) { > + AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx); > + if ((RegEdx & BIT26) !=3D 0) { > + Page1GSupport =3D TRUE; > + } > + } > + > + // > + // Get physical address bits supported. > + // > + Hob =3D GetFirstHob (EFI_HOB_TYPE_CPU); > + if (Hob !=3D NULL) { > + PhysicalAddressBits =3D ((EFI_HOB_CPU *)Hob)->SizeOfMemorySpace; > + } else { > + AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL); > + if (RegEax >=3D 0x80000008) { > + AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL); > + PhysicalAddressBits =3D (UINT8)RegEax; > + } else { > + PhysicalAddressBits =3D 36; > + } > + } > + > + // > + // IA-32e paging translates 48-bit linear addresses to 52-bit physical= addresses. > + // > + ASSERT (PhysicalAddressBits <=3D 52); > + if (PhysicalAddressBits > 48) { > + PhysicalAddressBits =3D 48; > + } > + > + // > + // Calculate the table entries needed. > + // > + if (PhysicalAddressBits <=3D 39 ) { > + NumberOfPml4EntriesNeeded =3D 1; > + NumberOfPdpEntriesNeeded =3D (UINT32)LShiftU64 (1, (PhysicalAddress= Bits - > 30)); > + } else { > + NumberOfPml4EntriesNeeded =3D (UINT32)LShiftU64 (1, (PhysicalAddress= Bits - > 39)); > + NumberOfPdpEntriesNeeded =3D 512; > + } > + > + // > + // Pre-allocate big pages to avoid later allocations. > + // > + BigPageAddress =3D (UINTN)PageTablesAddress; > + > + // > + // By architecture only one PageMapLevel4 exists - so lets allocate st= orage for > it. > + // > + PageMap =3D (VOID *)BigPageAddress; > + BigPageAddress +=3D SIZE_4KB; > + > + PageMapLevel4Entry =3D PageMap; > + PageAddress =3D 0; > + for (IndexOfPml4Entries =3D 0; IndexOfPml4Entries < > NumberOfPml4EntriesNeeded; IndexOfPml4Entries++, PageMapLevel4Entry++) { > + // > + // Each PML4 entry points to a page of Page Directory Pointer entire= s. > + // So lets allocate space for them and fill them in in the IndexOfPd= pEntries > loop. > + // > + PageDirectoryPointerEntry =3D (VOID *)BigPageAddress; > + BigPageAddress +=3D SIZE_4KB; > + > + // > + // Make a PML4 Entry > + // > + PageMapLevel4Entry->Uint64 =3D > (UINT64)(UINTN)PageDirectoryPointerEntry; > + PageMapLevel4Entry->Bits.ReadWrite =3D 1; > + PageMapLevel4Entry->Bits.Present =3D 1; > + > + if (Page1GSupport) { > + PageDirectory1GEntry =3D (VOID *)PageDirectoryPointerEntry; > + > + for (IndexOfPageDirectoryEntries =3D 0; IndexOfPageDirectoryEntrie= s < 512; > IndexOfPageDirectoryEntries++, PageDirectory1GEntry++, PageAddress +=3D > SIZE_1GB) { > + // > + // Fill in the Page Directory entries > + // > + PageDirectory1GEntry->Uint64 =3D (UINT64)PageAddress; > + PageDirectory1GEntry->Bits.ReadWrite =3D 1; > + PageDirectory1GEntry->Bits.Present =3D 1; > + PageDirectory1GEntry->Bits.MustBe1 =3D 1; > + } > + } else { > + for (IndexOfPdpEntries =3D 0; IndexOfPdpEntries < > NumberOfPdpEntriesNeeded; IndexOfPdpEntries++, > PageDirectoryPointerEntry++) { > + // > + // Each Directory Pointer entries points to a page of Page Direc= tory entires. > + // So allocate space for them and fill them in in the > IndexOfPageDirectoryEntries loop. > + // > + PageDirectoryEntry =3D (VOID *)BigPageAddress; > + BigPageAddress +=3D SIZE_4KB; > + > + // > + // Fill in a Page Directory Pointer Entries > + // > + PageDirectoryPointerEntry->Uint64 =3D > (UINT64)(UINTN)PageDirectoryEntry; > + PageDirectoryPointerEntry->Bits.ReadWrite =3D 1; > + PageDirectoryPointerEntry->Bits.Present =3D 1; > + > + for (IndexOfPageDirectoryEntries =3D 0; IndexOfPageDirectoryEntr= ies < 512; > IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PageAddress +=3D > SIZE_2MB) { > + // > + // Fill in the Page Directory entries > + // > + PageDirectoryEntry->Uint64 =3D (UINT64)PageAddress; > + PageDirectoryEntry->Bits.ReadWrite =3D 1; > + PageDirectoryEntry->Bits.Present =3D 1; > + PageDirectoryEntry->Bits.MustBe1 =3D 1; > + } > + } > + > + for ( ; IndexOfPdpEntries < 512; IndexOfPdpEntries++, > PageDirectoryPointerEntry++) { > + ZeroMem ( > + PageDirectoryPointerEntry, > + sizeof (PAGE_MAP_AND_DIRECTORY_POINTER) > + ); > + } > + } > + } > + > + // > + // For the PML4 entries we are not using fill in a null entry. > + // > + for ( ; IndexOfPml4Entries < 512; IndexOfPml4Entries++, > PageMapLevel4Entry++) { > + ZeroMem ( > + PageMapLevel4Entry, > + sizeof (PAGE_MAP_AND_DIRECTORY_POINTER) > + ); > + } > +} > + > +/** > + If in 32 bit protection mode, and coalesce image is of X64, switch to = long mode. > + > + @param Entry Entry of Standalone MM Foundation. > + @param Context1 A pointer to the context to pass int= o the > EntryPoint > + function. > + @param Context2 A pointer to the context to pass int= o the > EntryPoint > + function. > + @retval EFI_SUCCESS Successfully switched to long mode a= nd execute > coalesce. > + @retval Others Failed to execute coalesce in long m= ode. > + > +**/ > +EFI_STATUS > +ModeSwitch ( > + IN EFI_PHYSICAL_ADDRESS Entry, > + IN VOID *Context1, > + IN VOID *Context2 > + ) > +{ > + UINTN PageTableAddress; > + UINTN PageTableSize; > + EFI_STATUS Status; > + IA32_DESCRIPTOR Gdtr; > + > + DEBUG ((DEBUG_INFO, "ModeSwitch\n")); > + > + // > + // Save IA32 GDTR > + // > + AsmReadGdtr (&Gdtr); > + > + // > + // Set X64 GDTR > + // > + AsmWriteGdtr (&mGdt); > + > + PageTableAddress =3D AsmReadCr3 () & 0xFFFFF000; > + > + // > + // If page table was created, no need to create > + // > + if (PageTableAddress =3D=3D 0) { > + PageTableSize =3D CalculatePageTableSize (); > + > + PageTableAddress =3D (UINTN)AllocatePages (EFI_SIZE_TO_PAGES > (PageTableSize)); > + ASSERT (PageTableAddress !=3D 0); > + > + CreateIdentityMappingPageTables (PageTableAddress); > + > + AsmWriteCr3 ((UINTN)PageTableAddress); > + } > + > + DEBUG ((DEBUG_INFO, "AsmExecute64BitCode ...\n")); > + > + Status =3D AsmExecute64BitCode (Entry, (UINT64)(UINTN)Context1, > (UINT64)(UINTN)Context2, NULL); > + if (Status !=3D 0) { > + Status =3D Status | MAX_BIT; > + } > + > + DEBUG ((DEBUG_INFO, "AsmExecute64BitCode - %r\n", Status)); > + > + // > + // Restore IA32 GDTR > + // > + AsmWriteGdtr (&Gdtr); > + > + return Status; > +} > + > +/** > + Load SMM core to dispatch other Standalone MM drivers. > + > + @param Entry Entry of Standalone MM Foundation. > + @param Context1 A pointer to the context to pass int= o the > EntryPoint > + function. > + @retval EFI_SUCCESS Successfully loaded SMM core. > + @retval Others Failed to load SMM core. > +**/ > +EFI_STATUS > +LoadSmmCore ( > + IN EFI_PHYSICAL_ADDRESS Entry, > + IN VOID *Context1 > + ) > +{ > + return ModeSwitch (Entry, Context1, NULL); > +} > diff --git > a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c > b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c > new file mode 100644 > index 0000000000..7fa42c32fb > --- /dev/null > +++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c > @@ -0,0 +1,787 @@ > +/** @file > + SMM IPL that load the SMM Core into SMRAM at PEI stage > + > + Copyright (c) 2023, Intel Corporation. All rights reserved.
> + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +// > +// MM Core Private Data structure that contains the data shared between > +// the SMM IPL and the Standalone MM Core. > +// > +MM_CORE_PRIVATE_DATA mMmCorePrivateData =3D { > + MM_CORE_PRIVATE_DATA_SIGNATURE, // Signature > + 0, // MmramRangeCount > + 0, // MmramRanges > + 0, // MmEntryPoint > + FALSE, // MmEntryPointRegistered > + FALSE, // InMm > + 0, // Mmst > + 0, // CommunicationBuffer > + 0, // BufferSize > + EFI_SUCCESS, // ReturnStatus > + 0, // MmCoreImageBase > + 0, // MmCoreImageSize > + 0, // MmCoreEntryPoint > + 0, // StandaloneBfvAddress > +}; > + > +// > +// Global pointer used to access mMmCorePrivateData from outside and ins= ide > SMM > +// > +MM_CORE_PRIVATE_DATA *gMmCorePrivate; > + > +// > +// SMM IPL global variables > +// > +PEI_SMM_ACCESS_PPI *mSmmAccess; > +EFI_SMRAM_DESCRIPTOR *mCurrentSmramRange; > +BOOLEAN mSmmLocked =3D FALSE; > +EFI_PHYSICAL_ADDRESS mSmramCacheBase; > +UINT64 mSmramCacheSize; > + > +EFI_PEI_NOTIFY_DESCRIPTOR mReadyToBootNotifyList =3D { > + (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | > EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), > + &gEfiEventReadyToBootGuid, > + ReadyToBootEvent > +}; > + > +/** > + This is the callback function on ready to boot. > + > + Close and Lock smram range on ready to boot stage. > + > + @param PeiServices General purpose services available to ev= ery PEIM. > + @param NotifyDescriptor The notification structure this PEIM reg= istered on > install. > + @param Ppi Pointer to the PPI data associated with = this function. > + @retval EFI_SUCCESS Close and lock smram ranges successfully= . > + @retval Other Close and lock smram ranges failed. > +**/ > +EFI_STATUS > +EFIAPI > +ReadyToBootEvent ( > + IN EFI_PEI_SERVICES **PeiServices, > + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, > + IN VOID *Ppi > + ) > +{ > + EFI_STATUS Status; > + > + // > + // Close all SMRAM ranges > + // > + Status =3D mSmmAccess->Close ((EFI_PEI_SERVICES **)PeiServices, > mSmmAccess, 0); > + ASSERT_EFI_ERROR (Status); > + > + // > + // Lock all SMRAM ranges > + // > + Status =3D mSmmAccess->Lock ((EFI_PEI_SERVICES **)PeiServices, > mSmmAccess, 0); > + ASSERT_EFI_ERROR (Status); > + > + return Status; > +} > + > +/** > + Find the maximum SMRAM cache range that covers the range specified by > SmramRange. > + > + This function searches and joins all adjacent ranges of SmramRange int= o a > range to be cached. > + > + @param SmramRange The SMRAM range to search from. > + @param SmramCacheBase The returned cache range base. > + @param SmramCacheSize The returned cache range size. > +**/ > +VOID > +GetSmramCacheRange ( > + IN EFI_SMRAM_DESCRIPTOR *SmramRange, > + OUT EFI_PHYSICAL_ADDRESS *SmramCacheBase, > + OUT UINT64 *SmramCacheSize > + ) > +{ > + UINTN Index; > + EFI_PHYSICAL_ADDRESS RangeCpuStart; > + UINT64 RangePhysicalSize; > + BOOLEAN FoundAdjacentRange; > + EFI_SMRAM_DESCRIPTOR *SmramRanges; > + > + *SmramCacheBase =3D SmramRange->CpuStart; > + *SmramCacheSize =3D SmramRange->PhysicalSize; > + > + SmramRanges =3D (EFI_SMRAM_DESCRIPTOR *)(UINTN)gMmCorePrivate- > >MmramRanges; > + do { > + FoundAdjacentRange =3D FALSE; > + for (Index =3D 0; Index < gMmCorePrivate->MmramRangeCount; Index++) = { > + RangeCpuStart =3D SmramRanges[Index].CpuStart; > + RangePhysicalSize =3D SmramRanges[Index].PhysicalSize; > + if ((RangeCpuStart < *SmramCacheBase) && (*SmramCacheBase =3D=3D > (RangeCpuStart + RangePhysicalSize))) { > + *SmramCacheBase =3D RangeCpuStart; > + *SmramCacheSize +=3D RangePhysicalSize; > + FoundAdjacentRange =3D TRUE; > + } else if (((*SmramCacheBase + *SmramCacheSize) =3D=3D RangeCpuSta= rt) && > (RangePhysicalSize > 0)) { > + *SmramCacheSize +=3D RangePhysicalSize; > + FoundAdjacentRange =3D TRUE; > + } > + } > + } while (FoundAdjacentRange); > +} > + > +/** > + Get the fixed loading address from image header assigned by build tool= . This > function only be called > + when Loading module at Fixed address feature enabled. > + > + @param ImageContext Pointer to the image context structu= re that > describes the PE/COFF > + image that needs to be examined by t= his function. > + @retval EFI_SUCCESS An fixed loading address is assigned= to this image > by build tools . > + @retval EFI_NOT_FOUND The image has no assigned fixed load= ing > address. > +**/ > +EFI_STATUS > +GetPeCoffImageFixLoadingAssignedAddress ( > + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext > + ) > +{ > + UINTN SectionHeaderOffset; > + EFI_STATUS Status; > + EFI_IMAGE_SECTION_HEADER SectionHeader; > + EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr; > + EFI_PHYSICAL_ADDRESS FixLoadingAddress; > + UINT16 Index; > + UINTN Size; > + UINT16 NumberOfSections; > + EFI_PHYSICAL_ADDRESS SmramBase; > + UINT64 SmmCodeSize; > + UINT64 ValueInSectionHeader; > + > + // > + // Build tool will calculate the smm code size and then patch the > PcdLoadFixAddressSmmCodePageNumber > + // > + SmmCodeSize =3D EFI_PAGES_TO_SIZE (PcdGet32 > (PcdLoadFixAddressSmmCodePageNumber)); > + FixLoadingAddress =3D 0; > + Status =3D EFI_NOT_FOUND; > + SmramBase =3D mCurrentSmramRange->CpuStart; > + // > + // Get PeHeader pointer > + // > + ImgHdr =3D (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((CHAR8 > *)ImageContext->Handle + ImageContext->PeCoffHeaderOffset); > + SectionHeaderOffset =3D (UINTN)( > + ImageContext->PeCoffHeaderOffset + > + sizeof (UINT32) + > + sizeof (EFI_IMAGE_FILE_HEADER) + > + ImgHdr->Pe32.FileHeader.SizeOfOptionalHe= ader > + ); > + NumberOfSections =3D ImgHdr->Pe32.FileHeader.NumberOfSections; > + > + // > + // Get base address from the first section header that doesn't point t= o code > section. > + // > + for (Index =3D 0; Index < NumberOfSections; Index++) { > + // > + // Read section header from file > + // > + Size =3D sizeof (EFI_IMAGE_SECTION_HEADER); > + Status =3D ImageContext->ImageRead ( > + ImageContext->Handle, > + SectionHeaderOffset, > + &Size, > + &SectionHeader > + ); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + Status =3D EFI_NOT_FOUND; > + > + if ((SectionHeader.Characteristics & EFI_IMAGE_SCN_CNT_CODE) =3D=3D = 0) { > + // > + // Build tool saves the offset to SMRAM base as image base in > PointerToRelocations & PointerToLineNumbers fields in the > + // first section header that doesn't point to code section in imag= e header. > And there is an assumption that when the > + // feature is enabled, if a module is assigned a loading address b= y tools, > PointerToRelocations & PointerToLineNumbers > + // fields should NOT be Zero, or else, these 2 fields should be se= t to Zero > + // > + ValueInSectionHeader =3D ReadUnaligned64 ((UINT64 > *)&SectionHeader.PointerToRelocations); > + if (ValueInSectionHeader !=3D 0) { > + // > + // Found first section header that doesn't point to code section= in which > build tool saves the > + // offset to SMRAM base as image base in PointerToRelocations & > PointerToLineNumbers fields > + // > + FixLoadingAddress =3D (EFI_PHYSICAL_ADDRESS)(SmramBase + > (INT64)ValueInSectionHeader); > + > + if ((SmramBase + SmmCodeSize > FixLoadingAddress) && (SmramBase = <=3D > FixLoadingAddress)) { > + // > + // The assigned address is valid. Return the specified loading= address > + // > + ImageContext->ImageAddress =3D FixLoadingAddress; > + Status =3D EFI_SUCCESS; > + } > + } > + > + break; > + } > + > + SectionHeaderOffset +=3D sizeof (EFI_IMAGE_SECTION_HEADER); > + } > + > + DEBUG ((DEBUG_INFO|DEBUG_LOAD, "LOADING MODULE FIXED INFO: > Loading module at fixed address %x, Status =3D %r \n", FixLoadingAddress,= Status)); > + return Status; > +} > + > +/** > + Searches all the available firmware volumes and returns the first matc= hing FFS > section. > + > + This function searches all the firmware volumes for FFS files with FV = file type > specified by FileType > + The order that the firmware volumes is searched is not deterministic. = For each > available FV a search > + is made for FFS file of type FileType. If the FV contains more than on= e FFS file > with the same FileType, > + the FileInstance instance will be the matched FFS file. For each FFS f= ile found a > search > + is made for FFS sections of type SectionType. If the FFS file contains= at least > SectionInstance instances > + of the FFS section specified by SectionType, then the SectionInstance = instance > is returned in Buffer. > + Buffer is allocated using AllocatePool(), and the size of the allocate= d buffer is > returned in Size. > + It is the caller's responsibility to use FreePool() to free the alloca= ted buffer. > + > + If Buffer is NULL, then ASSERT(). > + If Size is NULL, then ASSERT(). > + > + @param FileType Indicates the FV file type to search for = within all > available FVs. > + @param FileInstance Indicates which file instance within all = available FVs > specified by FileType. > + FileInstance starts from zero. > + @param SectionType Indicates the FFS section type to search = for within > the FFS file > + specified by FileType with FileInstance. > + @param SectionInstance Indicates which section instance within t= he FFS > file > + specified by FileType with FileInstance t= o retrieve. > SectionInstance starts from zero. > + @param Buffer On output, a pointer to a callee allocate= d buffer > containing the FFS file section that was found. > + Is it the caller's responsibility to free= this buffer using > FreePool(). > + @param Size On output, a pointer to the size, in byte= s, of Buffer. > + > + @retval EFI_SUCCESS The specified FFS section was returned. > + @retval EFI_NOT_FOUND The specified FFS section could not be f= ound. > + @retval EFI_OUT_OF_RESOURCES There are not enough resources available > to retrieve the matching FFS section. > + > +**/ > +EFI_STATUS > +EFIAPI > +GetSectionFromAnyFvByFileType ( > + IN EFI_FV_FILETYPE FileType, > + IN UINTN FileInstance, > + IN EFI_SECTION_TYPE SectionType, > + IN UINTN SectionInstance, > + OUT VOID **Buffer, > + OUT UINTN *Size > + ) > +{ > + EFI_STATUS Status; > + UINTN FvIndex; > + EFI_PEI_FV_HANDLE VolumeHandle; > + EFI_PEI_FILE_HANDLE FileHandle; > + EFI_PE32_SECTION *SectionData; > + UINT32 SectionSize; > + > + // > + // Search all FV > + // > + VolumeHandle =3D NULL; > + for (FvIndex =3D 0; ; FvIndex++) { > + Status =3D PeiServicesFfsFindNextVolume (FvIndex, &VolumeHandle); > + if (EFI_ERROR (Status)) { > + break; > + } > + > + // > + // Search PEIM FFS > + // > + FileHandle =3D NULL; > + Status =3D PeiServicesFfsFindNextFile (FileType, VolumeHandle, &= FileHandle); > + if (EFI_ERROR (Status)) { > + continue; > + } > + > + // > + // Search Section > + // > + SectionData =3D NULL; > + Status =3D PeiServicesFfsFindSectionData (SectionType, FileHand= le, Buffer); > + if (EFI_ERROR (Status)) { > + continue; > + } > + > + // > + // Great! > + // > + SectionData =3D (EFI_PE32_SECTION *)((UINT8 *)*Buffer - sizeof > (EFI_PE32_SECTION)); > + ASSERT (SectionData->Type =3D=3D SectionType); > + SectionSize =3D *(UINT32 *)SectionData->Size; > + SectionSize &=3D 0xFFFFFF; > + *Size =3D SectionSize - sizeof (EFI_PE32_SECTION); > + > + if (FileType =3D=3D EFI_FV_FILETYPE_MM_CORE_STANDALONE) { > + EFI_FV_INFO VolumeInfo; > + // > + // This is SMM BFV > + // > + Status =3D PeiServicesFfsGetVolumeInfo (VolumeHandle, &VolumeInfo)= ; > + if (!EFI_ERROR (Status)) { > + gMmCorePrivate->StandaloneBfvAddress =3D > (EFI_PHYSICAL_ADDRESS)(UINTN)VolumeInfo.FvStart; > + } > + } > + > + return EFI_SUCCESS; > + } > + > + return EFI_NOT_FOUND; > +} > + > +/** > + Load the SMM Core image into SMRAM and executes the SMM Core from > SMRAM. > + > + @param[in, out] SmramRange Descriptor for the range of SMRA= M to > reload the > + currently executing image, the r= ang of SMRAM to > + hold SMM Core will be excluded. > + @param[in, out] SmramRangeSmmCore Descriptor for the range of SMRA= M > to hold SMM Core. > + > + @param[in] Context Context to pass into SMM Core > + > + @return EFI_STATUS > + > +**/ > +EFI_STATUS > +ExecuteSmmCoreFromSmram ( > + IN OUT EFI_SMRAM_DESCRIPTOR *SmramRange, > + IN OUT EFI_SMRAM_DESCRIPTOR *SmramRangeSmmCore, > + IN VOID *Context > + ) > +{ > + EFI_STATUS Status; > + VOID *SourceBuffer; > + UINTN SourceSize; > + PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; > + UINTN PageCount; > + VOID *HobList; > + > + Status =3D PeiServicesGetHobList (&HobList); > + ASSERT_EFI_ERROR (Status); > + > + // > + // Search all Firmware Volumes for a PE/COFF image in a file of type > SMM_CORE > + // > + Status =3D GetSectionFromAnyFvByFileType ( > + EFI_FV_FILETYPE_MM_CORE_STANDALONE, > + 0, > + EFI_SECTION_PE32, > + 0, > + &SourceBuffer, > + &SourceSize > + ); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + // > + // Initialize ImageContext > + // > + ImageContext.Handle =3D SourceBuffer; > + ImageContext.ImageRead =3D PeCoffLoaderImageReadFromMemory; > + > + // > + // Get information about the image being loaded > + // > + Status =3D PeCoffLoaderGetImageInfo (&ImageContext); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + // > + // if Loading module at Fixed Address feature is enabled, the SMM core= driver > will be loaded to > + // the address assigned by build tool. > + // > + if (PcdGet64 (PcdLoadModuleAtFixAddressEnable) !=3D 0) { > + // > + // Get the fixed loading address assigned by Build tool > + // > + Status =3D GetPeCoffImageFixLoadingAssignedAddress (&ImageContext); > + if (!EFI_ERROR (Status)) { > + // > + // Since the memory range to load SMM CORE will be cut out in SMM = core, > so no need to allocate and free this range > + // > + PageCount =3D 0; > + // > + // Reserved Smram Region for SmmCore is not used, and remove it fr= om > SmramRangeCount. > + // > + gMmCorePrivate->MmramRangeCount--; > + } else { > + DEBUG ((DEBUG_INFO, "LOADING MODULE FIXED ERROR: Loading module > at fixed address at address failed\n")); > + // > + // Allocate memory for the image being loaded from the > EFI_SRAM_DESCRIPTOR > + // specified by SmramRange > + // > + PageCount =3D (UINTN)EFI_SIZE_TO_PAGES ((UINTN)ImageContext.ImageS= ize > + ImageContext.SectionAlignment); > + > + ASSERT ((SmramRange->PhysicalSize & EFI_PAGE_MASK) =3D=3D 0); > + ASSERT (SmramRange->PhysicalSize > EFI_PAGES_TO_SIZE (PageCount)); > + > + SmramRange->PhysicalSize -=3D EFI_PAGES_TO_SIZE (PageCount)= ; > + SmramRangeSmmCore->CpuStart =3D SmramRange->CpuStart + > SmramRange->PhysicalSize; > + SmramRangeSmmCore->PhysicalStart =3D SmramRange->PhysicalStart + > SmramRange->PhysicalSize; > + SmramRangeSmmCore->RegionState =3D SmramRange->RegionState | > EFI_ALLOCATED; > + SmramRangeSmmCore->PhysicalSize =3D EFI_PAGES_TO_SIZE (PageCount)= ; > + > + // > + // Align buffer on section boundary > + // > + ImageContext.ImageAddress =3D SmramRangeSmmCore->CpuStart; > + } > + } else { > + // > + // Allocate memory for the image being loaded from the > EFI_SRAM_DESCRIPTOR > + // specified by SmramRange > + // > + PageCount =3D (UINTN)EFI_SIZE_TO_PAGES ((UINTN)ImageContext.ImageSiz= e + > ImageContext.SectionAlignment); > + > + ASSERT ((SmramRange->PhysicalSize & EFI_PAGE_MASK) =3D=3D 0); > + ASSERT (SmramRange->PhysicalSize > EFI_PAGES_TO_SIZE (PageCount)); > + > + SmramRange->PhysicalSize -=3D EFI_PAGES_TO_SIZE (PageCount); > + SmramRangeSmmCore->CpuStart =3D SmramRange->CpuStart + > SmramRange->PhysicalSize; > + SmramRangeSmmCore->PhysicalStart =3D SmramRange->PhysicalStart + > SmramRange->PhysicalSize; > + SmramRangeSmmCore->RegionState =3D SmramRange->RegionState | > EFI_ALLOCATED; > + SmramRangeSmmCore->PhysicalSize =3D EFI_PAGES_TO_SIZE (PageCount); > + > + // > + // Align buffer on section boundary > + // > + ImageContext.ImageAddress =3D SmramRangeSmmCore->CpuStart; > + } > + > + ImageContext.ImageAddress +=3D ImageContext.SectionAlignment - 1; > + ImageContext.ImageAddress &=3D > ~((EFI_PHYSICAL_ADDRESS)ImageContext.SectionAlignment - 1); > + > + // > + // Print debug message showing SMM Core load address. > + // > + DEBUG ((DEBUG_INFO, "SMM IPL loading SMM Core at SMRAM > address %p\n", (VOID *)(UINTN)ImageContext.ImageAddress)); > + > + // > + // Load the image to our new buffer > + // > + Status =3D PeCoffLoaderLoadImage (&ImageContext); > + if (!EFI_ERROR (Status)) { > + // > + // Relocate the image in our new buffer > + // > + Status =3D PeCoffLoaderRelocateImage (&ImageContext); > + if (!EFI_ERROR (Status)) { > + // > + // Flush the instruction cache so the image data are written befor= e we > execute it > + // > + InvalidateInstructionCacheRange ((VOID > *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize); > + > + // > + // Print debug message showing SMM Core entry point address. > + // > + DEBUG ((DEBUG_INFO, "SMM IPL calling SMM Core at SMRAM > address %p\n", (VOID *)(UINTN)ImageContext.EntryPoint)); > + > + gMmCorePrivate->MmCoreImageBase =3D ImageContext.ImageAddress; > + gMmCorePrivate->MmCoreImageSize =3D ImageContext.ImageSize; > + DEBUG ((DEBUG_INFO, "SmmCoreImageBase - 0x%016lx\n", > gMmCorePrivate->MmCoreImageBase)); > + DEBUG ((DEBUG_INFO, "SmmCoreImageSize - 0x%016lx\n", > gMmCorePrivate->MmCoreImageSize)); > + > + gMmCorePrivate->MmCoreEntryPoint =3D ImageContext.EntryPoint; > + > + // > + // Print debug message showing Standalone MM Core entry point addr= ess. > + // > + DEBUG ((DEBUG_INFO, "SMM IPL calling Standalone MM Core at SMRAM > address - 0x%016lx\n", gMmCorePrivate->MmCoreEntryPoint)); > + > + // > + // Execute image > + // > + LoadSmmCore (ImageContext.EntryPoint, HobList); > + } > + } > + > + // > + // If the load operation, relocate operation, or the image execution r= eturn an > + // error, then free memory allocated from the EFI_SRAM_DESCRIPTOR > specified by > + // SmramRange > + // > + if (EFI_ERROR (Status)) { > + SmramRange->PhysicalSize +=3D EFI_PAGES_TO_SIZE (PageCount); > + } > + > + // > + // Always free memory allocated by GetFileBufferByFilePath () > + // > + FreePool (SourceBuffer); > + > + return Status; > +} > + > +/** > + Get full SMRAM ranges. > + > + It will get SMRAM ranges from SmmAccess protocol and SMRAM reserved > ranges from > + SmmConfiguration protocol, split the entries if there is overlap betwe= en them. > + It will also reserve one entry for SMM core. > + > + @param[in] PeiServices Describes the list of possible PEI S= ervices. > + @param[out] FullSmramRangeCount Output pointer to full SMRAM range > count. > + > + @return Pointer to full SMRAM ranges. > + > +**/ > +EFI_SMRAM_DESCRIPTOR * > +GetFullSmramRanges ( > + IN CONST EFI_PEI_SERVICES **PeiServices, > + OUT UINTN *FullSmramRangeCount > + ) > +{ > + EFI_STATUS Status; > + UINTN Size; > + EFI_SMRAM_DESCRIPTOR *FullSmramRanges; > + UINTN AdditionSmramRangeCount; > + UINTN SmramRangeCount; > + > + // > + // Get SMRAM information. > + // > + Size =3D 0; > + Status =3D mSmmAccess->GetCapabilities ((EFI_PEI_SERVICES **)PeiServic= es, > mSmmAccess, &Size, NULL); > + ASSERT (Status =3D=3D EFI_BUFFER_TOO_SMALL); > + > + SmramRangeCount =3D Size / sizeof (EFI_SMRAM_DESCRIPTOR); > + > + // > + // Reserve one entry SMM Core in the full SMRAM ranges. > + // > + AdditionSmramRangeCount =3D 1; > + if (PcdGet64 (PcdLoadModuleAtFixAddressEnable) !=3D 0) { > + // > + // Reserve two entries for all SMM drivers & SMM Core in the full SM= RAM > ranges. > + // > + AdditionSmramRangeCount =3D 2; > + } > + > + *FullSmramRangeCount =3D SmramRangeCount + AdditionSmramRangeCount; > + Size =3D (*FullSmramRangeCount) * sizeof (EFI_SMRAM_DE= SCRIPTOR); > + FullSmramRanges =3D (EFI_SMRAM_DESCRIPTOR *)AllocateZeroPool (Siz= e); > + ASSERT (FullSmramRanges !=3D NULL); > + if (FullSmramRanges =3D=3D NULL) { > + return NULL; > + } > + > + Status =3D mSmmAccess->GetCapabilities ((EFI_PEI_SERVICES **)PeiServic= es, > mSmmAccess, &Size, FullSmramRanges); > + > + ASSERT_EFI_ERROR (Status); > + > + return FullSmramRanges; > +} > + > +/** > + The Entry Point for SMM IPL > + > + Load SMM Core into SMRAM. > + > + @param FileHandle Handle of the file being invoked. > + @param PeiServices Describes the list of possible PEI Services. > + > + @retval EFI_SUCCESS The entry point is executed successfully. > + @retval Other Some error occurred when executing this entry p= oint. > + > +**/ > +EFI_STATUS > +EFIAPI > +SmmIplEntry ( > + IN EFI_PEI_FILE_HANDLE FileHandle, > + IN CONST EFI_PEI_SERVICES **PeiServices > + ) > +{ > + EFI_STATUS Status; > + UINTN Index; > + UINT64 MaxSize; > + UINT64 SmmCodeSize; > + MM_CORE_DATA_HOB_DATA SmmCoreDataHobData; > + EFI_SMRAM_DESCRIPTOR *MmramRanges; > + EFI_SMRAM_DESCRIPTOR *SmramRangeSmmDriver; > + > + // > + // Build Hob for SMM and DXE phase > + // > + SmmCoreDataHobData.Address =3D > (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateRuntimePages (EFI_SIZE_TO_PAGES > (sizeof (mMmCorePrivateData))); > + ASSERT (SmmCoreDataHobData.Address !=3D 0); > + gMmCorePrivate =3D (VOID *)(UINTN)SmmCoreDataHobData.Address; > + CopyMem ((VOID *)(UINTN)SmmCoreDataHobData.Address, > &mMmCorePrivateData, sizeof (mMmCorePrivateData)); > + DEBUG ((DEBUG_INFO, "gMmCorePrivate - 0x%x\n", gMmCorePrivate)); > + > + BuildGuidDataHob ( > + &gMmCoreDataHobGuid, > + (VOID *)&SmmCoreDataHobData, > + sizeof (SmmCoreDataHobData) > + ); > + > + // > + // Get SMM Access Protocol > + // > + Status =3D PeiServicesLocatePpi (&gPeiSmmAccessPpiGuid, 0, NULL, (VOID > **)&mSmmAccess); > + ASSERT_EFI_ERROR (Status); > + > + // > + // Get SMRAM information > + // > + gMmCorePrivate->MmramRanges =3D > (EFI_PHYSICAL_ADDRESS)(UINTN)GetFullSmramRanges (PeiServices, (UINTN > *)&gMmCorePrivate->MmramRangeCount); > + ASSERT (gMmCorePrivate->MmramRanges !=3D 0); > + if (gMmCorePrivate->MmramRanges =3D=3D 0) { > + return EFI_OUT_OF_RESOURCES; > + } > + > + // > + // Open all SMRAM ranges > + // > + Status =3D mSmmAccess->Open ((EFI_PEI_SERVICES **)PeiServices, > mSmmAccess, 0); > + ASSERT_EFI_ERROR (Status); > + > + // > + // Print debug message that the SMRAM window is now open. > + // > + DEBUG ((DEBUG_INFO, "SMM IPL opened SMRAM window\n")); > + > + // > + // Find the largest SMRAM range between 1MB and 4GB that is at least 2= 56KB > - 4K in size > + // > + mCurrentSmramRange =3D NULL; > + MmramRanges =3D (EFI_MMRAM_DESCRIPTOR *)(UINTN)gMmCorePrivate- > >MmramRanges; > + if (MmramRanges =3D=3D NULL) { > + DEBUG ((DEBUG_ERROR, "Fail to retrieve MmramRanges\n")); > + return EFI_UNSUPPORTED; > + } > + > + for (Index =3D 0, MaxSize =3D SIZE_256KB - EFI_PAGE_SIZE; Index < > gMmCorePrivate->MmramRangeCount; Index++) { > + // > + // Skip any SMRAM region that is already allocated, needs testing, o= r needs > ECC initialization > + // > + if ((MmramRanges[Index].RegionState & (EFI_ALLOCATED | > EFI_NEEDS_TESTING | EFI_NEEDS_ECC_INITIALIZATION)) !=3D 0) { > + continue; > + } > + > + if (MmramRanges[Index].CpuStart >=3D BASE_1MB) { > + if ((MmramRanges[Index].CpuStart + MmramRanges[Index].PhysicalSize= ) <=3D > BASE_4GB) { > + if (MmramRanges[Index].PhysicalSize >=3D MaxSize) { > + MaxSize =3D MmramRanges[Index].PhysicalSize; > + mCurrentSmramRange =3D &MmramRanges[Index]; > + } > + } > + } > + } > + > + if (mCurrentSmramRange !=3D NULL) { > + // > + // Print debug message showing SMRAM window that will be used by SMM > IPL and SMM Core > + // > + DEBUG (( > + DEBUG_INFO, > + "SMM IPL found SMRAM window %p - %p\n", > + (VOID *)(UINTN)mCurrentSmramRange->CpuStart, > + (VOID *)(UINTN)(mCurrentSmramRange->CpuStart + > mCurrentSmramRange->PhysicalSize - 1) > + )); > + > + GetSmramCacheRange (mCurrentSmramRange, &mSmramCacheBase, > &mSmramCacheSize); > + > + // > + // if Loading module at Fixed Address feature is enabled, save the S= MRAM > base to Load > + // Modules At Fixed Address Configuration Table. > + // > + if (PcdGet64 (PcdLoadModuleAtFixAddressEnable) !=3D 0) { > + // > + // Build tool will calculate the smm code size and then patch the > PcdLoadFixAddressSmmCodePageNumber > + // > + SmmCodeSize =3D LShiftU64 (PcdGet32 > (PcdLoadFixAddressSmmCodePageNumber), EFI_PAGE_SHIFT); > + // > + // The SMRAM available memory is assumed to be larger than SmmCode= Size > + // > + ASSERT (mCurrentSmramRange->PhysicalSize > SmmCodeSize); > + // > + // Fill the Smram range for all SMM code > + // > + MmramRanges =3D (EFI_MMRAM_DESCRIPTOR *)(UINTN)gMmCorePrivate- > >MmramRanges; > + // > + // Note: SmramRanges specific for all SMM code will put in the > gMmCorePrivate->MmramRangeCount - 2. > + // > + SmramRangeSmmDriver =3D &MmramRanges[gMmCorePrivate= - > >MmramRangeCount - 2]; > + SmramRangeSmmDriver->CpuStart =3D mCurrentSmramRange->CpuStar= t; > + SmramRangeSmmDriver->PhysicalStart =3D mCurrentSmramRange- > >PhysicalStart; > + SmramRangeSmmDriver->RegionState =3D mCurrentSmramRange- > >RegionState | EFI_ALLOCATED; > + SmramRangeSmmDriver->PhysicalSize =3D SmmCodeSize; > + > + mCurrentSmramRange->PhysicalSize -=3D SmmCodeSize; > + mCurrentSmramRange->CpuStart =3D mCurrentSmramRange->CpuStart= + > SmmCodeSize; > + mCurrentSmramRange->PhysicalStart =3D mCurrentSmramRange- > >PhysicalStart + SmmCodeSize; > + } > + > + // > + // Load SMM Core into SMRAM and execute it from SMRAM > + // Note: SmramRanges specific for SMM Core will put in the gMmCorePr= ivate- > >MmramRangeCount - 1. > + // > + Status =3D ExecuteSmmCoreFromSmram ( > + mCurrentSmramRange, > + &(((EFI_MMRAM_DESCRIPTOR *)(UINTN)gMmCorePrivate- > >MmramRanges)[gMmCorePrivate->MmramRangeCount - 1]), > + gMmCorePrivate > + ); > + if (EFI_ERROR (Status)) { > + // > + // Print error message that the SMM Core failed to be loaded and e= xecuted. > + // > + DEBUG ((DEBUG_ERROR, "SMM IPL could not load and execute SMM Core > from SMRAM\n")); > + } > + } else { > + // > + // Print error message that there are not enough SMRAM resources to = load > the SMM Core. > + // > + DEBUG ((DEBUG_ERROR, "SMM IPL could not find a large enough SMRAM > region to load SMM Core\n")); > + } > + > + // > + // If the SMM Core could not be loaded then close SMRAM window, free > allocated > + // resources, and return an error so SMM IPL will be unloaded. > + // > + if ((mCurrentSmramRange =3D=3D NULL) || EFI_ERROR (Status)) { > + // > + // Close all SMRAM ranges > + // > + Status =3D mSmmAccess->Close ((EFI_PEI_SERVICES **)PeiServices, > mSmmAccess, 0); > + ASSERT_EFI_ERROR (Status); > + > + // > + // Print debug message that the SMRAM window is now closed. > + // > + DEBUG ((DEBUG_INFO, "SMM IPL closed SMRAM window\n")); > + > + // > + // Free all allocated resources > + // > + FreePool ((VOID *)(UINTN)gMmCorePrivate->MmramRanges); > + > + return EFI_UNSUPPORTED; > + } > + > + // > + // Create ready to boot for close and lock smram ranges > + // > + Status =3D PeiServicesNotifyPpi (&mReadyToBootNotifyList); > + ASSERT_EFI_ERROR (Status); > + > + return EFI_SUCCESS; > +} > diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/X64/LoadSmmCore.c > b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/X64/LoadSmmCore.c > new file mode 100644 > index 0000000000..6d3497f2ea > --- /dev/null > +++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/X64/LoadSmmCore.c > @@ -0,0 +1,32 @@ > +/** @file > + SMM IPL that load the SMM Core into SMRAM > + > + Copyright (c) 2023, Intel Corporation. All rights reserved.
> + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include > +#include > +#include > + > +/** > + Load SMM core to dispatch other Standalone MM drivers. > + > + @param Entry Entry of Standalone MM Foundation. > + @param Context1 A pointer to the context to pass int= o the > EntryPoint > + function. > + @retval EFI_SUCCESS Successfully loaded SMM core. > + @retval Others Failed to load SMM core. > +**/ > +EFI_STATUS > +LoadSmmCore ( > + IN EFI_PHYSICAL_ADDRESS Entry, > + IN VOID *Context1 > + ) > +{ > + STANDALONE_MM_FOUNDATION_ENTRY_POINT EntryPoint; > + > + EntryPoint =3D (STANDALONE_MM_FOUNDATION_ENTRY_POINT)(UINTN)Entry; > + return EntryPoint (Context1); > +} > diff --git > a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/Ia32/Thunk32To64.nasm > b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/Ia32/Thunk32To64.nasm > new file mode 100644 > index 0000000000..7f887eb77d > --- /dev/null > +++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/Ia32/Thunk32To64.nasm > @@ -0,0 +1,148 @@ > +;-----------------------------------------------------------------------= ------- > +; > +; Copyright (c) 2023, Intel Corporation. All rights reserved.
> +; SPDX-License-Identifier: BSD-2-Clause-Patent > +; > +; Module Name: > +; > +; Thunk32To64.nasm > +; > +; Abstract: > +; > +; This is the assembly code to transition from long mode to compatibil= ity > +; mode to execute 32-bit code and then transit back to long mode. > +; > +;-----------------------------------------------------------------------= ------- > + > + SECTION .text > + > +;-----------------------------------------------------------------------= ------- > +; Procedure: AsmExecute64BitCode > +; > +; Input: None > +; > +; Output: None > +; > +; Prototype: UINT32 > +; AsmExecute64BitCode ( > +; IN UINT64 Function, > +; IN UINT64 Param1, > +; IN UINT64 Param2, > +; IN IA32_DESCRIPTOR *InternalGdtr > +; ); > +; > +; > +; Description: A thunk function to execute 32-bit code in long mode. > +; > +;-----------------------------------------------------------------------= ------- > +global ASM_PFX(AsmExecute64BitCode) > +ASM_PFX(AsmExecute64BitCode): > +; > +; +---------+ > +; | EIP(64) | > +; +---------+ > +; | CS (64) | > +; +---------+ > +; | EIP(32) | > +; +---------+ > +; | CS (32) |<-ESP (16 bytes aligned) > +; +---------+ > +; | ... | > +; +---------+ > +; | ebx |<-EBP > +; +---------+ > +; | ebp |<-EBP + 4 > +; +---------+ > +; | esi |<-EBP + 8 > +; +---------+ > +; | edi |<-EBP + 12 > +; +---------+ > +; | RFlags |<-EBP + 16 > +; +---------+ > +; | RetAddr |<-EBP (org) > +; +---------+ > +; | Func |<-EBP + 24 > +; | Func | > +; +---------+ > +; | Param1 |<-EBP + 32 > +; | Param1 | > +; +---------+ > +; | Param2 |<-EBP + 40 > +; | Param2 | > +; +---------+ > +; | Gdtr | > +; +---------+ > +; > + ; > + ; Save general purpose register and RFlags register > + ; > + pushfd > + push edi > + push esi > + push ebp > + push ebx > + mov ebp, esp > + > + and esp, 0FFFFFFF0h > + > + push 010h ; protected mode selector on sta= ck > + mov eax, Compatible ; offset for LongMode > + push eax ; offset on stack > + > + push 038h ; long mode selector on stack > + mov eax, LongMode ; offset for LongMode > + push eax ; offset on stack > + > + mov eax, cr4 > + or al, 020h > + mov cr4, eax ; enable PAE > + mov ecx, 0c0000080h > + rdmsr > + or ah, 1 ; set LME > + wrmsr > + mov eax, cr0 > + bts eax, 31 ; set PG > + mov cr0, eax ; enable paging > + retf ; topmost 2 dwords hold the addr= ess > +LongMode: ; long mode starts here > + > + ; Call long mode function > + DB 67h, 48h ; 32-bit address size, 64-bit op= erand size > + mov eax, [ebp + 24] ; mov rbx, [ebp + 24] > + DB 67h, 48h > + mov ecx, [ebp + 24 + 8] ; mov rcx, [ebp + 24 + 8] > + DB 67h, 48h > + mov edx, [ebp + 24 + 16] ; mov rdx, [ebp + 24 + 16] > + > + DB 48h > + add esp, -20h ; add rsp, -20h > + call eax ; call rax > + DB 48h > + add esp, 20h ; add rsp, 20h > + > + ; after long mode function call > + mov ebx, eax > + > + retf > +Compatible: > + mov ecx, cr0 > + btc ecx, 31 ; clear PG > + mov cr0, ecx ; disable paging > + mov ecx, 0C0000080h > + rdmsr > + btc eax, 8 ; clear LME > + wrmsr > + > + ; > + ; Restore C register and eax hold the return status from 32-bit func= tion. > + ; Note: Do not touch rax from now which hold the return value from I= A32 > function > + ; > + mov eax, ebx ; put return status to EAX > + mov esp, ebp ; restore stack pointer > + pop ebx > + pop ebp > + pop esi > + pop edi > + popfd > + > + ret > diff --git > a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h > b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h > new file mode 100644 > index 0000000000..be0aae70f0 > --- /dev/null > +++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h > @@ -0,0 +1,66 @@ > +/** @file > + Private header with declarations and definitions specific to the Stand= alone > + MM IPL PEI driver > + > + Copyright (c) 2023, Intel Corporation. All rights reserved.
> + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#ifndef STANDALONE_MM_IPL_PEI_H_ > +#define STANDALONE_MM_IPL_PEI_H_ > + > +/** > + Load SMM core to dispatch other Standalone MM drivers. > + > + @param Entry Entry of Standalone MM Foundation. > + @param Context1 A pointer to the context to pass int= o the > EntryPoint > + function. > + @retval EFI_SUCCESS Successfully loaded SMM core. > + @retval Others Failed to load SMM core. > +**/ > +EFI_STATUS > +LoadSmmCore ( > + IN EFI_PHYSICAL_ADDRESS Entry, > + IN VOID *Context1 > + ); > + > +/** > + Assembly function to transition from long mode to compatibility mode t= o > + execute 32-bit code and then transit back to long mode. > + > + @param[in] Function The 32bit code entry to be executed. > + @param[in] Param1 The first parameter to pass to 32bit code > + @param[in] Param2 The second parameter to pass to 32bit code > + @param[in] InternalGdtr The GDT and GDT descriptor used by this librar= y > + > + @retval status. > +**/ > +UINT32 > +AsmExecute64BitCode ( > + IN UINT64 Function, > + IN UINT64 Param1, > + IN UINT64 Param2, > + IN IA32_DESCRIPTOR *InternalGdtr > + ); > + > +/** > + This is the callback function on ready to boot. > + > + Close and lock smram ranges on ready to boot stage. > + > + @param PeiServices General purpose services available to every= PEIM. > + @param NotifyDescriptor The notification structure this PEIM regist= ered on > install. > + @param Ppi Pointer to the PPI data associated with thi= s function. > + @retval EFI_SUCCESS Close and lock smram ranges successfully. > + @retval Other Close and lock smram ranges failed. > +**/ > +EFI_STATUS > +EFIAPI > +ReadyToBootEvent ( > + IN EFI_PEI_SERVICES **PeiServices, > + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, > + IN VOID *Ppi > + ); > + > +#endif > diff --git > a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf > b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf > new file mode 100644 > index 0000000000..ff4c67a92c > --- /dev/null > +++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf > @@ -0,0 +1,75 @@ > +## @file > +# This module provide a Standalone SMM compliant implementation of SMM > IPL PEIM. > +# > +# Copyright (c) 2023, Intel Corporation. All rights reserved.
> +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > + INF_VERSION =3D 0x00010005 > + BASE_NAME =3D StandaloneMmIplPei > + FILE_GUID =3D 578A0D17-2DC0-4C7D-A121-D8D771923BB= 0 > + MODULE_TYPE =3D PEIM > + VERSION_STRING =3D 1.0 > + PI_SPECIFICATION_VERSION =3D 0x0001000A > + ENTRY_POINT =3D SmmIplEntry > + > +# > +# The following information is for reference only and not required by th= e build > tools. > +# > +# VALID_ARCHITECTURES =3D IA32 X64 > +# > + > +[Sources] > + StandaloneMmIplPei.h > + StandaloneMmIplPei.c > + > +[Sources.Ia32] > + Ia32/LoadSmmCore.c > + Ia32/Thunk32To64.nasm > + > +[Sources.X64] > + X64/LoadSmmCore.c > + > +[Packages] > + MdePkg/MdePkg.dec > + MdeModulePkg/MdeModulePkg.dec > + StandaloneMmPkg/StandaloneMmPkg.dec > + > +[LibraryClasses] > + PeimEntryPoint > + PeiServicesTablePointerLib > + PeiServicesLib > + BaseLib > + BaseMemoryLib > + PeCoffLib > + CacheMaintenanceLib > + MemoryAllocationLib > + DebugLib > + HobLib > + IntrinsicLib > + > +[Guids] > + gMmCoreDataHobGuid > + gEfiEventReadyToBootGuid > + > +[Ppis] > + gPeiSmmAccessPpiGuid ## CONSUMES > + gPeiSmmControlPpiGuid ## CONSUMES > + > +[FeaturePcd.IA32] > + gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode ## > CONSUMES > + > +[Pcd.IA32] > + gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable ## > SOMETIMES_CONSUMES > + > +[Pcd] > + gEfiMdeModulePkgTokenSpaceGuid.PcdLoadFixAddressSmmCodePageNumber > ## SOMETIMES_CONSUMES > + gEfiMdeModulePkgTokenSpaceGuid.PcdLoadModuleAtFixAddressEnable = ## > CONSUMES > + > +[Depex] > + gPeiSmmAccessPpiGuid AND > + gPeiSmmControlPpiGuid > + > diff --git a/StandaloneMmPkg/StandaloneMmPkg.ci.yaml > b/StandaloneMmPkg/StandaloneMmPkg.ci.yaml > index 4777532a7e..872f7958be 100644 > --- a/StandaloneMmPkg/StandaloneMmPkg.ci.yaml > +++ b/StandaloneMmPkg/StandaloneMmPkg.ci.yaml > @@ -78,7 +78,9 @@ > ## options defined .pytool/Plugin/SpellCheck > "SpellCheck": { > "AuditOnly": False, > - "IgnoreFiles": [], # use gitignore syntax to ignore er= rors > + "IgnoreFiles": [ > + "Drivers/StandaloneMmIplPei/Ia32/Thunk32To64.nasm" > + ], # use gitignore syntax to ignore errors > # in matching files > "ExtendWords": [ > "Bsymbolic", > diff --git a/StandaloneMmPkg/StandaloneMmPkg.dsc > b/StandaloneMmPkg/StandaloneMmPkg.dsc > index 8012f93b7d..d88471fe82 100644 > --- a/StandaloneMmPkg/StandaloneMmPkg.dsc > +++ b/StandaloneMmPkg/StandaloneMmPkg.dsc > @@ -20,7 +20,7 @@ > PLATFORM_VERSION =3D 1.0 > DSC_SPECIFICATION =3D 0x00010011 > OUTPUT_DIRECTORY =3D Build/StandaloneMm > - SUPPORTED_ARCHITECTURES =3D AARCH64|X64|ARM > + SUPPORTED_ARCHITECTURES =3D AARCH64|X64|ARM|IA32 > BUILD_TARGETS =3D DEBUG|RELEASE > SKUID_IDENTIFIER =3D DEFAULT >=20 > @@ -60,6 +60,14 @@ >=20 > StandaloneMmDriverEntryPoint|MdePkg/Library/StandaloneMmDriverEntryPoin > t/StandaloneMmDriverEntryPoint.inf >=20 > VariableMmDependency|StandaloneMmPkg/Library/VariableMmDependency/V > ariableMmDependency.inf >=20 > +[LibraryClasses.common.PEIM] > + HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf > + PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf > + > MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAlloc > ationLib.inf > + PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf > + > PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLib/PeiS= ervic > esTablePointerLib.inf > + IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf > + > [LibraryClasses.AARCH64, LibraryClasses.ARM] > ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf >=20 > StandaloneMmMmuLib|ArmPkg/Library/StandaloneMmMmuLib/ArmMmuStand > aloneMmLib.inf > @@ -104,7 +112,7 @@ > # generated for it, but the binary will not be put into any firmwa= re volume. > # >=20 > ################################################################# > ################################## > -[Components.common] > +[Components.AARCH64, Components.ARM, Components.X64] > # > # MM Core > # > @@ -122,6 +130,9 @@ > StandaloneMmPkg/Drivers/StandaloneMmCpu/StandaloneMmCpu.inf >=20 > StandaloneMmPkg/Library/StandaloneMmPeCoffExtraActionLib/StandaloneMm > PeCoffExtraActionLib.inf >=20 > +[Components.X64, Components.IA32] > + StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf > + >=20 > ################################################################# > ################################## > # > # BuildOptions Section - Define the module specific tool chain flags tha= t should > be used as > diff --git a/UefiPayloadPkg/UniversalPayloadBuild.sh > b/UefiPayloadPkg/UniversalPayloadBuild.sh > index 9a72eedd35..bacf5233a8 100644 > --- a/UefiPayloadPkg/UniversalPayloadBuild.sh > +++ b/UefiPayloadPkg/UniversalPayloadBuild.sh > @@ -1,17 +1,17 @@ > -#!/usr/bin/env bash > -# > -# Copyright (c) 2022, Intel Corporation. All rights reserved.
> -# > -# SPDX-License-Identifier: BSD-2-Clause-Patent > -# > - > -if command -v ${PYTHON_COMMAND} >/dev/null 2>&1; then > - echo python_exe=3D${PYTHON_COMMAND} > -fi > - > -# Get file path of UniversalPayloadBuild.sh > -uplbld_filepath=3D${BASH_SOURCE:-$0} > -# Remove ".sh" extension > -uplbld_filepath_noext=3D${uplbld_filepath%.*} > -# execute UniversalPayloadBuild.py to build UefiPayloadPkg > -exec "${python_exe:-python}" "$uplbld_filepath_noext.py" "$@" > +#!/usr/bin/env bash > +# > +# Copyright (c) 2022, Intel Corporation. All rights reserved.
> +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > + > +if command -v ${PYTHON_COMMAND} >/dev/null 2>&1; then > + echo python_exe=3D${PYTHON_COMMAND} > +fi > + > +# Get file path of UniversalPayloadBuild.sh > +uplbld_filepath=3D${BASH_SOURCE:-$0} > +# Remove ".sh" extension > +uplbld_filepath_noext=3D${uplbld_filepath%.*} > +# execute UniversalPayloadBuild.py to build UefiPayloadPkg > +exec "${python_exe:-python}" "$uplbld_filepath_noext.py" "$@" > diff --git a/edksetup.sh b/edksetup.sh > index cab3a8c113..553e1676d0 100755 > --- a/edksetup.sh > +++ b/edksetup.sh > @@ -1,147 +1,147 @@ > -# > -# Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.
> -# Copyright (c) 2016, Linaro Ltd. All rights reserved.
> -# SPDX-License-Identifier: BSD-2-Clause-Patent > -# > -# In *inux environment, the build tools's source is required and need to= be > compiled > -# firstly, please reference > https://github.com/tianocore/tianocore.github.io/wiki/SourceForge-to-Gith= ub- > Quick-Start > -# to get how to setup build tool. > -# > -# Setup the environment for unix-like systems running a bash-like shell. > -# This file must be "sourced" not merely executed. For example: ". edkse= tup.sh" > -# > -# CYGWIN users: Your path and filename related environment variables sho= uld > be > -# set up in the unix style. This script will make the necessary convers= ions to > -# windows style. > -# > -# Please reference edk2 user manual for more detail descriptions at > https://github.com/tianocore- > docs/Docs/raw/master/User_Docs/EDK_II_UserManual_0_7.pdf > -# > - > -SCRIPTNAME=3D"edksetup.sh" > -RECONFIG=3DFALSE > - > -HelpMsg() > -{ > - echo "Usage: $SCRIPTNAME [Options]" > - echo > - echo "The system environment variable, WORKSPACE, is always set to the > current" > - echo "working directory." > - echo > - echo "Options: " > - echo " --help, -h, -? Print this help screen and exit." > - echo > - echo " --reconfig Overwrite the WORKSPACE/Conf/*.txt files= with the" > - echo " template files from the BaseTools/Conf d= irectory." > - echo > - echo Please note: This script must be \'sourced\' so the environment c= an be > changed. > - echo ". $SCRIPTNAME" > - echo "source $SCRIPTNAME" > -} > - > -SetWorkspace() > -{ > - # > - # If WORKSPACE is already set, then we can return right now > - # > - export PYTHONHASHSEED=3D1 > - if [ -n "$WORKSPACE" ] > - then > - return 0 > - fi > - > - if [ ! -f ${SCRIPTNAME} ] && [ -z "$PACKAGES_PATH" ] > - then > - echo Source this script from the base of your tree. For example: > - echo " cd /Path/To/Edk2/Clone" > - echo " . $SCRIPTNAME" > - return 1 > - fi > - > - # > - # Check for BaseTools/BuildEnv before dirtying the user's environment. > - # > - if [ ! -f BaseTools/BuildEnv ] && [ -z "$EDK_TOOLS_PATH" ] > - then > - echo BaseTools not found in your tree, and EDK_TOOLS_PATH is not set= . > - echo Please point EDK_TOOLS_PATH at the directory that contains > - echo the EDK2 BuildEnv script. > - return 1 > - fi > - > - # > - # Set $WORKSPACE > - # > - export WORKSPACE=3D$PWD > - return 0 > -} > - > -SetupEnv() > -{ > - if [ -n "$EDK_TOOLS_PATH" ] > - then > - . $EDK_TOOLS_PATH/BuildEnv > - elif [ -f "$WORKSPACE/BaseTools/BuildEnv" ] > - then > - . $WORKSPACE/BaseTools/BuildEnv > - elif [ -n "$PACKAGES_PATH" ] > - then > - for DIR in $(echo $PACKAGES_PATH | tr ':' ' ') > - do > - if [ -f "$DIR/BaseTools/BuildEnv" ] > - then > - export EDK_TOOLS_PATH=3D$DIR/BaseTools > - . $DIR/BaseTools/BuildEnv > - break > - fi > - done > - else > - echo BaseTools not found in your tree, and EDK_TOOLS_PATH is not set= . > - echo Please check that WORKSPACE or PACKAGES_PATH is not set incorre= ctly > - echo in your shell, or point EDK_TOOLS_PATH at the directory that co= ntains > - echo the EDK2 BuildEnv script. > - return 1 > - fi > -} > - > -SetupPython3() > -{ > - export PYTHON_COMMAND=3Dpython3 > -} > - > -SourceEnv() > -{ > - SetupPython3 > - SetWorkspace > - SetupEnv > -} > - > -I=3D$# > -while [ $I -gt 0 ] > -do > - case "$1" in > - BaseTools) > - # Ignore argument for backwards compatibility > - shift > - ;; > - --reconfig) > - RECONFIG=3DTRUE > - shift > - ;; > - *) > - HelpMsg > - break > - ;; > - esac > - I=3D$((I - 1)) > -done > - > -if [ $I -gt 0 ] > -then > - return 1 > -fi > - > -SourceEnv > - > -unset SCRIPTNAME RECONFIG > - > -return $? > +# > +# Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.
> +# Copyright (c) 2016, Linaro Ltd. All rights reserved.
> +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +# In *inux environment, the build tools's source is required and need to= be > compiled > +# firstly, please reference > https://github.com/tianocore/tianocore.github.io/wiki/SourceForge-to-Gith= ub- > Quick-Start > +# to get how to setup build tool. > +# > +# Setup the environment for unix-like systems running a bash-like shell. > +# This file must be "sourced" not merely executed. For example: ". edkse= tup.sh" > +# > +# CYGWIN users: Your path and filename related environment variables sho= uld > be > +# set up in the unix style. This script will make the necessary convers= ions to > +# windows style. > +# > +# Please reference edk2 user manual for more detail descriptions at > https://github.com/tianocore- > docs/Docs/raw/master/User_Docs/EDK_II_UserManual_0_7.pdf > +# > + > +SCRIPTNAME=3D"edksetup.sh" > +RECONFIG=3DFALSE > + > +HelpMsg() > +{ > + echo "Usage: $SCRIPTNAME [Options]" > + echo > + echo "The system environment variable, WORKSPACE, is always set to the > current" > + echo "working directory." > + echo > + echo "Options: " > + echo " --help, -h, -? Print this help screen and exit." > + echo > + echo " --reconfig Overwrite the WORKSPACE/Conf/*.txt files= with the" > + echo " template files from the BaseTools/Conf d= irectory." > + echo > + echo Please note: This script must be \'sourced\' so the environment c= an be > changed. > + echo ". $SCRIPTNAME" > + echo "source $SCRIPTNAME" > +} > + > +SetWorkspace() > +{ > + # > + # If WORKSPACE is already set, then we can return right now > + # > + export PYTHONHASHSEED=3D1 > + if [ -n "$WORKSPACE" ] > + then > + return 0 > + fi > + > + if [ ! -f ${SCRIPTNAME} ] && [ -z "$PACKAGES_PATH" ] > + then > + echo Source this script from the base of your tree. For example: > + echo " cd /Path/To/Edk2/Clone" > + echo " . $SCRIPTNAME" > + return 1 > + fi > + > + # > + # Check for BaseTools/BuildEnv before dirtying the user's environment. > + # > + if [ ! -f BaseTools/BuildEnv ] && [ -z "$EDK_TOOLS_PATH" ] > + then > + echo BaseTools not found in your tree, and EDK_TOOLS_PATH is not set= . > + echo Please point EDK_TOOLS_PATH at the directory that contains > + echo the EDK2 BuildEnv script. > + return 1 > + fi > + > + # > + # Set $WORKSPACE > + # > + export WORKSPACE=3D$PWD > + return 0 > +} > + > +SetupEnv() > +{ > + if [ -n "$EDK_TOOLS_PATH" ] > + then > + . $EDK_TOOLS_PATH/BuildEnv > + elif [ -f "$WORKSPACE/BaseTools/BuildEnv" ] > + then > + . $WORKSPACE/BaseTools/BuildEnv > + elif [ -n "$PACKAGES_PATH" ] > + then > + for DIR in $(echo $PACKAGES_PATH | tr ':' ' ') > + do > + if [ -f "$DIR/BaseTools/BuildEnv" ] > + then > + export EDK_TOOLS_PATH=3D$DIR/BaseTools > + . $DIR/BaseTools/BuildEnv > + break > + fi > + done > + else > + echo BaseTools not found in your tree, and EDK_TOOLS_PATH is not set= . > + echo Please check that WORKSPACE or PACKAGES_PATH is not set incorre= ctly > + echo in your shell, or point EDK_TOOLS_PATH at the directory that co= ntains > + echo the EDK2 BuildEnv script. > + return 1 > + fi > +} > + > +SetupPython3() > +{ > + export PYTHON_COMMAND=3Dpython3 > +} > + > +SourceEnv() > +{ > + SetupPython3 > + SetWorkspace > + SetupEnv > +} > + > +I=3D$# > +while [ $I -gt 0 ] > +do > + case "$1" in > + BaseTools) > + # Ignore argument for backwards compatibility > + shift > + ;; > + --reconfig) > + RECONFIG=3DTRUE > + shift > + ;; > + *) > + HelpMsg > + break > + ;; > + esac > + I=3D$((I - 1)) > +done > + > +if [ $I -gt 0 ] > +then > + return 1 > +fi > + > +SourceEnv > + > +unset SCRIPTNAME RECONFIG > + > +return $? > -- > 2.37.0.windows.1