Hongbin, The patch is so big. Can you please split the patch to small patches? For example: 1st patch only implements the Ipl entrypoint to find the correct SMRAM range 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) == 4 but SMM core module type is 64bit. 4th patch Deadloop() when sizeof (UINTN) == 8 but SMM core module type is 32bit. 5th patch register ReadyToBoot callback. But is it too late from security perspective? 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 enable that later. 2. "EFIAPI" for GetSectionFromAnyFvByFileType should be removed. And the function 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. 3. Can the StandaloneMmCore in open source be directly used with this IPL? Thanks, Ray > -----Original Message----- > From: Zhang, Hongbin1 <hongbin1.zh...@intel.com> > Sent: Monday, May 22, 2023 1:21 PM > To: devel@edk2.groups.io > Cc: Zhang, Hongbin1 <hongbin1.zh...@intel.com>; Yao, Jiewen > <jiewen....@intel.com>; Ni, Ray <ray...@intel.com>; Zeng, Star > <star.z...@intel.com>; Wu, Jiaxin <jiaxin...@intel.com>; Sami Mujawar > <sami.muja...@arm.com>; Ard Biesheuvel <ardb+tianoc...@kernel.org>; > Supreeth Venkatesh <supreeth.venkat...@arm.com> > Subject: [PATCH v1] StandaloneMmPkg: Add StandaloneMmIplPei driver. > > 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 <hongbin1.zh...@intel.com> > Cc: Jiewen Yao <jiewen....@intel.com> > Cc: Ray Ni <ray...@intel.com> > Cc: Star Zeng <star.z...@intel.com> > Cc: Jiaxin Wu <jiaxin...@intel.com> > Cc: Sami Mujawar <sami.muja...@arm.com> > Cc: Ard Biesheuvel <ardb+tianoc...@kernel.org> > Cc: Supreeth Venkatesh <supreeth.venkat...@arm.com> > --- > 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(-) > > 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.<BR> > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include <PiPei.h> > +#include <PiSmm.h> > +#include <StandaloneMm.h> > +#include <Library/HobLib.h> > +#include <Library/DebugLib.h> > +#include <Library/BaseMemoryLib.h> > +#include <Library/MemoryAllocationLib.h> > +#include <StandaloneMmIplPei.h> > + > +#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 = Not present in memory, 1 = > Present in > memory > + UINT64 ReadWrite : 1; // 0 = Read-Only, 1= Read/Write > + UINT64 UserSupervisor : 1; // 0 = Supervisor, 1=User > + UINT64 WriteThrough : 1; // 0 = Write-Back caching, > 1=Write-Through > caching > + UINT64 CacheDisabled : 1; // 0 = Cached, 1=Non-Cached > + UINT64 Accessed : 1; // 0 = Not accessed, 1 = Accessed > (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 = Not present in memory, 1 = > Present in > memory > + UINT64 ReadWrite : 1; // 0 = Read-Only, 1= Read/Write > + UINT64 UserSupervisor : 1; // 0 = Supervisor, 1=User > + UINT64 WriteThrough : 1; // 0 = Write-Back caching, > 1=Write-Through > caching > + UINT64 CacheDisabled : 1; // 0 = Cached, 1=Non-Cached > + UINT64 Accessed : 1; // 0 = Not accessed, 1 = Accessed > (set by CPU) > + UINT64 Dirty : 1; // 0 = Not Dirty, 1 = written by > processor on > access to page > + UINT64 MustBe1 : 1; // Must be 1 > + UINT64 Global : 1; // 0 = Not global page, 1 = 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 = Execute Code, 1 = No Code > Execution > + } Bits; > + UINT64 Uint64; > +} PAGE_TABLE_ENTRY; > + > +// > +// Page Table Entry 1GB > +// > +typedef union { > + struct { > + UINT64 Present : 1; // 0 = Not present in memory, 1 = > Present in > memory > + UINT64 ReadWrite : 1; // 0 = Read-Only, 1= Read/Write > + UINT64 UserSupervisor : 1; // 0 = Supervisor, 1=User > + UINT64 WriteThrough : 1; // 0 = Write-Back caching, > 1=Write-Through > caching > + UINT64 CacheDisabled : 1; // 0 = Cached, 1=Non-Cached > + UINT64 Accessed : 1; // 0 = Not accessed, 1 = Accessed > (set by CPU) > + UINT64 Dirty : 1; // 0 = Not Dirty, 1 = written by > processor on > access to page > + UINT64 MustBe1 : 1; // Must be 1 > + UINT64 Global : 1; // 0 = Not global page, 1 = 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 = Execute Code, 1 = No Code > Execution > + } Bits; > + UINT64 Uint64; > +} PAGE_TABLE_1G_ENTRY; > + > +#pragma pack() > + > +// > +// Global Descriptor Table (GDT) > +// > +GLOBAL_REMOVE_IF_UNREFERENCED IA32_SEGMENT_DESCRIPTOR > mGdtEntries[] = { > + /* 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 = { > + 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 = FALSE; > + if (PcdGetBool (PcdUse1GPageTable)) { > + AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL); > + if (RegEax >= 0x80000001) { > + AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx); > + if ((RegEdx & BIT26) != 0) { > + Page1GSupport = TRUE; > + } > + } > + } > + > + // > + // Get physical address bits supported. > + // > + Hob = GetFirstHob (EFI_HOB_TYPE_CPU); > + if (Hob != NULL) { > + PhysicalAddressBits = ((EFI_HOB_CPU *)Hob)->SizeOfMemorySpace; > + } else { > + AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL); > + if (RegEax >= 0x80000008) { > + AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL); > + PhysicalAddressBits = (UINT8)RegEax; > + } else { > + PhysicalAddressBits = 36; > + } > + } > + > + // > + // IA-32e paging translates 48-bit linear addresses to 52-bit physical > addresses. > + // > + ASSERT (PhysicalAddressBits <= 52); > + if (PhysicalAddressBits > 48) { > + PhysicalAddressBits = 48; > + } > + > + // > + // Calculate the table entries needed. > + // > + if (PhysicalAddressBits <= 39 ) { > + NumberOfPml4EntriesNeeded = 1; > + NumberOfPdpEntriesNeeded = (UINT32)LShiftU64 (1, (PhysicalAddressBits - > 30)); > + } else { > + NumberOfPml4EntriesNeeded = (UINT32)LShiftU64 (1, (PhysicalAddressBits - > 39)); > + NumberOfPdpEntriesNeeded = 512; > + } > + > + if (!Page1GSupport) { > + TotalPagesNum = (NumberOfPdpEntriesNeeded + 1) * > NumberOfPml4EntriesNeeded + 1; > + } else { > + TotalPagesNum = 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 = FALSE; > + AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL); > + if (RegEax >= 0x80000001) { > + AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx); > + if ((RegEdx & BIT26) != 0) { > + Page1GSupport = TRUE; > + } > + } > + > + // > + // Get physical address bits supported. > + // > + Hob = GetFirstHob (EFI_HOB_TYPE_CPU); > + if (Hob != NULL) { > + PhysicalAddressBits = ((EFI_HOB_CPU *)Hob)->SizeOfMemorySpace; > + } else { > + AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL); > + if (RegEax >= 0x80000008) { > + AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL); > + PhysicalAddressBits = (UINT8)RegEax; > + } else { > + PhysicalAddressBits = 36; > + } > + } > + > + // > + // IA-32e paging translates 48-bit linear addresses to 52-bit physical > addresses. > + // > + ASSERT (PhysicalAddressBits <= 52); > + if (PhysicalAddressBits > 48) { > + PhysicalAddressBits = 48; > + } > + > + // > + // Calculate the table entries needed. > + // > + if (PhysicalAddressBits <= 39 ) { > + NumberOfPml4EntriesNeeded = 1; > + NumberOfPdpEntriesNeeded = (UINT32)LShiftU64 (1, (PhysicalAddressBits - > 30)); > + } else { > + NumberOfPml4EntriesNeeded = (UINT32)LShiftU64 (1, (PhysicalAddressBits - > 39)); > + NumberOfPdpEntriesNeeded = 512; > + } > + > + // > + // Pre-allocate big pages to avoid later allocations. > + // > + BigPageAddress = (UINTN)PageTablesAddress; > + > + // > + // By architecture only one PageMapLevel4 exists - so lets allocate > storage for > it. > + // > + PageMap = (VOID *)BigPageAddress; > + BigPageAddress += SIZE_4KB; > + > + PageMapLevel4Entry = PageMap; > + PageAddress = 0; > + for (IndexOfPml4Entries = 0; IndexOfPml4Entries < > NumberOfPml4EntriesNeeded; IndexOfPml4Entries++, PageMapLevel4Entry++) { > + // > + // Each PML4 entry points to a page of Page Directory Pointer entires. > + // So lets allocate space for them and fill them in in the > IndexOfPdpEntries > loop. > + // > + PageDirectoryPointerEntry = (VOID *)BigPageAddress; > + BigPageAddress += SIZE_4KB; > + > + // > + // Make a PML4 Entry > + // > + PageMapLevel4Entry->Uint64 = > (UINT64)(UINTN)PageDirectoryPointerEntry; > + PageMapLevel4Entry->Bits.ReadWrite = 1; > + PageMapLevel4Entry->Bits.Present = 1; > + > + if (Page1GSupport) { > + PageDirectory1GEntry = (VOID *)PageDirectoryPointerEntry; > + > + for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < > 512; > IndexOfPageDirectoryEntries++, PageDirectory1GEntry++, PageAddress += > SIZE_1GB) { > + // > + // Fill in the Page Directory entries > + // > + PageDirectory1GEntry->Uint64 = (UINT64)PageAddress; > + PageDirectory1GEntry->Bits.ReadWrite = 1; > + PageDirectory1GEntry->Bits.Present = 1; > + PageDirectory1GEntry->Bits.MustBe1 = 1; > + } > + } else { > + for (IndexOfPdpEntries = 0; IndexOfPdpEntries < > NumberOfPdpEntriesNeeded; IndexOfPdpEntries++, > PageDirectoryPointerEntry++) { > + // > + // Each Directory Pointer entries points to a page of Page Directory > entires. > + // So allocate space for them and fill them in in the > IndexOfPageDirectoryEntries loop. > + // > + PageDirectoryEntry = (VOID *)BigPageAddress; > + BigPageAddress += SIZE_4KB; > + > + // > + // Fill in a Page Directory Pointer Entries > + // > + PageDirectoryPointerEntry->Uint64 = > (UINT64)(UINTN)PageDirectoryEntry; > + PageDirectoryPointerEntry->Bits.ReadWrite = 1; > + PageDirectoryPointerEntry->Bits.Present = 1; > + > + for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < > 512; > IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PageAddress += > SIZE_2MB) { > + // > + // Fill in the Page Directory entries > + // > + PageDirectoryEntry->Uint64 = (UINT64)PageAddress; > + PageDirectoryEntry->Bits.ReadWrite = 1; > + PageDirectoryEntry->Bits.Present = 1; > + PageDirectoryEntry->Bits.MustBe1 = 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 into the > EntryPoint > + function. > + @param Context2 A pointer to the context to pass into the > EntryPoint > + function. > + @retval EFI_SUCCESS Successfully switched to long mode and > execute > coalesce. > + @retval Others Failed to execute coalesce in long mode. > + > +**/ > +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 = AsmReadCr3 () & 0xFFFFF000; > + > + // > + // If page table was created, no need to create > + // > + if (PageTableAddress == 0) { > + PageTableSize = CalculatePageTableSize (); > + > + PageTableAddress = (UINTN)AllocatePages (EFI_SIZE_TO_PAGES > (PageTableSize)); > + ASSERT (PageTableAddress != 0); > + > + CreateIdentityMappingPageTables (PageTableAddress); > + > + AsmWriteCr3 ((UINTN)PageTableAddress); > + } > + > + DEBUG ((DEBUG_INFO, "AsmExecute64BitCode ...\n")); > + > + Status = AsmExecute64BitCode (Entry, (UINT64)(UINTN)Context1, > (UINT64)(UINTN)Context2, NULL); > + if (Status != 0) { > + Status = 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 into 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.<BR> > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include <PiPei.h> > +#include <PiSmm.h> > +#include <Ppi/SmmAccess.h> > +#include <Ppi/SmmControl.h> > +#include <Library/BaseLib.h> > +#include <Library/BaseMemoryLib.h> > +#include <Library/PeCoffLib.h> > +#include <Library/CacheMaintenanceLib.h> > +#include <Library/MemoryAllocationLib.h> > +#include <Library/DebugLib.h> > +#include <Library/PeiServicesTablePointerLib.h> > +#include <Library/PeiServicesLib.h> > +#include <Library/HobLib.h> > +#include <Library/PcdLib.h> > +#include <Guid/SmramMemoryReserve.h> > +#include <Guid/MmCoreData.h> > +#include <StandaloneMmIplPei.h> > + > +// > +// MM Core Private Data structure that contains the data shared between > +// the SMM IPL and the Standalone MM Core. > +// > +MM_CORE_PRIVATE_DATA mMmCorePrivateData = { > + 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 inside > SMM > +// > +MM_CORE_PRIVATE_DATA *gMmCorePrivate; > + > +// > +// SMM IPL global variables > +// > +PEI_SMM_ACCESS_PPI *mSmmAccess; > +EFI_SMRAM_DESCRIPTOR *mCurrentSmramRange; > +BOOLEAN mSmmLocked = FALSE; > +EFI_PHYSICAL_ADDRESS mSmramCacheBase; > +UINT64 mSmramCacheSize; > + > +EFI_PEI_NOTIFY_DESCRIPTOR mReadyToBootNotifyList = { > + (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 every > PEIM. > + @param NotifyDescriptor The notification structure this PEIM > registered 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 = mSmmAccess->Close ((EFI_PEI_SERVICES **)PeiServices, > mSmmAccess, 0); > + ASSERT_EFI_ERROR (Status); > + > + // > + // Lock all SMRAM ranges > + // > + Status = 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 into 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 = SmramRange->CpuStart; > + *SmramCacheSize = SmramRange->PhysicalSize; > + > + SmramRanges = (EFI_SMRAM_DESCRIPTOR *)(UINTN)gMmCorePrivate- > >MmramRanges; > + do { > + FoundAdjacentRange = FALSE; > + for (Index = 0; Index < gMmCorePrivate->MmramRangeCount; Index++) { > + RangeCpuStart = SmramRanges[Index].CpuStart; > + RangePhysicalSize = SmramRanges[Index].PhysicalSize; > + if ((RangeCpuStart < *SmramCacheBase) && (*SmramCacheBase == > (RangeCpuStart + RangePhysicalSize))) { > + *SmramCacheBase = RangeCpuStart; > + *SmramCacheSize += RangePhysicalSize; > + FoundAdjacentRange = TRUE; > + } else if (((*SmramCacheBase + *SmramCacheSize) == RangeCpuStart) && > (RangePhysicalSize > 0)) { > + *SmramCacheSize += RangePhysicalSize; > + FoundAdjacentRange = 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 structure > that > describes the PE/COFF > + image that needs to be examined by this > 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 loading > 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 = EFI_PAGES_TO_SIZE (PcdGet32 > (PcdLoadFixAddressSmmCodePageNumber)); > + FixLoadingAddress = 0; > + Status = EFI_NOT_FOUND; > + SmramBase = mCurrentSmramRange->CpuStart; > + // > + // Get PeHeader pointer > + // > + ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((CHAR8 > *)ImageContext->Handle + ImageContext->PeCoffHeaderOffset); > + SectionHeaderOffset = (UINTN)( > + ImageContext->PeCoffHeaderOffset + > + sizeof (UINT32) + > + sizeof (EFI_IMAGE_FILE_HEADER) + > + ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader > + ); > + NumberOfSections = ImgHdr->Pe32.FileHeader.NumberOfSections; > + > + // > + // Get base address from the first section header that doesn't point to > code > section. > + // > + for (Index = 0; Index < NumberOfSections; Index++) { > + // > + // Read section header from file > + // > + Size = sizeof (EFI_IMAGE_SECTION_HEADER); > + Status = ImageContext->ImageRead ( > + ImageContext->Handle, > + SectionHeaderOffset, > + &Size, > + &SectionHeader > + ); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + Status = EFI_NOT_FOUND; > + > + if ((SectionHeader.Characteristics & EFI_IMAGE_SCN_CNT_CODE) == 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 image > header. > And there is an assumption that when the > + // feature is enabled, if a module is assigned a loading address by > tools, > PointerToRelocations & PointerToLineNumbers > + // fields should NOT be Zero, or else, these 2 fields should be set to > Zero > + // > + ValueInSectionHeader = ReadUnaligned64 ((UINT64 > *)&SectionHeader.PointerToRelocations); > + if (ValueInSectionHeader != 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 = (EFI_PHYSICAL_ADDRESS)(SmramBase + > (INT64)ValueInSectionHeader); > + > + if ((SmramBase + SmmCodeSize > FixLoadingAddress) && (SmramBase <= > FixLoadingAddress)) { > + // > + // The assigned address is valid. Return the specified loading > address > + // > + ImageContext->ImageAddress = FixLoadingAddress; > + Status = EFI_SUCCESS; > + } > + } > + > + break; > + } > + > + SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER); > + } > + > + DEBUG ((DEBUG_INFO|DEBUG_LOAD, "LOADING MODULE FIXED INFO: > Loading module at fixed address %x, Status = %r \n", FixLoadingAddress, > Status)); > + return Status; > +} > + > +/** > + Searches all the available firmware volumes and returns the first matching > 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 one > FFS file > with the same FileType, > + the FileInstance instance will be the matched FFS file. For each FFS file > 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 allocated > buffer is > returned in Size. > + It is the caller's responsibility to use FreePool() to free the allocated > 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 the > FFS > file > + specified by FileType with FileInstance to > retrieve. > SectionInstance starts from zero. > + @param Buffer On output, a pointer to a callee allocated > 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 bytes, > of Buffer. > + > + @retval EFI_SUCCESS The specified FFS section was returned. > + @retval EFI_NOT_FOUND The specified FFS section could not be found. > + @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 = NULL; > + for (FvIndex = 0; ; FvIndex++) { > + Status = PeiServicesFfsFindNextVolume (FvIndex, &VolumeHandle); > + if (EFI_ERROR (Status)) { > + break; > + } > + > + // > + // Search PEIM FFS > + // > + FileHandle = NULL; > + Status = PeiServicesFfsFindNextFile (FileType, VolumeHandle, > &FileHandle); > + if (EFI_ERROR (Status)) { > + continue; > + } > + > + // > + // Search Section > + // > + SectionData = NULL; > + Status = PeiServicesFfsFindSectionData (SectionType, FileHandle, > Buffer); > + if (EFI_ERROR (Status)) { > + continue; > + } > + > + // > + // Great! > + // > + SectionData = (EFI_PE32_SECTION *)((UINT8 *)*Buffer - sizeof > (EFI_PE32_SECTION)); > + ASSERT (SectionData->Type == SectionType); > + SectionSize = *(UINT32 *)SectionData->Size; > + SectionSize &= 0xFFFFFF; > + *Size = SectionSize - sizeof (EFI_PE32_SECTION); > + > + if (FileType == EFI_FV_FILETYPE_MM_CORE_STANDALONE) { > + EFI_FV_INFO VolumeInfo; > + // > + // This is SMM BFV > + // > + Status = PeiServicesFfsGetVolumeInfo (VolumeHandle, &VolumeInfo); > + if (!EFI_ERROR (Status)) { > + gMmCorePrivate->StandaloneBfvAddress = > (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 SMRAM to > reload the > + currently executing image, the rang > of SMRAM to > + hold SMM Core will be excluded. > + @param[in, out] SmramRangeSmmCore Descriptor for the range of SMRAM > 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 = PeiServicesGetHobList (&HobList); > + ASSERT_EFI_ERROR (Status); > + > + // > + // Search all Firmware Volumes for a PE/COFF image in a file of type > SMM_CORE > + // > + Status = GetSectionFromAnyFvByFileType ( > + EFI_FV_FILETYPE_MM_CORE_STANDALONE, > + 0, > + EFI_SECTION_PE32, > + 0, > + &SourceBuffer, > + &SourceSize > + ); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + // > + // Initialize ImageContext > + // > + ImageContext.Handle = SourceBuffer; > + ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory; > + > + // > + // Get information about the image being loaded > + // > + Status = 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) != 0) { > + // > + // Get the fixed loading address assigned by Build tool > + // > + Status = 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 = 0; > + // > + // Reserved Smram Region for SmmCore is not used, and remove it from > 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 = (UINTN)EFI_SIZE_TO_PAGES ((UINTN)ImageContext.ImageSize > + ImageContext.SectionAlignment); > + > + ASSERT ((SmramRange->PhysicalSize & EFI_PAGE_MASK) == 0); > + ASSERT (SmramRange->PhysicalSize > EFI_PAGES_TO_SIZE (PageCount)); > + > + SmramRange->PhysicalSize -= EFI_PAGES_TO_SIZE (PageCount); > + SmramRangeSmmCore->CpuStart = SmramRange->CpuStart + > SmramRange->PhysicalSize; > + SmramRangeSmmCore->PhysicalStart = SmramRange->PhysicalStart + > SmramRange->PhysicalSize; > + SmramRangeSmmCore->RegionState = SmramRange->RegionState | > EFI_ALLOCATED; > + SmramRangeSmmCore->PhysicalSize = EFI_PAGES_TO_SIZE (PageCount); > + > + // > + // Align buffer on section boundary > + // > + ImageContext.ImageAddress = SmramRangeSmmCore->CpuStart; > + } > + } else { > + // > + // Allocate memory for the image being loaded from the > EFI_SRAM_DESCRIPTOR > + // specified by SmramRange > + // > + PageCount = (UINTN)EFI_SIZE_TO_PAGES ((UINTN)ImageContext.ImageSize + > ImageContext.SectionAlignment); > + > + ASSERT ((SmramRange->PhysicalSize & EFI_PAGE_MASK) == 0); > + ASSERT (SmramRange->PhysicalSize > EFI_PAGES_TO_SIZE (PageCount)); > + > + SmramRange->PhysicalSize -= EFI_PAGES_TO_SIZE (PageCount); > + SmramRangeSmmCore->CpuStart = SmramRange->CpuStart + > SmramRange->PhysicalSize; > + SmramRangeSmmCore->PhysicalStart = SmramRange->PhysicalStart + > SmramRange->PhysicalSize; > + SmramRangeSmmCore->RegionState = SmramRange->RegionState | > EFI_ALLOCATED; > + SmramRangeSmmCore->PhysicalSize = EFI_PAGES_TO_SIZE (PageCount); > + > + // > + // Align buffer on section boundary > + // > + ImageContext.ImageAddress = SmramRangeSmmCore->CpuStart; > + } > + > + ImageContext.ImageAddress += ImageContext.SectionAlignment - 1; > + ImageContext.ImageAddress &= > ~((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 = PeCoffLoaderLoadImage (&ImageContext); > + if (!EFI_ERROR (Status)) { > + // > + // Relocate the image in our new buffer > + // > + Status = PeCoffLoaderRelocateImage (&ImageContext); > + if (!EFI_ERROR (Status)) { > + // > + // Flush the instruction cache so the image data are written before 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 = ImageContext.ImageAddress; > + gMmCorePrivate->MmCoreImageSize = ImageContext.ImageSize; > + DEBUG ((DEBUG_INFO, "SmmCoreImageBase - 0x%016lx\n", > gMmCorePrivate->MmCoreImageBase)); > + DEBUG ((DEBUG_INFO, "SmmCoreImageSize - 0x%016lx\n", > gMmCorePrivate->MmCoreImageSize)); > + > + gMmCorePrivate->MmCoreEntryPoint = ImageContext.EntryPoint; > + > + // > + // Print debug message showing Standalone MM Core entry point address. > + // > + 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 > return an > + // error, then free memory allocated from the EFI_SRAM_DESCRIPTOR > specified by > + // SmramRange > + // > + if (EFI_ERROR (Status)) { > + SmramRange->PhysicalSize += 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 between > them. > + It will also reserve one entry for SMM core. > + > + @param[in] PeiServices Describes the list of possible PEI > Services. > + @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 = 0; > + Status = mSmmAccess->GetCapabilities ((EFI_PEI_SERVICES **)PeiServices, > mSmmAccess, &Size, NULL); > + ASSERT (Status == EFI_BUFFER_TOO_SMALL); > + > + SmramRangeCount = Size / sizeof (EFI_SMRAM_DESCRIPTOR); > + > + // > + // Reserve one entry SMM Core in the full SMRAM ranges. > + // > + AdditionSmramRangeCount = 1; > + if (PcdGet64 (PcdLoadModuleAtFixAddressEnable) != 0) { > + // > + // Reserve two entries for all SMM drivers & SMM Core in the full SMRAM > ranges. > + // > + AdditionSmramRangeCount = 2; > + } > + > + *FullSmramRangeCount = SmramRangeCount + AdditionSmramRangeCount; > + Size = (*FullSmramRangeCount) * sizeof > (EFI_SMRAM_DESCRIPTOR); > + FullSmramRanges = (EFI_SMRAM_DESCRIPTOR *)AllocateZeroPool (Size); > + ASSERT (FullSmramRanges != NULL); > + if (FullSmramRanges == NULL) { > + return NULL; > + } > + > + Status = mSmmAccess->GetCapabilities ((EFI_PEI_SERVICES **)PeiServices, > 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 point. > + > +**/ > +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 = > (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateRuntimePages (EFI_SIZE_TO_PAGES > (sizeof (mMmCorePrivateData))); > + ASSERT (SmmCoreDataHobData.Address != 0); > + gMmCorePrivate = (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 = PeiServicesLocatePpi (&gPeiSmmAccessPpiGuid, 0, NULL, (VOID > **)&mSmmAccess); > + ASSERT_EFI_ERROR (Status); > + > + // > + // Get SMRAM information > + // > + gMmCorePrivate->MmramRanges = > (EFI_PHYSICAL_ADDRESS)(UINTN)GetFullSmramRanges (PeiServices, (UINTN > *)&gMmCorePrivate->MmramRangeCount); > + ASSERT (gMmCorePrivate->MmramRanges != 0); > + if (gMmCorePrivate->MmramRanges == 0) { > + return EFI_OUT_OF_RESOURCES; > + } > + > + // > + // Open all SMRAM ranges > + // > + Status = 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 256KB > - 4K in size > + // > + mCurrentSmramRange = NULL; > + MmramRanges = (EFI_MMRAM_DESCRIPTOR *)(UINTN)gMmCorePrivate- > >MmramRanges; > + if (MmramRanges == NULL) { > + DEBUG ((DEBUG_ERROR, "Fail to retrieve MmramRanges\n")); > + return EFI_UNSUPPORTED; > + } > + > + for (Index = 0, MaxSize = SIZE_256KB - EFI_PAGE_SIZE; Index < > gMmCorePrivate->MmramRangeCount; Index++) { > + // > + // Skip any SMRAM region that is already allocated, needs testing, or > needs > ECC initialization > + // > + if ((MmramRanges[Index].RegionState & (EFI_ALLOCATED | > EFI_NEEDS_TESTING | EFI_NEEDS_ECC_INITIALIZATION)) != 0) { > + continue; > + } > + > + if (MmramRanges[Index].CpuStart >= BASE_1MB) { > + if ((MmramRanges[Index].CpuStart + MmramRanges[Index].PhysicalSize) <= > BASE_4GB) { > + if (MmramRanges[Index].PhysicalSize >= MaxSize) { > + MaxSize = MmramRanges[Index].PhysicalSize; > + mCurrentSmramRange = &MmramRanges[Index]; > + } > + } > + } > + } > + > + if (mCurrentSmramRange != 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 SMRAM > base to Load > + // Modules At Fixed Address Configuration Table. > + // > + if (PcdGet64 (PcdLoadModuleAtFixAddressEnable) != 0) { > + // > + // Build tool will calculate the smm code size and then patch the > PcdLoadFixAddressSmmCodePageNumber > + // > + SmmCodeSize = LShiftU64 (PcdGet32 > (PcdLoadFixAddressSmmCodePageNumber), EFI_PAGE_SHIFT); > + // > + // The SMRAM available memory is assumed to be larger than SmmCodeSize > + // > + ASSERT (mCurrentSmramRange->PhysicalSize > SmmCodeSize); > + // > + // Fill the Smram range for all SMM code > + // > + MmramRanges = (EFI_MMRAM_DESCRIPTOR *)(UINTN)gMmCorePrivate- > >MmramRanges; > + // > + // Note: SmramRanges specific for all SMM code will put in the > gMmCorePrivate->MmramRangeCount - 2. > + // > + SmramRangeSmmDriver = &MmramRanges[gMmCorePrivate- > >MmramRangeCount - 2]; > + SmramRangeSmmDriver->CpuStart = mCurrentSmramRange->CpuStart; > + SmramRangeSmmDriver->PhysicalStart = mCurrentSmramRange- > >PhysicalStart; > + SmramRangeSmmDriver->RegionState = mCurrentSmramRange- > >RegionState | EFI_ALLOCATED; > + SmramRangeSmmDriver->PhysicalSize = SmmCodeSize; > + > + mCurrentSmramRange->PhysicalSize -= SmmCodeSize; > + mCurrentSmramRange->CpuStart = mCurrentSmramRange->CpuStart + > SmmCodeSize; > + mCurrentSmramRange->PhysicalStart = mCurrentSmramRange- > >PhysicalStart + SmmCodeSize; > + } > + > + // > + // Load SMM Core into SMRAM and execute it from SMRAM > + // Note: SmramRanges specific for SMM Core will put in the > gMmCorePrivate- > >MmramRangeCount - 1. > + // > + Status = 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 > executed. > + // > + 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 == NULL) || EFI_ERROR (Status)) { > + // > + // Close all SMRAM ranges > + // > + Status = 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 = 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.<BR> > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include <PiPei.h> > +#include <PiSmm.h> > +#include <StandaloneMm.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 into 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 = (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.<BR> > +; SPDX-License-Identifier: BSD-2-Clause-Patent > +; > +; Module Name: > +; > +; Thunk32To64.nasm > +; > +; Abstract: > +; > +; This is the assembly code to transition from long mode to compatibility > +; 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 stack > + 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 address > +LongMode: ; long mode starts here > + > + ; Call long mode function > + DB 67h, 48h ; 32-bit address size, 64-bit > operand 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 function. > + ; Note: Do not touch rax from now which hold the return value from IA32 > 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 Standalone > + MM IPL PEI driver > + > + Copyright (c) 2023, Intel Corporation. All rights reserved.<BR> > + 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 into 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 to > + 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 library > + > + @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 registered > 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 > + ); > + > +#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.<BR> > +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > + INF_VERSION = 0x00010005 > + BASE_NAME = StandaloneMmIplPei > + FILE_GUID = 578A0D17-2DC0-4C7D-A121-D8D771923BB0 > + MODULE_TYPE = PEIM > + VERSION_STRING = 1.0 > + PI_SPECIFICATION_VERSION = 0x0001000A > + ENTRY_POINT = SmmIplEntry > + > +# > +# The following information is for reference only and not required by the > build > tools. > +# > +# VALID_ARCHITECTURES = 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 errors > + "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 = 1.0 > DSC_SPECIFICATION = 0x00010011 > OUTPUT_DIRECTORY = Build/StandaloneMm > - SUPPORTED_ARCHITECTURES = AARCH64|X64|ARM > + SUPPORTED_ARCHITECTURES = AARCH64|X64|ARM|IA32 > BUILD_TARGETS = DEBUG|RELEASE > SKUID_IDENTIFIER = DEFAULT > > @@ -60,6 +60,14 @@ > > StandaloneMmDriverEntryPoint|MdePkg/Library/StandaloneMmDriverEntryPoin > t/StandaloneMmDriverEntryPoint.inf > > VariableMmDependency|StandaloneMmPkg/Library/VariableMmDependency/V > ariableMmDependency.inf > > +[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/PeiServic > esTablePointerLib.inf > + IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf > + > [LibraryClasses.AARCH64, LibraryClasses.ARM] > ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf > > StandaloneMmMmuLib|ArmPkg/Library/StandaloneMmMmuLib/ArmMmuStand > aloneMmLib.inf > @@ -104,7 +112,7 @@ > # generated for it, but the binary will not be put into any firmware > volume. > # > > ################################################################# > ################################## > -[Components.common] > +[Components.AARCH64, Components.ARM, Components.X64] > # > # MM Core > # > @@ -122,6 +130,9 @@ > StandaloneMmPkg/Drivers/StandaloneMmCpu/StandaloneMmCpu.inf > > StandaloneMmPkg/Library/StandaloneMmPeCoffExtraActionLib/StandaloneMm > PeCoffExtraActionLib.inf > > +[Components.X64, Components.IA32] > + StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf > + > > ################################################################# > ################################## > # > # BuildOptions Section - Define the module specific tool chain flags that > 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.<BR> > -# > -# SPDX-License-Identifier: BSD-2-Clause-Patent > -# > - > -if command -v ${PYTHON_COMMAND} >/dev/null 2>&1; then > - echo python_exe=${PYTHON_COMMAND} > -fi > - > -# Get file path of UniversalPayloadBuild.sh > -uplbld_filepath=${BASH_SOURCE:-$0} > -# Remove ".sh" extension > -uplbld_filepath_noext=${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.<BR> > +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > + > +if command -v ${PYTHON_COMMAND} >/dev/null 2>&1; then > + echo python_exe=${PYTHON_COMMAND} > +fi > + > +# Get file path of UniversalPayloadBuild.sh > +uplbld_filepath=${BASH_SOURCE:-$0} > +# Remove ".sh" extension > +uplbld_filepath_noext=${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.<BR> > -# Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR> > -# 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-Github- > 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: ". > edksetup.sh" > -# > -# CYGWIN users: Your path and filename related environment variables should > be > -# set up in the unix style. This script will make the necessary conversions > 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="edksetup.sh" > -RECONFIG=FALSE > - > -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 > directory." > - echo > - echo Please note: This script must be \'sourced\' so the environment can be > changed. > - echo ". $SCRIPTNAME" > - echo "source $SCRIPTNAME" > -} > - > -SetWorkspace() > -{ > - # > - # If WORKSPACE is already set, then we can return right now > - # > - export PYTHONHASHSEED=1 > - 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=$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=$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 incorrectly > - echo in your shell, or point EDK_TOOLS_PATH at the directory that > contains > - echo the EDK2 BuildEnv script. > - return 1 > - fi > -} > - > -SetupPython3() > -{ > - export PYTHON_COMMAND=python3 > -} > - > -SourceEnv() > -{ > - SetupPython3 > - SetWorkspace > - SetupEnv > -} > - > -I=$# > -while [ $I -gt 0 ] > -do > - case "$1" in > - BaseTools) > - # Ignore argument for backwards compatibility > - shift > - ;; > - --reconfig) > - RECONFIG=TRUE > - shift > - ;; > - *) > - HelpMsg > - break > - ;; > - esac > - I=$((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.<BR> > +# Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR> > +# 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-Github- > 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: ". > edksetup.sh" > +# > +# CYGWIN users: Your path and filename related environment variables should > be > +# set up in the unix style. This script will make the necessary conversions > 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="edksetup.sh" > +RECONFIG=FALSE > + > +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 > directory." > + echo > + echo Please note: This script must be \'sourced\' so the environment can be > changed. > + echo ". $SCRIPTNAME" > + echo "source $SCRIPTNAME" > +} > + > +SetWorkspace() > +{ > + # > + # If WORKSPACE is already set, then we can return right now > + # > + export PYTHONHASHSEED=1 > + 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=$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=$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 incorrectly > + echo in your shell, or point EDK_TOOLS_PATH at the directory that > contains > + echo the EDK2 BuildEnv script. > + return 1 > + fi > +} > + > +SetupPython3() > +{ > + export PYTHON_COMMAND=python3 > +} > + > +SourceEnv() > +{ > + SetupPython3 > + SetWorkspace > + SetupEnv > +} > + > +I=$# > +while [ $I -gt 0 ] > +do > + case "$1" in > + BaseTools) > + # Ignore argument for backwards compatibility > + shift > + ;; > + --reconfig) > + RECONFIG=TRUE > + shift > + ;; > + *) > + HelpMsg > + break > + ;; > + esac > + I=$((I - 1)) > +done > + > +if [ $I -gt 0 ] > +then > + return 1 > +fi > + > +SourceEnv > + > +unset SCRIPTNAME RECONFIG > + > +return $? > -- > 2.37.0.windows.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#105834): https://edk2.groups.io/g/devel/message/105834 Mute This Topic: https://groups.io/mt/99079640/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/leave/9847357/21656/1706620634/xyzzy [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-