diff --git a/UefiCpuPkg/SecCore/SecBist.c b/UefiCpuPkg/SecCore/SecBist.c
index cd2e340171..5016f37d7b 100644
--- a/UefiCpuPkg/SecCore/SecBist.c
+++ b/UefiCpuPkg/SecCore/SecBist.c
@@ -8,6 +8,45 @@
#include "SecMain.h"
+/**
+ Implementation of the PlatformInformation service in EFI_SEC_PLATFORM_INFORMATION_PPI.
+
+ @param PeiServices Pointer to the PEI Services Table.
+ @param StructureSize Pointer to the variable describing size of the input buffer.
+ @param PlatformInformationRecord Pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD.
+
+ @retval EFI_SUCCESS The data was successfully returned.
+ @retval EFI_BUFFER_TOO_SMALL The buffer was too small.
+
+**/
+EFI_STATUS
+EFIAPI
+SecPlatformInformationBist (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN OUT UINT64 *StructureSize,
+ OUT EFI_SEC_PLATFORM_INFORMATION_RECORD *PlatformInformationRecord
+ );
+
+/**
+ Implementation of the PlatformInformation2 service in EFI_SEC_PLATFORM_INFORMATION2_PPI.
+
+ @param PeiServices The pointer to the PEI Services Table.
+ @param StructureSize The pointer to the variable describing size of the input buffer.
+ @param PlatformInformationRecord2 The pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD2.
+
+ @retval EFI_SUCCESS The data was successfully returned.
+ @retval EFI_BUFFER_TOO_SMALL The buffer was too small. The current buffer size needed to
+ hold the record is returned in StructureSize.
+
+**/
+EFI_STATUS
+EFIAPI
+SecPlatformInformation2Bist (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN OUT UINT64 *StructureSize,
+ OUT EFI_SEC_PLATFORM_INFORMATION_RECORD2 *PlatformInformationRecord2
+ );
+
EFI_SEC_PLATFORM_INFORMATION_PPI mSecPlatformInformation = {
SecPlatformInformationBist
};
diff --git a/UefiCpuPkg/SecCore/SecCore.inf b/UefiCpuPkg/SecCore/SecCore.inf
index 94966f4edf..255d3a9a3f 100644
--- a/UefiCpuPkg/SecCore/SecCore.inf
+++ b/UefiCpuPkg/SecCore/SecCore.inf
@@ -31,11 +31,14 @@
SecMain.c
SecMain.h
FindPeiCore.c
- SecBist.c
[Sources.IA32]
Ia32/ResetVec.nasmb
+[Sources.IA32, Sources.X64]
+ SecBist.c
+ SecTemporaryRamDone.c
+
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
@@ -55,9 +58,11 @@
PeiServicesLib
PeiServicesTablePointerLib
HobLib
- CpuPageTableLib
StackCheckLib
+[LibraryClasses.IA32, LibraryClasses.X64]
+ CpuPageTableLib
+
[Ppis]
## SOMETIMES_CONSUMES
## PRODUCES
diff --git a/UefiCpuPkg/SecCore/SecCoreNative.inf b/UefiCpuPkg/SecCore/SecCoreNative.inf
index facb79c2c4..4d9f385e06 100644
--- a/UefiCpuPkg/SecCore/SecCoreNative.inf
+++ b/UefiCpuPkg/SecCore/SecCoreNative.inf
@@ -31,7 +31,10 @@
SecMain.c
SecMain.h
FindPeiCore.c
+
+[Sources.IA32, Sources.X64]
SecBist.c
+ SecTemporaryRamDone.c
[Packages]
MdePkg/MdePkg.dec
@@ -52,9 +55,11 @@
PeiServicesLib
PeiServicesTablePointerLib
HobLib
- CpuPageTableLib
StackCheckLib
+[LibraryClasses.IA32, LibraryClasses.X64]
+ CpuPageTableLib
+
[Ppis]
## SOMETIMES_CONSUMES
## PRODUCES
diff --git a/UefiCpuPkg/SecCore/SecMain.c b/UefiCpuPkg/SecCore/SecMain.c
index 23a75d3076..f6917e88d1 100644
--- a/UefiCpuPkg/SecCore/SecMain.c
+++ b/UefiCpuPkg/SecCore/SecMain.c
@@ -2,12 +2,48 @@
C functions in SEC
Copyright (c) 2008 - 2019, Intel Corporation. All rights reserved.
+ Copyright (c) 2025, Ventana Micro Systems Inc. All rights reserved.
+
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "SecMain.h"
+#if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
+
+#define SEC_IDT_ENTRY_COUNT 34
+
+typedef struct _SEC_IDT_TABLE {
+ //
+ // Reserved 8 bytes preceding IDT to store EFI_PEI_SERVICES**, since IDT base
+ // address should be 8-byte alignment.
+ // Note: For IA32, only the 4 bytes immediately preceding IDT is used to store
+ // EFI_PEI_SERVICES**
+ //
+ UINT64 PeiService;
+ IA32_IDT_GATE_DESCRIPTOR IdtTable[SEC_IDT_ENTRY_COUNT];
+} SEC_IDT_TABLE;
+
+//
+// These are IDT entries pointing to 10:FFFFFFE4h.
+//
+UINT64 mIdtEntryTemplate = 0xffff8e000010ffe4ULL;
+
+/**
+ TemporaryRamDone() disables the use of Temporary RAM. If present, this service is invoked
+ by the PEI Foundation after the EFI_PEI_PERMANANT_MEMORY_INSTALLED_PPI is installed.
+
+ @retval EFI_SUCCESS Use of Temporary RAM was disabled.
+ @retval EFI_INVALID_PARAMETER Temporary RAM could not be disabled.
+
+**/
+EFI_STATUS
+EFIAPI
+SecTemporaryRamDone (
+ VOID
+ );
+
EFI_PEI_TEMPORARY_RAM_DONE_PPI gSecTemporaryRamDonePpi = {
SecTemporaryRamDone
};
@@ -34,136 +70,18 @@ EFI_PEI_PPI_DESCRIPTOR mPeiSecPlatformInformationPpi[] = {
&mSecPlatformInformationPpi
}
};
-
-/**
- Migrates the Global Descriptor Table (GDT) to permanent memory.
-
- @retval EFI_SUCCESS The GDT was migrated successfully.
- @retval EFI_OUT_OF_RESOURCES The GDT could not be migrated due to lack of available memory.
-
-**/
-EFI_STATUS
-MigrateGdt (
- VOID
- )
-{
- EFI_STATUS Status;
- UINTN GdtBufferSize;
- IA32_DESCRIPTOR Gdtr;
- VOID *GdtBuffer;
-
- AsmReadGdtr ((IA32_DESCRIPTOR *)&Gdtr);
- GdtBufferSize = sizeof (IA32_SEGMENT_DESCRIPTOR) -1 + Gdtr.Limit + 1;
-
- Status = PeiServicesAllocatePool (
- GdtBufferSize,
- &GdtBuffer
- );
- ASSERT (GdtBuffer != NULL);
- if (EFI_ERROR (Status)) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- GdtBuffer = ALIGN_POINTER (GdtBuffer, sizeof (IA32_SEGMENT_DESCRIPTOR));
- CopyMem (GdtBuffer, (VOID *)Gdtr.Base, Gdtr.Limit + 1);
- Gdtr.Base = (UINTN)GdtBuffer;
- AsmWriteGdtr (&Gdtr);
-
- return EFI_SUCCESS;
-}
-
-/**
- Get Paging Mode
-
- @retval Paging Mode.
-**/
-PAGING_MODE
-GetPagingMode (
- VOID
- )
-{
- IA32_CR4 Cr4;
- BOOLEAN Page5LevelSupport;
- UINT32 RegEax;
- CPUID_EXTENDED_CPU_SIG_EDX RegEdx;
- BOOLEAN Page1GSupport;
- PAGING_MODE PagingMode;
-
- //
- // Check Page5Level Support or not.
- //
- Cr4.UintN = AsmReadCr4 ();
- Page5LevelSupport = (Cr4.Bits.LA57 ? TRUE : FALSE);
-
- //
- // Check Page1G Support or not.
- //
- Page1GSupport = FALSE;
- AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);
- if (RegEax >= CPUID_EXTENDED_CPU_SIG) {
- AsmCpuid (CPUID_EXTENDED_CPU_SIG, NULL, NULL, NULL, &RegEdx.Uint32);
- if (RegEdx.Bits.Page1GB != 0) {
- Page1GSupport = TRUE;
- }
- }
-
- //
- // Decide Paging Mode according Page5LevelSupport & Page1GSupport.
- //
- if (Page5LevelSupport) {
- PagingMode = Page1GSupport ? Paging5Level1GB : Paging5Level;
- } else {
- PagingMode = Page1GSupport ? Paging4Level1GB : Paging4Level;
- }
-
- return PagingMode;
-}
-
-/**
- Get max physical address supported by specific page mode
-
- @param[in] PagingMode The paging mode.
-
- @retval Max Address.
-**/
-UINT32
-GetMaxAddress (
- IN PAGING_MODE PagingMode
- )
-{
- CPUID_VIR_PHY_ADDRESS_SIZE_EAX VirPhyAddressSize;
- UINT32 MaxExtendedFunctionId;
- UINT32 MaxAddressBits;
-
- VirPhyAddressSize.Uint32 = 0;
-
- //
- // Get Maximum Physical Address Bits
- // Get the number of address lines; Maximum Physical Address is 2^PhysicalAddressBits - 1.
- // If CPUID does not supported, then use a max value of 36 as per SDM 3A, 4.1.4.
- //
- AsmCpuid (CPUID_EXTENDED_FUNCTION, &MaxExtendedFunctionId, NULL, NULL, NULL);
- if (MaxExtendedFunctionId >= CPUID_VIR_PHY_ADDRESS_SIZE) {
- AsmCpuid (CPUID_VIR_PHY_ADDRESS_SIZE, &VirPhyAddressSize.Uint32, NULL, NULL, NULL);
- MaxAddressBits = VirPhyAddressSize.Bits.PhysicalAddressBits;
- } else {
- MaxAddressBits = 36;
- }
-
- if ((PagingMode == Paging4Level1GB) || (PagingMode == Paging4Level)) {
+#else
+EFI_PEI_PPI_DESCRIPTOR mPeiSecPlatformInformationPpi[] = {
+ {
//
- // The max liner address bits is 48 for 4 level page table.
+ // SecPerformance PPI notify descriptor.
//
- MaxAddressBits = MIN (VirPhyAddressSize.Bits.PhysicalAddressBits, 48);
+ EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
+ &gPeiSecPerformancePpiGuid,
+ (VOID *)(UINTN)SecPerformancePpiCallBack
}
-
- return MaxAddressBits;
-}
-
-//
-// These are IDT entries pointing to 10:FFFFFFE4h.
-//
-UINT64 mIdtEntryTemplate = 0xffff8e000010ffe4ULL;
+};
+#endif
/**
Caller provided function to be invoked at the end of InitializeDebugAgent().
@@ -241,9 +159,6 @@ SecStartup (
)
{
EFI_SEC_PEI_HAND_OFF SecCoreData;
- IA32_DESCRIPTOR IdtDescriptor;
- SEC_IDT_TABLE IdtTableInStack;
- UINT32 Index;
UINT32 PeiStackSize;
EFI_STATUS Status;
@@ -282,6 +197,11 @@ SecStartup (
//
InitializeFloatingPointUnits ();
+ #if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
+ IA32_DESCRIPTOR IdtDescriptor;
+ SEC_IDT_TABLE IdtTableInStack;
+ UINT32 Index;
+
// |-------------------|---->
// |IDT Table |
// |-------------------|
@@ -307,6 +227,7 @@ SecStartup (
IdtDescriptor.Limit = (UINT16)(sizeof (IdtTableInStack.IdtTable) - 1);
AsmWriteIdtr (&IdtDescriptor);
+ #endif
//
// Setup the default exception handlers
@@ -520,179 +441,3 @@ SecStartupPhase2 (
//
UNREACHABLE ();
}
-
-/**
- TemporaryRamDone() disables the use of Temporary RAM. If present, this service is invoked
- by the PEI Foundation after the EFI_PEI_PERMANANT_MEMORY_INSTALLED_PPI is installed.
-
- @retval EFI_SUCCESS Use of Temporary RAM was disabled.
- @retval EFI_INVALID_PARAMETER Temporary RAM could not be disabled.
-
-**/
-EFI_STATUS
-EFIAPI
-SecTemporaryRamDone (
- VOID
- )
-{
- EFI_STATUS Status;
- EFI_STATUS Status2;
- UINTN Index;
- BOOLEAN State;
- EFI_PEI_PPI_DESCRIPTOR *PeiPpiDescriptor;
- REPUBLISH_SEC_PPI_PPI *RepublishSecPpiPpi;
- IA32_CR0 Cr0;
- PAGING_MODE PagingMode;
- UINT32 MaxAddressBits;
- UINTN PageTable;
- EFI_PHYSICAL_ADDRESS Buffer;
- UINTN BufferSize;
- UINT64 Length;
- UINT64 Address;
- IA32_MAP_ATTRIBUTE MapAttribute;
- IA32_MAP_ATTRIBUTE MapMask;
-
- PageTable = 0;
- BufferSize = 0;
- MapAttribute.Uint64 = 0;
- MapAttribute.Bits.Present = 1;
- MapAttribute.Bits.ReadWrite = 1;
- MapMask.Uint64 = MAX_UINT64;
-
- //
- // Republish Sec Platform Information(2) PPI
- //
- RepublishSecPlatformInformationPpi ();
-
- //
- // Re-install SEC PPIs using a PEIM produced service if published
- //
- for (Index = 0, Status = EFI_SUCCESS; Status == EFI_SUCCESS; Index++) {
- Status = PeiServicesLocatePpi (
- &gRepublishSecPpiPpiGuid,
- Index,
- &PeiPpiDescriptor,
- (VOID **)&RepublishSecPpiPpi
- );
- if (!EFI_ERROR (Status)) {
- DEBUG ((DEBUG_INFO, "Calling RepublishSecPpi instance %d.\n", Index));
- Status2 = RepublishSecPpiPpi->RepublishSecPpis ();
- ASSERT_EFI_ERROR (Status2);
- }
- }
-
- //
- // Migrate DebugAgentContext.
- //
- InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, NULL, NULL);
-
- //
- // Disable interrupts and save current interrupt state
- //
- State = SaveAndDisableInterrupts ();
-
- //
- // Migrate GDT before NEM near down
- //
- if (PcdGetBool (PcdMigrateTemporaryRamFirmwareVolumes)) {
- Status = MigrateGdt ();
- ASSERT_EFI_ERROR (Status);
- }
-
- //
- // Migrate page table to permanent memory mapping entire physical address space if CR0.PG is set.
- //
- Cr0.UintN = AsmReadCr0 ();
- if (Cr0.Bits.PG != 0) {
- //
- // Assume CPU runs in 64bit mode if paging is enabled.
- //
- ASSERT (sizeof (UINTN) == sizeof (UINT64));
-
- //
- // Get PagingMode & MaxAddressBits.
- //
- PagingMode = GetPagingMode ();
- MaxAddressBits = GetMaxAddress (PagingMode);
- DEBUG ((DEBUG_INFO, "SecTemporaryRamDone: PagingMode = 0x%lx, MaxAddressBits = %d\n", PagingMode, MaxAddressBits));
-
- //
- // Create page table to cover the max mapping address in physical memory before Temp
- // Ram Exit. The max mapping address is defined by PcdMaxMappingAddressBeforeTempRamExit.
- //
- Length = FixedPcdGet64 (PcdMaxMappingAddressBeforeTempRamExit);
- Length = MIN (LShiftU64 (1, MaxAddressBits), Length);
- if (Length != 0) {
- Status = PageTableMap (&PageTable, PagingMode, 0, &BufferSize, 0, Length, &MapAttribute, &MapMask, NULL);
- ASSERT (Status == EFI_BUFFER_TOO_SMALL);
- if (Status != EFI_BUFFER_TOO_SMALL) {
- return Status;
- }
-
- Status = PeiServicesAllocatePages (
- EfiBootServicesData,
- EFI_SIZE_TO_PAGES (BufferSize),
- &Buffer
- );
- if (EFI_ERROR (Status)) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- Status = PageTableMap (&PageTable, PagingMode, (VOID *)(UINTN)Buffer, &BufferSize, 0, Length, &MapAttribute, &MapMask, NULL);
- ASSERT (BufferSize == 0);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "SecTemporaryRamDone: Failed to create page table in physical memory before Temp Ram Exit: %r.\n", Status));
- CpuDeadLoop ();
- }
-
- AsmWriteCr3 (PageTable);
- }
- }
-
- //
- // Disable Temporary RAM after Stack and Heap have been migrated at this point.
- //
- SecPlatformDisableTemporaryMemory ();
-
- //
- // Expanding the page table to cover the entire memory space since the physical memory is WB after TempRamExit.
- //
- if ((Cr0.Bits.PG != 0) && (Length < LShiftU64 (1, MaxAddressBits))) {
- Address = Length;
- Length = LShiftU64 (1, MaxAddressBits) - Length;
-
- MapAttribute.Uint64 = Address;
- MapAttribute.Bits.Present = 1;
- MapAttribute.Bits.ReadWrite = 1;
-
- Status = PageTableMap (&PageTable, PagingMode, 0, &BufferSize, Address, Length, &MapAttribute, &MapMask, NULL);
- ASSERT (Status == EFI_BUFFER_TOO_SMALL);
- if (Status != EFI_BUFFER_TOO_SMALL) {
- return Status;
- }
-
- Status = PeiServicesAllocatePages (
- EfiBootServicesData,
- EFI_SIZE_TO_PAGES (BufferSize),
- &Buffer
- );
- if (EFI_ERROR (Status)) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- Status = PageTableMap (&PageTable, PagingMode, (VOID *)(UINTN)Buffer, &BufferSize, Address, Length, &MapAttribute, &MapMask, NULL);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "SecTemporaryRamDone: Failed to create full range page table in physical memory after Temp Ram Exit: %r.\n", Status));
- CpuDeadLoop ();
- }
-
- AsmWriteCr3 (PageTable);
- }
-
- //
- // Restore original interrupt state
- //
- SetInterruptState (State);
-
- return EFI_SUCCESS;
-}
diff --git a/UefiCpuPkg/SecCore/SecMain.h b/UefiCpuPkg/SecCore/SecMain.h
index 81c561424e..6b312a8ac1 100644
--- a/UefiCpuPkg/SecCore/SecMain.h
+++ b/UefiCpuPkg/SecCore/SecMain.h
@@ -33,36 +33,6 @@
#include
#include
#include
-#include
-#include
-#include
-
-#define SEC_IDT_ENTRY_COUNT 34
-
-typedef struct _SEC_IDT_TABLE {
- //
- // Reserved 8 bytes preceding IDT to store EFI_PEI_SERVICES**, since IDT base
- // address should be 8-byte alignment.
- // Note: For IA32, only the 4 bytes immediately preceding IDT is used to store
- // EFI_PEI_SERVICES**
- //
- UINT64 PeiService;
- IA32_IDT_GATE_DESCRIPTOR IdtTable[SEC_IDT_ENTRY_COUNT];
-} SEC_IDT_TABLE;
-
-/**
- TemporaryRamDone() disables the use of Temporary RAM. If present, this service is invoked
- by the PEI Foundation after the EFI_PEI_PERMANANT_MEMORY_INSTALLED_PPI is installed.
-
- @retval EFI_SUCCESS Use of Temporary RAM was disabled.
- @retval EFI_INVALID_PARAMETER Temporary RAM could not be disabled.
-
-**/
-EFI_STATUS
-EFIAPI
-SecTemporaryRamDone (
- VOID
- );
/**
Entry point to the C language phase of SEC. After the SEC assembly
@@ -101,45 +71,6 @@ FindAndReportEntryPoints (
OUT EFI_PEI_CORE_ENTRY_POINT *PeiCoreEntryPoint
);
-/**
- Implementation of the PlatformInformation service in EFI_SEC_PLATFORM_INFORMATION_PPI.
-
- @param PeiServices Pointer to the PEI Services Table.
- @param StructureSize Pointer to the variable describing size of the input buffer.
- @param PlatformInformationRecord Pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD.
-
- @retval EFI_SUCCESS The data was successfully returned.
- @retval EFI_BUFFER_TOO_SMALL The buffer was too small.
-
-**/
-EFI_STATUS
-EFIAPI
-SecPlatformInformationBist (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN OUT UINT64 *StructureSize,
- OUT EFI_SEC_PLATFORM_INFORMATION_RECORD *PlatformInformationRecord
- );
-
-/**
- Implementation of the PlatformInformation2 service in EFI_SEC_PLATFORM_INFORMATION2_PPI.
-
- @param PeiServices The pointer to the PEI Services Table.
- @param StructureSize The pointer to the variable describing size of the input buffer.
- @param PlatformInformationRecord2 The pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD2.
-
- @retval EFI_SUCCESS The data was successfully returned.
- @retval EFI_BUFFER_TOO_SMALL The buffer was too small. The current buffer size needed to
- hold the record is returned in StructureSize.
-
-**/
-EFI_STATUS
-EFIAPI
-SecPlatformInformation2Bist (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN OUT UINT64 *StructureSize,
- OUT EFI_SEC_PLATFORM_INFORMATION_RECORD2 *PlatformInformationRecord2
- );
-
/**
Republish SecPlatformInformationPpi/SecPlatformInformation2Ppi.
diff --git a/UefiCpuPkg/SecCore/SecTemporaryRamDone.c b/UefiCpuPkg/SecCore/SecTemporaryRamDone.c
new file mode 100644
index 0000000000..f921d457e8
--- /dev/null
+++ b/UefiCpuPkg/SecCore/SecTemporaryRamDone.c
@@ -0,0 +1,315 @@
+/** @file
+ SEC platform information(2) PPI.
+
+ Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.
+ Copyright (c) 2025, Ventana Micro Systems Inc. All rights reserved.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include
+#include
+#include
+#include "SecMain.h"
+
+/**
+ Migrates the Global Descriptor Table (GDT) to permanent memory.
+
+ @retval EFI_SUCCESS The GDT was migrated successfully.
+ @retval EFI_OUT_OF_RESOURCES The GDT could not be migrated due to lack of available memory.
+
+**/
+EFI_STATUS
+MigrateGdt (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINTN GdtBufferSize;
+ IA32_DESCRIPTOR Gdtr;
+ VOID *GdtBuffer;
+
+ AsmReadGdtr ((IA32_DESCRIPTOR *)&Gdtr);
+ GdtBufferSize = sizeof (IA32_SEGMENT_DESCRIPTOR) -1 + Gdtr.Limit + 1;
+
+ Status = PeiServicesAllocatePool (
+ GdtBufferSize,
+ &GdtBuffer
+ );
+ ASSERT (GdtBuffer != NULL);
+ if (EFI_ERROR (Status)) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ GdtBuffer = ALIGN_POINTER (GdtBuffer, sizeof (IA32_SEGMENT_DESCRIPTOR));
+ CopyMem (GdtBuffer, (VOID *)Gdtr.Base, Gdtr.Limit + 1);
+ Gdtr.Base = (UINTN)GdtBuffer;
+ AsmWriteGdtr (&Gdtr);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Get Paging Mode
+
+ @retval Paging Mode.
+**/
+PAGING_MODE
+GetPagingMode (
+ VOID
+ )
+{
+ IA32_CR4 Cr4;
+ BOOLEAN Page5LevelSupport;
+ UINT32 RegEax;
+ CPUID_EXTENDED_CPU_SIG_EDX RegEdx;
+ BOOLEAN Page1GSupport;
+ PAGING_MODE PagingMode;
+
+ //
+ // Check Page5Level Support or not.
+ //
+ Cr4.UintN = AsmReadCr4 ();
+ Page5LevelSupport = (Cr4.Bits.LA57 ? TRUE : FALSE);
+
+ //
+ // Check Page1G Support or not.
+ //
+ Page1GSupport = FALSE;
+ AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);
+ if (RegEax >= CPUID_EXTENDED_CPU_SIG) {
+ AsmCpuid (CPUID_EXTENDED_CPU_SIG, NULL, NULL, NULL, &RegEdx.Uint32);
+ if (RegEdx.Bits.Page1GB != 0) {
+ Page1GSupport = TRUE;
+ }
+ }
+
+ //
+ // Decide Paging Mode according Page5LevelSupport & Page1GSupport.
+ //
+ if (Page5LevelSupport) {
+ PagingMode = Page1GSupport ? Paging5Level1GB : Paging5Level;
+ } else {
+ PagingMode = Page1GSupport ? Paging4Level1GB : Paging4Level;
+ }
+
+ return PagingMode;
+}
+
+/**
+ Get max physical address supported by specific page mode
+
+ @param[in] PagingMode The paging mode.
+
+ @retval Max Address.
+**/
+UINT32
+GetMaxAddress (
+ IN PAGING_MODE PagingMode
+ )
+{
+ CPUID_VIR_PHY_ADDRESS_SIZE_EAX VirPhyAddressSize;
+ UINT32 MaxExtendedFunctionId;
+ UINT32 MaxAddressBits;
+
+ VirPhyAddressSize.Uint32 = 0;
+
+ //
+ // Get Maximum Physical Address Bits
+ // Get the number of address lines; Maximum Physical Address is 2^PhysicalAddressBits - 1.
+ // If CPUID does not supported, then use a max value of 36 as per SDM 3A, 4.1.4.
+ //
+ AsmCpuid (CPUID_EXTENDED_FUNCTION, &MaxExtendedFunctionId, NULL, NULL, NULL);
+ if (MaxExtendedFunctionId >= CPUID_VIR_PHY_ADDRESS_SIZE) {
+ AsmCpuid (CPUID_VIR_PHY_ADDRESS_SIZE, &VirPhyAddressSize.Uint32, NULL, NULL, NULL);
+ MaxAddressBits = VirPhyAddressSize.Bits.PhysicalAddressBits;
+ } else {
+ MaxAddressBits = 36;
+ }
+
+ if ((PagingMode == Paging4Level1GB) || (PagingMode == Paging4Level)) {
+ //
+ // The max liner address bits is 48 for 4 level page table.
+ //
+ MaxAddressBits = MIN (VirPhyAddressSize.Bits.PhysicalAddressBits, 48);
+ }
+
+ return MaxAddressBits;
+}
+
+/**
+ TemporaryRamDone() disables the use of Temporary RAM. If present, this service is invoked
+ by the PEI Foundation after the EFI_PEI_PERMANANT_MEMORY_INSTALLED_PPI is installed.
+
+ @retval EFI_SUCCESS Use of Temporary RAM was disabled.
+ @retval EFI_INVALID_PARAMETER Temporary RAM could not be disabled.
+
+**/
+EFI_STATUS
+EFIAPI
+SecTemporaryRamDone (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_STATUS Status2;
+ UINTN Index;
+ BOOLEAN State;
+ EFI_PEI_PPI_DESCRIPTOR *PeiPpiDescriptor;
+ REPUBLISH_SEC_PPI_PPI *RepublishSecPpiPpi;
+ IA32_CR0 Cr0;
+ PAGING_MODE PagingMode;
+ UINT32 MaxAddressBits;
+ UINTN PageTable;
+ EFI_PHYSICAL_ADDRESS Buffer;
+ UINTN BufferSize;
+ UINT64 Length;
+ UINT64 Address;
+ IA32_MAP_ATTRIBUTE MapAttribute;
+ IA32_MAP_ATTRIBUTE MapMask;
+
+ PageTable = 0;
+ BufferSize = 0;
+ MapAttribute.Uint64 = 0;
+ MapAttribute.Bits.Present = 1;
+ MapAttribute.Bits.ReadWrite = 1;
+ MapMask.Uint64 = MAX_UINT64;
+
+ //
+ // Republish Sec Platform Information(2) PPI
+ //
+ RepublishSecPlatformInformationPpi ();
+
+ //
+ // Re-install SEC PPIs using a PEIM produced service if published
+ //
+ for (Index = 0, Status = EFI_SUCCESS; Status == EFI_SUCCESS; Index++) {
+ Status = PeiServicesLocatePpi (
+ &gRepublishSecPpiPpiGuid,
+ Index,
+ &PeiPpiDescriptor,
+ (VOID **)&RepublishSecPpiPpi
+ );
+ if (!EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_INFO, "Calling RepublishSecPpi instance %d.\n", Index));
+ Status2 = RepublishSecPpiPpi->RepublishSecPpis ();
+ ASSERT_EFI_ERROR (Status2);
+ }
+ }
+
+ //
+ // Migrate DebugAgentContext.
+ //
+ InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, NULL, NULL);
+
+ //
+ // Disable interrupts and save current interrupt state
+ //
+ State = SaveAndDisableInterrupts ();
+
+ //
+ // Migrate GDT before NEM near down
+ //
+ if (PcdGetBool (PcdMigrateTemporaryRamFirmwareVolumes)) {
+ Status = MigrateGdt ();
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ //
+ // Migrate page table to permanent memory mapping entire physical address space if CR0.PG is set.
+ //
+ Cr0.UintN = AsmReadCr0 ();
+ if (Cr0.Bits.PG != 0) {
+ //
+ // Assume CPU runs in 64bit mode if paging is enabled.
+ //
+ ASSERT (sizeof (UINTN) == sizeof (UINT64));
+
+ //
+ // Get PagingMode & MaxAddressBits.
+ //
+ PagingMode = GetPagingMode ();
+ MaxAddressBits = GetMaxAddress (PagingMode);
+ DEBUG ((DEBUG_INFO, "SecTemporaryRamDone: PagingMode = 0x%lx, MaxAddressBits = %d\n", PagingMode, MaxAddressBits));
+
+ //
+ // Create page table to cover the max mapping address in physical memory before Temp
+ // Ram Exit. The max mapping address is defined by PcdMaxMappingAddressBeforeTempRamExit.
+ //
+ Length = FixedPcdGet64 (PcdMaxMappingAddressBeforeTempRamExit);
+ Length = MIN (LShiftU64 (1, MaxAddressBits), Length);
+ if (Length != 0) {
+ Status = PageTableMap (&PageTable, PagingMode, 0, &BufferSize, 0, Length, &MapAttribute, &MapMask, NULL);
+ ASSERT (Status == EFI_BUFFER_TOO_SMALL);
+ if (Status != EFI_BUFFER_TOO_SMALL) {
+ return Status;
+ }
+
+ Status = PeiServicesAllocatePages (
+ EfiBootServicesData,
+ EFI_SIZE_TO_PAGES (BufferSize),
+ &Buffer
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = PageTableMap (&PageTable, PagingMode, (VOID *)(UINTN)Buffer, &BufferSize, 0, Length, &MapAttribute, &MapMask, NULL);
+ ASSERT (BufferSize == 0);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "SecTemporaryRamDone: Failed to create page table in physical memory before Temp Ram Exit: %r.\n", Status));
+ CpuDeadLoop ();
+ }
+
+ AsmWriteCr3 (PageTable);
+ }
+ }
+
+ //
+ // Disable Temporary RAM after Stack and Heap have been migrated at this point.
+ //
+ SecPlatformDisableTemporaryMemory ();
+
+ //
+ // Expanding the page table to cover the entire memory space since the physical memory is WB after TempRamExit.
+ //
+ if ((Cr0.Bits.PG != 0) && (Length < LShiftU64 (1, MaxAddressBits))) {
+ Address = Length;
+ Length = LShiftU64 (1, MaxAddressBits) - Length;
+
+ MapAttribute.Uint64 = Address;
+ MapAttribute.Bits.Present = 1;
+ MapAttribute.Bits.ReadWrite = 1;
+
+ Status = PageTableMap (&PageTable, PagingMode, 0, &BufferSize, Address, Length, &MapAttribute, &MapMask, NULL);
+ ASSERT (Status == EFI_BUFFER_TOO_SMALL);
+ if (Status != EFI_BUFFER_TOO_SMALL) {
+ return Status;
+ }
+
+ Status = PeiServicesAllocatePages (
+ EfiBootServicesData,
+ EFI_SIZE_TO_PAGES (BufferSize),
+ &Buffer
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = PageTableMap (&PageTable, PagingMode, (VOID *)(UINTN)Buffer, &BufferSize, Address, Length, &MapAttribute, &MapMask, NULL);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "SecTemporaryRamDone: Failed to create full range page table in physical memory after Temp Ram Exit: %r.\n", Status));
+ CpuDeadLoop ();
+ }
+
+ AsmWriteCr3 (PageTable);
+ }
+
+ //
+ // Restore original interrupt state
+ //
+ SetInterruptState (State);
+
+ return EFI_SUCCESS;
+}