Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/Makefile.kmk
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/Makefile.kmk	(revision 59894)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/Makefile.kmk	(revision 59895)
@@ -82,4 +82,5 @@
        bs3-cmn-PagingInitRootForPAE.c \
        bs3-cmn-PagingInitRootForLM.c \
+       bs3-cmn-SelProtFar32ToFlat32.c \
        bs3-cmn-SlabInit.c \
        bs3-cmn-SlabAlloc.c \
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-SelProtFar32ToFlat32.c
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-SelProtFar32ToFlat32.c	(revision 59895)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-SelProtFar32ToFlat32.c	(revision 59895)
@@ -0,0 +1,44 @@
+/* $Id$ */
+/** @file
+ * BS3Kit - Bs3SelProtFar32ToFlat32
+ */
+
+/*
+ * 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"
+
+
+BS3_DECL(uint32_t) Bs3SelProtFar32ToFlat32(uint32_t off, uint16_t uSel)
+{
+    uint32_t    uRet;
+    PCX86DESC   pEntry;
+    if (!(uSel & X86_SEL_LDT))
+         pEntry = &BS3_DATA_NM(Bs3Gdt)[uSel & X86_SEL_MASK];
+    else
+         pEntry = &BS3_DATA_NM(Bs3Ldt)[uSel & X86_SEL_MASK];
+    uRet  = pEntry->Gen.u16BaseLow;
+    uRet |= (uint32_t)pEntry->Gen.u8BaseHigh1 << 16;
+    uRet |= (uint32_t)pEntry->Gen.u8BaseHigh2 << 16;
+    uRet += off;
+    return uRet;
+}
+
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-SwitchTo16BitV86.asm
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-SwitchTo16BitV86.asm	(revision 59894)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-SwitchTo16BitV86.asm	(revision 59895)
@@ -31,4 +31,5 @@
 BS3_EXTERN_DATA16   g_bBs3CurrentMode
 BS3_EXTERN_CMN      Bs3SwitchToRing0
+BS3_EXTERN_CMN      Bs3SelProtFar32ToFlat32
 TMPL_BEGIN_TEXT
 
@@ -36,13 +37,15 @@
 ;;
 ; @cproto   BS3_DECL(void) Bs3SwitchTo16BitV86(void);
+; @uses No general registers modified. Regment registers loaded with specific
+;       values and the stack register converted to real mode (not ebp).
 ;
 BS3_PROC_BEGIN_CMN Bs3SwitchTo16BitV86
         ; Construct basic v8086 return frame.
-        BS3_ONLY_16BIT_STMT push gs
-        BS3_ONLY_16BIT_STMT movzx esp, sp
-        push    dword fs
+        BS3_ONLY_16BIT_STMT movzx   esp, sp
+        push    dword 0                 ; GS
+        push    dword 0                 ; FS
         push    dword BS3_SEL_DATA16    ; ES
         push    dword BS3_SEL_DATA16    ; DS
-        push    dword ss
+        push    dword 0                 ; SS - later
         push    dword 0                 ; return ESP, later.
         pushfd
@@ -57,5 +60,8 @@
         ; Save registers and stuff.
         push    eax
- %if TMPL_BITS == 16
+        push    edx
+        push    ecx
+        push    ebx
+%if TMPL_BITS == 16
         push    ds
 
@@ -69,4 +75,7 @@
 
         pop     ds
+        pop     ebx
+        pop     ecx
+        pop     edx
         pop     eax
         add     xSP, (9-1)*4
@@ -91,22 +100,27 @@
         ; Set GS.
         mov     ax, gs
-        mov     [xSP + 4 + 20h], ax
+        mov     [xSP + 4*4 + 20h], ax
  %endif
 
-        ; Thunk SS:ESP, first step: calc flat address.
-        lea     eax, [esp + 4 + 24h]
+        ; Thunk SS:ESP to real-mode address via 32-bit flat.
+        lea     eax, [esp + 4*4 + 24h]
+        push    ss
         push    eax
-        push    ss
-;        call    Bs3SelFar32ToFlat32
-
-        ; Second step: Calc realmode segment and offset.
-
+        BS3_CALL Bs3SelProtFar32ToFlat32, 2
+        mov     [esp + 4*4 + 0ch], ax   ; high word is already zero
+ %if TMPL_BITS == 16
+        mov     [esp + 4*4 + 10h], dx
+ %else
+        shr     eax, 16
+        mov     [esp + 4*4 + 10h], ax
+ %endif
 
         ; Return to v8086 mode.
+        pop     ebx
+        pop     ecx
+        pop     edx
         pop     eax
         iretd
-BS3_PROC_END_CMN   Bs3SwitchTo16Bit
-
-
+BS3_PROC_END_CMN   Bs3SwitchTo16BitV86
 
 %endif ; ! 64-bit
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit.h
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit.h	(revision 59894)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit.h	(revision 59895)
@@ -1309,4 +1309,16 @@
 
 
+/**
+ * Converts a protected mode 32-bit far pointer to a 32-bit flat address.
+ *
+ * @returns 32-bit flat address.
+ * @param   off             The segment offset.
+ * @param   uSel            The protected mode segment selector.
+ */
+BS3_DECL(uint32_t) Bs3SelProtFar32ToFlat32_c16(uint32_t off, uint16_t uSel);
+BS3_DECL(uint32_t) Bs3SelProtFar32ToFlat32_c32(uint32_t off, uint16_t uSel); /**< @copydoc Bs3SelProtFar32ToFlat32_c16 */
+BS3_DECL(uint32_t) Bs3SelProtFar32ToFlat32_c64(uint32_t off, uint16_t uSel); /**< @copydoc Bs3SelProtFar32ToFlat32_c16 */
+#define Bs3SelProtFar32ToFlat32 BS3_CMN_NM(Bs3SelProtFar32ToFlat32) /**< Selects #Bs3SelProtFar32ToFlat32_c16, #Bs3SelProtFar32ToFlat32_c32 or #Bs3SelProtFar32ToFlat32_c64. */
+
 
 /**
