--- /dev/null
+/*++\r
+\r
+Copyright (c) 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\r
+\r
+--*/\r
+\r
+#include "Thunk16Lib.h"\r
+#include "EfiCommonLib.h"\r
+\r
+#define IA32API __cdecl\r
+\r
+extern CONST UINTN mCode16Size;\r
+\r
+extern\r
+IA32_REGISTER_SET *\r
+IA32API\r
+_Thunk16 (\r
+ IN OUT IA32_REGISTER_SET *RegisterSet,\r
+ IN UINT32 ThunkFlags,\r
+ IN UINT32 RealModeCs\r
+ );\r
+\r
+extern\r
+VOID\r
+IA32API\r
+_Code16Addr (\r
+ VOID\r
+ );\r
+\r
+VOID\r
+IA32API\r
+AsmFxRestore (\r
+ IN CONST IA32_FX_BUFFER *Buffer\r
+ );\r
+\r
+VOID\r
+IA32API\r
+AsmFxSave (\r
+ OUT IA32_FX_BUFFER *Buffer\r
+ );\r
+\r
+//\r
+// Implementation\r
+//\r
+STATIC\r
+IA32_REGISTER_SET *\r
+AsmThunk16 (\r
+ IN THUNK_CONTEXT *ThunkContext,\r
+ IN OUT IA32_REGISTER_SET *RegisterSet,\r
+ IN UINT32 ThunkFlags\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Do the 16-bit thunk code.\r
+\r
+ NOTE: This function must be called on TPL_HIGH_LEVEL or with interrupts\r
+ disabled because of GDTR and IDTR manipulations.\r
+ This function must be placed in identity mapped pages.\r
+\r
+Arguments:\r
+\r
+ ThunkContext - Thunk context to use.\r
+ RegisterSet - CPU registers would be set to the values contained in this\r
+ structure before making the far call. Then CPU registers are\r
+ copied back to this structure.\r
+ SS:ESP points to the real mode stack if THUNK_USER_STACK is\r
+ set on input, otherwise ignored.\r
+ EFlages is ignored on input.\r
+ On output, values of CS, EIP, SS and ESP should be ignored.\r
+ ThunkFlags - 2 flags have currently been defined, THUNK_SAVE_FP_STATE and\r
+ THUNK_USER_STACK.\r
+ THUNK_SAVE_FP_STATE - FPU state would be saved/restored\r
+ before/after calling real mode code.\r
+ THUNK_USER_STACK - The stack specified by SS:ESP would be\r
+ used instead of the default stack.\r
+\r
+Returns:\r
+\r
+ RegisterSet is returned.\r
+\r
+--*/\r
+{\r
+ IA32_FX_BUFFER *FpSavedState;\r
+ UINT8 FpBuffer[sizeof (*FpSavedState) + 0x10];\r
+\r
+ FpSavedState = (IA32_FX_BUFFER*)(((UINTN)FpBuffer + 0xf) & ~0xf);\r
+\r
+ if (!(ThunkFlags & THUNK_USER_STACK)) {\r
+ RegisterSet->E.ESP = (UINT16)ThunkContext->DefaultStack;\r
+ RegisterSet->E.SS = (UINT16)((ThunkContext->DefaultStack >> 4) & 0xf000);\r
+ }\r
+\r
+ if (ThunkFlags & THUNK_SAVE_FP_STATE) {\r
+ AsmFxSave (FpSavedState);\r
+ }\r
+\r
+ EfiCommonLibCopyMem (\r
+ RegisterSet,\r
+ _Thunk16 (\r
+ RegisterSet,\r
+ (UINT16)(ThunkFlags >> 16),\r
+ ThunkContext->RealModeBuffer >> 4\r
+ ),\r
+ sizeof (*RegisterSet)\r
+ );\r
+\r
+ if (ThunkFlags & THUNK_SAVE_FP_STATE) {\r
+ AsmFxRestore (FpSavedState);\r
+ }\r
+\r
+ return RegisterSet;\r
+}\r
+\r
+UINTN\r
+EFIAPI\r
+AsmThunk16GetProperties (\r
+ OUT UINTN *MinimumStackSize\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Returns the properties of this real mode thunk implementation. Currently\r
+ there are 2 properties has been defined, the minimum real mode buffer size\r
+ and the minimum stack size.\r
+\r
+Arguments:\r
+\r
+ MinimumStackSize - The minimum size required for a 16-bit stack.\r
+\r
+Returns:\r
+\r
+ The minimum size of the real mode buffer needed by this thunk implementation\r
+ is returned.\r
+\r
+--*/\r
+{\r
+ //\r
+ // This size should be large enough to hold the register set as well as saved\r
+ // CPU contexts including GDTR, CR0 and CR4\r
+ //\r
+ if (MinimumStackSize) {\r
+ *MinimumStackSize = sizeof (IA32_REGISTER_SET) + 0x200;\r
+ }\r
+\r
+ return mCode16Size;\r
+}\r
+\r
+THUNK_CONTEXT *\r
+EFIAPI\r
+AsmThunk16SetProperties (\r
+ OUT THUNK_CONTEXT *ThunkContext,\r
+ IN VOID *RealModeBuffer,\r
+ IN UINTN BufferSize\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Tell this real mode thunk implementation the address and size of the real\r
+ mode buffer needed.\r
+\r
+Arguments:\r
+\r
+ ThunkContext - The thunk context whose properties to set.\r
+ RealModeBuffer - The address of the buffer allocated by caller. It should be\r
+ aligned on a 16-byte boundary.\r
+ This buffer must be in identity mapped pages.\r
+ BufferSize - The size of RealModeBuffer. Must be larger than the minimum\r
+ size required as returned by AsmThunk16GetProperties().\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ BufferSize &= ~3;\r
+\r
+ ThunkContext->RealModeBuffer = (UINT32)(UINTN)RealModeBuffer;\r
+ ThunkContext->DefaultStack = (UINT32)(ThunkContext->RealModeBuffer + BufferSize);\r
+ EfiCommonLibCopyMem (RealModeBuffer, (VOID*)(UINTN)_Code16Addr, mCode16Size);\r
+\r
+ return ThunkContext;\r
+}\r
+\r
+VOID\r
+EFIAPI\r
+AsmThunk16Destroy (\r
+ IN OUT THUNK_CONTEXT *ThunkContext\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Reset all internal states to their initial values. The caller should not\r
+ release the real mode buffer until after a call to this function.\r
+\r
+Arguments:\r
+\r
+ ThunkContext - The thunk context to destroy.\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ ThunkContext->RealModeBuffer = 0;\r
+}\r
+\r
+IA32_REGISTER_SET *\r
+EFIAPI\r
+AsmThunk16FarCall86 (\r
+ IN THUNK_CONTEXT *ThunkContext,\r
+ IN OUT IA32_REGISTER_SET *RegisterSet,\r
+ IN UINT32 Flags\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Make a far call to 16-bit code.\r
+\r
+ NOTE: This function must be called on TPL_HIGH_LEVEL or with interrupts\r
+ disabled because of GDTR and IDTR manipulations.\r
+ This function must be placed in identity mapped pages.\r
+\r
+Arguments:\r
+\r
+ ThunkContext - Thunk context to use.\r
+ RegisterSet - CPU registers would be set to the values contained in this\r
+ structure before making the far call. Then CPU registers are\r
+ copied back to this structure.\r
+ CS:EIP points to the real mode code being called on input.\r
+ SS:ESP points to the real mode stack if THUNK_USER_STACK is\r
+ set on input, otherwise ignored.\r
+ EFlages is ignored on input.\r
+ On output, values of CS, EIP, SS and ESP should be ignored.\r
+ ThunkFlags - 2 flags have currently been defined, THUNK_SAVE_FP_STATE and\r
+ THUNK_USER_STACK.\r
+ THUNK_SAVE_FP_STATE - FPU state would be saved/restored\r
+ before/after calling real mode code.\r
+ THUNK_USER_STACK - The stack specified by SS:ESP would be\r
+ used instead of the default stack.\r
+\r
+Returns:\r
+\r
+ RegisterSet is returned.\r
+\r
+--*/\r
+{\r
+ return AsmThunk16 (ThunkContext, RegisterSet, Flags);\r
+}\r
+\r
+IA32_REGISTER_SET *\r
+EFIAPI\r
+AsmThunk16Int86 (\r
+ IN THUNK_CONTEXT *ThunkContext,\r
+ IN UINT8 IntNumber,\r
+ IN OUT IA32_REGISTER_SET *RegisterSet,\r
+ IN UINT32 Flags\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Invoke a 16-bit interrupt handler.\r
+\r
+ NOTE: This function must be called on TPL_HIGH_LEVEL or with interrupts\r
+ disabled because of GDTR and IDTR manipulations.\r
+ This function must be placed in identity mapped pages.\r
+\r
+Arguments:\r
+\r
+ ThunkContext - Thunk context to use.\r
+ IntNumber - The ordinal of the interrupt handler ranging from 0 to 255.\r
+ RegisterSet - CPU registers would be set to the values contained in this\r
+ structure before making the far call. Then CPU registers are\r
+ copied back to this structure.\r
+ SS:ESP points to the real mode stack if THUNK_USER_STACK is\r
+ set on input, otherwise ignored.\r
+ EFlages is ignored on input.\r
+ On output, values of CS, EIP, SS and ESP should be ignored.\r
+ ThunkFlags - 2 flags have currently been defined, THUNK_SAVE_FP_STATE and\r
+ THUNK_USER_STACK.\r
+ THUNK_SAVE_FP_STATE - FPU state would be saved/restored\r
+ before/after calling real mode code.\r
+ THUNK_USER_STACK - The stack specified by SS:ESP would be\r
+ used instead of the default stack.\r
+\r
+Returns:\r
+\r
+ RegisterSet is returned.\r
+\r
+--*/\r
+{\r
+ RegisterSet->E.EIP = (UINT16)((UINT32 *)NULL)[IntNumber];\r
+ RegisterSet->E.CS = (UINT16)(((UINT32 *)NULL)[IntNumber] >> 16);\r
+\r
+ return AsmThunk16 (ThunkContext, RegisterSet, Flags | THUNK_INTERRUPT);\r
+}\r
+++ /dev/null
-/*++\r
-\r
-Copyright (c) 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\r
-\r
---*/\r
-\r
-#include "Thunk16Lib.h"\r
-#include "EfiCommonLib.h"\r
-\r
-#define IA32API __cdecl\r
-\r
-extern CONST UINTN mCode16Size;\r
-\r
-extern\r
-IA32_REGISTER_SET *\r
-IA32API\r
-_Thunk16 (\r
- IN OUT IA32_REGISTER_SET *RegisterSet,\r
- IN UINT32 ThunkFlags,\r
- IN UINT32 RealModeCs\r
- );\r
-\r
-extern\r
-VOID\r
-IA32API\r
-_Code16Addr (\r
- VOID\r
- );\r
-\r
-VOID\r
-IA32API\r
-AsmFxRestore (\r
- IN CONST IA32_FX_BUFFER *Buffer\r
- );\r
-\r
-VOID\r
-IA32API\r
-AsmFxSave (\r
- OUT IA32_FX_BUFFER *Buffer\r
- );\r
-\r
-//\r
-// Implementation\r
-//\r
-STATIC\r
-IA32_REGISTER_SET *\r
-AsmThunk16 (\r
- IN THUNK_CONTEXT *ThunkContext,\r
- IN OUT IA32_REGISTER_SET *RegisterSet,\r
- IN UINT32 ThunkFlags\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Do the 16-bit thunk code.\r
-\r
- NOTE: This function must be called on TPL_HIGH_LEVEL or with interrupts\r
- disabled because of GDTR and IDTR manipulations.\r
- This function must be placed in identity mapped pages.\r
-\r
-Arguments:\r
-\r
- ThunkContext - Thunk context to use.\r
- RegisterSet - CPU registers would be set to the values contained in this\r
- structure before making the far call. Then CPU registers are\r
- copied back to this structure.\r
- SS:ESP points to the real mode stack if THUNK_USER_STACK is\r
- set on input, otherwise ignored.\r
- EFlages is ignored on input.\r
- On output, values of CS, EIP, SS and ESP should be ignored.\r
- ThunkFlags - 2 flags have currently been defined, THUNK_SAVE_FP_STATE and\r
- THUNK_USER_STACK.\r
- THUNK_SAVE_FP_STATE - FPU state would be saved/restored\r
- before/after calling real mode code.\r
- THUNK_USER_STACK - The stack specified by SS:ESP would be\r
- used instead of the default stack.\r
-\r
-Returns:\r
-\r
- RegisterSet is returned.\r
-\r
---*/\r
-{\r
- IA32_FX_BUFFER *FpSavedState;\r
- UINT8 FpBuffer[sizeof (*FpSavedState) + 0x10];\r
-\r
- FpSavedState = (IA32_FX_BUFFER*)(((UINTN)FpBuffer + 0xf) & ~0xf);\r
-\r
- if (!(ThunkFlags & THUNK_USER_STACK)) {\r
- RegisterSet->E.ESP = (UINT16)ThunkContext->DefaultStack;\r
- RegisterSet->E.SS = (UINT16)((ThunkContext->DefaultStack >> 4) & 0xf000);\r
- }\r
-\r
- if (ThunkFlags & THUNK_SAVE_FP_STATE) {\r
- AsmFxSave (FpSavedState);\r
- }\r
-\r
- EfiCommonLibCopyMem (\r
- RegisterSet,\r
- _Thunk16 (\r
- RegisterSet,\r
- (UINT16)(ThunkFlags >> 16),\r
- ThunkContext->RealModeBuffer >> 4\r
- ),\r
- sizeof (*RegisterSet)\r
- );\r
-\r
- if (ThunkFlags & THUNK_SAVE_FP_STATE) {\r
- AsmFxRestore (FpSavedState);\r
- }\r
-\r
- return RegisterSet;\r
-}\r
-\r
-UINTN\r
-EFIAPI\r
-AsmThunk16GetProperties (\r
- OUT UINTN *MinimumStackSize\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Returns the properties of this real mode thunk implementation. Currently\r
- there are 2 properties has been defined, the minimum real mode buffer size\r
- and the minimum stack size.\r
-\r
-Arguments:\r
-\r
- MinimumStackSize - The minimum size required for a 16-bit stack.\r
-\r
-Returns:\r
-\r
- The minimum size of the real mode buffer needed by this thunk implementation\r
- is returned.\r
-\r
---*/\r
-{\r
- //\r
- // This size should be large enough to hold the register set as well as saved\r
- // CPU contexts including GDTR, CR0 and CR4\r
- //\r
- if (MinimumStackSize) {\r
- *MinimumStackSize = sizeof (IA32_REGISTER_SET) + 0x200;\r
- }\r
-\r
- return mCode16Size;\r
-}\r
-\r
-THUNK_CONTEXT *\r
-EFIAPI\r
-AsmThunk16SetProperties (\r
- OUT THUNK_CONTEXT *ThunkContext,\r
- IN VOID *RealModeBuffer,\r
- IN UINTN BufferSize\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Tell this real mode thunk implementation the address and size of the real\r
- mode buffer needed.\r
-\r
-Arguments:\r
-\r
- ThunkContext - The thunk context whose properties to set.\r
- RealModeBuffer - The address of the buffer allocated by caller. It should be\r
- aligned on a 16-byte boundary.\r
- This buffer must be in identity mapped pages.\r
- BufferSize - The size of RealModeBuffer. Must be larger than the minimum\r
- size required as returned by AsmThunk16GetProperties().\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-{\r
- BufferSize &= ~3;\r
-\r
- ThunkContext->RealModeBuffer = (UINT32)(UINTN)RealModeBuffer;\r
- ThunkContext->DefaultStack = (UINT32)(ThunkContext->RealModeBuffer + BufferSize);\r
- EfiCommonLibCopyMem (RealModeBuffer, (VOID*)(UINTN)_Code16Addr, mCode16Size);\r
-\r
- return ThunkContext;\r
-}\r
-\r
-VOID\r
-EFIAPI\r
-AsmThunk16Destroy (\r
- IN OUT THUNK_CONTEXT *ThunkContext\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Reset all internal states to their initial values. The caller should not\r
- release the real mode buffer until after a call to this function.\r
-\r
-Arguments:\r
-\r
- ThunkContext - The thunk context to destroy.\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-{\r
- ThunkContext->RealModeBuffer = 0;\r
-}\r
-\r
-IA32_REGISTER_SET *\r
-EFIAPI\r
-AsmThunk16FarCall86 (\r
- IN THUNK_CONTEXT *ThunkContext,\r
- IN OUT IA32_REGISTER_SET *RegisterSet,\r
- IN UINT32 Flags\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Make a far call to 16-bit code.\r
-\r
- NOTE: This function must be called on TPL_HIGH_LEVEL or with interrupts\r
- disabled because of GDTR and IDTR manipulations.\r
- This function must be placed in identity mapped pages.\r
-\r
-Arguments:\r
-\r
- ThunkContext - Thunk context to use.\r
- RegisterSet - CPU registers would be set to the values contained in this\r
- structure before making the far call. Then CPU registers are\r
- copied back to this structure.\r
- CS:EIP points to the real mode code being called on input.\r
- SS:ESP points to the real mode stack if THUNK_USER_STACK is\r
- set on input, otherwise ignored.\r
- EFlages is ignored on input.\r
- On output, values of CS, EIP, SS and ESP should be ignored.\r
- ThunkFlags - 2 flags have currently been defined, THUNK_SAVE_FP_STATE and\r
- THUNK_USER_STACK.\r
- THUNK_SAVE_FP_STATE - FPU state would be saved/restored\r
- before/after calling real mode code.\r
- THUNK_USER_STACK - The stack specified by SS:ESP would be\r
- used instead of the default stack.\r
-\r
-Returns:\r
-\r
- RegisterSet is returned.\r
-\r
---*/\r
-{\r
- return AsmThunk16 (ThunkContext, RegisterSet, Flags);\r
-}\r
-\r
-IA32_REGISTER_SET *\r
-EFIAPI\r
-AsmThunk16Int86 (\r
- IN THUNK_CONTEXT *ThunkContext,\r
- IN UINT8 IntNumber,\r
- IN OUT IA32_REGISTER_SET *RegisterSet,\r
- IN UINT32 Flags\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Invoke a 16-bit interrupt handler.\r
-\r
- NOTE: This function must be called on TPL_HIGH_LEVEL or with interrupts\r
- disabled because of GDTR and IDTR manipulations.\r
- This function must be placed in identity mapped pages.\r
-\r
-Arguments:\r
-\r
- ThunkContext - Thunk context to use.\r
- IntNumber - The ordinal of the interrupt handler ranging from 0 to 255.\r
- RegisterSet - CPU registers would be set to the values contained in this\r
- structure before making the far call. Then CPU registers are\r
- copied back to this structure.\r
- SS:ESP points to the real mode stack if THUNK_USER_STACK is\r
- set on input, otherwise ignored.\r
- EFlages is ignored on input.\r
- On output, values of CS, EIP, SS and ESP should be ignored.\r
- ThunkFlags - 2 flags have currently been defined, THUNK_SAVE_FP_STATE and\r
- THUNK_USER_STACK.\r
- THUNK_SAVE_FP_STATE - FPU state would be saved/restored\r
- before/after calling real mode code.\r
- THUNK_USER_STACK - The stack specified by SS:ESP would be\r
- used instead of the default stack.\r
-\r
-Returns:\r
-\r
- RegisterSet is returned.\r
-\r
---*/\r
-{\r
- RegisterSet->E.EIP = (UINT16)((UINT32 *)NULL)[IntNumber];\r
- RegisterSet->E.CS = (UINT16)(((UINT32 *)NULL)[IntNumber] >> 16);\r
-\r
- return AsmThunk16 (ThunkContext, RegisterSet, Flags | THUNK_INTERRUPT);\r
-}\r