From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by mx.groups.io with SMTP id smtpd.web12.363.1667974667014491211 for ; Tue, 08 Nov 2022 22:17:47 -0800 Authentication-Results: mx.groups.io; dkim=fail reason="unable to parse pub key" header.i=@intel.com header.s=intel header.b=StcNT2Vf; spf=pass (domain: intel.com, ip: 134.134.136.65, 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=1667974667; x=1699510667; h=from:to:cc:subject:date:message-id:mime-version: content-transfer-encoding; bh=aovG3Avua/OEZB0EhsOIYGgyBSdhk/xwreeNJQ2MOSo=; b=StcNT2Vfwf0k6RrMDCtCEIKkMIxFOxm5sZ5Ab/uJrs0jgHtdrWx/Wvhk nXBglC4riSR6oCrDd4KOHbWw+jh91F4XbcQPNFV+9+7tt+Pa/Djgf+GvM ES9SsQLarLAvZaEEjZyAOTbS43FjCZ956SMKKQGociIJf9vx0z1tiCUJN jQiiSyydz5zltKdElBXynXpQYqt/mhBhYfRYlllTvyFxfzY61sxrMR7a2 uUTA0HViXsT4tJa2We+YshZahVHFIOloANuJRRBAcdTYU/0OMuVv8JGE5 RRu05SumEBAE+p167TahCpcYpDjgmDFtHLEeBfztMSazr0C3Yg+U7+Cuo A==; X-IronPort-AV: E=McAfee;i="6500,9779,10525"; a="312697606" X-IronPort-AV: E=Sophos;i="5.96,149,1665471600"; d="scan'208";a="312697606" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Nov 2022 22:17:46 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6500,9779,10525"; a="700223934" X-IronPort-AV: E=Sophos;i="5.96,149,1665471600"; d="scan'208";a="700223934" Received: from shwdeopenlab606.ccr.corp.intel.com ([10.239.56.26]) by fmsmga008.fm.intel.com with ESMTP; 08 Nov 2022 22:17:43 -0800 From: Hongbin1 Zhang To: devel@edk2.groups.io Cc: Hongbin1 Zhang , Jiewen Yao , Ray Ni , Star Zeng , Sami Mujawar , Ard Biesheuvel , Supreeth Venkatesh Subject: [PATCH v1 1/1] StandaloneMmPkg: Add StandaloneMmIplPei driver. Date: Wed, 9 Nov 2022 14:16:36 +0800 Message-Id: <20221109061636.578-1-hongbin1.zhang@intel.com> X-Mailer: git-send-email 2.26.2.windows.1 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Add StandaloneMmIplPei IA32/X64 driver at PEI stage. FSP will use this driver to load Standalone MM code to dispatch other Standalone MM drivers. Signed-off-by: Hongbin1 Zhang Cc: Jiewen Yao Cc: Ray Ni Cc: Star Zeng Cc: Sami Mujawar Cc: Ard Biesheuvel Cc: Supreeth Venkatesh --- StandaloneMmPkg/Drivers/StandaloneMmIplPei/Ia32/LoadSmmCore.c | 442 ++= ++++++++++ StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c | 726 ++= ++++++++++++++++++ StandaloneMmPkg/Drivers/StandaloneMmIplPei/X64/LoadSmmCore.c | 32 + StandaloneMmPkg/Drivers/StandaloneMmIplPei/Ia32/Thunk32To64.nasm | 148 ++= ++ StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h | 47 ++ StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf | 74 ++ StandaloneMmPkg/StandaloneMmPkg.ci.yaml | 4 +- StandaloneMmPkg/StandaloneMmPkg.dsc | 15 +- 8 files changed, 1485 insertions(+), 3 deletions(-) diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/Ia32/LoadSmmCore.c = b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/Ia32/LoadSmmCore.c new file mode 100644 index 000000000000..0dfb574bd228 --- /dev/null +++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/Ia32/LoadSmmCore.c @@ -0,0 +1,442 @@ +/** @file=0D + SMM IPL that load the SMM Core into SMRAM=0D +=0D + Copyright (c) 2022, Intel Corporation. All rights reserved.
=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D +**/=0D +=0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +=0D +#pragma pack(1)=0D +=0D +//=0D +// Page-Map Level-4 Offset (PML4) and=0D +// Page-Directory-Pointer Offset (PDPE) entries 4K & 2MB=0D +//=0D +=0D +typedef union {=0D + struct {=0D + UINT64 Present : 1; // 0 =3D Not present in memory, = 1 =3D Present in memory=0D + UINT64 ReadWrite : 1; // 0 =3D Read-Only, 1=3D Read/Wr= ite=0D + UINT64 UserSupervisor : 1; // 0 =3D Supervisor, 1=3DUser=0D + UINT64 WriteThrough : 1; // 0 =3D Write-Back caching, 1= =3DWrite-Through caching=0D + UINT64 CacheDisabled : 1; // 0 =3D Cached, 1=3DNon-Cached= =0D + UINT64 Accessed : 1; // 0 =3D Not accessed, 1 =3D Acc= essed (set by CPU)=0D + UINT64 Reserved : 1; // Reserved=0D + UINT64 MustBeZero : 2; // Must Be Zero=0D + UINT64 Available : 3; // Available for use by system s= oftware=0D + UINT64 PageTableBaseAddress : 40; // Page Table Base Address=0D + UINT64 AvailableHigh : 11; // Available for use by system s= oftware=0D + UINT64 Nx : 1; // No Execute bit=0D + } Bits;=0D + UINT64 Uint64;=0D +} PAGE_MAP_AND_DIRECTORY_POINTER;=0D +=0D +//=0D +// Page Table Entry 2MB=0D +//=0D +typedef union {=0D + struct {=0D + UINT64 Present : 1; // 0 =3D Not present in memory, = 1 =3D Present in memory=0D + UINT64 ReadWrite : 1; // 0 =3D Read-Only, 1=3D Read/Wr= ite=0D + UINT64 UserSupervisor : 1; // 0 =3D Supervisor, 1=3DUser=0D + UINT64 WriteThrough : 1; // 0 =3D Write-Back caching, 1= =3DWrite-Through caching=0D + UINT64 CacheDisabled : 1; // 0 =3D Cached, 1=3DNon-Cached= =0D + UINT64 Accessed : 1; // 0 =3D Not accessed, 1 =3D Acc= essed (set by CPU)=0D + UINT64 Dirty : 1; // 0 =3D Not Dirty, 1 =3D writte= n by processor on access to page=0D + UINT64 MustBe1 : 1; // Must be 1=0D + UINT64 Global : 1; // 0 =3D Not global page, 1 =3D = global page TLB not cleared on CR3 write=0D + UINT64 Available : 3; // Available for use by system s= oftware=0D + UINT64 Pat : 1; //=0D + UINT64 MustBeZero : 8; // Must be zero=0D + UINT64 PageTableBaseAddress : 31; // Page Table Base Address=0D + UINT64 AvailableHigh : 11; // Available for use by system s= oftware=0D + UINT64 Nx : 1; // 0 =3D Execute Code, 1 =3D No = Code Execution=0D + } Bits;=0D + UINT64 Uint64;=0D +} PAGE_TABLE_ENTRY;=0D +=0D +//=0D +// Page Table Entry 1GB=0D +//=0D +typedef union {=0D + struct {=0D + UINT64 Present : 1; // 0 =3D Not present in memory, = 1 =3D Present in memory=0D + UINT64 ReadWrite : 1; // 0 =3D Read-Only, 1=3D Read/Wr= ite=0D + UINT64 UserSupervisor : 1; // 0 =3D Supervisor, 1=3DUser=0D + UINT64 WriteThrough : 1; // 0 =3D Write-Back caching, 1= =3DWrite-Through caching=0D + UINT64 CacheDisabled : 1; // 0 =3D Cached, 1=3DNon-Cached= =0D + UINT64 Accessed : 1; // 0 =3D Not accessed, 1 =3D Acc= essed (set by CPU)=0D + UINT64 Dirty : 1; // 0 =3D Not Dirty, 1 =3D writte= n by processor on access to page=0D + UINT64 MustBe1 : 1; // Must be 1=0D + UINT64 Global : 1; // 0 =3D Not global page, 1 =3D = global page TLB not cleared on CR3 write=0D + UINT64 Available : 3; // Available for use by system s= oftware=0D + UINT64 Pat : 1; //=0D + UINT64 MustBeZero : 17; // Must be zero;=0D + UINT64 PageTableBaseAddress : 22; // Page Table Base Address=0D + UINT64 AvailableHigh : 11; // Available for use by system s= oftware=0D + UINT64 Nx : 1; // 0 =3D Execute Code, 1 =3D No = Code Execution=0D + } Bits;=0D + UINT64 Uint64;=0D +} PAGE_TABLE_1G_ENTRY;=0D +=0D +#pragma pack()=0D +=0D +//=0D +// Global Descriptor Table (GDT)=0D +//=0D +GLOBAL_REMOVE_IF_UNREFERENCED IA32_SEGMENT_DESCRIPTOR mGdtEntries[] =3D {= =0D + /* selector { Global Segment Descriptor } *= /=0D + /* 0x00 */ {=0D + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }=0D + }, = // null descriptor=0D + /* 0x08 */ {=0D + { 0xffff, 0, 0, 0x3, 1, 0, 1, 0xf, 0, 0, 1, 1, 0 }=0D + }, = // linear data segment descriptor=0D + /* 0x10 */ {=0D + { 0xffff, 0, 0, 0xf, 1, 0, 1, 0xf, 0, 0, 1, 1, 0 }=0D + }, = // linear code segment descriptor=0D + /* 0x18 */ {=0D + { 0xffff, 0, 0, 0x3, 1, 0, 1, 0xf, 0, 0, 1, 1, 0 }=0D + }, = // system data segment descriptor=0D + /* 0x20 */ {=0D + { 0xffff, 0, 0, 0xb, 1, 0, 1, 0xf, 0, 0, 1, 1, 0 }=0D + }, = // system code segment descriptor=0D + /* 0x28 */ {=0D + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }=0D + }, = // spare segment descriptor=0D + /* 0x30 */ {=0D + { 0xffff, 0, 0, 0x3, 1, 0, 1, 0xf, 0, 0, 1, 1, 0 }=0D + }, = // system data segment descriptor=0D + /* 0x38 */ {=0D + { 0xffff, 0, 0, 0xb, 1, 0, 1, 0xf, 0, 1, 0, 1, 0 }=0D + }, = // system code segment descriptor=0D + /* 0x40 */ {=0D + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }=0D + }, = // spare segment descriptor=0D +};=0D +=0D +//=0D +// IA32 Gdt register=0D +//=0D +GLOBAL_REMOVE_IF_UNREFERENCED CONST IA32_DESCRIPTOR mGdt =3D {=0D + sizeof (mGdtEntries) - 1,=0D + (UINTN)mGdtEntries=0D +};=0D +=0D +/**=0D + Calculate the total size of page table.=0D +=0D + @return The size of page table.=0D +=0D +**/=0D +UINTN=0D +CalculatePageTableSize (=0D + VOID=0D + )=0D +{=0D + UINT32 RegEax;=0D + UINT32 RegEdx;=0D + UINTN TotalPagesNum;=0D + UINT8 PhysicalAddressBits;=0D + VOID *Hob;=0D + UINT32 NumberOfPml4EntriesNeeded;=0D + UINT32 NumberOfPdpEntriesNeeded;=0D + BOOLEAN Page1GSupport;=0D +=0D + Page1GSupport =3D FALSE;=0D + if (PcdGetBool (PcdUse1GPageTable)) {=0D + AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);=0D + if (RegEax >=3D 0x80000001) {=0D + AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx);=0D + if ((RegEdx & BIT26) !=3D 0) {=0D + Page1GSupport =3D TRUE;=0D + }=0D + }=0D + }=0D +=0D + //=0D + // Get physical address bits supported.=0D + //=0D + Hob =3D GetFirstHob (EFI_HOB_TYPE_CPU);=0D + if (Hob !=3D NULL) {=0D + PhysicalAddressBits =3D ((EFI_HOB_CPU *)Hob)->SizeOfMemorySpace;=0D + } else {=0D + AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);=0D + if (RegEax >=3D 0x80000008) {=0D + AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);=0D + PhysicalAddressBits =3D (UINT8)RegEax;=0D + } else {=0D + PhysicalAddressBits =3D 36;=0D + }=0D + }=0D +=0D + //=0D + // IA-32e paging translates 48-bit linear addresses to 52-bit physical a= ddresses.=0D + //=0D + ASSERT (PhysicalAddressBits <=3D 52);=0D + if (PhysicalAddressBits > 48) {=0D + PhysicalAddressBits =3D 48;=0D + }=0D +=0D + //=0D + // Calculate the table entries needed.=0D + //=0D + if (PhysicalAddressBits <=3D 39 ) {=0D + NumberOfPml4EntriesNeeded =3D 1;=0D + NumberOfPdpEntriesNeeded =3D (UINT32)LShiftU64 (1, (PhysicalAddressBi= ts - 30));=0D + } else {=0D + NumberOfPml4EntriesNeeded =3D (UINT32)LShiftU64 (1, (PhysicalAddressBi= ts - 39));=0D + NumberOfPdpEntriesNeeded =3D 512;=0D + }=0D +=0D + if (!Page1GSupport) {=0D + TotalPagesNum =3D (NumberOfPdpEntriesNeeded + 1) * NumberOfPml4Entries= Needed + 1;=0D + } else {=0D + TotalPagesNum =3D NumberOfPml4EntriesNeeded + 1;=0D + }=0D +=0D + return EFI_PAGES_TO_SIZE (TotalPagesNum);=0D +}=0D +=0D +/**=0D + Allocates and fills in the Page Directory and Page Table Entries to=0D + establish a 1:1 Virtual to Physical mapping.=0D +=0D + @param[in] PageTablesAddress The base address of page table.=0D +=0D +**/=0D +VOID=0D +CreateIdentityMappingPageTables (=0D + IN EFI_PHYSICAL_ADDRESS PageTablesAddress=0D + )=0D +{=0D + UINT32 RegEax;=0D + UINT32 RegEdx;=0D + UINT8 PhysicalAddressBits;=0D + EFI_PHYSICAL_ADDRESS PageAddress;=0D + UINTN IndexOfPml4Entries;=0D + UINTN IndexOfPdpEntries;=0D + UINTN IndexOfPageDirectoryEntries;=0D + UINT32 NumberOfPml4EntriesNeeded;=0D + UINT32 NumberOfPdpEntriesNeeded;=0D + PAGE_MAP_AND_DIRECTORY_POINTER *PageMapLevel4Entry;=0D + PAGE_MAP_AND_DIRECTORY_POINTER *PageMap;=0D + PAGE_MAP_AND_DIRECTORY_POINTER *PageDirectoryPointerEntry;=0D + PAGE_TABLE_ENTRY *PageDirectoryEntry;=0D + UINTN BigPageAddress;=0D + VOID *Hob;=0D + BOOLEAN Page1GSupport;=0D + PAGE_TABLE_1G_ENTRY *PageDirectory1GEntry;=0D +=0D + Page1GSupport =3D FALSE;=0D + AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);=0D + if (RegEax >=3D 0x80000001) {=0D + AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx);=0D + if ((RegEdx & BIT26) !=3D 0) {=0D + Page1GSupport =3D TRUE;=0D + }=0D + }=0D +=0D + //=0D + // Get physical address bits supported.=0D + //=0D + Hob =3D GetFirstHob (EFI_HOB_TYPE_CPU);=0D + if (Hob !=3D NULL) {=0D + PhysicalAddressBits =3D ((EFI_HOB_CPU *)Hob)->SizeOfMemorySpace;=0D + } else {=0D + AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);=0D + if (RegEax >=3D 0x80000008) {=0D + AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);=0D + PhysicalAddressBits =3D (UINT8)RegEax;=0D + } else {=0D + PhysicalAddressBits =3D 36;=0D + }=0D + }=0D +=0D + //=0D + // IA-32e paging translates 48-bit linear addresses to 52-bit physical a= ddresses.=0D + //=0D + ASSERT (PhysicalAddressBits <=3D 52);=0D + if (PhysicalAddressBits > 48) {=0D + PhysicalAddressBits =3D 48;=0D + }=0D +=0D + //=0D + // Calculate the table entries needed.=0D + //=0D + if (PhysicalAddressBits <=3D 39 ) {=0D + NumberOfPml4EntriesNeeded =3D 1;=0D + NumberOfPdpEntriesNeeded =3D (UINT32)LShiftU64 (1, (PhysicalAddressBi= ts - 30));=0D + } else {=0D + NumberOfPml4EntriesNeeded =3D (UINT32)LShiftU64 (1, (PhysicalAddressBi= ts - 39));=0D + NumberOfPdpEntriesNeeded =3D 512;=0D + }=0D +=0D + //=0D + // Pre-allocate big pages to avoid later allocations.=0D + //=0D + BigPageAddress =3D (UINTN)PageTablesAddress;=0D +=0D + //=0D + // By architecture only one PageMapLevel4 exists - so lets allocate stor= age for it.=0D + //=0D + PageMap =3D (VOID *)BigPageAddress;=0D + BigPageAddress +=3D SIZE_4KB;=0D +=0D + PageMapLevel4Entry =3D PageMap;=0D + PageAddress =3D 0;=0D + for (IndexOfPml4Entries =3D 0; IndexOfPml4Entries < NumberOfPml4EntriesN= eeded; IndexOfPml4Entries++, PageMapLevel4Entry++) {=0D + //=0D + // Each PML4 entry points to a page of Page Directory Pointer entires.= =0D + // So lets allocate space for them and fill them in in the IndexOfPdpE= ntries loop.=0D + //=0D + PageDirectoryPointerEntry =3D (VOID *)BigPageAddress;=0D + BigPageAddress +=3D SIZE_4KB;=0D +=0D + //=0D + // Make a PML4 Entry=0D + //=0D + PageMapLevel4Entry->Uint64 =3D (UINT64)(UINTN)PageDirectoryPoi= nterEntry;=0D + PageMapLevel4Entry->Bits.ReadWrite =3D 1;=0D + PageMapLevel4Entry->Bits.Present =3D 1;=0D +=0D + if (Page1GSupport) {=0D + PageDirectory1GEntry =3D (VOID *)PageDirectoryPointerEntry;=0D +=0D + for (IndexOfPageDirectoryEntries =3D 0; IndexOfPageDirectoryEntries = < 512; IndexOfPageDirectoryEntries++, PageDirectory1GEntry++, PageAddress += =3D SIZE_1GB) {=0D + //=0D + // Fill in the Page Directory entries=0D + //=0D + PageDirectory1GEntry->Uint64 =3D (UINT64)PageAddress;=0D + PageDirectory1GEntry->Bits.ReadWrite =3D 1;=0D + PageDirectory1GEntry->Bits.Present =3D 1;=0D + PageDirectory1GEntry->Bits.MustBe1 =3D 1;=0D + }=0D + } else {=0D + for (IndexOfPdpEntries =3D 0; IndexOfPdpEntries < NumberOfPdpEntries= Needed; IndexOfPdpEntries++, PageDirectoryPointerEntry++) {=0D + //=0D + // Each Directory Pointer entries points to a page of Page Directo= ry entires.=0D + // So allocate space for them and fill them in in the IndexOfPageD= irectoryEntries loop.=0D + //=0D + PageDirectoryEntry =3D (VOID *)BigPageAddress;=0D + BigPageAddress +=3D SIZE_4KB;=0D +=0D + //=0D + // Fill in a Page Directory Pointer Entries=0D + //=0D + PageDirectoryPointerEntry->Uint64 =3D (UINT64)(UINTN)PageD= irectoryEntry;=0D + PageDirectoryPointerEntry->Bits.ReadWrite =3D 1;=0D + PageDirectoryPointerEntry->Bits.Present =3D 1;=0D +=0D + for (IndexOfPageDirectoryEntries =3D 0; IndexOfPageDirectoryEntrie= s < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PageAddress += =3D SIZE_2MB) {=0D + //=0D + // Fill in the Page Directory entries=0D + //=0D + PageDirectoryEntry->Uint64 =3D (UINT64)PageAddress;=0D + PageDirectoryEntry->Bits.ReadWrite =3D 1;=0D + PageDirectoryEntry->Bits.Present =3D 1;=0D + PageDirectoryEntry->Bits.MustBe1 =3D 1;=0D + }=0D + }=0D +=0D + for ( ; IndexOfPdpEntries < 512; IndexOfPdpEntries++, PageDirectoryP= ointerEntry++) {=0D + ZeroMem (=0D + PageDirectoryPointerEntry,=0D + sizeof (PAGE_MAP_AND_DIRECTORY_POINTER)=0D + );=0D + }=0D + }=0D + }=0D +=0D + //=0D + // For the PML4 entries we are not using fill in a null entry.=0D + //=0D + for ( ; IndexOfPml4Entries < 512; IndexOfPml4Entries++, PageMapLevel4Ent= ry++) {=0D + ZeroMem (=0D + PageMapLevel4Entry,=0D + sizeof (PAGE_MAP_AND_DIRECTORY_POINTER)=0D + );=0D + }=0D +}=0D +=0D +/**=0D + If in 32 bit protection mode, and coalesce image is of X64, switch to lo= ng mode.=0D +=0D + @param Entry Entry of Standalone MM Foundation.=0D + @param Context1 A pointer to the context to pass into = the EntryPoint=0D + function.=0D + @param Context2 A pointer to the context to pass into = the EntryPoint=0D + function.=0D + @retval EFI_SUCCESS Successfully switched to long mode and= execute coalesce.=0D + @retval Others Failed to execute coalesce in long mod= e.=0D +=0D +**/=0D +EFI_STATUS=0D +ModeSwitch (=0D + IN EFI_PHYSICAL_ADDRESS Entry,=0D + IN VOID *Context1,=0D + IN VOID *Context2=0D + )=0D +{=0D + UINTN PageTableAddress;=0D + UINTN PageTableSize;=0D + EFI_STATUS Status;=0D +=0D + DEBUG ((DEBUG_INFO, "ModeSwitch\n"));=0D +=0D + PageTableSize =3D CalculatePageTableSize ();=0D +=0D + PageTableAddress =3D (UINTN)AllocatePages (EFI_SIZE_TO_PAGES (PageTableS= ize));=0D + ASSERT (PageTableAddress !=3D 0);=0D +=0D + CreateIdentityMappingPageTables (PageTableAddress);=0D +=0D + AsmWriteGdtr (&mGdt);=0D +=0D + AsmWriteCr3 ((UINTN)PageTableAddress);=0D +=0D + DEBUG ((DEBUG_INFO, "AsmExecute64BitCode ...\n"));=0D +=0D + Status =3D AsmExecute64BitCode (Entry, (UINT64)(UINTN)Context1, (UINT64)= (UINTN)Context2, NULL);=0D + if (Status !=3D 0) {=0D + Status =3D Status | MAX_BIT;=0D + }=0D +=0D + DEBUG ((DEBUG_INFO, "AsmExecute64BitCode - %r\n", Status));=0D +=0D + return Status;=0D +}=0D +=0D +/**=0D + Load SMM core to dispatch other Standalone MM drivers.=0D +=0D + @param Entry Entry of Standalone MM Foundation.=0D + @param Context1 A pointer to the context to pass into = the EntryPoint=0D + function.=0D + @retval EFI_SUCCESS Successfully loaded SMM core.=0D + @retval Others Failed to load SMM core.=0D +**/=0D +EFI_STATUS=0D +LoadSmmCore (=0D + IN EFI_PHYSICAL_ADDRESS Entry,=0D + IN VOID *Context1=0D + )=0D +{=0D + STANDALONE_MM_FOUNDATION_ENTRY_POINT EntryPoint;=0D +=0D + if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {=0D + return ModeSwitch (Entry, Context1, NULL);=0D + }=0D +=0D + EntryPoint =3D (STANDALONE_MM_FOUNDATION_ENTRY_POINT)(UINTN)Entry;=0D + return EntryPoint (Context1);=0D +}=0D diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.= c b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c new file mode 100644 index 000000000000..e1ac6a2b3119 --- /dev/null +++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c @@ -0,0 +1,726 @@ +/** @file=0D + SMM IPL that load the SMM Core into SMRAM at PEI stage=0D +=0D + Copyright (c) 2022, Intel Corporation. All rights reserved.
=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D +**/=0D +=0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +=0D +//=0D +// MM Core Private Data structure that contains the data shared between=0D +// the SMM IPL and the Standalone MM Core.=0D +//=0D +MM_CORE_PRIVATE_DATA mMmCorePrivateData =3D {=0D + MM_CORE_PRIVATE_DATA_SIGNATURE, // Signature=0D + 0, // MmramRangeCount=0D + 0, // MmramRanges=0D + 0, // MmEntryPoint=0D + FALSE, // MmEntryPointRegistered=0D + FALSE, // InMm=0D + 0, // Mmst=0D + 0, // CommunicationBuffer=0D + 0, // BufferSize=0D + EFI_SUCCESS, // ReturnStatus=0D + 0, // MmCoreImageBase=0D + 0, // MmCoreImageSize=0D + 0, // MmCoreEntryPoint=0D + 0, // StandaloneBfvAddress=0D +};=0D +=0D +//=0D +// Global pointer used to access mMmCorePrivateData from outside and insid= e SMM=0D +//=0D +MM_CORE_PRIVATE_DATA *gMmCorePrivate;=0D +=0D +//=0D +// SMM IPL global variables=0D +//=0D +PEI_SMM_ACCESS_PPI *mSmmAccess;=0D +EFI_SMRAM_DESCRIPTOR *mCurrentSmramRange;=0D +BOOLEAN mSmmLocked =3D FALSE;=0D +EFI_PHYSICAL_ADDRESS mSmramCacheBase;=0D +UINT64 mSmramCacheSize;=0D +=0D +/**=0D + Find the maximum SMRAM cache range that covers the range specified by Sm= ramRange.=0D +=0D + This function searches and joins all adjacent ranges of SmramRange into = a range to be cached.=0D +=0D + @param SmramRange The SMRAM range to search from.=0D + @param SmramCacheBase The returned cache range base.=0D + @param SmramCacheSize The returned cache range size.=0D +=0D +**/=0D +VOID=0D +GetSmramCacheRange (=0D + IN EFI_SMRAM_DESCRIPTOR *SmramRange,=0D + OUT EFI_PHYSICAL_ADDRESS *SmramCacheBase,=0D + OUT UINT64 *SmramCacheSize=0D + )=0D +{=0D + UINTN Index;=0D + EFI_PHYSICAL_ADDRESS RangeCpuStart;=0D + UINT64 RangePhysicalSize;=0D + BOOLEAN FoundAdjacentRange;=0D + EFI_SMRAM_DESCRIPTOR *SmramRanges;=0D +=0D + *SmramCacheBase =3D SmramRange->CpuStart;=0D + *SmramCacheSize =3D SmramRange->PhysicalSize;=0D +=0D + SmramRanges =3D (EFI_SMRAM_DESCRIPTOR *)(UINTN)gMmCorePrivate->MmramRang= es;=0D + do {=0D + FoundAdjacentRange =3D FALSE;=0D + for (Index =3D 0; Index < gMmCorePrivate->MmramRangeCount; Index++) {= =0D + RangeCpuStart =3D SmramRanges[Index].CpuStart;=0D + RangePhysicalSize =3D SmramRanges[Index].PhysicalSize;=0D + if ((RangeCpuStart < *SmramCacheBase) && (*SmramCacheBase =3D=3D (Ra= ngeCpuStart + RangePhysicalSize))) {=0D + *SmramCacheBase =3D RangeCpuStart;=0D + *SmramCacheSize +=3D RangePhysicalSize;=0D + FoundAdjacentRange =3D TRUE;=0D + } else if (((*SmramCacheBase + *SmramCacheSize) =3D=3D RangeCpuStart= ) && (RangePhysicalSize > 0)) {=0D + *SmramCacheSize +=3D RangePhysicalSize;=0D + FoundAdjacentRange =3D TRUE;=0D + }=0D + }=0D + } while (FoundAdjacentRange);=0D +}=0D +=0D +/**=0D + Get the fixed loading address from image header assigned by build tool. = This function only be called=0D + when Loading module at Fixed address feature enabled.=0D +=0D + @param ImageContext Pointer to the image context structure= that describes the PE/COFF=0D + image that needs to be examined by thi= s function.=0D + @retval EFI_SUCCESS An fixed loading address is assigned t= o this image by build tools .=0D + @retval EFI_NOT_FOUND The image has no assigned fixed loadin= g address.=0D +**/=0D +EFI_STATUS=0D +GetPeCoffImageFixLoadingAssignedAddress (=0D + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext=0D + )=0D +{=0D + UINTN SectionHeaderOffset;=0D + EFI_STATUS Status;=0D + EFI_IMAGE_SECTION_HEADER SectionHeader;=0D + EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr;=0D + EFI_PHYSICAL_ADDRESS FixLoadingAddress;=0D + UINT16 Index;=0D + UINTN Size;=0D + UINT16 NumberOfSections;=0D + EFI_PHYSICAL_ADDRESS SmramBase;=0D + UINT64 SmmCodeSize;=0D + UINT64 ValueInSectionHeader;=0D +=0D + //=0D + // Build tool will calculate the smm code size and then patch the PcdLoa= dFixAddressSmmCodePageNumber=0D + //=0D + SmmCodeSize =3D EFI_PAGES_TO_SIZE (PcdGet32 (PcdLoadFixAddressSmmC= odePageNumber));=0D + FixLoadingAddress =3D 0;=0D + Status =3D EFI_NOT_FOUND;=0D + SmramBase =3D mCurrentSmramRange->CpuStart;=0D + //=0D + // Get PeHeader pointer=0D + //=0D + ImgHdr =3D (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((CHAR8 *)Ima= geContext->Handle + ImageContext->PeCoffHeaderOffset);=0D + SectionHeaderOffset =3D (UINTN)(=0D + ImageContext->PeCoffHeaderOffset +=0D + sizeof (UINT32) +=0D + sizeof (EFI_IMAGE_FILE_HEADER) +=0D + ImgHdr->Pe32.FileHeader.SizeOfOptionalHead= er=0D + );=0D + NumberOfSections =3D ImgHdr->Pe32.FileHeader.NumberOfSections;=0D +=0D + //=0D + // Get base address from the first section header that doesn't point to = code section.=0D + //=0D + for (Index =3D 0; Index < NumberOfSections; Index++) {=0D + //=0D + // Read section header from file=0D + //=0D + Size =3D sizeof (EFI_IMAGE_SECTION_HEADER);=0D + Status =3D ImageContext->ImageRead (=0D + ImageContext->Handle,=0D + SectionHeaderOffset,=0D + &Size,=0D + &SectionHeader=0D + );=0D + if (EFI_ERROR (Status)) {=0D + return Status;=0D + }=0D +=0D + Status =3D EFI_NOT_FOUND;=0D +=0D + if ((SectionHeader.Characteristics & EFI_IMAGE_SCN_CNT_CODE) =3D=3D 0)= {=0D + //=0D + // Build tool saves the offset to SMRAM base as image base in Pointe= rToRelocations & PointerToLineNumbers fields in the=0D + // first section header that doesn't point to code section in image = header. And there is an assumption that when the=0D + // feature is enabled, if a module is assigned a loading address by = tools, PointerToRelocations & PointerToLineNumbers=0D + // fields should NOT be Zero, or else, these 2 fields should be set = to Zero=0D + //=0D + ValueInSectionHeader =3D ReadUnaligned64 ((UINT64 *)&SectionHeader.P= ointerToRelocations);=0D + if (ValueInSectionHeader !=3D 0) {=0D + //=0D + // Found first section header that doesn't point to code section i= n which build tool saves the=0D + // offset to SMRAM base as image base in PointerToRelocations & Po= interToLineNumbers fields=0D + //=0D + FixLoadingAddress =3D (EFI_PHYSICAL_ADDRESS)(SmramBase + (INT64)Va= lueInSectionHeader);=0D +=0D + if ((SmramBase + SmmCodeSize > FixLoadingAddress) && (SmramBase <= =3D FixLoadingAddress)) {=0D + //=0D + // The assigned address is valid. Return the specified loading a= ddress=0D + //=0D + ImageContext->ImageAddress =3D FixLoadingAddress;=0D + Status =3D EFI_SUCCESS;=0D + }=0D + }=0D +=0D + break;=0D + }=0D +=0D + SectionHeaderOffset +=3D sizeof (EFI_IMAGE_SECTION_HEADER);=0D + }=0D +=0D + DEBUG ((DEBUG_INFO|DEBUG_LOAD, "LOADING MODULE FIXED INFO: Loading modul= e at fixed address %x, Status =3D %r \n", FixLoadingAddress, Status));=0D + return Status;=0D +}=0D +=0D +/**=0D + Searches all the available firmware volumes and returns the first matchi= ng FFS section.=0D +=0D + This function searches all the firmware volumes for FFS files with FV fi= le type specified by FileType=0D + The order that the firmware volumes is searched is not deterministic. Fo= r each available FV a search=0D + is made for FFS file of type FileType. If the FV contains more than one = FFS file with the same FileType,=0D + the FileInstance instance will be the matched FFS file. For each FFS fil= e found a search=0D + is made for FFS sections of type SectionType. If the FFS file contains a= t least SectionInstance instances=0D + of the FFS section specified by SectionType, then the SectionInstance in= stance is returned in Buffer.=0D + Buffer is allocated using AllocatePool(), and the size of the allocated = buffer is returned in Size.=0D + It is the caller's responsibility to use FreePool() to free the allocate= d buffer.=0D +=0D + If Buffer is NULL, then ASSERT().=0D + If Size is NULL, then ASSERT().=0D +=0D + @param FileType Indicates the FV file type to search for wi= thin all available FVs.=0D + @param FileInstance Indicates which file instance within all av= ailable FVs specified by FileType.=0D + FileInstance starts from zero.=0D + @param SectionType Indicates the FFS section type to search fo= r within the FFS file=0D + specified by FileType with FileInstance.=0D + @param SectionInstance Indicates which section instance within the= FFS file=0D + specified by FileType with FileInstance to = retrieve. SectionInstance starts from zero.=0D + @param Buffer On output, a pointer to a callee allocated = buffer containing the FFS file section that was found.=0D + Is it the caller's responsibility to free t= his buffer using FreePool().=0D + @param Size On output, a pointer to the size, in bytes,= of Buffer.=0D +=0D + @retval EFI_SUCCESS The specified FFS section was returned.=0D + @retval EFI_NOT_FOUND The specified FFS section could not be fou= nd.=0D + @retval EFI_OUT_OF_RESOURCES There are not enough resources available t= o retrieve the matching FFS section.=0D +=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +GetSectionFromAnyFvByFileType (=0D + IN EFI_FV_FILETYPE FileType,=0D + IN UINTN FileInstance,=0D + IN EFI_SECTION_TYPE SectionType,=0D + IN UINTN SectionInstance,=0D + OUT VOID **Buffer,=0D + OUT UINTN *Size=0D + )=0D +{=0D + EFI_STATUS Status;=0D + UINTN FvIndex;=0D + EFI_PEI_FV_HANDLE VolumeHandle;=0D + EFI_PEI_FILE_HANDLE FileHandle;=0D + EFI_PE32_SECTION *SectionData;=0D + UINT32 SectionSize;=0D +=0D + //=0D + // Search all FV=0D + //=0D + VolumeHandle =3D NULL;=0D + for (FvIndex =3D 0; ; FvIndex++) {=0D + Status =3D PeiServicesFfsFindNextVolume (FvIndex, &VolumeHandle);=0D + if (EFI_ERROR (Status)) {=0D + break;=0D + }=0D +=0D + //=0D + // Search PEIM FFS=0D + //=0D + FileHandle =3D NULL;=0D + Status =3D PeiServicesFfsFindNextFile (FileType, VolumeHandle, &Fi= leHandle);=0D + if (EFI_ERROR (Status)) {=0D + continue;=0D + }=0D +=0D + //=0D + // Search Section=0D + //=0D + SectionData =3D NULL;=0D + Status =3D PeiServicesFfsFindSectionData (SectionType, FileHandle= , Buffer);=0D + if (EFI_ERROR (Status)) {=0D + continue;=0D + }=0D +=0D + //=0D + // Great!=0D + //=0D + SectionData =3D (EFI_PE32_SECTION *)((UINT8 *)*Buffer - sizeof (EFI_PE= 32_SECTION));=0D + ASSERT (SectionData->Type =3D=3D SectionType);=0D + SectionSize =3D *(UINT32 *)SectionData->Size;=0D + SectionSize &=3D 0xFFFFFF;=0D + *Size =3D SectionSize - sizeof (EFI_PE32_SECTION);=0D +=0D + if (FileType =3D=3D EFI_FV_FILETYPE_MM_CORE_STANDALONE) {=0D + EFI_FV_INFO VolumeInfo;=0D + //=0D + // This is SMM BFV=0D + //=0D + Status =3D PeiServicesFfsGetVolumeInfo (VolumeHandle, &VolumeInfo);= =0D + if (!EFI_ERROR (Status)) {=0D + gMmCorePrivate->StandaloneBfvAddress =3D (EFI_PHYSICAL_ADDRESS)(UI= NTN)VolumeInfo.FvStart;=0D + }=0D + }=0D +=0D + return EFI_SUCCESS;=0D + }=0D +=0D + return EFI_NOT_FOUND;=0D +}=0D +=0D +/**=0D + Load the SMM Core image into SMRAM and executes the SMM Core from SMRAM.= =0D +=0D + @param[in, out] SmramRange Descriptor for the range of SMRAM = to reload the=0D + currently executing image, the ran= g of SMRAM to=0D + hold SMM Core will be excluded.=0D + @param[in, out] SmramRangeSmmCore Descriptor for the range of SMRAM = to hold SMM Core.=0D +=0D + @param[in] Context Context to pass into SMM Core=0D +=0D + @return EFI_STATUS=0D +=0D +**/=0D +EFI_STATUS=0D +ExecuteSmmCoreFromSmram (=0D + IN OUT EFI_SMRAM_DESCRIPTOR *SmramRange,=0D + IN OUT EFI_SMRAM_DESCRIPTOR *SmramRangeSmmCore,=0D + IN VOID *Context=0D + )=0D +{=0D + EFI_STATUS Status;=0D + VOID *SourceBuffer;=0D + UINTN SourceSize;=0D + PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;=0D + UINTN PageCount;=0D + VOID *HobList;=0D +=0D + Status =3D PeiServicesGetHobList (&HobList);=0D + ASSERT_EFI_ERROR (Status);=0D +=0D + //=0D + // Search all Firmware Volumes for a PE/COFF image in a file of type SMM= _CORE=0D + //=0D + Status =3D GetSectionFromAnyFvByFileType (=0D + EFI_FV_FILETYPE_MM_CORE_STANDALONE,=0D + 0,=0D + EFI_SECTION_PE32,=0D + 0,=0D + &SourceBuffer,=0D + &SourceSize=0D + );=0D + if (EFI_ERROR (Status)) {=0D + return Status;=0D + }=0D +=0D + //=0D + // Initialize ImageContext=0D + //=0D + ImageContext.Handle =3D SourceBuffer;=0D + ImageContext.ImageRead =3D PeCoffLoaderImageReadFromMemory;=0D +=0D + //=0D + // Get information about the image being loaded=0D + //=0D + Status =3D PeCoffLoaderGetImageInfo (&ImageContext);=0D + if (EFI_ERROR (Status)) {=0D + return Status;=0D + }=0D +=0D + //=0D + // if Loading module at Fixed Address feature is enabled, the SMM core d= river will be loaded to=0D + // the address assigned by build tool.=0D + //=0D + if (PcdGet64 (PcdLoadModuleAtFixAddressEnable) !=3D 0) {=0D + //=0D + // Get the fixed loading address assigned by Build tool=0D + //=0D + Status =3D GetPeCoffImageFixLoadingAssignedAddress (&ImageContext);=0D + if (!EFI_ERROR (Status)) {=0D + //=0D + // Since the memory range to load SMM CORE will be cut out in SMM co= re, so no need to allocate and free this range=0D + //=0D + PageCount =3D 0;=0D + //=0D + // Reserved Smram Region for SmmCore is not used, and remove it from= SmramRangeCount.=0D + //=0D + gMmCorePrivate->MmramRangeCount--;=0D + } else {=0D + DEBUG ((DEBUG_INFO, "LOADING MODULE FIXED ERROR: Loading module at f= ixed address at address failed\n"));=0D + //=0D + // Allocate memory for the image being loaded from the EFI_SRAM_DESC= RIPTOR=0D + // specified by SmramRange=0D + //=0D + PageCount =3D (UINTN)EFI_SIZE_TO_PAGES ((UINTN)ImageContext.ImageSiz= e + ImageContext.SectionAlignment);=0D +=0D + ASSERT ((SmramRange->PhysicalSize & EFI_PAGE_MASK) =3D=3D 0);=0D + ASSERT (SmramRange->PhysicalSize > EFI_PAGES_TO_SIZE (PageCount));=0D +=0D + SmramRange->PhysicalSize -=3D EFI_PAGES_TO_SIZE (PageCount);= =0D + SmramRangeSmmCore->CpuStart =3D SmramRange->CpuStart + SmramRan= ge->PhysicalSize;=0D + SmramRangeSmmCore->PhysicalStart =3D SmramRange->PhysicalStart + Smr= amRange->PhysicalSize;=0D + SmramRangeSmmCore->RegionState =3D SmramRange->RegionState | EFI_A= LLOCATED;=0D + SmramRangeSmmCore->PhysicalSize =3D EFI_PAGES_TO_SIZE (PageCount);= =0D +=0D + //=0D + // Align buffer on section boundary=0D + //=0D + ImageContext.ImageAddress =3D SmramRangeSmmCore->CpuStart;=0D + }=0D + } else {=0D + //=0D + // Allocate memory for the image being loaded from the EFI_SRAM_DESCRI= PTOR=0D + // specified by SmramRange=0D + //=0D + PageCount =3D (UINTN)EFI_SIZE_TO_PAGES ((UINTN)ImageContext.ImageSize = + ImageContext.SectionAlignment);=0D +=0D + ASSERT ((SmramRange->PhysicalSize & EFI_PAGE_MASK) =3D=3D 0);=0D + ASSERT (SmramRange->PhysicalSize > EFI_PAGES_TO_SIZE (PageCount));=0D +=0D + SmramRange->PhysicalSize -=3D EFI_PAGES_TO_SIZE (PageCount);=0D + SmramRangeSmmCore->CpuStart =3D SmramRange->CpuStart + SmramRange= ->PhysicalSize;=0D + SmramRangeSmmCore->PhysicalStart =3D SmramRange->PhysicalStart + Smram= Range->PhysicalSize;=0D + SmramRangeSmmCore->RegionState =3D SmramRange->RegionState | EFI_ALL= OCATED;=0D + SmramRangeSmmCore->PhysicalSize =3D EFI_PAGES_TO_SIZE (PageCount);=0D +=0D + //=0D + // Align buffer on section boundary=0D + //=0D + ImageContext.ImageAddress =3D SmramRangeSmmCore->CpuStart;=0D + }=0D +=0D + ImageContext.ImageAddress +=3D ImageContext.SectionAlignment - 1;=0D + ImageContext.ImageAddress &=3D ~((EFI_PHYSICAL_ADDRESS)ImageContext.Sect= ionAlignment - 1);=0D +=0D + //=0D + // Print debug message showing SMM Core load address.=0D + //=0D + DEBUG ((DEBUG_INFO, "SMM IPL loading SMM Core at SMRAM address %p\n", (V= OID *)(UINTN)ImageContext.ImageAddress));=0D +=0D + //=0D + // Load the image to our new buffer=0D + //=0D + Status =3D PeCoffLoaderLoadImage (&ImageContext);=0D + if (!EFI_ERROR (Status)) {=0D + //=0D + // Relocate the image in our new buffer=0D + //=0D + Status =3D PeCoffLoaderRelocateImage (&ImageContext);=0D + if (!EFI_ERROR (Status)) {=0D + //=0D + // Flush the instruction cache so the image data are written before = we execute it=0D + //=0D + InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAd= dress, (UINTN)ImageContext.ImageSize);=0D +=0D + //=0D + // Print debug message showing SMM Core entry point address.=0D + //=0D + DEBUG ((DEBUG_INFO, "SMM IPL calling SMM Core at SMRAM address %p\n"= , (VOID *)(UINTN)ImageContext.EntryPoint));=0D +=0D + gMmCorePrivate->MmCoreImageBase =3D ImageContext.ImageAddress;=0D + gMmCorePrivate->MmCoreImageSize =3D ImageContext.ImageSize;=0D + DEBUG ((DEBUG_INFO, "SmmCoreImageBase - 0x%016lx\n", gMmCorePrivate-= >MmCoreImageBase));=0D + DEBUG ((DEBUG_INFO, "SmmCoreImageSize - 0x%016lx\n", gMmCorePrivate-= >MmCoreImageSize));=0D +=0D + gMmCorePrivate->MmCoreEntryPoint =3D ImageContext.EntryPoint;=0D +=0D + //=0D + // Print debug message showing Standalone MM Core entry point addres= s.=0D + //=0D + DEBUG ((DEBUG_INFO, "SMM IPL calling Standalone MM Core at SMRAM add= ress - 0x%016lx\n", gMmCorePrivate->MmCoreEntryPoint));=0D +=0D + //=0D + // Execute image=0D + //=0D + LoadSmmCore (ImageContext.EntryPoint, HobList);=0D + }=0D + }=0D +=0D + //=0D + // If the load operation, relocate operation, or the image execution ret= urn an=0D + // error, then free memory allocated from the EFI_SRAM_DESCRIPTOR specif= ied by=0D + // SmramRange=0D + //=0D + if (EFI_ERROR (Status)) {=0D + SmramRange->PhysicalSize +=3D EFI_PAGES_TO_SIZE (PageCount);=0D + }=0D +=0D + //=0D + // Always free memory allocated by GetFileBufferByFilePath ()=0D + //=0D + FreePool (SourceBuffer);=0D +=0D + return Status;=0D +}=0D +=0D +/**=0D + Get full SMRAM ranges.=0D +=0D + It will get SMRAM ranges from SmmAccess protocol and SMRAM reserved rang= es from=0D + SmmConfiguration protocol, split the entries if there is overlap between= them.=0D + It will also reserve one entry for SMM core.=0D +=0D + @param[in] PeiServices Describes the list of possible PEI Ser= vices.=0D + @param[out] FullSmramRangeCount Output pointer to full SMRAM range cou= nt.=0D +=0D + @return Pointer to full SMRAM ranges.=0D +=0D +**/=0D +EFI_SMRAM_DESCRIPTOR *=0D +GetFullSmramRanges (=0D + IN CONST EFI_PEI_SERVICES **PeiServices,=0D + OUT UINTN *FullSmramRangeCount=0D + )=0D +{=0D + EFI_STATUS Status;=0D + UINTN Size;=0D + EFI_SMRAM_DESCRIPTOR *FullSmramRanges;=0D + UINTN AdditionSmramRangeCount;=0D + UINTN SmramRangeCount;=0D +=0D + //=0D + // Get SMRAM information.=0D + //=0D + Size =3D 0;=0D + Status =3D mSmmAccess->GetCapabilities ((EFI_PEI_SERVICES **)PeiServices= , mSmmAccess, &Size, NULL);=0D + ASSERT (Status =3D=3D EFI_BUFFER_TOO_SMALL);=0D +=0D + SmramRangeCount =3D Size / sizeof (EFI_SMRAM_DESCRIPTOR);=0D +=0D + //=0D + // Reserve one entry SMM Core in the full SMRAM ranges.=0D + //=0D + AdditionSmramRangeCount =3D 1;=0D + if (PcdGet64 (PcdLoadModuleAtFixAddressEnable) !=3D 0) {=0D + //=0D + // Reserve three entries for all SMM drivers & SMM Core in the full SM= RAM ranges.=0D + //=0D + AdditionSmramRangeCount =3D 2;=0D + }=0D +=0D + //=0D + // No reserved SMRAM entry from SMM Configuration Protocol.=0D + //=0D + *FullSmramRangeCount =3D SmramRangeCount + AdditionSmramRangeCount;=0D + Size =3D (*FullSmramRangeCount) * sizeof (EFI_SMRAM_DESC= RIPTOR);=0D + FullSmramRanges =3D (EFI_SMRAM_DESCRIPTOR *)AllocateZeroPool (Size)= ;=0D + ASSERT (FullSmramRanges !=3D NULL);=0D + if (FullSmramRanges =3D=3D NULL) {=0D + return NULL;=0D + }=0D +=0D + Status =3D mSmmAccess->GetCapabilities ((EFI_PEI_SERVICES **)PeiServices= , mSmmAccess, &Size, FullSmramRanges);=0D +=0D + ASSERT_EFI_ERROR (Status);=0D +=0D + return FullSmramRanges;=0D +}=0D +=0D +/**=0D + The Entry Point for SMM IPL=0D +=0D + Load SMM Core into SMRAM.=0D +=0D + @param FileHandle Handle of the file being invoked.=0D + @param PeiServices Describes the list of possible PEI Services.=0D +=0D + @retval EFI_SUCCESS The entry point is executed successfully.=0D + @retval Other Some error occurred when executing this entry poi= nt.=0D +=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +SmmIplEntry (=0D + IN EFI_PEI_FILE_HANDLE FileHandle,=0D + IN CONST EFI_PEI_SERVICES **PeiServices=0D + )=0D +{=0D + EFI_STATUS Status;=0D + UINTN Index;=0D + UINT64 MaxSize;=0D + UINT64 SmmCodeSize;=0D + MM_CORE_DATA_HOB_DATA SmmCoreDataHobData;=0D + EFI_SMRAM_DESCRIPTOR *MmramRanges;=0D +=0D + //=0D + // Build Hob for SMM and DXE phase=0D + //=0D + SmmCoreDataHobData.Address =3D (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateRunt= imePages (EFI_SIZE_TO_PAGES (sizeof (mMmCorePrivateData)));=0D + ASSERT (SmmCoreDataHobData.Address !=3D 0);=0D + gMmCorePrivate =3D (VOID *)(UINTN)SmmCoreDataHobData.Address;=0D + CopyMem ((VOID *)(UINTN)SmmCoreDataHobData.Address, &mMmCorePrivateData,= sizeof (mMmCorePrivateData));=0D + DEBUG ((DEBUG_INFO, "gMmCorePrivate - 0x%x\n", gMmCorePrivate));=0D +=0D + BuildGuidDataHob (=0D + &gMmCoreDataHobGuid,=0D + (VOID *)&SmmCoreDataHobData,=0D + sizeof (SmmCoreDataHobData)=0D + );=0D +=0D + //=0D + // Get SMM Access Protocol=0D + //=0D + Status =3D PeiServicesLocatePpi (&gPeiSmmAccessPpiGuid, 0, NULL, (VOID *= *)&mSmmAccess);=0D + ASSERT_EFI_ERROR (Status);=0D +=0D + //=0D + // Get SMRAM information=0D + //=0D + gMmCorePrivate->MmramRanges =3D (EFI_PHYSICAL_ADDRESS)(UINTN)GetFullSmra= mRanges (PeiServices, (UINTN *)&gMmCorePrivate->MmramRangeCount);=0D + ASSERT (gMmCorePrivate->MmramRanges !=3D 0);=0D + if (gMmCorePrivate->MmramRanges =3D=3D 0) {=0D + return EFI_OUT_OF_RESOURCES;=0D + }=0D +=0D + //=0D + // Open all SMRAM ranges=0D + //=0D + Status =3D mSmmAccess->Open ((EFI_PEI_SERVICES **)PeiServices, mSmmAcces= s, 0);=0D + ASSERT_EFI_ERROR (Status);=0D +=0D + //=0D + // Print debug message that the SMRAM window is now open.=0D + //=0D + DEBUG ((DEBUG_INFO, "SMM IPL opened SMRAM window\n"));=0D +=0D + //=0D + // Find the largest SMRAM range between 1MB and 4GB that is at least 256= KB - 4K in size=0D + //=0D + mCurrentSmramRange =3D NULL;=0D + MmramRanges =3D (EFI_MMRAM_DESCRIPTOR *)(UINTN)gMmCorePrivate->Mm= ramRanges;=0D + if (MmramRanges =3D=3D NULL) {=0D + DEBUG ((DEBUG_ERROR, "Fail to retrieve MmramRanges\n"));=0D + return EFI_UNSUPPORTED;=0D + }=0D +=0D + for (Index =3D 0, MaxSize =3D SIZE_256KB - EFI_PAGE_SIZE; Index < gMmCor= ePrivate->MmramRangeCount; Index++) {=0D + //=0D + // Skip any SMRAM region that is already allocated, needs testing, or = needs ECC initialization=0D + //=0D + if ((MmramRanges[Index].RegionState & (EFI_ALLOCATED | EFI_NEEDS_TESTI= NG | EFI_NEEDS_ECC_INITIALIZATION)) !=3D 0) {=0D + continue;=0D + }=0D +=0D + if (MmramRanges[Index].CpuStart >=3D BASE_1MB) {=0D + if ((MmramRanges[Index].CpuStart + MmramRanges[Index].PhysicalSize) = <=3D BASE_4GB) {=0D + if (MmramRanges[Index].PhysicalSize >=3D MaxSize) {=0D + MaxSize =3D MmramRanges[Index].PhysicalSize;=0D + mCurrentSmramRange =3D &MmramRanges[Index];=0D + }=0D + }=0D + }=0D + }=0D +=0D + if (mCurrentSmramRange !=3D NULL) {=0D + //=0D + // Print debug message showing SMRAM window that will be used by SMM I= PL and SMM Core=0D + //=0D + DEBUG ((=0D + DEBUG_INFO,=0D + "SMM IPL found SMRAM window %p - %p\n",=0D + (VOID *)(UINTN)mCurrentSmramRange->CpuStart,=0D + (VOID *)(UINTN)(mCurrentSmramRange->CpuStart + mCurrentSmramRange->P= hysicalSize - 1)=0D + ));=0D +=0D + GetSmramCacheRange (mCurrentSmramRange, &mSmramCacheBase, &mSmramCache= Size);=0D +=0D + //=0D + // if Loading module at Fixed Address feature is enabled, save the SMR= AM base to Load=0D + // Modules At Fixed Address Configuration Table.=0D + //=0D + if (PcdGet64 (PcdLoadModuleAtFixAddressEnable) !=3D 0) {=0D + //=0D + // Build tool will calculate the smm code size and then patch the Pc= dLoadFixAddressSmmCodePageNumber=0D + //=0D + SmmCodeSize =3D LShiftU64 (PcdGet32 (PcdLoadFixAddressSmmCodePageNum= ber), EFI_PAGE_SHIFT);=0D + //=0D + // The SMRAM available memory is assumed to be larger than SmmCodeSi= ze=0D + //=0D + ASSERT (mCurrentSmramRange->PhysicalSize > SmmCodeSize);=0D + }=0D +=0D + //=0D + // Load SMM Core into SMRAM and execute it from SMRAM=0D + // Note: SmramRanges specific for SMM Core will put in the gMmCorePriv= ate->MmramRangeCount - 1.=0D + //=0D + Status =3D ExecuteSmmCoreFromSmram (=0D + mCurrentSmramRange,=0D + &(((EFI_MMRAM_DESCRIPTOR *)(UINTN)gMmCorePrivate->MmramRang= es)[gMmCorePrivate->MmramRangeCount - 1]),=0D + gMmCorePrivate=0D + );=0D + if (EFI_ERROR (Status)) {=0D + //=0D + // Print error message that the SMM Core failed to be loaded and exe= cuted.=0D + //=0D + DEBUG ((DEBUG_ERROR, "SMM IPL could not load and execute SMM Core fr= om SMRAM\n"));=0D + }=0D + } else {=0D + //=0D + // Print error message that there are not enough SMRAM resources to lo= ad the SMM Core.=0D + //=0D + DEBUG ((DEBUG_ERROR, "SMM IPL could not find a large enough SMRAM regi= on to load SMM Core\n"));=0D + }=0D +=0D + //=0D + // If the SMM Core could not be loaded then close SMRAM window, free all= ocated=0D + // resources, and return an error so SMM IPL will be unloaded.=0D + //=0D + if ((mCurrentSmramRange =3D=3D NULL) || EFI_ERROR (Status)) {=0D + //=0D + // Close all SMRAM ranges=0D + //=0D + Status =3D mSmmAccess->Close ((EFI_PEI_SERVICES **)PeiServices, mSmmAc= cess, 0);=0D + ASSERT_EFI_ERROR (Status);=0D +=0D + //=0D + // Print debug message that the SMRAM window is now closed.=0D + //=0D + DEBUG ((DEBUG_INFO, "SMM IPL closed SMRAM window\n"));=0D +=0D + //=0D + // Free all allocated resources=0D + //=0D + FreePool ((VOID *)(UINTN)gMmCorePrivate->MmramRanges);=0D +=0D + return EFI_UNSUPPORTED;=0D + }=0D +=0D + return EFI_SUCCESS;=0D +}=0D diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/X64/LoadSmmCore.c b= /StandaloneMmPkg/Drivers/StandaloneMmIplPei/X64/LoadSmmCore.c new file mode 100644 index 000000000000..5cabf310e33c --- /dev/null +++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/X64/LoadSmmCore.c @@ -0,0 +1,32 @@ +/** @file=0D + SMM IPL that load the SMM Core into SMRAM=0D +=0D + Copyright (c) 2022, Intel Corporation. All rights reserved.
=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D +**/=0D +=0D +#include =0D +#include =0D +#include =0D +=0D +/**=0D + Load SMM core to dispatch other Standalone MM drivers.=0D +=0D + @param Entry Entry of Standalone MM Foundation.=0D + @param Context1 A pointer to the context to pass into = the EntryPoint=0D + function.=0D + @retval EFI_SUCCESS Successfully loaded SMM core.=0D + @retval Others Failed to load SMM core.=0D +**/=0D +EFI_STATUS=0D +LoadSmmCore (=0D + IN EFI_PHYSICAL_ADDRESS Entry,=0D + IN VOID *Context1=0D + )=0D +{=0D + STANDALONE_MM_FOUNDATION_ENTRY_POINT EntryPoint;=0D +=0D + EntryPoint =3D (STANDALONE_MM_FOUNDATION_ENTRY_POINT)(UINTN)Entry;=0D + return EntryPoint (Context1);=0D +}=0D diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/Ia32/Thunk32To64.na= sm b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/Ia32/Thunk32To64.nasm new file mode 100644 index 000000000000..2332d32e5885 --- /dev/null +++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/Ia32/Thunk32To64.nasm @@ -0,0 +1,148 @@ +;-------------------------------------------------------------------------= -----=0D +;=0D +; Copyright (c) 2022, Intel Corporation. All rights reserved.
=0D +; SPDX-License-Identifier: BSD-2-Clause-Patent=0D +;=0D +; Module Name:=0D +;=0D +; Thunk32To64.nasm=0D +;=0D +; Abstract:=0D +;=0D +; This is the assembly code to transition from long mode to compatibilit= y=0D +; mode to execute 32-bit code and then transit back to long mode.=0D +;=0D +;-------------------------------------------------------------------------= -----=0D +=0D + SECTION .text=0D +=0D +;-------------------------------------------------------------------------= -----=0D +; Procedure: AsmExecute64BitCode=0D +;=0D +; Input: None=0D +;=0D +; Output: None=0D +;=0D +; Prototype: UINT32=0D +; AsmExecute64BitCode (=0D +; IN UINT64 Function,=0D +; IN UINT64 Param1,=0D +; IN UINT64 Param2,=0D +; IN IA32_DESCRIPTOR *InternalGdtr=0D +; );=0D +;=0D +;=0D +; Description: A thunk function to execute 32-bit code in long mode.=0D +;=0D +;-------------------------------------------------------------------------= -----=0D +global ASM_PFX(AsmExecute64BitCode)=0D +ASM_PFX(AsmExecute64BitCode):=0D +;=0D +; +---------+=0D +; | EIP(64) |=0D +; +---------+=0D +; | CS (64) |=0D +; +---------+=0D +; | EIP(32) |=0D +; +---------+=0D +; | CS (32) |<-ESP (16 bytes aligned)=0D +; +---------+=0D +; | ... |=0D +; +---------+=0D +; | ebx |<-EBP=0D +; +---------+=0D +; | ebp |<-EBP + 4=0D +; +---------+=0D +; | esi |<-EBP + 8=0D +; +---------+=0D +; | edi |<-EBP + 12=0D +; +---------+=0D +; | RFlags |<-EBP + 16=0D +; +---------+=0D +; | RetAddr |<-EBP (org)=0D +; +---------+=0D +; | Func |<-EBP + 24=0D +; | Func |=0D +; +---------+=0D +; | Param1 |<-EBP + 32=0D +; | Param1 |=0D +; +---------+=0D +; | Param2 |<-EBP + 40=0D +; | Param2 |=0D +; +---------+=0D +; | Gdtr |=0D +; +---------+=0D +;=0D + ;=0D + ; Save general purpose register and RFlags register=0D + ;=0D + pushfd=0D + push edi=0D + push esi=0D + push ebp=0D + push ebx=0D + mov ebp, esp=0D +=0D + and esp, 0FFFFFFF0h=0D +=0D + push 010h ; protected mode selector on stack= =0D + mov eax, Compatible ; offset for LongMode=0D + push eax ; offset on stack=0D +=0D + push 038h ; long mode selector on stack=0D + mov eax, LongMode ; offset for LongMode=0D + push eax ; offset on stack=0D +=0D + mov eax, cr4=0D + or al, 020h=0D + mov cr4, eax ; enable PAE=0D + mov ecx, 0c0000080h=0D + rdmsr=0D + or ah, 1 ; set LME=0D + wrmsr=0D + mov eax, cr0=0D + bts eax, 31 ; set PG=0D + mov cr0, eax ; enable paging=0D + retf ; topmost 2 dwords hold the addres= s=0D +LongMode: ; long mode starts here=0D +=0D + ; Call long mode function=0D + DB 67h, 48h ; 32-bit address size, 64-bit oper= and size=0D + mov eax, [ebp + 24] ; mov rbx, [ebp + 24]=0D + DB 67h, 48h=0D + mov ecx, [ebp + 24 + 8] ; mov rcx, [ebp + 24 + 8]=0D + DB 67h, 48h=0D + mov edx, [ebp + 24 + 16] ; mov rdx, [ebp + 24 + 16]=0D +=0D + DB 48h=0D + add esp, -20h ; add rsp, -20h=0D + call eax ; call rax=0D + DB 48h=0D + add esp, 20h ; add rsp, 20h=0D +=0D + ; after long mode function call=0D + mov ebx, eax=0D +=0D + retf=0D +Compatible:=0D + mov ecx, cr0=0D + btc ecx, 31 ; clear PG=0D + mov cr0, ecx ; disable paging=0D + mov ecx, 0C0000080h=0D + rdmsr=0D + btc eax, 8 ; clear LME=0D + wrmsr=0D +=0D + ;=0D + ; Restore C register and eax hold the return status from 32-bit functi= on.=0D + ; Note: Do not touch rax from now which hold the return value from IA3= 2 function=0D + ;=0D + mov eax, ebx ; put return status to EAX=0D + mov esp, ebp ; restore stack pointer=0D + pop ebx=0D + pop ebp=0D + pop esi=0D + pop edi=0D + popfd=0D +=0D + ret=0D diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.= h b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h new file mode 100644 index 000000000000..5e27dfe1454c --- /dev/null +++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h @@ -0,0 +1,47 @@ +/** @file=0D + Private header with declarations and definitions specific to the Standal= one=0D + MM IPL PEI driver=0D +=0D + Copyright (c) 2022, Intel Corporation. All rights reserved.
=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D +**/=0D +=0D +#ifndef STANDALONE_MM_IPL_PEI_H_=0D +#define STANDALONE_MM_IPL_PEI_H_=0D +=0D +/**=0D + Load SMM core to dispatch other Standalone MM drivers.=0D +=0D + @param Entry Entry of Standalone MM Foundation.=0D + @param Context1 A pointer to the context to pass into = the EntryPoint=0D + function.=0D + @retval EFI_SUCCESS Successfully loaded SMM core.=0D + @retval Others Failed to load SMM core.=0D +**/=0D +EFI_STATUS=0D +LoadSmmCore (=0D + IN EFI_PHYSICAL_ADDRESS Entry,=0D + IN VOID *Context1=0D + );=0D +=0D +/**=0D + Assembly function to transition from long mode to compatibility mode to= =0D + execute 32-bit code and then transit back to long mode.=0D +=0D + @param[in] Function The 32bit code entry to be executed.=0D + @param[in] Param1 The first parameter to pass to 32bit code=0D + @param[in] Param2 The second parameter to pass to 32bit code=0D + @param[in] InternalGdtr The GDT and GDT descriptor used by this library= =0D +=0D + @return status.=0D +**/=0D +UINT32=0D +AsmExecute64BitCode (=0D + IN UINT64 Function,=0D + IN UINT64 Param1,=0D + IN UINT64 Param2,=0D + IN IA32_DESCRIPTOR *InternalGdtr=0D + );=0D +=0D +#endif=0D diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.= inf b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf new file mode 100644 index 000000000000..e531280abdfe --- /dev/null +++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf @@ -0,0 +1,74 @@ +## @file=0D +# This module provide a Standalone SMM compliant implementation of SMM IP= L PEIM.=0D +#=0D +# Copyright (c) 2022, Intel Corporation. All rights reserved.
=0D +#=0D +# SPDX-License-Identifier: BSD-2-Clause-Patent=0D +#=0D +##=0D +=0D +[Defines]=0D + INF_VERSION =3D 0x00010005=0D + BASE_NAME =3D StandaloneMmIplPei=0D + FILE_GUID =3D 578A0D17-2DC0-4C7D-A121-D8D771923BB0= =0D + MODULE_TYPE =3D PEIM=0D + VERSION_STRING =3D 1.0=0D + PI_SPECIFICATION_VERSION =3D 0x0001000A=0D + ENTRY_POINT =3D SmmIplEntry=0D +=0D +#=0D +# The following information is for reference only and not required by the = build tools.=0D +#=0D +# VALID_ARCHITECTURES =3D IA32 X64=0D +#=0D +=0D +[Sources]=0D + StandaloneMmIplPei.h=0D + StandaloneMmIplPei.c=0D +=0D +[Sources.Ia32]=0D + Ia32/LoadSmmCore.c=0D + Ia32/Thunk32To64.nasm=0D +=0D +[Sources.X64]=0D + X64/LoadSmmCore.c=0D +=0D +[Packages]=0D + MdePkg/MdePkg.dec=0D + MdeModulePkg/MdeModulePkg.dec=0D + StandaloneMmPkg/StandaloneMmPkg.dec=0D +=0D +[LibraryClasses]=0D + PeimEntryPoint=0D + PeiServicesTablePointerLib=0D + PeiServicesLib=0D + BaseLib=0D + BaseMemoryLib=0D + PeCoffLib=0D + CacheMaintenanceLib=0D + MemoryAllocationLib=0D + DebugLib=0D + HobLib=0D + IntrinsicLib=0D +=0D +[Guids]=0D + gMmCoreDataHobGuid=0D +=0D +[Ppis]=0D + gPeiSmmAccessPpiGuid ## CONSUMES=0D + gPeiSmmControlPpiGuid ## CONSUMES=0D +=0D +[FeaturePcd.IA32]=0D + gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode ## CONSUME= S=0D +=0D +[Pcd.IA32]=0D + gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable ## SOMETIM= ES_CONSUMES=0D +=0D +[Pcd]=0D + gEfiMdeModulePkgTokenSpaceGuid.PcdLoadFixAddressSmmCodePageNumber ##= SOMETIMES_CONSUMES=0D + gEfiMdeModulePkgTokenSpaceGuid.PcdLoadModuleAtFixAddressEnable ##= CONSUMES=0D +=0D +[Depex]=0D + gPeiSmmAccessPpiGuid AND=0D + gPeiSmmControlPpiGuid=0D +=0D diff --git a/StandaloneMmPkg/StandaloneMmPkg.ci.yaml b/StandaloneMmPkg/Stan= daloneMmPkg.ci.yaml index 4777532a7ede..872f7958be84 100644 --- a/StandaloneMmPkg/StandaloneMmPkg.ci.yaml +++ b/StandaloneMmPkg/StandaloneMmPkg.ci.yaml @@ -78,7 +78,9 @@ ## options defined .pytool/Plugin/SpellCheck=0D "SpellCheck": {=0D "AuditOnly": False,=0D - "IgnoreFiles": [], # use gitignore syntax to ignore erro= rs=0D + "IgnoreFiles": [=0D + "Drivers/StandaloneMmIplPei/Ia32/Thunk32To64.nasm"=0D + ], # use gitignore syntax to ignore errors=0D # in matching files=0D "ExtendWords": [=0D "Bsymbolic",=0D diff --git a/StandaloneMmPkg/StandaloneMmPkg.dsc b/StandaloneMmPkg/Standalo= neMmPkg.dsc index 8012f93b7dcc..d88471fe82be 100644 --- a/StandaloneMmPkg/StandaloneMmPkg.dsc +++ b/StandaloneMmPkg/StandaloneMmPkg.dsc @@ -20,7 +20,7 @@ PLATFORM_VERSION =3D 1.0=0D DSC_SPECIFICATION =3D 0x00010011=0D OUTPUT_DIRECTORY =3D Build/StandaloneMm=0D - SUPPORTED_ARCHITECTURES =3D AARCH64|X64|ARM=0D + SUPPORTED_ARCHITECTURES =3D AARCH64|X64|ARM|IA32=0D BUILD_TARGETS =3D DEBUG|RELEASE=0D SKUID_IDENTIFIER =3D DEFAULT=0D =0D @@ -60,6 +60,14 @@ StandaloneMmDriverEntryPoint|MdePkg/Library/StandaloneMmDriverEntryPoint= /StandaloneMmDriverEntryPoint.inf=0D VariableMmDependency|StandaloneMmPkg/Library/VariableMmDependency/Variab= leMmDependency.inf=0D =0D +[LibraryClasses.common.PEIM]=0D + HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf=0D + PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf=0D + MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAlloc= ationLib.inf=0D + PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf=0D + PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLib/Pei= ServicesTablePointerLib.inf=0D + IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf=0D +=0D [LibraryClasses.AARCH64, LibraryClasses.ARM]=0D ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf=0D StandaloneMmMmuLib|ArmPkg/Library/StandaloneMmMmuLib/ArmMmuStandaloneMmL= ib.inf=0D @@ -104,7 +112,7 @@ # generated for it, but the binary will not be put into any firmware= volume.=0D #=0D ##########################################################################= #########################=0D -[Components.common]=0D +[Components.AARCH64, Components.ARM, Components.X64]=0D #=0D # MM Core=0D #=0D @@ -122,6 +130,9 @@ StandaloneMmPkg/Drivers/StandaloneMmCpu/StandaloneMmCpu.inf=0D StandaloneMmPkg/Library/StandaloneMmPeCoffExtraActionLib/StandaloneMmPeC= offExtraActionLib.inf=0D =0D +[Components.X64, Components.IA32]=0D + StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf=0D +=0D ##########################################################################= #########################=0D #=0D # BuildOptions Section - Define the module specific tool chain flags that = should be used as=0D --=20 2.26.2.windows.1