VirtualBox

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

Last change on this file since 7821 was 5999, checked in by vboxsync, 17 years ago

The Giant CDDL Dual-License Header Change.

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