From d9697eefe69365e225bdbd72562fe2b4e1736e3a Mon Sep 17 00:00:00 2001 From: vanjeff Date: Sat, 27 Sep 2008 06:41:28 +0000 Subject: Renamed remotely git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@6045 6f19259b-4bc3-4df7-8a09-765794883524 --- .../Foundation/Library/Thunk16/X86Thunk.c | 320 +++++++++++++++++++++ 1 file changed, 320 insertions(+) create mode 100644 EdkCompatibilityPkg/Foundation/Library/Thunk16/X86Thunk.c (limited to 'EdkCompatibilityPkg/Foundation/Library/Thunk16/X86Thunk.c') diff --git a/EdkCompatibilityPkg/Foundation/Library/Thunk16/X86Thunk.c b/EdkCompatibilityPkg/Foundation/Library/Thunk16/X86Thunk.c new file mode 100644 index 0000000000..9bd77e24ca --- /dev/null +++ b/EdkCompatibilityPkg/Foundation/Library/Thunk16/X86Thunk.c @@ -0,0 +1,320 @@ +/*++ + +Copyright (c) 2006, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + +Module Name: + + x86Thunk.c + +Abstract: + + Real Mode Thunk Functions + +--*/ + +#include "Thunk16Lib.h" +#include "EfiCommonLib.h" + +#define IA32API __cdecl + +extern CONST UINTN mCode16Size; + +extern +IA32_REGISTER_SET * +IA32API +_Thunk16 ( + IN OUT IA32_REGISTER_SET *RegisterSet, + IN UINT32 ThunkFlags, + IN UINT32 RealModeCs + ); + +extern +VOID +IA32API +_Code16Addr ( + VOID + ); + +VOID +IA32API +AsmFxRestore ( + IN CONST IA32_FX_BUFFER *Buffer + ); + +VOID +IA32API +AsmFxSave ( + OUT IA32_FX_BUFFER *Buffer + ); + +// +// Implementation +// +STATIC +IA32_REGISTER_SET * +AsmThunk16 ( + IN THUNK_CONTEXT *ThunkContext, + IN OUT IA32_REGISTER_SET *RegisterSet, + IN UINT32 ThunkFlags + ) +/*++ + +Routine Description: + + Do the 16-bit thunk code. + + NOTE: This function must be called on TPL_HIGH_LEVEL or with interrupts + disabled because of GDTR and IDTR manipulations. + This function must be placed in identity mapped pages. + +Arguments: + + ThunkContext - Thunk context to use. + RegisterSet - CPU registers would be set to the values contained in this + structure before making the far call. Then CPU registers are + copied back to this structure. + SS:ESP points to the real mode stack if THUNK_USER_STACK is + set on input, otherwise ignored. + EFlages is ignored on input. + On output, values of CS, EIP, SS and ESP should be ignored. + ThunkFlags - 2 flags have currently been defined, THUNK_SAVE_FP_STATE and + THUNK_USER_STACK. + THUNK_SAVE_FP_STATE - FPU state would be saved/restored + before/after calling real mode code. + THUNK_USER_STACK - The stack specified by SS:ESP would be + used instead of the default stack. + +Returns: + + RegisterSet is returned. + +--*/ +{ + IA32_FX_BUFFER *FpSavedState; + UINT8 FpBuffer[sizeof (*FpSavedState) + 0x10]; + + FpSavedState = (IA32_FX_BUFFER*)(((UINTN)FpBuffer + 0xf) & ~0xf); + + if (!(ThunkFlags & THUNK_USER_STACK)) { + RegisterSet->E.ESP = (UINT16)ThunkContext->DefaultStack; + RegisterSet->E.SS = (UINT16)((ThunkContext->DefaultStack >> 4) & 0xf000); + } + + if (ThunkFlags & THUNK_SAVE_FP_STATE) { + AsmFxSave (FpSavedState); + } + + EfiCommonLibCopyMem ( + RegisterSet, + _Thunk16 ( + RegisterSet, + (UINT16)(ThunkFlags >> 16), + ThunkContext->RealModeBuffer >> 4 + ), + sizeof (*RegisterSet) + ); + + if (ThunkFlags & THUNK_SAVE_FP_STATE) { + AsmFxRestore (FpSavedState); + } + + return RegisterSet; +} + +UINTN +EFIAPI +AsmThunk16GetProperties ( + OUT UINTN *MinimumStackSize + ) +/*++ + +Routine Description: + + Returns the properties of this real mode thunk implementation. Currently + there are 2 properties has been defined, the minimum real mode buffer size + and the minimum stack size. + +Arguments: + + MinimumStackSize - The minimum size required for a 16-bit stack. + +Returns: + + The minimum size of the real mode buffer needed by this thunk implementation + is returned. + +--*/ +{ + // + // This size should be large enough to hold the register set as well as saved + // CPU contexts including GDTR, CR0 and CR4 + // + if (MinimumStackSize) { + *MinimumStackSize = sizeof (IA32_REGISTER_SET) + 0x200; + } + + return mCode16Size; +} + +THUNK_CONTEXT * +EFIAPI +AsmThunk16SetProperties ( + OUT THUNK_CONTEXT *ThunkContext, + IN VOID *RealModeBuffer, + IN UINTN BufferSize + ) +/*++ + +Routine Description: + + Tell this real mode thunk implementation the address and size of the real + mode buffer needed. + +Arguments: + + ThunkContext - The thunk context whose properties to set. + RealModeBuffer - The address of the buffer allocated by caller. It should be + aligned on a 16-byte boundary. + This buffer must be in identity mapped pages. + BufferSize - The size of RealModeBuffer. Must be larger than the minimum + size required as returned by AsmThunk16GetProperties(). + +Returns: + + None + +--*/ +{ + BufferSize &= ~3; + + ThunkContext->RealModeBuffer = (UINT32)(UINTN)RealModeBuffer; + ThunkContext->DefaultStack = (UINT32)(ThunkContext->RealModeBuffer + BufferSize); + EfiCommonLibCopyMem (RealModeBuffer, (VOID*)(UINTN)_Code16Addr, mCode16Size); + + return ThunkContext; +} + +VOID +EFIAPI +AsmThunk16Destroy ( + IN OUT THUNK_CONTEXT *ThunkContext + ) +/*++ + +Routine Description: + + Reset all internal states to their initial values. The caller should not + release the real mode buffer until after a call to this function. + +Arguments: + + ThunkContext - The thunk context to destroy. + +Returns: + + None + +--*/ +{ + ThunkContext->RealModeBuffer = 0; +} + +IA32_REGISTER_SET * +EFIAPI +AsmThunk16FarCall86 ( + IN THUNK_CONTEXT *ThunkContext, + IN OUT IA32_REGISTER_SET *RegisterSet, + IN UINT32 Flags + ) +/*++ + +Routine Description: + + Make a far call to 16-bit code. + + NOTE: This function must be called on TPL_HIGH_LEVEL or with interrupts + disabled because of GDTR and IDTR manipulations. + This function must be placed in identity mapped pages. + +Arguments: + + ThunkContext - Thunk context to use. + RegisterSet - CPU registers would be set to the values contained in this + structure before making the far call. Then CPU registers are + copied back to this structure. + CS:EIP points to the real mode code being called on input. + SS:ESP points to the real mode stack if THUNK_USER_STACK is + set on input, otherwise ignored. + EFlages is ignored on input. + On output, values of CS, EIP, SS and ESP should be ignored. + ThunkFlags - 2 flags have currently been defined, THUNK_SAVE_FP_STATE and + THUNK_USER_STACK. + THUNK_SAVE_FP_STATE - FPU state would be saved/restored + before/after calling real mode code. + THUNK_USER_STACK - The stack specified by SS:ESP would be + used instead of the default stack. + +Returns: + + RegisterSet is returned. + +--*/ +{ + return AsmThunk16 (ThunkContext, RegisterSet, Flags); +} + +IA32_REGISTER_SET * +EFIAPI +AsmThunk16Int86 ( + IN THUNK_CONTEXT *ThunkContext, + IN UINT8 IntNumber, + IN OUT IA32_REGISTER_SET *RegisterSet, + IN UINT32 Flags + ) +/*++ + +Routine Description: + + Invoke a 16-bit interrupt handler. + + NOTE: This function must be called on TPL_HIGH_LEVEL or with interrupts + disabled because of GDTR and IDTR manipulations. + This function must be placed in identity mapped pages. + +Arguments: + + ThunkContext - Thunk context to use. + IntNumber - The ordinal of the interrupt handler ranging from 0 to 255. + RegisterSet - CPU registers would be set to the values contained in this + structure before making the far call. Then CPU registers are + copied back to this structure. + SS:ESP points to the real mode stack if THUNK_USER_STACK is + set on input, otherwise ignored. + EFlages is ignored on input. + On output, values of CS, EIP, SS and ESP should be ignored. + ThunkFlags - 2 flags have currently been defined, THUNK_SAVE_FP_STATE and + THUNK_USER_STACK. + THUNK_SAVE_FP_STATE - FPU state would be saved/restored + before/after calling real mode code. + THUNK_USER_STACK - The stack specified by SS:ESP would be + used instead of the default stack. + +Returns: + + RegisterSet is returned. + +--*/ +{ + RegisterSet->E.EIP = (UINT16)((UINT32 *)NULL)[IntNumber]; + RegisterSet->E.CS = (UINT16)(((UINT32 *)NULL)[IntNumber] >> 16); + + return AsmThunk16 (ThunkContext, RegisterSet, Flags | THUNK_INTERRUPT); +} -- cgit v1.2.3