--- /dev/null
+/*++\r
+\r
+Copyright (c) 2004 - 2006, Intel Corporation \r
+All rights reserved. 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
+Module Name:\r
+\r
+ x86Thunk.c\r
+ \r
+Abstract: \r
+\r
+ Real Mode Thunk Functions for IA32 and X64.\r
+\r
+--*/\r
+\r
+#include "BaseLibInternals.h"\r
+//\r
+// Byte packed structure for a segment descriptor in a GDT/LDT\r
+//\r
+typedef union {\r
+ struct {\r
+ UINT32 LimitLow:16;\r
+ UINT32 BaseLow:16;\r
+ UINT32 BaseMid:8;\r
+ UINT32 Type:4;\r
+ UINT32 S:1;\r
+ UINT32 DPL:2;\r
+ UINT32 P:1;\r
+ UINT32 LimitHigh:4;\r
+ UINT32 AVL:1;\r
+ UINT32 L:1;\r
+ UINT32 DB:1;\r
+ UINT32 G:1;\r
+ UINT32 BaseHigh:8;\r
+ } Bits;\r
+ UINT64 Uint64;\r
+} IA32_SEGMENT_DESCRIPTOR;\r
+\r
+extern CONST UINT8 m16Start;\r
+extern CONST UINT16 m16Size;\r
+extern CONST UINT16 mThunk16Attr;\r
+extern CONST UINT16 m16Gdt;\r
+extern CONST UINT16 m16GdtrBase;\r
+extern CONST UINT16 mTransition;\r
+\r
+/**\r
+ Invokes 16-bit code in big real mode and returns the updated register set.\r
+\r
+ This function transfers control to the 16-bit code specified by CS:EIP using\r
+ the stack specified by SS:ESP in RegisterSet. The updated registers are saved\r
+ on the real mode stack and the starting address of the save area is returned.\r
+\r
+ @param RegisterSet Values of registers before invocation of 16-bit code.\r
+ @param Transition Pointer to the transition code under 1MB.\r
+\r
+ @return The pointer to a IA32_REGISTER_SET structure containing the updated\r
+ register values.\r
+\r
+**/\r
+IA32_REGISTER_SET *\r
+EFIAPI\r
+InternalAsmThunk16 (\r
+ IN IA32_REGISTER_SET *RegisterSet,\r
+ IN OUT VOID *Transition\r
+ );\r
+\r
+/**\r
+ Retrieves the properties for 16-bit thunk functions.\r
+\r
+ Computes the size of the buffer and stack below 1MB required to use the\r
+ AsmPrepareThunk16(), AsmThunk16() and AsmPrepareAndThunk16() functions. This\r
+ buffer size is returned in RealModeBufferSize, and the stack size is returned\r
+ in ExtraStackSize. If parameters are passed to the 16-bit real mode code,\r
+ then the actual minimum stack size is ExtraStackSize plus the maximum number\r
+ of bytes that need to be passed to the 16-bit real mode code.\r
+\r
+ If RealModeBufferSize is NULL, then ASSERT().\r
+ If ExtraStackSize is NULL, then ASSERT().\r
+\r
+ @param RealModeBufferSize A pointer to the size of the buffer below 1MB\r
+ required to use the 16-bit thunk functions.\r
+ @param ExtraStackSize A pointer to the extra size of stack below 1MB\r
+ that the 16-bit thunk functions require for\r
+ temporary storage in the transition to and from\r
+ 16-bit real mode.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+AsmGetThunk16Properties (\r
+ OUT UINT32 *RealModeBufferSize,\r
+ OUT UINT32 *ExtraStackSize\r
+ )\r
+{\r
+ ASSERT (RealModeBufferSize != NULL);\r
+ ASSERT (ExtraStackSize != NULL);\r
+\r
+ *RealModeBufferSize = m16Size;\r
+\r
+ //\r
+ // Extra 4 bytes for return address, and another 4 bytes for mode transition\r
+ //\r
+ *ExtraStackSize = sizeof (IA32_DWORD_REGS) + 8;\r
+}\r
+\r
+/**\r
+ Prepares all structures a code required to use AsmThunk16().\r
+\r
+ Prepares all structures and code required to use AsmThunk16().\r
+\r
+ If ThunkContext is NULL, then ASSERT().\r
+\r
+ @param ThunkContext A pointer to the context structure that describes the\r
+ 16-bit real mode code to call.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+AsmPrepareThunk16 (\r
+ OUT THUNK_CONTEXT *ThunkContext\r
+ )\r
+{\r
+ IA32_SEGMENT_DESCRIPTOR *RealModeGdt;\r
+\r
+ ASSERT (ThunkContext != NULL);\r
+ ASSERT ((UINTN)ThunkContext->RealModeBuffer < 0x100000);\r
+ ASSERT (ThunkContext->RealModeBufferSize >= m16Size);\r
+ ASSERT ((UINTN)ThunkContext->RealModeBuffer + m16Size <= 0x100000);\r
+\r
+ CopyMem (ThunkContext->RealModeBuffer, &m16Start, m16Size);\r
+\r
+ //\r
+ // Point RealModeGdt to the GDT to be used in transition\r
+ //\r
+ // RealModeGdt[0]: Reserved as NULL descriptor\r
+ // RealModeGdt[1]: Code Segment\r
+ // RealModeGdt[2]: Data Segment\r
+ // RealModeGdt[3]: Call Gate\r
+ //\r
+ RealModeGdt = (IA32_SEGMENT_DESCRIPTOR*)(\r
+ (UINTN)ThunkContext->RealModeBuffer + m16Gdt);\r
+\r
+ //\r
+ // Update Code & Data Segment Descriptor\r
+ //\r
+ RealModeGdt[1].Bits.BaseLow =\r
+ (UINT32)(UINTN)ThunkContext->RealModeBuffer & ~0xf;\r
+ RealModeGdt[1].Bits.BaseMid =\r
+ (UINT32)(UINTN)ThunkContext->RealModeBuffer >> 16;\r
+\r
+ //\r
+ // Update transition code entry point offset\r
+ //\r
+ *(UINT32*)((UINTN)ThunkContext->RealModeBuffer + mTransition) +=\r
+ (UINT32)(UINTN)ThunkContext->RealModeBuffer & 0xf;\r
+\r
+ //\r
+ // Update Segment Limits for both Code and Data Segment Descriptors\r
+ //\r
+ if ((ThunkContext->ThunkAttributes & THUNK_ATTRIBUTE_BIG_REAL_MODE) == 0) {\r
+ //\r
+ // Set segment limits to 64KB\r
+ //\r
+ RealModeGdt[1].Bits.LimitHigh = 0;\r
+ RealModeGdt[1].Bits.G = 0;\r
+ RealModeGdt[2].Bits.LimitHigh = 0;\r
+ RealModeGdt[2].Bits.G = 0;\r
+ }\r
+\r
+ //\r
+ // Update GDTBASE for this thunk context\r
+ //\r
+ *(VOID**)((UINTN)ThunkContext->RealModeBuffer + m16GdtrBase) = RealModeGdt;\r
+\r
+ //\r
+ // Update Thunk Attributes\r
+ //\r
+ *(UINT32*)((UINTN)ThunkContext->RealModeBuffer + mThunk16Attr) =\r
+ ThunkContext->ThunkAttributes;\r
+}\r
+\r
+/**\r
+ Transfers control to a 16-bit real mode entry point and returns the results.\r
+\r
+ Transfers control to a 16-bit real mode entry point and returns the results.\r
+ AsmPrepareThunk16() must be called with ThunkContext before this function is\r
+ used. This function must be called with interrupts disabled.\r
+\r
+ If ThunkContext is NULL, then ASSERT().\r
+ If AsmPrepareThunk16() was not previously called with ThunkContext, then ASSERT().\r
+\r
+ @param ThunkContext A pointer to the context structure that describes the\r
+ 16-bit real mode code to call.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+AsmThunk16 (\r
+ IN OUT THUNK_CONTEXT *ThunkContext\r
+ )\r
+{\r
+ IA32_REGISTER_SET *UpdatedRegs;\r
+\r
+ ASSERT (ThunkContext != NULL);\r
+ ASSERT ((UINTN)ThunkContext->RealModeBuffer < 0x100000);\r
+ ASSERT (ThunkContext->RealModeBufferSize >= m16Size);\r
+ ASSERT ((UINTN)ThunkContext->RealModeBuffer + m16Size <= 0x100000);\r
+\r
+ UpdatedRegs = InternalAsmThunk16 (\r
+ ThunkContext->RealModeState,\r
+ ThunkContext->RealModeBuffer\r
+ );\r
+\r
+ CopyMem (ThunkContext->RealModeState, UpdatedRegs, sizeof (*UpdatedRegs));\r
+}\r
+\r
+/**\r
+ Prepares all structures and code for a 16-bit real mode thunk, transfers\r
+ control to a 16-bit real mode entry point, and returns the results.\r
+\r
+ Prepares all structures and code for a 16-bit real mode thunk, transfers\r
+ control to a 16-bit real mode entry point, and returns the results. If the\r
+ caller only need to perform a single 16-bit real mode thunk, then this\r
+ service should be used. If the caller intends to make more than one 16-bit\r
+ real mode thunk, then it is more efficient if AsmPrepareThunk16() is called\r
+ once and AsmThunk16() can be called for each 16-bit real mode thunk. This\r
+ function must be called with interrupts disabled.\r
+\r
+ If ThunkContext is NULL, then ASSERT().\r
+\r
+ @param ThunkContext A pointer to the context structure that describes the\r
+ 16-bit real mode code to call.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+AsmPrepareAndThunk16 (\r
+ IN OUT THUNK_CONTEXT *ThunkContext\r
+ )\r
+{\r
+ AsmPrepareThunk16 (ThunkContext);\r
+ AsmThunk16 (ThunkContext);\r
+}\r
+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2004 - 2006, Intel Corporation \r
-All rights reserved. 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
-Module Name:\r
-\r
- x86Thunk.c\r
- \r
-Abstract: \r
-\r
- Real Mode Thunk Functions for IA32 and X64.\r
-\r
---*/\r
-\r
-#include "BaseLibInternals.h"\r
-//\r
-// Byte packed structure for a segment descriptor in a GDT/LDT\r
-//\r
-typedef union {\r
- struct {\r
- UINT32 LimitLow:16;\r
- UINT32 BaseLow:16;\r
- UINT32 BaseMid:8;\r
- UINT32 Type:4;\r
- UINT32 S:1;\r
- UINT32 DPL:2;\r
- UINT32 P:1;\r
- UINT32 LimitHigh:4;\r
- UINT32 AVL:1;\r
- UINT32 L:1;\r
- UINT32 DB:1;\r
- UINT32 G:1;\r
- UINT32 BaseHigh:8;\r
- } Bits;\r
- UINT64 Uint64;\r
-} IA32_SEGMENT_DESCRIPTOR;\r
-\r
-extern CONST UINT8 m16Start;\r
-extern CONST UINT16 m16Size;\r
-extern CONST UINT16 mThunk16Attr;\r
-extern CONST UINT16 m16Gdt;\r
-extern CONST UINT16 m16GdtrBase;\r
-extern CONST UINT16 mTransition;\r
-\r
-/**\r
- Invokes 16-bit code in big real mode and returns the updated register set.\r
-\r
- This function transfers control to the 16-bit code specified by CS:EIP using\r
- the stack specified by SS:ESP in RegisterSet. The updated registers are saved\r
- on the real mode stack and the starting address of the save area is returned.\r
-\r
- @param RegisterSet Values of registers before invocation of 16-bit code.\r
- @param Transition Pointer to the transition code under 1MB.\r
-\r
- @return The pointer to a IA32_REGISTER_SET structure containing the updated\r
- register values.\r
-\r
-**/\r
-IA32_REGISTER_SET *\r
-EFIAPI\r
-InternalAsmThunk16 (\r
- IN IA32_REGISTER_SET *RegisterSet,\r
- IN OUT VOID *Transition\r
- );\r
-\r
-/**\r
- Retrieves the properties for 16-bit thunk functions.\r
-\r
- Computes the size of the buffer and stack below 1MB required to use the\r
- AsmPrepareThunk16(), AsmThunk16() and AsmPrepareAndThunk16() functions. This\r
- buffer size is returned in RealModeBufferSize, and the stack size is returned\r
- in ExtraStackSize. If parameters are passed to the 16-bit real mode code,\r
- then the actual minimum stack size is ExtraStackSize plus the maximum number\r
- of bytes that need to be passed to the 16-bit real mode code.\r
-\r
- If RealModeBufferSize is NULL, then ASSERT().\r
- If ExtraStackSize is NULL, then ASSERT().\r
-\r
- @param RealModeBufferSize A pointer to the size of the buffer below 1MB\r
- required to use the 16-bit thunk functions.\r
- @param ExtraStackSize A pointer to the extra size of stack below 1MB\r
- that the 16-bit thunk functions require for\r
- temporary storage in the transition to and from\r
- 16-bit real mode.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-AsmGetThunk16Properties (\r
- OUT UINT32 *RealModeBufferSize,\r
- OUT UINT32 *ExtraStackSize\r
- )\r
-{\r
- ASSERT (RealModeBufferSize != NULL);\r
- ASSERT (ExtraStackSize != NULL);\r
-\r
- *RealModeBufferSize = m16Size;\r
-\r
- //\r
- // Extra 4 bytes for return address, and another 4 bytes for mode transition\r
- //\r
- *ExtraStackSize = sizeof (IA32_DWORD_REGS) + 8;\r
-}\r
-\r
-/**\r
- Prepares all structures a code required to use AsmThunk16().\r
-\r
- Prepares all structures and code required to use AsmThunk16().\r
-\r
- If ThunkContext is NULL, then ASSERT().\r
-\r
- @param ThunkContext A pointer to the context structure that describes the\r
- 16-bit real mode code to call.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-AsmPrepareThunk16 (\r
- OUT THUNK_CONTEXT *ThunkContext\r
- )\r
-{\r
- IA32_SEGMENT_DESCRIPTOR *RealModeGdt;\r
-\r
- ASSERT (ThunkContext != NULL);\r
- ASSERT ((UINTN)ThunkContext->RealModeBuffer < 0x100000);\r
- ASSERT (ThunkContext->RealModeBufferSize >= m16Size);\r
- ASSERT ((UINTN)ThunkContext->RealModeBuffer + m16Size <= 0x100000);\r
-\r
- CopyMem (ThunkContext->RealModeBuffer, &m16Start, m16Size);\r
-\r
- //\r
- // Point RealModeGdt to the GDT to be used in transition\r
- //\r
- // RealModeGdt[0]: Reserved as NULL descriptor\r
- // RealModeGdt[1]: Code Segment\r
- // RealModeGdt[2]: Data Segment\r
- // RealModeGdt[3]: Call Gate\r
- //\r
- RealModeGdt = (IA32_SEGMENT_DESCRIPTOR*)(\r
- (UINTN)ThunkContext->RealModeBuffer + m16Gdt);\r
-\r
- //\r
- // Update Code & Data Segment Descriptor\r
- //\r
- RealModeGdt[1].Bits.BaseLow =\r
- (UINT32)(UINTN)ThunkContext->RealModeBuffer & ~0xf;\r
- RealModeGdt[1].Bits.BaseMid =\r
- (UINT32)(UINTN)ThunkContext->RealModeBuffer >> 16;\r
-\r
- //\r
- // Update transition code entry point offset\r
- //\r
- *(UINT32*)((UINTN)ThunkContext->RealModeBuffer + mTransition) +=\r
- (UINT32)(UINTN)ThunkContext->RealModeBuffer & 0xf;\r
-\r
- //\r
- // Update Segment Limits for both Code and Data Segment Descriptors\r
- //\r
- if ((ThunkContext->ThunkAttributes & THUNK_ATTRIBUTE_BIG_REAL_MODE) == 0) {\r
- //\r
- // Set segment limits to 64KB\r
- //\r
- RealModeGdt[1].Bits.LimitHigh = 0;\r
- RealModeGdt[1].Bits.G = 0;\r
- RealModeGdt[2].Bits.LimitHigh = 0;\r
- RealModeGdt[2].Bits.G = 0;\r
- }\r
-\r
- //\r
- // Update GDTBASE for this thunk context\r
- //\r
- *(VOID**)((UINTN)ThunkContext->RealModeBuffer + m16GdtrBase) = RealModeGdt;\r
-\r
- //\r
- // Update Thunk Attributes\r
- //\r
- *(UINT32*)((UINTN)ThunkContext->RealModeBuffer + mThunk16Attr) =\r
- ThunkContext->ThunkAttributes;\r
-}\r
-\r
-/**\r
- Transfers control to a 16-bit real mode entry point and returns the results.\r
-\r
- Transfers control to a 16-bit real mode entry point and returns the results.\r
- AsmPrepareThunk16() must be called with ThunkContext before this function is\r
- used. This function must be called with interrupts disabled.\r
-\r
- If ThunkContext is NULL, then ASSERT().\r
- If AsmPrepareThunk16() was not previously called with ThunkContext, then ASSERT().\r
-\r
- @param ThunkContext A pointer to the context structure that describes the\r
- 16-bit real mode code to call.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-AsmThunk16 (\r
- IN OUT THUNK_CONTEXT *ThunkContext\r
- )\r
-{\r
- IA32_REGISTER_SET *UpdatedRegs;\r
-\r
- ASSERT (ThunkContext != NULL);\r
- ASSERT ((UINTN)ThunkContext->RealModeBuffer < 0x100000);\r
- ASSERT (ThunkContext->RealModeBufferSize >= m16Size);\r
- ASSERT ((UINTN)ThunkContext->RealModeBuffer + m16Size <= 0x100000);\r
-\r
- UpdatedRegs = InternalAsmThunk16 (\r
- ThunkContext->RealModeState,\r
- ThunkContext->RealModeBuffer\r
- );\r
-\r
- CopyMem (ThunkContext->RealModeState, UpdatedRegs, sizeof (*UpdatedRegs));\r
-}\r
-\r
-/**\r
- Prepares all structures and code for a 16-bit real mode thunk, transfers\r
- control to a 16-bit real mode entry point, and returns the results.\r
-\r
- Prepares all structures and code for a 16-bit real mode thunk, transfers\r
- control to a 16-bit real mode entry point, and returns the results. If the\r
- caller only need to perform a single 16-bit real mode thunk, then this\r
- service should be used. If the caller intends to make more than one 16-bit\r
- real mode thunk, then it is more efficient if AsmPrepareThunk16() is called\r
- once and AsmThunk16() can be called for each 16-bit real mode thunk. This\r
- function must be called with interrupts disabled.\r
-\r
- If ThunkContext is NULL, then ASSERT().\r
-\r
- @param ThunkContext A pointer to the context structure that describes the\r
- 16-bit real mode code to call.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-AsmPrepareAndThunk16 (\r
- IN OUT THUNK_CONTEXT *ThunkContext\r
- )\r
-{\r
- AsmPrepareThunk16 (ThunkContext);\r
- AsmThunk16 (ThunkContext);\r
-}\r