Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-basic-2-template.c
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-basic-2-template.c	(revision 60748)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-basic-2-template.c	(revision 60749)
@@ -1445,4 +1445,5 @@
 }
 
+#if TMPL_BITS == 16
 
 /**
@@ -2046,4 +2047,88 @@
 }
 
+BS3_DECL_FAR(uint8_t) BS3_CMN_FAR_NM(bs3CpuBasic2_sidt)(uint8_t bMode)
+{
+    union
+    {
+        RTIDTR  Idtr;
+        uint8_t ab[16];
+    } Expected;
+
+    g_pszTestMode = Bs3GetModeName(bMode);
+    g_bTestMode   = bMode;
+    g_f16BitSys   = BS3_MODE_IS_16BIT_SYS(bMode);
+
+
+    /*
+     * Pass to common worker which is only compiled once per mode.
+     */
+    Bs3MemZero(&Expected, sizeof(Expected));
+    ASMGetIDTR(&Expected.Idtr);
+    bs3CpuBasic2_sidt_sgdt_Common(bMode, g_aSidtWorkers, RT_ELEMENTS(g_aSidtWorkers), Expected.ab);
+
+    /*
+     * Re-initialize the IDT.
+     */
+    Bs3TrapReInit();
+    return 0;
+}
+
+
+BS3_DECL_FAR(uint8_t) BS3_CMN_FAR_NM(bs3CpuBasic2_sgdt)(uint8_t bMode)
+{
+    uint64_t const uOrgAddr = Bs3Lgdt_Gdt.uAddr;
+    uint64_t       uNew     = 0;
+    union
+    {
+        RTGDTR  Gdtr;
+        uint8_t ab[16];
+    } Expected;
+
+    g_pszTestMode = Bs3GetModeName(bMode);
+    g_bTestMode   = bMode;
+    g_f16BitSys   = BS3_MODE_IS_16BIT_SYS(bMode);
+
+    /*
+     * If paged mode, try push the GDT way up.
+     */
+    if (BS3_MODE_IS_PAGED(bMode))
+    {
+/** @todo loading non-canonical base addresses.   */
+        int rc;
+        uNew  = BS3_MODE_IS_64BIT_SYS(bMode) ? UINT64_C(0xffff80fedcb70000) : UINT64_C(0xc2d28000);
+        uNew |= uOrgAddr & X86_PAGE_OFFSET_MASK;
+        rc = Bs3PagingAlias(uNew, uOrgAddr, Bs3Lgdt_Gdt.cb, X86_PTE_P | X86_PTE_RW | X86_PTE_US | X86_PTE_D | X86_PTE_A);
+        if (RT_SUCCESS(rc))
+        {
+            Bs3Lgdt_Gdt.uAddr = uNew;
+            Bs3UtilSetFullGdtr(Bs3Lgdt_Gdt.cb, uNew);
+        }
+    }
+
+    /*
+     * Pass to common worker which is only compiled once per mode.
+     */
+    Bs3MemZero(&Expected, sizeof(Expected));
+    ASMGetGDTR(&Expected.Gdtr);
+    bs3CpuBasic2_sidt_sgdt_Common(bMode, g_aSgdtWorkers, RT_ELEMENTS(g_aSgdtWorkers), Expected.ab);
+
+    /*
+     * Unalias the GDT.
+     */
+    if (uNew != 0)
+    {
+        Bs3Lgdt_Gdt.uAddr = uOrgAddr;
+        Bs3UtilSetFullGdtr(Bs3Lgdt_Gdt.cb, uOrgAddr);
+        Bs3PagingUnalias(uNew, Bs3Lgdt_Gdt.cb);
+    }
+
+    /*
+     * Re-initialize the IDT.
+     */
+    Bs3TrapReInit();
+    return 0;
+}
+
+
 
 /*
@@ -2751,4 +2836,75 @@
 
 
+BS3_DECL_FAR(uint8_t) BS3_CMN_FAR_NM(bs3CpuBasic2_lidt)(uint8_t bMode)
+{
+    union
+    {
+        RTIDTR  Idtr;
+        uint8_t ab[32]; /* At least cbIdtr*2! */
+    } Expected;
+
+    g_pszTestMode = Bs3GetModeName(bMode);
+    g_bTestMode   = bMode;
+    g_f16BitSys   = BS3_MODE_IS_16BIT_SYS(bMode);
+
+    /*
+     * Pass to common worker which is only compiled once per mode.
+     */
+    Bs3MemZero(&Expected, sizeof(Expected));
+    ASMGetIDTR(&Expected.Idtr);
+
+    if (BS3_MODE_IS_RM_SYS(bMode))
+        bs3CpuBasic2_lidt_lgdt_Common(bMode, g_aLidtWorkers, RT_ELEMENTS(g_aLidtWorkers),
+                                      &Bs3Lidt_Ivt, sizeof(Bs3Lidt_Ivt), Expected.ab);
+    else if (BS3_MODE_IS_16BIT_SYS(bMode))
+        bs3CpuBasic2_lidt_lgdt_Common(bMode, g_aLidtWorkers, RT_ELEMENTS(g_aLidtWorkers),
+                                      &Bs3Lidt_Idt16, sizeof(Bs3Lidt_Idt16), Expected.ab);
+    else if (BS3_MODE_IS_32BIT_SYS(bMode))
+        bs3CpuBasic2_lidt_lgdt_Common(bMode, g_aLidtWorkers, RT_ELEMENTS(g_aLidtWorkers),
+                                      &Bs3Lidt_Idt32, sizeof(Bs3Lidt_Idt32), Expected.ab);
+    else
+        bs3CpuBasic2_lidt_lgdt_Common(bMode, g_aLidtWorkers, RT_ELEMENTS(g_aLidtWorkers),
+                                      &Bs3Lidt_Idt64, sizeof(Bs3Lidt_Idt64), Expected.ab);
+
+    /*
+     * Re-initialize the IDT.
+     */
+    Bs3TrapReInit();
+    return 0;
+}
+
+
+BS3_DECL_FAR(uint8_t) BS3_CMN_FAR_NM(bs3CpuBasic2_lgdt)(uint8_t bMode)
+{
+    union
+    {
+        RTGDTR  Gdtr;
+        uint8_t ab[32]; /* At least cbIdtr*2! */
+    } Expected;
+
+    g_pszTestMode = Bs3GetModeName(bMode);
+    g_bTestMode   = bMode;
+    g_f16BitSys   = BS3_MODE_IS_16BIT_SYS(bMode);
+
+    /*
+     * Pass to common worker which is only compiled once per mode.
+     */
+    if (BS3_MODE_IS_RM_SYS(bMode))
+        ASMSetGDTR((PRTGDTR)&Bs3LgdtDef_Gdt);
+    Bs3MemZero(&Expected, sizeof(Expected));
+    ASMGetGDTR(&Expected.Gdtr);
+
+    bs3CpuBasic2_lidt_lgdt_Common(bMode, g_aLgdtWorkers, RT_ELEMENTS(g_aLgdtWorkers),
+                                  &Bs3LgdtDef_Gdt, sizeof(Bs3LgdtDef_Gdt), Expected.ab);
+
+    /*
+     * Re-initialize the IDT.
+     */
+    Bs3TrapReInit();
+    return 0;
+}
+#endif /* TMPL_BITS == 16 */
+
+
 # if ARCH_BITS != 64
 
@@ -2997,161 +3153,29 @@
 
 
+# if 0
 BS3_DECL_FAR(uint8_t) TMPL_NM(bs3CpuBasic2_sidt)(uint8_t bMode)
 {
-    union
-    {
-        RTIDTR  Idtr;
-        uint8_t ab[16];
-    } Expected;
-
-    g_pszTestMode = TMPL_NM(g_szBs3ModeName);
-    g_bTestMode   = bMode;
-    g_f16BitSys   = BS3_MODE_IS_16BIT_SYS(TMPL_MODE);
-
     BS3_ASSERT(bMode == TMPL_MODE);
-
-    /*
-     * Pass to common worker which is only compiled once per mode.
-     */
-    Bs3MemZero(&Expected, sizeof(Expected));
-    ASMGetIDTR(&Expected.Idtr);
-    bs3CpuBasic2_sidt_sgdt_Common(bMode, g_aSidtWorkers, RT_ELEMENTS(g_aSidtWorkers), Expected.ab);
-
-    /*
-     * Re-initialize the IDT.
-     */
-    Bs3TrapInit();
-    return 0;
+    return BS3_CMN_FAR_NM(bs3CpuBasic2_sidt)(bMode);
 }
 
-
 BS3_DECL_FAR(uint8_t) TMPL_NM(bs3CpuBasic2_sgdt)(uint8_t bMode)
 {
-    uint64_t const uOrgAddr = Bs3Lgdt_Gdt.uAddr;
-    uint64_t       uNew     = 0;
-    union
-    {
-        RTGDTR  Gdtr;
-        uint8_t ab[16];
-    } Expected;
-
-    g_pszTestMode = TMPL_NM(g_szBs3ModeName);
-    g_bTestMode   = bMode;
-    g_f16BitSys   = BS3_MODE_IS_16BIT_SYS(TMPL_MODE);
     BS3_ASSERT(bMode == TMPL_MODE);
-
-    /*
-     * If paged mode, try push the GDT way up.
-     */
-    if (BS3_MODE_IS_PAGED(bMode))
-    {
-/** @todo loading non-canonical base addresses.   */
-        int rc;
-        uNew  = BS3_MODE_IS_64BIT_SYS(bMode) ? UINT64_C(0xffff80fedcb70000) : UINT64_C(0xc2d28000);
-        uNew |= uOrgAddr & X86_PAGE_OFFSET_MASK;
-        rc = Bs3PagingAlias(uNew, uOrgAddr, Bs3Lgdt_Gdt.cb, X86_PTE_P | X86_PTE_RW | X86_PTE_US | X86_PTE_D | X86_PTE_A);
-        if (RT_SUCCESS(rc))
-        {
-            Bs3Lgdt_Gdt.uAddr = uNew;
-            Bs3UtilSetFullGdtr(Bs3Lgdt_Gdt.cb, uNew);
-        }
-    }
-
-    /*
-     * Pass to common worker which is only compiled once per mode.
-     */
-    Bs3MemZero(&Expected, sizeof(Expected));
-    ASMGetGDTR(&Expected.Gdtr);
-    bs3CpuBasic2_sidt_sgdt_Common(bMode, g_aSgdtWorkers, RT_ELEMENTS(g_aSgdtWorkers), Expected.ab);
-
-    /*
-     * Unalias the GDT.
-     */
-    if (uNew != 0)
-    {
-        Bs3Lgdt_Gdt.uAddr = uOrgAddr;
-        Bs3UtilSetFullGdtr(Bs3Lgdt_Gdt.cb, uOrgAddr);
-        Bs3PagingUnalias(uNew, Bs3Lgdt_Gdt.cb);
-    }
-
-    /*
-     * Re-initialize the IDT.
-     */
-    Bs3TrapInit();
-    return 0;
+    return BS3_CMN_FAR_NM(bs3CpuBasic2_sgdt)(bMode);
 }
 
-
 BS3_DECL_FAR(uint8_t) TMPL_NM(bs3CpuBasic2_lidt)(uint8_t bMode)
 {
-    union
-    {
-        RTIDTR  Idtr;
-        uint8_t ab[32]; /* At least cbIdtr*2! */
-    } Expected;
-
-    g_pszTestMode = TMPL_NM(g_szBs3ModeName);
-    g_bTestMode   = bMode;
-    g_f16BitSys   = BS3_MODE_IS_16BIT_SYS(TMPL_MODE);
-
     BS3_ASSERT(bMode == TMPL_MODE);
-
-    /*
-     * Pass to common worker which is only compiled once per mode.
-     */
-    Bs3MemZero(&Expected, sizeof(Expected));
-    ASMGetIDTR(&Expected.Idtr);
-
-    if (BS3_MODE_IS_RM_SYS(bMode))
-        bs3CpuBasic2_lidt_lgdt_Common(bMode, g_aLidtWorkers, RT_ELEMENTS(g_aLidtWorkers),
-                                      &Bs3Lidt_Ivt, sizeof(Bs3Lidt_Ivt), Expected.ab);
-    else if (BS3_MODE_IS_16BIT_SYS(bMode))
-        bs3CpuBasic2_lidt_lgdt_Common(bMode, g_aLidtWorkers, RT_ELEMENTS(g_aLidtWorkers),
-                                      &Bs3Lidt_Idt16, sizeof(Bs3Lidt_Idt16), Expected.ab);
-    else if (BS3_MODE_IS_32BIT_SYS(bMode))
-        bs3CpuBasic2_lidt_lgdt_Common(bMode, g_aLidtWorkers, RT_ELEMENTS(g_aLidtWorkers),
-                                      &Bs3Lidt_Idt32, sizeof(Bs3Lidt_Idt32), Expected.ab);
-    else
-        bs3CpuBasic2_lidt_lgdt_Common(bMode, g_aLidtWorkers, RT_ELEMENTS(g_aLidtWorkers),
-                                      &Bs3Lidt_Idt64, sizeof(Bs3Lidt_Idt64), Expected.ab);
-
-    /*
-     * Re-initialize the IDT.
-     */
-    Bs3TrapInit();
-    return 0;
+    return BS3_CMN_FAR_NM(bs3CpuBasic2_lidt)(bMode);
 }
 
 BS3_DECL_FAR(uint8_t) TMPL_NM(bs3CpuBasic2_lgdt)(uint8_t bMode)
 {
-    union
-    {
-        RTGDTR  Gdtr;
-        uint8_t ab[32]; /* At least cbIdtr*2! */
-    } Expected;
-
-    g_pszTestMode = TMPL_NM(g_szBs3ModeName);
-    g_bTestMode   = bMode;
-    g_f16BitSys   = BS3_MODE_IS_16BIT_SYS(TMPL_MODE);
-
     BS3_ASSERT(bMode == TMPL_MODE);
-
-    /*
-     * Pass to common worker which is only compiled once per mode.
-     */
-    if (BS3_MODE_IS_RM_SYS(bMode))
-        ASMSetGDTR((PRTGDTR)&Bs3LgdtDef_Gdt);
-    Bs3MemZero(&Expected, sizeof(Expected));
-    ASMGetGDTR(&Expected.Gdtr);
-
-    bs3CpuBasic2_lidt_lgdt_Common(bMode, g_aLgdtWorkers, RT_ELEMENTS(g_aLgdtWorkers),
-                                  &Bs3LgdtDef_Gdt, sizeof(Bs3LgdtDef_Gdt), Expected.ab);
-
-    /*
-     * Re-initialize the IDT.
-     */
-    Bs3TrapInit();
-    return 0;
+    return BS3_CMN_FAR_NM(bs3CpuBasic2_lgdt)(bMode);
 }
+# endif
 
 #endif /* BS3_INSTANTIATING_MODE */
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-basic-2.c
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-basic-2.c	(revision 60748)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-basic-2.c	(revision 60749)
@@ -38,5 +38,4 @@
 BS3TESTMODE_PROTOTYPES_MODE(bs3CpuBasic2_TssGateEsp);
 BS3TESTMODE_PROTOTYPES_MODE(bs3CpuBasic2_RaiseXcpt1);
-//BS3TESTMODE_PROTOTYPES_CMN(bs3CpuBasic2_iret);
 BS3TESTMODE_PROTOTYPES_MODE(bs3CpuBasic2_iret);
 BS3TESTMODE_PROTOTYPES_MODE(bs3CpuBasic2_sidt);
@@ -45,20 +44,33 @@
 BS3TESTMODE_PROTOTYPES_MODE(bs3CpuBasic2_lgdt);
 
+FNBS3TESTDOMODE             bs3CpuBasic2_sidt_f16;
+FNBS3TESTDOMODE             bs3CpuBasic2_sgdt_f16;
+FNBS3TESTDOMODE             bs3CpuBasic2_lidt_f16;
+FNBS3TESTDOMODE             bs3CpuBasic2_lgdt_f16;
+FNBS3TESTDOMODE             bs3CpuBasic2_iret_f16;
+
 
 /*********************************************************************************************************************************
 *   Global Variables                                                                                                             *
 *********************************************************************************************************************************/
+#if 0
 static const BS3TESTMODEENTRY g_aModeTest[] =
 {
-    //BS3TESTMODEENTRY_MODE("tss / gate / esp", bs3CpuBasic2_TssGateEsp),
-    //BS3TESTMODEENTRY_CMN("iret", bs3CpuBasic2_iret),
+#if 0
+    BS3TESTMODEENTRY_MODE("tss / gate / esp", bs3CpuBasic2_TssGateEsp),
+    BS3TESTMODEENTRY_MODE("raise xcpt #1", bs3CpuBasic2_RaiseXcpt1),
+//    BS3TESTMODEENTRY_MODE("sidt", bs3CpuBasic2_sidt),
+//    BS3TESTMODEENTRY_MODE("sgdt", bs3CpuBasic2_sgdt),
+//    BS3TESTMODEENTRY_MODE("lidt", bs3CpuBasic2_lidt),
+//    BS3TESTMODEENTRY_MODE("lgdt", bs3CpuBasic2_lgdt),
+#endif
 //    BS3TESTMODEENTRY_MODE("iret", bs3CpuBasic2_iret),
-#if 1
-    BS3TESTMODEENTRY_MODE("raise xcpt #1", bs3CpuBasic2_RaiseXcpt1),
-    BS3TESTMODEENTRY_MODE("sidt", bs3CpuBasic2_sidt),
-    BS3TESTMODEENTRY_MODE("sgdt", bs3CpuBasic2_sgdt),
+};
 #endif
-    BS3TESTMODEENTRY_MODE("lidt", bs3CpuBasic2_lidt),
-    BS3TESTMODEENTRY_MODE("lgdt", bs3CpuBasic2_lgdt),
+
+static const BS3TESTMODEBYONEENTRY g_aModeByOneTests[] =
+{
+    //{ "iret", bs3CpuBasic2_iret_f16, 0 },
+    { "lgdt", bs3CpuBasic2_lgdt_f16, 0 },
 };
 
@@ -70,8 +82,9 @@
     Bs3TestPrintf("g_uBs3CpuDetected=%#x\n", g_uBs3CpuDetected);
 
-    Bs3TestDoModes_rm(g_aModeTest, RT_ELEMENTS(g_aModeTest));
+    //Bs3TestDoModes_rm(g_aModeTest, RT_ELEMENTS(g_aModeTest));
+    Bs3TestDoModesByOne_rm(g_aModeByOneTests, RT_ELEMENTS(g_aModeByOneTests), 0);
 
     Bs3TestTerm();
-for (;;) { }
+for (;;) { ASMHalt(); }
 }
 
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/Makefile.kmk
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/Makefile.kmk	(revision 60748)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/Makefile.kmk	(revision 60749)
@@ -55,4 +55,5 @@
 	bs3-cmn-A20Disable.asm \
 	bs3-cmn-A20Enable.asm \
+	bs3-cmn-GetModeName.c \
 	bs3-cmn-KbdRead.asm \
 	bs3-cmn-KbdWait.asm \
@@ -145,4 +146,5 @@
 	bs3-cmn-TestCheckRegCtxEx.c \
 	bs3-cmn-TestPrintf.c \
+	bs3-cmn-TrapReInit.c \
 	bs3-cmn-TrapRmV86Init.c \
 	bs3-cmn-TrapRmV86SetGate.c \
@@ -161,4 +163,5 @@
        bs3-cmn-UtilSetFullGdtr.asm \
        bs3-cmn-UtilSetFullIdtr.asm \
+       bs3-cmn-TestDoModesByOneHlp.asm \
        ../../../Runtime/common/asm/ASMBitFirstClear.asm \
        ../../../Runtime/common/asm/ASMBitFirstSet.asm \
@@ -281,4 +284,5 @@
 	bs3-mode-TrapSystemCallHandler.asm \
 	bs3-mode-TestDoModes.c \
+	bs3-mode-TestDoModesByOne.c \
 	bs3-mode-TestDoModesHlp.asm \
 
@@ -290,5 +294,6 @@
 bs3kit-rm_SOURCES  = $(VBOX_BS3KIT_MODE_SOURCES) \
 	bs3-first-rm.asm \
-	bs3-mode-CpuDetect.asm
+	bs3-mode-CpuDetect.asm \
+	bs3-mode-TestDoModesByOneStub.asm \
 
 
@@ -300,4 +305,5 @@
 bs3kit-pe16_SOURCES  = $(VBOX_BS3KIT_MODE_SOURCES) \
 	bs3-first-pe16.asm \
+	bs3-mode-TestDoModesByOneStub.asm \
 #	bs3-mode-CpuDetect.asm
 
@@ -307,5 +313,6 @@
 bs3kit-pe16_32_INSTTYPE = none
 bs3kit-pe16_32_DEFS     = TMPL_MODE=BS3_MODE_PE16_32
-bs3kit-pe16_32_SOURCES  = $(VBOX_BS3KIT_MODE_SOURCES)
+bs3kit-pe16_32_SOURCES  = $(VBOX_BS3KIT_MODE_SOURCES) \
+	bs3-mode-TestDoModesByOneStub.asm \
 
 # The v86 BS3Kit library for 16-bit protected kernel+tss.
@@ -314,5 +321,6 @@
 bs3kit-pe16_v86_INSTTYPE = none
 bs3kit-pe16_v86_DEFS     = TMPL_MODE=BS3_MODE_PE16_V86
-bs3kit-pe16_v86_SOURCES  = $(VBOX_BS3KIT_MODE_SOURCES)
+bs3kit-pe16_v86_SOURCES  = $(VBOX_BS3KIT_MODE_SOURCES) \
+	bs3-mode-TestDoModesByOneStub.asm \
 
 # The 32-bit BS3Kit library for 32-bit protected kernel+tss.
@@ -328,5 +336,6 @@
 bs3kit-pe32_16_INSTTYPE = none
 bs3kit-pe32_16_DEFS     = TMPL_MODE=BS3_MODE_PE32_16
-bs3kit-pe32_16_SOURCES  = $(VBOX_BS3KIT_MODE_SOURCES)
+bs3kit-pe32_16_SOURCES  = $(VBOX_BS3KIT_MODE_SOURCES) \
+	bs3-mode-TestDoModesByOneStub.asm \
 
 # The v8086 BS3Kit library for 32-bit protected kernel+tss.
@@ -337,5 +346,4 @@
 bs3kit-pev86_SOURCES  = $(VBOX_BS3KIT_MODE_SOURCES)
 
-
 # The 16-bit BS3Kit library for 16-bit paged protected kernel+tss.
 LIBRARIES += bs3kit-pp16
@@ -344,5 +352,6 @@
 bs3kit-pp16_DEFS     = TMPL_MODE=BS3_MODE_PP16
 bs3kit-pp16_SOURCES  = $(VBOX_BS3KIT_MODE_SOURCES) \
-	bs3-mode-CpuDetect.asm
+	bs3-mode-CpuDetect.asm \
+	bs3-mode-TestDoModesByOneStub.asm \
 
 # The 32-bit BS3Kit library for 16-bit paged protected kernel+tss.
@@ -372,5 +381,6 @@
 bs3kit-pp32_16_INSTTYPE = none
 bs3kit-pp32_16_DEFS     = TMPL_MODE=BS3_MODE_PP32_16
-bs3kit-pp32_16_SOURCES  = $(VBOX_BS3KIT_MODE_SOURCES)
+bs3kit-pp32_16_SOURCES  = $(VBOX_BS3KIT_MODE_SOURCES) \
+	bs3-mode-TestDoModesByOneStub.asm \
 
 # The v8086 BS3Kit library for 32-bit paged protected kernel+tss.
@@ -388,5 +398,6 @@
 bs3kit-pae16_DEFS     = TMPL_MODE=BS3_MODE_PAE16
 bs3kit-pae16_SOURCES  = $(VBOX_BS3KIT_MODE_SOURCES) \
-	bs3-mode-CpuDetect.asm
+	bs3-mode-CpuDetect.asm \
+	bs3-mode-TestDoModesByOneStub.asm \
 
 # The 16-bit BS3Kit library for 16-bit PAE paged protected kernel+tss.
@@ -416,5 +427,6 @@
 bs3kit-pae32_16_INSTTYPE = none
 bs3kit-pae32_16_DEFS     = TMPL_MODE=BS3_MODE_PAE32_16
-bs3kit-pae32_16_SOURCES  = $(VBOX_BS3KIT_MODE_SOURCES)
+bs3kit-pae32_16_SOURCES  = $(VBOX_BS3KIT_MODE_SOURCES) \
+	bs3-mode-TestDoModesByOneStub.asm \
 
 # The v8086 BS3Kit library for 32-bit PAE paged protected kernel+tss.
@@ -431,5 +443,6 @@
 bs3kit-lm16_INSTTYPE = none
 bs3kit-lm16_DEFS     = TMPL_MODE=BS3_MODE_LM16
-bs3kit-lm16_SOURCES  = $(VBOX_BS3KIT_MODE_SOURCES)
+bs3kit-lm16_SOURCES  = $(VBOX_BS3KIT_MODE_SOURCES) \
+	bs3-mode-TestDoModesByOneStub.asm \
 
 # The 32-bit long mode BS3Kit library.
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-GetModeName.c
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-GetModeName.c	(revision 60749)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-GetModeName.c	(revision 60749)
@@ -0,0 +1,62 @@
+/* $Id$ */
+/** @file
+ * BS3Kit - Bs3GetModeName
+ */
+
+/*
+ * 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.h"
+
+
+
+#undef Bs3GetModeName
+BS3_CMN_DEF(const char BS3_FAR *, Bs3GetModeName,(uint8_t bMode))
+{
+    switch (bMode)
+    {
+        case BS3_MODE_RM:           return g_szBs3ModeName_rm;
+        case BS3_MODE_PE16:         return g_szBs3ModeName_pe16;
+        case BS3_MODE_PE16_32:      return g_szBs3ModeName_pe16_32;
+        case BS3_MODE_PE16_V86:     return g_szBs3ModeName_pe16_v86;
+        case BS3_MODE_PE32:         return g_szBs3ModeName_pe32;
+        case BS3_MODE_PE32_16:      return g_szBs3ModeName_pe32_16;
+        case BS3_MODE_PEV86:        return g_szBs3ModeName_pev86;
+        case BS3_MODE_PP16:         return g_szBs3ModeName_pp16;
+        case BS3_MODE_PP16_32:      return g_szBs3ModeName_pp16_32;
+        case BS3_MODE_PP16_V86:     return g_szBs3ModeName_pp16_v86;
+        case BS3_MODE_PP32:         return g_szBs3ModeName_pp32;
+        case BS3_MODE_PP32_16:      return g_szBs3ModeName_pp32_16;
+        case BS3_MODE_PPV86:        return g_szBs3ModeName_ppv86;
+        case BS3_MODE_PAE16:        return g_szBs3ModeName_pae16;
+        case BS3_MODE_PAE16_32:     return g_szBs3ModeName_pae16_32;
+        case BS3_MODE_PAE16_V86:    return g_szBs3ModeName_pae16_v86;
+        case BS3_MODE_PAE32:        return g_szBs3ModeName_pae32;
+        case BS3_MODE_PAE32_16:     return g_szBs3ModeName_pae32_16;
+        case BS3_MODE_PAEV86:       return g_szBs3ModeName_paev86;
+        case BS3_MODE_LM16:         return g_szBs3ModeName_lm16;
+        case BS3_MODE_LM32:         return g_szBs3ModeName_lm32;
+        case BS3_MODE_LM64:         return g_szBs3ModeName_lm64;
+        case BS3_MODE_INVALID:      return "invalid";
+        default:                    return "unknow";
+    }
+}
+
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-RegCtxRestore.asm
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-RegCtxRestore.asm	(revision 60748)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-RegCtxRestore.asm	(revision 60749)
@@ -35,4 +35,5 @@
 TMPL_BEGIN_TEXT
 BS3_EXTERN_CMN Bs3Syscall
+BS3_EXTERN_CMN Bs3Panic
 TMPL_BEGIN_TEXT
 
@@ -80,16 +81,25 @@
 
 .do_syscall_restore_ctx:
-%if TMPL_BITS == 16
+%if TMPL_BITS != 16
+.do_syscall_restore_ctx_restore_ds:
+        mov     cx, ds
+        mov     xSI, [xBP + xCB*2]
+        movzx   edx, word [xBP + xCB*3]
+        mov     eax, BS3_SYSCALL_RESTORE_CTX
+%else
         mov     si, [bp + xCB + cbCurRetAddr]
         mov     cx, [bp + xCB + cbCurRetAddr + 2]
         mov     dx, [bp + xCB + cbCurRetAddr + sCB]
         mov     ax, BS3_SYSCALL_RESTORE_CTX
-%else
-        mov     cx, ds
-        mov     xSI, [xBP + xCB*2]
-        movzx   edx, word [xBP + xCB*3]
-        mov     eax, BS3_SYSCALL_RESTORE_CTX
 %endif
         call    Bs3Syscall
+        call    Bs3Panic
+
+%if TMPL_BITS == 16
+.do_syscall_restore_ctx_restore_ds:
+        push    es
+        pop     ds
+        jmp     .do_syscall_restore_ctx
+%endif
 
         ;
@@ -115,4 +125,12 @@
 %endif
 
+
+%if TMPL_BITS != 64
+        ; Restoring a 64-bit context is best done from 64-bit code.
+        mov     al, [xBX + BS3REGCTX.bMode]
+        test    al, BS3_MODE_CODE_64
+        jnz     .do_syscall_restore_ctx_restore_ds
+%endif
+
         ; The remainder must be done with interrupts disabled.
         cli
@@ -121,5 +139,7 @@
         ; Update g_bs3CurrentMode.
         ;
+%if TMPL_BITS == 64
         mov     al, [xBX + BS3REGCTX.bMode]
+%endif
         and     al, BS3_MODE_CODE_MASK
         mov     ah, [BS3_ONLY_16BIT(es:) BS3_DATA16_WRT(g_bBs3CurrentMode)]
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-RegCtxSaveEx.asm
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-RegCtxSaveEx.asm	(revision 60748)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-RegCtxSaveEx.asm	(revision 60749)
@@ -77,4 +77,5 @@
 %if TMPL_BITS != 64
 extern              _Bs3RegCtxSave_c64
+extern              _Bs3SwitchTo%[TMPL_BITS]Bit_c64
 %endif
 
@@ -103,5 +104,5 @@
         and     dl, BS3_MODE_CODE_MASK
 %if TMPL_BITS == 16
-        push    dx                          ; xBP - xCB*1: save space for previous CPU mode (16-bit)
+        push    dx                          ; bp - 2: previous CPU mode (16-bit)
 %endif
 
@@ -286,6 +287,6 @@
 
  %if TMPL_BITS == 16
-        cmp     byte [xBP - xCB*1], BS3_MODE_CODE_16
-        jne     .code_32_back_to_v86
+        cmp     byte [bp - 2], BS3_MODE_CODE_V86
+        je      .code_32_back_to_v86
         call    _Bs3SwitchTo16Bit_c32
         BS3_SET_BITS TMPL_BITS
@@ -328,6 +329,6 @@
         call    _Bs3RegCtxSave_c64          ; No BS3_CALL as rcx is already ready.
 
-        call    _Bs3SwitchTo16Bit_c32
-        BS3_SET_BITS 16
+        call    _Bs3SwitchTo%[TMPL_BITS]Bit_c64
+        BS3_SET_BITS TMPL_BITS
         jmp     .return
 %endif
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-SwitchTo64Bit.asm
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-SwitchTo64Bit.asm	(revision 60748)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-SwitchTo64Bit.asm	(revision 60749)
@@ -74,5 +74,5 @@
         push    sAX
  %if TMPL_BITS == 16
-        push    dword .sixty_four_bit
+        push    dword .sixty_four_bit wrt FLAT
         o32 retf
  %else
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-TestDoModesByOneHlp.asm
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-TestDoModesByOneHlp.asm	(revision 60749)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-TestDoModesByOneHlp.asm	(revision 60749)
@@ -0,0 +1,244 @@
+; $Id$
+;; @file
+; BS3Kit - Bs3TestDoModesByOne Helpers for switching to the bit-count of the worker function.
+;
+
+;
+; 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-template-header.mac"
+
+
+;*********************************************************************************************************************************
+;*  Global Variables                                                                                                             *
+;*********************************************************************************************************************************
+BS3_BEGIN_DATA16
+BS3_GLOBAL_NAME_EX BS3_CMN_NM(g_pfnBs3TestDoModesByOneCurrent),,0
+    RTCCPTR_DEF     0
+
+
+;*********************************************************************************************************************************
+;*  Exported Symbols                                                                                                             *
+;*********************************************************************************************************************************
+%ifdef BS3_STRICT
+BS3_EXTERN_DATA16 g_bBs3CurrentMode
+%endif
+
+%if TMPL_BITS == 16
+BS3_BEGIN_TEXT16
+extern  _Bs3SelRealModeCodeToProtMode_c16
+%endif
+
+
+;;
+; @cproto FNBS3TESTDOMODE
+;
+; @param    bMode       The current mode
+; @uses     What allowed by calling convention and possibly mode, caller deals with it.
+;
+
+%if TMPL_BITS == 16
+        ;
+        ; For 16-bit workers.
+        ;
+BS3_BEGIN_TEXT16
+
+BS3_SET_BITS 32
+BS3_PROC_BEGIN _Bs3TestCallDoerTo16_c32
+        push    xBP
+        mov     xBP, xSP
+
+        ; Load bMode into eax.
+        movzx   eax, byte [xBP + xCB*2]
+ %ifdef BS3_STRICT
+        cmp     al, [BS3_DATA16_WRT(g_bBs3CurrentMode)]
+        je      .ok_mode
+        int3
+.ok_mode:
+ %endif
+        ; Switch to 16-bit.
+        extern  _Bs3SwitchTo16Bit_c32
+        call    _Bs3SwitchTo16Bit_c32
+        BS3_SET_BITS 16
+
+        push    ax                                                  ; Worker bMode argument.
+
+        ; Assuming real mode far pointer, convert protected mode before calling it.
+        push    word [BS3_CMN_NM(g_pfnBs3TestDoModesByOneCurrent) + 2]
+        call    _Bs3SelRealModeCodeToProtMode_c16
+        add     sp, 2
+
+        push    cs                                                  ; return selector
+        push    word .return                                        ; return address
+
+        push    ax                                                  ; call converted selector
+        push    word [BS3_CMN_NM(g_pfnBs3TestDoModesByOneCurrent)]  ; call offset
+        retf
+
+.return:
+        ; Switch back to 32-bit mode.
+        extern  _Bs3SwitchTo32Bit_c16
+        call    _Bs3SwitchTo32Bit_c16
+        BS3_SET_BITS 32
+
+        leave
+        ret
+BS3_PROC_END   _Bs3TestCallDoerTo16_c32
+
+
+BS3_SET_BITS 64
+BS3_PROC_BEGIN _Bs3TestCallDoerTo16_c64
+        push    xBP
+        mov     xBP, xSP
+
+        ; Load bMode into eax.
+        movzx   eax, cl
+ %ifdef BS3_STRICT
+        cmp     al, [BS3_DATA16_WRT(g_bBs3CurrentMode)]
+        je      .ok_mode
+        int3
+.ok_mode:
+ %endif
+        ; Switch to 16-bit.
+        extern  _Bs3SwitchTo16Bit_c64
+        call    _Bs3SwitchTo16Bit_c64
+        BS3_SET_BITS 16
+
+        push    ax                                                  ; Worker bMode argument.
+
+        ; Assuming real mode far pointer, convert protected mode before calling it.
+        push    word [BS3_CMN_NM(g_pfnBs3TestDoModesByOneCurrent) + 2]
+        call    _Bs3SelRealModeCodeToProtMode_c16
+        add     sp, 2
+
+        push    cs                                                  ; return selector
+        push    word .return                                        ; return address
+        push    ax                                                  ; call converted selector
+        push    word [BS3_CMN_NM(g_pfnBs3TestDoModesByOneCurrent)]  ; call offset
+        retf
+
+.return:
+hlt
+        ; Switch back to 64-bit mode.
+        extern  _Bs3SwitchTo64Bit_c16
+        call    _Bs3SwitchTo64Bit_c16
+        BS3_SET_BITS 64
+
+        leave
+        ret
+BS3_PROC_END   _Bs3TestCallDoerTo16_c64
+
+
+%elif TMPL_BITS == 32
+        ;
+        ; For 32-bit workers.
+        ;
+
+BS3_BEGIN_TEXT16
+BS3_SET_BITS 32
+BS3_PROC_BEGIN _Bs3TestCallDoerTo32_f16
+        push    xBP
+        mov     xBP, xSP
+
+        ; Load bMode into eax.
+        movzx   eax, byte [xBP + xCB + sCB]
+ %ifdef BS3_STRICT
+        cmp     al, [BS3_DATA16_WRT(g_bBs3CurrentMode)]
+        je      .ok_mode
+        int3
+.ok_mode:
+ %endif
+        ; Switch to 32-bit.
+        extern  _Bs3SwitchTo32Bit_c16
+        call    _Bs3SwitchTo32Bit_c16
+        BS3_SET_BITS 32
+
+        push    eax                     ; Worker bMode argument.
+
+        test    al, BS3_MODE_CODE_V86
+        jnz     .return_to_v86          ; Need to figure this while we still have the mode value.
+
+        call    [BS3_CMN_NM(g_pfnBs3TestDoModesByOneCurrent)]
+
+        ; Switch back to 16-bit mode.
+        extern  _Bs3SwitchTo16Bit_c32
+        call    _Bs3SwitchTo16Bit_c32
+        BS3_SET_BITS 16
+.return:
+        leave
+        retf
+
+        BS3_SET_BITS 32
+.return_to_v86:
+        call    [BS3_CMN_NM(g_pfnBs3TestDoModesByOneCurrent)]
+
+        ; Switch back to v8086 mode.
+        extern  _Bs3SwitchTo16BitV86_c32
+        call    _Bs3SwitchTo16BitV86_c32
+        BS3_SET_BITS 16
+        jmp     .return
+BS3_PROC_END   _Bs3TestCallDoerTo32_f16
+
+
+BS3_BEGIN_TEXT32
+BS3_SET_BITS 64
+BS3_PROC_BEGIN _Bs3TestCallDoerTo32_c64
+        push    xBP
+        mov     xBP, xSP
+
+        ; Load bMode into eax.
+        movzx   eax, cl
+ %ifdef BS3_STRICT
+        cmp     al, [BS3_DATA16_WRT(g_bBs3CurrentMode)]
+        je      .ok_mode
+        int3
+.ok_mode:
+ %endif
+        ; Switch to 32-bit.
+        extern  _Bs3SwitchTo32Bit_c64
+        call    _Bs3SwitchTo32Bit_c64
+        BS3_SET_BITS 32
+
+        push    eax                     ; Worker bMode argument.
+        call    [BS3_CMN_NM(g_pfnBs3TestDoModesByOneCurrent)]
+
+        ; Switch back to 64-bit mode.
+        extern  _Bs3SwitchTo64Bit_c32
+        call    _Bs3SwitchTo64Bit_c32
+        BS3_SET_BITS 64
+
+        leave
+        ret
+BS3_PROC_END   _Bs3TestCallDoerTo32_c64
+
+
+%elif TMPL_BITS == 64
+;
+; 64-bit workers makes no sense, so skip that.
+;
+%else
+ %error "TMPL_BITS!"
+%endif
+
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-TrapReInit.c
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-TrapReInit.c	(revision 60749)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-TrapReInit.c	(revision 60749)
@@ -0,0 +1,55 @@
+/* $Id$ */
+/** @file
+ * BS3Kit - Bs3TrapReInit
+ */
+
+/*
+ * 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-template-header.h"
+
+
+#undef Bs3TrapReInit
+BS3_CMN_DEF(void, Bs3TrapReInit,(void))
+{
+    if (BS3_MODE_IS_RM_SYS(g_bBs3CurrentMode))
+        Bs3TrapRmV86Init();
+    else if (BS3_MODE_IS_16BIT_SYS(g_bBs3CurrentMode))
+    {
+        Bs3TrapRmV86Init();
+        Bs3Trap16Init();
+    }
+    else if (BS3_MODE_IS_32BIT_SYS(g_bBs3CurrentMode))
+    {
+        Bs3TrapRmV86Init();
+        Bs3Trap32Init();
+    }
+    else
+    {
+        BS3_ASSERT(BS3_MODE_IS_64BIT_SYS(g_bBs3CurrentMode));
+        Bs3Trap64Init();
+    }
+}
+
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-TestDoModesByOne.c
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-TestDoModesByOne.c	(revision 60749)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-TestDoModesByOne.c	(revision 60749)
@@ -0,0 +1,452 @@
+/* $Id$ */
+/** @file
+ * BS3Kit - Bs3TestDoModesByOne
+ */
+
+/*
+ * 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                                                                                                                 *
+*********************************************************************************************************************************/
+#if TMPL_MODE == BS3_MODE_RM
+# define BS3_USE_RM_TEXT_SEG 1 /* Real mode version in RMTEXT16 segment to save space. */
+# include "bs3kit-template-header.h"
+# include "bs3-cmn-test.h"
+#else
+# include "bs3kit-template-header.h"
+# include "bs3-cmn-test.h"
+#endif
+
+
+/*********************************************************************************************************************************
+*   Defined Constants And Macros                                                                                                 *
+*********************************************************************************************************************************/
+/** @def CONV_TO_FLAT
+ * Get flat address.  In 16-bit the parameter is a real mode far address, while
+ * in 32-bit and 64-bit modes it is already flat.
+ */
+/** @def CONV_TO_PROT_FAR16
+ * Get a 32-bit value that makes a protected mode far 16:16 address.
+ */
+/** @def CONV_TO_RM_FAR16
+ * Get a 32-bit value that makes a real mode far 16:16 address.  In 16-bit mode
+ * this is already what we've got, except must be converted to uint32_t.
+ */
+#if ARCH_BITS == 16
+# define CONV_TO_FLAT(a_fpfn)           (((uint32_t)BS3_FP_SEG(a_fpfn) << 4) + BS3_FP_OFF(a_fpfn))
+# define CONV_TO_PROT_FAR16(a_fpfn)     RT_MAKE_U32(BS3_FP_OFF(a_fpfn), Bs3SelRealModeCodeToProtMode(BS3_FP_SEG(a_fpfn)))
+# define CONV_TO_RM_FAR16(a_fpfn)       RT_MAKE_U32(BS3_FP_OFF(a_fpfn), BS3_FP_SEG(a_fpfn))
+#else
+# define CONV_TO_FLAT(a_fpfn)           ((uint32_t)(uintptr_t)(a_fpfn))
+# define CONV_TO_PROT_FAR16(a_fpfn)     Bs3SelFlatCodeToProtFar16((uint32_t)(uintptr_t)(a_fpfn))
+# define CONV_TO_RM_FAR16(a_fpfn)       Bs3SelFlatCodeToRealMode( (uint32_t)(uintptr_t)(a_fpfn))
+#endif
+
+/*********************************************************************************************************************************
+*   Assembly Symbols                                                                                                             *
+*********************************************************************************************************************************/
+/* These are in the same code segment as this code, so no FAR necessary. */
+#if ARCH_BITS != 64
+BS3_DECL_NEAR(uint8_t) TMPL_NM(Bs3TestCallDoerInRM)(uint32_t uCallbackFarPtr);
+BS3_DECL_NEAR(uint8_t) TMPL_NM(Bs3TestCallDoerInPE16)(uint32_t uCallbackFarPtr);
+BS3_DECL_NEAR(uint8_t) TMPL_NM(Bs3TestCallDoerInPE16_32)(uint32_t uFlatAddrCallback);
+BS3_DECL_NEAR(uint8_t) TMPL_NM(Bs3TestCallDoerInPE16_V86)(uint32_t uCallbackFarPtr);
+BS3_DECL_NEAR(uint8_t) TMPL_NM(Bs3TestCallDoerInPE32)(uint32_t uFlatAddrCallback);
+BS3_DECL_NEAR(uint8_t) TMPL_NM(Bs3TestCallDoerInPE32_16)(uint32_t uCallbackFarPtr);
+BS3_DECL_NEAR(uint8_t) TMPL_NM(Bs3TestCallDoerInPEV86)(uint32_t uCallbackFarPtr);
+BS3_DECL_NEAR(uint8_t) TMPL_NM(Bs3TestCallDoerInPP16)(uint32_t uCallbackFarPtr);
+BS3_DECL_NEAR(uint8_t) TMPL_NM(Bs3TestCallDoerInPP16_32)(uint32_t uFlatAddrCallback);
+BS3_DECL_NEAR(uint8_t) TMPL_NM(Bs3TestCallDoerInPP16_V86)(uint32_t uCallbackFarPtr);
+BS3_DECL_NEAR(uint8_t) TMPL_NM(Bs3TestCallDoerInPP32)(uint32_t uFlatAddrCallback);
+BS3_DECL_NEAR(uint8_t) TMPL_NM(Bs3TestCallDoerInPP32_16)(uint32_t uCallbackFarPtr);
+BS3_DECL_NEAR(uint8_t) TMPL_NM(Bs3TestCallDoerInPPV86)(uint32_t uCallbackFarPtr);
+BS3_DECL_NEAR(uint8_t) TMPL_NM(Bs3TestCallDoerInPAE16)(uint32_t uCallbackFarPtr);
+BS3_DECL_NEAR(uint8_t) TMPL_NM(Bs3TestCallDoerInPAE16_32)(uint32_t uFlatAddrCallback);
+BS3_DECL_NEAR(uint8_t) TMPL_NM(Bs3TestCallDoerInPAE16_V86)(uint32_t uCallbackFarPtr);
+BS3_DECL_NEAR(uint8_t) TMPL_NM(Bs3TestCallDoerInPAE32)(uint32_t uFlatAddrCallback);
+BS3_DECL_NEAR(uint8_t) TMPL_NM(Bs3TestCallDoerInPAE32_16)(uint32_t uCallbackFarPtr);
+BS3_DECL_NEAR(uint8_t) TMPL_NM(Bs3TestCallDoerInPAEV86)(uint32_t uCallbackFarPtr);
+#endif
+BS3_DECL_NEAR(uint8_t) TMPL_NM(Bs3TestCallDoerInLM16)(uint32_t uCallbackFarPtr);
+BS3_DECL_NEAR(uint8_t) TMPL_NM(Bs3TestCallDoerInLM32)(uint32_t uFlatAddrCallback);
+BS3_DECL_NEAR(uint8_t) TMPL_NM(Bs3TestCallDoerInLM64)(uint32_t uFlatAddrCallback);
+
+
+/* Assembly helpers for switching to the work bitcount and calling it. */
+BS3_DECL_FAR(uint8_t) Bs3TestCallDoerTo16_f16(uint8_t bMode);
+BS3_DECL_FAR(uint8_t) Bs3TestCallDoerTo16_c32(uint8_t bMode);
+BS3_DECL_FAR(uint8_t) Bs3TestCallDoerTo16_c64(uint8_t bMode);
+BS3_DECL_FAR(uint8_t) Bs3TestCallDoerTo32_f16(uint8_t bMode);
+BS3_DECL_FAR(uint8_t) Bs3TestCallDoerTo32_c32(uint8_t bMode);
+BS3_DECL_FAR(uint8_t) Bs3TestCallDoerTo32_c64(uint8_t bMode);
+BS3_DECL_FAR(uint8_t) Bs3TestCallDoerTo64_f16(uint8_t bMode);
+BS3_DECL_FAR(uint8_t) Bs3TestCallDoerTo64_c32(uint8_t bMode);
+BS3_DECL_FAR(uint8_t) Bs3TestCallDoerTo64_c64(uint8_t bMode);
+
+
+/** The current worker function, picked up by our assembly helpers. */
+#ifndef DOXYGEN_RUNNING
+# define g_pfnBs3TestDoModesByOneCurrent BS3_CMN_NM(g_pfnBs3TestDoModesByOneCurrent)
+#endif
+extern PFNBS3TESTDOMODE g_pfnBs3TestDoModesByOneCurrent;
+
+
+
+#undef Bs3TestDoModesByOne
+BS3_MODE_DEF(void, Bs3TestDoModesByOne,(PCBS3TESTMODEBYONEENTRY paEntries, size_t cEntries, uint32_t fFlags))
+{
+    bool const      fVerbose         = true;
+    bool const      fDoV86Modes      = true;
+    bool const      fDoWeirdV86Modes = true;
+    uint16_t const  uCpuDetected     = g_uBs3CpuDetected;
+    uint8_t const   bCpuType         = uCpuDetected & BS3CPU_TYPE_MASK;
+    bool const      fHavePae         = RT_BOOL(uCpuDetected & BS3CPU_F_PAE);
+    bool const      fHaveLongMode    = RT_BOOL(uCpuDetected & BS3CPU_F_LONG_MODE);
+    unsigned        i;
+
+#if 1 /* debug. */
+    Bs3Printf("Bs3TestDoModesByOne: uCpuDetected=%#x fHavePae=%d fHaveLongMode=%d\n", uCpuDetected, fHavePae, fHaveLongMode);
+#endif
+
+    /*
+     * Inform about modes we won't test (if any).
+     */
+    if (bCpuType < BS3CPU_80286)
+        Bs3Printf("Only executing real-mode tests as no 80286+ CPU was detected.\n");
+    else if (bCpuType < BS3CPU_80386)
+        Bs3Printf("80286 CPU: Only executing 16-bit protected and real mode tests.\n");
+    else if (!fHavePae)
+        Bs3Printf("PAE and long mode tests will be skipped.\n");
+    else if (!fHaveLongMode)
+        Bs3Printf("Long mode tests will be skipped.\n");
+#if ARCH_BITS != 16
+    Bs3Printf("Real-mode tests will be skipped.\n");
+#endif
+
+    /*
+     * The real run.
+     */
+    for (i = 0; i < cEntries; i++)
+    {
+        const char *pszFmtStr = "Error #%u (%#x) in %s!\n";
+        bool        fSkipped  = true;
+        uint8_t     bErrNo;
+        Bs3TestSub(paEntries[i].pszSubTest);
+
+#define PRE_DO_CALL(a_szModeName) do { if (fVerbose) Bs3TestPrintf("...%s\n", a_szModeName); } while (0)
+#define CHECK_RESULT(a_szModeName) \
+            do { \
+                if (bErrNo != BS3TESTDOMODE_SKIPPED) \
+                { \
+                    /*Bs3Printf("bErrNo=%#x %s\n", bErrNo, a_szModeName);*/ \
+                    fSkipped = false; \
+                    if (bErrNo != 0) \
+                        Bs3TestFailedF(pszFmtStr, bErrNo, bErrNo, a_szModeName); \
+                } \
+            } while (0)
+
+        g_pfnBs3TestDoModesByOneCurrent = paEntries[i].pfnWorker;
+
+#if ARCH_BITS != 64
+
+# if ARCH_BITS == 16
+        if (true)
+        {
+            PRE_DO_CALL(g_szBs3ModeName_rm);
+            bErrNo = TMPL_NM(Bs3TestCallDoerInRM)(CONV_TO_RM_FAR16(paEntries[i].pfnWorker));
+            CHECK_RESULT(g_szBs3ModeName_rm);
+        }
+# endif
+
+        if (bCpuType < BS3CPU_80286)
+        {
+            if (fSkipped)
+                Bs3TestSkipped(NULL);
+            continue;
+        }
+
+        /*
+         * Unpaged prot mode.
+         */
+        if (true)
+        {
+            PRE_DO_CALL(g_szBs3ModeName_pe16);
+# if ARCH_BITS == 16
+            bErrNo = TMPL_NM(Bs3TestCallDoerInPE16)(CONV_TO_PROT_FAR16(paEntries[i].pfnWorker));
+# else
+            bErrNo = TMPL_NM(Bs3TestCallDoerInPE16)(CONV_TO_PROT_FAR16(RT_CONCAT3(Bs3TestCallDoerTo,ARCH_BITS,_f16)));
+# endif
+            CHECK_RESULT(g_szBs3ModeName_pe16);
+        }
+        if (bCpuType < BS3CPU_80386)
+        {
+            if (fSkipped)
+                Bs3TestSkipped(NULL);
+            continue;
+        }
+
+        if (true)
+        {
+            PRE_DO_CALL(g_szBs3ModeName_pe16_32);
+# if ARCH_BITS == 32
+            bErrNo = TMPL_NM(Bs3TestCallDoerInPE16_32)(CONV_TO_FLAT(paEntries[i].pfnWorker));
+# else
+            bErrNo = TMPL_NM(Bs3TestCallDoerInPE16_32)(CONV_TO_FLAT(RT_CONCAT3(Bs3TestCallDoerTo,ARCH_BITS,_c32)));
+# endif
+            CHECK_RESULT(g_szBs3ModeName_pe16_32);
+        }
+
+        if (fDoWeirdV86Modes)
+        {
+            PRE_DO_CALL(g_szBs3ModeName_pe16_v86);
+# if ARCH_BITS == 16
+            bErrNo = TMPL_NM(Bs3TestCallDoerInPE16_V86)(CONV_TO_RM_FAR16(paEntries[i].pfnWorker));
+# else
+            bErrNo = TMPL_NM(Bs3TestCallDoerInPE16_V86)(CONV_TO_RM_FAR16(RT_CONCAT3(Bs3TestCallDoerTo,ARCH_BITS,_f16)));
+# endif
+            CHECK_RESULT(g_szBs3ModeName_pe16_v86);
+        }
+
+        if (true)
+        {
+            PRE_DO_CALL(g_szBs3ModeName_pe32);
+# if ARCH_BITS == 32
+            bErrNo = TMPL_NM(Bs3TestCallDoerInPE32)(CONV_TO_FLAT(paEntries[i].pfnWorker));
+# else
+            bErrNo = TMPL_NM(Bs3TestCallDoerInPE32)(CONV_TO_FLAT(RT_CONCAT3(Bs3TestCallDoerTo,ARCH_BITS,_c32)));
+# endif
+            CHECK_RESULT(g_szBs3ModeName_pe32);
+        }
+
+        if (true)
+        {
+            PRE_DO_CALL(g_szBs3ModeName_pe32_16);
+# if ARCH_BITS == 16
+            bErrNo = TMPL_NM(Bs3TestCallDoerInPE32_16)(CONV_TO_PROT_FAR16(paEntries[i].pfnWorker));
+# else
+            bErrNo = TMPL_NM(Bs3TestCallDoerInPE32_16)(CONV_TO_PROT_FAR16(RT_CONCAT3(Bs3TestCallDoerTo,ARCH_BITS,_f16)));
+# endif
+            CHECK_RESULT(g_szBs3ModeName_pe32_16);
+        }
+
+        if (fDoV86Modes)
+        {
+            PRE_DO_CALL(g_szBs3ModeName_pev86);
+# if ARCH_BITS == 16
+            bErrNo = TMPL_NM(Bs3TestCallDoerInPEV86)(CONV_TO_RM_FAR16(paEntries[i].pfnWorker));
+# else
+            bErrNo = TMPL_NM(Bs3TestCallDoerInPEV86)(CONV_TO_RM_FAR16(RT_CONCAT3(Bs3TestCallDoerTo,ARCH_BITS,_f16)));
+# endif
+            CHECK_RESULT(g_szBs3ModeName_pev86);
+        }
+
+        /*
+         * Paged protected mode.
+         */
+        if (true)
+        {
+            PRE_DO_CALL(g_szBs3ModeName_pp16);
+# if ARCH_BITS == 16
+            bErrNo = TMPL_NM(Bs3TestCallDoerInPP16)(CONV_TO_PROT_FAR16(paEntries[i].pfnWorker));
+# else
+            bErrNo = TMPL_NM(Bs3TestCallDoerInPP16)(CONV_TO_PROT_FAR16(RT_CONCAT3(Bs3TestCallDoerTo,ARCH_BITS,_f16)));
+# endif
+            CHECK_RESULT(g_szBs3ModeName_pp16);
+        }
+
+        if (true)
+        {
+            PRE_DO_CALL(g_szBs3ModeName_pp16_32);
+# if ARCH_BITS == 32
+            bErrNo = TMPL_NM(Bs3TestCallDoerInPP16_32)(CONV_TO_FLAT(paEntries[i].pfnWorker));
+# else
+            bErrNo = TMPL_NM(Bs3TestCallDoerInPP16_32)(CONV_TO_FLAT(RT_CONCAT3(Bs3TestCallDoerTo,ARCH_BITS,_c32)));
+# endif
+            CHECK_RESULT(g_szBs3ModeName_pp16_32);
+        }
+
+        if (fDoWeirdV86Modes)
+        {
+            PRE_DO_CALL(g_szBs3ModeName_pp16_v86);
+# if ARCH_BITS == 16
+            bErrNo = TMPL_NM(Bs3TestCallDoerInPP16_V86)(CONV_TO_RM_FAR16(paEntries[i].pfnWorker));
+# else
+            bErrNo = TMPL_NM(Bs3TestCallDoerInPP16_V86)(CONV_TO_RM_FAR16(RT_CONCAT3(Bs3TestCallDoerTo,ARCH_BITS,_f16)));
+# endif
+            CHECK_RESULT(g_szBs3ModeName_pp16_v86);
+        }
+
+        if (true)
+        {
+            PRE_DO_CALL(g_szBs3ModeName_pp32);
+# if ARCH_BITS == 32
+            bErrNo = TMPL_NM(Bs3TestCallDoerInPP32)(CONV_TO_FLAT(paEntries[i].pfnWorker));
+# else
+            bErrNo = TMPL_NM(Bs3TestCallDoerInPP32)(CONV_TO_FLAT(RT_CONCAT3(Bs3TestCallDoerTo,ARCH_BITS,_c32)));
+# endif
+            CHECK_RESULT(g_szBs3ModeName_pp32);
+        }
+
+        if (true)
+        {
+            PRE_DO_CALL(g_szBs3ModeName_pp32_16);
+# if ARCH_BITS == 16
+            bErrNo = TMPL_NM(Bs3TestCallDoerInPP32_16)(CONV_TO_PROT_FAR16(paEntries[i].pfnWorker));
+# else
+            bErrNo = TMPL_NM(Bs3TestCallDoerInPP32_16)(CONV_TO_PROT_FAR16(RT_CONCAT3(Bs3TestCallDoerTo,ARCH_BITS,_f16)));
+# endif
+            CHECK_RESULT(g_szBs3ModeName_pp32_16);
+        }
+
+        if (fDoV86Modes)
+        {
+            PRE_DO_CALL(g_szBs3ModeName_ppv86);
+# if ARCH_BITS == 16
+            bErrNo = TMPL_NM(Bs3TestCallDoerInPPV86)(CONV_TO_RM_FAR16(paEntries[i].pfnWorker));
+# else
+            bErrNo = TMPL_NM(Bs3TestCallDoerInPPV86)(CONV_TO_RM_FAR16(RT_CONCAT3(Bs3TestCallDoerTo,ARCH_BITS,_f16)));
+# endif
+            CHECK_RESULT(g_szBs3ModeName_ppv86);
+        }
+
+
+        /*
+         * Protected mode with PAE paging.
+         */
+        if (true)
+        {
+            PRE_DO_CALL(g_szBs3ModeName_pae16);
+# if ARCH_BITS == 16
+            bErrNo = TMPL_NM(Bs3TestCallDoerInPAE16)(CONV_TO_PROT_FAR16(paEntries[i].pfnWorker));
+# else
+            bErrNo = TMPL_NM(Bs3TestCallDoerInPAE16)(CONV_TO_PROT_FAR16(RT_CONCAT3(Bs3TestCallDoerTo,ARCH_BITS,_f16)));
+# endif
+            CHECK_RESULT(g_szBs3ModeName_pae16);
+        }
+
+        if (true)
+        {
+            PRE_DO_CALL(g_szBs3ModeName_pae16_32);
+# if ARCH_BITS == 32
+            bErrNo = TMPL_NM(Bs3TestCallDoerInPAE16_32)(CONV_TO_FLAT(paEntries[i].pfnWorker));
+# else
+            bErrNo = TMPL_NM(Bs3TestCallDoerInPAE16_32)(CONV_TO_FLAT(RT_CONCAT3(Bs3TestCallDoerTo,ARCH_BITS,_c32)));
+# endif
+            CHECK_RESULT(g_szBs3ModeName_pae16_32);
+        }
+
+        if (fDoWeirdV86Modes)
+        {
+            PRE_DO_CALL(g_szBs3ModeName_pae16_v86);
+# if ARCH_BITS == 16
+            bErrNo = TMPL_NM(Bs3TestCallDoerInPAE16_V86)(CONV_TO_RM_FAR16(paEntries[i].pfnWorker));
+# else
+            bErrNo = TMPL_NM(Bs3TestCallDoerInPAE16_V86)(CONV_TO_RM_FAR16(RT_CONCAT3(Bs3TestCallDoerTo,ARCH_BITS,_f16)));
+# endif
+            CHECK_RESULT(g_szBs3ModeName_pae16_v86);
+        }
+
+        if (true)
+        {
+            PRE_DO_CALL(g_szBs3ModeName_pae32);
+# if ARCH_BITS == 32
+            bErrNo = TMPL_NM(Bs3TestCallDoerInPAE32)(CONV_TO_FLAT(paEntries[i].pfnWorker));
+# else
+            bErrNo = TMPL_NM(Bs3TestCallDoerInPAE32)(CONV_TO_FLAT(RT_CONCAT3(Bs3TestCallDoerTo,ARCH_BITS,_c32)));
+# endif
+            CHECK_RESULT(g_szBs3ModeName_pae32);
+        }
+
+        if (true)
+        {
+            PRE_DO_CALL(g_szBs3ModeName_pae32_16);
+# if ARCH_BITS == 16
+            bErrNo = TMPL_NM(Bs3TestCallDoerInPAE32_16)(CONV_TO_PROT_FAR16(paEntries[i].pfnWorker));
+# else
+            bErrNo = TMPL_NM(Bs3TestCallDoerInPAE32_16)(CONV_TO_PROT_FAR16(RT_CONCAT3(Bs3TestCallDoerTo,ARCH_BITS,_f16)));
+# endif
+            CHECK_RESULT(g_szBs3ModeName_pae32_16);
+        }
+
+        if (fDoV86Modes)
+        {
+            PRE_DO_CALL(g_szBs3ModeName_paev86);
+# if ARCH_BITS == 16
+            bErrNo = TMPL_NM(Bs3TestCallDoerInPAEV86)(CONV_TO_RM_FAR16(paEntries[i].pfnWorker));
+# else
+            bErrNo = TMPL_NM(Bs3TestCallDoerInPAEV86)(CONV_TO_RM_FAR16(RT_CONCAT3(Bs3TestCallDoerTo,ARCH_BITS,_f16)));
+# endif
+            CHECK_RESULT(g_szBs3ModeName_paev86);
+        }
+
+#endif /* ARCH_BITS != 64 */
+
+        /*
+         * Long mode.
+         */
+        if (!fHaveLongMode)
+        {
+            if (fSkipped)
+                Bs3TestSkipped(NULL);
+            continue;
+        }
+
+        if (true)
+        {
+            PRE_DO_CALL(g_szBs3ModeName_lm16);
+#if ARCH_BITS == 16
+            bErrNo = TMPL_NM(Bs3TestCallDoerInLM16)(CONV_TO_PROT_FAR16(paEntries[i].pfnWorker));
+#else
+            bErrNo = TMPL_NM(Bs3TestCallDoerInLM16)(CONV_TO_PROT_FAR16(RT_CONCAT3(Bs3TestCallDoerTo,ARCH_BITS,_f16)));
+#endif
+            CHECK_RESULT(g_szBs3ModeName_lm16);
+        }
+
+        if (true)
+        {
+            PRE_DO_CALL(g_szBs3ModeName_lm32);
+#if ARCH_BITS == 32
+            bErrNo = TMPL_NM(Bs3TestCallDoerInLM32)(CONV_TO_FLAT(paEntries[i].pfnWorker));
+#else
+            bErrNo = TMPL_NM(Bs3TestCallDoerInLM32)(CONV_TO_FLAT(RT_CONCAT3(Bs3TestCallDoerTo,ARCH_BITS,_c32)));
+#endif
+            CHECK_RESULT(g_szBs3ModeName_lm32);
+        }
+
+        if (true)
+        {
+            PRE_DO_CALL(g_szBs3ModeName_lm64);
+#if ARCH_BITS == 64
+            bErrNo = TMPL_NM(Bs3TestCallDoerInLM64)(CONV_TO_FLAT(paEntries[i].pfnWorker));
+#else
+            bErrNo = TMPL_NM(Bs3TestCallDoerInLM64)(CONV_TO_FLAT(RT_CONCAT3(Bs3TestCallDoerTo,ARCH_BITS,_c64)));
+#endif
+            CHECK_RESULT(g_szBs3ModeName_lm64);
+        }
+
+        if (fSkipped)
+            Bs3TestSkipped("skipped\n");
+    }
+    Bs3TestSubDone();
+}
+
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-TestDoModesByOneStub.asm
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-TestDoModesByOneStub.asm	(revision 60749)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-TestDoModesByOneStub.asm	(revision 60749)
@@ -0,0 +1,55 @@
+; $Id$
+;; @file
+; BS3Kit - Bs3TestDoModesByOne near stub.
+;
+
+;
+; 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-template-header.mac"
+
+;
+; Finally near stub for the API call (16-bit only).
+;
+%if TMPL_BITS == 16
+ %if TMPL_MODE == BS3_MODE_RM
+BS3_BEGIN_RMTEXT16
+ %endif
+BS3_BEGIN_TEXT16_NEARSTUBS
+BS3_PROC_BEGIN_MODE Bs3TestDoModesByOne, BS3_PBC_NEAR
+        pop     ax
+ %if TMPL_MODE == BS3_MODE_RM
+        push    cs
+        push    ax
+        extern TMPL_FAR_NM(Bs3TestDoModesByOne):wrt BS3GROUPRMTEXT16
+        jmp far TMPL_FAR_NM(Bs3TestDoModesByOne)
+ %else
+        push    cs
+        push    ax
+        extern TMPL_FAR_NM(Bs3TestDoModesByOne):wrt CGROUP16
+        jmp     TMPL_NM(Bs3TestDoModesByOne)
+ %endif
+BS3_PROC_END_MODE   Bs3TestDoModesByOne
+%endif
+
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-rm-InitAll.c
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-rm-InitAll.c	(revision 60748)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-rm-InitAll.c	(revision 60749)
@@ -39,23 +39,39 @@
 BS3_DECL(void) Bs3InitAll_rm(void)
 {
-    uint32_t volatile BS3_FAR *pcTicks = (uint32_t volatile BS3_FAR *)BS3_FP_MAKE(0x40, 0x6c);
-    uint32_t                   cInitialTicks = *pcTicks;
-    int                        i = 3;
+    uint8_t volatile BS3_FAR  *pcTicksFlpyOff;
 
+    /*
+     * Detect CPU first as the memory init code will otherwise use 386
+     * instrunctions and cause trouble on older CPUs.
+     */
     Bs3CpuDetect_rm_far();
     Bs3InitMemory_rm_far();
     Bs3InitGdt_rm_far();
 
-    /* For for floppy to stop (a couple of ticks), then disable interrupts. */
-    ASMIntEnable();
-    while (i-- > 0)
+    /*
+     * Before we disable all interrupts, try convince the BIOS to stop the
+     * floppy motor, as it is kind of disturbing when the floppy light remains
+     * on for the whole testcase execution.
+     */
+    ASMIntDisable(); /* (probably already disabled, but no guarantees) */
+    pcTicksFlpyOff = (uint8_t volatile BS3_FAR *)BS3_FP_MAKE(0x40, 0x40);
+    if (*pcTicksFlpyOff)
     {
+        uint32_t volatile BS3_FAR *pcTicks = (uint32_t volatile BS3_FAR *)BS3_FP_MAKE(0x40, 0x6c);
+        uint32_t cInitialTicks;
+
+        *pcTicksFlpyOff = 1;            /* speed up the countdown, don't want to wait for two seconds here. */
+        cInitialTicks   = *pcTicks;
+        ASMIntEnable();
+
         while (*pcTicks == cInitialTicks)
             ASMHalt();
-        *pcTicks = cInitialTicks;
     }
     ASMIntDisable();
     Bs3PicMaskAll();
 
+    /*
+     * Initialize IDTs and such.
+     */
     if (g_uBs3CpuDetected & BS3CPU_F_LONG_MODE)
         Bs3Trap64Init();
@@ -65,4 +81,9 @@
         Bs3Trap16Init();
     Bs3TrapRmV86Init();
+
+    /*
+     * Perform a real-mode enter to make some final environment adjustments
+     * (like installing our syscall).
+     */
     Bs3EnteredMode_rm();
 }
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-autostubs.kmk
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-autostubs.kmk	(revision 60748)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-autostubs.kmk	(revision 60749)
@@ -36,4 +36,5 @@
 $(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3TestCheckRegCtxEx)
 $(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3StrCpy)
+$(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3GetModeName)
 $(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3PagingAlias)
 $(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3PagingInitRootForLM)
@@ -105,4 +106,5 @@
 $(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3TrapDefaultHandler)
 $(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3TrapPrintFrame)
+$(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3TrapReInit)
 $(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3TrapRmV86Init)
 $(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3TrapRmV86InitEx)
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-mangling-code-define.h
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-mangling-code-define.h	(revision 60748)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-mangling-code-define.h	(revision 60749)
@@ -31,4 +31,5 @@
 #define Bs3A20EnableViaKbd BS3_CMN_MANGLER(Bs3A20EnableViaKbd)
 #define Bs3A20EnableViaPortA BS3_CMN_MANGLER(Bs3A20EnableViaPortA)
+#define Bs3GetModeName BS3_CMN_MANGLER(Bs3GetModeName)
 #define Bs3KbdRead BS3_CMN_MANGLER(Bs3KbdRead)
 #define Bs3KbdWait BS3_CMN_MANGLER(Bs3KbdWait)
@@ -131,4 +132,5 @@
 #define Bs3TrapDefaultHandler BS3_CMN_MANGLER(Bs3TrapDefaultHandler)
 #define Bs3TrapPrintFrame BS3_CMN_MANGLER(Bs3TrapPrintFrame)
+#define Bs3TrapReInit BS3_CMN_MANGLER(Bs3TrapReInit)
 #define Bs3TrapRmV86Init BS3_CMN_MANGLER(Bs3TrapRmV86Init)
 #define Bs3TrapRmV86InitEx BS3_CMN_MANGLER(Bs3TrapRmV86InitEx)
@@ -145,4 +147,5 @@
 # define Bs3CpuDetect BS3_MODE_MANGLER(Bs3CpuDetect)
 # define Bs3TestDoModes BS3_MODE_MANGLER(Bs3TestDoModes)
+# define Bs3TestDoModesByOne BS3_MODE_MANGLER(Bs3TestDoModesByOne)
 # define Bs3TrapInit BS3_MODE_MANGLER(Bs3TrapInit)
 #endif /* !BS3_CMN_ONLY */
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-mangling-code-undef.h
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-mangling-code-undef.h	(revision 60748)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-mangling-code-undef.h	(revision 60749)
@@ -31,4 +31,5 @@
 #undef Bs3A20EnableViaKbd
 #undef Bs3A20EnableViaPortA
+#undef Bs3GetModeName
 #undef Bs3KbdRead
 #undef Bs3KbdWait
@@ -131,4 +132,5 @@
 #undef Bs3TrapDefaultHandler
 #undef Bs3TrapPrintFrame
+#undef Bs3TrapReInit
 #undef Bs3TrapRmV86Init
 #undef Bs3TrapRmV86InitEx
@@ -145,4 +147,5 @@
 # undef Bs3CpuDetect
 # undef Bs3TestDoModes
+# undef Bs3TestDoModesByOne
 # undef Bs3TrapInit
 #endif /* !BS3_CMN_ONLY */
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit.h
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit.h	(revision 60748)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit.h	(revision 60749)
@@ -1442,4 +1442,13 @@
 #endif
 
+
+/**
+ * Translate a mode into a string.
+ *
+ * @returns Pointer to read-only mode name string.
+ * @param   bMode       The mode value (BS3_MODE_XXX).
+ */
+BS3_CMN_PROTO_STUB(const char BS3_FAR *, Bs3GetModeName,(uint8_t bMode));
+
 /**
  * Shutdown the system, never returns.
@@ -2482,4 +2491,13 @@
 
 /**
+ * Re-initializes the trap handling for the current mode.
+ *
+ * Useful after a test that messes with the IDT/IVT.
+ *
+ * @sa      Bs3TrapInit
+ */
+BS3_CMN_PROTO_STUB(void, Bs3TrapReInit,(void));
+
+/**
  * Initializes real mode and v8086 trap handling.
  *
@@ -2944,4 +2962,21 @@
     FNBS3TESTDOMODE   RT_CONCAT(a_BaseNm, _lm32); \
     FNBS3TESTDOMODE   RT_CONCAT(a_BaseNm, _lm64)
+
+
+/**
+ * One worker drives all modes.
+ *
+ * This is an alternative to BS3TESTMODEENTRY where one worker, typically
+ * 16-bit, does all the test driver work.  It's called repeatedly from all
+ * the modes being tested.
+ */
+typedef struct BS3TESTMODEBYONEENTRY
+{
+    const char * BS3_FAR    pszSubTest;
+    PFNBS3TESTDOMODE        pfnWorker;
+    uint32_t                u32Reserved;
+} BS3TESTMODEBYONEENTRY;
+/** Pointer to a mode-by-one sub-test entry. */
+typedef BS3TESTMODEBYONEENTRY const *PCBS3TESTMODEBYONEENTRY;
 
 
@@ -3160,4 +3195,17 @@
 BS3_MODE_PROTO_NOSB(void, Bs3TestDoModes,(PCBS3TESTMODEENTRY paEntries, size_t cEntries));
 
+/**
+ * Executes the array of tests in every possibly mode, unitifed driver.
+ *
+ * This requires much less code space than Bs3TestDoModes as there is only one
+ * instace of each sub-test driver code, instead of 3 (cmn) or 22 (per-mode)
+ * copies.
+ *
+ * @param   paEntries       The mode sub-test-by-one entries.
+ * @param   cEntries        The number of sub-test-by-one entries.
+ * @param   fFlags          Reserved for the future, MBZ.
+ */
+BS3_MODE_PROTO_NOSB(void, Bs3TestDoModesByOne,(PCBS3TESTMODEBYONEENTRY paEntries, size_t cEntries, uint32_t fFlags));
+
 
 /** @} */
