]> git.proxmox.com Git - mirror_edk2.git/commitdiff
1. Updated S3Resume2Pei to save IA32 IDT table setup in protected mode.
authorvanjeff <vanjeff@6f19259b-4bc3-4df7-8a09-765794883524>
Thu, 15 Mar 2012 05:33:43 +0000 (05:33 +0000)
committervanjeff <vanjeff@6f19259b-4bc3-4df7-8a09-765794883524>
Thu, 15 Mar 2012 05:33:43 +0000 (05:33 +0000)
2. Updated BootScriptSaveOnS3SaveStateThunk restore IA32 IDT table before transferring to protected mode.
It could support exception handler in 32-bit Framework Boot Script code.

Signed-off-by: vanjeff
Reviewed-by: jyao1
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13099 6f19259b-4bc3-4df7-8a09-765794883524

EdkCompatibilityPkg/Compatibility/BootScriptSaveOnS3SaveStateThunk/X64/DispatchExecute.c
UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume.c

index 8ef42999018c609287fe63b36d6b5a86ad71d60b..20567bddebee8486d7397816e88a5caa3f861a62 100644 (file)
@@ -3,7 +3,7 @@
   Provide a thunk function to transition from long mode to compatibility mode to execute 32-bit code and then transit\r
   back to long mode.\r
   \r
-  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>\r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
   which accompanies this distribution.  The full text of the license may be found at\r
@@ -34,8 +34,24 @@ typedef union {
   } Bits;\r
   UINT64  Uint64;\r
 } IA32_GDT;\r
+\r
+///\r
+/// Byte packed structure for an IA-32 Interrupt Gate Descriptor.\r
+///\r
+typedef union {\r
+  struct {\r
+    UINT32  OffsetLow:16;   ///< Offset bits 15..0.\r
+    UINT32  Selector:16;    ///< Selector.\r
+    UINT32  Reserved_0:8;   ///< Reserved.\r
+    UINT32  GateType:8;     ///< Gate Type.  See #defines above.\r
+    UINT32  OffsetHigh:16;  ///< Offset bits 31..16.\r
+  } Bits;\r
+  UINT64  Uint64;\r
+} IA32_IDT_ENTRY;\r
 #pragma pack()\r
 \r
+#define COMPATIBILITY_MODE_SELECTOR  8\r
+\r
 //\r
 // Global Descriptor Table (GDT)\r
 //\r
@@ -92,7 +108,36 @@ Execute32BitCode (
   )\r
 {\r
   EFI_STATUS                 Status;\r
\r
+  IA32_DESCRIPTOR            *Ia32Idtr;\r
+  IA32_DESCRIPTOR            X64Idtr;\r
+  UINTN                      Ia32IdtEntryCount;\r
+  UINTN                      Index;\r
+  IA32_IDT_ENTRY             *Ia32IdtEntry;\r
+\r
+  //\r
+  // Save x64 IDT Descriptor\r
+  //\r
+  AsmReadIdtr ((IA32_DESCRIPTOR *) &X64Idtr);\r
+\r
+  //\r
+  // Get the IA32 IDT Descriptor saved in 16 bytes in front of X64 IDT table.\r
+  //\r
+  Ia32Idtr = (IA32_DESCRIPTOR *) (UINTN) (X64Idtr.Base - 16);\r
+  Ia32IdtEntryCount = (Ia32Idtr->Limit + 1) / sizeof (IA32_IDT_ENTRY);\r
+\r
+  Ia32IdtEntry = (IA32_IDT_ENTRY *)(Ia32Idtr->Base);\r
+  for (Index = 0; Index < Ia32IdtEntryCount; Index ++ ) {\r
+    //\r
+    // Use the new Code Selector value\r
+    //\r
+    Ia32IdtEntry[Index].Bits.Selector = COMPATIBILITY_MODE_SELECTOR;\r
+  }\r
+\r
+  //\r
+  // Setup IA32 IDT table for 32-bit framework Boot Script code\r
+  //\r
+  AsmWriteIdtr (Ia32Idtr);\r
+\r
   ASSERT (Function != 0);\r
  \r
   Status = AsmExecute32BitCode (\r
@@ -101,6 +146,12 @@ Execute32BitCode (
              Param2,\r
              &mGdt\r
              );\r
+\r
+  //\r
+  // Restore X64 IDT table\r
+  //\r
+  AsmWriteIdtr ((IA32_DESCRIPTOR *) &X64Idtr);\r
+\r
   return Status;\r
 }\r
 \r
index 3afd0ff0e395859679c22afae22fc51bd9fa368a..c0680bf7715767055e0a243ef40c42024d7c44aa 100644 (file)
@@ -4,7 +4,7 @@
   This module will excute the boot script saved during last boot and after that,\r
   control is passed to OS waking up handler.\r
 \r
-  Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
 \r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions\r
@@ -712,6 +712,12 @@ S3ResumeExecuteBootScript (
     // \r
     IdtBuffer = AllocatePages (EFI_SIZE_TO_PAGES((IdtDescriptor->Limit + 1) + 16));\r
     ASSERT (IdtBuffer != NULL);\r
+    //\r
+    // Additional 16 bytes allocated to save IA32 IDT descriptor and Pei Service Table Pointer\r
+    // IA32 IDT descriptor will be used to setup IA32 IDT table for 32-bit Framework Boot Script code\r
+    // \r
+    ZeroMem (IdtBuffer, 16);\r
+    AsmReadIdtr ((IA32_DESCRIPTOR *)IdtBuffer);\r
     CopyMem ((VOID*)((UINT8*)IdtBuffer + 16),(VOID*)(IdtDescriptor->Base), (IdtDescriptor->Limit + 1));\r
     IdtDescriptor->Base = (UINTN)((UINT8*)IdtBuffer + 16);\r
     *(UINTN*)(IdtDescriptor->Base - sizeof(UINTN)) = (UINTN)GetPeiServicesTablePointer ();\r