VirtualBox

source: vbox/trunk/src/VBox/VMM/VMMGC/TRPMGCHandlersA.asm@ 9363

Last change on this file since 9363 was 9300, checked in by vboxsync, 17 years ago

More 64 bits guest ptr fixes

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 42.1 KB
Line 
1; $Id: TRPMGCHandlersA.asm 9300 2008-06-02 13:30:12Z vboxsync $
2;; @file
3; TRPM - Guest Context Trap Handlers
4;
5
6; Copyright (C) 2006-2007 Sun Microsystems, Inc.
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; Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
17; Clara, CA 95054 USA or visit http://www.sun.com if you need
18; additional information or have any questions.
19;
20
21;*******************************************************************************
22;* Header Files *
23;*******************************************************************************
24%include "VMMGC.mac"
25%include "VBox/x86.mac"
26%include "VBox/cpum.mac"
27%include "VBox/stam.mac"
28%include "VBox/vm.mac"
29%include "TRPMInternal.mac"
30%include "VBox/err.mac"
31%include "VBox/trpm.mac"
32
33
34;*******************************************************************************
35;* External Symbols *
36;*******************************************************************************
37extern IMPNAME(g_CPUM) ; These IMPNAME(g_*) symbols resolve to the import table
38extern IMPNAME(g_TRPM) ; where there is a pointer to the real symbol. PE imports
39extern IMPNAME(g_VM) ; are a bit confusing at first... :-)
40extern NAME(CPUMGCRestoreInt)
41extern NAME(CPUMHandleLazyFPUAsm)
42extern NAME(CPUMHyperSetCtxCore)
43extern NAME(trpmGCTrapInGeneric)
44extern NAME(TRPMGCHyperTrap0bHandler)
45extern NAME(TRPMGCHyperTrap0dHandler)
46extern NAME(TRPMGCHyperTrap0eHandler)
47extern NAME(TRPMGCTrap01Handler)
48%ifdef VBOX_WITH_NMI
49extern NAME(TRPMGCTrap02Handler)
50%endif
51extern NAME(TRPMGCTrap03Handler)
52extern NAME(TRPMGCTrap06Handler)
53extern NAME(TRPMGCTrap0bHandler)
54extern NAME(TRPMGCTrap0dHandler)
55extern NAME(TRPMGCTrap0eHandler)
56extern NAME(TRPMGCTrap07Handler)
57
58;; IMPORTANT all COM_ functions trashes esi, some edi and the LOOP_SHORT_WHILE kills ecx.
59;%define DEBUG_STUFF 1
60;%define DEBUG_STUFF_TRPG 1
61;%define DEBUG_STUFF_INT 1
62
63BEGINCODE
64
65;;
66; Jump table for trap handlers for hypervisor traps.
67;
68g_apfnStaticTrapHandlersHyper:
69 ; N - M M - T - C - D i
70 ; o - n o - y - o - e p
71 ; - e n - p - d - s t
72 ; - i - e - e - c .
73 ; - c - - - r
74 ; =============================================================
75 dd 0 ; 0 - #DE - F - N - Divide error
76 dd NAME(TRPMGCTrap01Handler) ; 1 - #DB - F/T - N - Single step, INT 1 instruction
77%ifdef VBOX_WITH_NMI
78 dd NAME(TRPMGCTrap02Handler) ; 2 - - I - N - Non-Maskable Interrupt (NMI)
79%else
80 dd 0 ; 2 - - I - N - Non-Maskable Interrupt (NMI)
81%endif
82 dd NAME(TRPMGCTrap03Handler) ; 3 - #BP - T - N - Breakpoint, INT 3 instruction.
83 dd 0 ; 4 - #OF - T - N - Overflow, INTO instruction.
84 dd 0 ; 5 - #BR - F - N - BOUND Range Exceeded, BOUND instruction.
85 dd 0 ; 6 - #UD - F - N - Undefined(/Invalid) Opcode.
86 dd 0 ; 7 - #NM - F - N - Device not available, FP or (F)WAIT instruction.
87 dd 0 ; 8 - #DF - A - 0 - Double fault.
88 dd 0 ; 9 - - F - N - Coprocessor Segment Overrun (obsolete).
89 dd 0 ; a - #TS - F - Y - Invalid TSS, Taskswitch or TSS access.
90 dd NAME(TRPMGCHyperTrap0bHandler) ; b - #NP - F - Y - Segment not present.
91 dd 0 ; c - #SS - F - Y - Stack-Segment fault.
92 dd NAME(TRPMGCHyperTrap0dHandler) ; d - #GP - F - Y - General protection fault.
93 dd NAME(TRPMGCHyperTrap0eHandler) ; e - #PF - F - Y - Page fault.
94 dd 0 ; f - - - - Intel Reserved. Do not use.
95 dd 0 ; 10 - #MF - F - N - x86 FPU Floating-Point Error (Math fault), FP or (F)WAIT instruction.
96 dd 0 ; 11 - #AC - F - 0 - Alignment Check.
97 dd 0 ; 12 - #MC - A - N - Machine Check.
98 dd 0 ; 13 - #XF - F - N - SIMD Floating-Point Exception.
99 dd 0 ; 14 - - - - Intel Reserved. Do not use.
100 dd 0 ; 15 - - - - Intel Reserved. Do not use.
101 dd 0 ; 16 - - - - Intel Reserved. Do not use.
102 dd 0 ; 17 - - - - Intel Reserved. Do not use.
103 dd 0 ; 18 - - - - Intel Reserved. Do not use.
104
105
106;;
107; Jump table for trap handlers for guest traps
108;
109g_apfnStaticTrapHandlersGuest:
110 ; N - M M - T - C - D i
111 ; o - n o - y - o - e p
112 ; - e n - p - d - s t
113 ; - i - e - e - c .
114 ; - c - - - r
115 ; =============================================================
116 dd 0 ; 0 - #DE - F - N - Divide error
117 dd NAME(TRPMGCTrap01Handler) ; 1 - #DB - F/T - N - Single step, INT 1 instruction
118%ifdef VBOX_WITH_NMI
119 dd NAME(TRPMGCTrap02Handler) ; 2 - - I - N - Non-Maskable Interrupt (NMI)
120%else
121 dd 0 ; 2 - - I - N - Non-Maskable Interrupt (NMI)
122%endif
123 dd NAME(TRPMGCTrap03Handler) ; 3 - #BP - T - N - Breakpoint, INT 3 instruction.
124 dd 0 ; 4 - #OF - T - N - Overflow, INTO instruction.
125 dd 0 ; 5 - #BR - F - N - BOUND Range Exceeded, BOUND instruction.
126 dd NAME(TRPMGCTrap06Handler) ; 6 - #UD - F - N - Undefined(/Invalid) Opcode.
127 dd NAME(TRPMGCTrap07Handler) ; 7 - #NM - F - N - Device not available, FP or (F)WAIT instruction.
128 dd 0 ; 8 - #DF - A - 0 - Double fault.
129 dd 0 ; 9 - - F - N - Coprocessor Segment Overrun (obsolete).
130 dd 0 ; a - #TS - F - Y - Invalid TSS, Taskswitch or TSS access.
131 dd NAME(TRPMGCTrap0bHandler) ; b - #NP - F - Y - Segment not present.
132 dd 0 ; c - #SS - F - Y - Stack-Segment fault.
133 dd NAME(TRPMGCTrap0dHandler) ; d - #GP - F - Y - General protection fault.
134 dd NAME(TRPMGCTrap0eHandler) ; e - #PF - F - Y - Page fault.
135 dd 0 ; f - - - - Intel Reserved. Do not use.
136 dd 0 ; 10 - #MF - F - N - x86 FPU Floating-Point Error (Math fault), FP or (F)WAIT instruction.
137 dd 0 ; 11 - #AC - F - 0 - Alignment Check.
138 dd 0 ; 12 - #MC - A - N - Machine Check.
139 dd 0 ; 13 - #XF - F - N - SIMD Floating-Point Exception.
140 dd 0 ; 14 - - - - Intel Reserved. Do not use.
141 dd 0 ; 15 - - - - Intel Reserved. Do not use.
142 dd 0 ; 16 - - - - Intel Reserved. Do not use.
143 dd 0 ; 17 - - - - Intel Reserved. Do not use.
144 dd 0 ; 18 - - - - Intel Reserved. Do not use.
145
146
147
148;;
149; We start by 24 push <vector no.> + jmp <generic entry point>
150;
151ALIGNCODE(16)
152BEGINPROC_EXPORTED TRPMGCHandlerGeneric
153%macro TRPMGenericEntry 1
154 db 06ah, i ; push imm8 - note that this is a signextended value.
155 jmp %1
156 ALIGNCODE(8)
157%assign i i+1
158%endmacro
159
160%assign i 0 ; start counter.
161 TRPMGenericEntry GenericTrap ; 0
162 TRPMGenericEntry GenericTrap ; 1
163 TRPMGenericEntry GenericTrap ; 2
164 TRPMGenericEntry GenericTrap ; 3
165 TRPMGenericEntry GenericTrap ; 4
166 TRPMGenericEntry GenericTrap ; 5
167 TRPMGenericEntry GenericTrap ; 6
168 TRPMGenericEntry GenericTrap ; 7
169 TRPMGenericEntry GenericTrapErrCode ; 8
170 TRPMGenericEntry GenericTrap ; 9
171 TRPMGenericEntry GenericTrapErrCode ; a
172 TRPMGenericEntry GenericTrapErrCode ; b
173 TRPMGenericEntry GenericTrapErrCode ; c
174 TRPMGenericEntry GenericTrapErrCode ; d
175 TRPMGenericEntry GenericTrapErrCode ; e
176 TRPMGenericEntry GenericTrap ; f (reserved)
177 TRPMGenericEntry GenericTrap ; 10
178 TRPMGenericEntry GenericTrapErrCode ; 11
179 TRPMGenericEntry GenericTrap ; 12
180 TRPMGenericEntry GenericTrap ; 13
181 TRPMGenericEntry GenericTrap ; 14 (reserved)
182 TRPMGenericEntry GenericTrap ; 15 (reserved)
183 TRPMGenericEntry GenericTrap ; 16 (reserved)
184 TRPMGenericEntry GenericTrap ; 17 (reserved)
185%undef i
186%undef TRPMGenericEntry
187
188;;
189; Main exception handler for the guest context
190;
191; Stack:
192; 14 SS
193; 10 ESP
194; c EFLAGS
195; 8 CS
196; 4 EIP
197; 0 vector number
198;
199; @uses none
200;
201ALIGNCODE(8)
202GenericTrap:
203 ;
204 ; for the present we fake an error code ~0
205 ;
206 push eax
207 mov eax, 0ffffffffh
208 xchg [esp + 4], eax ; get vector number, set error code
209 xchg [esp], eax ; get saved eax, set vector number
210 jmp short GenericTrapErrCode
211
212
213;;
214; Main exception handler for the guest context with error code
215;
216; Stack:
217; 28 GS (V86 only)
218; 24 FS (V86 only)
219; 20 DS (V86 only)
220; 1C ES (V86 only)
221; 18 SS (only if ring transition.)
222; 14 ESP (only if ring transition.)
223; 10 EFLAGS
224; c CS
225; 8 EIP
226; 4 Error code. (~0 for vectors which don't take an error code.)
227; 0 vector number
228;
229; Error code:
230;
231; 31 16 15 3 2 1 0
232;
233; reserved segment TI IDT EXT
234; selector GDT/LDT (1) IDT External interrupt
235; index (IDT=0) index
236;
237; NOTE: Page faults (trap 14) have a different error code
238;
239; @uses none
240;
241ALIGNCODE(8)
242GenericTrapErrCode:
243 cld
244
245 ;
246 ; Setup CPUMCTXCORE frame
247 ;
248 ; ASSUMPTION: If trap in hypervisor, we assume that we can read two dword
249 ; under the bottom of the stack. This is atm safe.
250 ; ASSUMPTION: There is sufficient stack space.
251 ; ASSUMPTION: The stack is not write protected.
252 ;
253%define ESPOFF CPUMCTXCORE_size
254
255 sub esp, CPUMCTXCORE_size
256 mov [esp + CPUMCTXCORE.eax], eax
257 mov [esp + CPUMCTXCORE.ecx], ecx
258 mov [esp + CPUMCTXCORE.edx], edx
259 mov [esp + CPUMCTXCORE.ebx], ebx
260 mov [esp + CPUMCTXCORE.esi], esi
261 mov [esp + CPUMCTXCORE.edi], edi
262 mov [esp + CPUMCTXCORE.ebp], ebp
263
264 mov eax, [esp + 14h + ESPOFF] ; esp
265 mov [esp + CPUMCTXCORE.esp], eax
266 mov eax, [esp + 18h + ESPOFF] ; ss
267 mov dword [esp + CPUMCTXCORE.ss], eax
268
269 mov eax, [esp + 0ch + ESPOFF] ; cs
270 mov dword [esp + CPUMCTXCORE.cs], eax
271 mov eax, [esp + 08h + ESPOFF] ; eip
272 mov [esp + CPUMCTXCORE.eip], eax
273 mov eax, [esp + 10h + ESPOFF] ; eflags
274 mov [esp + CPUMCTXCORE.eflags], eax
275
276 mov eax, es
277 mov dword [esp + CPUMCTXCORE.es], eax
278 mov eax, ds
279 mov dword [esp + CPUMCTXCORE.ds], eax
280 mov eax, fs
281 mov dword [esp + CPUMCTXCORE.fs], eax
282 mov eax, gs
283 mov dword [esp + CPUMCTXCORE.gs], eax
284
285 test dword [esp + CPUMCTXCORE.eflags], X86_EFL_VM
286 jz short gt_SkipV86Entry
287
288 ;
289 ; The DS, ES, FS and GS registers are zeroed in V86 mode and their real values are on the stack
290 ;
291 mov eax, dword [esp + ESPOFF + 1Ch]
292 mov dword [esp + CPUMCTXCORE.es], eax
293
294 mov eax, dword [esp + ESPOFF + 20h]
295 mov dword [esp + CPUMCTXCORE.ds], eax
296
297 mov eax, dword [esp + ESPOFF + 24h]
298 mov dword [esp + CPUMCTXCORE.fs], eax
299
300 mov eax, dword [esp + ESPOFF + 28h]
301 mov dword [esp + CPUMCTXCORE.gs], eax
302
303gt_SkipV86Entry:
304 ;
305 ; Disable Ring-0 WP
306 ;
307 mov eax, cr0 ;; @todo elimitate this read?
308 and eax, ~X86_CR0_WRITE_PROTECT
309 mov cr0, eax
310
311 ;
312 ; Load Hypervisor DS and ES (get it from the SS)
313 ;
314 mov eax, ss
315 mov ds, eax
316 mov es, eax
317
318%ifdef VBOX_WITH_STATISTICS
319 ;
320 ; Start profiling.
321 ;
322 mov edx, [esp + 0h + ESPOFF] ; vector number
323 imul edx, edx, byte STAMPROFILEADV_size ; assumes < 128.
324 add edx, TRPM.aStatGCTraps
325 add edx, IMP(g_TRPM)
326 STAM_PROFILE_ADV_START edx
327%endif
328
329 ;
330 ; Store the information about the active trap/interrupt.
331 ;
332 mov eax, IMP(g_TRPM)
333 movzx edx, byte [esp + 0h + ESPOFF] ; vector number
334 mov [eax + TRPM.uActiveVector], edx
335 mov edx, [esp + 4h + ESPOFF] ; error code
336 mov [eax + TRPM.uActiveErrorCode], edx
337 mov dword [eax + TRPM.enmActiveType], TRPM_TRAP
338 mov edx, cr2 ;; @todo Check how expensive cr2 reads are!
339 mov dword [eax + TRPM.uActiveCR2], edx
340
341%if GC_ARCH_BITS == 64
342 ; zero out the high dword
343 mov dword [eax + TRPM.uActiveErrorCode + 4], 0
344 mov dword [eax + TRPM.uActiveCR2 + 4], 0
345%endif
346
347 ;
348 ; Check if we're in Hypervisor when this happend.
349 ;
350 test dword [esp + CPUMCTXCORE.eflags], X86_EFL_VM
351 jnz short gt_NotHyperVisor
352
353 test byte [esp + 0ch + ESPOFF], 3h ; check CPL of the cs selector
354 jz near gt_InHypervisor
355
356 ;
357 ; Trap in guest code.
358 ;
359gt_NotHyperVisor:
360%ifdef DEBUG_STUFF_TRPG
361 mov ebx, [esp + 4h + ESPOFF] ; error code
362 mov ecx, 'trpG' ; indicate trap.
363 mov edx, [esp + 0h + ESPOFF] ; vector number
364 lea eax, [esp]
365 call trpmDbgDumpRegisterFrame
366%endif
367
368 ;
369 ; Do we have a GC handler for these traps?
370 ;
371 mov edx, [esp + 0h + ESPOFF] ; vector number
372 mov eax, [g_apfnStaticTrapHandlersGuest + edx * 4]
373 or eax, eax
374 jnz short gt_HaveHandler
375 mov eax, VINF_EM_RAW_GUEST_TRAP
376 jmp short gt_GuestTrap
377
378 ;
379 ; Call static handler.
380 ;
381gt_HaveHandler:
382 push esp ; Param 2 - CPUMCTXCORE pointer.
383 push dword IMP(g_TRPM) ; Param 1 - Pointer to TRPM
384 call eax
385 add esp, byte 8 ; cleanup stack (cdecl)
386 or eax, eax
387 je near gt_continue_guest
388
389 ;
390 ; Switch back to the host and process it there.
391 ;
392gt_GuestTrap:
393%ifdef VBOX_WITH_STATISTICS
394 mov edx, [esp + 0h + ESPOFF] ; vector number
395 imul edx, edx, byte STAMPROFILEADV_size ; assume < 128
396 add edx, IMP(g_TRPM)
397 add edx, TRPM.aStatGCTraps
398 STAM_PROFILE_ADV_STOP edx
399%endif
400 mov edx, IMP(g_VM)
401 call [edx + VM.pfnVMMGCGuestToHostAsmGuestCtx]
402
403 ;; @todo r=bird: is this path actually every taken? if not we should replace this code with a panic.
404 ;
405 ; We've returned!
406 ; N.B. The stack has been changed now! No CPUMCTXCORE any longer. esp = vector number.
407 ; N.B. Current scheduling design causes this code path to be unused.
408 ; N.B. Better not use it when in V86 mode!
409 ;
410
411 ; Enable WP
412 mov eax, cr0 ;; @todo try elimiate this read.
413 or eax, X86_CR0_WRITE_PROTECT
414 mov cr0, eax
415 ; Restore guest context and continue execution.
416 mov edx, IMP(g_CPUM)
417 lea eax, [esp + 8]
418 push eax
419 call NAME(CPUMGCRestoreInt)
420 lea esp, [esp + 0ch] ; cleanup call and skip vector & error code.
421
422 iret
423
424
425 ;
426 ; Continue(/Resume/Restart/Whatever) guest execution.
427 ;
428ALIGNCODE(16)
429gt_continue_guest:
430%ifdef VBOX_WITH_STATISTICS
431 mov edx, [esp + 0h + ESPOFF] ; vector number
432 imul edx, edx, byte STAMPROFILEADV_size ; assumes < 128
433 add edx, TRPM.aStatGCTraps
434 add edx, IMP(g_TRPM)
435 STAM_PROFILE_ADV_STOP edx
436%endif
437
438 ; enable WP
439 mov eax, cr0 ;; @todo try elimiate this read.
440 or eax, X86_CR0_WRITE_PROTECT
441 mov cr0, eax
442
443 ; restore guest state and start executing again.
444 test dword [esp + CPUMCTXCORE.eflags], X86_EFL_VM
445 jnz gt_V86Return
446
447 mov ecx, [esp + CPUMCTXCORE.ecx]
448 mov edx, [esp + CPUMCTXCORE.edx]
449 mov ebx, [esp + CPUMCTXCORE.ebx]
450 mov ebp, [esp + CPUMCTXCORE.ebp]
451 mov esi, [esp + CPUMCTXCORE.esi]
452 mov edi, [esp + CPUMCTXCORE.edi]
453
454 mov eax, [esp + CPUMCTXCORE.esp]
455 mov [esp + 14h + ESPOFF], eax ; esp
456 mov eax, dword [esp + CPUMCTXCORE.ss]
457 mov [esp + 18h + ESPOFF], eax ; ss
458
459 mov eax, dword [esp + CPUMCTXCORE.gs]
460 TRPM_NP_GP_HANDLER NAME(trpmGCTrapInGeneric), TRPM_TRAP_IN_MOV_GS
461 mov gs, eax
462
463 mov eax, dword [esp + CPUMCTXCORE.fs]
464 TRPM_NP_GP_HANDLER NAME(trpmGCTrapInGeneric), TRPM_TRAP_IN_MOV_FS
465 mov fs, eax
466
467 mov eax, dword [esp + CPUMCTXCORE.es]
468 TRPM_NP_GP_HANDLER NAME(trpmGCTrapInGeneric), TRPM_TRAP_IN_MOV_ES
469 mov es, eax
470
471 mov eax, dword [esp + CPUMCTXCORE.ds]
472 TRPM_NP_GP_HANDLER NAME(trpmGCTrapInGeneric), TRPM_TRAP_IN_MOV_DS
473 mov ds, eax
474
475 mov eax, dword [esp + CPUMCTXCORE.cs]
476 mov [esp + 0ch + ESPOFF], eax ; cs
477 mov eax, [esp + CPUMCTXCORE.eflags]
478 mov [esp + 10h + ESPOFF], eax ; eflags
479 mov eax, [esp + CPUMCTXCORE.eip]
480 mov [esp + 08h + ESPOFF], eax ; eip
481
482 ; finally restore our scratch register eax
483 mov eax, [esp + CPUMCTXCORE.eax]
484
485 add esp, ESPOFF + 8 ; skip CPUMCTXCORE structure, error code and vector number
486
487 TRPM_NP_GP_HANDLER NAME(trpmGCTrapInGeneric), TRPM_TRAP_IN_IRET
488 iret
489
490ALIGNCODE(16)
491gt_V86Return:
492 mov ecx, [esp + CPUMCTXCORE.ecx]
493 mov edx, [esp + CPUMCTXCORE.edx]
494 mov ebx, [esp + CPUMCTXCORE.ebx]
495 mov ebp, [esp + CPUMCTXCORE.ebp]
496 mov esi, [esp + CPUMCTXCORE.esi]
497 mov edi, [esp + CPUMCTXCORE.edi]
498
499 mov eax, [esp + CPUMCTXCORE.esp]
500 mov [esp + 14h + ESPOFF], eax ; esp
501 mov eax, dword [esp + CPUMCTXCORE.ss]
502 mov [esp + 18h + ESPOFF], eax ; ss
503
504 mov eax, dword [esp + CPUMCTXCORE.es]
505 mov [esp + 1ch + ESPOFF], eax ; es
506 mov eax, dword [esp + CPUMCTXCORE.ds]
507 mov [esp + 20h + ESPOFF], eax ; ds
508 mov eax, dword [esp + CPUMCTXCORE.fs]
509 mov [esp + 24h + ESPOFF], eax ; fs
510 mov eax, dword [esp + CPUMCTXCORE.gs]
511 mov [esp + 28h + ESPOFF], eax ; gs
512
513 mov eax, [esp + CPUMCTXCORE.eip]
514 mov [esp + 08h + ESPOFF], eax ; eip
515 mov eax, dword [esp + CPUMCTXCORE.cs]
516 mov [esp + 0ch + ESPOFF], eax ; cs
517 mov eax, [esp + CPUMCTXCORE.eflags]
518 mov [esp + 10h + ESPOFF], eax ; eflags
519
520 ; finally restore our scratch register eax
521 mov eax, [esp + CPUMCTXCORE.eax]
522
523 add esp, ESPOFF + 8 ; skip CPUMCTXCORE structure, error code and vector number
524
525 TRPM_NP_GP_HANDLER NAME(trpmGCTrapInGeneric), TRPM_TRAP_IN_IRET | TRPM_TRAP_IN_V86
526 iret
527
528 ;
529 ; Trap in Hypervisor, try to handle it.
530 ;
531 ; (eax = pTRPM)
532 ;
533ALIGNCODE(16)
534gt_InHypervisor:
535 ; fix ss:esp.
536 lea ebx, [esp + 14h + ESPOFF] ; calc esp at trap
537 mov [esp + CPUMCTXCORE.esp], ebx; update esp in register frame
538 mov [esp + CPUMCTXCORE.ss], ss ; update ss in register frame
539
540 ; tell cpum about the context core.
541 xchg esi, eax ; save pTRPM - @todo reallocate this variable to esi, edi, or ebx
542 push esp ; Param 2 - The new CPUMCTXCORE pointer.
543 push IMP(g_VM) ; Param 1 - Pointer to the VM.
544 call NAME(CPUMHyperSetCtxCore)
545 add esp, byte 8 ; stack cleanup (cdecl)
546 xchg eax, esi ; restore pTRPM
547
548 ; check for temporary handler.
549 movzx ebx, byte [eax + TRPM.uActiveVector]
550 xor ecx, ecx
551 xchg ecx, [eax + TRPM.aTmpTrapHandlers + ebx * 4] ; ecx = Temp handler pointer or 0
552 or ecx, ecx
553 jnz short gt_Hyper_HaveTemporaryHandler
554
555 ; check for static trap handler.
556 mov ecx, [g_apfnStaticTrapHandlersHyper + ebx * 4] ; ecx = Static handler pointer or 0
557 or ecx, ecx
558 jnz short gt_Hyper_HaveStaticHandler
559 jmp gt_Hyper_AbandonShip
560
561
562 ;
563 ; Temporary trap handler present, call it (CDECL).
564 ;
565gt_Hyper_HaveTemporaryHandler:
566 push esp ; Param 2 - Pointer to CPUMCTXCORE.
567 push IMP(g_VM) ; Param 1 - Pointer to VM.
568 call ecx
569 add esp, byte 8 ; cleanup stack (cdecl)
570
571 cmp eax, byte VINF_SUCCESS ; If completely handled Then resume execution.
572 je near gt_Hyper_Continue
573 ;; @todo Handle ALL returns types from temporary handlers!
574 jmp gt_Hyper_AbandonShip
575
576
577 ;
578 ; Static trap handler present, call it (CDECL).
579 ;
580gt_Hyper_HaveStaticHandler:
581 push esp ; Param 2 - Pointer to CPUMCTXCORE.
582 push eax ; Param 1 - Pointer to TRPM
583 call ecx
584 add esp, byte 8 ; cleanup stack (cdecl)
585
586 cmp eax, byte VINF_SUCCESS ; If completely handled Then resume execution.
587 je short gt_Hyper_Continue
588 cmp eax, VINF_EM_DBG_HYPER_STEPPED
589 je short gt_Hyper_ToHost
590 cmp eax, VINF_EM_DBG_HYPER_BREAKPOINT
591 je short gt_Hyper_ToHost
592 cmp eax, VINF_EM_DBG_HYPER_ASSERTION
593 je short gt_Hyper_ToHost
594 jmp gt_Hyper_AbandonShip
595
596 ;
597 ; Pop back to the host to service the error.
598 ;
599gt_Hyper_ToHost:
600 mov ecx, esp
601 mov edx, IMP(g_VM)
602 call [edx + VM.pfnVMMGCGuestToHostAsm]
603 jmp short gt_Hyper_Continue
604
605 ;
606 ; Continue(/Resume/Restart/Whatever) hypervisor execution.
607 ; Don't reset the TRPM state. Caller takes care of that.
608 ;
609ALIGNCODE(16)
610gt_Hyper_Continue:
611%ifdef DEBUG_STUFF
612 mov ebx, [esp + 4h + ESPOFF] ; error code
613 mov ecx, 'resH' ; indicate trap.
614 mov edx, [esp + 0h + ESPOFF] ; vector number
615 lea eax, [esp]
616 call trpmDbgDumpRegisterFrame
617%endif
618 ; tell CPUM to use the default CPUMCTXCORE.
619 push byte 0 ; Param 2 - NULL indicating use default context core.
620 push IMP(g_VM) ; Param 1 - The VM pointer.
621 call NAME(CPUMHyperSetCtxCore)
622 add esp, byte 8 ; stack cleanup (cdecl)
623
624%ifdef VBOX_WITH_STATISTICS
625 mov edx, [esp + 0h + ESPOFF] ; vector number
626 imul edx, edx, byte STAMPROFILEADV_size ; assumes < 128
627 add edx, TRPM.aStatGCTraps
628 add edx, IMP(g_TRPM)
629 STAM_PROFILE_ADV_STOP edx
630%endif
631
632 ; restore
633 mov ecx, [esp + CPUMCTXCORE.ecx]
634 mov edx, [esp + CPUMCTXCORE.edx]
635 mov ebx, [esp + CPUMCTXCORE.ebx]
636 mov ebp, [esp + CPUMCTXCORE.ebp]
637 mov esi, [esp + CPUMCTXCORE.esi]
638 mov edi, [esp + CPUMCTXCORE.edi]
639
640 mov eax, dword [esp + CPUMCTXCORE.gs]
641 TRPM_NP_GP_HANDLER NAME(trpmGCTrapInGeneric), TRPM_TRAP_IN_MOV_GS | TRPM_TRAP_IN_HYPER
642 mov gs, eax
643
644 mov eax, dword [esp + CPUMCTXCORE.fs]
645 TRPM_NP_GP_HANDLER NAME(trpmGCTrapInGeneric), TRPM_TRAP_IN_MOV_FS | TRPM_TRAP_IN_HYPER
646 mov fs, eax
647
648 mov eax, dword [esp + CPUMCTXCORE.es]
649 mov es, eax
650 mov eax, dword [esp + CPUMCTXCORE.ds]
651 mov ds, eax
652
653 ; skip esp & ss
654
655 mov eax, [esp + CPUMCTXCORE.eip]
656 mov [esp + 08h + ESPOFF], eax ; eip
657 mov eax, dword [esp + CPUMCTXCORE.cs]
658 mov [esp + 0ch + ESPOFF], eax ; cs
659 mov eax, [esp + CPUMCTXCORE.eflags]
660 mov [esp + 10h + ESPOFF], eax ; eflags
661
662 ; finally restore our scratch register eax
663 mov eax, [esp + CPUMCTXCORE.eax]
664
665 add esp, ESPOFF + 8 ; skip CPUMCTXCORE structure, error code and vector number
666
667 iret
668
669
670 ;
671 ; ABANDON SHIP! DON'T PANIC!
672 ;
673gt_Hyper_AbandonShip:
674%ifdef DEBUG_STUFF
675 mov ebx, [esp + 4h + ESPOFF] ; error code
676 mov ecx, 'trpH' ; indicate trap.
677 mov edx, [esp + 0h + ESPOFF] ; vector number
678 lea eax, [esp]
679 call trpmDbgDumpRegisterFrame
680%endif
681
682gt_Hyper_DontPanic:
683 mov ecx, esp
684 mov edx, IMP(g_VM)
685 mov eax, VERR_TRPM_DONT_PANIC
686 call [edx + VM.pfnVMMGCGuestToHostAsmHyperCtx]
687%ifdef DEBUG_STUFF
688 COM_S_PRINT 'bad!!!'
689%endif
690 jmp gt_Hyper_DontPanic ; this shall never ever happen!
691%undef ESPOFF
692ENDPROC TRPMGCHandlerGeneric
693
694
695
696
697
698;;
699; We start by 256 push <vector no.> + jmp interruptworker
700;
701ALIGNCODE(16)
702BEGINPROC_EXPORTED TRPMGCHandlerInterupt
703 ; NASM has some nice features, here an example of a loop.
704%assign i 0
705%rep 256
706 db 06ah, i ; push imm8 - note that this is a signextended value.
707 jmp ti_GenericInterrupt
708 ALIGNCODE(8)
709%assign i i+1
710%endrep
711
712;;
713; Main interrupt handler for the guest context
714;
715; Stack:
716; 24 GS (V86 only)
717; 20 FS (V86 only)
718; 1C DS (V86 only)
719; 18 ES (V86 only)
720; 14 SS
721; 10 ESP
722; c EFLAGS
723; 8 CS
724; 4 EIP
725; ESP -> 0 Vector number (only use low byte!).
726;
727; @uses none
728ti_GenericInterrupt:
729 cld
730
731 ;
732 ; Setup CPUMCTXCORE frame
733 ;
734 ; ASSUMPTION: If trap in hypervisor, we assume that we can read two dword
735 ; under the bottom of the stack. This is atm safe.
736 ; ASSUMPTION: There is sufficient stack space.
737 ; ASSUMPTION: The stack is not write protected.
738 ;
739%define ESPOFF CPUMCTXCORE_size
740
741 sub esp, CPUMCTXCORE_size
742 mov [esp + CPUMCTXCORE.eax], eax
743 mov [esp + CPUMCTXCORE.ecx], ecx
744 mov [esp + CPUMCTXCORE.edx], edx
745 mov [esp + CPUMCTXCORE.ebx], ebx
746 mov [esp + CPUMCTXCORE.esi], esi
747 mov [esp + CPUMCTXCORE.edi], edi
748 mov [esp + CPUMCTXCORE.ebp], ebp
749
750 mov eax, [esp + 04h + ESPOFF] ; eip
751 mov [esp + CPUMCTXCORE.eip], eax
752 mov eax, dword [esp + 08h + ESPOFF] ; cs
753 mov [esp + CPUMCTXCORE.cs], eax
754 mov eax, [esp + 0ch + ESPOFF] ; eflags
755 mov [esp + CPUMCTXCORE.eflags], eax
756
757 mov eax, [esp + 10h + ESPOFF] ; esp
758 mov [esp + CPUMCTXCORE.esp], eax
759 mov eax, dword [esp + 14h + ESPOFF] ; ss
760 mov [esp + CPUMCTXCORE.ss], eax
761
762 mov eax, es
763 mov dword [esp + CPUMCTXCORE.es], eax
764 mov eax, ds
765 mov dword [esp + CPUMCTXCORE.ds], eax
766 mov eax, fs
767 mov dword [esp + CPUMCTXCORE.fs], eax
768 mov eax, gs
769 mov dword [esp + CPUMCTXCORE.gs], eax
770
771 test dword [esp + CPUMCTXCORE.eflags], X86_EFL_VM
772 jz short ti_SkipV86Entry
773
774 ;
775 ; The DS, ES, FS and GS registers are zeroed in V86 mode and their real values are on the stack
776 ;
777 mov eax, dword [esp + ESPOFF + 18h]
778 mov dword [esp + CPUMCTXCORE.es], eax
779
780 mov eax, dword [esp + ESPOFF + 1Ch]
781 mov dword [esp + CPUMCTXCORE.ds], eax
782
783 mov eax, dword [esp + ESPOFF + 20h]
784 mov dword [esp + CPUMCTXCORE.fs], eax
785
786 mov eax, dword [esp + ESPOFF + 24h]
787 mov dword [esp + CPUMCTXCORE.gs], eax
788
789ti_SkipV86Entry:
790
791 ;
792 ; Disable Ring-0 WP
793 ;
794 mov eax, cr0 ;; @todo try elimiate this read.
795 and eax, ~X86_CR0_WRITE_PROTECT
796 mov cr0, eax
797
798 ;
799 ; Load Hypervisor DS and ES (get it from the SS)
800 ;
801 mov eax, ss
802 mov ds, eax
803 mov es, eax
804
805 ;
806 ; Store the information about the active trap/interrupt.
807 ;
808 mov eax, IMP(g_TRPM)
809 movzx edx, byte [esp + 0h + ESPOFF] ; vector number
810 mov [eax + TRPM.uActiveVector], edx
811 xor edx, edx
812 mov dword [eax + TRPM.enmActiveType], TRPM_HARDWARE_INT
813 dec edx
814 mov [eax + TRPM.uActiveErrorCode], edx
815 mov [eax + TRPM.uActiveCR2], edx
816%if GC_ARCH_BITS == 64
817 ; zero out the high dword
818 mov dword [eax + TRPM.uActiveErrorCode + 4], 0
819 mov dword [eax + TRPM.uActiveCR2 + 4], 0
820%endif
821
822 ;
823 ; Check if we're in Hypervisor when this happend.
824 ;
825 test byte [esp + 08h + ESPOFF], 3h ; check CPL of the cs selector
826 jnz short gi_NotHyperVisor
827 jmp gi_HyperVisor
828
829 ;
830 ; Trap in guest code.
831 ;
832gi_NotHyperVisor:
833 and dword [esp + CPUMCTXCORE.eflags], ~010000h ; Clear RF (Resume Flag). @todo make %defines for eflags.
834 ; The guest shall not see this in it's state.
835%ifdef DEBUG_STUFF_INT
836 mov ecx, 'intG' ; indicate trap.
837 movzx edx, byte [esp + 0h + ESPOFF] ; vector number
838 lea eax, [esp]
839 call trpmDbgDumpRegisterFrame
840%endif
841
842 ;
843 ; Switch back to the host and process it there.
844 ;
845 mov edx, IMP(g_VM)
846 mov eax, VINF_EM_RAW_INTERRUPT
847 call [edx + VM.pfnVMMGCGuestToHostAsmGuestCtx]
848
849 ;
850 ; We've returned!
851 ; NOTE that the stack has been changed now!
852 ; there is no longer any CPUMCTXCORE around and esp points to vector number!
853 ;
854 ; Reset TRPM state
855 mov eax, IMP(g_TRPM)
856 xor edx, edx
857 dec edx ; edx = 0ffffffffh
858 xchg [eax + TRPM.uActiveVector], edx
859 mov [eax + TRPM.uPrevVector], edx
860
861 ; Enable WP
862 mov eax, cr0 ;; @todo try elimiate this read.
863 or eax, X86_CR0_WRITE_PROTECT
864 mov cr0, eax
865 ; restore guest context and continue execution.
866 lea eax, [esp + 8]
867 push eax
868 call NAME(CPUMGCRestoreInt)
869 lea esp, [esp + 0ch] ; cleanup call and skip vector & error code.
870
871 iret
872
873 ; -+- Entry point -+-
874 ;
875 ; We're in hypervisor mode which means no guest context
876 ; and special care to be taken to restore the hypervisor
877 ; context correctely.
878 ;
879 ; ATM the only place this can happen is when entering a trap handler.
880 ; We make ASSUMPTIONS about this in respects to the WP CR0 bit
881 ;
882gi_HyperVisor:
883 lea eax, [esp + 14h + ESPOFF] ; calc esp at trap
884 mov [esp + CPUMCTXCORE.esp], eax ; update esp in register frame
885 mov [esp + CPUMCTXCORE.ss], ss ; update ss in register frame
886
887%ifdef DEBUG_STUFF_INT
888 mov ebx, [esp + 4h + ESPOFF] ; error code
889 mov ecx, 'intH' ; indicate hypervisor interrupt.
890 movzx edx, byte [esp + 0h + ESPOFF] ; vector number
891 lea eax, [esp]
892 call trpmDbgDumpRegisterFrame
893%endif
894
895 mov ecx, esp
896 mov edx, IMP(g_VM)
897 mov eax, VINF_EM_RAW_INTERRUPT_HYPER
898 call [edx + VM.pfnVMMGCGuestToHostAsm]
899%ifdef DEBUG_STUFF_INT
900 COM_CHAR '!'
901%endif
902
903 ;
904 ; We've returned!
905 ;
906 ; Reset TRPM state - don't record this.
907 mov eax, IMP(g_TRPM)
908 mov dword [eax + TRPM.uActiveVector], 0ffffffffh
909
910 ;
911 ; Restore the hypervisor context and return.
912 ;
913 mov ecx, [esp + CPUMCTXCORE.ecx]
914 mov edx, [esp + CPUMCTXCORE.edx]
915 mov ebx, [esp + CPUMCTXCORE.ebx]
916 mov ebp, [esp + CPUMCTXCORE.ebp]
917 mov esi, [esp + CPUMCTXCORE.esi]
918 mov edi, [esp + CPUMCTXCORE.edi]
919
920 ; In V86 mode DS, ES, FS & GS are restored by the iret
921 test dword [esp + CPUMCTXCORE.eflags], X86_EFL_VM
922 jnz short ti_SkipSelRegs
923
924 mov eax, [esp + CPUMCTXCORE.gs]
925 TRPM_NP_GP_HANDLER NAME(trpmGCTrapInGeneric), TRPM_TRAP_IN_MOV_GS | TRPM_TRAP_IN_HYPER
926 mov gs, eax
927
928 mov eax, [esp + CPUMCTXCORE.fs]
929 TRPM_NP_GP_HANDLER NAME(trpmGCTrapInGeneric), TRPM_TRAP_IN_MOV_FS | TRPM_TRAP_IN_HYPER
930 mov fs, eax
931
932 mov eax, [esp + CPUMCTXCORE.es]
933 mov es, eax
934 mov eax, [esp + CPUMCTXCORE.ds]
935 mov ds, eax
936
937ti_SkipSelRegs:
938 ; finally restore our scratch register eax
939 mov eax, [esp + CPUMCTXCORE.eax]
940
941 ; skip esp, ss, cs, eip & eflags. Done by iret
942
943 add esp, ESPOFF + 4h ; skip CPUMCTXCORE structure & vector number.
944
945 iret
946%undef ESPOFF
947ENDPROC TRPMGCHandlerInterupt
948
949
950
951;;
952; Trap handler for #MC
953;
954; This handler will forward the #MC to the host OS. Since this
955; is generalized in the generic interrupt handler, we just disable
956; interrupts and push vector number and jump to the generic code.
957;
958; Stack:
959; 10 SS (only if ring transition.)
960; c ESP (only if ring transition.)
961; 8 EFLAGS
962; 4 CS
963; 0 EIP
964;
965; @uses none
966;
967ALIGNCODE(16)
968BEGINPROC_EXPORTED TRPMGCHandlerTrap12
969 push byte 12h
970 jmp ti_GenericInterrupt
971ENDPROC TRPMGCHandlerTrap12
972
973
974
975
976;;
977; Trap handler for double fault (#DF).
978;
979; This is a special trap handler executes in separate task with own TSS, with
980; one of the intermediate memory contexts instead of the shadow context.
981; The handler will unconditionally print an report to the comport configured
982; for the COM_S_* macros before attempting to return to the host. If it it ends
983; up double faulting more than 10 times, it will simply cause an tripple fault
984; to get us out of the mess.
985;
986; @param esp Half way down the hypvervisor stack + the trap frame.
987; @param ebp Half way down the hypvervisor stack.
988; @param eflags Interrupts disabled, nested flag is probably set (we don't care).
989; @param ecx The address of the hypervisor TSS.
990; @param edi Same as ecx.
991; @param eax Same as ecx.
992; @param edx Address of the VM structure.
993; @param esi Same as edx.
994; @param ebx Same as edx.
995; @param ss Hypervisor DS.
996; @param ds Hypervisor DS.
997; @param es Hypervisor DS.
998; @param fs 0
999; @param gs 0
1000;
1001;
1002; @remark To be able to catch errors with WP turned off, it is required that the
1003; TSS GDT descriptor and the TSSes are writable (X86_PTE_RW). See SELM.cpp
1004; for how to enable this.
1005;
1006; @remark It is *not* safe to resume the VMM after a double fault. (At least not
1007; without clearing the busy flag of the TssTrap8 and fixing whatever cause it.)
1008;
1009ALIGNCODE(16)
1010BEGINPROC_EXPORTED TRPMGCHandlerTrap08
1011 ; be careful.
1012 cli
1013 cld
1014
1015 ;
1016 ; Load Hypervisor DS and ES (get it from the SS) - paranoia, but the TSS could be overwritten.. :)
1017 ;
1018 mov eax, ss
1019 mov ds, eax
1020 mov es, eax
1021
1022 COM_S_PRINT 10,13,'*** Guru Mediation 00000008 - Double Fault! ***',10,13
1023
1024 ;
1025 ; Disable write protection.
1026 ;
1027 mov eax, cr0
1028 and eax, ~X86_CR0_WRITE_PROTECT
1029 mov cr0, eax
1030
1031
1032 COM_S_PRINT 'VM='
1033 COM_S_DWORD_REG edx
1034 COM_S_PRINT ' prevTSS='
1035 COM_S_DWORD_REG ecx
1036 COM_S_PRINT ' prevCR3='
1037 mov eax, [ecx + VBOXTSS.cr3]
1038 COM_S_DWORD_REG eax
1039 COM_S_PRINT ' prevLdtr='
1040 movzx eax, word [ecx + VBOXTSS.selLdt]
1041 COM_S_DWORD_REG eax
1042 COM_S_NEWLINE
1043
1044 ;
1045 ; Create CPUMCTXCORE structure.
1046 ;
1047 sub esp, CPUMCTXCORE_size
1048
1049 mov eax, [ecx + VBOXTSS.eip]
1050 mov [esp + CPUMCTXCORE.eip], eax
1051 mov eax, [ecx + VBOXTSS.eflags]
1052 mov [esp + CPUMCTXCORE.eflags], eax
1053
1054 movzx eax, word [ecx + VBOXTSS.cs]
1055 mov dword [esp + CPUMCTXCORE.cs], eax
1056 movzx eax, word [ecx + VBOXTSS.ds]
1057 mov dword [esp + CPUMCTXCORE.ds], eax
1058 movzx eax, word [ecx + VBOXTSS.es]
1059 mov dword [esp + CPUMCTXCORE.es], eax
1060 movzx eax, word [ecx + VBOXTSS.fs]
1061 mov dword [esp + CPUMCTXCORE.fs], eax
1062 movzx eax, word [ecx + VBOXTSS.gs]
1063 mov dword [esp + CPUMCTXCORE.gs], eax
1064 movzx eax, word [ecx + VBOXTSS.ss]
1065 mov [esp + CPUMCTXCORE.ss], eax
1066 mov eax, [ecx + VBOXTSS.esp]
1067 mov [esp + CPUMCTXCORE.esp], eax
1068 mov eax, [ecx + VBOXTSS.ecx]
1069 mov [esp + CPUMCTXCORE.ecx], eax
1070 mov eax, [ecx + VBOXTSS.edx]
1071 mov [esp + CPUMCTXCORE.edx], eax
1072 mov eax, [ecx + VBOXTSS.ebx]
1073 mov [esp + CPUMCTXCORE.ebx], eax
1074 mov eax, [ecx + VBOXTSS.eax]
1075 mov [esp + CPUMCTXCORE.eax], eax
1076 mov eax, [ecx + VBOXTSS.ebp]
1077 mov [esp + CPUMCTXCORE.ebp], eax
1078 mov eax, [ecx + VBOXTSS.esi]
1079 mov [esp + CPUMCTXCORE.esi], eax
1080 mov eax, [ecx + VBOXTSS.edi]
1081 mov [esp + CPUMCTXCORE.edi], eax
1082
1083 ;
1084 ; Show regs
1085 ;
1086 mov ebx, 0ffffffffh
1087 mov ecx, 'trpH' ; indicate trap.
1088 mov edx, 08h ; vector number
1089 lea eax, [esp]
1090 call trpmDbgDumpRegisterFrame
1091
1092 ;
1093 ; Should we try go back?
1094 ;
1095 inc dword [df_Count]
1096 cmp dword [df_Count], byte 10
1097 jb df_to_host
1098 jmp df_tripple_fault
1099df_Count: dd 0
1100
1101 ;
1102 ; Try return to the host.
1103 ;
1104df_to_host:
1105 COM_S_PRINT 'Trying to return to host...',10,13
1106 mov ecx, esp
1107 mov edx, IMP(g_VM)
1108 mov eax, VERR_TRPM_PANIC
1109 call [edx + VM.pfnVMMGCGuestToHostAsmHyperCtx]
1110 jmp short df_to_host
1111
1112 ;
1113 ; Perform a tripple fault.
1114 ;
1115df_tripple_fault:
1116 COM_S_PRINT 'Giving up - tripple faulting the machine...',10,13
1117 push byte 0
1118 push byte 0
1119 sidt [esp]
1120 mov word [esp], 0
1121 lidt [esp]
1122 xor eax, eax
1123 mov dword [eax], 0
1124 jmp df_tripple_fault
1125
1126ENDPROC TRPMGCHandlerTrap08
1127
1128
1129
1130
1131;;
1132; Internal procedure used to dump registers.
1133;
1134; @param eax Pointer to CPUMCTXCORE.
1135; @param edx Vector number
1136; @param ecx 'trap' if trap, 'int' if interrupt.
1137; @param ebx Error code if trap.
1138;
1139trpmDbgDumpRegisterFrame:
1140 sub esp, byte 8 ; working space for sidt/sgdt/etc
1141
1142; Init _must_ be done on host before crashing!
1143; push edx
1144; push eax
1145; COM_INIT
1146; pop eax
1147; pop edx
1148
1149 cmp ecx, 'trpH'
1150 je near tddrf_trpH
1151 cmp ecx, 'trpG'
1152 je near tddrf_trpG
1153 cmp ecx, 'intH'
1154 je near tddrf_intH
1155 cmp ecx, 'intG'
1156 je near tddrf_intG
1157 cmp ecx, 'resH'
1158 je near tddrf_resH
1159 COM_S_PRINT 10,13,'*** Bogus Dump Code '
1160 jmp tddrf_regs
1161
1162%if 1 ; the verbose version
1163
1164tddrf_intG:
1165 COM_S_PRINT 10,13,'*** Interrupt (Guest) '
1166 COM_S_DWORD_REG edx
1167 jmp tddrf_regs
1168
1169tddrf_intH:
1170 COM_S_PRINT 10,13,'*** Interrupt (Hypervisor) '
1171 COM_S_DWORD_REG edx
1172 jmp tddrf_regs
1173
1174tddrf_trpG:
1175 COM_S_PRINT 10,13,'*** Trap '
1176 jmp tddrf_trap_rest
1177
1178%else ; the short version
1179
1180tddrf_intG:
1181 COM_S_CHAR 'I'
1182 jmp tddrf_ret
1183
1184tddrf_intH:
1185 COM_S_CHAR 'i'
1186 jmp tddrf_ret
1187
1188tddrf_trpG:
1189 COM_S_CHAR 'T'
1190 jmp tddrf_ret
1191
1192%endif ; the short version
1193
1194tddrf_trpH:
1195 COM_S_PRINT 10,13,'*** Guru Meditation '
1196 jmp tddrf_trap_rest
1197
1198tddrf_resH:
1199 COM_S_PRINT 10,13,'*** Resuming Hypervisor Trap '
1200 jmp tddrf_trap_rest
1201
1202tddrf_trap_rest:
1203 COM_S_DWORD_REG edx
1204 COM_S_PRINT ' ErrorCode='
1205 COM_S_DWORD_REG ebx
1206 COM_S_PRINT ' cr2='
1207 mov ecx, cr2
1208 COM_S_DWORD_REG ecx
1209
1210tddrf_regs:
1211 COM_S_PRINT ' ***',10,13,'cs:eip='
1212 movzx ecx, word [eax + CPUMCTXCORE.cs]
1213 COM_S_DWORD_REG ecx
1214 COM_S_CHAR ':'
1215 mov ecx, [eax + CPUMCTXCORE.eip]
1216 COM_S_DWORD_REG ecx
1217
1218 COM_S_PRINT ' ss:esp='
1219 movzx ecx, word [eax + CPUMCTXCORE.ss]
1220 COM_S_DWORD_REG ecx
1221 COM_S_CHAR ':'
1222 mov ecx, [eax + CPUMCTXCORE.esp]
1223 COM_S_DWORD_REG ecx
1224
1225
1226 sgdt [esp]
1227 COM_S_PRINT 10,13,' gdtr='
1228 movzx ecx, word [esp]
1229 COM_S_DWORD_REG ecx
1230 COM_S_CHAR ':'
1231 mov ecx, [esp + 2]
1232 COM_S_DWORD_REG ecx
1233
1234 sidt [esp]
1235 COM_S_PRINT ' idtr='
1236 movzx ecx, word [esp]
1237 COM_S_DWORD_REG ecx
1238 COM_S_CHAR ':'
1239 mov ecx, [esp + 2]
1240 COM_S_DWORD_REG ecx
1241
1242
1243 str [esp] ; yasm BUG! it generates sldt [esp] here! YASMCHECK!
1244 COM_S_PRINT 10,13,' tr='
1245 movzx ecx, word [esp]
1246 COM_S_DWORD_REG ecx
1247
1248 sldt [esp]
1249 COM_S_PRINT ' ldtr='
1250 movzx ecx, word [esp]
1251 COM_S_DWORD_REG ecx
1252
1253 COM_S_PRINT ' eflags='
1254 mov ecx, [eax + CPUMCTXCORE.eflags]
1255 COM_S_DWORD_REG ecx
1256
1257
1258 COM_S_PRINT 10,13,'cr0='
1259 mov ecx, cr0
1260 COM_S_DWORD_REG ecx
1261
1262 COM_S_PRINT ' cr2='
1263 mov ecx, cr2
1264 COM_S_DWORD_REG ecx
1265
1266 COM_S_PRINT ' cr3='
1267 mov ecx, cr3
1268 COM_S_DWORD_REG ecx
1269 COM_S_PRINT ' cr4='
1270 mov ecx, cr4
1271 COM_S_DWORD_REG ecx
1272
1273
1274 COM_S_PRINT 10,13,' ds='
1275 movzx ecx, word [eax + CPUMCTXCORE.ds]
1276 COM_S_DWORD_REG ecx
1277
1278 COM_S_PRINT ' es='
1279 movzx ecx, word [eax + CPUMCTXCORE.es]
1280 COM_S_DWORD_REG ecx
1281
1282 COM_S_PRINT ' fs='
1283 movzx ecx, word [eax + CPUMCTXCORE.fs]
1284 COM_S_DWORD_REG ecx
1285
1286 COM_S_PRINT ' gs='
1287 movzx ecx, word [eax + CPUMCTXCORE.gs]
1288 COM_S_DWORD_REG ecx
1289
1290
1291 COM_S_PRINT 10,13,'eax='
1292 mov ecx, [eax + CPUMCTXCORE.eax]
1293 COM_S_DWORD_REG ecx
1294
1295 COM_S_PRINT ' ebx='
1296 mov ecx, [eax + CPUMCTXCORE.ebx]
1297 COM_S_DWORD_REG ecx
1298
1299 COM_S_PRINT ' ecx='
1300 mov ecx, [eax + CPUMCTXCORE.ecx]
1301 COM_S_DWORD_REG ecx
1302
1303 COM_S_PRINT ' edx='
1304 mov ecx, [eax + CPUMCTXCORE.edx]
1305 COM_S_DWORD_REG ecx
1306
1307
1308 COM_S_PRINT 10,13,'esi='
1309 mov ecx, [eax + CPUMCTXCORE.esi]
1310 COM_S_DWORD_REG ecx
1311
1312 COM_S_PRINT ' edi='
1313 mov ecx, [eax + CPUMCTXCORE.edi]
1314 COM_S_DWORD_REG ecx
1315
1316 COM_S_PRINT ' ebp='
1317 mov ecx, [eax + CPUMCTXCORE.ebp]
1318 COM_S_DWORD_REG ecx
1319
1320
1321 COM_S_NEWLINE
1322
1323tddrf_ret:
1324 add esp, byte 8
1325 ret
1326
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