#include <Library/UefiBootServicesTableLib.h>\r
#include <Library/DebugAgentLib.h>\r
#include <Library/DxeServicesTableLib.h>\r
+#include <Register/Amd/Fam17Msr.h>\r
+#include <Register/Amd/Ghcb.h>\r
\r
#include <Protocol/Timer.h>\r
\r
return (UINTN)StartAddress;\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
+ EFI_STATUS Status;\r
+ EFI_PHYSICAL_ADDRESS StartAddress;\r
+\r
+ //\r
+ // Allocate 1 page for AP jump table page\r
+ //\r
+ StartAddress = BASE_4GB - 1;\r
+ Status = gBS->AllocatePages (\r
+ AllocateMaxAddress,\r
+ EfiReservedMemoryType,\r
+ 1,\r
+ &StartAddress\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ DEBUG ((DEBUG_INFO, "Dxe: SevEsAPMemory = %lx\n", (UINTN) StartAddress));\r
+\r
+ return (UINTN) StartAddress;\r
+}\r
+\r
/**\r
Checks APs status and updates APs status if needed.\r
\r
}\r
}\r
\r
+/**\r
+ Get Protected mode code segment with 16-bit default addressing\r
+ from current GDT table.\r
+\r
+ @return Protected mode 16-bit code segment value.\r
+**/\r
+UINT16\r
+GetProtectedMode16CS (\r
+ VOID\r
+ )\r
+{\r
+ IA32_DESCRIPTOR GdtrDesc;\r
+ IA32_SEGMENT_DESCRIPTOR *GdtEntry;\r
+ UINTN GdtEntryCount;\r
+ UINT16 Index;\r
+\r
+ Index = (UINT16) -1;\r
+ AsmReadGdtr (&GdtrDesc);\r
+ GdtEntryCount = (GdtrDesc.Limit + 1) / sizeof (IA32_SEGMENT_DESCRIPTOR);\r
+ GdtEntry = (IA32_SEGMENT_DESCRIPTOR *) GdtrDesc.Base;\r
+ for (Index = 0; Index < GdtEntryCount; Index++) {\r
+ if (GdtEntry->Bits.L == 0) {\r
+ if (GdtEntry->Bits.Type > 8 && GdtEntry->Bits.DB == 0) {\r
+ break;\r
+ }\r
+ }\r
+ GdtEntry++;\r
+ }\r
+ ASSERT (Index != GdtEntryCount);\r
+ return Index * 8;\r
+}\r
+\r
/**\r
Get Protected mode code segment from current GDT table.\r
\r
GdtEntry = (IA32_SEGMENT_DESCRIPTOR *) GdtrDesc.Base;\r
for (Index = 0; Index < GdtEntryCount; Index++) {\r
if (GdtEntry->Bits.L == 0) {\r
- if (GdtEntry->Bits.Type > 8 && GdtEntry->Bits.L == 0) {\r
+ if (GdtEntry->Bits.Type > 8 && GdtEntry->Bits.DB == 1) {\r
break;\r
}\r
}\r
\r
CpuMpData = GetCpuMpData ();\r
CpuMpData->PmCodeSegment = GetProtectedModeCS ();\r
+ CpuMpData->Pm16CodeSegment = GetProtectedMode16CS ();\r
CpuMpData->ApLoopMode = PcdGet8 (PcdCpuApLoopMode);\r
mNumberToFinish = CpuMpData->CpuCount - 1;\r
WakeUpAP (CpuMpData, TRUE, 0, RelocateApLoop, NULL, TRUE);\r