+++ /dev/null
-/** @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) 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
- 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
-#include "ScriptSave.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
-\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
-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
- Assembly function to transition from long mode to compatibility mode to execute 32-bit code and then transit back to\r
- long mode.\r
- @param Function The 32bit code entry to be executed.\r
- @param Param1 The first parameter to pass to 32bit code\r
- @param Param2 The second parameter to pass to 32bit code\r
- @param InternalGdtr The GDT and GDT descriptor used by this library\r
- \r
- @retval EFI_SUCCESS Execute 32bit code successfully.\r
- @retval other Something wrong when execute the 32bit code \r
-**/\r
-EFI_STATUS\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 Function The 32bit code entry to be executed.\r
- @param Param1 The first parameter to pass to 32bit code\r
- @param Param2 The second parameter to pass to 32bit code\r
- @retval EFI_SUCCESS Execute 32bit code successfully.\r
- @retval other Something wrong when execute the 32bit code \r
- \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 *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
- Function,\r
- Param1,\r
- Param2,\r
- &mGdt\r
- );\r
-\r
- //\r
- // Restore X64 IDT table\r
- //\r
- AsmWriteIdtr ((IA32_DESCRIPTOR *) &X64Idtr);\r
-\r
- return Status;\r
-}\r
-\r