X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=OvmfPkg%2FSec%2FSecMain.c;h=3ca0dcdfd3ddd513f85566be0692fea2aa5825b3;hp=b7df549f31007afbe3a0cb72e04b5dfaf639632e;hb=ff36b2550f94dc5fac838cf298ae5a23cfddf204;hpb=6394c35a7db3d7a7cc68f491179a45fe430a335a
diff --git a/OvmfPkg/Sec/SecMain.c b/OvmfPkg/Sec/SecMain.c
index b7df549f31..3ca0dcdfd3 100644
--- a/OvmfPkg/Sec/SecMain.c
+++ b/OvmfPkg/Sec/SecMain.c
@@ -1,15 +1,11 @@
/** @file
Main SEC phase code. Transitions to PEI.
- Copyright (c) 2008 - 2013, Intel Corporation. All rights reserved.
+ Copyright (c) 2008 - 2015, Intel Corporation. All rights reserved.
+ (C) Copyright 2016 Hewlett Packard Enterprise Development LP
+ Copyright (c) 2020, Advanced Micro Devices, Inc. All rights reserved.
- This program and the accompanying materials
- are licensed and made available under the terms and conditions of the BSD License
- which accompanies this distribution. The full text of the license may be found at
- http://opensource.org/licenses/bsd-license.php
-
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -21,6 +17,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -28,44 +25,67 @@
#include
#include
#include
-
+#include
+#include
#include
+#include
+#include
+#include
+#include "AmdSev.h"
#define SEC_IDT_ENTRY_COUNT 34
typedef struct _SEC_IDT_TABLE {
- EFI_PEI_SERVICES *PeiService;
- IA32_IDT_GATE_DESCRIPTOR IdtTable[SEC_IDT_ENTRY_COUNT];
+ EFI_PEI_SERVICES *PeiService;
+ IA32_IDT_GATE_DESCRIPTOR IdtTable[SEC_IDT_ENTRY_COUNT];
} SEC_IDT_TABLE;
VOID
EFIAPI
SecStartupPhase2 (
- IN VOID *Context
+ IN VOID *Context
);
EFI_STATUS
EFIAPI
TemporaryRamMigration (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,
- IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,
- IN UINTN CopySize
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,
+ IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,
+ IN UINTN CopySize
);
//
//
-//
-EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI mTemporaryRamSupportPpi = {
+//
+EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI mTemporaryRamSupportPpi = {
TemporaryRamMigration
};
-EFI_PEI_PPI_DESCRIPTOR mPrivateDispatchTable[] = {
+EFI_PEI_PPI_DESCRIPTOR mPrivateDispatchTableMp[] = {
+ {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI),
+ &gEfiTemporaryRamSupportPpiGuid,
+ &mTemporaryRamSupportPpi
+ },
{
(EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiPeiMpInitLibMpDepPpiGuid,
+ NULL
+ },
+};
+
+EFI_PEI_PPI_DESCRIPTOR mPrivateDispatchTableUp[] = {
+ {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI),
&gEfiTemporaryRamSupportPpiGuid,
&mTemporaryRamSupportPpi
},
+ {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiPeiMpInitLibUpDepPpiGuid,
+ NULL
+ },
};
//
@@ -78,7 +98,7 @@ IA32_IDT_GATE_DESCRIPTOR mIdtEntryTemplate = {
0x0, // Reserved_0
IA32_IDT_GATE_TYPE_INTERRUPT_32, // GateType
0xffff // OffsetHigh
- }
+ }
};
/**
@@ -93,18 +113,18 @@ IA32_IDT_GATE_DESCRIPTOR mIdtEntryTemplate = {
**/
EFI_STATUS
FindMainFv (
- IN OUT EFI_FIRMWARE_VOLUME_HEADER **BootFv
+ IN OUT EFI_FIRMWARE_VOLUME_HEADER **BootFv
)
{
EFI_FIRMWARE_VOLUME_HEADER *Fv;
UINTN Distance;
- ASSERT (((UINTN) *BootFv & EFI_PAGE_MASK) == 0);
+ ASSERT (((UINTN)*BootFv & EFI_PAGE_MASK) == 0);
- Fv = *BootFv;
- Distance = (UINTN) (*BootFv)->FvLength;
+ Fv = *BootFv;
+ Distance = (UINTN)(*BootFv)->FvLength;
do {
- Fv = (EFI_FIRMWARE_VOLUME_HEADER*) ((UINT8*) Fv - EFI_PAGE_SIZE);
+ Fv = (EFI_FIRMWARE_VOLUME_HEADER *)((UINT8 *)Fv - EFI_PAGE_SIZE);
Distance += EFI_PAGE_SIZE;
if (Distance > SIZE_32MB) {
return EFI_NOT_FOUND;
@@ -114,13 +134,12 @@ FindMainFv (
continue;
}
- if ((UINTN) Fv->FvLength > Distance) {
+ if ((UINTN)Fv->FvLength > Distance) {
continue;
}
*BootFv = Fv;
return EFI_SUCCESS;
-
} while (TRUE);
}
@@ -144,34 +163,35 @@ FindMainFv (
**/
EFI_STATUS
FindFfsSectionInstance (
- IN VOID *Sections,
- IN UINTN SizeOfSections,
- IN EFI_SECTION_TYPE SectionType,
- IN UINTN Instance,
- OUT EFI_COMMON_SECTION_HEADER **FoundSection
+ IN VOID *Sections,
+ IN UINTN SizeOfSections,
+ IN EFI_SECTION_TYPE SectionType,
+ IN UINTN Instance,
+ OUT EFI_COMMON_SECTION_HEADER **FoundSection
)
{
- EFI_PHYSICAL_ADDRESS CurrentAddress;
- UINT32 Size;
- EFI_PHYSICAL_ADDRESS EndOfSections;
- EFI_COMMON_SECTION_HEADER *Section;
- EFI_PHYSICAL_ADDRESS EndOfSection;
+ EFI_PHYSICAL_ADDRESS CurrentAddress;
+ UINT32 Size;
+ EFI_PHYSICAL_ADDRESS EndOfSections;
+ EFI_COMMON_SECTION_HEADER *Section;
+ EFI_PHYSICAL_ADDRESS EndOfSection;
//
// Loop through the FFS file sections within the PEI Core FFS file
//
- EndOfSection = (EFI_PHYSICAL_ADDRESS)(UINTN) Sections;
+ EndOfSection = (EFI_PHYSICAL_ADDRESS)(UINTN)Sections;
EndOfSections = EndOfSection + SizeOfSections;
- for (;;) {
+ for ( ; ;) {
if (EndOfSection == EndOfSections) {
break;
}
+
CurrentAddress = (EndOfSection + 3) & ~(3ULL);
if (CurrentAddress >= EndOfSections) {
return EFI_VOLUME_CORRUPTED;
}
- Section = (EFI_COMMON_SECTION_HEADER*)(UINTN) CurrentAddress;
+ Section = (EFI_COMMON_SECTION_HEADER *)(UINTN)CurrentAddress;
Size = SECTION_SIZE (Section);
if (Size < sizeof (*Section)) {
@@ -215,10 +235,10 @@ FindFfsSectionInstance (
**/
EFI_STATUS
FindFfsSectionInSections (
- IN VOID *Sections,
- IN UINTN SizeOfSections,
- IN EFI_SECTION_TYPE SectionType,
- OUT EFI_COMMON_SECTION_HEADER **FoundSection
+ IN VOID *Sections,
+ IN UINTN SizeOfSections,
+ IN EFI_SECTION_TYPE SectionType,
+ OUT EFI_COMMON_SECTION_HEADER **FoundSection
)
{
return FindFfsSectionInstance (
@@ -246,39 +266,38 @@ FindFfsSectionInSections (
**/
EFI_STATUS
FindFfsFileAndSection (
- IN EFI_FIRMWARE_VOLUME_HEADER *Fv,
- IN EFI_FV_FILETYPE FileType,
- IN EFI_SECTION_TYPE SectionType,
- OUT EFI_COMMON_SECTION_HEADER **FoundSection
+ IN EFI_FIRMWARE_VOLUME_HEADER *Fv,
+ IN EFI_FV_FILETYPE FileType,
+ IN EFI_SECTION_TYPE SectionType,
+ OUT EFI_COMMON_SECTION_HEADER **FoundSection
)
{
- EFI_STATUS Status;
- EFI_PHYSICAL_ADDRESS CurrentAddress;
- EFI_PHYSICAL_ADDRESS EndOfFirmwareVolume;
- EFI_FFS_FILE_HEADER *File;
- UINT32 Size;
- EFI_PHYSICAL_ADDRESS EndOfFile;
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS CurrentAddress;
+ EFI_PHYSICAL_ADDRESS EndOfFirmwareVolume;
+ EFI_FFS_FILE_HEADER *File;
+ UINT32 Size;
+ EFI_PHYSICAL_ADDRESS EndOfFile;
if (Fv->Signature != EFI_FVH_SIGNATURE) {
- DEBUG ((EFI_D_ERROR, "FV at %p does not have FV header signature\n", Fv));
+ DEBUG ((DEBUG_ERROR, "FV at %p does not have FV header signature\n", Fv));
return EFI_VOLUME_CORRUPTED;
}
- CurrentAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) Fv;
+ CurrentAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Fv;
EndOfFirmwareVolume = CurrentAddress + Fv->FvLength;
//
// Loop through the FFS files in the Boot Firmware Volume
//
for (EndOfFile = CurrentAddress + Fv->HeaderLength; ; ) {
-
CurrentAddress = (EndOfFile + 7) & ~(7ULL);
if (CurrentAddress > EndOfFirmwareVolume) {
return EFI_VOLUME_CORRUPTED;
}
- File = (EFI_FFS_FILE_HEADER*)(UINTN) CurrentAddress;
- Size = *(UINT32*) File->Size & 0xffffff;
+ File = (EFI_FFS_FILE_HEADER *)(UINTN)CurrentAddress;
+ Size = FFS_FILE_SIZE (File);
if (Size < (sizeof (*File) + sizeof (EFI_COMMON_SECTION_HEADER))) {
return EFI_VOLUME_CORRUPTED;
}
@@ -296,8 +315,8 @@ FindFfsFileAndSection (
}
Status = FindFfsSectionInSections (
- (VOID*) (File + 1),
- (UINTN) EndOfFile - (UINTN) (File + 1),
+ (VOID *)(File + 1),
+ (UINTN)EndOfFile - (UINTN)(File + 1),
SectionType,
FoundSection
);
@@ -320,31 +339,33 @@ FindFfsFileAndSection (
**/
EFI_STATUS
DecompressMemFvs (
- IN OUT EFI_FIRMWARE_VOLUME_HEADER **Fv
+ IN OUT EFI_FIRMWARE_VOLUME_HEADER **Fv
)
{
- EFI_STATUS Status;
- EFI_GUID_DEFINED_SECTION *Section;
- UINT32 OutputBufferSize;
- UINT32 ScratchBufferSize;
- UINT16 SectionAttribute;
- UINT32 AuthenticationStatus;
- VOID *OutputBuffer;
- VOID *ScratchBuffer;
- EFI_FIRMWARE_VOLUME_IMAGE_SECTION *FvSection;
- EFI_FIRMWARE_VOLUME_HEADER *PeiMemFv;
- EFI_FIRMWARE_VOLUME_HEADER *DxeMemFv;
-
- FvSection = (EFI_FIRMWARE_VOLUME_IMAGE_SECTION*) NULL;
+ EFI_STATUS Status;
+ EFI_GUID_DEFINED_SECTION *Section;
+ UINT32 OutputBufferSize;
+ UINT32 ScratchBufferSize;
+ UINT16 SectionAttribute;
+ UINT32 AuthenticationStatus;
+ VOID *OutputBuffer;
+ VOID *ScratchBuffer;
+ EFI_COMMON_SECTION_HEADER *FvSection;
+ EFI_FIRMWARE_VOLUME_HEADER *PeiMemFv;
+ EFI_FIRMWARE_VOLUME_HEADER *DxeMemFv;
+ UINT32 FvHeaderSize;
+ UINT32 FvSectionSize;
+
+ FvSection = (EFI_COMMON_SECTION_HEADER *)NULL;
Status = FindFfsFileAndSection (
*Fv,
EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE,
EFI_SECTION_GUID_DEFINED,
- (EFI_COMMON_SECTION_HEADER**) &Section
+ (EFI_COMMON_SECTION_HEADER **)&Section
);
if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "Unable to find GUID defined section\n"));
+ DEBUG ((DEBUG_ERROR, "Unable to find GUID defined section\n"));
return Status;
}
@@ -355,12 +376,29 @@ DecompressMemFvs (
&SectionAttribute
);
if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "Unable to GetInfo for GUIDed section\n"));
+ DEBUG ((DEBUG_ERROR, "Unable to GetInfo for GUIDed section\n"));
return Status;
}
- OutputBuffer = (VOID*) ((UINT8*)(UINTN) PcdGet32 (PcdOvmfDxeMemFvBase) + SIZE_1MB);
- ScratchBuffer = ALIGN_POINTER ((UINT8*) OutputBuffer + OutputBufferSize, SIZE_1MB);
+ OutputBuffer = (VOID *)((UINT8 *)(UINTN)PcdGet32 (PcdOvmfDxeMemFvBase) + SIZE_1MB);
+ ScratchBuffer = ALIGN_POINTER ((UINT8 *)OutputBuffer + OutputBufferSize, SIZE_1MB);
+
+ DEBUG ((
+ DEBUG_VERBOSE,
+ "%a: OutputBuffer@%p+0x%x ScratchBuffer@%p+0x%x "
+ "PcdOvmfDecompressionScratchEnd=0x%x\n",
+ __FUNCTION__,
+ OutputBuffer,
+ OutputBufferSize,
+ ScratchBuffer,
+ ScratchBufferSize,
+ PcdGet32 (PcdOvmfDecompressionScratchEnd)
+ ));
+ ASSERT (
+ (UINTN)ScratchBuffer + ScratchBufferSize ==
+ PcdGet32 (PcdOvmfDecompressionScratchEnd)
+ );
+
Status = ExtractGuidedSectionDecode (
Section,
&OutputBuffer,
@@ -368,7 +406,7 @@ DecompressMemFvs (
&AuthenticationStatus
);
if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "Error during GUID section decode\n"));
+ DEBUG ((DEBUG_ERROR, "Error during GUID section decode\n"));
return Status;
}
@@ -377,22 +415,24 @@ DecompressMemFvs (
OutputBufferSize,
EFI_SECTION_FIRMWARE_VOLUME_IMAGE,
0,
- (EFI_COMMON_SECTION_HEADER**) &FvSection
+ &FvSection
);
if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "Unable to find PEI FV section\n"));
+ DEBUG ((DEBUG_ERROR, "Unable to find PEI FV section\n"));
return Status;
}
- ASSERT (SECTION_SIZE (FvSection) ==
- (PcdGet32 (PcdOvmfPeiMemFvSize) + sizeof (*FvSection)));
+ ASSERT (
+ SECTION_SIZE (FvSection) ==
+ (PcdGet32 (PcdOvmfPeiMemFvSize) + sizeof (*FvSection))
+ );
ASSERT (FvSection->Type == EFI_SECTION_FIRMWARE_VOLUME_IMAGE);
- PeiMemFv = (EFI_FIRMWARE_VOLUME_HEADER*)(UINTN) PcdGet32 (PcdOvmfPeiMemFvBase);
- CopyMem (PeiMemFv, (VOID*) (FvSection + 1), PcdGet32 (PcdOvmfPeiMemFvSize));
+ PeiMemFv = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)PcdGet32 (PcdOvmfPeiMemFvBase);
+ CopyMem (PeiMemFv, (VOID *)(FvSection + 1), PcdGet32 (PcdOvmfPeiMemFvSize));
if (PeiMemFv->Signature != EFI_FVH_SIGNATURE) {
- DEBUG ((EFI_D_ERROR, "Extracted FV at %p does not have FV header signature\n", PeiMemFv));
+ DEBUG ((DEBUG_ERROR, "Extracted FV at %p does not have FV header signature\n", PeiMemFv));
CpuDeadLoop ();
return EFI_VOLUME_CORRUPTED;
}
@@ -402,22 +442,30 @@ DecompressMemFvs (
OutputBufferSize,
EFI_SECTION_FIRMWARE_VOLUME_IMAGE,
1,
- (EFI_COMMON_SECTION_HEADER**) &FvSection
+ &FvSection
);
if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "Unable to find DXE FV section\n"));
+ DEBUG ((DEBUG_ERROR, "Unable to find DXE FV section\n"));
return Status;
}
ASSERT (FvSection->Type == EFI_SECTION_FIRMWARE_VOLUME_IMAGE);
- ASSERT (SECTION_SIZE (FvSection) ==
- (PcdGet32 (PcdOvmfDxeMemFvSize) + sizeof (*FvSection)));
- DxeMemFv = (EFI_FIRMWARE_VOLUME_HEADER*)(UINTN) PcdGet32 (PcdOvmfDxeMemFvBase);
- CopyMem (DxeMemFv, (VOID*) (FvSection + 1), PcdGet32 (PcdOvmfDxeMemFvSize));
+ if (IS_SECTION2 (FvSection)) {
+ FvSectionSize = SECTION2_SIZE (FvSection);
+ FvHeaderSize = sizeof (EFI_COMMON_SECTION_HEADER2);
+ } else {
+ FvSectionSize = SECTION_SIZE (FvSection);
+ FvHeaderSize = sizeof (EFI_COMMON_SECTION_HEADER);
+ }
+
+ ASSERT (FvSectionSize == (PcdGet32 (PcdOvmfDxeMemFvSize) + FvHeaderSize));
+
+ DxeMemFv = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)PcdGet32 (PcdOvmfDxeMemFvBase);
+ CopyMem (DxeMemFv, (VOID *)((UINTN)FvSection + FvHeaderSize), PcdGet32 (PcdOvmfDxeMemFvSize));
if (DxeMemFv->Signature != EFI_FVH_SIGNATURE) {
- DEBUG ((EFI_D_ERROR, "Extracted FV at %p does not have FV header signature\n", DxeMemFv));
+ DEBUG ((DEBUG_ERROR, "Extracted FV at %p does not have FV header signature\n", DxeMemFv));
CpuDeadLoop ();
return EFI_VOLUME_CORRUPTED;
}
@@ -439,12 +487,12 @@ DecompressMemFvs (
**/
EFI_STATUS
FindPeiCoreImageBaseInFv (
- IN EFI_FIRMWARE_VOLUME_HEADER *Fv,
- OUT EFI_PHYSICAL_ADDRESS *PeiCoreImageBase
+ IN EFI_FIRMWARE_VOLUME_HEADER *Fv,
+ OUT EFI_PHYSICAL_ADDRESS *PeiCoreImageBase
)
{
- EFI_STATUS Status;
- EFI_COMMON_SECTION_HEADER *Section;
+ EFI_STATUS Status;
+ EFI_COMMON_SECTION_HEADER *Section;
Status = FindFfsFileAndSection (
Fv,
@@ -460,7 +508,7 @@ FindPeiCoreImageBaseInFv (
&Section
);
if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "Unable to find PEI Core image\n"));
+ DEBUG ((DEBUG_ERROR, "Unable to find PEI Core image\n"));
return Status;
}
}
@@ -469,7 +517,6 @@ FindPeiCoreImageBaseInFv (
return EFI_SUCCESS;
}
-
/**
Reads 8-bits of CMOS data.
@@ -484,14 +531,13 @@ FindPeiCoreImageBaseInFv (
STATIC
UINT8
CmosRead8 (
- IN UINTN Index
+ IN UINTN Index
)
{
- IoWrite8 (0x70, (UINT8) Index);
+ IoWrite8 (0x70, (UINT8)Index);
return IoRead8 (0x71);
}
-
STATIC
BOOLEAN
IsS3Resume (
@@ -501,18 +547,16 @@ IsS3Resume (
return (CmosRead8 (0xF) == 0xFE);
}
-
STATIC
EFI_STATUS
GetS3ResumePeiFv (
- IN OUT EFI_FIRMWARE_VOLUME_HEADER **PeiFv
+ IN OUT EFI_FIRMWARE_VOLUME_HEADER **PeiFv
)
{
- *PeiFv = (EFI_FIRMWARE_VOLUME_HEADER*)(UINTN) PcdGet32 (PcdOvmfPeiMemFvBase);
+ *PeiFv = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)PcdGet32 (PcdOvmfPeiMemFvBase);
return EFI_SUCCESS;
}
-
/**
Locates the PEI Core entry point address
@@ -526,17 +570,32 @@ GetS3ResumePeiFv (
**/
VOID
FindPeiCoreImageBase (
- IN OUT EFI_FIRMWARE_VOLUME_HEADER **BootFv,
- OUT EFI_PHYSICAL_ADDRESS *PeiCoreImageBase
+ IN OUT EFI_FIRMWARE_VOLUME_HEADER **BootFv,
+ OUT EFI_PHYSICAL_ADDRESS *PeiCoreImageBase
)
{
+ BOOLEAN S3Resume;
+
*PeiCoreImageBase = 0;
- if (IsS3Resume ()) {
- DEBUG ((EFI_D_VERBOSE, "SEC: S3 resume\n"));
+ S3Resume = IsS3Resume ();
+ if (S3Resume && !FeaturePcdGet (PcdSmmSmramRequire)) {
+ //
+ // A malicious runtime OS may have injected something into our previously
+ // decoded PEI FV, but we don't care about that unless SMM/SMRAM is required.
+ //
+ DEBUG ((DEBUG_VERBOSE, "SEC: S3 resume\n"));
GetS3ResumePeiFv (BootFv);
} else {
- DEBUG ((EFI_D_VERBOSE, "SEC: Normal boot\n"));
+ //
+ // We're either not resuming, or resuming "securely" -- we'll decompress
+ // both PEI FV and DXE FV from pristine flash.
+ //
+ DEBUG ((
+ DEBUG_VERBOSE,
+ "SEC: %a\n",
+ S3Resume ? "S3 resume (with PEI decompression)" : "Normal boot"
+ ));
FindMainFv (BootFv);
DecompressMemFvs (BootFv);
@@ -551,35 +610,34 @@ FindPeiCoreImageBase (
**/
EFI_STATUS
FindImageBase (
- IN EFI_FIRMWARE_VOLUME_HEADER *BootFirmwareVolumePtr,
- OUT EFI_PHYSICAL_ADDRESS *SecCoreImageBase
+ IN EFI_FIRMWARE_VOLUME_HEADER *BootFirmwareVolumePtr,
+ OUT EFI_PHYSICAL_ADDRESS *SecCoreImageBase
)
{
- EFI_PHYSICAL_ADDRESS CurrentAddress;
- EFI_PHYSICAL_ADDRESS EndOfFirmwareVolume;
- EFI_FFS_FILE_HEADER *File;
- UINT32 Size;
- EFI_PHYSICAL_ADDRESS EndOfFile;
- EFI_COMMON_SECTION_HEADER *Section;
- EFI_PHYSICAL_ADDRESS EndOfSection;
+ EFI_PHYSICAL_ADDRESS CurrentAddress;
+ EFI_PHYSICAL_ADDRESS EndOfFirmwareVolume;
+ EFI_FFS_FILE_HEADER *File;
+ UINT32 Size;
+ EFI_PHYSICAL_ADDRESS EndOfFile;
+ EFI_COMMON_SECTION_HEADER *Section;
+ EFI_PHYSICAL_ADDRESS EndOfSection;
*SecCoreImageBase = 0;
- CurrentAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) BootFirmwareVolumePtr;
+ CurrentAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)BootFirmwareVolumePtr;
EndOfFirmwareVolume = CurrentAddress + BootFirmwareVolumePtr->FvLength;
//
// Loop through the FFS files in the Boot Firmware Volume
//
for (EndOfFile = CurrentAddress + BootFirmwareVolumePtr->HeaderLength; ; ) {
-
CurrentAddress = (EndOfFile + 7) & 0xfffffffffffffff8ULL;
if (CurrentAddress > EndOfFirmwareVolume) {
return EFI_NOT_FOUND;
}
- File = (EFI_FFS_FILE_HEADER*)(UINTN) CurrentAddress;
- Size = *(UINT32*) File->Size & 0xffffff;
+ File = (EFI_FFS_FILE_HEADER *)(UINTN)CurrentAddress;
+ Size = FFS_FILE_SIZE (File);
if (Size < sizeof (*File)) {
return EFI_NOT_FOUND;
}
@@ -599,12 +657,12 @@ FindImageBase (
//
// Loop through the FFS file sections within the FFS file
//
- EndOfSection = (EFI_PHYSICAL_ADDRESS)(UINTN) (File + 1);
- for (;;) {
+ EndOfSection = (EFI_PHYSICAL_ADDRESS)(UINTN)(File + 1);
+ for ( ; ;) {
CurrentAddress = (EndOfSection + 3) & 0xfffffffffffffffcULL;
- Section = (EFI_COMMON_SECTION_HEADER*)(UINTN) CurrentAddress;
+ Section = (EFI_COMMON_SECTION_HEADER *)(UINTN)CurrentAddress;
- Size = *(UINT32*) Section->Size & 0xffffff;
+ Size = SECTION_SIZE (Section);
if (Size < sizeof (*Section)) {
return EFI_NOT_FOUND;
}
@@ -617,10 +675,11 @@ FindImageBase (
//
// Look for executable sections
//
- if (Section->Type == EFI_SECTION_PE32 || Section->Type == EFI_SECTION_TE) {
+ if ((Section->Type == EFI_SECTION_PE32) || (Section->Type == EFI_SECTION_TE)) {
if (File->Type == EFI_FV_FILETYPE_SECURITY_CORE) {
- *SecCoreImageBase = (PHYSICAL_ADDRESS) (UINTN) (Section + 1);
+ *SecCoreImageBase = (PHYSICAL_ADDRESS)(UINTN)(Section + 1);
}
+
break;
}
}
@@ -637,48 +696,48 @@ FindImageBase (
/*
Find and return Pei Core entry point.
- It also find SEC and PEI Core file debug inforamtion. It will report them if
+ It also find SEC and PEI Core file debug information. It will report them if
remote debug is enabled.
**/
VOID
FindAndReportEntryPoints (
- IN EFI_FIRMWARE_VOLUME_HEADER **BootFirmwareVolumePtr,
- OUT EFI_PEI_CORE_ENTRY_POINT *PeiCoreEntryPoint
+ IN EFI_FIRMWARE_VOLUME_HEADER **BootFirmwareVolumePtr,
+ OUT EFI_PEI_CORE_ENTRY_POINT *PeiCoreEntryPoint
)
{
- EFI_STATUS Status;
- EFI_PHYSICAL_ADDRESS SecCoreImageBase;
- EFI_PHYSICAL_ADDRESS PeiCoreImageBase;
- PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS SecCoreImageBase;
+ EFI_PHYSICAL_ADDRESS PeiCoreImageBase;
+ PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
//
// Find SEC Core and PEI Core image base
- //
+ //
Status = FindImageBase (*BootFirmwareVolumePtr, &SecCoreImageBase);
ASSERT_EFI_ERROR (Status);
FindPeiCoreImageBase (BootFirmwareVolumePtr, &PeiCoreImageBase);
-
- ZeroMem ((VOID *) &ImageContext, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT));
+
+ ZeroMem ((VOID *)&ImageContext, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT));
//
// Report SEC Core debug information when remote debug is enabled
//
ImageContext.ImageAddress = SecCoreImageBase;
- ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN) ImageContext.ImageAddress);
+ ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)ImageContext.ImageAddress);
PeCoffLoaderRelocateImageExtraAction (&ImageContext);
//
// Report PEI Core debug information when remote debug is enabled
//
ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)PeiCoreImageBase;
- ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN) ImageContext.ImageAddress);
+ ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)ImageContext.ImageAddress);
PeCoffLoaderRelocateImageExtraAction (&ImageContext);
//
// Find PEI Core entry point
//
- Status = PeCoffLoaderGetEntryPoint ((VOID *) (UINTN) PeiCoreImageBase, (VOID**) PeiCoreEntryPoint);
+ Status = PeCoffLoaderGetEntryPoint ((VOID *)(UINTN)PeiCoreImageBase, (VOID **)PeiCoreEntryPoint);
if (EFI_ERROR (Status)) {
*PeiCoreEntryPoint = 0;
}
@@ -689,18 +748,119 @@ FindAndReportEntryPoints (
VOID
EFIAPI
SecCoreStartupWithStack (
- IN EFI_FIRMWARE_VOLUME_HEADER *BootFv,
- IN VOID *TopOfCurrentStack
+ IN EFI_FIRMWARE_VOLUME_HEADER *BootFv,
+ IN VOID *TopOfCurrentStack
)
{
- EFI_SEC_PEI_HAND_OFF SecCoreData;
- SEC_IDT_TABLE IdtTableInStack;
- IA32_DESCRIPTOR IdtDescriptor;
- UINT32 Index;
+ EFI_SEC_PEI_HAND_OFF SecCoreData;
+ SEC_IDT_TABLE IdtTableInStack;
+ IA32_DESCRIPTOR IdtDescriptor;
+ UINT32 Index;
+ volatile UINT8 *Table;
+
+ #if defined (TDX_GUEST_SUPPORTED)
+ if (CcProbe () == CcGuestTypeIntelTdx) {
+ //
+ // For Td guests, the memory map info is in TdHobLib. It should be processed
+ // first so that the memory is accepted. Otherwise access to the unaccepted
+ // memory will trigger tripple fault.
+ //
+ if (ProcessTdxHobList () != EFI_SUCCESS) {
+ CpuDeadLoop ();
+ }
+ }
+
+ #endif
+
+ //
+ // To ensure SMM can't be compromised on S3 resume, we must force re-init of
+ // the BaseExtractGuidedSectionLib. Since this is before library contructors
+ // are called, we must use a loop rather than SetMem.
+ //
+ Table = (UINT8 *)(UINTN)FixedPcdGet64 (PcdGuidedExtractHandlerTableAddress);
+ for (Index = 0;
+ Index < FixedPcdGet32 (PcdGuidedExtractHandlerTableSize);
+ ++Index)
+ {
+ Table[Index] = 0;
+ }
+
+ //
+ // Initialize IDT - Since this is before library constructors are called,
+ // we use a loop rather than CopyMem.
+ //
+ IdtTableInStack.PeiService = NULL;
+
+ for (Index = 0; Index < SEC_IDT_ENTRY_COUNT; Index++) {
+ //
+ // Declare the local variables that actually move the data elements as
+ // volatile to prevent the optimizer from replacing this function with
+ // the intrinsic memcpy()
+ //
+ CONST UINT8 *Src;
+ volatile UINT8 *Dst;
+ UINTN Byte;
+
+ Src = (CONST UINT8 *)&mIdtEntryTemplate;
+ Dst = (volatile UINT8 *)&IdtTableInStack.IdtTable[Index];
+ for (Byte = 0; Byte < sizeof (mIdtEntryTemplate); Byte++) {
+ Dst[Byte] = Src[Byte];
+ }
+ }
+
+ IdtDescriptor.Base = (UINTN)&IdtTableInStack.IdtTable;
+ IdtDescriptor.Limit = (UINT16)(sizeof (IdtTableInStack.IdtTable) - 1);
+
+ if (SevEsIsEnabled ()) {
+ SevEsProtocolCheck ();
+
+ //
+ // For SEV-ES guests, the exception handler is needed before calling
+ // ProcessLibraryConstructorList() because some of the library constructors
+ // perform some functions that result in #VC exceptions being generated.
+ //
+ // Due to this code executing before library constructors, *all* library
+ // API calls are theoretically interface contract violations. However,
+ // because this is SEC (executing in flash), those constructors cannot
+ // write variables with static storage duration anyway. Furthermore, only
+ // a small, restricted set of APIs, such as AsmWriteIdtr() and
+ // InitializeCpuExceptionHandlers(), are called, where we require that the
+ // underlying library not require constructors to have been invoked and
+ // that the library instance not trigger any #VC exceptions.
+ //
+ AsmWriteIdtr (&IdtDescriptor);
+ InitializeCpuExceptionHandlers (NULL);
+ }
ProcessLibraryConstructorList (NULL, NULL);
- DEBUG ((EFI_D_INFO,
+ if (!SevEsIsEnabled ()) {
+ //
+ // For non SEV-ES guests, just load the IDTR.
+ //
+ AsmWriteIdtr (&IdtDescriptor);
+ } else {
+ //
+ // Under SEV-ES, the hypervisor can't modify CR0 and so can't enable
+ // caching in order to speed up the boot. Enable caching early for
+ // an SEV-ES guest.
+ //
+ AsmEnableCache ();
+ }
+
+ #if defined (TDX_GUEST_SUPPORTED)
+ if (CcProbe () == CcGuestTypeIntelTdx) {
+ //
+ // InitializeCpuExceptionHandlers () should be called in Td guests so that
+ // #VE exceptions can be handled correctly.
+ //
+ InitializeCpuExceptionHandlers (NULL);
+ }
+
+ #endif
+
+ DEBUG ((
+ DEBUG_INFO,
"SecCoreStartupWithStack(0x%x, 0x%x)\n",
(UINT32)(UINTN)BootFv,
(UINT32)(UINTN)TopOfCurrentStack
@@ -712,26 +872,13 @@ SecCoreStartupWithStack (
//
InitializeFloatingPointUnits ();
- //
- // Initialize IDT
- //
- IdtTableInStack.PeiService = NULL;
- for (Index = 0; Index < SEC_IDT_ENTRY_COUNT; Index ++) {
- CopyMem (&IdtTableInStack.IdtTable[Index], &mIdtEntryTemplate, sizeof (mIdtEntryTemplate));
- }
-
- IdtDescriptor.Base = (UINTN)&IdtTableInStack.IdtTable;
- IdtDescriptor.Limit = (UINT16)(sizeof (IdtTableInStack.IdtTable) - 1);
-
- AsmWriteIdtr (&IdtDescriptor);
-
-#if defined (MDE_CPU_X64)
+ #if defined (MDE_CPU_X64)
//
// ASSERT that the Page Tables were set by the reset vector code to
// the address we expect.
//
- ASSERT (AsmReadCr3 () == (UINTN) PcdGet32 (PcdOvmfSecPageTablesBase));
-#endif
+ ASSERT (AsmReadCr3 () == (UINTN)PcdGet32 (PcdOvmfSecPageTablesBase));
+ #endif
//
// |-------------| <-- TopOfCurrentStack
@@ -741,39 +888,54 @@ SecCoreStartupWithStack (
// |-------------| <-- SecCoreData.TemporaryRamBase
//
- ASSERT ((UINTN) (PcdGet32 (PcdOvmfSecPeiTempRamBase) +
- PcdGet32 (PcdOvmfSecPeiTempRamSize)) ==
- (UINTN) TopOfCurrentStack);
+ ASSERT (
+ (UINTN)(PcdGet32 (PcdOvmfSecPeiTempRamBase) +
+ PcdGet32 (PcdOvmfSecPeiTempRamSize)) ==
+ (UINTN)TopOfCurrentStack
+ );
//
// Initialize SEC hand-off state
//
- SecCoreData.DataSize = sizeof(EFI_SEC_PEI_HAND_OFF);
+ SecCoreData.DataSize = sizeof (EFI_SEC_PEI_HAND_OFF);
- SecCoreData.TemporaryRamSize = (UINTN) PcdGet32 (PcdOvmfSecPeiTempRamSize);
- SecCoreData.TemporaryRamBase = (VOID*)((UINT8 *)TopOfCurrentStack - SecCoreData.TemporaryRamSize);
+ SecCoreData.TemporaryRamSize = (UINTN)PcdGet32 (PcdOvmfSecPeiTempRamSize);
+ SecCoreData.TemporaryRamBase = (VOID *)((UINT8 *)TopOfCurrentStack - SecCoreData.TemporaryRamSize);
- SecCoreData.PeiTemporaryRamBase = SecCoreData.TemporaryRamBase;
- SecCoreData.PeiTemporaryRamSize = SecCoreData.TemporaryRamSize >> 1;
+ SecCoreData.PeiTemporaryRamBase = SecCoreData.TemporaryRamBase;
+ SecCoreData.PeiTemporaryRamSize = SecCoreData.TemporaryRamSize >> 1;
- SecCoreData.StackBase = (UINT8 *)SecCoreData.TemporaryRamBase + SecCoreData.PeiTemporaryRamSize;
- SecCoreData.StackSize = SecCoreData.TemporaryRamSize >> 1;
+ SecCoreData.StackBase = (UINT8 *)SecCoreData.TemporaryRamBase + SecCoreData.PeiTemporaryRamSize;
+ SecCoreData.StackSize = SecCoreData.TemporaryRamSize >> 1;
SecCoreData.BootFirmwareVolumeBase = BootFv;
- SecCoreData.BootFirmwareVolumeSize = (UINTN) BootFv->FvLength;
+ SecCoreData.BootFirmwareVolumeSize = (UINTN)BootFv->FvLength;
+
+ //
+ // Validate the System RAM used in the SEC Phase
+ //
+ SecValidateSystemRam ();
//
// Make sure the 8259 is masked before initializing the Debug Agent and the debug timer is enabled
//
IoWrite8 (0x21, 0xff);
IoWrite8 (0xA1, 0xff);
-
+
+ //
+ // Initialize Local APIC Timer hardware and disable Local APIC Timer
+ // interrupts before initializing the Debug Agent and the debug timer is
+ // enabled.
+ //
+ InitializeApicTimer (0, MAX_UINT32, TRUE, 5);
+ DisableApicTimerInterrupt ();
+
//
// Initialize Debug Agent to support source level debug in SEC/PEI phases before memory ready.
//
InitializeDebugAgent (DEBUG_AGENT_INIT_PREMEM_SEC, &SecCoreData, SecStartupPhase2);
}
-
+
/**
Caller provided function to be invoked at the end of InitializeDebugAgent().
@@ -786,16 +948,17 @@ SecCoreStartupWithStack (
**/
VOID
EFIAPI
-SecStartupPhase2(
- IN VOID *Context
+SecStartupPhase2 (
+ IN VOID *Context
)
{
EFI_SEC_PEI_HAND_OFF *SecCoreData;
EFI_FIRMWARE_VOLUME_HEADER *BootFv;
EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint;
-
- SecCoreData = (EFI_SEC_PEI_HAND_OFF *) Context;
-
+ EFI_PEI_PPI_DESCRIPTOR *EfiPeiPpiDescriptor;
+
+ SecCoreData = (EFI_SEC_PEI_HAND_OFF *)Context;
+
//
// Find PEI Core entry point. It will report SEC and Pei Core debug information if remote debug
// is enabled.
@@ -803,13 +966,23 @@ SecStartupPhase2(
BootFv = (EFI_FIRMWARE_VOLUME_HEADER *)SecCoreData->BootFirmwareVolumeBase;
FindAndReportEntryPoints (&BootFv, &PeiCoreEntryPoint);
SecCoreData->BootFirmwareVolumeBase = BootFv;
- SecCoreData->BootFirmwareVolumeSize = (UINTN) BootFv->FvLength;
+ SecCoreData->BootFirmwareVolumeSize = (UINTN)BootFv->FvLength;
+
+ //
+ // Td guest is required to use the MpInitLibUp (unique-processor version).
+ // Other guests use the MpInitLib (multi-processor version).
+ //
+ if (CcProbe () == CcGuestTypeIntelTdx) {
+ EfiPeiPpiDescriptor = (EFI_PEI_PPI_DESCRIPTOR *)&mPrivateDispatchTableUp;
+ } else {
+ EfiPeiPpiDescriptor = (EFI_PEI_PPI_DESCRIPTOR *)&mPrivateDispatchTableMp;
+ }
//
// Transfer the control to the PEI core
//
- (*PeiCoreEntryPoint) (SecCoreData, (EFI_PEI_PPI_DESCRIPTOR *)&mPrivateDispatchTable);
-
+ (*PeiCoreEntryPoint)(SecCoreData, EfiPeiPpiDescriptor);
+
//
// If we get here then the PEI Core returned, which is not recoverable.
//
@@ -820,10 +993,10 @@ SecStartupPhase2(
EFI_STATUS
EFIAPI
TemporaryRamMigration (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,
- IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,
- IN UINTN CopySize
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,
+ IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,
+ IN UINTN CopySize
)
{
IA32_DESCRIPTOR IdtDescriptor;
@@ -834,25 +1007,26 @@ TemporaryRamMigration (
DEBUG_AGENT_CONTEXT_POSTMEM_SEC DebugAgentContext;
BOOLEAN OldStatus;
BASE_LIBRARY_JUMP_BUFFER JumpBuffer;
-
- DEBUG ((EFI_D_INFO,
+
+ DEBUG ((
+ DEBUG_INFO,
"TemporaryRamMigration(0x%Lx, 0x%Lx, 0x%Lx)\n",
TemporaryMemoryBase,
PermanentMemoryBase,
(UINT64)CopySize
));
-
- OldHeap = (VOID*)(UINTN)TemporaryMemoryBase;
- NewHeap = (VOID*)((UINTN)PermanentMemoryBase + (CopySize >> 1));
-
- OldStack = (VOID*)((UINTN)TemporaryMemoryBase + (CopySize >> 1));
- NewStack = (VOID*)(UINTN)PermanentMemoryBase;
-
- DebugAgentContext.HeapMigrateOffset = (UINTN)NewHeap - (UINTN)OldHeap;
+
+ OldHeap = (VOID *)(UINTN)TemporaryMemoryBase;
+ NewHeap = (VOID *)((UINTN)PermanentMemoryBase + (CopySize >> 1));
+
+ OldStack = (VOID *)((UINTN)TemporaryMemoryBase + (CopySize >> 1));
+ NewStack = (VOID *)(UINTN)PermanentMemoryBase;
+
+ DebugAgentContext.HeapMigrateOffset = (UINTN)NewHeap - (UINTN)OldHeap;
DebugAgentContext.StackMigrateOffset = (UINTN)NewStack - (UINTN)OldStack;
-
+
OldStatus = SaveAndSetDebugTimerInterrupt (FALSE);
- InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, (VOID *) &DebugAgentContext, NULL);
+ InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, (VOID *)&DebugAgentContext, NULL);
//
// Migrate Heap
@@ -863,7 +1037,7 @@ TemporaryRamMigration (
// Migrate Stack
//
CopyMem (NewStack, OldStack, CopySize >> 1);
-
+
//
// Rebase IDT table in permanent memory
//
@@ -874,14 +1048,20 @@ TemporaryRamMigration (
//
// Use SetJump()/LongJump() to switch to a new stack.
- //
+ //
if (SetJump (&JumpBuffer) == 0) {
-#if defined (MDE_CPU_IA32)
+ #if defined (MDE_CPU_IA32)
JumpBuffer.Esp = JumpBuffer.Esp + DebugAgentContext.StackMigrateOffset;
-#endif
-#if defined (MDE_CPU_X64)
+ #ifndef OMIT_FRAME_POINTER
+ JumpBuffer.Ebp = JumpBuffer.Ebp + DebugAgentContext.StackMigrateOffset;
+ #endif
+ #endif
+ #if defined (MDE_CPU_X64)
JumpBuffer.Rsp = JumpBuffer.Rsp + DebugAgentContext.StackMigrateOffset;
-#endif
+ #ifndef OMIT_FRAME_POINTER
+ JumpBuffer.Rbp = JumpBuffer.Rbp + DebugAgentContext.StackMigrateOffset;
+ #endif
+ #endif
LongJump (&JumpBuffer, (UINTN)-1);
}
@@ -889,4 +1069,3 @@ TemporaryRamMigration (
return EFI_SUCCESS;
}
-