VirtualBox

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

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

bs3kit: fixes.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.9 KB
Line 
1; $Id: bs3-cmn-RegCtxSave.asm 60661 2016-04-22 16:46:15Z vboxsync $
2;; @file
3; BS3Kit - Bs3RegCtxSave.
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 != 64
33BS3_EXTERN_DATA16 g_uBs3CpuDetected
34%endif
35TMPL_BEGIN_TEXT
36
37
38
39;;
40; Saves the current register context.
41;
42; @param pRegCtx
43; @uses None.
44;
45BS3_PROC_BEGIN_CMN Bs3RegCtxSave, BS3_PBC_HYBRID_SAFE
46TONLY16 CPU 8086
47 BS3_CALL_CONV_PROLOG 1
48 push xBP
49 mov xBP, xSP
50 xPUSHF ; xBP - xCB*1: save the incoming flags exactly.
51 push xAX ; xBP - xCB*2: save incoming xAX
52 push xCX ; xBP - xCB*3: save incoming xCX
53 push xDI ; xBP - xCB*4: save incoming xDI
54BONLY16 push es ; xBP - xCB*5
55BONLY16 push ds ; xBP - xCB*6
56
57 ;
58 ; Clear the whole structure first.
59 ;
60 xor xAX, xAX
61 cld
62 AssertCompileSizeAlignment(BS3REGCTX, 4)
63%if TMPL_BITS == 16
64 les xDI, [xBP + xCB + cbCurRetAddr]
65 mov xCX, BS3REGCTX_size / 2
66 rep stosw
67%else
68 mov xDI, [xBP + xCB + cbCurRetAddr]
69 mov xCX, BS3REGCTX_size / 4
70 rep stosd
71%endif
72 mov xDI, [xBP + xCB + cbCurRetAddr]
73
74 ;
75 ; Save the current mode.
76 ;
77 mov cl, [BS3_DATA16_WRT(g_bBs3CurrentMode)]
78 mov [BS3_ONLY_16BIT(es:) xDI + BS3REGCTX.bMode], cl
79%if TMPL_BITS == 16
80
81 ;
82 ; In 16-bit mode we could be running on really ancient CPUs, so check
83 ; mode and detected CPU and proceed with care.
84 ;
85 cmp cl, BS3_MODE_PP16
86 jae .save_full
87
88 mov cl, [BS3_DATA16_WRT(g_uBs3CpuDetected)]
89 cmp cl, BS3CPU_80386
90 jae .save_full
91
92 ; load ES into DS so we can save some segment prefix bytes.
93 push es
94 pop ds
95
96 ; 16-bit GPRs not on the stack.
97 mov [xDI + BS3REGCTX.rdx], dx
98 mov [xDI + BS3REGCTX.rbx], bx
99 mov [xDI + BS3REGCTX.rsi], si
100
101 ; Join the common code.
102 cmp cl, BS3CPU_80286
103 jb .common_ancient
104 CPU 286
105 smsw [xDI + BS3REGCTX.cr0]
106
107 mov cl, [xDI + BS3REGCTX.bMode] ; assumed by jump destination
108 jmp .common_80286
109
110 CPU 386
111%endif
112
113
114.save_full:
115 ;
116 ; 80386 or later.
117 ;
118%if TMPL_BITS != 64
119 ; Check for CR4 here while we've got a working DS in all contexts.
120 test byte [1 + BS3_DATA16_WRT(g_uBs3CpuDetected)], (BS3CPU_F_CPUID >> 8)
121 jnz .save_full_have_cr4
122 or byte [BS3_ONLY_16BIT(es:) xDI + BS3REGCTX.fbFlags], BS3REG_CTX_F_NO_CR4
123.save_full_have_cr4:
124%endif
125%if TMPL_BITS == 16
126 ; Load es into ds so we can save ourselves some segment prefix bytes.
127 push es
128 pop ds
129%endif
130
131 ; GPRs first.
132 mov [xDI + BS3REGCTX.rdx], sDX
133 mov [xDI + BS3REGCTX.rbx], sBX
134 mov [xDI + BS3REGCTX.rsi], sSI
135%if TMPL_BITS == 64
136 mov [xDI + BS3REGCTX.r8], r8
137 mov [xDI + BS3REGCTX.r9], r9
138 mov [xDI + BS3REGCTX.r10], r10
139 mov [xDI + BS3REGCTX.r11], r11
140 mov [xDI + BS3REGCTX.r12], r12
141 mov [xDI + BS3REGCTX.r13], r13
142 mov [xDI + BS3REGCTX.r14], r14
143 mov [xDI + BS3REGCTX.r15], r15
144%else
145 or byte [xDI + BS3REGCTX.fbFlags], BS3REG_CTX_F_NO_AMD64
146%endif
147%if TMPL_BITS == 16 ; Save high bits.
148 mov [xDI + BS3REGCTX.rax], eax
149 mov [xDI + BS3REGCTX.rcx], ecx
150 mov [xDI + BS3REGCTX.rdi], edi
151 mov [xDI + BS3REGCTX.rbp], ebp
152 mov [xDI + BS3REGCTX.rsp], esp
153 pushfd
154 pop dword [xDI + BS3REGCTX.rflags]
155%endif
156%if TMPL_BITS != 64
157 ; The VM flag is never on the stack, so derive it from the bMode we saved above.
158 test byte [xDI + BS3REGCTX.bMode], BS3_MODE_CODE_V86
159 jz .not_v8086
160 or byte [xDI + BS3REGCTX.rflags + 2], X86_EFL_VM >> 16
161 mov byte [xDI + BS3REGCTX.bCpl], 3
162.not_v8086:
163%endif
164
165 ; 386 segment registers.
166 mov [xDI + BS3REGCTX.fs], fs
167 mov [xDI + BS3REGCTX.gs], gs
168
169%if TMPL_BITS == 16 ; v8086 and real mode woes.
170 mov cl, [xDI + BS3REGCTX.bMode]
171 cmp cl, BS3_MODE_RM
172 je .common_full_control_regs
173 test cl, BS3_MODE_CODE_V86
174 jnz .common_full_no_control_regs
175%endif
176 mov ax, ss
177 test al, 3
178 jnz .common_full_no_control_regs
179
180 ; Control registers (ring-0 and real-mode only).
181.common_full_control_regs:
182 mov sAX, cr0
183 mov [xDI + BS3REGCTX.cr0], sAX
184 mov sAX, cr2
185 mov [xDI + BS3REGCTX.cr2], sAX
186 mov sAX, cr3
187 mov [xDI + BS3REGCTX.cr3], sAX
188%if TMPL_BITS != 64
189 test byte [xDI + BS3REGCTX.fbFlags], BS3REG_CTX_F_NO_CR4
190 jnz .common_80286
191%endif
192 mov sAX, cr4
193 mov [xDI + BS3REGCTX.cr4], sAX
194 jmp .common_80286
195
196.common_full_no_control_regs:
197 or byte [xDI + BS3REGCTX.fbFlags], BS3REG_CTX_F_NO_CR0_IS_MSW | BS3REG_CTX_F_NO_CR2_CR3 | BS3REG_CTX_F_NO_CR4
198 smsw [xDI + BS3REGCTX.cr0]
199
200 ; 80286 control registers.
201.common_80286:
202TONLY16 CPU 286
203%if TMPL_BITS != 64
204 cmp cl, BS3_MODE_RM
205 je .no_str_sldt
206 test cl, BS3_MODE_CODE_V86
207 jnz .no_str_sldt
208%endif
209 str [xDI + BS3REGCTX.tr]
210 sldt [xDI + BS3REGCTX.ldtr]
211 jmp .common_ancient
212
213.no_str_sldt:
214 or byte [xDI + BS3REGCTX.fbFlags], BS3REG_CTX_F_NO_TR_LDTR
215
216 ; Common stuff - stuff on the stack, 286 segment registers.
217.common_ancient:
218TONLY16 CPU 8086
219 mov xAX, [xBP - xCB*1]
220 mov [xDI + BS3REGCTX.rflags], xAX
221 mov xAX, [xBP - xCB*2]
222 mov [xDI + BS3REGCTX.rax], xAX
223 mov xAX, [xBP - xCB*3]
224 mov [xDI + BS3REGCTX.rcx], xAX
225 mov xAX, [xBP - xCB*4]
226 mov [xDI + BS3REGCTX.rdi], xAX
227 mov xAX, [xBP]
228 mov [xDI + BS3REGCTX.rbp], xAX
229 mov xAX, [xBP + xCB]
230 mov [xDI + BS3REGCTX.rip], xAX
231 lea xAX, [xBP + xCB + cbCurRetAddr]
232 mov [xDI + BS3REGCTX.rsp], xAX
233
234%if TMPL_BITS == 16
235 mov ax, [xBP + xCB + 2]
236 mov [xDI + BS3REGCTX.cs], ax
237 mov ax, [xBP - xCB*6]
238 mov [xDI + BS3REGCTX.ds], ax
239 mov ax, [xBP - xCB*5]
240 mov [xDI + BS3REGCTX.es], ax
241%else
242 mov [xDI + BS3REGCTX.cs], cs
243 mov [xDI + BS3REGCTX.ds], ds
244 mov [xDI + BS3REGCTX.es], es
245%endif
246 mov [xDI + BS3REGCTX.ss], ss
247
248 ;
249 ; Return.
250 ;
251.return:
252BONLY16 pop ds
253BONLY16 pop es
254 pop xDI
255 pop xCX
256 pop xAX
257 xPOPF
258 pop xBP
259 BS3_HYBRID_RET
260BS3_PROC_END_CMN Bs3RegCtxSave
261
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