VirtualBox

source: vbox/trunk/src/VBox/VMM/VMMGC/CPUMGCA.asm@ 5605

Last change on this file since 5605 was 4071, checked in by vboxsync, 17 years ago

Biggest check-in ever. New source code headers for all (C) innotek files.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 11.7 KB
Line 
1; $Id: CPUMGCA.asm 4071 2007-08-07 17:07:59Z vboxsync $
2;; @file
3;
4; CPUM - Guest Context Assembly Routines.
5
6; Copyright (C) 2006-2007 innotek GmbH
7;
8; This file is part of VirtualBox Open Source Edition (OSE), as
9; available from http://www.virtualbox.org. This file is free software;
10; you can redistribute it and/or modify it under the terms of the GNU
11; General Public License as published by the Free Software Foundation,
12; in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
13; distribution. VirtualBox OSE is distributed in the hope that it will
14; be useful, but WITHOUT ANY WARRANTY of any kind.
15
16;*******************************************************************************
17;* Header Files *
18;*******************************************************************************
19%include "VMMGC.mac"
20%include "VBox/vm.mac"
21%include "VBox/err.mac"
22%include "VBox/stam.mac"
23%include "CPUMInternal.mac"
24%include "VBox/x86.mac"
25%include "VBox/cpum.mac"
26
27
28;*******************************************************************************
29;* External Symbols *
30;*******************************************************************************
31extern IMPNAME(g_CPUM) ; VMM GC Builtin import
32extern IMPNAME(g_VM) ; VMM GC Builtin import
33extern NAME(cpumGCHandleNPAndGP) ; CPUMGC.cpp
34
35;
36; Enables write protection of Hypervisor memory pages.
37; !note! Must be commented out for Trap8 debug handler.
38;
39%define ENABLE_WRITE_PROTECTION 1
40
41BEGINCODE
42
43
44;;
45; Restores GC context before doing iret.
46;
47; @param [esp + 4] Pointer to interrupt stack frame, i.e. pointer
48; to the a struct with this layout:
49; 00h eip
50; 04h cs
51; 08h eflags
52; 0ch esp
53; 10h ss
54; 14h es (V86 only)
55; 18h ds (V86 only)
56; 1Ch fs (V86 only)
57; 20h gs (V86 only)
58;
59; @uses everything but cs, ss, esp, and eflags.
60;
61; @remark Assumes we're restoring in Ring-0 a context which is not Ring-0.
62; Further assumes flat stack and valid ds.
63
64BEGINPROC CPUMGCRestoreInt
65 ;
66 ; Update iret frame.
67 ;
68 mov eax, [esp + 4] ; get argument
69 mov edx, IMP(g_CPUM)
70
71 mov ecx, [edx + CPUM.Guest.eip]
72 mov [eax + 0h], ecx
73 mov ecx, [edx + CPUM.Guest.cs]
74 mov [eax + 4h], ecx
75 mov ecx, [edx + CPUM.Guest.eflags]
76 mov [eax + 8h], ecx
77 mov ecx, [edx + CPUM.Guest.esp]
78 mov [eax + 0ch], ecx
79 mov ecx, [edx + CPUM.Guest.ss]
80 mov [eax + 10h], ecx
81
82 test dword [edx + CPUM.Guest.eflags], X86_EFL_VM
83 jnz short CPUMGCRestoreInt_V86
84
85 ;
86 ; Load registers.
87 ;
88 ; todo: potential trouble loading invalid es,fs,gs,ds because
89 ; of a VMM imposed exception?
90 mov es, [edx + CPUM.Guest.es]
91 mov fs, [edx + CPUM.Guest.fs]
92 mov gs, [edx + CPUM.Guest.gs]
93 mov esi, [edx + CPUM.Guest.esi]
94 mov edi, [edx + CPUM.Guest.edi]
95 mov ebp, [edx + CPUM.Guest.ebp]
96 mov ebx, [edx + CPUM.Guest.ebx]
97 mov ecx, [edx + CPUM.Guest.ecx]
98 mov eax, [edx + CPUM.Guest.eax]
99 push dword [edx + CPUM.Guest.ds]
100 mov edx, [edx + CPUM.Guest.edx]
101 pop ds
102
103 ret
104
105CPUMGCRestoreInt_V86:
106 ; iret restores ds, es, fs & gs
107 mov ecx, [edx + CPUM.Guest.es]
108 mov [eax + 14h], ecx
109 mov ecx, [edx + CPUM.Guest.ds]
110 mov [eax + 18h], ecx
111 mov ecx, [edx + CPUM.Guest.fs]
112 mov [eax + 1Ch], ecx
113 mov ecx, [edx + CPUM.Guest.gs]
114 mov [eax + 20h], ecx
115 mov esi, [edx + CPUM.Guest.esi]
116 mov edi, [edx + CPUM.Guest.edi]
117 mov ebp, [edx + CPUM.Guest.ebp]
118 mov ebx, [edx + CPUM.Guest.ebx]
119 mov ecx, [edx + CPUM.Guest.ecx]
120 mov eax, [edx + CPUM.Guest.eax]
121 mov edx, [edx + CPUM.Guest.edx]
122 ret
123
124ENDPROC CPUMGCRestoreInt
125
126
127;;
128; Calls a guest trap/interrupt handler directly
129; Assumes a trap stack frame has already been setup on the guest's stack!
130;
131; @param pRegFrame [esp + 4] Original trap/interrupt context
132; @param selCS [esp + 8] Code selector of handler
133; @param pHandler [esp + 12] GC virtual address of handler
134; @param eflags [esp + 16] Callee's EFLAGS
135; @param selSS [esp + 20] Stack selector for handler
136; @param pEsp [esp + 24] Stack address for handler
137;
138; @remark This call never returns!
139;
140; CPUMGCDECL(void) CPUMGCCallGuestTrapHandler(PCPUMCTXCORE pRegFrame, uint32_t selCS, RTGCPTR pHandler, uint32_t eflags, uint32_t selSS, RTGCPTR pEsp);
141align 16
142BEGINPROC_EXPORTED CPUMGCCallGuestTrapHandler
143 mov ebp, esp
144
145 ; construct iret stack frame
146 push dword [ebp + 20] ; SS
147 push dword [ebp + 24] ; ESP
148 push dword [ebp + 16] ; EFLAGS
149 push dword [ebp + 8] ; CS
150 push dword [ebp + 12] ; EIP
151
152 ;
153 ; enable WP
154 ;
155%ifdef ENABLE_WRITE_PROTECTION
156 mov eax, cr0
157 or eax, X86_CR0_WRITE_PROTECT
158 mov cr0, eax
159%endif
160
161 ; restore CPU context (all except cs, eip, ss, esp & eflags; which are restored or overwritten by iret)
162 mov ebp, [ebp + 4] ; pRegFrame
163 mov ebx, [ebp + CPUMCTXCORE.ebx]
164 mov ecx, [ebp + CPUMCTXCORE.ecx]
165 mov edx, [ebp + CPUMCTXCORE.edx]
166 mov esi, [ebp + CPUMCTXCORE.esi]
167 mov edi, [ebp + CPUMCTXCORE.edi]
168
169 ;; @todo load segment registers *before* enabling WP.
170 TRPM_NP_GP_HANDLER NAME(cpumGCHandleNPAndGP), CPUM_HANDLER_GS | CPUM_HANDLER_CTXCORE_IN_EBP
171 mov gs, [ebp + CPUMCTXCORE.gs]
172 TRPM_NP_GP_HANDLER NAME(cpumGCHandleNPAndGP), CPUM_HANDLER_FS | CPUM_HANDLER_CTXCORE_IN_EBP
173 mov fs, [ebp + CPUMCTXCORE.fs]
174 TRPM_NP_GP_HANDLER NAME(cpumGCHandleNPAndGP), CPUM_HANDLER_ES | CPUM_HANDLER_CTXCORE_IN_EBP
175 mov es, [ebp + CPUMCTXCORE.es]
176 TRPM_NP_GP_HANDLER NAME(cpumGCHandleNPAndGP), CPUM_HANDLER_DS | CPUM_HANDLER_CTXCORE_IN_EBP
177 mov ds, [ebp + CPUMCTXCORE.ds]
178
179 mov eax, [ebp + CPUMCTXCORE.eax]
180 mov ebp, [ebp + CPUMCTXCORE.ebp]
181
182 TRPM_NP_GP_HANDLER NAME(cpumGCHandleNPAndGP), CPUM_HANDLER_IRET
183 iret
184
185ENDPROC CPUMGCCallGuestTrapHandler
186
187;;
188; Performs an iret to V86 code
189; Assumes a trap stack frame has already been setup on the guest's stack!
190;
191; @param pRegFrame Original trap/interrupt context
192;
193; This function does not return!
194;
195;CPUMGCDECL(void) CPUMGCCallV86Code(PCPUMCTXCORE pRegFrame);
196align 16
197BEGINPROC CPUMGCCallV86Code
198 mov ebp, [esp + 4] ; pRegFrame
199
200 ; construct iret stack frame
201 push dword [ebp + CPUMCTXCORE.gs]
202 push dword [ebp + CPUMCTXCORE.fs]
203 push dword [ebp + CPUMCTXCORE.ds]
204 push dword [ebp + CPUMCTXCORE.es]
205 push dword [ebp + CPUMCTXCORE.ss]
206 push dword [ebp + CPUMCTXCORE.esp]
207 push dword [ebp + CPUMCTXCORE.eflags]
208 push dword [ebp + CPUMCTXCORE.cs]
209 push dword [ebp + CPUMCTXCORE.eip]
210
211 ;
212 ; enable WP
213 ;
214%ifdef ENABLE_WRITE_PROTECTION
215 mov eax, cr0
216 or eax, X86_CR0_WRITE_PROTECT
217 mov cr0, eax
218%endif
219
220 ; restore CPU context (all except cs, eip, ss, esp, eflags, ds, es, fs & gs; which are restored or overwritten by iret)
221 mov eax, [ebp + CPUMCTXCORE.eax]
222 mov ebx, [ebp + CPUMCTXCORE.ebx]
223 mov ecx, [ebp + CPUMCTXCORE.ecx]
224 mov edx, [ebp + CPUMCTXCORE.edx]
225 mov esi, [ebp + CPUMCTXCORE.esi]
226 mov edi, [ebp + CPUMCTXCORE.edi]
227 mov ebp, [ebp + CPUMCTXCORE.ebp]
228
229 TRPM_NP_GP_HANDLER NAME(cpumGCHandleNPAndGP), CPUM_HANDLER_IRET
230 iret
231ENDPROC CPUMGCCallV86Code
232
233;;
234; This is a main entry point for resuming (or starting) guest
235; code execution.
236;
237; We get here directly from VMMSwitcher.asm (jmp at the end
238; of VMMSwitcher_HostToGuest).
239;
240; This call never returns!
241;
242; @param edx Pointer to CPUM structure.
243;
244align 16
245BEGINPROC_EXPORTED CPUMGCResumeGuest
246 ;
247 ; Setup iretd
248 ;
249 push dword [edx + CPUM.Guest.ss]
250 push dword [edx + CPUM.Guest.esp]
251 push dword [edx + CPUM.Guest.eflags]
252 push dword [edx + CPUM.Guest.cs]
253 push dword [edx + CPUM.Guest.eip]
254
255 ;
256 ; Restore registers.
257 ;
258 TRPM_NP_GP_HANDLER NAME(cpumGCHandleNPAndGP), CPUM_HANDLER_ES
259 mov es, [edx + CPUM.Guest.es]
260 TRPM_NP_GP_HANDLER NAME(cpumGCHandleNPAndGP), CPUM_HANDLER_FS
261 mov fs, [edx + CPUM.Guest.fs]
262 TRPM_NP_GP_HANDLER NAME(cpumGCHandleNPAndGP), CPUM_HANDLER_GS
263 mov gs, [edx + CPUM.Guest.gs]
264
265%ifdef VBOX_WITH_STATISTICS
266 ;
267 ; Statistics.
268 ;
269 push edx
270 mov edx, IMP(g_VM)
271 lea edx, [edx + VM.StatTotalQemuToGC]
272 STAM_PROFILE_ADV_STOP edx
273
274 mov edx, IMP(g_VM)
275 lea edx, [edx + VM.StatTotalInGC]
276 STAM_PROFILE_ADV_START edx
277 pop edx
278%endif
279
280 ;
281 ; enable WP
282 ;
283%ifdef ENABLE_WRITE_PROTECTION
284 mov eax, cr0
285 or eax, X86_CR0_WRITE_PROTECT
286 mov cr0, eax
287%endif
288
289 ;
290 ; Continue restore.
291 ;
292 mov esi, [edx + CPUM.Guest.esi]
293 mov edi, [edx + CPUM.Guest.edi]
294 mov ebp, [edx + CPUM.Guest.ebp]
295 mov ebx, [edx + CPUM.Guest.ebx]
296 mov ecx, [edx + CPUM.Guest.ecx]
297 mov eax, [edx + CPUM.Guest.eax]
298 push dword [edx + CPUM.Guest.ds]
299 mov edx, [edx + CPUM.Guest.edx]
300 TRPM_NP_GP_HANDLER NAME(cpumGCHandleNPAndGP), CPUM_HANDLER_DS
301 pop ds
302
303 ; restart execution.
304 TRPM_NP_GP_HANDLER NAME(cpumGCHandleNPAndGP), CPUM_HANDLER_IRET
305 iretd
306ENDPROC CPUMGCResumeGuest
307
308
309;;
310; This is a main entry point for resuming (or starting) guest
311; code execution for raw V86 mode
312;
313; We get here directly from VMMSwitcher.asm (jmp at the end
314; of VMMSwitcher_HostToGuest).
315;
316; This call never returns!
317;
318; @param edx Pointer to CPUM structure.
319;
320align 16
321BEGINPROC_EXPORTED CPUMGCResumeGuestV86
322 ;
323 ; Setup iretd
324 ;
325 push dword [edx + CPUM.Guest.gs]
326 push dword [edx + CPUM.Guest.fs]
327 push dword [edx + CPUM.Guest.ds]
328 push dword [edx + CPUM.Guest.es]
329
330 push dword [edx + CPUM.Guest.ss]
331 push dword [edx + CPUM.Guest.esp]
332
333 push dword [edx + CPUM.Guest.eflags]
334 push dword [edx + CPUM.Guest.cs]
335 push dword [edx + CPUM.Guest.eip]
336
337 ;
338 ; Restore registers.
339 ;
340
341%ifdef VBOX_WITH_STATISTICS
342 ;
343 ; Statistics.
344 ;
345 push edx
346 mov edx, IMP(g_VM)
347 lea edx, [edx + VM.StatTotalQemuToGC]
348 STAM_PROFILE_ADV_STOP edx
349
350 mov edx, IMP(g_VM)
351 lea edx, [edx + VM.StatTotalInGC]
352 STAM_PROFILE_ADV_START edx
353 pop edx
354%endif
355
356 ;
357 ; enable WP
358 ;
359%ifdef ENABLE_WRITE_PROTECTION
360 mov eax, cr0
361 or eax, X86_CR0_WRITE_PROTECT
362 mov cr0, eax
363%endif
364
365 ;
366 ; Continue restore.
367 ;
368 mov esi, [edx + CPUM.Guest.esi]
369 mov edi, [edx + CPUM.Guest.edi]
370 mov ebp, [edx + CPUM.Guest.ebp]
371 mov ecx, [edx + CPUM.Guest.ecx]
372 mov ebx, [edx + CPUM.Guest.ebx]
373 mov eax, [edx + CPUM.Guest.eax]
374 mov edx, [edx + CPUM.Guest.edx]
375
376 ; restart execution.
377 TRPM_NP_GP_HANDLER NAME(cpumGCHandleNPAndGP), CPUM_HANDLER_IRET
378 iretd
379ENDPROC CPUMGCResumeGuestV86
380
381
382;;
383; Set the Guest CPU CR2 register.
384;
385; @param eax cr2
386; @uses edx
387;
388align 16
389BEGINPROC CPUMGCSetGuestCR2Asm
390 mov edx, IMP(g_CPUM)
391 mov [edx + CPUM.Guest.cr2], eax
392 ret
393ENDPROC CPUMGCSetGuestCR2Asm
394
395
396;;
397; Get the Guest CPU CR0 register.
398;
399; @returns cr0 in eax
400; @uses eax
401;
402align 16
403BEGINPROC CPUMGCGetGuestCR0
404 mov eax, IMP(g_CPUM)
405 mov eax, [eax + CPUM.Guest.cr0]
406 ret
407ENDPROC CPUMGCGetGuestCR0
408
409
410
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