#include <Guid/S3SmmInitDone.h>\r
#include <Ppi/ShadowMicrocode.h>\r
\r
+STATIC UINT64 mSevEsPeiWakeupBuffer = BASE_1MB;\r
+\r
/**\r
S3 SMM Init Done notification function.\r
\r
EFI_STATUS\r
EFIAPI\r
NotifyOnS3SmmInitDonePpi (\r
- IN EFI_PEI_SERVICES **PeiServices,\r
- IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,\r
- IN VOID *InvokePpi\r
+ IN EFI_PEI_SERVICES **PeiServices,\r
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,\r
+ IN VOID *InvokePpi\r
);\r
\r
-\r
//\r
// Global function\r
//\r
-EFI_PEI_NOTIFY_DESCRIPTOR mS3SmmInitDoneNotifyDesc = {\r
+EFI_PEI_NOTIFY_DESCRIPTOR mS3SmmInitDoneNotifyDesc = {\r
EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,\r
&gEdkiiS3SmmInitDoneGuid,\r
NotifyOnS3SmmInitDonePpi\r
EFI_STATUS\r
EFIAPI\r
NotifyOnS3SmmInitDonePpi (\r
- IN EFI_PEI_SERVICES **PeiServices,\r
- IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,\r
- IN VOID *InvokePpi\r
+ IN EFI_PEI_SERVICES **PeiServices,\r
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,\r
+ IN VOID *InvokePpi\r
)\r
{\r
- CPU_MP_DATA *CpuMpData;\r
+ CPU_MP_DATA *CpuMpData;\r
\r
CpuMpData = GetCpuMpData ();\r
\r
return EFI_SUCCESS;\r
}\r
\r
-\r
/**\r
Enable Debug Agent to support source debugging on AP function.\r
\r
ASSERT (CpuMpData != NULL);\r
} else {\r
AsmReadIdtr (&Idtr);\r
- CpuMpData = (CPU_MP_DATA *) (Idtr.Base + Idtr.Limit + 1);\r
+ CpuMpData = (CPU_MP_DATA *)(Idtr.Base + Idtr.Limit + 1);\r
}\r
+\r
return CpuMpData;\r
}\r
\r
**/\r
VOID\r
SaveCpuMpData (\r
- IN CPU_MP_DATA *CpuMpData\r
+ IN CPU_MP_DATA *CpuMpData\r
)\r
{\r
- UINT64 Data64;\r
+ UINT64 Data64;\r
+\r
//\r
// Build location of CPU MP DATA buffer in HOB\r
//\r
- Data64 = (UINT64) (UINTN) CpuMpData;\r
+ Data64 = (UINT64)(UINTN)CpuMpData;\r
BuildGuidDataHob (\r
&mCpuInitMpLibHobGuid,\r
- (VOID *) &Data64,\r
+ (VOID *)&Data64,\r
sizeof (UINT64)\r
);\r
}\r
**/\r
BOOLEAN\r
CheckOverlapWithAllocatedBuffer (\r
- IN UINT64 WakeupBufferStart,\r
- IN UINT64 WakeupBufferEnd\r
+ IN UINT64 WakeupBufferStart,\r
+ IN UINT64 WakeupBufferEnd\r
)\r
{\r
- EFI_PEI_HOB_POINTERS Hob;\r
- EFI_HOB_MEMORY_ALLOCATION *MemoryHob;\r
- BOOLEAN Overlapped;\r
- UINT64 MemoryStart;\r
- UINT64 MemoryEnd;\r
+ EFI_PEI_HOB_POINTERS Hob;\r
+ EFI_HOB_MEMORY_ALLOCATION *MemoryHob;\r
+ BOOLEAN Overlapped;\r
+ UINT64 MemoryStart;\r
+ UINT64 MemoryEnd;\r
\r
Overlapped = FALSE;\r
//\r
break;\r
}\r
}\r
+\r
Hob.Raw = GET_NEXT_HOB (Hob);\r
}\r
+\r
return Overlapped;\r
}\r
\r
**/\r
UINTN\r
GetWakeupBuffer (\r
- IN UINTN WakeupBufferSize\r
+ IN UINTN WakeupBufferSize\r
)\r
{\r
- EFI_PEI_HOB_POINTERS Hob;\r
- UINT64 WakeupBufferStart;\r
- UINT64 WakeupBufferEnd;\r
+ EFI_PEI_HOB_POINTERS Hob;\r
+ UINT64 WakeupBufferStart;\r
+ UINT64 WakeupBufferEnd;\r
\r
WakeupBufferSize = (WakeupBufferSize + SIZE_4KB - 1) & ~(SIZE_4KB - 1);\r
\r
(EFI_RESOURCE_ATTRIBUTE_READ_PROTECTED |\r
EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTED |\r
EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTED\r
- )) == 0)\r
- ) {\r
+ )) == 0)\r
+ )\r
+ {\r
//\r
// Need memory under 1MB to be collected here\r
//\r
WakeupBufferEnd = Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength;\r
- if (WakeupBufferEnd > BASE_1MB) {\r
+ if (ConfidentialComputingGuestHas (CCAttrAmdSevEs) &&\r
+ (WakeupBufferEnd > mSevEsPeiWakeupBuffer))\r
+ {\r
+ //\r
+ // SEV-ES Wakeup buffer should be under 1MB and under any previous one\r
+ //\r
+ WakeupBufferEnd = mSevEsPeiWakeupBuffer;\r
+ } else if (WakeupBufferEnd > BASE_1MB) {\r
//\r
// Wakeup buffer should be under 1MB\r
//\r
WakeupBufferEnd = BASE_1MB;\r
}\r
+\r
while (WakeupBufferEnd > WakeupBufferSize) {\r
//\r
// Wakeup buffer should be aligned on 4KB\r
if (WakeupBufferStart < Hob.ResourceDescriptor->PhysicalStart) {\r
break;\r
}\r
+\r
if (CheckOverlapWithAllocatedBuffer (WakeupBufferStart, WakeupBufferEnd)) {\r
//\r
// If this range is overlapped with existing allocated buffer, skip it\r
WakeupBufferEnd -= WakeupBufferSize;\r
continue;\r
}\r
- DEBUG ((DEBUG_INFO, "WakeupBufferStart = %x, WakeupBufferSize = %x\n",\r
- WakeupBufferStart, WakeupBufferSize));\r
+\r
+ DEBUG ((\r
+ DEBUG_INFO,\r
+ "WakeupBufferStart = %x, WakeupBufferSize = %x\n",\r
+ WakeupBufferStart,\r
+ WakeupBufferSize\r
+ ));\r
+\r
+ if (ConfidentialComputingGuestHas (CCAttrAmdSevEs)) {\r
+ //\r
+ // Next SEV-ES wakeup buffer allocation must be below this\r
+ // allocation\r
+ //\r
+ mSevEsPeiWakeupBuffer = WakeupBufferStart;\r
+ }\r
+\r
return (UINTN)WakeupBufferStart;\r
}\r
}\r
}\r
+\r
//\r
// Find the next HOB\r
//\r
Hob.Raw = GET_NEXT_HOB (Hob);\r
}\r
\r
- return (UINTN) -1;\r
+ return (UINTN)-1;\r
}\r
\r
/**\r
**/\r
UINTN\r
GetModeTransitionBuffer (\r
- IN UINTN BufferSize\r
+ IN UINTN BufferSize\r
+ )\r
+{\r
+ //\r
+ // PEI phase doesn't need to do such transition. So simply return 0.\r
+ //\r
+ return 0;\r
+}\r
+\r
+/**\r
+ Return the address of the SEV-ES AP jump table.\r
+\r
+ This buffer is required in order for an SEV-ES guest to transition from\r
+ UEFI into an OS.\r
+\r
+ @return Return SEV-ES AP jump table buffer\r
+**/\r
+UINTN\r
+GetSevEsAPMemory (\r
+ VOID\r
)\r
{\r
//\r
**/\r
VOID\r
BuildMicrocodeCacheHob (\r
- IN CPU_MP_DATA *CpuMpData\r
+ IN CPU_MP_DATA *CpuMpData\r
)\r
{\r
- EDKII_MICROCODE_PATCH_HOB *MicrocodeHob;\r
- UINTN HobDataLength;\r
- UINT32 Index;\r
+ EDKII_MICROCODE_PATCH_HOB *MicrocodeHob;\r
+ UINTN HobDataLength;\r
+ UINT32 Index;\r
\r
HobDataLength = sizeof (EDKII_MICROCODE_PATCH_HOB) +\r
sizeof (UINT64) * CpuMpData->CpuCount;\r
\r
- MicrocodeHob = AllocatePool (HobDataLength);\r
+ MicrocodeHob = AllocatePool (HobDataLength);\r
if (MicrocodeHob == NULL) {\r
ASSERT (FALSE);\r
return;\r
**/\r
VOID\r
InitMpGlobalData (\r
- IN CPU_MP_DATA *CpuMpData\r
+ IN CPU_MP_DATA *CpuMpData\r
)\r
{\r
EFI_STATUS Status;\r
EFI_STATUS\r
EFIAPI\r
MpInitLibStartupAllAPs (\r
- IN EFI_AP_PROCEDURE Procedure,\r
- IN BOOLEAN SingleThread,\r
- IN EFI_EVENT WaitEvent OPTIONAL,\r
- IN UINTN TimeoutInMicroseconds,\r
- IN VOID *ProcedureArgument OPTIONAL,\r
- OUT UINTN **FailedCpuList OPTIONAL\r
+ IN EFI_AP_PROCEDURE Procedure,\r
+ IN BOOLEAN SingleThread,\r
+ IN EFI_EVENT WaitEvent OPTIONAL,\r
+ IN UINTN TimeoutInMicroseconds,\r
+ IN VOID *ProcedureArgument OPTIONAL,\r
+ OUT UINTN **FailedCpuList OPTIONAL\r
)\r
{\r
if (WaitEvent != NULL) {\r
EFI_STATUS\r
EFIAPI\r
MpInitLibStartupThisAP (\r
- IN EFI_AP_PROCEDURE Procedure,\r
- IN UINTN ProcessorNumber,\r
- IN EFI_EVENT WaitEvent OPTIONAL,\r
- IN UINTN TimeoutInMicroseconds,\r
- IN VOID *ProcedureArgument OPTIONAL,\r
- OUT BOOLEAN *Finished OPTIONAL\r
+ IN EFI_AP_PROCEDURE Procedure,\r
+ IN UINTN ProcessorNumber,\r
+ IN EFI_EVENT WaitEvent OPTIONAL,\r
+ IN UINTN TimeoutInMicroseconds,\r
+ IN VOID *ProcedureArgument OPTIONAL,\r
+ OUT BOOLEAN *Finished OPTIONAL\r
)\r
{\r
if (WaitEvent != NULL) {\r
EFI_STATUS\r
EFIAPI\r
MpInitLibSwitchBSP (\r
- IN UINTN ProcessorNumber,\r
- IN BOOLEAN EnableOldBSP\r
+ IN UINTN ProcessorNumber,\r
+ IN BOOLEAN EnableOldBSP\r
)\r
{\r
return SwitchBSPWorker (ProcessorNumber, EnableOldBSP);\r
EFI_STATUS\r
EFIAPI\r
MpInitLibEnableDisableAP (\r
- IN UINTN ProcessorNumber,\r
- IN BOOLEAN EnableAP,\r
- IN UINT32 *HealthFlag OPTIONAL\r
+ IN UINTN ProcessorNumber,\r
+ IN BOOLEAN EnableAP,\r
+ IN UINT32 *HealthFlag OPTIONAL\r
)\r
{\r
return EnableDisableApWorker (ProcessorNumber, EnableAP, HealthFlag);\r
This funtion will try to invoke platform specific microcode shadow logic to\r
relocate microcode update patches into memory.\r
\r
- @param[in] CpuMpData The pointer to CPU MP Data structure.\r
+ @param[in, out] CpuMpData The pointer to CPU MP Data structure.\r
\r
@retval EFI_SUCCESS Shadow microcode success.\r
@retval EFI_OUT_OF_RESOURCES No enough resource to complete the operation.\r
**/\r
EFI_STATUS\r
PlatformShadowMicrocode (\r
- IN OUT CPU_MP_DATA *CpuMpData\r
+ IN OUT CPU_MP_DATA *CpuMpData\r
)\r
{\r
- EFI_STATUS Status;\r
- EDKII_PEI_SHADOW_MICROCODE_PPI *ShadowMicrocodePpi;\r
- UINTN CpuCount;\r
- EDKII_PEI_MICROCODE_CPU_ID *MicrocodeCpuId;\r
- UINTN Index;\r
- UINTN BufferSize;\r
- VOID *Buffer;\r
+ EFI_STATUS Status;\r
+ EDKII_PEI_SHADOW_MICROCODE_PPI *ShadowMicrocodePpi;\r
+ UINTN CpuCount;\r
+ EDKII_PEI_MICROCODE_CPU_ID *MicrocodeCpuId;\r
+ UINTN Index;\r
+ UINTN BufferSize;\r
+ VOID *Buffer;\r
\r
Status = PeiServicesLocatePpi (\r
&gEdkiiPeiShadowMicrocodePpiGuid,\r
0,\r
NULL,\r
- (VOID **) &ShadowMicrocodePpi\r
+ (VOID **)&ShadowMicrocodePpi\r
);\r
if (EFI_ERROR (Status)) {\r
return EFI_UNSUPPORTED;\r
}\r
\r
- CpuCount = CpuMpData->CpuCount;\r
- MicrocodeCpuId = (EDKII_PEI_MICROCODE_CPU_ID *) AllocateZeroPool (sizeof (EDKII_PEI_MICROCODE_CPU_ID) * CpuCount);\r
+ CpuCount = CpuMpData->CpuCount;\r
+ MicrocodeCpuId = (EDKII_PEI_MICROCODE_CPU_ID *)AllocateZeroPool (sizeof (EDKII_PEI_MICROCODE_CPU_ID) * CpuCount);\r
if (MicrocodeCpuId == NULL) {\r
return EFI_OUT_OF_RESOURCES;\r
}\r
}\r
\r
Status = ShadowMicrocodePpi->ShadowMicrocode (\r
- ShadowMicrocodePpi,\r
- CpuCount,\r
- MicrocodeCpuId,\r
- &BufferSize,\r
- &Buffer\r
- );\r
+ ShadowMicrocodePpi,\r
+ CpuCount,\r
+ MicrocodeCpuId,\r
+ &BufferSize,\r
+ &Buffer\r
+ );\r
FreePool (MicrocodeCpuId);\r
if (EFI_ERROR (Status)) {\r
return EFI_NOT_FOUND;\r
}\r
\r
- CpuMpData->MicrocodePatchAddress = (UINTN) Buffer;\r
+ CpuMpData->MicrocodePatchAddress = (UINTN)Buffer;\r
CpuMpData->MicrocodePatchRegionSize = BufferSize;\r
\r
DEBUG ((\r
DEBUG_INFO,\r
"%a: Required microcode patches have been loaded at 0x%lx, with size 0x%lx.\n",\r
- __FUNCTION__, CpuMpData->MicrocodePatchAddress, CpuMpData->MicrocodePatchRegionSize\r
+ __FUNCTION__,\r
+ CpuMpData->MicrocodePatchAddress,\r
+ CpuMpData->MicrocodePatchRegionSize\r
));\r
\r
return EFI_SUCCESS;\r