#include <Library/BaseMemoryLib.h>\r
#include <Library/PeiServicesLib.h>\r
#include <Library/PcdLib.h>\r
+#include <Library/CpuLib.h>\r
#include <Library/UefiCpuLib.h>\r
#include <Library/DebugAgentLib.h>\r
#include <Library/IoLib.h>\r
#include <Library/ExtractGuidedSectionLib.h>\r
#include <Library/LocalApicLib.h>\r
#include <Library/CpuExceptionHandlerLib.h>\r
-#include <Library/MemEncryptSevLib.h>\r
-#include <Register/Amd/Ghcb.h>\r
-#include <Register/Amd/Msr.h>\r
-\r
#include <Ppi/TemporaryRamSupport.h>\r
+#include <Ppi/MpInitLibDep.h>\r
+#include <Library/PlatformInitLib.h>\r
+#include <Library/CcProbeLib.h>\r
+#include "AmdSev.h"\r
\r
#define SEC_IDT_ENTRY_COUNT 34\r
\r
TemporaryRamMigration\r
};\r
\r
-EFI_PEI_PPI_DESCRIPTOR mPrivateDispatchTable[] = {\r
+EFI_PEI_PPI_DESCRIPTOR mPrivateDispatchTableMp[] = {\r
+ {\r
+ (EFI_PEI_PPI_DESCRIPTOR_PPI),\r
+ &gEfiTemporaryRamSupportPpiGuid,\r
+ &mTemporaryRamSupportPpi\r
+ },\r
{\r
(EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
+ &gEfiPeiMpInitLibMpDepPpiGuid,\r
+ NULL\r
+ },\r
+};\r
+\r
+EFI_PEI_PPI_DESCRIPTOR mPrivateDispatchTableUp[] = {\r
+ {\r
+ (EFI_PEI_PPI_DESCRIPTOR_PPI),\r
&gEfiTemporaryRamSupportPpiGuid,\r
&mTemporaryRamSupportPpi\r
},\r
+ {\r
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
+ &gEfiPeiMpInitLibUpDepPpiGuid,\r
+ NULL\r
+ },\r
};\r
\r
//\r
return;\r
}\r
\r
-/**\r
- Handle an SEV-ES/GHCB protocol check failure.\r
-\r
- Notify the hypervisor using the VMGEXIT instruction that the SEV-ES guest\r
- wishes to be terminated.\r
-\r
- @param[in] ReasonCode Reason code to provide to the hypervisor for the\r
- termination request.\r
-\r
-**/\r
-STATIC\r
-VOID\r
-SevEsProtocolFailure (\r
- IN UINT8 ReasonCode\r
- )\r
-{\r
- MSR_SEV_ES_GHCB_REGISTER Msr;\r
-\r
- //\r
- // Use the GHCB MSR Protocol to request termination by the hypervisor\r
- //\r
- Msr.GhcbPhysicalAddress = 0;\r
- Msr.GhcbTerminate.Function = GHCB_INFO_TERMINATE_REQUEST;\r
- Msr.GhcbTerminate.ReasonCodeSet = GHCB_TERMINATE_GHCB;\r
- Msr.GhcbTerminate.ReasonCode = ReasonCode;\r
- AsmWriteMsr64 (MSR_SEV_ES_GHCB, Msr.GhcbPhysicalAddress);\r
-\r
- AsmVmgExit ();\r
-\r
- ASSERT (FALSE);\r
- CpuDeadLoop ();\r
-}\r
-\r
-/**\r
- Validate the SEV-ES/GHCB protocol level.\r
-\r
- Verify that the level of SEV-ES/GHCB protocol supported by the hypervisor\r
- and the guest intersect. If they don't intersect, request termination.\r
-\r
-**/\r
-STATIC\r
-VOID\r
-SevEsProtocolCheck (\r
- VOID\r
- )\r
-{\r
- MSR_SEV_ES_GHCB_REGISTER Msr;\r
- GHCB *Ghcb;\r
-\r
- //\r
- // Use the GHCB MSR Protocol to obtain the GHCB SEV-ES Information for\r
- // protocol checking\r
- //\r
- Msr.GhcbPhysicalAddress = 0;\r
- Msr.GhcbInfo.Function = GHCB_INFO_SEV_INFO_GET;\r
- AsmWriteMsr64 (MSR_SEV_ES_GHCB, Msr.GhcbPhysicalAddress);\r
-\r
- AsmVmgExit ();\r
-\r
- Msr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB);\r
-\r
- if (Msr.GhcbInfo.Function != GHCB_INFO_SEV_INFO) {\r
- SevEsProtocolFailure (GHCB_TERMINATE_GHCB_GENERAL);\r
- }\r
-\r
- if (Msr.GhcbProtocol.SevEsProtocolMin > Msr.GhcbProtocol.SevEsProtocolMax) {\r
- SevEsProtocolFailure (GHCB_TERMINATE_GHCB_PROTOCOL);\r
- }\r
-\r
- if ((Msr.GhcbProtocol.SevEsProtocolMin > GHCB_VERSION_MAX) ||\r
- (Msr.GhcbProtocol.SevEsProtocolMax < GHCB_VERSION_MIN))\r
- {\r
- SevEsProtocolFailure (GHCB_TERMINATE_GHCB_PROTOCOL);\r
- }\r
-\r
- //\r
- // SEV-ES protocol checking succeeded, set the initial GHCB address\r
- //\r
- Msr.GhcbPhysicalAddress = FixedPcdGet32 (PcdOvmfSecGhcbBase);\r
- AsmWriteMsr64 (MSR_SEV_ES_GHCB, Msr.GhcbPhysicalAddress);\r
-\r
- Ghcb = Msr.Ghcb;\r
- SetMem (Ghcb, sizeof (*Ghcb), 0);\r
-\r
- //\r
- // Set the version to the maximum that can be supported\r
- //\r
- Ghcb->ProtocolVersion = MIN (Msr.GhcbProtocol.SevEsProtocolMax, GHCB_VERSION_MAX);\r
- Ghcb->GhcbUsage = GHCB_STANDARD_USAGE;\r
-}\r
-\r
-/**\r
- Determine if the SEV is active.\r
-\r
- During the early booting, GuestType is set in the work area. Verify that it\r
- is an SEV guest.\r
-\r
- @retval TRUE SEV is enabled\r
- @retval FALSE SEV is not enabled\r
-\r
-**/\r
-STATIC\r
-BOOLEAN\r
-IsSevGuest (\r
- VOID\r
- )\r
-{\r
- OVMF_WORK_AREA *WorkArea;\r
-\r
- //\r
- // Ensure that the size of the Confidential Computing work area header\r
- // is same as what is provided through a fixed PCD.\r
- //\r
- ASSERT (\r
- (UINTN)FixedPcdGet32 (PcdOvmfConfidentialComputingWorkAreaHeader) ==\r
- sizeof (CONFIDENTIAL_COMPUTING_WORK_AREA_HEADER)\r
- );\r
-\r
- WorkArea = (OVMF_WORK_AREA *)FixedPcdGet32 (PcdOvmfWorkAreaBase);\r
-\r
- return ((WorkArea != NULL) && (WorkArea->Header.GuestType == GUEST_TYPE_AMD_SEV));\r
-}\r
-\r
-/**\r
- Determine if SEV-ES is active.\r
-\r
- During early booting, SEV-ES support code will set a flag to indicate that\r
- SEV-ES is enabled. Return the value of this flag as an indicator that SEV-ES\r
- is enabled.\r
-\r
- @retval TRUE SEV-ES is enabled\r
- @retval FALSE SEV-ES is not enabled\r
-\r
-**/\r
-STATIC\r
-BOOLEAN\r
-SevEsIsEnabled (\r
- VOID\r
- )\r
-{\r
- SEC_SEV_ES_WORK_AREA *SevEsWorkArea;\r
-\r
- if (!IsSevGuest ()) {\r
- return FALSE;\r
- }\r
-\r
- SevEsWorkArea = (SEC_SEV_ES_WORK_AREA *)FixedPcdGet32 (PcdSevEsWorkAreaBase);\r
-\r
- return (SevEsWorkArea->SevEsEnabled != 0);\r
-}\r
-\r
VOID\r
EFIAPI\r
SecCoreStartupWithStack (\r
UINT32 Index;\r
volatile UINT8 *Table;\r
\r
+ #if defined (TDX_GUEST_SUPPORTED)\r
+ if (CcProbe () == CcGuestTypeIntelTdx) {\r
+ //\r
+ // For Td guests, the memory map info is in TdHobLib. It should be processed\r
+ // first so that the memory is accepted. Otherwise access to the unaccepted\r
+ // memory will trigger tripple fault.\r
+ //\r
+ if (ProcessTdxHobList () != EFI_SUCCESS) {\r
+ CpuDeadLoop ();\r
+ }\r
+ }\r
+\r
+ #endif\r
+\r
//\r
// To ensure SMM can't be compromised on S3 resume, we must force re-init of\r
// the BaseExtractGuidedSectionLib. Since this is before library contructors\r
// we use a loop rather than CopyMem.\r
//\r
IdtTableInStack.PeiService = NULL;\r
+\r
for (Index = 0; Index < SEC_IDT_ENTRY_COUNT; Index++) {\r
- UINT8 *Src;\r
- UINT8 *Dst;\r
- UINTN Byte;\r
+ //\r
+ // Declare the local variables that actually move the data elements as\r
+ // volatile to prevent the optimizer from replacing this function with\r
+ // the intrinsic memcpy()\r
+ //\r
+ CONST UINT8 *Src;\r
+ volatile UINT8 *Dst;\r
+ UINTN Byte;\r
\r
- Src = (UINT8 *)&mIdtEntryTemplate;\r
- Dst = (UINT8 *)&IdtTableInStack.IdtTable[Index];\r
+ Src = (CONST UINT8 *)&mIdtEntryTemplate;\r
+ Dst = (volatile UINT8 *)&IdtTableInStack.IdtTable[Index];\r
for (Byte = 0; Byte < sizeof (mIdtEntryTemplate); Byte++) {\r
Dst[Byte] = Src[Byte];\r
}\r
AsmEnableCache ();\r
}\r
\r
+ #if defined (TDX_GUEST_SUPPORTED)\r
+ if (CcProbe () == CcGuestTypeIntelTdx) {\r
+ //\r
+ // InitializeCpuExceptionHandlers () should be called in Td guests so that\r
+ // #VE exceptions can be handled correctly.\r
+ //\r
+ InitializeCpuExceptionHandlers (NULL);\r
+ }\r
+\r
+ #endif\r
+\r
DEBUG ((\r
DEBUG_INFO,\r
"SecCoreStartupWithStack(0x%x, 0x%x)\n",\r
SecCoreData.BootFirmwareVolumeBase = BootFv;\r
SecCoreData.BootFirmwareVolumeSize = (UINTN)BootFv->FvLength;\r
\r
+ //\r
+ // Validate the System RAM used in the SEC Phase\r
+ //\r
+ SecValidateSystemRam ();\r
+\r
//\r
// Make sure the 8259 is masked before initializing the Debug Agent and the debug timer is enabled\r
//\r
EFI_SEC_PEI_HAND_OFF *SecCoreData;\r
EFI_FIRMWARE_VOLUME_HEADER *BootFv;\r
EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint;\r
+ EFI_PEI_PPI_DESCRIPTOR *EfiPeiPpiDescriptor;\r
\r
SecCoreData = (EFI_SEC_PEI_HAND_OFF *)Context;\r
\r
SecCoreData->BootFirmwareVolumeBase = BootFv;\r
SecCoreData->BootFirmwareVolumeSize = (UINTN)BootFv->FvLength;\r
\r
+ //\r
+ // Td guest is required to use the MpInitLibUp (unique-processor version).\r
+ // Other guests use the MpInitLib (multi-processor version).\r
+ //\r
+ if (CcProbe () == CcGuestTypeIntelTdx) {\r
+ EfiPeiPpiDescriptor = (EFI_PEI_PPI_DESCRIPTOR *)&mPrivateDispatchTableUp;\r
+ } else {\r
+ EfiPeiPpiDescriptor = (EFI_PEI_PPI_DESCRIPTOR *)&mPrivateDispatchTableMp;\r
+ }\r
+\r
//\r
// Transfer the control to the PEI core\r
//\r
- (*PeiCoreEntryPoint)(SecCoreData, (EFI_PEI_PPI_DESCRIPTOR *)&mPrivateDispatchTable);\r
+ (*PeiCoreEntryPoint)(SecCoreData, EfiPeiPpiDescriptor);\r
\r
//\r
// If we get here then the PEI Core returned, which is not recoverable.\r
if (SetJump (&JumpBuffer) == 0) {\r
#if defined (MDE_CPU_IA32)\r
JumpBuffer.Esp = JumpBuffer.Esp + DebugAgentContext.StackMigrateOffset;\r
+ #ifndef OMIT_FRAME_POINTER\r
JumpBuffer.Ebp = JumpBuffer.Ebp + DebugAgentContext.StackMigrateOffset;\r
#endif\r
+ #endif\r
#if defined (MDE_CPU_X64)\r
JumpBuffer.Rsp = JumpBuffer.Rsp + DebugAgentContext.StackMigrateOffset;\r
+ #ifndef OMIT_FRAME_POINTER\r
JumpBuffer.Rbp = JumpBuffer.Rbp + DebugAgentContext.StackMigrateOffset;\r
+ #endif\r
#endif\r
LongJump (&JumpBuffer, (UINTN)-1);\r
}\r