diff options
-rw-r--r-- | UefiCpuPkg/SecCore/SecCore.inf | 1 | ||||
-rw-r--r-- | UefiCpuPkg/SecCore/SecCoreNative.inf | 1 | ||||
-rw-r--r-- | UefiCpuPkg/SecCore/SecMain.c | 205 |
3 files changed, 126 insertions, 81 deletions
diff --git a/UefiCpuPkg/SecCore/SecCore.inf b/UefiCpuPkg/SecCore/SecCore.inf index 4f732cccb7..20a2ccef0b 100644 --- a/UefiCpuPkg/SecCore/SecCore.inf +++ b/UefiCpuPkg/SecCore/SecCore.inf @@ -78,6 +78,7 @@ [Pcd]
gUefiCpuPkgTokenSpaceGuid.PcdPeiTemporaryRamStackSize ## CONSUMES
+ gUefiCpuPkgTokenSpaceGuid.PcdMaxMappingAddressBeforeTempRamExit ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdMigrateTemporaryRamFirmwareVolumes ## CONSUMES
[UserExtensions.TianoCore."ExtraFiles"]
diff --git a/UefiCpuPkg/SecCore/SecCoreNative.inf b/UefiCpuPkg/SecCore/SecCoreNative.inf index 454a3629e5..6d6d306294 100644 --- a/UefiCpuPkg/SecCore/SecCoreNative.inf +++ b/UefiCpuPkg/SecCore/SecCoreNative.inf @@ -75,6 +75,7 @@ [Pcd]
gUefiCpuPkgTokenSpaceGuid.PcdPeiTemporaryRamStackSize ## CONSUMES
+ gUefiCpuPkgTokenSpaceGuid.PcdMaxMappingAddressBeforeTempRamExit ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdMigrateTemporaryRamFirmwareVolumes ## CONSUMES
[UserExtensions.TianoCore."ExtraFiles"]
diff --git a/UefiCpuPkg/SecCore/SecMain.c b/UefiCpuPkg/SecCore/SecMain.c index b0ab6cdae4..23a75d3076 100644 --- a/UefiCpuPkg/SecCore/SecMain.c +++ b/UefiCpuPkg/SecCore/SecMain.c @@ -73,40 +73,21 @@ MigrateGdt ( }
/**
- Migrate page table to permanent memory mapping entire physical address space.
-
- @retval EFI_SUCCESS The PageTable was migrated successfully.
- @retval EFI_UNSUPPORTED Unsupport to migrate page table to permanent memory if IA-32e Mode not actived.
- @retval EFI_OUT_OF_RESOURCES The PageTable could not be migrated due to lack of available memory.
+ Get Paging Mode
+ @retval Paging Mode.
**/
-EFI_STATUS
-MigratePageTable (
+PAGING_MODE
+GetPagingMode (
VOID
)
{
- EFI_STATUS Status;
- IA32_CR4 Cr4;
- BOOLEAN Page5LevelSupport;
- UINT32 RegEax;
- CPUID_EXTENDED_CPU_SIG_EDX RegEdx;
- BOOLEAN Page1GSupport;
- PAGING_MODE PagingMode;
- CPUID_VIR_PHY_ADDRESS_SIZE_EAX VirPhyAddressSize;
- UINT32 MaxExtendedFunctionId;
- UINTN PageTable;
- EFI_PHYSICAL_ADDRESS Buffer;
- UINTN BufferSize;
- IA32_MAP_ATTRIBUTE MapAttribute;
- IA32_MAP_ATTRIBUTE MapMask;
-
- VirPhyAddressSize.Uint32 = 0;
- PageTable = 0;
- BufferSize = 0;
- MapAttribute.Uint64 = 0;
- MapMask.Uint64 = MAX_UINT64;
- MapAttribute.Bits.Present = 1;
- MapAttribute.Bits.ReadWrite = 1;
+ IA32_CR4 Cr4;
+ BOOLEAN Page5LevelSupport;
+ UINT32 RegEax;
+ CPUID_EXTENDED_CPU_SIG_EDX RegEdx;
+ BOOLEAN Page1GSupport;
+ PAGING_MODE PagingMode;
//
// Check Page5Level Support or not.
@@ -135,6 +116,27 @@ MigratePageTable ( 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.
@@ -143,62 +145,19 @@ MigratePageTable ( 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 {
- VirPhyAddressSize.Bits.PhysicalAddressBits = 36;
+ MaxAddressBits = 36;
}
if ((PagingMode == Paging4Level1GB) || (PagingMode == Paging4Level)) {
//
- // The max lineaddress bits is 48 for 4 level page table.
+ // The max liner address bits is 48 for 4 level page table.
//
- VirPhyAddressSize.Bits.PhysicalAddressBits = MIN (VirPhyAddressSize.Bits.PhysicalAddressBits, 48);
- }
-
- //
- // Get required buffer size for the pagetable that will be created.
- //
- Status = PageTableMap (&PageTable, PagingMode, 0, &BufferSize, 0, LShiftU64 (1, VirPhyAddressSize.Bits.PhysicalAddressBits), &MapAttribute, &MapMask, NULL);
- ASSERT (Status == EFI_BUFFER_TOO_SMALL);
- if (Status != EFI_BUFFER_TOO_SMALL) {
- return Status;
+ MaxAddressBits = MIN (VirPhyAddressSize.Bits.PhysicalAddressBits, 48);
}
- //
- // Allocate required Buffer.
- //
- Status = PeiServicesAllocatePages (
- EfiBootServicesData,
- EFI_SIZE_TO_PAGES (BufferSize),
- &Buffer
- );
- if (EFI_ERROR (Status)) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- //
- // Create PageTable in permanent memory.
- //
- Status = PageTableMap (&PageTable, PagingMode, (VOID *)(UINTN)Buffer, &BufferSize, 0, LShiftU64 (1, VirPhyAddressSize.Bits.PhysicalAddressBits), &MapAttribute, &MapMask, NULL);
- ASSERT_EFI_ERROR (Status);
- if (EFI_ERROR (Status) || (PageTable == 0)) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- //
- // Write the Pagetable to CR3.
- //
- AsmWriteCr3 (PageTable);
-
- DEBUG ((
- DEBUG_INFO,
- "MigratePageTable: Created PageTable = 0x%lx, BufferSize = %x, PagingMode = 0x%lx, Support Max Physical Address Bits = %d\n",
- PageTable,
- BufferSize,
- (UINTN)PagingMode,
- VirPhyAddressSize.Bits.PhysicalAddressBits
- ));
-
- return Status;
+ return MaxAddressBits;
}
//
@@ -583,6 +542,22 @@ SecTemporaryRamDone ( 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
@@ -634,10 +609,43 @@ SecTemporaryRamDone ( //
ASSERT (sizeof (UINTN) == sizeof (UINT64));
- Status = MigratePageTable ();
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "SecTemporaryRamDone: Failed to migrate page table to permanent memory: %r.\n", Status));
- CpuDeadLoop ();
+ //
+ // 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);
}
}
@@ -647,6 +655,41 @@ SecTemporaryRamDone ( 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);
|