Index: /trunk/src/VBox/VMM/Makefile.kmk
===================================================================
--- /trunk/src/VBox/VMM/Makefile.kmk	(revision 48235)
+++ /trunk/src/VBox/VMM/Makefile.kmk	(revision 48236)
@@ -65,4 +65,7 @@
 ifdef VBOX_WITH_64ON32_IDT
  VMM_COMMON_DEFS += VBOX_WITH_64ON32_IDT
+endif
+ifdef VBOX_WITH_64ON32_CMOS_DEBUG
+ VMM_COMMON_DEFS += VBOX_WITH_64ON32_CMOS_DEBUG
 endif
 
Index: /trunk/src/VBox/VMM/VMMR0/VMMR0.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/VMMR0.cpp	(revision 48235)
+++ /trunk/src/VBox/VMM/VMMR0/VMMR0.cpp	(revision 48236)
@@ -115,4 +115,14 @@
 #endif
     LogFlow(("ModuleInit:\n"));
+
+#ifdef VBOX_WITH_64ON32_CMOS_DEBUG
+    /*
+     * Display the CMOS debug code.
+     */
+    ASMOutU8(0x72, 0x03);
+    uint8_t bDebugCode = ASMInU8(0x73);
+    LogRel(("CMOS Debug Code: %#x (%d)\n", bDebugCode, bDebugCode));
+    RTLogComPrintf("CMOS Debug Code: %#x (%d)\n", bDebugCode, bDebugCode);
+#endif
 
     /*
Index: /trunk/src/VBox/VMM/VMMSwitcher/LegacyandAMD64.mac
===================================================================
--- /trunk/src/VBox/VMM/VMMSwitcher/LegacyandAMD64.mac	(revision 48235)
+++ /trunk/src/VBox/VMM/VMMSwitcher/LegacyandAMD64.mac	(revision 48236)
@@ -30,4 +30,50 @@
 %define HM64ON32OP_HMRCSaveGuestDebug64 4
 %define HM64ON32OP_HMRCTestSwitcher64   5
+
+;;
+; This macro is used for storing a debug code in a CMOS location.
+;
+; If we tripple fault or something, the debug code can be retrieved and we
+; might have a clue as to where the problem occurred.  The code is currently
+; using CMOS register 3 in the 2nd bank as this _seems_ to be unused on my
+; Extreme4 X79 asrock mainboard.
+;
+; @param %1     The debug code (byte)
+; @note Trashes AL.
+;
+%macro DEBUG_CMOS_TRASH_AL 1
+%ifdef VBOX_WITH_64ON32_CMOS_DEBUG
+    mov     al, 3
+    out     72h, al
+    mov     al, %1
+    out     73h, al
+    in      al, 73h
+%endif
+%endmacro
+
+;;
+; Version of DEBUG_CMOS_TRASH_AL that saves AL on the stack and therefore
+; doesn't trash any registers.
+;
+%macro DEBUG_CMOS_STACK64 1
+%ifdef VBOX_WITH_64ON32_CMOS_DEBUG
+    push    rax
+    DEBUG_CMOS_TRASH_AL %1
+    pop     rax
+%endif
+%endmacro
+
+;;
+; Version of DEBUG_CMOS_TRASH_AL that saves AL on the stack and therefore
+; doesn't trash any registers.
+;
+%macro DEBUG_CMOS_STACK32 1
+%ifdef VBOX_WITH_64ON32_CMOS_DEBUG
+    push    eax
+    DEBUG_CMOS_TRASH_AL %1
+    pop     eax
+%endif
+%endmacro
+
 
 ;; Stubs for making OS/2 compile (though, not work).
@@ -113,4 +159,5 @@
     pushf
     cli
+    DEBUG_CMOS_STACK32 10h
 
     ;
@@ -151,4 +198,5 @@
 
 gth_x2apic:
+    ;DEBUG_CMOS_STACK32 7ch
     push    eax                         ; save eax
     push    ebx                         ; save it for fApicDisVectors
@@ -191,4 +239,5 @@
 
     ; restore original flags
+    ;DEBUG_CMOS_STACK32 7eh
     popf
     pop     ebp
@@ -203,4 +252,5 @@
 %endif
 
+    ;DEBUG_CMOS_STACK32 7fh
     ret
 
@@ -399,4 +449,5 @@
 
     ; Load new gdt so we can do a far jump after going into 64 bits mode
+    ;DEBUG_CMOS_STACK32 16h
     lgdt    [edx + CPUMCPU.Hyper.gdtr]
 
@@ -414,4 +465,5 @@
     mov     cr3, eax
     DEBUG32_CHAR('?')
+    DEBUG_CMOS_TRASH_AL 17h
 
     ;;
@@ -509,4 +561,5 @@
 ALIGNCODE(16)
 GLOBALNAME ICEnterTarget
+    DEBUG_CMOS_TRASH_AL 1ah
     ; Load CPUM pointer into rdx
     mov     rdx, [NAME(pCpumIC) wrt rip]
@@ -716,4 +769,5 @@
     push    rbp
     mov     rbp, rsp
+    DEBUG_CMOS_STACK64 20h
 
     ; Make sure VT-x instructions are allowed.
@@ -815,4 +869,13 @@
     mov     eax, VMX_VMCS_HOST_FIELD_SS
     vmwrite rax, rdx
+
+%if 0 ; Another experiment regarding tripple faults... Seems not to be necessary.
+    sub     rsp, 16
+    str     [rsp]
+    movsx   rdx, word [rsp]
+    mov     eax, VMX_VMCS_HOST_FIELD_TR
+    vmwrite rax, rdx
+    add     rsp, 16
+%endif
 
     sub     rsp, 16
@@ -1078,4 +1141,5 @@
     mov     rbp, rsp
     pushf
+    DEBUG_CMOS_STACK64 30h
 
     ; Manual save and restore:
@@ -1169,4 +1233,5 @@
 ; */
 BEGINPROC HMRCSaveGuestFPU64
+    DEBUG_CMOS_STACK64 40h
     mov     rax, cr0
     mov     rcx, rax                    ; save old CR0
@@ -1189,4 +1254,5 @@
 ; */
 BEGINPROC HMRCSaveGuestDebug64
+    DEBUG_CMOS_STACK64 41h
     mov rax, dr0
     mov qword [rsi + CPUMCTX.dr + 0*8], rax
@@ -1215,4 +1281,5 @@
 ; */
 BEGINPROC HMRCTestSwitcher64
+    DEBUG_CMOS_STACK64 42h
     mov eax, [rsp+8]
     ret
@@ -1430,4 +1497,108 @@
  %endif
 
+ %if 1
+;; For debugging purposes.
+BEGINPROC vmm64On32DumpCmos
+    push    rax
+    push    rdx
+    push    rcx
+    push    rsi                         ; paranoia
+    push    rdi                         ; ditto
+    sub rsp, 16
+
+%if 0
+    mov     al, 3
+    out     72h, al
+    mov     al, 68h
+    out     73h, al
+%endif
+
+    COM64_S_NEWLINE
+    COM64_S_CHAR 'c'
+    COM64_S_CHAR 'm'
+    COM64_S_CHAR 'o'
+    COM64_S_CHAR 's'
+    COM64_S_CHAR '0'
+    COM64_S_CHAR ':'
+
+    xor     ecx, ecx
+.loop1:
+    mov     al, cl
+    out     70h, al
+    in      al, 71h
+    COM64_S_BYTE_REG eax
+    COM64_S_CHAR ' '
+    inc     ecx
+    cmp     ecx, 128
+    jb      .loop1
+
+    COM64_S_NEWLINE
+    COM64_S_CHAR 'c'
+    COM64_S_CHAR 'm'
+    COM64_S_CHAR 'o'
+    COM64_S_CHAR 's'
+    COM64_S_CHAR '1'
+    COM64_S_CHAR ':'
+    xor     ecx, ecx
+.loop2:
+    mov     al, cl
+    out     72h, al
+    in      al, 73h
+    COM64_S_BYTE_REG eax
+    COM64_S_CHAR ' '
+    inc     ecx
+    cmp     ecx, 128
+    jb      .loop2
+
+%if 0
+    COM64_S_NEWLINE
+    COM64_S_CHAR 'c'
+    COM64_S_CHAR 'm'
+    COM64_S_CHAR 'o'
+    COM64_S_CHAR 's'
+    COM64_S_CHAR '2'
+    COM64_S_CHAR ':'
+    xor     ecx, ecx
+.loop3:
+    mov     al, cl
+    out     74h, al
+    in      al, 75h
+    COM64_S_BYTE_REG eax
+    COM64_S_CHAR ' '
+    inc     ecx
+    cmp     ecx, 128
+    jb      .loop3
+
+    COM64_S_NEWLINE
+    COM64_S_CHAR 'c'
+    COM64_S_CHAR 'm'
+    COM64_S_CHAR 'o'
+    COM64_S_CHAR 's'
+    COM64_S_CHAR '3'
+    COM64_S_CHAR ':'
+    xor     ecx, ecx
+.loop4:
+    mov     al, cl
+    out     72h, al
+    in      al, 73h
+    COM64_S_BYTE_REG eax
+    COM64_S_CHAR ' '
+    inc     ecx
+    cmp     ecx, 128
+    jb      .loop4
+
+    COM64_S_NEWLINE
+%endif
+
+    add rsp, 16
+    pop     rdi
+    pop     rsi
+    pop     rcx
+    pop     rdx
+    pop     rax
+    ret
+ENDPROC   vmm64On32DumpCmos
+ %endif
+
 %endif ; VBOX_WITH_64ON32_IDT
 
@@ -1568,4 +1739,5 @@
 GLOBALNAME ICExitTarget
     DEBUG32_CHAR('9')
+    ;DEBUG_CMOS_TRASH_AL 70h
 
     ; load the hypervisor data selector into ds & es
@@ -1646,4 +1818,5 @@
 
     ; store the return code in eax
+    DEBUG_CMOS_TRASH_AL 79h
     mov     eax, [edx + CPUMCPU.u32RetCode]
     retf
