Index: /trunk/src/VBox/ValidationKit/bootsectors/Makefile.kmk
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/Makefile.kmk	(revision 59310)
+++ /trunk/src/VBox/ValidationKit/bootsectors/Makefile.kmk	(revision 59311)
@@ -42,4 +42,5 @@
 if defined(VBOX_WITH_OPEN_WATCOM)
  if1of ($(KBUILD_TARGET), win) # requires patched NASM.
+  VBOX_WITH_BS3KIT = 1
   include $(PATH_SUB_CURRENT)/bs3kit/Makefile.kmk
  endif
@@ -205,4 +206,17 @@
 
 
+ifdef VBOX_WITH_BS3KIT
+#
+# Bs3kit
+#
+
+# shutdown example.
+MISCBINS += bs3-cpu-basic-2
+bs3-cpu-basic-2_TEMPLATE = VBoxBS3KitImg
+bs3-cpu-basic-2_SOURCES = \
+	bs3-cpu-basic-2.asm
+endif
+
+
 include $(FILE_KBUILD_SUB_FOOTER)
 
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-basic-2.asm
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-basic-2.asm	(revision 59311)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-basic-2.asm	(revision 59311)
@@ -0,0 +1,78 @@
+; $Id$
+;; @file
+; BS3Kit - bs3-cpu-basic-2
+;
+
+;
+; Copyright (C) 2007-2016 Oracle Corporation
+;
+; This file is part of VirtualBox Open Source Edition (OSE), as
+; available from http://www.virtualbox.org. This file is free software;
+; you can redistribute it and/or modify it under the terms of the GNU
+; General Public License (GPL) as published by the Free Software
+; Foundation, in version 2 as it comes in the "COPYING" file of the
+; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+;
+; The contents of this file may alternatively be used under the terms
+; of the Common Development and Distribution License Version 1.0
+; (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+; VirtualBox OSE distribution, in which case the provisions of the
+; CDDL are applicable instead of those of the GPL.
+;
+; You may elect to license modified versions of this file under the
+; terms and conditions of either the GPL or the CDDL or both.
+;
+
+
+;*********************************************************************************************************************************
+;*  Header Files                                                                                                                 *
+;*********************************************************************************************************************************
+%include "bs3kit.mac"
+
+;
+; Segment defs, grouping and related variables.
+; Defines the entry point 'start' as well, leaving us in BS3TEXT16.
+;
+%include "bs3-first-common.mac"
+
+
+;
+; We start in real mode.
+;
+%define TMPL_RM
+%include "bs3kit-template-header.mac"
+
+BS3_BEGIN_TEXT16
+BS3_EXTERN_TMPL Bs3InitMemory
+BS3_EXTERN_CMN  Bs3Trap32Init
+BS3_EXTERN_CMN  Bs3Shutdown
+
+
+BS3_BEGIN_TEXT16
+BS3_PROC_BEGIN Bs3CpuBasic2_Main
+        push    word 0                  ; zero return address.
+        push    word 0                  ; zero caller BP
+        mov     bp, sp
+        sub     sp, 20h                 ; reserve 20h for 64-bit calls (we're doing them MSC style, remember).
+
+        ;
+        ; Do bs3kit init.
+        ;
+        call    Bs3InitMemory           ; Initialize the memory (must be done from real mode).
+        call    Bs3Trap32Init
+
+        ;
+        ; Start testing.
+        ;
+
+        ;
+        ; Done.
+        ;
+.shutdown:
+        call    Bs3Shutdown
+        jmp     .shutdown
+BS3_PROC_END   Bs3CpuBasic2_Main
+
+
+
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/Makefile.kmk
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/Makefile.kmk	(revision 59310)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/Makefile.kmk	(revision 59311)
@@ -189,5 +189,6 @@
 bs3kit-rm_DEFS     = TMPL_RM
 bs3kit-rm_SOURCES  = $(VBOX_BS3KIT_MODE_SOURCES) \
-	bs3-first-rm.asm
+	bs3-first-rm.asm \
+	bs3-mode-CpuDetect.asm
 
 
@@ -197,5 +198,6 @@
 bs3kit-pe16_DEFS     = TMPL_PE16
 bs3kit-pe16_SOURCES  = $(VBOX_BS3KIT_MODE_SOURCES) \
-	bs3-first-pe16.asm
+	bs3-first-pe16.asm \
+#	bs3-mode-CpuDetect.asm
 
 # The virtual 8086 under protected mode BS3Kit library.
@@ -217,4 +219,5 @@
 bs3kit-pp16_DEFS     = TMPL_PP16
 bs3kit-pp16_SOURCES  = $(VBOX_BS3KIT_MODE_SOURCES) \
+	bs3-mode-CpuDetect.asm
 
 # The 32-bit paged protected mode BS3Kit library.
@@ -235,5 +238,6 @@
 bs3kit-pae16_TEMPLATE = VBoxBS3KitImg
 bs3kit-pae16_DEFS     = TMPL_PAE16
-bs3kit-pae16_SOURCES  = $(VBOX_BS3KIT_MODE_SOURCES)
+bs3kit-pae16_SOURCES  = $(VBOX_BS3KIT_MODE_SOURCES) \
+	bs3-mode-CpuDetect.asm
 
 # The 32-bit paged protected mode BS3Kit library.
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-CpuDetect.asm
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-CpuDetect.asm	(revision 59311)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-CpuDetect.asm	(revision 59311)
@@ -0,0 +1,230 @@
+; $Id$
+;; @file
+; BS3Kit - Bs3CpuDetect
+;
+
+;
+; Copyright (C) 2007-2016 Oracle Corporation
+;
+; This file is part of VirtualBox Open Source Edition (OSE), as
+; available from http://www.virtualbox.org. This file is free software;
+; you can redistribute it and/or modify it under the terms of the GNU
+; General Public License (GPL) as published by the Free Software
+; Foundation, in version 2 as it comes in the "COPYING" file of the
+; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+;
+; The contents of this file may alternatively be used under the terms
+; of the Common Development and Distribution License Version 1.0
+; (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+; VirtualBox OSE distribution, in which case the provisions of the
+; CDDL are applicable instead of those of the GPL.
+;
+; You may elect to license modified versions of this file under the
+; terms and conditions of either the GPL or the CDDL or both.
+;
+
+%include "bs3kit-template-header.mac"
+
+%define BS3CPU_8086             1
+%define BS3CPU_V20              2
+%define BS3CPU_80186            3
+%define BS3CPU_80286            4
+%define BS3CPU_80386            5
+%define BS3CPU_80486            6
+%define BS3CPU_80486            7
+%define BS3CPU_Pentium          8
+%define BS3CPU_PPro             9
+%define BS3CPU_PProOrNewer      10
+%define BS3CPU_F_CPUID          0x80
+
+
+;;
+; Rough CPU detection, mainly for detecting really old CPUs.
+;
+; A Bs3CpuDetectEx can be added if this is insufficient.
+;
+; @returns  BS3CPU_xxx in xAX.
+; @cproto   BS3_DECL(BS3CPU) Bs3CpuDetect(void);
+;
+; @uses     xAX.
+;
+; @remarks  ASSUMES we're in ring-0 when not in some kind of real mode.
+;
+BS3_PROC_BEGIN_MODE Bs3CpuDetect
+CPU 8086
+        push    xBP
+        mov     xBP, xSP
+        pushf
+        push    xCX
+        push    xDX
+        push    xBX
+
+%ifndef TMPL_CMN_PAGING
+ %ifdef TMPL_RM
+  %if 1                 ; this is simpler
+        ;
+        ; FLAGS bits 15:12 are always set on 8086, 8088, V20, V30, 80186, and
+        ; 80188. FLAGS bit 15 is always zero on 286+, whereas bit 14 is NT and
+        ; bits 13:12 are IOPL.
+        ;
+        test    byte [xBP - xCB + 1], 80h ; Top byte of saved flags.
+        jz      .286plus
+  %else
+        ;
+        ; When executing 'PUSH SP' the 8086, 8088, V20, V30, 80186, and 80188
+        ; should be pushing the updated SP value instead of the initial one.
+        ;
+        push    xSP
+        pop     xAX
+        cmp     xAX, xSP
+        je      .286plus
+  %endif
+
+        ;
+        ; Older than 286.
+        ;
+        ; Detect 8086/8088/V20/V30 vs. 80186/80188 by checking for pre 80186
+        ; shift behavior.  the 80186/188 and later will mask the CL value according
+        ; to the width of the destination register, whereas 8086/88 and V20/30 will
+        ; perform the exact number of shifts specified.
+        ;
+        mov     cl, 20h                 ; Shift count; 80186/88 and later will mask this by 0x1f (or 0xf)?
+        mov     dx, 7fh
+        shl     dx, cl
+        cmp     dx, 7fh                 ; If no change, this is a 80186/88.
+        mov     xAX, BS3CPU_80186
+        je      .return
+
+        ;
+        ; Detect 8086/88 vs V20/30 by exploiting undocumented POP CS encoding
+        ; that was redefined on V20/30 to SET1.
+        ;
+        xor     ax, ax                  ; clear
+        push    cs
+        db      0fh                     ; 8086/88: pop cs       V20/30: set1 bl,cl
+        db      14h, 3ch                ; 8086/88: add al, 3ch
+                                        ; 8086/88: al = 3ch     V20/30: al = 0, cs on stack, bl modified.
+        cmp     al, 3ch
+        jne     .is_v20_or_v30
+        mov     xAX, BS3CPU_8086
+        jmp     .return
+
+.is_v20_or_v30:
+        pop     xCX                     ; unclaimed CS
+        mov     xAX, BS3CPU_V20
+        jmp     .return
+
+ %endif ; TMPL_RM
+
+CPU 286
+.286plus:
+        ;
+        ; The 4th bit of the machine status word / CR0 indicates the precense
+        ; of a 80387 or later co-processor (a 80287+80386 => ET=0).  486 and
+        ; later should be hardcoding this to 1, according to the documentation
+        ; (need to test on 486SX).  The 286 should never have it set.
+        ;
+        smsw    ax
+        test    ax, X86_CR0_ET
+        jnz     .386plus
+ %ifndef TMPL_RM                        ; remove once 286plus_protmode is implemented (relevant in DOS context).
+        test    ax, X86_CR0_PE
+        jnz     .286plus_protmode       ;; @todo The test below doesn't work in prot mode, I think...
+ %endif
+
+        ;
+        ; Detect 80286 by checking whether the IOPL and NT bits of EFLAGS can be
+        ; modified or not.  There are different accounts of these bits.  Dr.Dobb's
+        ; (http://www.drdobbs.com/embedded-systems/processor-detection-schemes/184409011)
+        ; say they are undefined on 286es and will always be zero.  Whereas Intel
+        ; iAPX 286 Programmer's Reference Manual (both order #210498-001 and
+        ; #210498-003) documents both IOPL and NT, but with comment 4 on page
+        ; C-43 stating that they cannot be POPFed in real mode and will both
+        ; remain 0.  This is different from the 386+, where the NT flag isn't
+        ; privileged according to page 3-37 in #230985-003.  Later Intel docs
+        ; (#235383-052US, page 4-192) documents real mode as taking both NT and
+        ; IOPL from what POPF reads off the stack - which is the behavior
+        ; observed a 386SX here.
+        ;
+        cli                             ; Disable interrupts to be on the safe side.
+        mov     xAX, [xBP - xCB]
+        or      xAX, X86_EFL_IOPL | X86_EFL_NT
+        push    xAX                     ; Load modified flags.
+        popf
+        pushf                           ; Get actual flags.
+        pop     xAX
+        test    ax, X86_EFL_IOPL | X86_EFL_NT
+        jnz     .386plus                ; If any of the flags are set, we're on 386+.
+
+        ; While we could in theory be in v8086 mode at this point and be fooled
+        ; by a flaky POPF implementation, we assume this isn't the case in our
+        ; execution environment.
+        mov     xAX, BS3CPU_80286
+        jmp     .return
+%endif
+
+CPU 386
+.386plus:
+        ;
+        ; Check for CPUID and AC.  The former flag indicates CPUID support, the
+        ; latter was introduced with the 486.
+        ;
+        mov     ebx, esp                ; Save esp.
+        and     esp, 0fffch             ; Clear high word and don't trigger ACs.
+        pushfd
+        mov     eax, [esp]              ; eax = original EFLAGS.
+        xor     dword [esp], X86_EFL_ID | X86_EFL_AC ; Flip the ID and AC flags.
+        popfd                           ; Load modified flags.
+        pushfd                          ; Save actual flags.
+        xchg    eax, [esp]              ; Switch, so the stack has the original flags.
+        xor     eax, [esp]              ; Calc changed flags.
+        popf                            ; Restore EFLAGS.
+        mov     esp, ebx                ; Restore possibly unaligned ESP.
+        test    eax, X86_EFL_ID
+        jnz     .have_cpuid             ; If ID changed, we've got CPUID.
+        test    eax, X86_EFL_AC
+        mov     xAX, BS3CPU_80486
+        jnz     .return                 ; If AC changed, we've got a 486 without CPUID (or similar).
+        mov     xAX, BS3CPU_80386
+        jmp     .return
+
+CPU 586
+.have_cpuid:
+        ;
+        ; Do a very simple minded check here using the (standard) family field.
+        ;
+        mov     eax, 1
+        cpuid
+        mov     cl, ah
+        and     cl, 0fh                 ; Family.
+        cmp     cl, 6
+        mov     xAX, BS3CPU_PPro | BS3CPU_F_CPUID
+        jz      .return
+        ja      .NewerThanPPro
+        cmp     cl, 5
+        mov     xAX, BS3CPU_Pentium | BS3CPU_F_CPUID
+        je      .return
+        cmp     cl, 4
+        mov     xAX, BS3CPU_80486 | BS3CPU_F_CPUID
+        je      .return
+        cmp     cl, 3
+        mov     xAX, BS3CPU_80386 | BS3CPU_F_CPUID
+        je      .return
+.NewerThanPPro:
+        mov     xAX, BS3CPU_PProOrNewer | BS3CPU_F_CPUID
+
+        ;
+        ; Epilogue.
+        ;
+CPU 8086
+.return:
+        popf
+        pop     xBX
+        pop     xDX
+        pop     xCX
+        pop     xBP
+;; @todo cache the return value.
+        ret
+BS3_PROC_END_MODE   Bs3EnteredMode
+
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-template-footer.h
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-template-footer.h	(revision 59310)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-template-footer.h	(revision 59311)
@@ -49,4 +49,5 @@
 #undef TMPL_CMN_LM
 #undef TMPL_CMN_V86
+#undef TMPL_CMN_PAGING
 
 #undef TMPL_CMN_P16
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-template-footer.mac
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-template-footer.mac	(revision 59310)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-template-footer.mac	(revision 59311)
@@ -59,4 +59,5 @@
 %undef TMPL_CMN_LM
 %undef TMPL_CMN_V86
+%undef TMPL_CMN_PAGING
 
 %undef TMPL_CMN_P16
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-template-header.h
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-template-header.h	(revision 59310)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-template-header.h	(revision 59311)
@@ -77,4 +77,5 @@
 # define TMPL_CMN_V86   /**< TMPL_PEV86 | TMPL_PPV86 | TMPL_PAEV86 */
 # define TMPL_CMN_R86   /**< TMPL_CMN_V86 | TMPL_RM                */
+# define TMPL_CMN_PAGING /**< TMPL_CMN_PP | TMPL_CMN_PAE | TMPL_CMN_LM */
 /** @} */
 
@@ -356,4 +357,5 @@
 # endif
 # define TMPL_CMN_PP
+# define TMPL_CMN_PAGING
 # define TMPL_CMN_P16
 # define TMPL_16BIT
@@ -405,4 +407,5 @@
 # endif
 # define TMPL_CMN_PP
+# define TMPL_CMN_PAGING
 # define TMPL_CMN_P32
 # define TMPL_32BIT
@@ -454,4 +457,5 @@
 # endif
 # define TMPL_CMN_PP
+# define TMPL_CMN_PAGING
 # define TMPL_CMN_V86
 # define TMPL_CMN_R86
@@ -504,4 +508,5 @@
 # endif
 # define TMPL_CMN_PAE
+# define TMPL_CMN_PAGING
 # define TMPL_16BIT
 # define TMPL_CMN_P16
@@ -553,4 +558,5 @@
 # endif
 # define TMPL_CMN_PAE
+# define TMPL_CMN_PAGING
 # define TMPL_CMN_P32
 # define TMPL_32BIT
@@ -602,4 +608,5 @@
 # endif
 # define TMPL_CMN_PAE
+# define TMPL_CMN_PAGING
 # define TMPL_CMN_V86
 # define TMPL_CMN_R86
@@ -652,4 +659,5 @@
 # endif
 # define TMPL_CMN_LM
+# define TMPL_CMN_PAGING
 # define TMPL_CMN_P16
 # define TMPL_16BIT
@@ -701,4 +709,5 @@
 # endif
 # define TMPL_CMN_LM
+# define TMPL_CMN_PAGING
 # define TMPL_CMN_P32
 # define TMPL_32BIT
@@ -750,4 +759,5 @@
 # endif
 # define TMPL_CMN_LM
+# define TMPL_CMN_PAGING
 # define TMPL_CMN_P64
 # define TMPL_64BIT
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-template-header.mac
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-template-header.mac	(revision 59310)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-template-header.mac	(revision 59311)
@@ -51,4 +51,5 @@
 ;       - TMPL_CMN_V86 = TMPL_PEV86 | TMPL_PPV86 | TMPL_PAEV86
 ;       - TMPL_CMN_R86 = TMPL_CMN_V86 | TMPL_RM
+;       - TMPL_CMN_PAGING = TMPL_CMN_PP | TMPL_CMN_PAE | TMPL_CMN_LM
 ;
 %ifdef TMPL_RM
@@ -291,4 +292,5 @@
  %endif
  %define TMPL_CMN_PP
+ %define TMPL_CMN_PAGING
  %define TMPL_CMN_P16
  %define TMPL_16BIT
@@ -341,4 +343,5 @@
  %endif
  %define TMPL_CMN_PP
+ %define TMPL_CMN_PAGING
  %define TMPL_CMN_P32
  %define TMPL_32BIT
@@ -391,4 +394,5 @@
  %endif
  %define TMPL_CMN_PP
+ %define TMPL_CMN_PAGING
  %define TMPL_CMN_V86
  %define TMPL_CMN_R86
@@ -442,4 +446,5 @@
  %endif
  %define TMPL_CMN_PAE
+ %define TMPL_CMN_PAGING
  %define TMPL_16BIT
  %define TMPL_CMN_P16
@@ -492,4 +497,5 @@
  %endif
  %define TMPL_CMN_PAE
+ %define TMPL_CMN_PAGING
  %define TMPL_CMN_P32
  %define TMPL_32BIT
@@ -542,4 +548,5 @@
  %endif
  %define TMPL_CMN_PAE
+ %define TMPL_CMN_PAGING
  %define TMPL_CMN_V86
  %define TMPL_CMN_R86
@@ -593,4 +600,5 @@
  %endif
  %define TMPL_CMN_LM
+ %define TMPL_CMN_PAGING
  %define TMPL_CMN_P16
  %define TMPL_16BIT
@@ -643,4 +651,5 @@
  %endif
  %define TMPL_CMN_LM
+ %define TMPL_CMN_PAGING
  %define TMPL_CMN_P32
  %define TMPL_32BIT
@@ -693,4 +702,5 @@
  %endif
  %define TMPL_CMN_LM
+ %define TMPL_CMN_PAGING
  %define TMPL_CMN_P64
  %define TMPL_64BIT
@@ -857,4 +867,14 @@
 %endif
 
+;; @def BS3_EXTERN_TMPL
+; Mangles the given name into a template specific one.  For ease of use, the
+; name is redefined to the mangled one, just like BS3_EXTERN_CMN does.
+; @note Segment does not change.
+%macro BS3_EXTERN_TMPL 1
+ extern TMPL_NM(%1)
+ %undef  %1
+ %define %1 TMPL_NM(%1)
+%endmacro
+
 ;
 ; Default code segment (changes BITS too).
