Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-first-pe16.asm
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-first-pe16.asm	(revision 60667)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-first-pe16.asm	(revision 60668)
@@ -1,9 +1,9 @@
 ; $Id$
 ;; @file
-; BS3Kit - First Object, calling real-mode main().
+; BS3Kit - First Object, calling 16-bit protected-mode main().
 ;
 
 ;
-; Copyright (C) 2007-2015 Oracle Corporation
+; Copyright (C) 2007-2016 Oracle Corporation
 ;
 ; This file is part of VirtualBox Open Source Edition (OSE), as
@@ -40,139 +40,56 @@
 ;*  External Symbols                                                                                                             *
 ;*********************************************************************************************************************************
-BS3_EXTERN_SYSTEM16 Bs3Lgdt_Gdt
-BS3_EXTERN_SYSTEM16 Bs3Lidt_Idt16
-
-extern Bs3SelProtFar32ToFlat32_c64
-extern Bs3PrintChr_c64
-extern Bs3Printf_c64
-extern Bs3TestTerm_c64
-extern Bs3TestSub_c64
-extern Bs3TestInit_c64
+BS3_BEGIN_DATA16
 
 BS3_BEGIN_RMTEXT16
-EXTERN Bs3InitMemory_rm_far
+extern _Bs3CpuDetect_rm_far
+extern _Bs3InitMemory_rm_far
 
 BS3_BEGIN_TEXT16
-%if 0
-EXTERN Main_pe16
-EXTERN Bs3SwitchToPE16_rm
-EXTERN Bs3SwitchToRM_pe16
-EXTERN Bs3SwitchToPE32_rm
-EXTERN Bs3SwitchTo32Bit_c16
-EXTERN Bs3SwitchTo32Bit_c32
-EXTERN Bs3SwitchTo16Bit_c16
-EXTERN Bs3SwitchTo16Bit_c32
-EXTERN Bs3SwitchToPP16_rm
-EXTERN Bs3SwitchToPP32_rm
-EXTERN Bs3SwitchToPAE16_rm
-EXTERN Bs3SwitchToPAE32_rm
-EXTERN Bs3SwitchToLM64_rm
-EXTERN Bs3SwitchToRM_pe32
-EXTERN Bs3SwitchToRM_pp16
-EXTERN Bs3SwitchToRM_pp32
-EXTERN Bs3SwitchToRM_pae16
-EXTERN Bs3SwitchToRM_pae32
-extern Bs3SwitchToRM_lm64
-extern _Bs3PrintChr_c16
-extern _Bs3PrintChr_c32
-extern Bs3PrintChr_c64
-%endif
-
+BS3_EXTERN_CMN Bs3PicMaskAll
+BS3_EXTERN_CMN Bs3Trap16Init
+extern _Bs3SwitchToPE16_rm
+extern _Main_pe16
 BS3_EXTERN_CMN Bs3Shutdown
-BS3_EXTERN_CMN Bs3Trap32Init
 
 
 BS3_BEGIN_TEXT16
     ;
-    ; We need to enter 16-bit protected mode before we can call Main_pe16.
+    ; Zero return address and zero caller BP.
     ;
-    call far NAME(Bs3InitMemory_rm_far) ; Initialize the memory (must be done from real mode).
-    call    Bs3Trap32Init
-    sub     xSP, 20h                    ; for 64-bit calls.
-%if 0
-    call    NAME(Bs3SwitchToPE16_rm)
-    push    '1'
-    call    NAME(Bs3PrintChr_c16)
-
-    call    NAME(Bs3SwitchTo32Bit_c16)
-    BS3_SET_BITS 32
-    call    NAME(Bs3SwitchTo16Bit_c32)
-    BS3_SET_BITS 16
-    push    '2'
-    call    NAME(Bs3PrintChr_c16)
-
-    call    NAME(Bs3SwitchToRM_pe16)
-
-    call    NAME(Bs3SwitchToPE32_rm)
-    BS3_SET_BITS 32
-    push    '3'
-    call    NAME(Bs3PrintChr_c32)
-    call    NAME(Bs3SwitchToRM_pe32)
-    BS3_SET_BITS 16
-    push    '4'
-    call    NAME(Bs3PrintChr_c16)
-
-    call    NAME(Bs3SwitchToPE16_rm)
-    push    '5'
-    call    NAME(Bs3PrintChr_c16)
-
-    call    NAME(Bs3SwitchToRM_pe16)
-    push    '6'
-    call    NAME(Bs3PrintChr_c16)
-
-    call    NAME(Bs3SwitchToPP16_rm)
-    push    '7'
-    call    NAME(Bs3PrintChr_c16)
-
-    call    NAME(Bs3SwitchToRM_pp16)
-    push    '8'
-    call    NAME(Bs3PrintChr_c16)
-
-    call    NAME(Bs3SwitchToPP32_rm)
-    BS3_SET_BITS 32
-    push    '9'
-    call    NAME(Bs3PrintChr_c32)
-
-    call    NAME(Bs3SwitchToRM_pp32)
-    BS3_SET_BITS 16
-    push    'a'
-    call    NAME(Bs3PrintChr_c16)
-
-    call    NAME(Bs3SwitchToPAE32_rm)
-    BS3_SET_BITS 32
-    push    'b'
-    call    NAME(Bs3PrintChr_c32)
-
-    call    NAME(Bs3SwitchToRM_pae32)
-    BS3_SET_BITS 16
-    push    'c'
-    call    NAME(Bs3PrintChr_c16)
-
-    call    NAME(Bs3SwitchToPAE16_rm)
-    push    'd'
-    call    NAME(Bs3PrintChr_c16)
-
-    call    NAME(Bs3SwitchToRM_pae16)
-    push    'e'
-    call    NAME(Bs3PrintChr_c16)
-
-    call    NAME(Bs3SwitchToLM64_rm)
-    BS3_SET_BITS 64
-    push    'f'
-    BS3_CALL Bs3PrintChr_c64,1
-
-    call    Bs3SwitchToRM_lm64
-    BS3_SET_BITS 16
-    push    'g'
-    call    NAME(Bs3PrintChr_c16)
-%endif
+    xor     ax, ax
+    push    ax
+    push    ax
+    mov     bp, sp
 
     ;
-    ; Call main, if it returns shutdown the system.
+    ; Load DS and ES with data selectors.
     ;
-.halt:
-hlt
-jmp .halt
-;    call    NAME(Main_pe16)
+    mov     ax, BS3KIT_GRPNM_DATA16
+    mov     ds, ax
+    mov     es, ax
+
+
+    ;
+    ; Make sure interrupts are disabled as we cannot (don't want to) service
+    ; BIOS interrupts once we switch mode.
+    ;
+    cli
+    call    Bs3PicMaskAll
+
+    ;
+    ; Initialize 16-bit protected mode.
+    ;
+    call far _Bs3CpuDetect_rm_far
+    call far _Bs3InitMemory_rm_far
+    call    Bs3Trap16Init
+
+    ;
+    ; Switch to PE16 and call main.
+    ;
+    call    _Bs3SwitchToPE16_rm
+    call    _Main_pe16
+
+    ; Try shutdown if it returns.
     call    Bs3Shutdown
 
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-CpuDetect.asm
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-CpuDetect.asm	(revision 60667)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-CpuDetect.asm	(revision 60668)
@@ -127,12 +127,14 @@
         ; assume 386+ if ET=1.
         ;
-        ; However, it turns out the 286 I've got here has bits 4 thru 15 all
-        ; set.  This is very nice though, because only bits 4 and 5 are defined
-        ; on later CPUs and the remainder MBZ.  So, check whether any of the MBZ
-        ; bits are set, if so, then it's 286.
-        ;
+        ; The second idea was to check whether any reserved bits are set,
+        ; because the 286 here has bits 4 thru 15 all set.  Unfortunately, it
+        ; turned out the 386SX and AMD 486DX-40 also sets bits 4 thru 15 when
+        ; using SMSW.  So, nothing conclusive to distinguish 386 from 286, but
+        ; we've probably got a save 486+ detection here.
+        ;
+        ;; @todo check if LOADALL can set any of the reserved bits on a 286 or 386.
         smsw    ax
         test    ax, ~(X86_CR0_PE | X86_CR0_MP | X86_CR0_EM | X86_CR0_TS | X86_CR0_ET | X86_CR0_NE)
-        jnz     .is_286
+        jz      .486plus
 
         ;
@@ -177,4 +179,5 @@
 CPU 386
 .386plus:
+.486plus:
         ;
         ; Check for CPUID and AC.  The former flag indicates CPUID support, the
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-shutdown.c
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-shutdown.c	(revision 60667)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-shutdown.c	(revision 60668)
@@ -1,5 +1,35 @@
+/* $Id$ */
+/** @file
+ * BS3Kit - Shutdown VM from PE16 - proof of concept (BS3Kit).
+ */
 
+/*
+ * 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.h"
 #include <iprt/assert.h>
+#include <iprt/asm-amd64-x86.h>
 
 AssertCompileSize(uint16_t, 2);
@@ -7,57 +37,40 @@
 AssertCompileSize(uint64_t, 8);
 
+extern uint16_t ASMGetMsw();
+#pragma aux ASMGetMsw = \
+    ".286" \
+    "smsw ax" \
+    value [ax] \
+    modify exact;
+
+extern void ASMSetMsw(uint16_t uMsw);
+#pragma aux ASMSetMsw = \
+    ".286p" \
+    "lmsw ax" \
+    parm [ax] \
+    modify exact;
 
 /* Just a sample. */
 BS3_DECL(void) Main_pe16(void)
 {
-    void BS3_FAR *pvTmp1;
-    void BS3_FAR *pvTmp2;
-    void BS3_FAR *pvTmp3;
-    void BS3_FAR *pvTmp4;
+    uint16_t uMsw = ASMGetMsw();
+    Bs3Printf("msw=%#x cr0=%RX32 g_uBs3CpuDetected=%#x\n", uMsw, ASMGetCR0(), g_uBs3CpuDetected);
+    Bs3Printf("cr2=%RX32 cr3=%RX32\n", ASMGetCR2(), ASMGetCR3());
+    ASMSetMsw(X86_CR0_PE);
+    Bs3Printf("lmsw(PE) => msw=%#x cr0=%RX32\n", ASMGetMsw(), ASMGetCR0());
+    ASMSetMsw(UINT16_MAX);
+    Bs3Printf("lmsw(0xffff) => msw=%#x cr0=%RX32\n", ASMGetMsw(), ASMGetCR0());
+    ASMSetCR0(X86_CR0_PE);
+    Bs3Printf("ASMSetCR0(X86_CR0_PE) => msw=%#x cr0=%RX32\n", ASMGetMsw(), ASMGetCR0());
+    ASMSetCR0(UINT32_C(0x7fffffff));
+    Bs3Printf("ASMSetCR0(0x7fffffff) => msw=%#x cr0=%RX32\n", ASMGetMsw(), ASMGetCR0());
 
     Bs3TestInit("bs3-shutdown");
-
-Bs3PrintStr("Bs3PrintX32:");
-Bs3PrintX32(UINT32_C(0xfdb97531));
-Bs3PrintStr("\n");
-
-Bs3Printf("Bs3Printf: RX32=%#'RX32 string='%s' d=%d p=%p\n", UINT32_C(0xfdb97531), "my string", 42, Main_pe16);
-
-pvTmp2 = Bs3MemAlloc(BS3MEMKIND_REAL, _4K);
-Bs3PrintStr("pvTmp2=");
-Bs3PrintX32((uintptr_t)pvTmp2);
-Bs3PrintStr("\n");
-
-pvTmp3 = Bs3MemAlloc(BS3MEMKIND_REAL, _4K);
-Bs3PrintStr("pvTmp3=");
-Bs3PrintX32((uintptr_t)pvTmp3);
-Bs3PrintStr("\n");
-Bs3MemFree(pvTmp2, _4K);
-
-pvTmp4 = Bs3MemAlloc(BS3MEMKIND_REAL, _4K);
-Bs3PrintStr("pvTmp4=");
-Bs3PrintX32((uintptr_t)pvTmp4);
-Bs3PrintStr("\n");
-Bs3PrintStr("\n");
-
-pvTmp1 = Bs3MemAlloc(BS3MEMKIND_REAL, 31);
-Bs3PrintStr("pvTmp1=");
-Bs3PrintX32((uintptr_t)pvTmp1);
-Bs3PrintStr("\n");
-
-pvTmp2 = Bs3MemAlloc(BS3MEMKIND_REAL, 17);
-Bs3PrintStr("pvTmp2=");
-Bs3PrintX32((uintptr_t)pvTmp2);
-Bs3PrintStr("\n");
-
-Bs3MemFree(pvTmp1, 31);
-pvTmp3 = Bs3MemAlloc(BS3MEMKIND_REAL, 17);
-Bs3PrintStr("pvTmp3=");
-Bs3PrintX32((uintptr_t)pvTmp3);
-Bs3PrintStr("\n");
-
-
-Bs3Panic();
+    Bs3TestPrintf("detected cpu: %#x\n", g_uBs3CpuDetected);
+#if 1
+    ASMHalt();
+#else
     Bs3Shutdown();
+#endif
     return;
 }
