]>
git.proxmox.com Git - mirror_edk2.git/blob - EdkCompatibilityPkg/Foundation/Library/Thunk16/X86Thunk.c
3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. 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 #define IA32API EFIAPI
28 extern CONST UINTN mCode16Size
;
34 IN OUT IA32_REGISTER_SET
*RegisterSet
,
49 IN CONST IA32_FX_BUFFER
*Buffer
55 OUT IA32_FX_BUFFER
*Buffer
64 IN THUNK_CONTEXT
*ThunkContext
,
65 IN OUT IA32_REGISTER_SET
*RegisterSet
,
72 Do the 16-bit thunk code.
74 NOTE: This function must be called on TPL_HIGH_LEVEL or with interrupts
75 disabled because of GDTR and IDTR manipulations.
76 This function must be placed in identity mapped pages.
80 ThunkContext - Thunk context to use.
81 RegisterSet - CPU registers would be set to the values contained in this
82 structure before making the far call. Then CPU registers are
83 copied back to this structure.
84 SS:ESP points to the real mode stack if THUNK_USER_STACK is
85 set on input, otherwise ignored.
86 EFlages is ignored on input.
87 On output, values of CS, EIP, SS and ESP should be ignored.
88 ThunkFlags - 2 flags have currently been defined, THUNK_SAVE_FP_STATE and
90 THUNK_SAVE_FP_STATE - FPU state would be saved/restored
91 before/after calling real mode code.
92 THUNK_USER_STACK - The stack specified by SS:ESP would be
93 used instead of the default stack.
97 RegisterSet is returned.
101 IA32_FX_BUFFER
*FpSavedState
;
102 UINT8 FpBuffer
[sizeof (*FpSavedState
) + 0x10];
104 FpSavedState
= (IA32_FX_BUFFER
*)(((UINTN
)FpBuffer
+ 0xf) & ~0xf);
106 if (!(ThunkFlags
& THUNK_USER_STACK
)) {
107 RegisterSet
->E
.ESP
= (UINT16
)ThunkContext
->DefaultStack
;
108 RegisterSet
->E
.SS
= (UINT16
)((ThunkContext
->DefaultStack
>> 4) & 0xf000);
111 if (ThunkFlags
& THUNK_SAVE_FP_STATE
) {
112 AsmFxSave (FpSavedState
);
115 EfiCommonLibCopyMem (
119 (UINT16
)(ThunkFlags
>> 16),
120 ThunkContext
->RealModeBuffer
>> 4
122 sizeof (*RegisterSet
)
125 if (ThunkFlags
& THUNK_SAVE_FP_STATE
) {
126 AsmFxRestore (FpSavedState
);
134 AsmThunk16GetProperties (
135 OUT UINTN
*MinimumStackSize
141 Returns the properties of this real mode thunk implementation. Currently
142 there are 2 properties has been defined, the minimum real mode buffer size
143 and the minimum stack size.
147 MinimumStackSize - The minimum size required for a 16-bit stack.
151 The minimum size of the real mode buffer needed by this thunk implementation
157 // This size should be large enough to hold the register set as well as saved
158 // CPU contexts including GDTR, CR0 and CR4
160 if (MinimumStackSize
) {
161 *MinimumStackSize
= sizeof (IA32_REGISTER_SET
) + 0x200;
169 AsmThunk16SetProperties (
170 OUT THUNK_CONTEXT
*ThunkContext
,
171 IN VOID
*RealModeBuffer
,
178 Tell this real mode thunk implementation the address and size of the real
183 ThunkContext - The thunk context whose properties to set.
184 RealModeBuffer - The address of the buffer allocated by caller. It should be
185 aligned on a 16-byte boundary.
186 This buffer must be in identity mapped pages.
187 BufferSize - The size of RealModeBuffer. Must be larger than the minimum
188 size required as returned by AsmThunk16GetProperties().
198 ThunkContext
->RealModeBuffer
= (UINT32
)(UINTN
)RealModeBuffer
;
199 ThunkContext
->DefaultStack
= (UINT32
)(ThunkContext
->RealModeBuffer
+ BufferSize
);
200 EfiCommonLibCopyMem (RealModeBuffer
, (VOID
*)(UINTN
)_Code16Addr
, mCode16Size
);
208 IN OUT THUNK_CONTEXT
*ThunkContext
214 Reset all internal states to their initial values. The caller should not
215 release the real mode buffer until after a call to this function.
219 ThunkContext - The thunk context to destroy.
227 ThunkContext
->RealModeBuffer
= 0;
232 AsmThunk16FarCall86 (
233 IN THUNK_CONTEXT
*ThunkContext
,
234 IN OUT IA32_REGISTER_SET
*RegisterSet
,
241 Make a far call to 16-bit code.
243 NOTE: This function must be called on TPL_HIGH_LEVEL or with interrupts
244 disabled because of GDTR and IDTR manipulations.
245 This function must be placed in identity mapped pages.
249 ThunkContext - Thunk context to use.
250 RegisterSet - CPU registers would be set to the values contained in this
251 structure before making the far call. Then CPU registers are
252 copied back to this structure.
253 CS:EIP points to the real mode code being called on input.
254 SS:ESP points to the real mode stack if THUNK_USER_STACK is
255 set on input, otherwise ignored.
256 EFlages is ignored on input.
257 On output, values of CS, EIP, SS and ESP should be ignored.
258 ThunkFlags - 2 flags have currently been defined, THUNK_SAVE_FP_STATE and
260 THUNK_SAVE_FP_STATE - FPU state would be saved/restored
261 before/after calling real mode code.
262 THUNK_USER_STACK - The stack specified by SS:ESP would be
263 used instead of the default stack.
267 RegisterSet is returned.
271 return AsmThunk16 (ThunkContext
, RegisterSet
, Flags
);
277 IN THUNK_CONTEXT
*ThunkContext
,
279 IN OUT IA32_REGISTER_SET
*RegisterSet
,
286 Invoke a 16-bit interrupt handler.
288 NOTE: This function must be called on TPL_HIGH_LEVEL or with interrupts
289 disabled because of GDTR and IDTR manipulations.
290 This function must be placed in identity mapped pages.
294 ThunkContext - Thunk context to use.
295 IntNumber - The ordinal of the interrupt handler ranging from 0 to 255.
296 RegisterSet - CPU registers would be set to the values contained in this
297 structure before making the far call. Then CPU registers are
298 copied back to this structure.
299 SS:ESP points to the real mode stack if THUNK_USER_STACK is
300 set on input, otherwise ignored.
301 EFlages is ignored on input.
302 On output, values of CS, EIP, SS and ESP should be ignored.
303 ThunkFlags - 2 flags have currently been defined, THUNK_SAVE_FP_STATE and
305 THUNK_SAVE_FP_STATE - FPU state would be saved/restored
306 before/after calling real mode code.
307 THUNK_USER_STACK - The stack specified by SS:ESP would be
308 used instead of the default stack.
312 RegisterSet is returned.
316 RegisterSet
->E
.EIP
= (UINT16
)((UINT32
*)NULL
)[IntNumber
];
317 RegisterSet
->E
.CS
= (UINT16
)(((UINT32
*)NULL
)[IntNumber
] >> 16);
319 return AsmThunk16 (ThunkContext
, RegisterSet
, Flags
| THUNK_INTERRUPT
);