VirtualBox

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

Last change on this file since 1349 was 1132, checked in by vboxsync, 18 years ago

Backed out previous changeset. Stack is writable of course.

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