]> git.proxmox.com Git - mirror_edk2.git/blobdiff - IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/DispatchExecute.c
Add IntelFsp2Pkg and IntelFsp2WrapperPkg.
[mirror_edk2.git] / IntelFsp2WrapperPkg / Library / BaseFspWrapperApiLib / X64 / DispatchExecute.c
diff --git a/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/DispatchExecute.c b/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/DispatchExecute.c
new file mode 100644 (file)
index 0000000..061d381
--- /dev/null
@@ -0,0 +1,108 @@
+/** @file\r
+  Execute 32-bit code in Long Mode.\r
+  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) 2014 - 2016, 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
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <Uefi.h>\r
+#include <Library/BaseLib.h>\r
+#include <FspEas.h>\r
+\r
+#pragma pack(1)\r
+typedef union {\r
+  struct {\r
+    UINT32  LimitLow    : 16;\r
+    UINT32  BaseLow     : 16;\r
+    UINT32  BaseMid     : 8;\r
+    UINT32  Type        : 4;\r
+    UINT32  System      : 1;\r
+    UINT32  Dpl         : 2;\r
+    UINT32  Present     : 1;\r
+    UINT32  LimitHigh   : 4;\r
+    UINT32  Software    : 1;\r
+    UINT32  Reserved    : 1;\r
+    UINT32  DefaultSize : 1;\r
+    UINT32  Granularity : 1;\r
+    UINT32  BaseHigh    : 8;\r
+  } Bits;\r
+  UINT64  Uint64;\r
+} IA32_GDT;\r
+#pragma pack()\r
+\r
+GLOBAL_REMOVE_IF_UNREFERENCED IA32_GDT mGdtEntries[] = {\r
+  {{0,      0,  0,  0,    0,  0,  0,  0,    0,  0, 0,  0,  0}}, /* 0x0:  reserve */\r
+  {{0xFFFF, 0,  0,  0xB,  1,  0,  1,  0xF,  0,  0, 1,  1,  0}}, /* 0x8:  compatibility mode */\r
+  {{0xFFFF, 0,  0,  0xB,  1,  0,  1,  0xF,  0,  1, 0,  1,  0}}, /* 0x10: for long mode */\r
+  {{0xFFFF, 0,  0,  0x3,  1,  0,  1,  0xF,  0,  0, 1,  1,  0}}, /* 0x18: data */\r
+  {{0,      0,  0,  0,    0,  0,  0,  0,    0,  0, 0,  0,  0}}, /* 0x20: reserve */\r
+};\r
+\r
+//\r
+// IA32 Gdt register\r
+//\r
+GLOBAL_REMOVE_IF_UNREFERENCED IA32_DESCRIPTOR mGdt = {\r
+  sizeof (mGdtEntries) - 1,\r
+  (UINTN) mGdtEntries\r
+  };\r
+\r
+/**\r
+  Assembly function to transition from long mode to compatibility mode to execute 32-bit code and then transit back to\r
+  long mode.\r
+\r
+  @param[in] Function     The 32bit code entry to be executed.\r
+  @param[in] Param1       The first parameter to pass to 32bit code\r
+  @param[in] Param2       The second parameter to pass to 32bit code\r
+  @param[in] InternalGdtr The GDT and GDT descriptor used by this library\r
+\r
+  @return status.\r
+**/\r
+UINT32\r
+AsmExecute32BitCode (\r
+  IN UINT64           Function,\r
+  IN UINT64           Param1,\r
+  IN UINT64           Param2,\r
+  IN IA32_DESCRIPTOR  *InternalGdtr\r
+  );\r
+\r
+/**\r
+  Wrapper for a thunk  to transition from long mode to compatibility mode to execute 32-bit code and then transit back to\r
+  long mode.\r
+\r
+  @param[in] Function     The 32bit code entry to be executed.\r
+  @param[in] Param1       The first parameter to pass to 32bit code.\r
+  @param[in] Param2       The second parameter to pass to 32bit code.\r
+\r
+  @return EFI_STATUS.\r
+**/\r
+EFI_STATUS\r
+Execute32BitCode (\r
+  IN UINT64      Function,\r
+  IN UINT64      Param1,\r
+  IN UINT64      Param2\r
+  )\r
+{\r
+  EFI_STATUS       Status;\r
+  IA32_DESCRIPTOR  Idtr;\r
+\r
+  //\r
+  // Idtr might be changed inside of FSP. 32bit FSP only knows the <4G address.\r
+  // If IDTR.Base is >4G, FSP can not handle. So we need save/restore IDTR here for X64 only.\r
+  // Interrupt is already disabled here, so it is safety to update IDTR.\r
+  //\r
+  AsmReadIdtr (&Idtr);\r
+  Status = AsmExecute32BitCode (Function, Param1, Param2, &mGdt);\r
+  AsmWriteIdtr (&Idtr);\r
+\r
+  return Status;\r
+}\r
+\r