VirtualBox

source: vbox/trunk/src/VBox/ValidationKit/utils/cpu/cidet-appA.asm@ 93455

Last change on this file since 93455 was 93115, checked in by vboxsync, 3 years ago

scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.7 KB
Line 
1; $Id: cidet-appA.asm 93115 2022-01-01 11:31:46Z vboxsync $
2;; @file
3; CPU Instruction Decoding & Execution Tests - Ring-3 Driver Application, Assembly Code.
4;
5
6;
7; Copyright (C) 2009-2022 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
28;*******************************************************************************
29;* Header Files *
30;*******************************************************************************
31%include "iprt/asmdefs.mac"
32%include "iprt/x86.mac"
33%include "cidet.mac"
34
35
36;*******************************************************************************
37;* Global Variables *
38;*******************************************************************************
39%ifdef RT_ARCH_X86
40;; Used by CidetAppSaveAndRestoreCtx when we have a tricky target stack.
41g_uTargetEip dd 0
42g_uTargetCs dw 0
43%endif
44
45
46;;
47; Leave GS alone on 64-bit darwin (gs is 0, no ldt or gdt entry to load that'll
48; restore the lower 32-bits of the base when saving and restoring the register).
49%ifdef RT_OS_DARWIN
50 %ifdef RT_ARCH_AMD64
51 %define CIDET_LEAVE_GS_ALONE
52 %endif
53%endif
54
55
56
57BEGINCODE
58
59;;
60; ASSUMES that it's called and the EIP/RIP is found on the stack.
61;
62; @param pSaveCtx ds:xCX The context to save; DS, xDX and xCX have
63; already been saved by the caller.
64; @param pRestoreCtx ds:xDX The context to restore.
65;
66BEGINPROC CidetAppSaveAndRestoreCtx
67 ;
68 ; Save the stack pointer and program counter first so we can later
69 ; bypass this step if we need to.
70 ;
71 mov [xCX + CIDETCPUCTX.aGRegs + X86_GREG_xAX * 8], xAX ; need scratch register.
72 lea xAX, [xSP + xCB]
73 mov [xCX + CIDETCPUCTX.aGRegs + X86_GREG_xSP * 8], xAX
74 mov word [xCX + CIDETCPUCTX.aSRegs + X86_SREG_SS * 2], ss
75 mov word [xCX + CIDETCPUCTX.aSRegs + X86_SREG_CS * 2], cs
76 mov xAX, [xSP]
77 mov [xCX + CIDETCPUCTX.rip], xAX
78 jmp CidetAppSaveAndRestoreCtx_1
79
80GLOBALNAME CidetAppSaveAndRestoreCtx_NoSsSpCsIp
81 mov [xDX + CIDETCPUCTX.aGRegs + X86_GREG_xAX * 8], xAX
82CidetAppSaveAndRestoreCtx_1:
83
84 ; Flags.
85%ifdef RT_ARCH_AMD64
86 pushfq
87%else
88 pushfd
89%endif
90 pop xAX
91 mov [xCX + CIDETCPUCTX.rfl], xAX
92
93 ; Segment registers.
94 mov word [xCX + CIDETCPUCTX.aSRegs + X86_SREG_ES * 2], es
95 mov word [xCX + CIDETCPUCTX.aSRegs + X86_SREG_FS * 2], fs
96 mov word [xCX + CIDETCPUCTX.aSRegs + X86_SREG_GS * 2], gs
97
98 ; Remaining GPRs.
99 mov [xCX + CIDETCPUCTX.aGRegs + X86_GREG_xBX * 8], xBX
100 mov [xCX + CIDETCPUCTX.aGRegs + X86_GREG_xBP * 8], xBP
101 mov [xCX + CIDETCPUCTX.aGRegs + X86_GREG_xSI * 8], xSI
102 mov [xCX + CIDETCPUCTX.aGRegs + X86_GREG_xDI * 8], xDI
103%ifdef RT_ARCH_AMD64
104 mov [xCX + CIDETCPUCTX.aGRegs + X86_GREG_x8 * 8], r8
105 mov [xCX + CIDETCPUCTX.aGRegs + X86_GREG_x9 * 8], r9
106 mov [xCX + CIDETCPUCTX.aGRegs + X86_GREG_x10 * 8], r10
107 mov [xCX + CIDETCPUCTX.aGRegs + X86_GREG_x11 * 8], r11
108 mov [xCX + CIDETCPUCTX.aGRegs + X86_GREG_x12 * 8], r12
109 mov [xCX + CIDETCPUCTX.aGRegs + X86_GREG_x13 * 8], r13
110 mov [xCX + CIDETCPUCTX.aGRegs + X86_GREG_x14 * 8], r14
111 mov [xCX + CIDETCPUCTX.aGRegs + X86_GREG_x15 * 8], r15
112 xor eax, eax
113 mov [xCX + CIDETCPUCTX.cr2], rax
114 %ifndef CIDET_REDUCED_CTX
115 mov [xCX + CIDETCPUCTX.cr0], rax
116 mov [xCX + CIDETCPUCTX.cr3], rax
117 mov [xCX + CIDETCPUCTX.cr4], rax
118 mov [xCX + CIDETCPUCTX.cr8], rax
119 mov [xCX + CIDETCPUCTX.dr0], rax
120 mov [xCX + CIDETCPUCTX.dr1], rax
121 mov [xCX + CIDETCPUCTX.dr2], rax
122 mov [xCX + CIDETCPUCTX.dr3], rax
123 mov [xCX + CIDETCPUCTX.dr6], rax
124 mov [xCX + CIDETCPUCTX.dr7], rax
125 mov [xCX + CIDETCPUCTX.tr], ax
126 mov [xCX + CIDETCPUCTX.ldtr], ax
127 %endif
128%else
129 xor eax, eax
130 mov [xCX + CIDETCPUCTX.rfl + 4], eax
131 mov [xCX + CIDETCPUCTX.rip + 4], eax
132 mov [xCX + CIDETCPUCTX.aGRegs + X86_GREG_xAX * 8 + 4], eax
133 mov [xCX + CIDETCPUCTX.aGRegs + X86_GREG_xCX * 8 + 4], eax
134 mov [xCX + CIDETCPUCTX.aGRegs + X86_GREG_xDX * 8 + 4], eax
135 mov [xCX + CIDETCPUCTX.aGRegs + X86_GREG_xBX * 8 + 4], eax
136 mov [xCX + CIDETCPUCTX.aGRegs + X86_GREG_xSP * 8 + 4], eax
137 mov [xCX + CIDETCPUCTX.aGRegs + X86_GREG_xBP * 8 + 4], eax
138 mov [xCX + CIDETCPUCTX.aGRegs + X86_GREG_xSI * 8 + 4], eax
139 mov [xCX + CIDETCPUCTX.aGRegs + X86_GREG_xDI * 8 + 4], eax
140 mov [xCX + CIDETCPUCTX.aGRegs + X86_GREG_x8 * 8 ], eax
141 mov [xCX + CIDETCPUCTX.aGRegs + X86_GREG_x8 * 8 + 4], eax
142 mov [xCX + CIDETCPUCTX.aGRegs + X86_GREG_x9 * 8 ], eax
143 mov [xCX + CIDETCPUCTX.aGRegs + X86_GREG_x9 * 8 + 4], eax
144 mov [xCX + CIDETCPUCTX.aGRegs + X86_GREG_x10 * 8 ], eax
145 mov [xCX + CIDETCPUCTX.aGRegs + X86_GREG_x10 * 8 + 4], eax
146 mov [xCX + CIDETCPUCTX.aGRegs + X86_GREG_x11 * 8 ], eax
147 mov [xCX + CIDETCPUCTX.aGRegs + X86_GREG_x11 * 8 + 4], eax
148 mov [xCX + CIDETCPUCTX.aGRegs + X86_GREG_x12 * 8 ], eax
149 mov [xCX + CIDETCPUCTX.aGRegs + X86_GREG_x12 * 8 + 4], eax
150 mov [xCX + CIDETCPUCTX.aGRegs + X86_GREG_x13 * 8 ], eax
151 mov [xCX + CIDETCPUCTX.aGRegs + X86_GREG_x13 * 8 + 4], eax
152 mov [xCX + CIDETCPUCTX.aGRegs + X86_GREG_x14 * 8 ], eax
153 mov [xCX + CIDETCPUCTX.aGRegs + X86_GREG_x14 * 8 + 4], eax
154 mov [xCX + CIDETCPUCTX.aGRegs + X86_GREG_x15 * 8 ], eax
155 mov [xCX + CIDETCPUCTX.aGRegs + X86_GREG_x15 * 8 + 4], eax
156 mov [xCX + CIDETCPUCTX.cr2 ], eax
157 mov [xCX + CIDETCPUCTX.cr2 + 4], eax
158 %ifndef CIDET_REDUCED_CTX
159 mov [xCX + CIDETCPUCTX.cr0 ], eax
160 mov [xCX + CIDETCPUCTX.cr0 + 4], eax
161 mov [xCX + CIDETCPUCTX.cr3 ], eax
162 mov [xCX + CIDETCPUCTX.cr3 + 4], eax
163 mov [xCX + CIDETCPUCTX.cr4 ], eax
164 mov [xCX + CIDETCPUCTX.cr4 + 4], eax
165 mov [xCX + CIDETCPUCTX.cr8 ], eax
166 mov [xCX + CIDETCPUCTX.cr8 + 4], eax
167 mov [xCX + CIDETCPUCTX.dr0 ], eax
168 mov [xCX + CIDETCPUCTX.dr0 + 4], eax
169 mov [xCX + CIDETCPUCTX.dr1 ], eax
170 mov [xCX + CIDETCPUCTX.dr1 + 4], eax
171 mov [xCX + CIDETCPUCTX.dr2 ], eax
172 mov [xCX + CIDETCPUCTX.dr2 + 4], eax
173 mov [xCX + CIDETCPUCTX.dr3 ], eax
174 mov [xCX + CIDETCPUCTX.dr3 + 4], eax
175 mov [xCX + CIDETCPUCTX.dr6 ], eax
176 mov [xCX + CIDETCPUCTX.dr6 + 4], eax
177 mov [xCX + CIDETCPUCTX.dr7 ], eax
178 mov [xCX + CIDETCPUCTX.dr7 + 4], eax
179 mov [xCX + CIDETCPUCTX.tr], ax
180 mov [xCX + CIDETCPUCTX.ldtr], ax
181 %endif
182%endif
183 dec xAX
184 mov [xCX + CIDETCPUCTX.uErr], xAX
185%ifdef RT_ARCH_X86
186 mov [xCX + CIDETCPUCTX.uErr + 4], eax
187%endif
188 mov [xCX + CIDETCPUCTX.uXcpt], eax
189
190 ;
191 ; Restore the other state (pointer in xDX).
192 ;
193NAME(CidetAppSaveAndRestoreCtx_Restore):
194
195 ; Restore ES, FS, and GS.
196 mov es, [xDX + CIDETCPUCTX.aSRegs + X86_SREG_ES * 2]
197 mov fs, [xDX + CIDETCPUCTX.aSRegs + X86_SREG_FS * 2]
198%ifndef CIDET_LEAVE_GS_ALONE
199 mov gs, [xDX + CIDETCPUCTX.aSRegs + X86_SREG_GS * 2]
200%endif
201
202 ; Restore most GPRs (except xCX, xAX and xSP).
203 mov xCX, [xDX + CIDETCPUCTX.aGRegs + X86_GREG_xCX * 8]
204 mov xBX, [xDX + CIDETCPUCTX.aGRegs + X86_GREG_xBX * 8]
205 mov xBP, [xDX + CIDETCPUCTX.aGRegs + X86_GREG_xBP * 8]
206 mov xSI, [xDX + CIDETCPUCTX.aGRegs + X86_GREG_xSI * 8]
207 mov xDI, [xDX + CIDETCPUCTX.aGRegs + X86_GREG_xDI * 8]
208%ifdef RT_ARCH_AMD64
209 mov r8, [xDX + CIDETCPUCTX.aGRegs + X86_GREG_x8 * 8]
210 mov r9, [xDX + CIDETCPUCTX.aGRegs + X86_GREG_x9 * 8]
211 mov r10, [xDX + CIDETCPUCTX.aGRegs + X86_GREG_x10 * 8]
212 mov r11, [xDX + CIDETCPUCTX.aGRegs + X86_GREG_x11 * 8]
213 mov r12, [xDX + CIDETCPUCTX.aGRegs + X86_GREG_x12 * 8]
214 mov r13, [xDX + CIDETCPUCTX.aGRegs + X86_GREG_x13 * 8]
215 mov r14, [xDX + CIDETCPUCTX.aGRegs + X86_GREG_x14 * 8]
216 mov r15, [xDX + CIDETCPUCTX.aGRegs + X86_GREG_x15 * 8]
217%endif
218
219%ifdef RT_ARCH_AMD64
220 ; Create an iret frame which restores SS:RSP, RFLAGS, and CS:RIP.
221 movzx eax, word [xDX + CIDETCPUCTX.aSRegs + X86_SREG_SS * 2]
222 push xAX
223 push qword [xDX + CIDETCPUCTX.aGRegs + X86_GREG_xSP * 8]
224 push qword [xDX + CIDETCPUCTX.rfl]
225 movzx eax, word [xDX + CIDETCPUCTX.aSRegs + X86_SREG_CS * 2]
226 push xAX
227 push qword [xDX + CIDETCPUCTX.rip]
228
229 ; Restore DS, xAX and xDX then do the iret.
230 mov ds, [xDX + CIDETCPUCTX.aSRegs + X86_SREG_DS * 2]
231 mov xAX, [xDX + CIDETCPUCTX.aGRegs + X86_GREG_xAX * 8]
232 mov xDX, [xDX + CIDETCPUCTX.aGRegs + X86_GREG_xDX * 8]
233 iretq
234%else
235 ; In 32-bit mode iret doesn't restore CS:ESP for us, so we have to
236 ; make a choice whether the SS:ESP is more important than EFLAGS.
237 cmp byte [xDX + CIDETCPUCTX.fTrickyStack], 0
238 jne .tricky_stack
239
240 mov ss, [xDX + CIDETCPUCTX.aSRegs + X86_SREG_SS * 2]
241 mov xSP, [xDX + CIDETCPUCTX.aGRegs + X86_GREG_xSP * 8]
242
243 push dword [xDX + CIDETCPUCTX.rfl] ; iret frame
244 movzx eax, word [xDX + CIDETCPUCTX.aSRegs + X86_SREG_CS * 2] ; iret frame
245 push xAX ; iret frame
246 push dword [xDX + CIDETCPUCTX.rip] ; iret frame
247
248 mov xAX, [xDX + CIDETCPUCTX.aGRegs + X86_GREG_xAX * 8]
249 mov ds, [xDX + CIDETCPUCTX.aSRegs + X86_SREG_DS * 2]
250 mov xDX, [cs:xDX + CIDETCPUCTX.aGRegs + X86_GREG_xDX * 8]
251 iretd
252
253.tricky_stack:
254 mov xAX, [xDX + CIDETCPUCTX.rip]
255 mov [g_uTargetEip], xAX
256 mov ax, [xDX + CIDETCPUCTX.aSRegs + X86_SREG_CS * 2]
257 mov [g_uTargetCs], ax
258 push dword [xDX + CIDETCPUCTX.rfl]
259 popfd
260 mov ss, [xDX + CIDETCPUCTX.aSRegs + X86_SREG_SS * 2]
261 mov xSP, [xDX + CIDETCPUCTX.aGRegs + X86_GREG_xSP * 8]
262 mov xAX, [xDX + CIDETCPUCTX.aGRegs + X86_GREG_xAX * 8]
263 mov ds, [xDX + CIDETCPUCTX.aSRegs + X86_SREG_DS * 2]
264 mov xDX, [cs:xDX + CIDETCPUCTX.aGRegs + X86_GREG_xDX * 8]
265 jmp far [cs:g_uTargetEip]
266%endif
267ENDPROC CidetAppSaveAndRestoreCtx
268
269
270;;
271; C callable version of CidetAppSaveAndRestoreCtx more or less.
272;
273; @param pSaveCtx x86:esp+4 gcc:rdi msc:rcx
274; @param pRestoreCtx x86:esp+8 gcc:rsi msc:rdx
275BEGINPROC CidetAppExecute
276%ifdef RT_ARCH_X86
277 mov ecx, [esp + 4]
278 mov edx, [esp + 8]
279%elifdef ASM_CALL64_GCC
280 mov rcx, rdi
281 mov rdx, rsi
282%elifndef ASM_CALL64_MSC
283 %error "unsupport arch."
284%endif
285 mov word [xCX + CIDETCPUCTX.aSRegs + X86_SREG_DS * 2], ds
286 mov [xCX + CIDETCPUCTX.aGRegs + X86_GREG_xDX * 8], xDX
287 mov [xCX + CIDETCPUCTX.aGRegs + X86_GREG_xCX * 8], xCX
288 jmp NAME(CidetAppSaveAndRestoreCtx)
289ENDPROC CidetAppExecute
290
291
292;;
293; C callable restore function.
294;
295; @param pRestoreCtx x86:esp+4 gcc:rdi msc:rcx
296BEGINPROC CidetAppRestoreCtx
297%ifdef RT_ARCH_X86
298 mov edx, [esp + 4]
299%elifdef ASM_CALL64_GCC
300 mov rdx, rdi
301%elifdef ASM_CALL64_MSC
302 mov rdx, rcx
303%else
304 %error "unsupport arch."
305%endif
306 mov ds, [cs:xDX + CIDETCPUCTX.aSRegs + X86_SREG_DS * 2]
307 jmp NAME(CidetAppSaveAndRestoreCtx_Restore)
308ENDPROC CidetAppRestoreCtx
309
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