VirtualBox

source: vbox/trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-RegCtxSaveEx.asm@ 66199

Last change on this file since 66199 was 66199, checked in by vboxsync, 8 years ago

bs3-cmn-RegCtxSaveEx.asm: Do xSP subtraction on the whole register in 32-bit and 64-bit mode, not just SP.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.3 KB
Line 
1; $Id: bs3-cmn-RegCtxSaveEx.asm 66199 2017-03-22 14:24:38Z vboxsync $
2;; @file
3; BS3Kit - Bs3RegCtxSaveEx.
4;
5
6;
7; Copyright (C) 2007-2016 Oracle Corporation
8;
9; This file is part of VirtualBox Open Source Edition (OSE), as
10; available from http://www.virtualbox.org. This file is free software;
11; you can redistribute it and/or modify it under the terms of the GNU
12; General Public License (GPL) as published by the Free Software
13; Foundation, in version 2 as it comes in the "COPYING" file of the
14; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16;
17; The contents of this file may alternatively be used under the terms
18; of the Common Development and Distribution License Version 1.0
19; (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20; VirtualBox OSE distribution, in which case the provisions of the
21; CDDL are applicable instead of those of the GPL.
22;
23; You may elect to license modified versions of this file under the
24; terms and conditions of either the GPL or the CDDL or both.
25;
26
27%include "bs3kit-template-header.mac"
28
29
30
31;*********************************************************************************************************************************
32;* External Symbols *
33;*********************************************************************************************************************************
34BS3_EXTERN_DATA16 g_bBs3CurrentMode
35
36TMPL_BEGIN_TEXT
37BS3_EXTERN_CMN Bs3Panic
38BS3_EXTERN_CMN Bs3RegCtxSave
39BS3_EXTERN_CMN Bs3SwitchTo16Bit
40%if TMPL_BITS != 64
41BS3_EXTERN_CMN Bs3SwitchTo16BitV86
42%endif
43%if TMPL_BITS != 32
44BS3_EXTERN_CMN Bs3SwitchTo32Bit
45%endif
46%if TMPL_BITS != 64
47BS3_EXTERN_CMN Bs3SwitchTo64Bit
48%endif
49%if TMPL_BITS == 16
50BS3_EXTERN_CMN Bs3SelRealModeDataToProtFar16
51BS3_EXTERN_CMN Bs3SelProtFar16DataToRealMode
52BS3_EXTERN_CMN Bs3SelRealModeDataToFlat
53BS3_EXTERN_CMN Bs3SelProtFar16DataToFlat
54%else
55BS3_EXTERN_CMN Bs3SelFlatDataToProtFar16
56%endif
57%if TMPL_BITS == 32
58BS3_EXTERN_CMN Bs3SelFlatDataToRealMode
59%endif
60
61BS3_BEGIN_TEXT16
62%if TMPL_BITS != 16
63extern _Bs3RegCtxSave_c16
64extern _Bs3SwitchTo%[TMPL_BITS]Bit_c16
65%endif
66
67BS3_BEGIN_TEXT32
68%if TMPL_BITS != 32
69extern _Bs3RegCtxSave_c32
70extern _Bs3SwitchTo%[TMPL_BITS]Bit_c32
71%endif
72%if TMPL_BITS == 16
73extern _Bs3SwitchTo16BitV86_c32
74%endif
75
76BS3_BEGIN_TEXT64
77%if TMPL_BITS != 64
78extern _Bs3RegCtxSave_c64
79extern _Bs3SwitchTo%[TMPL_BITS]Bit_c64
80%endif
81
82TMPL_BEGIN_TEXT
83
84
85
86;;
87; Saves the current register context.
88;
89; @param pRegCtx
90; @param bBitMode (8)
91; @param cbExtraStack (16)
92; @uses xAX, xDX, xCX
93;
94BS3_PROC_BEGIN_CMN Bs3RegCtxSaveEx, BS3_PBC_NEAR ; Far stub generated by the makefile/bs3kit.h.
95TONLY16 CPU 8086
96 BS3_CALL_CONV_PROLOG 3
97 push xBP
98 mov xBP, xSP
99
100 ;
101 ; Get the CPU bitcount part of the current mode.
102 ;
103 mov dl, [BS3_DATA16_WRT(g_bBs3CurrentMode)]
104 and dl, BS3_MODE_CODE_MASK
105%if TMPL_BITS == 16
106 push dx ; bp - 2: previous CPU mode (16-bit)
107%endif
108
109 ;
110 ; Reserve extra stack space. Make sure we've got 20h here in case we
111 ; are saving a 64-bit context.
112 ;
113TONLY16 mov ax, [xBP + xCB + cbCurRetAddr + sCB + xCB]
114TNOT16 movzx eax, word [xBP + xCB + cbCurRetAddr + sCB + xCB]
115%ifdef BS3_STRICT
116 cmp xAX, 4096
117 jb .extra_stack_ok
118 call Bs3Panic
119.extra_stack_ok:
120%endif
121 cmp xAX, 20h
122 jae .at_least_20h_extra_stack
123 add xAX, 20h
124.at_least_20h_extra_stack:
125 sub xSP, xAX
126
127 ;
128 ; Are we just saving the mode we're already in?
129 ;
130 mov al, [xBP + xCB + cbCurRetAddr + sCB]
131 and al, BS3_MODE_CODE_MASK
132 cmp dl, al
133 jne .not_the_same_mode
134
135%if TMPL_BITS == 16
136 push word [xBP + xCB + cbCurRetAddr + 2]
137 push word [xBP + xCB + cbCurRetAddr]
138%elif TMPL_BITS == 32
139 push dword [xBP + xCB + cbCurRetAddr]
140%endif
141 call Bs3RegCtxSave ; 64-bit: rcx is untouched thus far.
142
143
144 ;
145 ; Return - no need to pop xAX and xDX as the last two
146 ; operations preserves all registers.
147 ;
148.return:
149 mov xSP, xBP
150 pop xBP
151 BS3_CALL_CONV_EPILOG 3
152 BS3_HYBRID_RET
153
154
155 ;
156 ; Turns out we have to do switch to a different bitcount before saving.
157 ;
158.not_the_same_mode:
159 cmp al, BS3_MODE_CODE_16
160 je .code_16
161
162TONLY16 CPU 386
163%if TMPL_BITS != 32
164 cmp al, BS3_MODE_CODE_32
165 je .code_32
166%endif
167%if TMPL_BITS != 64
168 cmp al, BS3_MODE_CODE_V86
169 je .code_v86
170 cmp al, BS3_MODE_CODE_64
171 jne .bad_input_mode
172 jmp .code_64
173%endif
174
175 ; Bad input (al=input, dl=current).
176.bad_input_mode:
177 call Bs3Panic
178
179
180 ;
181 ; Save a 16-bit context.
182 ;
183 ; Convert pRegCtx to 16:16 protected mode and make sure we're in the
184 ; 16-bit code segment.
185 ;
186.code_16:
187%if TMPL_BITS == 16
188 %ifdef BS3_STRICT
189 cmp dl, BS3_MODE_CODE_V86
190 jne .bad_input_mode
191 %endif
192 push word [xBP + xCB + cbCurRetAddr + 2]
193 push word [xBP + xCB + cbCurRetAddr]
194 call Bs3SelRealModeDataToProtFar16
195 add sp, 4h
196 push dx ; Parameter #0 for _Bs3RegCtxSave_c16
197 push ax
198%else
199 %if TMPL_BITS == 32
200 push dword [xBP + xCB + cbCurRetAddr]
201 %endif
202 call Bs3SelFlatDataToProtFar16 ; 64-bit: BS3_CALL not needed, ecx not touched thus far.
203 mov [xSP], eax ; Parameter #0 for _Bs3RegCtxSave_c16
204 jmp .code_16_safe_segment
205 BS3_BEGIN_TEXT16
206 BS3_SET_BITS TMPL_BITS
207.code_16_safe_segment:
208%endif
209 call Bs3SwitchTo16Bit
210 BS3_SET_BITS 16
211
212 call _Bs3RegCtxSave_c16
213
214%if TMPL_BITS == 16
215 call _Bs3SwitchTo16BitV86_c16
216%else
217 call _Bs3SwitchTo%[TMPL_BITS]Bit_c16
218%endif
219 BS3_SET_BITS TMPL_BITS
220 jmp .return
221 TMPL_BEGIN_TEXT
222
223TONLY16 CPU 386
224
225
226%if TMPL_BITS != 64
227 ;
228 ; Save a v8086 context.
229 ;
230.code_v86:
231 %if TMPL_BITS == 16
232 %ifdef BS3_STRICT
233 cmp dl, BS3_MODE_CODE_16
234 jne .bad_input_mode
235 %endif
236 push word [xBP + xCB + cbCurRetAddr + 2]
237 push word [xBP + xCB + cbCurRetAddr]
238 call Bs3SelProtFar16DataToRealMode
239 add sp, 4h
240 push dx ; Parameter #0 for _Bs3RegCtxSave_c16
241 push ax
242 %else
243 push dword [xBP + xCB + cbCurRetAddr]
244 call Bs3SelFlatDataToRealMode
245 mov [xSP], eax ; Parameter #0 for _Bs3RegCtxSave_c16
246 jmp .code_v86_safe_segment
247 BS3_BEGIN_TEXT16
248 BS3_SET_BITS TMPL_BITS
249.code_v86_safe_segment:
250 %endif
251 call Bs3SwitchTo16BitV86
252 BS3_SET_BITS 16
253
254 call _Bs3RegCtxSave_c16
255
256 call _Bs3SwitchTo%[TMPL_BITS]Bit_c16
257 BS3_SET_BITS TMPL_BITS
258 jmp .return
259TMPL_BEGIN_TEXT
260%endif
261
262
263%if TMPL_BITS != 32
264 ;
265 ; Save a 32-bit context.
266 ;
267.code_32:
268 %if TMPL_BITS == 16
269 push word [xBP + xCB + cbCurRetAddr + 2]
270 push word [xBP + xCB + cbCurRetAddr]
271 test dl, BS3_MODE_CODE_V86
272 jnz .code_32_from_v86
273 call Bs3SelProtFar16DataToFlat
274 jmp .code_32_flat_ptr
275.code_32_from_v86:
276 call Bs3SelRealModeDataToFlat
277.code_32_flat_ptr:
278 add sp, 4h
279 push dx ; Parameter #0 for _Bs3RegCtxSave_c32
280 push ax
281 %else
282 mov [rsp], ecx ; Parameter #0 for _Bs3RegCtxSave_c16
283 %endif
284 call Bs3SwitchTo32Bit
285 BS3_SET_BITS 32
286
287 call _Bs3RegCtxSave_c32
288
289 %if TMPL_BITS == 16
290 cmp byte [bp - 2], BS3_MODE_CODE_V86
291 je .code_32_back_to_v86
292 call _Bs3SwitchTo16Bit_c32
293 BS3_SET_BITS TMPL_BITS
294 jmp .return
295.code_32_back_to_v86:
296 BS3_SET_BITS 32
297 call _Bs3SwitchTo16BitV86_c32
298 %else
299 call _Bs3SwitchTo64Bit_c32
300 %endif
301 BS3_SET_BITS TMPL_BITS
302 jmp .return
303%endif
304
305
306%if TMPL_BITS != 64
307 ;
308 ; Save a 64-bit context.
309 ;
310 CPU x86-64
311.code_64:
312 %if TMPL_BITS == 16
313 %ifdef BS3_STRICT
314 cmp dl, BS3_MODE_CODE_16
315 jne .bad_input_mode
316 %endif
317 push word [xBP + xCB + cbCurRetAddr + 2]
318 push word [xBP + xCB + cbCurRetAddr]
319 call Bs3SelProtFar16DataToFlat
320 add sp, 4h
321 mov cx, dx ; Parameter #0 for _Bs3RegCtxSave_c64
322 shl ecx, 16
323 mov cx, ax
324 %else
325 mov ecx, [xBP + xCB + cbCurRetAddr] ; Parameter #0 for _Bs3RegCtxSave_c64
326 %endif
327 call Bs3SwitchTo64Bit ; (preserves all 32-bit GPRs)
328 BS3_SET_BITS 64
329
330 call _Bs3RegCtxSave_c64 ; No BS3_CALL as rcx is already ready.
331
332 call _Bs3SwitchTo%[TMPL_BITS]Bit_c64
333 BS3_SET_BITS TMPL_BITS
334 jmp .return
335%endif
336BS3_PROC_END_CMN Bs3RegCtxSaveEx
337
338
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette