Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/Makefile.kmk
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/Makefile.kmk	(revision 58776)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/Makefile.kmk	(revision 58777)
@@ -136,5 +136,5 @@
 define TOOL_Bs3Vcc64_COMPILE_C_CMDS
 $(TOOL_$(VBOX_VCC_TOOL_STEM)AMD64_COMPILE_C_CMDS)
-	-$(VBoxBs3ObjConverter_1_TARGET) "$(obj)"
+	$(QUIET)$(VBoxBs3ObjConverter_1_TARGET) "$(obj)"
 endef
 
@@ -375,7 +375,10 @@
        bs3-cmn-MemZero.asm \
        bs3-cmn-SlabInit.c \
+       bs3-cmn-SlabFree.c \
        bs3-cmn-SlabListInit.c \
        bs3-cmn-SlabListAdd.c \
        bs3-cmn-SlabListAlloc.c \
+       bs3-cmn-SlabListAllocEx.c \
+       bs3-cmn-SlabListFree.c \
        bs3-cmn-TestData.c \
        bs3-cmn-TestInit.c \
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-SlabFree.c
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-SlabFree.c	(revision 58777)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-SlabFree.c	(revision 58777)
@@ -0,0 +1,54 @@
+/* $Id$ */
+/** @file
+ * BS3Kit - Bs3SlabFree
+ */
+
+/*
+ * Copyright (C) 2007-2015 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"
+#include <iprt/asm.h>
+
+
+BS3_DECL(uint16_t) Bs3SlabFree(PBS3SLABCLT pSlabCtl, uint32_t uFlatChunkPtr, uint16_t cChunks)
+{
+    uint16_t cFreed = 0;
+    BS3_ASSERT(cChunks > 0);
+    if (cChunks > 0)
+    {
+        uint16_t iChunk = (uint16_t)((uFlatChunkPtr - BS3_XPTR_GET_FLAT(uint8_t, pSlabCtl->pbStart)) >> pSlabCtl->cChunkShift);
+        BS3_ASSERT(iChunk < pSlabCtl->cChunks);
+        BS3_ASSERT(iChunk + cChunks <= pSlabCtl->cChunks);
+
+        do
+        {
+            if (ASMBitTestAndClear(&pSlabCtl->bmAllocated, iChunk))
+                cFreed++;
+            else
+                BS3_ASSERT(0);
+            iChunk++;
+        } while (--cChunks > 0);
+
+        pSlabCtl->cFreeChunks += cFreed;
+    }
+    return cFreed;
+}
+
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-SlabInit.c
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-SlabInit.c	(revision 58776)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-SlabInit.c	(revision 58777)
@@ -1,5 +1,5 @@
 /* $Id$ */
 /** @file
- * BS3Kit - Bs3SlabListAdd
+ * BS3Kit - Bs3SlabInit
  */
 
@@ -31,4 +31,5 @@
 BS3_DECL(void) Bs3SlabInit(PBS3SLABCLT pSlabCtl, size_t cbSlabCtl, uint32_t uFlatSlabPtr, uint32_t cbSlab, uint16_t cbChunk)
 {
+    uint16_t cBits;
     BS3_ASSERT(RT_IS_POWER_OF_TWO(cbChunk));
     BS3_ASSERT(cbSlab >= cbChunk * 4);
@@ -39,15 +40,16 @@
     BS3_XPTR_SET_FLAT(BS3SLABCLT, pSlabCtl->pbStart, uFlatSlabPtr);
     pSlabCtl->cbChunk           = cbChunk;
-    pSlabCtl->cChunks           = cbSlab / cbChunk;
+    pSlabCtl->cChunkShift       = ASMBitFirstSetU16(cbChunk) - 1;
+    pSlabCtl->cChunks           = cbSlab >> pSlabCtl->cChunkShift;
     pSlabCtl->cFreeChunks       = pSlabCtl->cChunks;
-    pSlabCtl->cBits             = RT_ALIGN_T(pSlabCtl->cChunks, 32, uint16_t);
-    BS3_ASSERT(cbSlabCtl >= RT_OFFSETOF(BS3SLABCTL, bmAllocated[pSlabCtl->cBits >> 3]));
-    Bs3MemZero(&pSlabCtl->bmAllocated, pSlabCtl->cBits >> 3);
+    cBits                       = RT_ALIGN_T(pSlabCtl->cChunks, 32, uint16_t);
+    BS3_ASSERT(cbSlabCtl >= RT_OFFSETOF(BS3SLABCTL, bmAllocated[cBits >> 3]));
+    Bs3MemZero(&pSlabCtl->bmAllocated, cBits >> 3);
 
     /* Mark excess bitmap padding bits as allocated. */
-    if (pSlabCtl->cBits != pSlabCtl->cChunks)
+    if (cBits != pSlabCtl->cChunks)
     {
         uint16_t iBit;
-        for (iBit = pSlabCtl->cChunks; iBit < pSlabCtl->cBits; iBit++)
+        for (iBit = pSlabCtl->cChunks; iBit < cBits; iBit++)
             ASMBitSet(pSlabCtl->bmAllocated, iBit);
     }
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-SlabListAlloc.c
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-SlabListAlloc.c	(revision 58776)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-SlabListAlloc.c	(revision 58777)
@@ -26,8 +26,10 @@
 
 #include "bs3kit-template-header.h"
+#include <iprt/asm.h>
 
-BS3_DECL(void BS3_FAR *) Bs3SlabListAlloc(PBS3SLABHEAD pHead, uint16_t cChunks)
+
+BS3_DECL(void BS3_FAR *) Bs3SlabListAlloc(PBS3SLABHEAD pHead)
 {
-    if (pHead->cFreeChunks >= cChunks)
+    if (pHead->cFreeChunks)
     {
         PBS3SLABCLT pCur;
@@ -36,9 +38,17 @@
              pCur = BS3_XPTR_GET(BS3SLABCLT, pCur->pNext))
         {
-            if (pCur->cFreeChunks >= cChunks)
+            if (pCur->cFreeChunks)
             {
-                int32_t iBit = ASMBitFirstClear(&pCur->bmAllocated, pCur->cBits);
-                if (iBit >= )
+                int32_t iBit = ASMBitFirstClear(&pCur->bmAllocated, pCur->cChunks);
+                if (iBit >= 0)
                 {
+                    BS3_XPTR_AUTO(void, pvRet);
+                    ASMBitSet(&pCur->bmAllocated, iBit);
+                    pCur->cFreeChunks  -= 1;
+                    pHead->cFreeChunks -= 1;
+
+                    BS3_XPTR_SET_FLAT(void, pvRet,
+                                      BS3_XPTR_GET_FLAT(uint8_t, pCur->pbStart) + ((uint32_t)iBit << pCur->cChunkShift));
+                    return BS3_XPTR_GET(void, pvRet);
                 }
             }
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-SlabListAllocEx.c
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-SlabListAllocEx.c	(revision 58777)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-SlabListAllocEx.c	(revision 58777)
@@ -0,0 +1,102 @@
+/* $Id$ */
+/** @file
+ * BS3Kit - Bs3SlabListAllocEx
+ */
+
+/*
+ * Copyright (C) 2007-2015 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"
+#include <iprt/asm.h>
+
+
+BS3_DECL(void BS3_FAR *) Bs3SlabListAllocEx(PBS3SLABHEAD pHead, uint16_t cChunks, uint16_t fFlags)
+{
+    BS3_ASSERT(!(fFlags & ~BS3_SLAB_ALLOC_F_SAME_TILE));
+    if (pHead->cFreeChunks >= cChunks)
+    {
+        PBS3SLABCLT pCur;
+        for (pCur = BS3_XPTR_GET(BS3SLABCLT, pHead->pFirst);
+             pCur != NULL;
+             pCur = BS3_XPTR_GET(BS3SLABCLT, pCur->pNext))
+        {
+            if (pCur->cFreeChunks >= cChunks)
+            {
+                int32_t iBit = ASMBitFirstClear(&pCur->bmAllocated, pCur->cChunks);
+                if (iBit >= 0)
+                {
+                    while ((uint32_t)iBit + cChunks <= pCur->cChunks)
+                    {
+                        /* Check that we've got the requested number of free chunks here. */
+                        uint16_t i;
+                        for (i = 1; i < cChunks; i++)
+                            if (!ASMBitTest(&pCur->bmAllocated, iBit + i))
+                                break;
+                        if (i == cChunks)
+                        {
+                            BS3_XPTR_AUTO(void, pvRet);
+
+                            /* Check if the chunks are all in the same tiled segment. */
+                            BS3_XPTR_SET_FLAT(void, pvRet,
+                                              BS3_XPTR_GET_FLAT(uint8_t, pCur->pbStart) + ((uint32_t)iBit << pCur->cChunkShift));
+                            if (   !(fFlags & BS3_SLAB_ALLOC_F_SAME_TILE)
+                                ||    (BS3_XPTR_GET_FLAT(void, pvRet) >> 16)
+                                   == (BS3_XPTR_GET_FLAT(void, pvRet) + ((uint32_t)cChunks << pCur->cChunkShift)) )
+                            {
+                                /* Complete the allocation. */
+                                for (i = 0; i < cChunks; i++)
+                                    ASMBitSet(&pCur->bmAllocated, iBit + i);
+                                pCur->cFreeChunks  -= cChunks;
+                                pHead->cFreeChunks -= cChunks;
+
+                                return BS3_XPTR_GET(void, pvRet);
+                            }
+
+                            /*
+                             * We're crossing a tiled segment boundrary.
+                             * Skip to the start of the next segment and retry there.
+                             * (We already know that the first chunk in the next tiled
+                             * segment is free, otherwise we wouldn't have a crossing.)
+                             */
+                            BS3_ASSERT(((uint32_t)cChunks << pCur->cChunkShift) <= _64K);
+                            i = BS3_XPTR_GET_FLAT_LOW(void, pvRet);
+                            i = UINT16_C(0) - i;
+                            i >>= pCur->cChunkShift;
+                            iBit += i;
+                        }
+                        else
+                        {
+                            /*
+                             * Continue searching.
+                             */
+                            iBit = ASMBitNextClear(&pCur->bmAllocated, pCur->cChunks, iBit + i);
+                            if (iBit < 0)
+                                break;
+                        }
+                    }
+                }
+            }
+        }
+    }
+    return NULL;
+}
+
+
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-SlabListFree.c
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-SlabListFree.c	(revision 58777)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-SlabListFree.c	(revision 58777)
@@ -0,0 +1,53 @@
+/* $Id$ */
+/** @file
+ * BS3Kit - Bs3SlabListFree
+ */
+
+/*
+ * Copyright (C) 2007-2015 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(void) Bs3SlabListFree(PBS3SLABHEAD pHead, void BS3_FAR *pvChunks, uint16_t cChunks)
+{
+    BS3_ASSERT(cChunks > 0);
+    if (cChunks > 0)
+    {
+        PBS3SLABCLT         pCur;
+        BS3_XPTR_AUTO(void, pvFlatChunk);
+        BS3_XPTR_SET(void,  pvFlatChunk, pvChunks);
+
+        for (pCur = BS3_XPTR_GET(BS3SLABCLT, pHead->pFirst);
+             pCur != NULL;
+             pCur = BS3_XPTR_GET(BS3SLABCLT, pCur->pNext))
+        {
+            if (  ((BS3_XPTR_GET_FLAT(void, pvFlatChunk) - BS3_XPTR_GET_FLAT(uint8_t, pCur->pbStart)) >> pCur->cChunkShift)
+                < pCur->cChunks)
+            {
+                pHead->cFreeChunks += Bs3SlabFree(pCur, BS3_XPTR_GET_FLAT(void, pvFlatChunk), cChunks);
+                return;
+            }
+        }
+        BS3_ASSERT(0);
+    }
+}
+
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit.h
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit.h	(revision 58776)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit.h	(revision 58777)
@@ -683,5 +683,5 @@
 #endif
 
-/** @def BS3_XPTR_DEF_MEMB
+/** @def BS3_XPTR_DEF_MEMBER
  * Defines a pointer member that can be shared by all CPU modes.
  *
@@ -690,4 +690,15 @@
  */
 #define BS3_XPTR_MEMBER(a_Type, a_Name) BS3_XPTR_DEF_INTERNAL(RT_NOTHING, a_Type, a_Name)
+
+/** @def BS3_XPTR_DEF_AUTO
+ * Defines a pointer static variable for working with an XPTR.
+ *
+ * This is typically used to convert flat pointers into context specific
+ * pointers.
+ *
+ * @param   a_Type      The type we're pointing to.
+ * @param   a_Name      The member or variable name.
+ */
+#define BS3_XPTR_AUTO(a_Type, a_Name) BS3_XPTR_DEF_INTERNAL(RT_NOTHING, a_Type, a_Name)
 
 /** @def BS3_XPTR_SET
@@ -706,8 +717,18 @@
  * Gets the flat address of a cross context pointer.
  *
+ * @returns 32-bit flat pointer.
  * @param   a_Type      The type we're pointing to.
  * @param   a_Name      The member or variable name.
  */
 #define BS3_XPTR_GET_FLAT(a_Type, a_Name) (a_Name.XPtr.uFlat)
+
+/** @def BS3_XPTR_GET_FLAT_LOW
+ * Gets the low 16 bits of the flat address.
+ *
+ * @returns Low 16 bits of the flat pointer.
+ * @param   a_Type      The type we're pointing to.
+ * @param   a_Name      The member or variable name.
+ */
+#define BS3_XPTR_GET_FLAT_LOW(a_Type, a_Name) (a_Name.XPtr.u.uLow)
 
 
@@ -815,5 +836,10 @@
  */
 
-#define BS3_ASSERT(a_Expr) do { } while (0) /**< @todo later */
+#define BS3_STRICT  /**< @todo later */
+#ifdef BS3_STRICT
+# define BS3_ASSERT(a_Expr) do { } while (0) /**< @todo later */
+#else
+# define BS3_ASSERT(a_Expr) do { } while (0) /**< @todo later */
+#endif
 
 /**
@@ -1045,6 +1071,7 @@
     /** The chunk size. */
     uint16_t                        cbChunk;
-    /** Number of bits in the bitmap (cChunks rounded up to 32). */
-    uint16_t                        cBits;
+    /** The shift count corresponding to cbChunk.
+     * This is for turning a chunk number into a byte offset and vice versa. */
+    uint16_t                        cChunkShift;
     /** Bitmap where set bits indicates allocated blocks (variable size,
      * multiple of 4). */
@@ -1096,21 +1123,50 @@
 
 /**
- * Allocates one or more chunks.
+ * Allocates one chunk.
  *
  * @returns Pointer to a chunk on success, NULL if we're out of chunks.
  * @param   pHead           The slab list to allocate from.
+ */
+BS3_DECL(void BS3_FAR *) Bs3SlabListAlloc_c16(PBS3SLABHEAD pHead);
+BS3_DECL(void BS3_FAR *) Bs3SlabListAlloc_c32(PBS3SLABHEAD pHead); /**< @copydoc Bs3SlabListAlloc_c16 */
+BS3_DECL(void BS3_FAR *) Bs3SlabListAlloc_c64(PBS3SLABHEAD pHead); /**< @copydoc Bs3SlabListAlloc_c16 */
+#define Bs3SlabListAlloc BS3_CMN_NM(Bs3SlabListAlloc) /**< Selects #Bs3SlabListAlloc_c16, #Bs3SlabListAlloc_c32 or #Bs3SlabListAlloc_c64. */
+
+/**
+ * Allocates one or more chunks.
+ *
+ * @returns Pointer to the request number of chunks on success, NULL if we're
+ *          out of chunks.
+ * @param   pHead           The slab list to allocate from.
  * @param   cChunks         The number of contiguous chunks we want.
- */
-BS3_DECL(void BS3_FAR *) Bs3SlabListAlloc_c16(PBS3SLABHEAD pHead, uint16_t cChunks);
-BS3_DECL(void BS3_FAR *) Bs3SlabListAlloc_c32(PBS3SLABHEAD pHead, uint16_t cChunks); /**< @copydoc Bs3SlabListAlloc_c16 */
-BS3_DECL(void BS3_FAR *) Bs3SlabListAlloc_c64(PBS3SLABHEAD pHead, uint16_t cChunks); /**< @copydoc Bs3SlabListAlloc_c16 */
-#define Bs3SlabListAlloc BS3_CMN_NM(Bs3SlabListAlloc) /**< Selects #Bs3SlabListAlloc_c16, #Bs3SlabListAlloc_c32 or #Bs3SlabListAlloc_c64. */
-
-/**
- * Frees one or more chunks.
+ * @param   fFlags          Flags, see BS3_SLAB_ALLOC_F_XXX
+ */
+BS3_DECL(void BS3_FAR *) Bs3SlabListAllocEx_c16(PBS3SLABHEAD pHead, uint16_t cChunks, uint16_t fFlags);
+BS3_DECL(void BS3_FAR *) Bs3SlabListAllocEx_c32(PBS3SLABHEAD pHead, uint16_t cChunks, uint16_t fFlags); /**< @copydoc Bs3SlabListAllocEx_c16 */
+BS3_DECL(void BS3_FAR *) Bs3SlabListAllocEx_c64(PBS3SLABHEAD pHead, uint16_t cChunks, uint16_t fFlags); /**< @copydoc Bs3SlabListAllocEx_c16 */
+#define Bs3SlabListAllocEx BS3_CMN_NM(Bs3SlabListAllocEx) /**< Selects #Bs3SlabListAllocEx_c16, #Bs3SlabListAllocEx_c32 or #Bs3SlabListAllocEx_c64. */
+/** The chunks must all be in the same 16-bit segment tile. */
+#define BS3_SLAB_ALLOC_F_SAME_TILE      UINT16_C(0x0001)
+
+/**
+ * Frees one or more chunks from a slab.
+ *
+ * @returns Number of chunks actually freed.  When correctly used, this will
+ *          match the @a cChunks parameter, of course.
+ * @param   pSlabCtl        The slab constrol structure to free from.
+ * @param   uFlatChunkPtr   The flat address of the chunks to free.
+ * @param   cChunks         The number of contiguous chunks to free.
+ */
+BS3_DECL(uint16_t) Bs3SlabFree_c16(PBS3SLABCLT pSlabCtl, uint32_t uFlatChunkPtr, uint16_t cChunks);
+BS3_DECL(uint16_t) Bs3SlabFree_c32(PBS3SLABCLT pSlabCtl, uint32_t uFlatChunkPtr, uint16_t cChunks); /**< @copydoc Bs3SlabFree_c16 */
+BS3_DECL(uint16_t) Bs3SlabFree_c64(PBS3SLABCLT pSlabCtl, uint32_t uFlatChunkPtr, uint16_t cChunks); /**< @copydoc Bs3SlabFree_c16 */
+#define Bs3SlabFree BS3_CMN_NM(Bs3SlabFree) /**< Selects #Bs3SlabFree_c16, #Bs3SlabFree_c32 or #Bs3SlabFree_c64. */
+
+/**
+ * Frees one or more chunks from a slab list.
  *
  * @param   pHead           The slab list to allocate from.
  * @param   pvChunks        Pointer to the first chunk to free.
- * @param   cChunks         The number of contiguous chunks we want.
+ * @param   cChunks         The number of contiguous chunks to free.
  */
 BS3_DECL(void) Bs3SlabListFree_c16(PBS3SLABHEAD pHead, void BS3_FAR *pvChunks, uint16_t cChunks);
