]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c
Enable the 0-31 temporary IDT entries prior to activate the LongMode. If not enable...
[mirror_edk2.git] / MdeModulePkg / Core / DxeIplPeim / Ia32 / DxeLoadFunc.c
index 63ee2af39664e9f851153c40b2a1b9f5f9418c18..bdece76187d78d49fe9e4c2a250e65931ae21396 100644 (file)
@@ -46,6 +46,11 @@ GLOBAL_REMOVE_IF_UNREFERENCED CONST IA32_DESCRIPTOR gGdt = {
   (UINTN) gGdtEntries\r
   };\r
 \r
+GLOBAL_REMOVE_IF_UNREFERENCED  IA32_DESCRIPTOR gLidtDescriptor = {\r
+  sizeof (X64_IDT_GATE_DESCRIPTOR) * 32 - 1,\r
+  0\r
+};\r
+\r
 VOID\r
 HandOffToDxeCore (\r
   IN EFI_PHYSICAL_ADDRESS   DxeCoreEntryPoint,\r
@@ -57,6 +62,11 @@ HandOffToDxeCore (
   EFI_PHYSICAL_ADDRESS      BaseOfStack;\r
   EFI_PHYSICAL_ADDRESS      TopOfStack;\r
   UINTN                     PageTables;\r
+  X64_IDT_GATE_DESCRIPTOR   *IdtTable;\r
+  UINTN                     SizeOfTemplate;\r
+  VOID                      *TemplateBase;\r
+  EFI_PHYSICAL_ADDRESS      VectorAddress;\r
+  UINT32                    Index;\r
 \r
   Status = PeiServicesAllocatePages (EfiBootServicesData, EFI_SIZE_TO_PAGES (STACK_SIZE), &BaseOfStack);\r
   ASSERT_EFI_ERROR (Status);\r
@@ -95,7 +105,40 @@ HandOffToDxeCore (
     ASSERT_EFI_ERROR (Status);\r
     \r
     AsmWriteCr3 (PageTables);\r
-     //\r
+\r
+\r
+    if (FeaturePcdGet (PcdDxeIplEnableIdt)) {\r
+      SizeOfTemplate = AsmGetVectorTemplatInfo (&TemplateBase);\r
+  \r
+      Status = PeiServicesAllocatePages (\r
+                 EfiBootServicesData, \r
+                 EFI_SIZE_TO_PAGES((SizeOfTemplate + sizeof (X64_IDT_GATE_DESCRIPTOR)) * 32), \r
+                 &VectorAddress\r
+                 );\r
+  \r
+      ASSERT_EFI_ERROR (Status);\r
+  \r
+      IdtTable      = (X64_IDT_GATE_DESCRIPTOR *) (UINTN) (VectorAddress + SizeOfTemplate * 32);\r
+      for (Index = 0; Index < 32; Index++) {\r
+        IdtTable[Index].Ia32IdtEntry.Bits.GateType    =  0x8e;\r
+        IdtTable[Index].Ia32IdtEntry.Bits.Reserved_0  =  0;\r
+        IdtTable[Index].Ia32IdtEntry.Bits.Selector    =  SYS_CODE64_SEL;\r
+  \r
+        IdtTable[Index].Ia32IdtEntry.Bits.OffsetLow   = (UINT16) VectorAddress;\r
+        IdtTable[Index].Ia32IdtEntry.Bits.OffsetHigh  = (UINT16) (VectorAddress >> 16);\r
+        IdtTable[Index].Offset32To63                  = (UINT32) (VectorAddress >> 32);\r
+        IdtTable[Index].Reserved                      = 0;\r
+  \r
+        CopyMem ((VOID *) (UINTN) VectorAddress, TemplateBase, SizeOfTemplate);\r
+        AsmVectorFixup ((VOID *) (UINTN) VectorAddress, (UINT8) Index);\r
+  \r
+        VectorAddress += SizeOfTemplate;\r
+      }\r
+  \r
+      gLidtDescriptor.Base = (UINTN) IdtTable;\r
+      AsmWriteIdtr (&gLidtDescriptor);\r
+    }\r
+    //\r
     // Go to Long Mode. Interrupts will not get turned on until the CPU AP is loaded.\r
     // Call x64 drivers passing in single argument, a pointer to the HOBs.\r
     // \r