VirtualBox

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

Last change on this file was 106061, checked in by vboxsync, 2 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.2 KB
Line 
1; $Id: bs3-cmn-RegCtxSave.asm 106061 2024-09-16 14:03:52Z vboxsync $
2;; @file
3; BS3Kit - Bs3RegCtxSave.
4;
5
6;
7; Copyright (C) 2007-2024 Oracle and/or its affiliates.
8;
9; This file is part of VirtualBox base platform packages, as
10; available from https://www.virtualbox.org.
11;
12; This program is free software; you can redistribute it and/or
13; modify it under the terms of the GNU General Public License
14; as published by the Free Software Foundation, in version 3 of the
15; License.
16;
17; This program is distributed in the hope that it will be useful, but
18; WITHOUT ANY WARRANTY; without even the implied warranty of
19; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20; General Public License for more details.
21;
22; You should have received a copy of the GNU General Public License
23; along with this program; if not, see <https://www.gnu.org/licenses>.
24;
25; The contents of this file may alternatively be used under the terms
26; of the Common Development and Distribution License Version 1.0
27; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
28; in the VirtualBox distribution, in which case the provisions of the
29; CDDL are applicable instead of those of the GPL.
30;
31; You may elect to license modified versions of this file under the
32; terms and conditions of either the GPL or the CDDL or both.
33;
34; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
35;
36
37%include "bs3kit-template-header.mac"
38
39
40BS3_EXTERN_SYSTEM16 Bs3Gdt
41BS3_EXTERN_DATA16 g_bBs3CurrentMode
42%if TMPL_BITS != 64
43BS3_EXTERN_DATA16 g_uBs3CpuDetected
44%endif
45TMPL_BEGIN_TEXT
46
47
48
49;;
50; Saves the current register context.
51;
52; @param pRegCtx
53; @uses None.
54;
55BS3_PROC_BEGIN_CMN Bs3RegCtxSave, BS3_PBC_HYBRID_SAFE
56TONLY16 CPU 8086
57 BS3_CALL_CONV_PROLOG 1
58 push xBP
59 mov xBP, xSP
60 xPUSHF ; xBP - xCB*1: save the incoming flags exactly.
61 push xAX ; xBP - xCB*2: save incoming xAX
62 push xCX ; xBP - xCB*3: save incoming xCX
63 push xDI ; xBP - xCB*4: save incoming xDI
64BONLY16 push es ; xBP - xCB*5
65BONLY16 push ds ; xBP - xCB*6
66
67 ;
68 ; Clear the whole structure first.
69 ;
70 xor xAX, xAX
71 cld
72 AssertCompileSizeAlignment(BS3REGCTX, 4)
73%if TMPL_BITS == 16
74 les xDI, [xBP + xCB + cbCurRetAddr]
75 mov xCX, BS3REGCTX_size / 2
76 rep stosw
77%else
78 mov xDI, [xBP + xCB + cbCurRetAddr]
79 mov xCX, BS3REGCTX_size / 4
80 rep stosd
81%endif
82 mov xDI, [xBP + xCB + cbCurRetAddr]
83
84 ;
85 ; Save the current mode.
86 ;
87 mov cl, [BS3_DATA16_WRT(g_bBs3CurrentMode)]
88 mov [BS3_ONLY_16BIT(es:) xDI + BS3REGCTX.bMode], cl
89%if TMPL_BITS == 16
90
91 ;
92 ; In 16-bit mode we could be running on really ancient CPUs, so check
93 ; mode and detected CPU and proceed with care.
94 ;
95 cmp cl, BS3_MODE_PP16
96 jae .save_full
97
98 mov cl, [BS3_DATA16_WRT(g_uBs3CpuDetected)]
99 cmp cl, BS3CPU_80386
100 jae .save_full
101
102 ; load ES into DS so we can save some segment prefix bytes.
103 push es
104 pop ds
105
106 ; 16-bit GPRs not on the stack.
107 mov [xDI + BS3REGCTX.rdx], dx
108 mov [xDI + BS3REGCTX.rbx], bx
109 mov [xDI + BS3REGCTX.rsi], si
110
111 ; Join the common code.
112 cmp cl, BS3CPU_80286
113 jb .common_ancient
114 CPU 286
115 smsw [xDI + BS3REGCTX.cr0]
116
117 mov cl, [xDI + BS3REGCTX.bMode] ; assumed by jump destination
118 jmp .common_80286
119
120 CPU 386
121%endif
122
123
124.save_full:
125 ;
126 ; 80386 or later.
127 ;
128%if TMPL_BITS != 64
129 ; Check for CR4 here while we've got a working DS in all contexts.
130 test byte [1 + BS3_DATA16_WRT(g_uBs3CpuDetected)], (BS3CPU_F_CPUID >> 8)
131 jnz .save_full_have_cr4
132 or byte [BS3_ONLY_16BIT(es:) xDI + BS3REGCTX.fbFlags], BS3REG_CTX_F_NO_CR4
133.save_full_have_cr4:
134%endif
135%if TMPL_BITS == 16
136 ; Load es into ds so we can save ourselves some segment prefix bytes.
137 push es
138 pop ds
139%endif
140
141 ; GPRs first.
142 mov [xDI + BS3REGCTX.rdx], sDX
143 mov [xDI + BS3REGCTX.rbx], sBX
144 mov [xDI + BS3REGCTX.rsi], sSI
145%if TMPL_BITS == 64
146 mov [xDI + BS3REGCTX.r8], r8
147 mov [xDI + BS3REGCTX.r9], r9
148 mov [xDI + BS3REGCTX.r10], r10
149 mov [xDI + BS3REGCTX.r11], r11
150 mov [xDI + BS3REGCTX.r12], r12
151 mov [xDI + BS3REGCTX.r13], r13
152 mov [xDI + BS3REGCTX.r14], r14
153 mov [xDI + BS3REGCTX.r15], r15
154%else
155 or byte [xDI + BS3REGCTX.fbFlags], BS3REG_CTX_F_NO_AMD64
156%endif
157%if TMPL_BITS == 16 ; Save high bits.
158 mov [xDI + BS3REGCTX.rax], eax
159 mov [xDI + BS3REGCTX.rcx], ecx
160 mov [xDI + BS3REGCTX.rdi], edi
161 mov [xDI + BS3REGCTX.rbp], ebp
162 mov [xDI + BS3REGCTX.rsp], esp
163 pushfd
164 pop dword [xDI + BS3REGCTX.rflags]
165%endif
166%if TMPL_BITS != 64
167 ; The VM flag is never on the stack, so derive it from the bMode we saved above.
168 test byte [xDI + BS3REGCTX.bMode], BS3_MODE_CODE_V86
169 jz .not_v8086
170 or byte [xDI + BS3REGCTX.rflags + 2], X86_EFL_VM >> 16
171 mov byte [xDI + BS3REGCTX.bCpl], 3
172.not_v8086:
173%endif
174
175 ; 386 segment registers.
176 mov [xDI + BS3REGCTX.fs], fs
177 mov [xDI + BS3REGCTX.gs], gs
178
179%if TMPL_BITS == 16 ; v8086 and real mode woes.
180 mov cl, [xDI + BS3REGCTX.bMode]
181 cmp cl, BS3_MODE_RM
182 je .common_full_control_regs
183 test cl, BS3_MODE_CODE_V86
184 jnz .common_full_no_control_regs
185%endif
186 mov ax, ss
187 test al, 3
188 jnz .common_full_no_control_regs
189
190 ; Control registers (ring-0 and real-mode only).
191.common_full_control_regs:
192 mov sAX, cr0
193 mov [xDI + BS3REGCTX.cr0], sAX
194 mov sAX, cr2
195 mov [xDI + BS3REGCTX.cr2], sAX
196 mov sAX, cr3
197 mov [xDI + BS3REGCTX.cr3], sAX
198%if TMPL_BITS != 64
199 test byte [xDI + BS3REGCTX.fbFlags], BS3REG_CTX_F_NO_CR4
200 jnz .common_80286
201%endif
202 mov sAX, cr4
203 mov [xDI + BS3REGCTX.cr4], sAX
204 jmp .common_80286
205
206.common_full_no_control_regs:
207 or byte [xDI + BS3REGCTX.fbFlags], BS3REG_CTX_F_NO_CR0_IS_MSW | BS3REG_CTX_F_NO_CR2_CR3 | BS3REG_CTX_F_NO_CR4
208 smsw [xDI + BS3REGCTX.cr0]
209
210 ; 80286 control registers.
211.common_80286:
212TONLY16 CPU 286
213%if TMPL_BITS != 64
214 cmp cl, BS3_MODE_RM
215 je .no_str_sldt
216 test cl, BS3_MODE_CODE_V86
217 jnz .no_str_sldt
218%endif
219 str [xDI + BS3REGCTX.tr]
220 sldt [xDI + BS3REGCTX.ldtr]
221 jmp .common_ancient
222
223.no_str_sldt:
224 or byte [xDI + BS3REGCTX.fbFlags], BS3REG_CTX_F_NO_TR_LDTR
225
226 ; Common stuff - stuff on the stack, 286 segment registers.
227.common_ancient:
228TONLY16 CPU 8086
229 mov xAX, [xBP - xCB*1]
230 mov [xDI + BS3REGCTX.rflags], xAX
231 mov xAX, [xBP - xCB*2]
232 mov [xDI + BS3REGCTX.rax], xAX
233 mov xAX, [xBP - xCB*3]
234 mov [xDI + BS3REGCTX.rcx], xAX
235 mov xAX, [xBP - xCB*4]
236 mov [xDI + BS3REGCTX.rdi], xAX
237 mov xAX, [xBP]
238 mov [xDI + BS3REGCTX.rbp], xAX
239 mov xAX, [xBP + xCB]
240 mov [xDI + BS3REGCTX.rip], xAX
241 lea xAX, [xBP + xCB + cbCurRetAddr]
242 mov [xDI + BS3REGCTX.rsp], xAX
243
244%if TMPL_BITS == 16
245 mov ax, [xBP + xCB + 2]
246 mov [xDI + BS3REGCTX.cs], ax
247 mov ax, [xBP - xCB*6]
248 mov [xDI + BS3REGCTX.ds], ax
249 mov ax, [xBP - xCB*5]
250 mov [xDI + BS3REGCTX.es], ax
251%else
252 mov [xDI + BS3REGCTX.cs], cs
253 mov [xDI + BS3REGCTX.ds], ds
254 mov [xDI + BS3REGCTX.es], es
255%endif
256 mov [xDI + BS3REGCTX.ss], ss
257
258 ;
259 ; Return.
260 ;
261.return:
262BONLY16 pop ds
263BONLY16 pop es
264 pop xDI
265 pop xCX
266 pop xAX
267 xPOPF
268 pop xBP
269 BS3_HYBRID_RET
270BS3_PROC_END_CMN Bs3RegCtxSave
271
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