}\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
// These are IDT entries pointing to 10:FFFFFFE4h.\r
//\r
//\r
State = SaveAndDisableInterrupts ();\r
\r
+ //\r
+ // Migrate GDT before NEM near down\r
+ //\r
+ if (PcdGetBool (PcdMigrateTemporaryRamFirmwareVolumes)) {\r
+ Status = MigrateGdt ();\r
+ ASSERT_EFI_ERROR (Status);\r
+ }\r
+\r
//\r
// Disable Temporary RAM after Stack and Heap have been migrated at this point.\r
//\r