]>
git.proxmox.com Git - mirror_edk2.git/blob - EdkCompatibilityPkg/Foundation/Library/Thunk16/X86Thunk.c
3 Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
4 This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 Real Mode Thunk Functions
23 #include "Thunk16Lib.h"
24 #include "EfiCommonLib.h"
26 extern CONST UINTN mCode16Size
;
32 IN OUT IA32_REGISTER_SET
*RegisterSet
,
47 IN CONST IA32_FX_BUFFER
*Buffer
53 OUT IA32_FX_BUFFER
*Buffer
74 IN THUNK_CONTEXT
*ThunkContext
,
75 IN OUT IA32_REGISTER_SET
*RegisterSet
,
82 Do the 16-bit thunk code.
84 NOTE: This function must be called on TPL_HIGH_LEVEL or with interrupts
85 disabled because of GDTR and IDTR manipulations.
86 This function must be placed in identity mapped pages.
90 ThunkContext - Thunk context to use.
91 RegisterSet - CPU registers would be set to the values contained in this
92 structure before making the far call. Then CPU registers are
93 copied back to this structure.
94 SS:ESP points to the real mode stack if THUNK_USER_STACK is
95 set on input, otherwise ignored.
96 EFlages is ignored on input.
97 On output, values of CS, EIP, SS and ESP should be ignored.
98 ThunkFlags - 2 flags have currently been defined, THUNK_SAVE_FP_STATE and
100 THUNK_SAVE_FP_STATE - FPU state would be saved/restored
101 before/after calling real mode code.
102 THUNK_USER_STACK - The stack specified by SS:ESP would be
103 used instead of the default stack.
107 RegisterSet is returned.
111 IA32_FX_BUFFER
*FpSavedState
;
112 UINT8 FpBuffer
[sizeof (*FpSavedState
) + 0x10];
115 FpSavedState
= (IA32_FX_BUFFER
*)(((UINTN
)FpBuffer
+ 0xf) & ~0xf);
117 if (!(ThunkFlags
& THUNK_USER_STACK
)) {
118 RegisterSet
->E
.ESP
= (UINT16
)ThunkContext
->DefaultStack
;
119 RegisterSet
->E
.SS
= (UINT16
)((ThunkContext
->DefaultStack
>> 4) & 0xf000);
122 if (ThunkFlags
& THUNK_SAVE_FP_STATE
) {
123 AsmFxSave (FpSavedState
);
126 Eflags
= AsmGetEflags ();
128 EfiCommonLibCopyMem (
132 (UINT16
)(ThunkFlags
>> 16),
133 ThunkContext
->RealModeBuffer
>> 4
135 sizeof (*RegisterSet
)
138 AsmSetEflags (Eflags
);
140 if (ThunkFlags
& THUNK_SAVE_FP_STATE
) {
141 AsmFxRestore (FpSavedState
);
149 AsmThunk16GetProperties (
150 OUT UINTN
*MinimumStackSize
156 Returns the properties of this real mode thunk implementation. Currently
157 there are 2 properties has been defined, the minimum real mode buffer size
158 and the minimum stack size.
162 MinimumStackSize - The minimum size required for a 16-bit stack.
166 The minimum size of the real mode buffer needed by this thunk implementation
172 // This size should be large enough to hold the register set as well as saved
173 // CPU contexts including GDTR, CR0 and CR4
175 if (MinimumStackSize
) {
176 *MinimumStackSize
= sizeof (IA32_REGISTER_SET
) + 0x200;
184 AsmThunk16SetProperties (
185 OUT THUNK_CONTEXT
*ThunkContext
,
186 IN VOID
*RealModeBuffer
,
193 Tell this real mode thunk implementation the address and size of the real
198 ThunkContext - The thunk context whose properties to set.
199 RealModeBuffer - The address of the buffer allocated by caller. It should be
200 aligned on a 16-byte boundary.
201 This buffer must be in identity mapped pages.
202 BufferSize - The size of RealModeBuffer. Must be larger than the minimum
203 size required as returned by AsmThunk16GetProperties().
213 ThunkContext
->RealModeBuffer
= (UINT32
)(UINTN
)RealModeBuffer
;
214 ThunkContext
->DefaultStack
= (UINT32
)(ThunkContext
->RealModeBuffer
+ BufferSize
);
215 EfiCommonLibCopyMem (RealModeBuffer
, (VOID
*)(UINTN
)_Code16Addr
, mCode16Size
);
263 #define STACK_PARAM_SIZE 16
266 AsmThunk16SetUserStack (
267 IN THUNK_CONTEXT
*ThunkContext
,
272 if (StackSize
> STACK_PARAM_SIZE
) {
276 EfiCommonLibCopyMem ((VOID
*)(UINTN
)(ThunkContext
->DefaultStack
- sizeof(_STK16
) - sizeof(IA32_REGS
) - STACK_PARAM_SIZE
), Stack
, StackSize
);
284 IN OUT THUNK_CONTEXT
*ThunkContext
290 Reset all internal states to their initial values. The caller should not
291 release the real mode buffer until after a call to this function.
295 ThunkContext - The thunk context to destroy.
303 ThunkContext
->RealModeBuffer
= 0;
308 AsmThunk16FarCall86 (
309 IN THUNK_CONTEXT
*ThunkContext
,
310 IN OUT IA32_REGISTER_SET
*RegisterSet
,
317 Make a far call to 16-bit code.
319 NOTE: This function must be called on TPL_HIGH_LEVEL or with interrupts
320 disabled because of GDTR and IDTR manipulations.
321 This function must be placed in identity mapped pages.
325 ThunkContext - Thunk context to use.
326 RegisterSet - CPU registers would be set to the values contained in this
327 structure before making the far call. Then CPU registers are
328 copied back to this structure.
329 CS:EIP points to the real mode code being called on input.
330 SS:ESP points to the real mode stack if THUNK_USER_STACK is
331 set on input, otherwise ignored.
332 EFlages is ignored on input.
333 On output, values of CS, EIP, SS and ESP should be ignored.
334 ThunkFlags - THUNK_USER_STACK: The stack specified by SS:ESP would be
335 used instead of the default stack.
339 RegisterSet is returned.
343 return AsmThunk16 (ThunkContext
, RegisterSet
, Flags
);
349 IN THUNK_CONTEXT
*ThunkContext
,
351 IN OUT IA32_REGISTER_SET
*RegisterSet
,
358 Invoke a 16-bit interrupt handler.
360 NOTE: This function must be called on TPL_HIGH_LEVEL or with interrupts
361 disabled because of GDTR and IDTR manipulations.
362 This function must be placed in identity mapped pages.
366 ThunkContext - Thunk context to use.
367 IntNumber - The ordinal of the interrupt handler ranging from 0 to 255.
368 RegisterSet - CPU registers would be set to the values contained in this
369 structure before making the far call. Then CPU registers are
370 copied back to this structure.
371 SS:ESP points to the real mode stack if THUNK_USER_STACK is
372 set on input, otherwise ignored.
373 EFlages is ignored on input.
374 On output, values of CS, EIP, SS and ESP should be ignored.
375 ThunkFlags - THUNK_USER_STACK: The stack specified by SS:ESP would be
376 used instead of the default stack.
380 RegisterSet is returned.
384 RegisterSet
->E
.EIP
= (UINT16
)((UINT32
*)NULL
)[IntNumber
];
385 RegisterSet
->E
.CS
= (UINT16
)(((UINT32
*)NULL
)[IntNumber
] >> 16);
387 return AsmThunk16 (ThunkContext
, RegisterSet
, Flags
| THUNK_INTERRUPT
);