Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-basic-2-template.c
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-basic-2-template.c	(revision 60685)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-basic-2-template.c	(revision 60686)
@@ -1944,4 +1944,14 @@
     }
 
+    /*
+     * Move the table by setting up alias pages.  Aim at areas above 2GB for 32-bit and in
+     * the 'negative' space of 64-bit addresses.
+     */
+    if (BS3_MODE_IS_PAGED(bTestMode))
+    {
+
+    }
+
+
 }
 
@@ -1960,5 +1970,5 @@
         for (idx = 0; idx < cWorkers; idx++)
             if (    (paWorkers[idx].bMode & (bTestMode & BS3_MODE_CODE_MASK))
-                && (!paWorkers[idx].fSs || bRing != 0))
+                && (!paWorkers[idx].fSs || bRing != 0 /** @todo || BS3_MODE_IS_64BIT_SYS(bTestMode)*/ ))
             {
                 g_usBs3TestStep = iStep;
@@ -2253,6 +2263,8 @@
 BS3_DECL_FAR(uint8_t) TMPL_NM(bs3CpuBasic2_sgdt)(uint8_t bMode)
 {
-//if (bMode == BS3_MODE_LM64)
-{
+//if (bMode >= BS3_MODE_LM16)
+{
+    uint64_t const uOrgAddr = Bs3Lgdt_Gdt.uAddr;
+    uint64_t       uNew     = 0;
     union
     {
@@ -2264,6 +2276,22 @@
     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);
+        }
+    }
 
     /*
@@ -2273,4 +2301,14 @@
     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);
+    }
 
     /*
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/Makefile.kmk
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/Makefile.kmk	(revision 60685)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/Makefile.kmk	(revision 60686)
@@ -86,4 +86,5 @@
        bs3-cmn-PagingInitRootForPAE.c \
        bs3-cmn-PagingInitRootForLM.c \
+       bs3-cmn-PagingAlias.c \
        bs3-cmn-PagingProtect.c \
        bs3-cmn-PagingSetupCanonicalTraps.c \
@@ -158,4 +159,6 @@
 	bs3-cmn-TrapSetJmpAndRestore.c \
 	bs3-cmn-TrapUnsetJmp.c \
+       bs3-cmn-UtilSetFullGdtr.asm \
+       bs3-cmn-UtilSetFullIdtr.asm \
        ../../../Runtime/common/asm/ASMBitFirstClear.asm \
        ../../../Runtime/common/asm/ASMBitFirstSet.asm \
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-PagingAlias.c
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-PagingAlias.c	(revision 60686)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-PagingAlias.c	(revision 60686)
@@ -0,0 +1,182 @@
+/* $Id$ */
+/** @file
+ * BS3Kit - Bs3PagingAlias, Bs3PagingUnalias
+ */
+
+/*
+ * 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"
+#include "bs3-cmn-paging.h"
+#include "iprt/asm-amd64-x86.h"
+
+
+#undef Bs3PagingAlias
+BS3_CMN_DEF(int, Bs3PagingAlias,(uint64_t uDst, uint64_t uPhysToAlias, uint32_t cbHowMuch, uint64_t fPte))
+{
+#if ARCH_BITS == 16
+    if (!BS3_MODE_IS_V86(g_bBs3CurrentMode))
+#endif
+    {
+        RTCCUINTXREG    cr3 = ASMGetCR3();
+        uint32_t        cPages;
+        int             rc;
+
+        /*
+         * Validate and adjust the input a little.
+         */
+        if (uDst & X86_PAGE_OFFSET_MASK)
+        {
+            cbHowMuch += X86_PAGE_SIZE - (uDst & X86_PAGE_OFFSET_MASK);
+            uDst      &= ~(uint64_t)X86_PAGE_OFFSET_MASK;
+        }
+        uPhysToAlias &= X86_PTE_PAE_PG_MASK;
+        fPte         &= ~(X86_PTE_PAE_MBZ_MASK_NX | X86_PTE_PAE_PG_MASK);
+        cbHowMuch     = RT_ALIGN_32(cbHowMuch, X86_PAGE_SIZE);
+        cPages        = cbHowMuch >> X86_PAGE_SHIFT;
+        //Bs3TestPrintf("Bs3PagingAlias: adjusted: uDst=%RX64 uPhysToAlias=%RX64 cbHowMuch=%RX32 fPte=%Rx64 cPages=%RX32\n", uDst, uPhysToAlias, cbHowMuch, fPte, cPages);
+        if (BS3_MODE_IS_LEGACY_PAGING(g_bBs3CurrentMode))
+        {
+            X86PTE BS3_FAR *pPteLegacy;
+            uint32_t        uDst32 = (uint32_t)uDst;
+            uint32_t        uPhysToAlias32 = (uint32_t)uPhysToAlias;
+            if (uDst32 != uDst)
+            {
+                Bs3TestPrintf("warning: Bs3PagingAlias - uDst=%RX64 is out of range for legacy paging!\n", uDst);
+                return VERR_INVALID_PARAMETER;
+            }
+            if (uPhysToAlias32 != uPhysToAlias)
+            {
+                Bs3TestPrintf("warning: Bs3PagingAlias - uPhysToAlias=%RX64 is out of range for legacy paging!\n", uPhysToAlias);
+                return VERR_INVALID_PARAMETER;
+            }
+
+            /*
+             * Trigger page table splitting first.
+             */
+            while (cPages > 0)
+            {
+                pPteLegacy = bs3PagingGetLegacyPte(cr3, uDst32, false, &rc);
+                if (pPteLegacy)
+                {
+                    uint32_t cLeftInPt = X86_PG_ENTRIES - ((uDst32 >> X86_PT_SHIFT) & X86_PT_MASK);
+                    if (cPages <= cLeftInPt)
+                        break;
+                    uDst32 += cLeftInPt << X86_PAGE_SHIFT;
+                    cPages -= cLeftInPt;
+                }
+                else
+                {
+                    Bs3TestPrintf("warning: Bs3PagingAlias - bs3PagingGetLegacyPte failed: rc=%d\n", rc);
+                    return rc;
+                }
+            }
+
+            /*
+             * Make the changes.
+             */
+            cPages = cbHowMuch >> X86_PAGE_SHIFT;
+            uDst32 = (uint32_t)uDst;
+            while (cPages > 0)
+            {
+                uint32_t cLeftInPt = X86_PG_ENTRIES - ((uDst32 >> X86_PT_SHIFT) & X86_PT_MASK);
+                pPteLegacy = bs3PagingGetLegacyPte(cr3, uDst32, false, &rc);
+                while (cLeftInPt > 0 && cPages > 0)
+                {
+                    pPteLegacy->u = uPhysToAlias32 | (uint32_t)fPte;
+                    pPteLegacy++;
+                    uDst32         += X86_PAGE_SIZE;
+                    uPhysToAlias32 += X86_PAGE_SIZE;
+                    cPages--;
+                    cLeftInPt--;
+                }
+            }
+        }
+        else
+        {
+            X86PTEPAE BS3_FAR *pPtePae;
+            uint64_t const uDstSaved = uDst;
+
+            /*
+             * Trigger page table splitting first.
+             */
+            while (cPages > 0)
+            {
+                pPtePae = bs3PagingGetPte(cr3, g_bBs3CurrentMode, uDst, false, &rc);
+                if (pPtePae)
+                {
+                    uint32_t cLeftInPt = X86_PG_PAE_ENTRIES - ((uDst >> X86_PT_PAE_SHIFT) & X86_PT_PAE_MASK);
+                    if (cPages <= cLeftInPt)
+                        break;
+                    cPages -= cLeftInPt;
+                    uDst   += cLeftInPt << X86_PAGE_SHIFT;
+                }
+                else
+                {
+                    Bs3TestPrintf("warning: Bs3PagingAlias - bs3PagingGetLegacyPte failed: rc=%d\n", rc);
+                    return rc;
+                }
+            }
+
+            /*
+             * Make the changes.
+             */
+            cPages = cbHowMuch >> X86_PAGE_SHIFT;
+            uDst   = uDstSaved;
+            while (cPages > 0)
+            {
+                uint32_t cLeftInPt = X86_PG_PAE_ENTRIES - ((uDst >> X86_PT_PAE_SHIFT) & X86_PT_PAE_MASK);
+                pPtePae = bs3PagingGetPte(cr3, g_bBs3CurrentMode, uDst, false, &rc);
+                while (cLeftInPt > 0 && cPages > 0)
+                {
+                    pPtePae->u = uPhysToAlias | fPte;
+                    pPtePae++;
+                    uDst         += X86_PAGE_SIZE;
+                    uPhysToAlias += X86_PAGE_SIZE;
+                    cPages--;
+                    cLeftInPt--;
+                }
+            }
+        }
+
+        ASMReloadCR3();
+    }
+#if ARCH_BITS == 16
+    /*
+     * We can do this stuff in v8086 mode.
+     */
+    else
+        return Bs3SwitchFromV86To16BitAndCallC((FPFNBS3FAR)Bs3PagingAlias_f16, sizeof(uint64_t)*3 + sizeof(uint32_t),
+                                               uDst, uPhysToAlias, cbHowMuch, fPte);
+#endif
+    return VINF_SUCCESS;
+}
+
+
+#undef Bs3PagingUnalias
+BS3_CMN_DEF(int, Bs3PagingUnalias,(uint64_t uDst, uint32_t cbHowMuch))
+{
+    return BS3_CMN_NM(Bs3PagingAlias)(uDst, uDst, cbHowMuch, X86_PTE_P | X86_PTE_RW | X86_PTE_US | X86_PTE_A | X86_PTE_D);
+}
+
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-PagingProtect.c
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-PagingProtect.c	(revision 60685)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-PagingProtect.c	(revision 60686)
@@ -100,5 +100,6 @@
                 {
                     X86PT BS3_FAR *pPT;
-                    uint32_t       uPte = (pPD->a[iPde].u & ~(uint32_t)(X86_PTE_PG_MASK | X86_PDE4M_PS | X86_PDE4M_G)) | X86_PTE_D;
+                    uint32_t       uPte = (pPD->a[iPde].u & ~(uint32_t)(X86_PDE4M_PS | X86_PDE4M_G | X86_PDE4M_PG_HIGH_MASK)) \
+                                        | X86_PTE_D;
                     if (pPD->a[iPde].b.u1Global)
                         uPte |= X86_PTE_G;
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-SwitchToLM32.asm
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-SwitchToLM32.asm	(revision 60685)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-SwitchToLM32.asm	(revision 60686)
@@ -134,4 +134,17 @@
 
         ;
+        ; Load full 64-bit GDT base address from 64-bit segment.
+        ;
+        jmp     dword BS3_SEL_R0_CS64:.load_full_gdt_base wrt FLAT
+.load_full_gdt_base:
+        BS3_SET_BITS 64
+        lgdt    [Bs3Lgdt_Gdt wrt FLAT]
+        push    BS3_SEL_R0_CS32
+        push    .back_to_32bit wrt FLAT
+        o64 retf
+.back_to_32bit:
+        BS3_SET_BITS 32
+
+        ;
         ; Restore ecx, eax and flags (IF).
         ;
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-SwitchToPAE16.asm
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-SwitchToPAE16.asm	(revision 60685)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-SwitchToPAE16.asm	(revision 60686)
@@ -132,9 +132,10 @@
         ; Load the GDT and enable PP16.
         ;
+BS3_EXTERN_SYSTEM16 Bs3LgdtDef_Gdt
 BS3_EXTERN_SYSTEM16 Bs3Lgdt_Gdt
 BS3_BEGIN_TEXT16
         mov     ax, BS3SYSTEM16
         mov     ds, ax
-        lgdt    [Bs3Lgdt_Gdt]
+        lgdt    [Bs3LgdtDef_Gdt]        ; Will only load 24-bit base!
 
         mov     eax, cr0
@@ -156,4 +157,19 @@
         ;
         call    NAME(Bs3EnteredMode_pae16)
+
+        ;
+        ; Load full 32-bit GDT base address from 32-bit segment.
+        ;
+        push    ds
+        mov     ax, BS3_SEL_SYSTEM16
+        mov     ds, ax
+        jmp     dword BS3_SEL_R0_CS32:.load_full_gdt_base wrt FLAT
+.load_full_gdt_base:
+        BS3_SET_BITS 32
+        lgdt    [Bs3Lgdt_Gdt wrt BS3SYSTEM16]
+        jmp     BS3_SEL_R0_CS16:.back_to_16bit
+.back_to_16bit:
+        BS3_SET_BITS 16
+        pop     ds
 
         popfd
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-SwitchToPAE32.asm
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-SwitchToPAE32.asm	(revision 60685)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-SwitchToPAE32.asm	(revision 60686)
@@ -109,9 +109,10 @@
         ; Load the GDT and enable PE32.
         ;
+BS3_EXTERN_SYSTEM16 Bs3LgdtDef_Gdt
 BS3_EXTERN_SYSTEM16 Bs3Lgdt_Gdt
 BS3_BEGIN_TEXT16
         mov     ax, BS3SYSTEM16
         mov     ds, ax
-        lgdt    [Bs3Lgdt_Gdt]
+        lgdt    [Bs3LgdtDef_Gdt]        ; Will only load 24-bit base!
 
         mov     eax, cr0
@@ -139,4 +140,7 @@
         extern  NAME(Bs3EnteredMode_pae32)
         call    NAME(Bs3EnteredMode_pae32)
+
+        ; Load full 32-bit GDT base address.
+        lgdt    [Bs3Lgdt_Gdt wrt FLAT]
 
         ;
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-SwitchToPE16.asm
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-SwitchToPE16.asm	(revision 60685)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-SwitchToPE16.asm	(revision 60686)
@@ -94,8 +94,9 @@
         ;
 BS3_EXTERN_SYSTEM16 Bs3Lgdt_Gdt
+BS3_EXTERN_SYSTEM16 Bs3LgdtDef_Gdt
 BS3_BEGIN_TEXT16
         mov     ax, BS3SYSTEM16
         mov     ds, ax
-        lgdt    [Bs3Lgdt_Gdt]
+        lgdt    [Bs3LgdtDef_Gdt]        ; Will only load 24-bit base!
 
         smsw    ax
@@ -116,4 +117,24 @@
         extern  NAME(Bs3EnteredMode_pe16)
         call    NAME(Bs3EnteredMode_pe16)
+
+        ;
+        ; Load full 32-bit GDT base address from 32-bit segment, if 386+ CPU.
+        ;
+        BS3_EXTERN_DATA16 g_uBs3CpuDetected
+        BS3_BEGIN_TEXT16
+        cmp     byte [g_uBs3CpuDetected], BS3CPU_80386
+        jb      .old_cpu_skip_32bit_lgdt
+        push    ds
+        mov     ax, BS3_SEL_SYSTEM16
+        mov     ds, ax
+        jmp     dword BS3_SEL_R0_CS32:.load_full_gdt_base wrt FLAT
+.load_full_gdt_base:
+        BS3_SET_BITS 32
+        lgdt    [Bs3Lgdt_Gdt wrt BS3SYSTEM16]
+        jmp     BS3_SEL_R0_CS16:.back_to_16bit
+.back_to_16bit:
+        BS3_SET_BITS 16
+        pop     ds
+.old_cpu_skip_32bit_lgdt:
 
         popf
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-SwitchToPE32.asm
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-SwitchToPE32.asm	(revision 60685)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-SwitchToPE32.asm	(revision 60686)
@@ -87,9 +87,10 @@
         ; Load the GDT and enable PE32.
         ;
+BS3_EXTERN_SYSTEM16 Bs3LgdtDef_Gdt
 BS3_EXTERN_SYSTEM16 Bs3Lgdt_Gdt
 BS3_BEGIN_TEXT16
         mov     ax, BS3SYSTEM16
         mov     ds, ax
-        lgdt    [Bs3Lgdt_Gdt]
+        lgdt    [Bs3LgdtDef_Gdt]        ; Will only load 24-bit base!
 
         mov     eax, cr0
@@ -117,4 +118,7 @@
         extern  NAME(Bs3EnteredMode_pe32)
         call    NAME(Bs3EnteredMode_pe32)
+
+        ; Load full 32-bit GDT base address.
+        lgdt    [Bs3Lgdt_Gdt wrt FLAT]
 
         ;
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-SwitchToPP16.asm
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-SwitchToPP16.asm	(revision 60685)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-SwitchToPP16.asm	(revision 60686)
@@ -148,9 +148,10 @@
         ; Load the GDT and enable PP16.
         ;
+BS3_EXTERN_SYSTEM16 Bs3LgdtDef_Gdt
 BS3_EXTERN_SYSTEM16 Bs3Lgdt_Gdt
 BS3_BEGIN_TEXT16
         mov     ax, BS3SYSTEM16
         mov     ds, ax
-        lgdt    [Bs3Lgdt_Gdt]
+        lgdt    [Bs3LgdtDef_Gdt]        ; Will only load 24-bit base!
 
         mov     eax, cr0
@@ -172,4 +173,19 @@
         ;
         call    NAME(Bs3EnteredMode_pp16)
+
+        ;
+        ; Load full 32-bit GDT base address from 32-bit segment.
+        ;
+        push    ds
+        mov     ax, BS3_SEL_SYSTEM16
+        mov     ds, ax
+        jmp     dword BS3_SEL_R0_CS32:.load_full_gdt_base wrt FLAT
+.load_full_gdt_base:
+        BS3_SET_BITS 32
+        lgdt    [Bs3Lgdt_Gdt wrt BS3SYSTEM16]
+        jmp     BS3_SEL_R0_CS16:.back_to_16bit
+.back_to_16bit:
+        BS3_SET_BITS 16
+        pop     ds
 
         popfd
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-SwitchToPP32.asm
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-SwitchToPP32.asm	(revision 60685)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-SwitchToPP32.asm	(revision 60686)
@@ -117,9 +117,10 @@
         ; Load the GDT and enable PE32.
         ;
+BS3_EXTERN_SYSTEM16 Bs3LgdtDef_Gdt
 BS3_EXTERN_SYSTEM16 Bs3Lgdt_Gdt
 BS3_BEGIN_TEXT16
         mov     ax, BS3SYSTEM16
         mov     ds, ax
-        lgdt    [Bs3Lgdt_Gdt]
+        lgdt    [Bs3LgdtDef_Gdt]        ; Will only load 24-bit base!
 
         mov     eax, cr0
@@ -129,5 +130,4 @@
 BS3_BEGIN_TEXT32
 .thirty_two_bit:
-
         ;
         ; Convert the (now) real mode stack pointer to 32-bit flat.
@@ -147,4 +147,7 @@
         extern  NAME(Bs3EnteredMode_pp32)
         call    NAME(Bs3EnteredMode_pp32)
+
+        ; Load full 32-bit GDT base address.
+        lgdt    [Bs3Lgdt_Gdt wrt FLAT]
 
         ;
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-rm-InitMemory.c
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-rm-InitMemory.c	(revision 60685)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-rm-InitMemory.c	(revision 60686)
@@ -175,4 +175,9 @@
 
 
+/** The last RAM address below 4GB (approximately). */
+uint32_t                g_uBs3EndOfRamBelow4G = 0;
+
+
+
 /**
  * Adds a range of memory to the tiled slabs.
@@ -181,52 +186,58 @@
  * @param   cbRange     Size of range.
  */
-static void bs3InitMemoryAddRange(uint32_t uRange, uint32_t cbRange)
-{
-    if (uRange < BS3_SEL_TILED_AREA_SIZE)
+static void bs3InitMemoryAddRange32(uint32_t uRange, uint32_t cbRange)
+{
+    uint32_t uRangeEnd = uRange + cbRange;
+    if (uRangeEnd < uRange)
+        uRangeEnd = UINT32_MAX;
+
+    /* Raise the end-of-ram-below-4GB marker? */
+    if (uRangeEnd > g_uBs3EndOfRamBelow4G)
+        g_uBs3EndOfRamBelow4G = uRangeEnd;
+
+    /* Applicable to tiled memory? */
+    if (   uRange < BS3_SEL_TILED_AREA_SIZE
+        && (   uRange >= _1M
+            || uRangeEnd >= _1M))
     {
-        uint32_t uRangeEnd = uRange + cbRange;
-        if (   uRange >= _1M
-            || uRangeEnd > _1M)
-        {
-            uint16_t cPages;
-
-            /* Adjust the start of the range such that it's at or above 1MB and page aligned.  */
-            if (uRange < _1M)
+        uint16_t cPages;
+
+        /* Adjust the start of the range such that it's at or above 1MB and page aligned.  */
+        if (uRange < _1M)
+        {
+            cbRange -= _1M - uRange;
+            uRange   = _1M;
+        }
+        else if (uRange & (_4K - 1U))
+        {
+            cbRange -= uRange & (_4K - 1U);
+            uRange   = RT_ALIGN_32(uRange, _4K);
+        }
+
+        /* Adjust the end/size of the range such that it's page aligned and not beyond the tiled area. */
+        if (uRangeEnd > BS3_SEL_TILED_AREA_SIZE)
+        {
+            cbRange  -= uRangeEnd - BS3_SEL_TILED_AREA_SIZE;
+            uRangeEnd = BS3_SEL_TILED_AREA_SIZE;
+        }
+        else if (uRangeEnd & (_4K - 1U))
+        {
+            cbRange   -= uRangeEnd & (_4K - 1U);
+            uRangeEnd &= ~(uint32_t)(_4K - 1U);
+        }
+
+        /* If there is still something, enable it.
+           (We're a bit paranoid here don't trust the BIOS to only report a page once.)  */
+        cPages = cbRange >> 12; /*div 4K*/
+        if (cPages)
+        {
+            unsigned i;
+            uRange -= _1M;
+            i = uRange >> 12; /*div _4K*/
+            while (cPages-- > 0)
             {
-                cbRange -= _1M - uRange;
-                uRange   = _1M;
-            }
-            else if (uRange & (_4K - 1U))
-            {
-                cbRange -= uRange & (_4K - 1U);
-                uRange   = RT_ALIGN_32(uRange, _4K);
-            }
-
-            /* Adjust the end/size of the range such that it's page aligned and not beyond the tiled area. */
-            if (uRangeEnd > BS3_SEL_TILED_AREA_SIZE)
-            {
-                cbRange  -= uRangeEnd - BS3_SEL_TILED_AREA_SIZE;
-                uRangeEnd = BS3_SEL_TILED_AREA_SIZE;
-            }
-            else if (uRangeEnd & (_4K - 1U))
-            {
-                cbRange   -= uRangeEnd & (_4K - 1U);
-                uRangeEnd &= ~(uint32_t)(_4K - 1U);
-            }
-
-            /* If there is still something, enable it.
-               (We're a bit paranoid here don't trust the BIOS to only report a page once.)  */
-            cPages = cbRange >> 12; /*div 4K*/
-            if (cPages)
-            {
-                unsigned i;
-                uRange -= _1M;
-                i = uRange >> 12; /*div _4K*/
-                while (cPages-- > 0)
-                {
-                    uint16_t uLineToLong = ASMBitTestAndClear(g_Bs3Mem4KUpperTiled.Core.bmAllocated, i);
-                    g_Bs3Mem4KUpperTiled.Core.cFreeChunks += uLineToLong;
-                    i++;
-                }
+                uint16_t uLineToLong = ASMBitTestAndClear(g_Bs3Mem4KUpperTiled.Core.bmAllocated, i);
+                g_Bs3Mem4KUpperTiled.Core.cFreeChunks += uLineToLong;
+                i++;
             }
         }
@@ -308,17 +319,9 @@
         while (   (uCont = Bs3BiosInt15hE820(&Entry, sizeof(Entry), uCont)) != 0
                && i++ < 2048)
-        {
-            if (   Entry.uType == INT15E820_TYPE_USABLE
-                && Entry.uBaseAddr < BS3_SEL_TILED_AREA_SIZE)
-            {
-                /* Entry concerning tiled memory. Convert from 64-bit to 32-bit
-                   values and check whether it's concerning anything at or above 1MB  */
-                uint32_t uRange    = (uint32_t)Entry.uBaseAddr;
-                uint32_t cbRange   = Entry.cbRange >= BS3_SEL_TILED_AREA_SIZE
-                                   ? BS3_SEL_TILED_AREA_SIZE : (uint32_t)Entry.cbRange;
-                AssertCompile(BS3_SEL_TILED_AREA_SIZE <= _512M /* the range of 16-bit cPages. */ );
-                bs3InitMemoryAddRange(uRange, cbRange);
-            }
-        }
+            if (Entry.uType == INT15E820_TYPE_USABLE)
+                if (!(Entry.uBaseAddr >> 32))
+                    /* Convert from 64-bit to 32-bit value and record it. */
+                    bs3InitMemoryAddRange32((uint32_t)Entry.uBaseAddr,
+                                            (Entry.cbRange >> 32) ? UINT32_C(0xfffff000) : (uint32_t)Entry.cbRange);
     }
     /* Try the 286+ API for getting memory above 1MB and (usually) below 16MB. */
@@ -326,5 +329,5 @@
              && (u32 = Bs3BiosInt15h88()) != UINT32_MAX
              && u32 > 0)
-        bs3InitMemoryAddRange(_1M, u32 * _1K);
+        bs3InitMemoryAddRange32(_1M, u32 * _1K);
 
     /*
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-system-data.asm
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-system-data.asm	(revision 60685)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-system-data.asm	(revision 60686)
@@ -1005,5 +1005,5 @@
 
 ;;
-; LGDT structure for the GDT (8-byte aligned on offset).
+; LGDT structure for the current GDT (8-byte aligned on offset).
 BS3_GLOBAL_DATA Bs3Lgdt_Gdt, 2+8
         dw      BS3_DATA_NM(Bs3GdtEnd) - BS3_DATA_NM(Bs3Gdt) - 1 ; limit
@@ -1012,4 +1012,13 @@
         dd      0                                                ; top32 offset
 
+;;
+; LGDT structure for the default GDT (8-byte aligned on offset).
+; This must not be modified, whereas Bs3Lgdt_Gdt can be modified by the user.
+BS3_GLOBAL_DATA Bs3LgdtDef_Gdt, 2+8
+        dw      BS3_DATA_NM(Bs3GdtEnd) - BS3_DATA_NM(Bs3Gdt) - 1 ; limit
+        dw      BS3_SYSTEM16_BASE_LOW(Bs3Gdt)                    ; low offset
+        dw      (BS3_ADDR_BS3SYSTEM16 >> 16)                     ; high offset
+        dd      0                                                ; top32 offset
+
 
 
@@ -1018,9 +1027,9 @@
 ; LDT filling up the rest of the segment.
 ;
-; Currently this starts at 0x84d0, which leaves us with 0xb30 bytes.  We'll use
+; Currently this starts at 0x84e0, which leaves us with 0xb20 bytes.  We'll use
 ; the last 32 of those for an eye catcher.
 ;
-BS3_GLOBAL_DATA Bs3Ldt, 0b30h - 32
-        times (0b30h - 32) db 0
+BS3_GLOBAL_DATA Bs3Ldt, 0b20h - 32
+        times (0b20h - 32) db 0
 BS3_GLOBAL_DATA Bs3LdtEnd, 0
         db  10, 13, 'eye-catcher: SYSTEM16 END', 10, 13, 0, 0, 0 ; 32 bytes long
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-autostubs.kmk
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-autostubs.kmk	(revision 60685)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-autostubs.kmk	(revision 60686)
@@ -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,Bs3PagingAlias)
 $(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3PagingInitRootForLM)
 $(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3PagingInitRootForPAE)
@@ -41,4 +42,5 @@
 $(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3PagingProtect)
 $(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3PagingProtectPtr)
+$(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3PagingUnalias)
 $(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3SwitchFromV86To16BitAndCallC)
 $(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3TrapSetHandler)
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-mangling-code-define.h
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-mangling-code-define.h	(revision 60685)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-mangling-code-define.h	(revision 60686)
@@ -47,4 +47,5 @@
 #define Bs3MemSet BS3_CMN_MANGLER(Bs3MemSet)
 #define Bs3MemZero BS3_CMN_MANGLER(Bs3MemZero)
+#define Bs3PagingAlias BS3_CMN_MANGLER(Bs3PagingAlias)
 #define bs3PagingGetLegacyPte BS3_CMN_MANGLER(bs3PagingGetLegacyPte)
 #define bs3PagingGetPte BS3_CMN_MANGLER(bs3PagingGetPte)
@@ -55,4 +56,5 @@
 #define Bs3PagingProtectPtr BS3_CMN_MANGLER(Bs3PagingProtectPtr)
 #define Bs3PagingSetupCanonicalTraps BS3_CMN_MANGLER(Bs3PagingSetupCanonicalTraps)
+#define Bs3PagingUnalias BS3_CMN_MANGLER(Bs3PagingUnalias)
 #define Bs3Panic BS3_CMN_MANGLER(Bs3Panic)
 #define Bs3PicMaskAll BS3_CMN_MANGLER(Bs3PicMaskAll)
@@ -138,4 +140,6 @@
 #define Bs3UInt32Div BS3_CMN_MANGLER(Bs3UInt32Div)
 #define Bs3UInt64Div BS3_CMN_MANGLER(Bs3UInt64Div)
+#define Bs3UtilSetFullGdtr BS3_CMN_MANGLER(Bs3UtilSetFullGdtr)
+#define Bs3UtilSetFullIdtr BS3_CMN_MANGLER(Bs3UtilSetFullIdtr)
 #ifndef BS3_CMN_ONLY
 # define Bs3CpuDetect BS3_MODE_MANGLER(Bs3CpuDetect)
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-mangling-code-undef.h
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-mangling-code-undef.h	(revision 60685)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-mangling-code-undef.h	(revision 60686)
@@ -47,4 +47,5 @@
 #undef Bs3MemSet
 #undef Bs3MemZero
+#undef Bs3PagingAlias
 #undef bs3PagingGetLegacyPte
 #undef bs3PagingGetPte
@@ -55,4 +56,5 @@
 #undef Bs3PagingProtectPtr
 #undef Bs3PagingSetupCanonicalTraps
+#undef Bs3PagingUnalias
 #undef Bs3Panic
 #undef Bs3PicMaskAll
@@ -138,4 +140,6 @@
 #undef Bs3UInt32Div
 #undef Bs3UInt64Div
+#undef Bs3UtilSetFullGdtr
+#undef Bs3UtilSetFullIdtr
 #ifndef BS3_CMN_ONLY
 # undef Bs3CpuDetect
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit.h
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit.h	(revision 60685)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit.h	(revision 60686)
@@ -196,4 +196,7 @@
 /** Whether the mode has paging enabled. */
 #define BS3_MODE_IS_PAGED(a_fMode)              ((a_fMode) >= BS3_MODE_PP16)
+/** Whether the mode has legacy paging enabled (legacy as opposed to PAE or
+ * long mode). */
+#define BS3_MODE_IS_LEGACY_PAGING(a_fMode)      ((a_fMode) >= BS3_MODE_PP16 && (a_fMode) < BS3_MODE_PAE16)
 
 /** Whether the mode is running v8086 code. */
@@ -998,8 +1001,10 @@
  *  vector table.. */
 extern X86XDTR64 BS3_FAR_DATA Bs3Lidt_Ivt;
-/** Structure for the LGDT instruction for loading the GDT. */
+/** Structure for the LGDT instruction for loading the current GDT. */
 extern X86XDTR64 BS3_FAR_DATA Bs3Lgdt_Gdt;
+/** Structure for the LGDT instruction for loading the default GDT. */
+extern X86XDTR64 BS3_FAR_DATA Bs3LgdtDef_Gdt;
 /** The LDT (all entries are empty, fill in for testing). */
-extern X86DESC   BS3_FAR_DATA Bs3Ldt[118];
+extern X86DESC   BS3_FAR_DATA Bs3Ldt[116];
 /** The end of the LDT (exclusive).   */
 extern X86DESC   BS3_FAR_DATA Bs3LdtEnd;
@@ -2043,4 +2048,7 @@
 BS3_CMN_PROTO_STUB(void, Bs3MemGuardedTestPageFree,(void BS3_FAR *pvGuardedPage));
 
+/** Highes RAM byte below 4G. */
+extern uint32_t  g_uBs3EndOfRamBelow4G;
+
 
 /**
@@ -2136,4 +2144,42 @@
  */
 BS3_CMN_PROTO_STUB(int, Bs3PagingProtectPtr,(void BS3_FAR *pv, size_t cb, uint64_t fSet, uint64_t fClear));
+
+/**
+ * Aliases (maps) one or more contiguous physical pages to a virtual range.
+ *
+ * @returns VBox status code.
+ * @retval  VERR_INVALID_PARAMETER if we're in legacy paging mode and @a uDst or
+ *          @a uPhysToAlias are not compatible with legacy paging.
+ * @retval  VERR_OUT_OF_RANGE if we cannot traverse the page tables in this mode
+ *          (typically real mode or v86, maybe 16-bit PE).
+ * @retval  VERR_NO_MEMORY if we cannot allocate page tables for splitting up
+ *          the necessary large pages.  No aliasing was performed.
+ *
+ * @param   uDst                The virtual address to map it at. Rounded down
+ *                              to the nearest page (@a cbHowMuch is adjusted
+ *                              up).
+ * @param   uPhysToAlias        The physical address of the first page in the
+ *                              (contiguous) range to map.  Chopped down to
+ *                              nearest page boundrary (@a cbHowMuch is not
+ *                              adjusted).
+ * @param   cbHowMuch           How much to map. Rounded up to nearest page.
+ * @param   fPte                The PTE flags.
+ */
+BS3_CMN_PROTO_STUB(int, Bs3PagingAlias,(uint64_t uDst, uint64_t uPhysToAlias, uint32_t cbHowMuch, uint64_t fPte));
+
+/**
+ * Unaliases memory, i.e. restores the 1:1 mapping.
+ *
+ * @returns VBox status code.  Cannot fail if @a uDst and @a cbHowMuch specify
+ *          the range of a successful Bs3PagingAlias call, however it may run
+ *          out of memory if it's breaking new ground.
+ *
+ * @param   uDst                The virtual address to restore to 1:1 mapping.
+ *                              Rounded down to the nearest page (@a cbHowMuch
+ *                              is adjusted up).
+ * @param   cbHowMuch           How much to restore. Rounded up to nearest page.
+ */
+BS3_CMN_PROTO_STUB(int, Bs3PagingUnalias,(uint64_t uDst, uint32_t cbHowMuch));
+
 
 /** The physical / flat address of the buffer backing the canonical traps.
@@ -2899,4 +2945,24 @@
     FNBS3TESTDOMODE   RT_CONCAT(a_BaseNm, _lm64)
 
+
+/**
+ * Sets the full GDTR register.
+ *
+ * @param   cbLimit     The limit.
+ * @param   uBase       The base address - 24, 32 or 64 bit depending on the
+ *                      CPU mode.
+ */
+BS3_CMN_PROTO_NOSB(void, Bs3UtilSetFullGdtr,(uint16_t cbLimit, uint64_t uBase));
+
+/**
+ * Sets the full IDTR register.
+ *
+ * @param   cbLimit     The limit.
+ * @param   uBase       The base address - 24, 32 or 64 bit depending on the
+ *                      CPU mode.
+ */
+BS3_CMN_PROTO_NOSB(void, Bs3UtilSetFullIdtr,(uint16_t cbLimit, uint64_t uBase));
+
+
 /** @} */
 
