AsmReadGdtr ((IA32_DESCRIPTOR *)Buffer);\r
}\r
\r
+/**\r
+ Migrates the Global Descriptor Table (GDT) to permanent memory.\r
+\r
+ @retval EFI_SUCCESS The GDT was migrated successfully.\r
+ @retval EFI_OUT_OF_RESOURCES The GDT could not be migrated due to lack of available memory.\r
+\r
+**/\r
+EFI_STATUS\r
+MigrateGdt (\r
+ VOID\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN GdtBufferSize;\r
+ IA32_DESCRIPTOR Gdtr;\r
+ VOID *GdtBuffer;\r
+\r
+ AsmReadGdtr ((IA32_DESCRIPTOR *) &Gdtr);\r
+ GdtBufferSize = sizeof (IA32_SEGMENT_DESCRIPTOR) -1 + Gdtr.Limit + 1;\r
+\r
+ Status = PeiServicesAllocatePool (\r
+ GdtBufferSize,\r
+ &GdtBuffer\r
+ );\r
+ ASSERT (GdtBuffer != NULL);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ GdtBuffer = ALIGN_POINTER (GdtBuffer, sizeof (IA32_SEGMENT_DESCRIPTOR));\r
+ CopyMem (GdtBuffer, (VOID *) Gdtr.Base, Gdtr.Limit + 1);\r
+ Gdtr.Base = (UINTN) GdtBuffer;\r
+ AsmWriteGdtr (&Gdtr);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
/**\r
Initializes CPU exceptions handlers for the sake of stack switch requirement.\r
\r
OUT EFI_SEC_PLATFORM_INFORMATION_RECORD2 *PlatformInformationRecord2\r
);\r
\r
+/**\r
+ Migrates the Global Descriptor Table (GDT) to permanent memory.\r
+\r
+ @retval EFI_SUCCESS The GDT was migrated successfully.\r
+ @retval EFI_OUT_OF_RESOURCES The GDT could not be migrated due to lack of available memory.\r
+\r
+**/\r
+EFI_STATUS\r
+MigrateGdt (\r
+ VOID\r
+ );\r
+\r
/**\r
Initializes MP and exceptions handlers.\r
\r
gUefiCpuPkgTokenSpaceGuid.PcdCpuStackSwitchExceptionList ## SOMETIMES_CONSUMES\r
gUefiCpuPkgTokenSpaceGuid.PcdCpuKnownGoodStackSize ## SOMETIMES_CONSUMES\r
gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize ## SOMETIMES_CONSUMES\r
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMigrateTemporaryRamFirmwareVolumes ## CONSUMES\r
\r
[Depex]\r
TRUE\r
IN VOID *Ppi\r
)\r
{\r
- EFI_STATUS Status;\r
- BOOLEAN InitStackGuard;\r
+ EFI_STATUS Status;\r
+ BOOLEAN InitStackGuard;\r
+ BOOLEAN InterruptState;\r
+\r
+ if (PcdGetBool (PcdMigrateTemporaryRamFirmwareVolumes)) {\r
+ InterruptState = SaveAndDisableInterrupts ();\r
+ Status = MigrateGdt ();\r
+ ASSERT_EFI_ERROR (Status);\r
+ SetInterruptState (InterruptState);\r
+ }\r
\r
//\r
// Paging must be setup first. Otherwise the exception TSS setup during MP\r