VirtualBox

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

Last change on this file since 60199 was 60199, checked in by vboxsync, 9 years ago

bs3kit: updates

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 13.6 KB
Line 
1; $Id: bs3-cmn-RegCtxRestore.asm 60199 2016-03-26 22:38:14Z vboxsync $
2;; @file
3; BS3Kit - Bs3RegCtxRestore.
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
30BS3_EXTERN_SYSTEM16 Bs3Gdt
31BS3_EXTERN_DATA16 g_bBs3CurrentMode
32%if TMPL_BITS == 16
33BS3_EXTERN_DATA16 g_uBs3CpuDetected
34%endif
35TMPL_BEGIN_TEXT
36BS3_EXTERN_CMN Bs3SwitchToRing0
37TMPL_BEGIN_TEXT
38
39
40;;
41; Restores the given register context.
42;
43; @param pRegCtx
44; @param fFlags
45; @uses All registers and may trash stack immediately before the resume point.
46;
47; @note Only respects the BS3_MODE_CODE_MASK part of pRegCtx->bMode.
48;
49%if TMPL_BITS == 16 || TMPL_BITS == 32
50BS3_PROC_BEGIN_CMN Bs3RegCtxRestore_aborts ; special entry point for when watcom applies __aborts
51 %if TMPL_BITS == 16
52 xor xAX, xAX
53 push xAX ; fake return address.
54 %else
55 push 0feedfaceh ; fake return address.
56 %endif
57%endif
58BS3_PROC_BEGIN_CMN Bs3RegCtxRestore
59 BS3_CALL_CONV_PROLOG 2
60
61 ;
62 ; Make sure we're in ring-0 when we do this job.
63 ;
64 mov ax, ss
65 test al, 3
66 jz .in_ring0
67 call Bs3SwitchToRing0
68.in_ring0:
69
70 ;
71 ; Prologue. Loads ES with BS3DATA16/FLAT (for g_bBs3CurrentMode and
72 ; g_uBs3CpuDetected), DS:xBX with pRegCtx and fFlags into xCX.
73 ;
74 push xBP
75 mov xBP, xSP
76%if TMPL_BITS == 16
77 mov ax, BS3DATA16
78 mov es, ax
79 lds bx, [bp + 4]
80 mov cx, [bp + 8]
81%elif TMPL_BITS == 32
82 mov ax, BS3_SEL_R0_DS32
83 mov ds, ax
84 mov xBX, [xBP + xCB*2]
85 movzx xCX, word [xBP + xCB*3]
86%else
87 mov ax, BS3_SEL_R0_DS64
88 mov ds, ax
89 mov xBX, [xBP + xCB*2]
90 movzx xCX, word [xBP + xCB*3]
91%endif
92
93 ; The remainder must be done with interrupts disabled.
94 cli
95
96 ;
97 ; Update g_bs3CurrentMode.
98 ;
99 mov al, [xBX + BS3REGCTX.bMode]
100 and al, BS3_MODE_CODE_MASK
101 mov ah, [BS3_ONLY_16BIT(es:) BS3_DATA16_WRT(g_bBs3CurrentMode)]
102 and ah, ~BS3_MODE_CODE_MASK
103 or al, ah
104 mov [BS3_ONLY_16BIT(es:) BS3_DATA16_WRT(g_bBs3CurrentMode)], al
105
106%if TMPL_BITS == 16
107 ;
108 ; Check what the CPU can do.
109 ;
110 cmp byte [es:BS3_DATA16_WRT(g_uBs3CpuDetected)], BS3CPU_80386
111 jae .restore_full
112
113 ; Do the 80286 specifics first.
114 cmp byte [es:BS3_DATA16_WRT(g_uBs3CpuDetected)], BS3CPU_80286
115 jb .restore_16_bit_ancient
116
117 lmsw [bx + BS3REGCTX.cr0]
118 cmp byte [es:BS3_DATA16_WRT(g_bBs3CurrentMode)], BS3_MODE_RM
119 je .restore_16_bit_ancient
120 lldt [bx + BS3REGCTX.ldtr]
121 ltr [bx + BS3REGCTX.tr]
122
123.restore_16_bit_ancient:
124 ; Some general registers.
125 mov cx, [bx + BS3REGCTX.rcx]
126 mov dx, [bx + BS3REGCTX.rdx]
127
128 ; Do the return frame and final registers (keep short as we're not quite
129 ; NMI safe here if pRegCtx is on the stack).
130 cmp byte [es:BS3_DATA16_WRT(g_bBs3CurrentMode)], BS3_MODE_RM
131 mov di, [bx + BS3REGCTX.rsp]
132 je .restore_16_bit_same_privilege
133 cmp byte [bx + BS3REGCTX.bCpl], 0
134 je .restore_16_bit_same_privilege
135
136 mov ax, [bx + BS3REGCTX.ss]
137 push ax
138 mov ax, [bx + BS3REGCTX.rsp]
139 push ax
140 mov ax, [bx + BS3REGCTX.rflags]
141 push ax
142 mov ax, [bx + BS3REGCTX.cs]
143 push ax
144 mov ax, [bx + BS3REGCTX.rip]
145 push ax
146 mov ax, [bx + BS3REGCTX.ds]
147 push ax
148
149 mov si, [bx + BS3REGCTX.rsi]
150 mov di, [bx + BS3REGCTX.rdi]
151 mov es, [bx + BS3REGCTX.es]
152 mov ax, [bx + BS3REGCTX.rax]
153 mov bp, [bx + BS3REGCTX.rbp] ; restore late for better stacks.
154 mov bx, [bx + BS3REGCTX.rbx]
155
156 pop ds
157 iret
158
159.restore_16_bit_same_privilege:
160 sub di, 2*5 ; iret frame + pop ds
161 mov si, di
162 mov es, [bx + BS3REGCTX.ss] ; ES is target stack segment.
163 cld
164
165 mov ax, [bx + BS3REGCTX.ds]
166 stosw
167 mov ax, [bx + BS3REGCTX.rbp] ; Restore esp as late as possible for better stacks.
168 stosw
169 mov ax, [bx + BS3REGCTX.rip]
170 stosw
171 mov ax, [bx + BS3REGCTX.cs]
172 stosw
173 mov ax, [bx + BS3REGCTX.rflags]
174 stosw
175
176 mov di, [bx + BS3REGCTX.rdi]
177 mov es, [bx + BS3REGCTX.es]
178 mov ax, [bx + BS3REGCTX.rax]
179 mov ss, [bx + BS3REGCTX.ss]
180 mov sp, si
181 mov si, [bx + BS3REGCTX.rsi]
182 mov bx, [bx + BS3REGCTX.rbx]
183
184 pop ds
185 pop bp
186 iret
187%endif
188
189
190.restore_full:
191 ;
192 ; 80386 or later.
193 ; For 32-bit and 16-bit versions, we always use 32-bit iret.
194 ;
195
196 ; Restore control registers if they've changed.
197 test cl, BS3TRAPRESUME_F_SKIP_CRX
198 jnz .skip_control_regs
199 test byte [xBX + BS3REGCTX.fbFlags], BS3REG_CTX_F_NO_CR
200 jnz .skip_control_regs
201
202 mov sAX, [xBX + BS3REGCTX.cr4]
203 mov sDX, cr4
204 cmp sAX, sDX
205 je .skip_cr4
206 mov cr4, sAX
207.skip_cr4:
208
209 mov sAX, [xBX + BS3REGCTX.cr0]
210 mov sDX, cr0
211 cmp sAX, sDX
212 je .skip_cr0
213 mov cr0, sAX
214.skip_cr0:
215
216 mov sAX, [xBX + BS3REGCTX.cr3]
217 mov sDX, cr3
218 cmp sAX, sDX
219 je .skip_cr3
220 mov cr3, sAX
221.skip_cr3:
222
223 mov sAX, [xBX + BS3REGCTX.cr2]
224 mov sDX, cr2
225 cmp sAX, sDX
226 je .skip_cr2
227 mov cr2, sAX
228.skip_cr2:
229
230 ;
231 ; Restore
232 ;
233%if TMPL_BITS != 64
234 ; We cannot restore ldtr and tr if we're in real-mode.
235 cmp byte [BS3_ONLY_16BIT(es:) BS3_DATA16_WRT(g_bBs3CurrentMode)], BS3_MODE_RM
236 je .skip_control_regs
237%endif
238
239 ; LDTR
240 sldt ax
241 cmp ax, [xBX + BS3REGCTX.ldtr]
242 je .skip_ldtr
243 lldt [xBX + BS3REGCTX.ldtr]
244.skip_ldtr:
245
246 ; TR - complicated because we need to clear the busy bit. ASSUMES GDT.
247 str ax
248 cmp ax, [xBX + BS3REGCTX.tr]
249 je .skip_tr
250
251 movzx edi, word [xBX + BS3REGCTX.tr]
252 or edi, edi ; check for null.
253 jz .load_tr
254
255%if TMPL_BITS == 16
256 push ds
257 push BS3_SEL_SYSTEM16
258 pop ds
259 add xDI, Bs3Gdt wrt BS3SYSTEM16
260%else
261 add xDI, Bs3Gdt wrt FLAT
262%endif
263 add xDI, X86DESCGENERIC_BIT_OFF_TYPE / 8
264 and byte [xDI], ~(X86_SEL_TYPE_SYS_TSS_BUSY_MASK << (X86DESCGENERIC_BIT_OFF_TYPE % 8))
265%if TMPL_BITS == 16
266 pop ds
267%endif
268.load_tr:
269 ltr [xBX + BS3REGCTX.tr]
270.skip_tr:
271
272.skip_control_regs:
273
274
275%if TMPL_BITS == 64
276 ;
277 ; 64-bit returns are simple because ss:rsp are always restored.
278 ;
279 movzx eax, word [xBX + BS3REGCTX.ss]
280 push rax
281 push qword [xBX + BS3REGCTX.rsp]
282 push qword [xBX + BS3REGCTX.rflags]
283 movzx eax, word [xBX + BS3REGCTX.cs]
284 push rax
285 push qword [xBX + BS3REGCTX.rip]
286
287 mov es, [xBX + BS3REGCTX.es]
288 mov fs, [xBX + BS3REGCTX.fs]
289 mov gs, [xBX + BS3REGCTX.gs]
290 mov rax, [xBX + BS3REGCTX.rax]
291 mov rdx, [xBX + BS3REGCTX.rdx]
292 mov rcx, [xBX + BS3REGCTX.rcx]
293 mov rsi, [xBX + BS3REGCTX.rsi]
294 mov rdi, [xBX + BS3REGCTX.rdi]
295 mov r8, [xBX + BS3REGCTX.r8]
296 mov r9, [xBX + BS3REGCTX.r9]
297 mov r10, [xBX + BS3REGCTX.r10]
298 mov r11, [xBX + BS3REGCTX.r11]
299 mov r12, [xBX + BS3REGCTX.r12]
300 mov r13, [xBX + BS3REGCTX.r13]
301 mov r14, [xBX + BS3REGCTX.r14]
302 mov r15, [xBX + BS3REGCTX.r15]
303 mov rbp, [xBX + BS3REGCTX.rbp] ; restore late for better stacks.
304 mov ds, [xBX + BS3REGCTX.ds]
305 mov rbx, [xBX + BS3REGCTX.rbx]
306 iretq
307
308%else
309 ;
310 ; 32-bit/16-bit is more complicated as we have three different iret frames.
311 ;
312 cmp byte [BS3_ONLY_16BIT(es:) BS3_DATA16_WRT(g_bBs3CurrentMode)], BS3_MODE_RM
313 je .iretd_same_cpl_rm
314
315 test dword [xBX + BS3REGCTX.rflags], X86_EFL_VM
316 jnz .restore_v8086
317
318 cmp byte [xBX + BS3REGCTX.bCpl], 0
319 je .iretd_same_cpl
320
321 ;
322 ; IRETD to different CPL. Frame includes ss:esp.
323 ;
324.iretd_different_cpl:
325 or eax, 0ffffffffh ; poison unused parts of segment pushes
326 mov ax, [xBX + BS3REGCTX.ss]
327 push eax
328 push dword [xBX + BS3REGCTX.rsp]
329 push dword [xBX + BS3REGCTX.rflags]
330 mov ax, [xBX + BS3REGCTX.cs]
331 push eax
332 push dword [xBX + BS3REGCTX.rip]
333 push dword [xBX + BS3REGCTX.rbp] ; Restore esp as late as possible for better stacks.
334 mov ax, [xBX + BS3REGCTX.ds]
335 push xAX
336
337 mov es, [xBX + BS3REGCTX.es]
338 mov fs, [xBX + BS3REGCTX.fs]
339 mov gs, [xBX + BS3REGCTX.gs]
340 mov eax, [xBX + BS3REGCTX.rax]
341 mov edx, [xBX + BS3REGCTX.rdx]
342 mov ecx, [xBX + BS3REGCTX.rcx]
343 mov esi, [xBX + BS3REGCTX.rsi]
344%if TMPL_BITS == 16 ; if SS is 16-bit, we will not be able to restore the high word.
345 mov edi, [xBX + BS3REGCTX.rsp]
346 mov di, sp
347 mov esp, edi
348%endif
349 mov edi, [xBX + BS3REGCTX.rdi]
350 mov ebx, [xBX + BS3REGCTX.rbx]
351
352 pop ds
353 pop ebp
354 iretd
355
356 ;
357 ; IRETD to same CPL (includes real mode).
358 ;
359.iretd_same_cpl_rm:
360 ; Use STOSD/ES:EDI to create the frame.
361 mov es, [xBX + BS3REGCTX.ss]
362 movzx esp, word [xBX + BS3REGCTX.rsp]
363 jmp .using_16_bit_stack_pointer
364
365.iretd_same_cpl:
366 ; Use STOSD/ES:EDI to create the frame.
367 mov es, [xBX + BS3REGCTX.ss]
368 mov edi, [xBX + BS3REGCTX.rsp]
369 sub edi, 5*4
370
371 ; Which part of the stack pointer is actually used depends on the SS.D/B bit.
372 lar eax, [xBX + BS3REGCTX.ss]
373 jnz .using_32_bit_stack_pointer
374 test eax, X86LAR_F_D
375 jnz .using_32_bit_stack_pointer
376.using_16_bit_stack_pointer:
377 movzx edi, di
378 mov esi, [xBX + BS3REGCTX.rsp]
379 mov si, di ; save rsp for later.
380 jmp .es_edi_is_pointing_to_return_frame_location
381.using_32_bit_stack_pointer:
382 mov esi, edi
383.es_edi_is_pointing_to_return_frame_location:
384 cld
385 mov ax, [xBX + BS3REGCTX.ds]
386 o32 stosd
387 mov eax, [xBX + BS3REGCTX.rbp] ; Restore esp as late as possible for better stacks.
388 o32 stosd
389 mov eax, [xBX + BS3REGCTX.rip]
390 o32 stosd
391 mov ax, [xBX + BS3REGCTX.cs]
392 o32 stosd
393 mov eax, [xBX + BS3REGCTX.rflags]
394 o32 stosd
395
396 mov es, [xBX + BS3REGCTX.es]
397 mov fs, [xBX + BS3REGCTX.fs]
398 mov gs, [xBX + BS3REGCTX.gs]
399 mov eax, [xBX + BS3REGCTX.rax]
400 mov edx, [xBX + BS3REGCTX.rdx]
401 mov ecx, [xBX + BS3REGCTX.rcx]
402 mov edi, [xBX + BS3REGCTX.rdi]
403 mov ebp, [xBX + BS3REGCTX.rbp] ; restore late for better stacks.
404
405 mov ss, [xBX + BS3REGCTX.ss]
406 mov esp, esi
407 mov esi, [xBX + BS3REGCTX.rsi]
408 mov ebx, [xBX + BS3REGCTX.rbx]
409
410 o32 pop ds
411 pop ebp
412 iretd
413
414 ;
415 ; IRETD to v8086 mode. Frame includes ss:esp and the 4 data segment registers.
416 ;
417.restore_v8086:
418 or eax, 0ffffffffh ; poison unused parts of segment pushes
419 mov eax, [xBX + BS3REGCTX.gs]
420 push eax
421 mov eax, [xBX + BS3REGCTX.fs]
422 push eax
423 mov eax, [xBX + BS3REGCTX.ds]
424 push eax
425 mov eax, [xBX + BS3REGCTX.es]
426 push eax
427 mov eax, [xBX + BS3REGCTX.ss]
428 push eax
429 push dword [xBX + BS3REGCTX.rsp]
430 push dword [xBX + BS3REGCTX.rflags]
431 mov ax, [xBX + BS3REGCTX.cs]
432 push eax
433 push dword [xBX + BS3REGCTX.rip]
434
435 mov eax, [xBX + BS3REGCTX.rax]
436 mov edx, [xBX + BS3REGCTX.rdx]
437 mov ecx, [xBX + BS3REGCTX.rcx]
438 mov esi, [xBX + BS3REGCTX.rsi]
439 mov edi, [xBX + BS3REGCTX.rdi]
440 mov ebp, [xBX + BS3REGCTX.rbp] ; restore late for better stacks.
441 mov ebx, [xBX + BS3REGCTX.rbx]
442
443 iretd
444%endif
445BS3_PROC_END_CMN Bs3RegCtxRestore
446
Note: See TracBrowser for help on using the repository browser.

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