[PATCH 4/6] score: Work area initialization API change

Sebastian Huber sebastian.huber at embedded-brains.de
Mon Oct 15 13:13:55 UTC 2012


The work areas (RTEMS work space and C program heap) will be initialized
now in a separate step and are no longer part of
rtems_initialize_data_structures().  Initialization is performed with
tables of Heap_Area entries.  This allows usage of scattered memory
areas present on various small scale micro-controllers.

The sbrk() support API changes also.  The bsp_sbrk_init() must now deal
with a minimum size for the first memory chunk to take the configured
work space size into account.
---
 c/src/lib/libbsp/arm/gba/startup/bspgetworkarea.c  |   20 +--
 .../lib/libbsp/i386/pc386/startup/bspgetworkarea.c |   30 +---
 .../libbsp/powerpc/shared/startup/bspgetworkarea.c |   51 +------
 c/src/lib/libbsp/powerpc/shared/startup/sbrk.c     |   47 +++---
 .../libbsp/powerpc/tqm8xx/startup/bspgetworkarea.c |   27 ++--
 c/src/lib/libbsp/shared/bootcard.c                 |  118 +-------------
 c/src/lib/libbsp/shared/bspgetworkarea.c           |   54 +------
 c/src/lib/libbsp/shared/bsplibc.c                  |    8 +-
 c/src/lib/libbsp/shared/include/bootcard.h         |  175 +++++++++++++-------
 c/src/lib/libbsp/sparc/erc32/include/bsp.h         |    4 +-
 c/src/lib/libbsp/sparc/leon2/include/bsp.h         |    4 +-
 c/src/lib/libbsp/sparc/leon3/include/bsp.h         |    4 +-
 c/src/lib/libbsp/sparc/shared/bspgetworkarea.c     |   27 +--
 .../lib/libbsp/sparc/shared/startup/early_malloc.c |    4 +-
 c/src/lib/libbsp/sparc64/niagara/Makefile.am       |    2 +-
 .../libbsp/sparc64/shared/startup/bspgetworkarea.c |   91 ----------
 c/src/lib/libbsp/sparc64/usiii/Makefile.am         |    2 +-
 cpukit/libcsupport/Makefile.am                     |    4 +-
 cpukit/libcsupport/include/rtems/libcsupport.h     |    6 -
 cpukit/libcsupport/include/rtems/malloc.h          |   45 ++++-
 cpukit/libcsupport/src/malloc.c                    |    3 +-
 cpukit/libcsupport/src/malloc_initialize.c         |  115 +++++--------
 cpukit/libcsupport/src/malloc_p.h                  |    5 -
 cpukit/libcsupport/src/malloc_sbrk_helpers.c       |  108 ------------
 cpukit/libcsupport/src/mallocinfo.c                |    6 +-
 .../libcsupport/src/rtems_heap_extend_via_sbrk.c   |   58 +++++++
 cpukit/libcsupport/src/rtems_heap_null_extend.c    |   27 +++
 cpukit/libmisc/monitor/mon-config.c                |    1 -
 cpukit/sapi/include/confdefs.h                     |    9 +-
 cpukit/sapi/include/rtems/config.h                 |   10 -
 cpukit/sapi/src/exinit.c                           |    6 -
 cpukit/score/include/rtems/score/heap.h            |   30 ++++
 cpukit/score/include/rtems/score/interr.h          |    3 +-
 cpukit/score/include/rtems/score/wkspace.h         |   14 +-
 cpukit/score/inline/rtems/score/heap.inl           |   14 --
 cpukit/score/src/wkspace.c                         |   67 ++++++--
 testsuites/libtests/malloc04/init.c                |   43 ++++--
 testsuites/psxtests/psxfatal_support/init.c        |    9 +-
 testsuites/sptests/Makefile.am                     |    2 +-
 testsuites/sptests/configure.ac                    |    1 -
 testsuites/sptests/spfatal06/testcase.h            |   11 +-
 testsuites/sptests/spfatal07/testcase.h            |    6 +-
 testsuites/sptests/spfatal08/testcase.h            |   14 ++-
 testsuites/sptests/spfatal09/testcase.h            |   11 +-
 testsuites/sptests/spfatal12/testcase.h            |    5 +-
 testsuites/sptests/spfatal21/Makefile.am           |   21 ---
 testsuites/sptests/spfatal21/spfatal21.doc         |   19 --
 testsuites/sptests/spfatal21/spfatal21.scn         |    3 -
 testsuites/sptests/spfatal21/testcase.h            |   34 ----
 testsuites/sptests/spfatal_support/init.c          |    9 +-
 50 files changed, 524 insertions(+), 863 deletions(-)
 delete mode 100644 c/src/lib/libbsp/sparc64/shared/startup/bspgetworkarea.c
 delete mode 100644 cpukit/libcsupport/src/malloc_sbrk_helpers.c
 create mode 100644 cpukit/libcsupport/src/rtems_heap_extend_via_sbrk.c
 create mode 100644 cpukit/libcsupport/src/rtems_heap_null_extend.c
 delete mode 100644 testsuites/sptests/spfatal21/Makefile.am
 delete mode 100644 testsuites/sptests/spfatal21/spfatal21.doc
 delete mode 100644 testsuites/sptests/spfatal21/spfatal21.scn
 delete mode 100644 testsuites/sptests/spfatal21/testcase.h

diff --git a/c/src/lib/libbsp/arm/gba/startup/bspgetworkarea.c b/c/src/lib/libbsp/arm/gba/startup/bspgetworkarea.c
index abce92f..d1c06b1 100644
--- a/c/src/lib/libbsp/arm/gba/startup/bspgetworkarea.c
+++ b/c/src/lib/libbsp/arm/gba/startup/bspgetworkarea.c
@@ -11,21 +11,11 @@
 extern  void _end;
 extern  void __heap_limit;
 
-/*
- *  This method returns the base address and size of the area which
- *  is to be allocated between the RTEMS Workspace and the C Program
- *  Heap.
- */
-void bsp_get_work_area(
-  void      **work_area_start,
-  uintptr_t  *work_area_size,
-  void      **heap_start,
-  uintptr_t  *heap_size
-)
+void bsp_work_area_initialize(void)
 {
-  *work_area_start = (void *)&_end;
-  *work_area_size  = (uintptr_t)&__heap_limit - (uintptr_t)&_end;
-  *heap_start      = BSP_BOOTCARD_HEAP_USES_WORK_AREA;
-  *heap_size       = BSP_BOOTCARD_HEAP_SIZE_DEFAULT;
+  void *area_start = (void *)&_end;
+  uintptr_t area_size  = (uintptr_t)&__heap_limit - (uintptr_t)&_end;
+
+  bsp_work_area_initialize_default( area_start, area_size );
 }
 
diff --git a/c/src/lib/libbsp/i386/pc386/startup/bspgetworkarea.c b/c/src/lib/libbsp/i386/pc386/startup/bspgetworkarea.c
index 8668d45..f6ff139 100644
--- a/c/src/lib/libbsp/i386/pc386/startup/bspgetworkarea.c
+++ b/c/src/lib/libbsp/i386/pc386/startup/bspgetworkarea.c
@@ -1,5 +1,5 @@
 /*
- *  This routine is an implementation of the bsp_get_work_area()
+ *  This routine is an implementation of the bsp_work_area_initialize()
  *  that can be used by all m68k BSPs following linkcmds conventions
  *  regarding heap, stack, and workspace allocation.
  *
@@ -120,30 +120,10 @@ void bsp_size_memory(void)
   bsp_mem_size = topAddr;
 }
 
-/*
- *  This method returns the base address and size of the area which
- *  is to be allocated between the RTEMS Workspace and the C Program
- *  Heap.
- */
-void bsp_get_work_area(
-  void      **work_area_start,
-  uintptr_t  *work_area_size,
-  void      **heap_start,
-  uintptr_t  *heap_size
-)
+void bsp_work_area_initialize(void)
 {
-  *work_area_start = (void *) rtemsWorkAreaStart;
-  *work_area_size  = (uintptr_t) bsp_mem_size - (uintptr_t) rtemsWorkAreaStart;
-  *heap_start      = BSP_BOOTCARD_HEAP_USES_WORK_AREA;
-  *heap_size       = (uintptr_t) HeapSize;
+  void *area_start = (void *) rtemsWorkAreaStart;
+  uintptr_t work_area_size  = (uintptr_t) bsp_mem_size - (uintptr_t) rtemsWorkAreaStart;
 
-  #ifdef BSP_GET_WORK_AREA_DEBUG
-    printk( "bsp_mem_size = 0x%08x\n", bsp_mem_size );
-    printk( "rtemsWorkAreaStart = 0x%08x\n", rtemsWorkAreaStart );
-    printk( "WorkArea Base = %p\n", *work_area_start );
-    printk( "WorkArea Size = 0x%08x\n", *work_area_size );
-    printk( "C Program Heap Base = %p\n", *heap_start );
-    printk( "C Program Heap Size = 0x%08x\n", *heap_size );
-    printk( "End of WorkArea = %p\n", *work_area_start +  *work_area_size );
-  #endif
+  bsp_work_area_initialize_default( area_start, area_size );
 }
diff --git a/c/src/lib/libbsp/powerpc/shared/startup/bspgetworkarea.c b/c/src/lib/libbsp/powerpc/shared/startup/bspgetworkarea.c
index 174cf68..02d47c8 100644
--- a/c/src/lib/libbsp/powerpc/shared/startup/bspgetworkarea.c
+++ b/c/src/lib/libbsp/powerpc/shared/startup/bspgetworkarea.c
@@ -4,28 +4,12 @@
  *  http://www.rtems.com/license/LICENSE.
  */
 
-/* #define BSP_GET_WORK_AREA_DEBUG */
-
 #include <bsp.h>
 #include <bsp/bootcard.h>
-#include <stdint.h>
-#ifdef BSP_GET_WORK_AREA_DEBUG
-  #include <rtems/bspIo.h>
-#endif
 
 extern void *__rtems_end;
 
-/*
- *  This method returns the base address and size of the area which
- *  is to be allocated between the RTEMS Workspace and the C Program
- *  Heap.
- */
-void bsp_get_work_area(
-  void      **work_area_start,
-  uintptr_t  *work_area_size,
-  void      **heap_start,
-  uintptr_t  *heap_size
-)
+void bsp_work_area_initialize(void)
 {
   uintptr_t work_size;
   uintptr_t work_area;
@@ -34,36 +18,5 @@ void bsp_get_work_area(
               rtems_configuration_get_interrupt_stack_size();
   work_size = (uintptr_t)BSP_mem_size - work_area;
 
-  *work_area_start = (void *)work_area,
-  *work_area_size  = work_size;
-  *heap_start      = BSP_BOOTCARD_HEAP_USES_WORK_AREA;
-  *heap_size       = BSP_BOOTCARD_HEAP_SIZE_DEFAULT;
-
-  /*
-   *  The following may be helpful in debugging what goes wrong when
-   *  you are allocating the Work Area in a new BSP.
-   */
-  #ifdef BSP_GET_WORK_AREA_DEBUG
-    {
-      void *sp = __builtin_frame_address(0);
-      void *end = *work_area_start + *work_area_size;
-      printk(
-        "work_area_start = 0x%p\n"
-        "work_area_size = %d 0x%08x\n"
-        "end = 0x%p\n"
-        "heap_start = 0x%p\n"
-        "heap_size = %d\n"
-        "current stack pointer = 0x%p%s\n",
-        *work_area_start,
-        *work_area_size,  /* decimal */
-        *work_area_size,  /* hexadecimal */
-        end,
-        *heap_start,
-        *heap_size,
-        sp,
-        ((sp >= *work_area_start && sp <= end) ? " OVERLAPS!" : "")
-     );
-  }
-  #endif
+  bsp_work_area_initialize_default((void *) work_area, work_size);
 }
-
diff --git a/c/src/lib/libbsp/powerpc/shared/startup/sbrk.c b/c/src/lib/libbsp/powerpc/shared/startup/sbrk.c
index 35ce1f4..cd1867d 100644
--- a/c/src/lib/libbsp/powerpc/shared/startup/sbrk.c
+++ b/c/src/lib/libbsp/powerpc/shared/startup/sbrk.c
@@ -61,15 +61,15 @@
  *        for module code.
  */
 
-#include <rtems.h>
-
-#include <signal.h>
 #include <errno.h>
-#include <sys/types.h>
 #include <unistd.h>
 
-static void *           remaining_start=(void*)-1LL;
-static uintptr_t        remaining_size=0;
+#include <bsp/bootcard.h>
+
+#define INVALID_REMAINING_START ((uintptr_t) -1)
+
+static uintptr_t remaining_start = INVALID_REMAINING_START;
+static uintptr_t remaining_size = 0;
 
 /* App. may provide a value by defining the BSP_sbrk_policy
  * variable.
@@ -81,24 +81,24 @@ static uintptr_t        remaining_size=0;
  */
 extern uintptr_t        BSP_sbrk_policy __attribute__((weak));
 
-#define LIMIT_32M  ((void*)0x02000000)
+#define LIMIT_32M  0x02000000
 
-uintptr_t bsp_sbrk_init(
-  void              *heap_start,
-  uintptr_t         *heap_size_p
-)
+ptrdiff_t bsp_sbrk_init(Heap_Area *area, uintptr_t min_size)
 {
-  uintptr_t         rval=0;
+  uintptr_t         rval = 0;
   uintptr_t         policy;
+  uintptr_t         remaining_end;
 
-  remaining_start =  heap_start;
-  remaining_size  = *heap_size_p;
+  remaining_start = (uintptr_t) area->begin;
+  remaining_size  = area->size;
+  remaining_end   = remaining_start + remaining_size;
 
   if (remaining_start < LIMIT_32M &&
-      remaining_start + remaining_size > LIMIT_32M) {
+      remaining_end > LIMIT_32M &&
+      min_size <= LIMIT_32M - remaining_start) {
     /* clip at LIMIT_32M */
-    rval = remaining_start + remaining_size - LIMIT_32M;
-    *heap_size_p = LIMIT_32M - remaining_start;
+    rval = remaining_end - LIMIT_32M;
+    area->size = LIMIT_32M - remaining_start;
     remaining_start = LIMIT_32M;
     remaining_size  = rval;
   }
@@ -106,8 +106,8 @@ uintptr_t bsp_sbrk_init(
   policy = (0 == &BSP_sbrk_policy ? (uintptr_t)(-1) : BSP_sbrk_policy);
   switch ( policy ) {
       case (uintptr_t)(-1):
-        *heap_size_p    += rval;
-        remaining_start  = heap_start + *heap_size_p;
+        area->size      += rval;
+        remaining_start  = (uintptr_t) area->begin + area->size;
         remaining_size   = 0;
       break;
 
@@ -121,7 +121,7 @@ uintptr_t bsp_sbrk_init(
       break;
   }
 
-  return rval;
+  return (ptrdiff_t) (rval <= PTRDIFF_MAX ? rval : rval / 2);
 }
 
 /*
@@ -129,14 +129,13 @@ uintptr_t bsp_sbrk_init(
  * should just use the default implementation in this file.
  */
 void *sbrk(ptrdiff_t incr) __attribute__ (( weak, alias("bsp_sbrk") ));
-void *bsp_sbrk(ptrdiff_t incr)
+static void *bsp_sbrk(ptrdiff_t incr)
 {
   void *rval=(void*)-1;
 
-  /* FIXME: BEWARE if size >2G */
-  if ( remaining_start != (void*)-1LL && incr <= remaining_size) {
+  if ( remaining_start != INVALID_REMAINING_START && incr <= remaining_size) {
     remaining_size-=incr;
-    rval = remaining_start;
+    rval = (void *) remaining_start;
     remaining_start += incr;
   } else {
     errno = ENOMEM;
diff --git a/c/src/lib/libbsp/powerpc/tqm8xx/startup/bspgetworkarea.c b/c/src/lib/libbsp/powerpc/tqm8xx/startup/bspgetworkarea.c
index bd06b70..d952189 100644
--- a/c/src/lib/libbsp/powerpc/tqm8xx/startup/bspgetworkarea.c
+++ b/c/src/lib/libbsp/powerpc/tqm8xx/startup/bspgetworkarea.c
@@ -7,12 +7,13 @@
  */
 
 /*
- * Copyright (c) 2008
- * Embedded Brains GmbH
- * Obere Lagerstr. 30
- * D-82178 Puchheim
- * Germany
- * rtems at embedded-brains.de
+ * Copyright (c) 2008-2012 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Obere Lagerstr. 30
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems at embedded-brains.de>
  *
  * The license and distribution terms for this file may be
  * found in the file LICENSE in this distribution or at
@@ -24,17 +25,11 @@
 #include <bsp.h>
 #include <bsp/bootcard.h>
 
-void bsp_get_work_area(
-  void      **work_area_start,
-  uintptr_t  *work_area_size,
-  void      **heap_start,
-  uintptr_t  *heap_size
-)
+void bsp_work_area_initialize(void)
 {
   char *ram_end = (char *) (TQM_BD_INFO.sdram_size - (uint32_t)TopRamReserved);
+  void *area_start = bsp_work_area_start;
+  uintptr_t area_size = (uintptr_t) ram_end - (uintptr_t) bsp_work_area_start;
 
-  *work_area_start = bsp_work_area_start;
-  *work_area_size = ram_end - bsp_work_area_start;
-  *heap_start = BSP_BOOTCARD_HEAP_USES_WORK_AREA;
-  *heap_size = BSP_BOOTCARD_HEAP_SIZE_DEFAULT;
+  bsp_work_area_initialize_default( area_start, area_size );
 }
diff --git a/c/src/lib/libbsp/shared/bootcard.c b/c/src/lib/libbsp/shared/bootcard.c
index 189b463..33ad0ee 100644
--- a/c/src/lib/libbsp/shared/bootcard.c
+++ b/c/src/lib/libbsp/shared/bootcard.c
@@ -64,41 +64,6 @@
 const char *bsp_boot_cmdline;
 
 /*
- *  These are the prototypes and helper routines which are used
- *  when the BSP lets the framework handle RAM allocation between
- *  the RTEMS Workspace and C Program Heap.
- */
-static void bootcard_bsp_libc_helper(
-  void      *work_area_start,
-  uintptr_t  work_area_size,
-  void      *heap_start,
-  uintptr_t  heap_size,
-  uintptr_t  sbrk_amount
-)
-{
-  if ( heap_start == BSP_BOOTCARD_HEAP_USES_WORK_AREA ) {
-    if ( !rtems_configuration_get_unified_work_area() ) {
-      uintptr_t work_space_size = rtems_configuration_get_work_space_size();
-
-      heap_start = (char *) work_area_start + work_space_size;
-
-      if (heap_size == BSP_BOOTCARD_HEAP_SIZE_DEFAULT) {
-        uintptr_t heap_size_default = work_area_size - work_space_size;
-
-        heap_size = heap_size_default;
-      }
-    } else {
-      heap_start = work_area_start;
-      if (heap_size == BSP_BOOTCARD_HEAP_SIZE_DEFAULT) {
-        heap_size = work_area_size;
-      }
-    }
-  }
-
-  bsp_libc_init(heap_start, heap_size, sbrk_amount);
-}
-
-/*
  *  This is the initialization framework routine that weaves together
  *  calls to RTEMS and the BSP in the proper sequence to initialize
  *  the system while maximizing shared code and keeping BSP code in C
@@ -109,12 +74,6 @@ uint32_t boot_card(
 )
 {
   rtems_interrupt_level  bsp_isr_level;
-  void                  *work_area_start = NULL;
-  uintptr_t              work_area_size = 0;
-  void                  *heap_start = NULL;
-  uintptr_t              heap_size = 0;
-  uintptr_t              sbrk_amount = 0;
-  uintptr_t              work_space_size = 0;
   uint32_t               status = 0;
 
   /*
@@ -138,74 +97,9 @@ uint32_t boot_card(
   bsp_start();
 
   /*
-   *  Find out where the block of memory the BSP will use for
-   *  the RTEMS Workspace and the C Program Heap is.
+   *  Initialize the RTEMS Workspace and the C Program Heap.
    */
-  bsp_get_work_area(&work_area_start, &work_area_size,
-                    &heap_start, &heap_size);
-
-#ifdef CONFIGURE_MALLOC_BSP_SUPPORTS_SBRK
-  /* This routine may reduce the work area size with the
-   * option to extend it later via sbrk(). If the application
-   * was configured w/o CONFIGURE_MALLOC_BSP_SUPPORTS_SBRK then
-   * omit this step.
-   */
-  if ( rtems_malloc_sbrk_helpers ) {
-    sbrk_amount = bsp_sbrk_init(work_area_start, &work_area_size);
-    work_space_size = rtems_configuration_get_work_space_size();
-    if ( work_area_size <  work_space_size && sbrk_amount > 0 ) {
-      /* Need to use sbrk right now */
-      uintptr_t sbrk_now;
-
-      sbrk_now = (work_space_size - work_area_size) / sbrk_amount;
-      sbrk( sbrk_now * sbrk_amount );
-    }
-  }
-#else
-  if ( rtems_malloc_sbrk_helpers ) {
-    printk("Configuration error!\n"
-           "Application was configured with CONFIGURE_MALLOC_BSP_SUPPORTS_SBRK\n"
-           "but BSP was configured w/o sbrk support\n");
-    status = 1;
-    bsp_cleanup( status );
-    return status;
-  }
-#endif
-
-  /*
-   *  If the user has configured a set of objects which will require more
-   *  workspace than is actually available, print a message indicating
-   *  such and return to the invoking initialization code.
-   *
-   *  NOTE: Output from printk() may not work at this point on some BSPs.
-   *
-   *  NOTE: Use cast to (void *) and %p since these are uintptr_t types.
-   */
-  work_space_size = rtems_configuration_get_work_space_size();
-  if ( work_area_size <= work_space_size ) {
-    printk(
-      "bootcard: work space too big for work area: %p >= %p\n",
-      (void *) work_space_size,
-      (void *) work_area_size
-    );
-    status = 1;
-    bsp_cleanup( status );
-    return status;
-  }
-
-  if ( !rtems_configuration_get_unified_work_area() ) {
-    rtems_configuration_set_work_space_start( work_area_start );
-  } else {
-    rtems_configuration_set_work_space_start( work_area_start );
-    rtems_configuration_set_work_space_size( work_area_size );
-    if ( !rtems_configuration_get_stack_allocator_avoids_work_space() ) {
-      rtems_configuration_set_stack_space_size( 0 );
-    }
-  }
-
-  #if (BSP_DIRTY_MEMORY == 1)
-    memset( work_area_start, 0xCF,  work_area_size );
-  #endif
+  bsp_work_area_initialize();
 
   /*
    *  Initialize RTEMS data structures
@@ -216,13 +110,7 @@ uint32_t boot_card(
    *  Initialize the C library for those BSPs using the shared
    *  framework.
    */
-  bootcard_bsp_libc_helper(
-    work_area_start,
-    work_area_size,
-    heap_start,
-    heap_size,
-    sbrk_amount
-  );
+  bsp_libc_init();
 
   /*
    *  Let the BSP do any required initialization now that RTEMS
diff --git a/c/src/lib/libbsp/shared/bspgetworkarea.c b/c/src/lib/libbsp/shared/bspgetworkarea.c
index a2ad2e9..4122c9b 100644
--- a/c/src/lib/libbsp/shared/bspgetworkarea.c
+++ b/c/src/lib/libbsp/shared/bspgetworkarea.c
@@ -1,25 +1,20 @@
 /*
- *  This routine is an implementation of the bsp_get_work_area()
+ *  This routine is an implementation of the bsp_work_area_initialize()
  *  that can be used by all BSPs following linkcmds conventions
  *  regarding heap, stack, and workspace allocation.
  *
  *  COPYRIGHT (c) 1989-2008.
  *  On-Line Applications Research Corporation (OAR).
  *
- *  Copyright (c) 2011 embedded brains GmbH.
+ *  Copyright (c) 2011-2012 embedded brains GmbH.
  *
  *  The license and distribution terms for this file may be
  *  found in the file LICENSE in this distribution or at
  *  http://www.rtems.com/license/LICENSE.
  */
 
-/* #define BSP_GET_WORK_AREA_DEBUG */
-
 #include <bsp.h>
 #include <bsp/bootcard.h>
-#ifdef BSP_GET_WORK_AREA_DEBUG
-  #include <rtems/bspIo.h>
-#endif
 #ifdef BSP_INTERRUPT_STACK_AT_WORK_AREA_BEGIN
   #include <rtems/config.h>
 #endif
@@ -32,7 +27,6 @@
  *  These are provided by the linkcmds for ALL of the BSPs which use this file.
  */
 extern char WorkAreaBase[];
-extern char HeapSize[];
 
 /*
  *  We may get the size information from U-Boot or the linker scripts.
@@ -44,17 +38,7 @@ extern char HeapSize[];
   extern char RamSize[];
 #endif
 
-/*
- *  This method returns the base address and size of the area which
- *  is to be allocated between the RTEMS Workspace and the C Program
- *  Heap.
- */
-void bsp_get_work_area(
-  void      **work_area_start,
-  uintptr_t  *work_area_size,
-  void      **heap_start,
-  uintptr_t  *heap_size
-)
+void bsp_work_area_initialize(void)
 {
   uintptr_t work_base = (uintptr_t) WorkAreaBase;
   uintptr_t ram_end;
@@ -70,35 +54,5 @@ void bsp_get_work_area(
     work_base += Configuration.interrupt_stack_size;
   #endif
 
-  *work_area_start = (void *) work_base;
-  *work_area_size  = ram_end - work_base;
-  *heap_start      = BSP_BOOTCARD_HEAP_USES_WORK_AREA;
-  *heap_size       = (uintptr_t) HeapSize;
-
-  /*
-   *  The following may be helpful in debugging what goes wrong when
-   *  you are allocating the Work Area in a new BSP.
-   */
-  #ifdef BSP_GET_WORK_AREA_DEBUG
-    {
-      void *sp = __builtin_frame_address(0);
-      void *end = *work_area_start + *work_area_size;
-      printk(
-        "work_area_start = 0x%p\n"
-        "work_area_size = %d 0x%08x\n"
-        "end = 0x%p\n"
-        "heap_start = 0x%p\n"
-        "heap_size = %d\n"
-        "current stack pointer = 0x%p%s\n",
-        *work_area_start,
-        *work_area_size,  /* decimal */
-        *work_area_size,  /* hexadecimal */
-        end,
-        *heap_start,
-        *heap_size,
-        sp,
-        ((sp >= *work_area_start && sp <= end) ? " OVERLAPS!" : "")
-     );
-  }
- #endif
+  bsp_work_area_initialize_default( (void *) work_base, ram_end - work_base );
 }
diff --git a/c/src/lib/libbsp/shared/bsplibc.c b/c/src/lib/libbsp/shared/bsplibc.c
index 90ba613..181dcff 100644
--- a/c/src/lib/libbsp/shared/bsplibc.c
+++ b/c/src/lib/libbsp/shared/bsplibc.c
@@ -9,14 +9,8 @@
 
 #include <bsp/bootcard.h>
 
-void bsp_libc_init(
-  void *heap_begin,
-  uintptr_t heap_size,
-  size_t sbrk_amount
-)
+void bsp_libc_init(void)
 {
-    RTEMS_Malloc_Initialize( heap_begin, heap_size, sbrk_amount );
-
     /*
      *  Init the RTEMS libio facility to provide UNIX-like system
      *  calls for use by newlib (ie: provide open, close, etc)
diff --git a/c/src/lib/libbsp/shared/include/bootcard.h b/c/src/lib/libbsp/shared/include/bootcard.h
index 69717b2..751e77a 100644
--- a/c/src/lib/libbsp/shared/include/bootcard.h
+++ b/c/src/lib/libbsp/shared/include/bootcard.h
@@ -7,12 +7,13 @@
  */
 
 /*
- * Copyright (c) 2008
- * Embedded Brains GmbH
- * Obere Lagerstr. 30
- * D-82178 Puchheim
- * Germany
- * rtems at embedded-brains.de
+ * Copyright (c) 2008-2012 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Obere Lagerstr. 30
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems at embedded-brains.de>
  *
  * The license and distribution terms for this file may be
  * found in the file LICENSE in this distribution or at
@@ -25,22 +26,13 @@
  * @brief Board support package dependent code.
  */
 
-/**
- * @defgroup bsp_bootcard Bootcard
- *
- * @ingroup bsp_kit
- *
- * @brief Standard system startup.
- *
- * @{
- */
-
 #ifndef LIBBSP_SHARED_BOOTCARD_H
 #define LIBBSP_SHARED_BOOTCARD_H
 
-#include <stddef.h>
-#include <stdint.h>
-#include <sys/types.h>
+#include <unistd.h>
+
+#include <rtems/malloc.h>
+#include <rtems/bspIo.h>
 
 #include <bspopts.h>
 
@@ -49,6 +41,16 @@ extern "C" {
 #endif /* __cplusplus */
 
 /**
+ * @defgroup bsp_bootcard Bootcard
+ *
+ * @ingroup bsp_kit
+ *
+ * @brief Standard system startup.
+ *
+ * @{
+ */
+
+/**
  * @brief Global pointer to the command line of boot_card().
  */
 extern const char *bsp_boot_cmdline;
@@ -66,45 +68,6 @@ void bsp_cleanup(uint32_t status);
 void bsp_reset(void);
 
 /**
- * @brief Should be used as the heap begin address in bsp_get_work_area() if
- * the heap area is contained in the work area.
- */
-#define BSP_BOOTCARD_HEAP_USES_WORK_AREA NULL
-
-/**
- * @brief Should be used to request the default heap size in bsp_get_work_area().
- *
- * In case that the heap area is contained in the work area this heap size
- * value indicates that the area outside the work space should be used as heap
- * space.
- */
-#define BSP_BOOTCARD_HEAP_SIZE_DEFAULT 0
-
-void bsp_get_work_area(
-  void      **work_area_begin,
-  uintptr_t  *work_area_size,
-  void      **heap_begin,
-  uintptr_t  *heap_size
-);
-
-/**
- * @brief Gives the BSP a chance to reduce the work area size with sbrk() adding more later.
- *
- * bsp_sbrk_init() may reduce the work area size passed in. The routine
- * returns the 'sbrk_amount' to be used when extending the heap.
- * Note that the return value may be zero.
- *
- */
-
-#ifdef CONFIGURE_MALLOC_BSP_SUPPORTS_SBRK
-uintptr_t bsp_sbrk_init(
-  void              *work_area_begin,
-  uintptr_t         *work_area_size_p
-);
-#endif
-
-
-/**
  * @brief Standard system initialization procedure.
  *
  * You may pass a command line in @a cmdline.  It is later available via the
@@ -120,11 +83,10 @@ uintptr_t bsp_sbrk_init(
  * - disable interrupts, interrupts will be enabled during the first context
  *   switch
  * - bsp_start() - more advanced initialization
- * - obtain information on BSP memory via bsp_get_work_area() and allocate
- *   RTEMS Workspace
+ * - bsp_work_area_initialize() - initialize the RTEMS Workspace and the C
+ *   Program Heap
  * - rtems_initialize_data_structures()
- * - allocate memory for C Program Heap
- * - initialize C Library and C Program Heap
+ * - initialize C Library
  * - bsp_pretasking_hook()
  * - if defined( RTEMS_DEBUG )
  *   - rtems_debug_enable( RTEMS_DEBUG_ALL_MASK )
@@ -147,9 +109,94 @@ uintptr_t bsp_sbrk_init(
  */
 uint32_t boot_card(const char *cmdline);
 
-/** @} */
+#ifdef CONFIGURE_MALLOC_BSP_SUPPORTS_SBRK
+  /**
+   * @brief Gives the BSP a chance to reduce the work area size with sbrk()
+   * adding more later.
+   *
+   * bsp_sbrk_init() may reduce the work area size passed in. The routine
+   * returns the 'sbrk_amount' to be used when extending the heap.  Note that
+   * the return value may be zero.
+   *
+   * In case the @a area size is altered, then the remaining size of the
+   * @a area must be greater than or equal to @a min_size.
+   */
+  ptrdiff_t bsp_sbrk_init(Heap_Area *area, uintptr_t min_size);
+#endif
+
+static inline void bsp_work_area_initialize_default(
+  void *area_begin,
+  uintptr_t area_size
+)
+{
+  Heap_Area area = {
+    .begin = area_begin,
+    .size = area_size
+  };
+
+  #if BSP_DIRTY_MEMORY == 1
+    memset(area.begin, 0xCF,  area.size);
+  #endif
+
+  #ifdef CONFIGURE_MALLOC_BSP_SUPPORTS_SBRK
+    {
+      uintptr_t overhead = _Heap_Area_overhead(CPU_HEAP_ALIGNMENT);
+      uintptr_t work_space_size = rtems_configuration_get_work_space_size();
+      ptrdiff_t sbrk_amount = bsp_sbrk_init(
+        &area,
+        work_space_size
+          + overhead
+          + (rtems_configuration_get_unified_work_area() ? 0 : overhead)
+      );
+
+      rtems_heap_set_sbrk_amount(sbrk_amount);
+    }
+  #endif
+
+  /*
+   *  The following may be helpful in debugging what goes wrong when
+   *  you are allocating the Work Area in a new BSP.
+   */
+  #ifdef BSP_GET_WORK_AREA_DEBUG
+    {
+      void *sp = __builtin_frame_address(0);
+      void *end = (char *) area.begin + area.size;
+      printk(
+        "work_area_start = 0x%p\n"
+        "work_area_size = %lu 0x%08lx\n"
+        "end = 0x%p\n"
+        "current stack pointer = 0x%p%s\n",
+        area.begin,
+        (unsigned long) area.size,  /* decimal */
+        (unsigned long) area.size,  /* hexadecimal */
+        end,
+        sp,
+        (uintptr_t) sp >= (uintptr_t) area.begin
+          && (uintptr_t) sp <= (uintptr_t) end ?
+            " OVERLAPS!" : ""
+      );
+    }
+  #endif
+
+  _Workspace_Handler_initialization(&area, 1, NULL);
 
-void bsp_libc_init(void *heap_begin, uintptr_t heap_size, size_t sbrk_amount);
+  #ifdef BSP_GET_WORK_AREA_DEBUG
+    printk(
+      "heap_start = 0x%p\n"
+      "heap_size = %lu\n",
+      area.begin,
+      (unsigned long) area.size
+    );
+  #endif
+
+  RTEMS_Malloc_Initialize(&area, 1, NULL);
+}
+
+void bsp_work_area_initialize(void);
+
+void bsp_libc_init(void);
+
+/** @} */
 
 #ifdef __cplusplus
 }
diff --git a/c/src/lib/libbsp/sparc/erc32/include/bsp.h b/c/src/lib/libbsp/sparc/erc32/include/bsp.h
index 879e714..26d4d2f 100644
--- a/c/src/lib/libbsp/sparc/erc32/include/bsp.h
+++ b/c/src/lib/libbsp/sparc/erc32/include/bsp.h
@@ -81,8 +81,8 @@ void bsp_spurious_initialize( void );
 
 /* Allocate 8-byte aligned non-freeable pre-malloc() memory. The function
  * can be called at any time. The work-area will shrink when called before
- * bsp_get_work_area(). malloc() is called to get memory when this function
- * is called after bsp_get_work_area().
+ * bsp_work_area_initialize(). malloc() is called to get memory when this function
+ * is called after bsp_work_area_initialize().
  */
 void *bsp_early_malloc(int size);
 
diff --git a/c/src/lib/libbsp/sparc/leon2/include/bsp.h b/c/src/lib/libbsp/sparc/leon2/include/bsp.h
index e96a63e..dbefc34 100644
--- a/c/src/lib/libbsp/sparc/leon2/include/bsp.h
+++ b/c/src/lib/libbsp/sparc/leon2/include/bsp.h
@@ -101,8 +101,8 @@ void bsp_spurious_initialize( void );
 
 /* Allocate 8-byte aligned non-freeable pre-malloc() memory. The function
  * can be called at any time. The work-area will shrink when called before
- * bsp_get_work_area(). malloc() is called to get memory when this function
- * is called after bsp_get_work_area().
+ * bsp_work_area_initialize(). malloc() is called to get memory when this function
+ * is called after bsp_work_area_initialize().
  */
 void *bsp_early_malloc(int size);
 
diff --git a/c/src/lib/libbsp/sparc/leon3/include/bsp.h b/c/src/lib/libbsp/sparc/leon3/include/bsp.h
index d883064..31e527e 100644
--- a/c/src/lib/libbsp/sparc/leon3/include/bsp.h
+++ b/c/src/lib/libbsp/sparc/leon3/include/bsp.h
@@ -114,8 +114,8 @@ void bsp_spurious_initialize( void );
 
 /* Allocate 8-byte aligned non-freeable pre-malloc() memory. The function
  * can be called at any time. The work-area will shrink when called before
- * bsp_get_work_area(). malloc() is called to get memory when this function
- * is called after bsp_get_work_area().
+ * bsp_work_area_initialize(). malloc() is called to get memory when this function
+ * is called after bsp_work_area_initialize().
  */
 void *bsp_early_malloc(int size);
 
diff --git a/c/src/lib/libbsp/sparc/shared/bspgetworkarea.c b/c/src/lib/libbsp/sparc/shared/bspgetworkarea.c
index 45d3d0e..d799800 100644
--- a/c/src/lib/libbsp/sparc/shared/bspgetworkarea.c
+++ b/c/src/lib/libbsp/sparc/shared/bspgetworkarea.c
@@ -28,24 +28,17 @@ unsigned int early_mem = (unsigned int)&end;
  *  is to be allocated between the RTEMS Workspace and the C Program
  *  Heap.
  */
-void bsp_get_work_area(
-  void      **work_area_start,
-  uintptr_t  *work_area_size,
-  void      **heap_start,
-  uintptr_t  *heap_size
-)
+void bsp_work_area_initialize(void)
 {
   /* must be identical to STACK_SIZE in start.S */
   #define STACK_SIZE (16 * 1024)
 
   /* Early dynamic memory allocator is placed just above _end  */
-  *work_area_start = (void *)early_mem;
-  *work_area_size  = (void *)rdb_start - (void *)early_mem - STACK_SIZE;
+  void *work_area_start = (void *)early_mem;
+  uintptr_t work_area_size  =
+    (uintptr_t)rdb_start - (uintptr_t)early_mem - STACK_SIZE;
   early_mem        = ~0; /* Signal bsp_early_malloc not to be used anymore */
 
-  *heap_start      = BSP_BOOTCARD_HEAP_USES_WORK_AREA;
-  *heap_size       = BSP_BOOTCARD_HEAP_SIZE_DEFAULT;
-
   /*
    *  The following may be helpful in debugging what goes wrong when
    *  you are allocating the Work Area in a new BSP.
@@ -58,19 +51,17 @@ void bsp_get_work_area(
         "work_area_start = 0x%p\n"
         "work_area_size = %d 0x%08x\n"
         "end = 0x%p\n"
-        "heap_start = 0x%p\n"
-        "heap_size = %d\n"
         "current stack pointer = 0x%p%s\n",
-        *work_area_start,
-        *work_area_size,  /* decimal */
-        *work_area_size,  /* hexadecimal */
+        work_area_start,
+        work_area_size,  /* decimal */
+        work_area_size,  /* hexadecimal */
         end,
-        *heap_start,
-        *heap_size,
         sp,
         ((sp >= *work_area_start && sp <= end) ? " OVERLAPS!" : "")
      );
      printk( "rdb_start = 0x%08x\n", rdb_start );
    }
  #endif
+
+  bsp_work_area_initialize_default(work_area_start, work_area_size);
 }
diff --git a/c/src/lib/libbsp/sparc/shared/startup/early_malloc.c b/c/src/lib/libbsp/sparc/shared/startup/early_malloc.c
index 1f968da..dc89fad 100644
--- a/c/src/lib/libbsp/sparc/shared/startup/early_malloc.c
+++ b/c/src/lib/libbsp/sparc/shared/startup/early_malloc.c
@@ -25,8 +25,8 @@ extern unsigned int early_mem;
 
 /* Allocate 8-byte aligned non-freeable pre-malloc() memory. The function
  * can be called at any time. The work-area will shrink when called before
- * bsp_get_work_area(). malloc() is called to get memory when this function
- * is called after bsp_get_work_area().
+ * bsp_work_area_initialize(). malloc() is called to get memory when this function
+ * is called after bsp_work_area_initialize().
  */
 void *bsp_early_malloc(int size)
 {
diff --git a/c/src/lib/libbsp/sparc64/niagara/Makefile.am b/c/src/lib/libbsp/sparc64/niagara/Makefile.am
index 089649d..c251bee 100644
--- a/c/src/lib/libbsp/sparc64/niagara/Makefile.am
+++ b/c/src/lib/libbsp/sparc64/niagara/Makefile.am
@@ -42,7 +42,7 @@ startup_SOURCES = ../../shared/bspclean.c ../../shared/bsplibc.c \
     ../../shared/bsppredriverhook.c ../../shared/bsppretaskinghook.c \
     ../../shared/bsppost.c \
     ../../shared/bootcard.c ../../shared/sbrk.c \
-    ../shared/startup/bspgetworkarea.c \
+    ../../shared/bspgetworkarea.c \
     ../shared/startup/bspstart.c \
     ../shared/startup/setvec.c \
     ../../shared/gnatinstallhandler.c  \
diff --git a/c/src/lib/libbsp/sparc64/shared/startup/bspgetworkarea.c b/c/src/lib/libbsp/sparc64/shared/startup/bspgetworkarea.c
deleted file mode 100644
index 84f5777..0000000
--- a/c/src/lib/libbsp/sparc64/shared/startup/bspgetworkarea.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- *  This routine is an implementation of the bsp_get_work_area()
- *  that can be used by all BSPs following linkcmds conventions
- *  regarding heap, stack, and workspace allocation.
- *
- *  COPYRIGHT (c) 1989-2008.
- *  On-Line Applications Research Corporation (OAR).
- *
- *  The license and distribution terms for this file may be
- *  found in the file LICENSE in this distribution or at
- *  http://www.rtems.com/license/LICENSE.
- */
-
-#include <bsp.h>
-#include <bsp/bootcard.h>
-#ifdef BSP_GET_WORK_AREA_DEBUG
-  #include <rtems/bspIo.h>
-#endif
-
-/*
- *  These are provided by the linkcmds for ALL of the BSPs which use this file.
- */
-extern char WorkAreaBase[];
-extern char HeapSize[];
-extern char HeapBase[];
-
-
-/*
- *  We may get the size information from U-Boot or the linker scripts.
- */
-#ifdef HAS_UBOOT
-  extern bd_t bsp_uboot_board_info;
-#else
-  extern char RamBase[];
-  extern char RamSize[];
-#endif /* HAS_UBOOT */
-
-/*
- *  This method returns the base address and size of the area which
- *  is to be allocated between the RTEMS Workspace and the C Program
- *  Heap.
- */
-void bsp_get_work_area(
-  void      **work_area_start,
-  uintptr_t  *work_area_size,
-  void      **heap_start,
-  uintptr_t  *heap_size
-)
-{
-  uintptr_t ram_end;
-
-  #ifdef HAS_UBOOT
-    ram_end = (uintptr_t) bsp_uboot_board_info.bi_memstart +
-                          bsp_uboot_board_info.bi_memsize;
-  #else
-    ram_end = (uintptr_t)RamBase + (uintptr_t)RamSize;
-  #endif
-
-  *work_area_start = WorkAreaBase;
-  *work_area_size  = (uintptr_t) HeapSize;
-  *heap_start      = (void*) HeapBase;
-  *heap_size       = (uintptr_t) HeapSize;
-
-  /*
-   *  The following may be helpful in debugging what goes wrong when
-   *  you are allocating the Work Area in a new BSP.
-   */
-  #ifdef BSP_GET_WORK_AREA_DEBUG
-    {
-      void *sp = __builtin_frame_address(0);
-      void *end = *work_area_start + *work_area_size;
-      printk(
-		"bsp_get_work_area\n\r"
-        "work_area_start = 0x%p\n\r"
-        "work_area_size = %d 0x%08x\n\r"
-        "end = 0x%p\n\r"
-        "heap_start = 0x%p\n\r"
-        "heap_size = %d\n\r"
-        "current stack pointer = 0x%p%s\n\r",
-        *work_area_start,
-        *work_area_size,  /* decimal */
-        *work_area_size,  /* hexadecimal */
-        end,
-        *heap_start,
-        *heap_size,
-        sp,
-        ((sp >= *work_area_start && sp <= end) ? " OVERLAPS!" : "")
-     );
-  }
- #endif
-}
diff --git a/c/src/lib/libbsp/sparc64/usiii/Makefile.am b/c/src/lib/libbsp/sparc64/usiii/Makefile.am
index 6c169e0..10c0b35 100644
--- a/c/src/lib/libbsp/sparc64/usiii/Makefile.am
+++ b/c/src/lib/libbsp/sparc64/usiii/Makefile.am
@@ -88,7 +88,7 @@ startup_SOURCES = ../../shared/bspclean.c ../../shared/bsplibc.c \
     ../../shared/bspstart.c ../../shared/bsppretaskinghook.c \
     ../../shared/bsppost.c \
     ../../shared/bootcard.c ../../shared/sbrk.c \
-    ../shared/startup/bspgetworkarea.c \
+    ../../shared/bspgetworkarea.c \
     ../shared/startup/bsppredriverhook.c \
     ../shared/startup/setvec.c \
     ../../shared/gnatinstallhandler.c  \
diff --git a/cpukit/libcsupport/Makefile.am b/cpukit/libcsupport/Makefile.am
index 04d2455..703ef60 100644
--- a/cpukit/libcsupport/Makefile.am
+++ b/cpukit/libcsupport/Makefile.am
@@ -98,8 +98,10 @@ MALLOC_C_FILES = src/malloc_initialize.c src/calloc.c src/malloc.c \
     src/mallocinfo.c src/malloc_walk.c src/malloc_get_statistics.c \
     src/malloc_report_statistics.c src/malloc_report_statistics_plugin.c \
     src/malloc_statistics_helpers.c src/posix_memalign.c \
-    src/rtems_memalign.c src/malloc_deferred.c src/malloc_sbrk_helpers.c \
+    src/rtems_memalign.c src/malloc_deferred.c \
     src/malloc_dirtier.c src/malloc_p.h src/rtems_malloc.c \
+    src/rtems_heap_extend_via_sbrk.c \
+    src/rtems_heap_null_extend.c \
     src/rtems_heap_extend.c \
     src/rtems_heap_greedy.c
 
diff --git a/cpukit/libcsupport/include/rtems/libcsupport.h b/cpukit/libcsupport/include/rtems/libcsupport.h
index d264047..919b41e 100644
--- a/cpukit/libcsupport/include/rtems/libcsupport.h
+++ b/cpukit/libcsupport/include/rtems/libcsupport.h
@@ -27,12 +27,6 @@
 extern "C" {
 #endif
 
-void RTEMS_Malloc_Initialize(
-  void *heap_begin,
-  uintptr_t heap_size,
-  size_t sbrk_amount
-);
-
 extern void malloc_dump(void);
 extern bool malloc_walk(int source, bool printf_enabled);
 void malloc_set_heap_pointer(Heap_Control *new_heap);
diff --git a/cpukit/libcsupport/include/rtems/malloc.h b/cpukit/libcsupport/include/rtems/malloc.h
index d195b9f..9d475d3 100644
--- a/cpukit/libcsupport/include/rtems/malloc.h
+++ b/cpukit/libcsupport/include/rtems/malloc.h
@@ -26,6 +26,20 @@
 extern "C" {
 #endif
 
+/**
+ *  @brief C program heap control.
+ *
+ *  This is the pointer to the heap control structure used to manage the C
+ *  program heap.
+ */
+extern Heap_Control *RTEMS_Malloc_Heap;
+
+void RTEMS_Malloc_Initialize(
+  const Heap_Area *areas,
+  size_t area_count,
+  Heap_Initialization_or_extend_handler extend
+);
+
 /*
  *  Malloc Statistics Structure
  */
@@ -54,16 +68,29 @@ extern rtems_malloc_statistics_functions_t
   rtems_malloc_statistics_helpers_table;
 extern rtems_malloc_statistics_functions_t *rtems_malloc_statistics_helpers;
 
-/*
- *  Malloc Heap Extension (sbrk) plugin
- */
-typedef struct {
-  void *(*initialize)(void *, size_t);
-  void *(*extend)(size_t);
-} rtems_malloc_sbrk_functions_t;
+extern ptrdiff_t RTEMS_Malloc_Sbrk_amount;
+
+static inline void rtems_heap_set_sbrk_amount( ptrdiff_t sbrk_amount )
+{
+  RTEMS_Malloc_Sbrk_amount = sbrk_amount;
+}
+
+typedef void *(*rtems_heap_extend_handler)(
+  Heap_Control *heap,
+  size_t alloc_size
+);
+
+void *rtems_heap_extend_via_sbrk(
+  Heap_Control *heap,
+  size_t alloc_size
+);
+
+void *rtems_heap_null_extend(
+  Heap_Control *heap,
+  size_t alloc_size
+);
 
-extern rtems_malloc_sbrk_functions_t rtems_malloc_sbrk_helpers_table;
-extern rtems_malloc_sbrk_functions_t *rtems_malloc_sbrk_helpers;
+extern const rtems_heap_extend_handler rtems_malloc_extend_handler;
 
 /*
  * Malloc Plugin to Dirty Memory at Allocation Time
diff --git a/cpukit/libcsupport/src/malloc.c b/cpukit/libcsupport/src/malloc.c
index 0fff1d0..dea6f8f 100644
--- a/cpukit/libcsupport/src/malloc.c
+++ b/cpukit/libcsupport/src/malloc.c
@@ -55,8 +55,7 @@ void *malloc(
   return_this = _Protected_heap_Allocate( RTEMS_Malloc_Heap, size );
 
   if ( !return_this ) {
-    if (rtems_malloc_sbrk_helpers)
-      return_this = (*rtems_malloc_sbrk_helpers->extend)( size );
+    return_this = (*rtems_malloc_extend_handler)( RTEMS_Malloc_Heap, size );
     if ( !return_this ) {
       errno = ENOMEM;
       return (void *) 0;
diff --git a/cpukit/libcsupport/src/malloc_initialize.c b/cpukit/libcsupport/src/malloc_initialize.c
index fccddd1..06263bd 100644
--- a/cpukit/libcsupport/src/malloc_initialize.c
+++ b/cpukit/libcsupport/src/malloc_initialize.c
@@ -1,11 +1,11 @@
 /**
  * @file
  *
- * @brief Malloc initialization implementation.
+ * @brief RTEMS_Malloc_Initialize() implementation.
  */
 
 /*
- *  COPYRIGHT (c) 1989-2007.
+ *  COPYRIGHT (c) 1989-2012.
  *  On-Line Applications Research Corporation (OAR).
  *
  *  The license and distribution terms for this file may be
@@ -14,93 +14,68 @@
  */
 
 #if HAVE_CONFIG_H
-#include "config.h"
+  #include "config.h"
 #endif
 
-#include <rtems.h>
 #include <rtems/malloc.h>
-#include <rtems/score/wkspace.h>
+
 #include "malloc_p.h"
 
-/* FIXME: Dummy function */
-#ifndef RTEMS_NEWLIB
-void RTEMS_Malloc_Initialize(
-  void *heap_begin,
-  uintptr_t heap_size,
-  size_t sbrk_amount
-)
-{
-}
-#else
+#ifdef RTEMS_NEWLIB
 rtems_malloc_statistics_t rtems_malloc_statistics;
 
 void RTEMS_Malloc_Initialize(
-  void *heap_begin,
-  uintptr_t heap_size,
-  size_t sbrk_amount
+  const Heap_Area *areas,
+  size_t area_count,
+  Heap_Initialization_or_extend_handler extend
 )
 {
-  bool separate_areas = !rtems_configuration_get_unified_work_area();
-  /*
-   *  If configured, initialize the statistics support
-   */
-  if ( rtems_malloc_statistics_helpers != NULL ) {
-    (*rtems_malloc_statistics_helpers->initialize)();
-  }
+  Heap_Control *heap = RTEMS_Malloc_Heap;
 
-  /*
-   *  Initialize the optional sbrk support for extending the heap
-   */
-  if ( rtems_malloc_sbrk_helpers != NULL ) {
-    void *new_heap_begin = (*rtems_malloc_sbrk_helpers->initialize)(
-      heap_begin,
-      sbrk_amount
-    );
-
-    heap_size -= (uintptr_t) new_heap_begin - (uintptr_t) heap_begin;
-    heap_begin = new_heap_begin;
-  }
+  if ( !rtems_configuration_get_unified_work_area() ) {
+    Heap_Initialization_or_extend_handler init_or_extend = _Heap_Initialize;
+    uintptr_t page_size = CPU_HEAP_ALIGNMENT;
+    size_t i;
 
-  /*
-   *  If this system is configured to use the same heap for
-   *  the RTEMS Workspace and C Program Heap, then we need to
-   *  be very very careful about destroying the initialization
-   *  that has already been done.
-   */
+    for (i = 0; i < area_count; ++i) {
+      const Heap_Area *area = &areas [i];
+      uintptr_t space_available = (*init_or_extend)(
+        heap,
+        area->begin,
+        area->size,
+        page_size
+      );
 
-  /*
-   *  If the BSP is not clearing out the workspace, then it is most likely
-   *  not clearing out the initial memory for the heap.  There is no
-   *  standard supporting zeroing out the heap memory.  But much code
-   *  with UNIX history seems to assume that memory malloc'ed during
-   *  initialization (before any free's) is zero'ed.  This is true most
-   *  of the time under UNIX because zero'ing memory when it is first
-   *  given to a process eliminates the chance of a process seeing data
-   *  left over from another process.  This would be a security violation.
-   */
+      if ( space_available > 0 ) {
+        init_or_extend = extend;
+      }
+    }
 
-  if ( separate_areas && rtems_configuration_get_do_zero_of_workspace() ) {
-     memset( heap_begin, 0, heap_size );
+    if ( init_or_extend == _Heap_Initialize ) {
+      _Internal_error_Occurred(
+        INTERNAL_ERROR_CORE,
+        true,
+        INTERNAL_ERROR_NO_MEMORY_FOR_HEAP
+      );
+    }
   }
 
   /*
-   *  Unfortunately we cannot use assert if this fails because if this
-   *  has failed we do not have a heap and if we do not have a heap
-   *  STDIO cannot work because there will be no buffers.
+   *  If configured, initialize the statistics support
    */
-
-  if ( separate_areas ) {
-    uintptr_t status = _Protected_heap_Initialize(
-      RTEMS_Malloc_Heap,
-      heap_begin,
-      heap_size,
-      CPU_HEAP_ALIGNMENT
-    );
-    if ( status == 0 ) {
-      rtems_fatal_error_occurred( RTEMS_NO_MEMORY );
-    }
+  if ( rtems_malloc_statistics_helpers != NULL ) {
+    (*rtems_malloc_statistics_helpers->initialize)();
   }
 
-  MSBUMP( space_available, _Protected_heap_Get_size(RTEMS_Malloc_Heap) );
+  MSBUMP( space_available, _Protected_heap_Get_size( heap ) );
+}
+#else
+void RTEMS_Malloc_Initialize(
+  Heap_Area *areas,
+  size_t area_count,
+  Heap_Initialization_or_extend_handler extend
+)
+{
+  /* FIXME: Dummy function */
 }
 #endif
diff --git a/cpukit/libcsupport/src/malloc_p.h b/cpukit/libcsupport/src/malloc_p.h
index ea0709f..6bd9a49 100644
--- a/cpukit/libcsupport/src/malloc_p.h
+++ b/cpukit/libcsupport/src/malloc_p.h
@@ -23,11 +23,6 @@
 #include <rtems/chain.h>
 
 /*
- * Basic management data
- */
-extern Heap_Control  *RTEMS_Malloc_Heap;
-
-/*
  *  Malloc Statistics Structure
  */
 extern rtems_malloc_statistics_t rtems_malloc_statistics;
diff --git a/cpukit/libcsupport/src/malloc_sbrk_helpers.c b/cpukit/libcsupport/src/malloc_sbrk_helpers.c
deleted file mode 100644
index 64572a1..0000000
--- a/cpukit/libcsupport/src/malloc_sbrk_helpers.c
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- *  RTEMS Malloc -- SBRK Support Plugin
- *
- *  COPYRIGHT (c) 1989-2007.
- *  On-Line Applications Research Corporation (OAR).
- *
- *  The license and distribution terms for this file may be
- *  found in the file LICENSE in this distribution or at
- *  http://www.rtems.com/license/LICENSE.
- */
-
-#if HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <unistd.h> /* sbrk */
-
-#include <rtems.h>
-#include <rtems/malloc.h>
-#include "malloc_p.h"
-
-#include <errno.h>
-
-size_t  RTEMS_Malloc_Sbrk_amount;
-
-static void *malloc_sbrk_initialize(
-  void  *starting_address,
-  size_t length
-)
-{
-  uintptr_t     old_address;
-  uintptr_t     uaddress;
-
-  RTEMS_Malloc_Sbrk_amount = length;
-
-  /*
-   * If the starting address is 0 then we are to attempt to
-   * get length worth of memory using sbrk. Make sure we
-   * align the address that we get back.
-   */
-
-  if (!starting_address) {
-    uaddress = (uintptr_t)sbrk(length);
-
-    if (uaddress == (uintptr_t) -1) {
-      rtems_fatal_error_occurred( RTEMS_NO_MEMORY );
-      /* DOES NOT RETURN!!! */
-    }
-
-    if (uaddress & (CPU_HEAP_ALIGNMENT-1)) {
-      old_address = uaddress;
-      uaddress = (uaddress + CPU_HEAP_ALIGNMENT) & ~(CPU_HEAP_ALIGNMENT-1);
-
-      /*
-       * adjust the length by whatever we aligned by
-       */
-      length -= uaddress - old_address;
-    }
-
-    starting_address = (void *)uaddress;
-  }
-  return starting_address;
-}
-
-static void *malloc_sbrk_extend_and_allocate(
-  size_t size
-)
-{
-  uint32_t  sbrk_amount;
-  void     *starting_address;
-  uint32_t  the_size;
-  void     *return_this;
-
-  /*
-   *  Round to the "requested sbrk amount" so hopefully we won't have
-   *  to grow again for a while.  This effectively does sbrk() calls
-   *  in "page" amounts.
-   */
-
-  sbrk_amount = RTEMS_Malloc_Sbrk_amount;
-
-  if ( sbrk_amount == 0 )
-    return (void *) 0;
-
-  the_size = ((size + sbrk_amount) / sbrk_amount * sbrk_amount);
-
-  starting_address = (void *) sbrk(the_size);
-  if ( starting_address == (void*) -1 )
-    return (void *) 0;
-
-  if ( !_Protected_heap_Extend(
-          RTEMS_Malloc_Heap, starting_address, the_size) ) {
-    sbrk(-the_size);
-    errno = ENOMEM;
-    return (void *) 0;
-  }
-
-  MSBUMP(space_available, the_size);
-
-  return_this = _Protected_heap_Allocate( RTEMS_Malloc_Heap, size );
-  return return_this;
-}
-
-
-rtems_malloc_sbrk_functions_t rtems_malloc_sbrk_helpers_table = {
-  malloc_sbrk_initialize,
-  malloc_sbrk_extend_and_allocate
-};
diff --git a/cpukit/libcsupport/src/mallocinfo.c b/cpukit/libcsupport/src/mallocinfo.c
index 47aefc3..1532608 100644
--- a/cpukit/libcsupport/src/mallocinfo.c
+++ b/cpukit/libcsupport/src/mallocinfo.c
@@ -14,13 +14,9 @@
 #include "config.h"
 #endif
 
-#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__
-#include <rtems.h>
-#include <rtems/libcsupport.h>
+#include <rtems/malloc.h>
 #include <rtems/score/protectedheap.h>
 
-extern Heap_Control  *RTEMS_Malloc_Heap;
-
 /*
  *  Find amount of free heap remaining
  */
diff --git a/cpukit/libcsupport/src/rtems_heap_extend_via_sbrk.c b/cpukit/libcsupport/src/rtems_heap_extend_via_sbrk.c
new file mode 100644
index 0000000..831626b
--- /dev/null
+++ b/cpukit/libcsupport/src/rtems_heap_extend_via_sbrk.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2012 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Obere Lagerstr. 30
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems at embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ */
+
+#if HAVE_CONFIG_H
+  #include "config.h"
+#endif
+
+#include <unistd.h>
+
+#include <rtems/malloc.h>
+
+#include "malloc_p.h"
+
+ptrdiff_t RTEMS_Malloc_Sbrk_amount;
+
+void *rtems_heap_extend_via_sbrk(
+  Heap_Control *heap,
+  size_t alloc_size
+)
+{
+  ptrdiff_t sbrk_amount = RTEMS_Malloc_Sbrk_amount;
+  ptrdiff_t sbrk_size = (ptrdiff_t) alloc_size;
+  ptrdiff_t misaligned = sbrk_size % sbrk_amount;
+  void *return_this = NULL;
+
+  if ( misaligned != 0 ) {
+    sbrk_size += sbrk_amount - misaligned;
+  }
+
+  if ( sbrk_size > 0 && sbrk_amount > 0 ) {
+    void *area_begin = sbrk( sbrk_size );
+
+    if ( area_begin != (void *) -1 ) {
+      bool ok = _Protected_heap_Extend( heap, area_begin, sbrk_size );
+
+      if ( ok ) {
+        MSBUMP( space_available, sbrk_size );
+
+        return_this = _Protected_heap_Allocate( heap, alloc_size );
+      } else {
+        sbrk( -sbrk_size );
+      }
+    }
+  }
+
+  return return_this;
+}
diff --git a/cpukit/libcsupport/src/rtems_heap_null_extend.c b/cpukit/libcsupport/src/rtems_heap_null_extend.c
new file mode 100644
index 0000000..a821ef4
--- /dev/null
+++ b/cpukit/libcsupport/src/rtems_heap_null_extend.c
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2012 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Obere Lagerstr. 30
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems at embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ */
+
+#if HAVE_CONFIG_H
+  #include "config.h"
+#endif
+
+#include <rtems/malloc.h>
+
+void *rtems_heap_null_extend(
+  Heap_Control *heap __attribute__((unused)),
+  size_t alloc_size __attribute__((unused))
+)
+{
+  return NULL;
+}
diff --git a/cpukit/libmisc/monitor/mon-config.c b/cpukit/libmisc/monitor/mon-config.c
index 0df87d6..b5bc31c 100644
--- a/cpukit/libmisc/monitor/mon-config.c
+++ b/cpukit/libmisc/monitor/mon-config.c
@@ -33,7 +33,6 @@ rtems_monitor_config_canonical(
     rtems_configuration_table *c = (rtems_configuration_table *) config_void;
     rtems_api_configuration_table *r = &Configuration_RTEMS_API;
 
-    canonical_config->work_space_start = c->work_space_start;
     canonical_config->work_space_size = c->work_space_size;
     canonical_config->maximum_tasks = r->maximum_tasks;
     canonical_config->maximum_timers = r->maximum_timers;
diff --git a/cpukit/sapi/include/confdefs.h b/cpukit/sapi/include/confdefs.h
index d4f21ca..09edc97 100644
--- a/cpukit/sapi/include/confdefs.h
+++ b/cpukit/sapi/include/confdefs.h
@@ -901,11 +901,11 @@ rtems_fs_init_functions_t    rtems_fs_init_helper =
    *  RAM to the malloc family implementation so sbrk()'ing to get
    *  more memory would always fail anyway.
    */
-  rtems_malloc_sbrk_functions_t *rtems_malloc_sbrk_helpers =
-    #ifndef CONFIGURE_MALLOC_BSP_SUPPORTS_SBRK
-      NULL;
+  const rtems_heap_extend_handler rtems_malloc_extend_handler =
+    #ifdef CONFIGURE_MALLOC_BSP_SUPPORTS_SBRK
+      rtems_heap_extend_via_sbrk;
     #else
-      &rtems_malloc_sbrk_helpers_table;
+      rtems_heap_null_extend;
     #endif
 #endif
 
@@ -2318,7 +2318,6 @@ rtems_fs_init_functions_t    rtems_fs_init_helper =
    *  This is the primary Configuration Table for this application.
    */
   rtems_configuration_table Configuration = {
-    NULL,                                     /* filled in by BSP */
     CONFIGURE_EXECUTIVE_RAM_SIZE,             /* required RTEMS workspace */
     CONFIGURE_STACK_SPACE_SIZE,               /* required stack space */
     CONFIGURE_MAXIMUM_USER_EXTENSIONS,        /* maximum dynamic extensions */
diff --git a/cpukit/sapi/include/rtems/config.h b/cpukit/sapi/include/rtems/config.h
index 58b350d..d0e181c 100644
--- a/cpukit/sapi/include/rtems/config.h
+++ b/cpukit/sapi/include/rtems/config.h
@@ -124,10 +124,6 @@ typedef void (*rtems_stack_free_hook)( void *addr );
  *     + required number of each object type for each API configured
  */
 typedef struct {
-  /** This field specifies the base address of the RTEMS Workspace.
-   */
-  void                          *work_space_start;
-
   /** This field specifies the size in bytes of the RTEMS Workspace.
    */
   uintptr_t                      work_space_size;
@@ -266,12 +262,6 @@ extern rtems_configuration_table  Configuration;
 #define rtems_configuration_set_stack_space_size( _size ) \
         do { Configuration.stack_space_size = (_size); } while (0)
 
-#define rtems_configuration_get_work_space_start() \
-        (Configuration.work_space_start)
-
-#define rtems_configuration_set_work_space_start( _start ) \
-        do { Configuration.work_space_start = (_start); } while (0)
-
 #define rtems_configuration_get_work_space_size() \
         (Configuration.work_space_size + \
           (rtems_configuration_get_stack_allocator_avoids_work_space() ? \
diff --git a/cpukit/sapi/src/exinit.c b/cpukit/sapi/src/exinit.c
index 82e853a..1aa7e54 100644
--- a/cpukit/sapi/src/exinit.c
+++ b/cpukit/sapi/src/exinit.c
@@ -111,12 +111,6 @@ void rtems_initialize_data_structures(void)
 
   _Thread_Dispatch_initialization();
 
-  /*
-   *  Before this is called, we are not allowed to allocate memory
-   *  from the Workspace because it is not initialized.
-   */
-  _Workspace_Handler_initialization();
-
   #if defined(RTEMS_SMP)
     _SMP_Handler_initialize();
   #endif
diff --git a/cpukit/score/include/rtems/score/heap.h b/cpukit/score/include/rtems/score/heap.h
index 964386a..36ef48f 100644
--- a/cpukit/score/include/rtems/score/heap.h
+++ b/cpukit/score/include/rtems/score/heap.h
@@ -675,6 +675,36 @@ Heap_Resize_status _Heap_Resize_block(
   uintptr_t *new_size
 );
 
+RTEMS_INLINE_ROUTINE uintptr_t _Heap_Align_up(
+  uintptr_t value,
+  uintptr_t alignment
+)
+{
+  uintptr_t remainder = value % alignment;
+
+  if ( remainder != 0 ) {
+    return value - remainder + alignment;
+  } else {
+    return value;
+  }
+}
+
+/**
+ * @brief Returns the worst case overhead to manage a memory area.
+ */
+RTEMS_INLINE_ROUTINE uintptr_t _Heap_Area_overhead(
+  uintptr_t page_size
+)
+{
+  if ( page_size != 0 ) {
+    page_size = _Heap_Align_up( page_size, CPU_ALIGNMENT );
+  } else {
+    page_size = CPU_ALIGNMENT;
+  }
+
+  return 2 * (page_size - 1) + HEAP_BLOCK_HEADER_SIZE;
+}
+
 #if !defined(__RTEMS_APPLICATION__)
 
 #include <rtems/score/heap.inl>
diff --git a/cpukit/score/include/rtems/score/interr.h b/cpukit/score/include/rtems/score/interr.h
index 19342a3..2a21fe0 100644
--- a/cpukit/score/include/rtems/score/interr.h
+++ b/cpukit/score/include/rtems/score/interr.h
@@ -72,7 +72,8 @@ typedef enum {
   INTERNAL_ERROR_UNLIMITED_AND_MAXIMUM_IS_0,
   INTERNAL_ERROR_SHUTDOWN_WHEN_NOT_UP,
   INTERNAL_ERROR_GXX_KEY_ADD_FAILED,
-  INTERNAL_ERROR_GXX_MUTEX_INIT_FAILED
+  INTERNAL_ERROR_GXX_MUTEX_INIT_FAILED,
+  INTERNAL_ERROR_NO_MEMORY_FOR_HEAP
 } Internal_errors_Core_list;
 
 typedef uint32_t Internal_errors_t;
diff --git a/cpukit/score/include/rtems/score/wkspace.h b/cpukit/score/include/rtems/score/wkspace.h
index 10b80cc..db6eb38 100644
--- a/cpukit/score/include/rtems/score/wkspace.h
+++ b/cpukit/score/include/rtems/score/wkspace.h
@@ -36,19 +36,23 @@ extern "C" {
 #include <rtems/score/interr.h>
 
 /**
- * @brief Executive Workspace Control
+ *  @brief Executive workspace control.
  *
- *  The is the heap control structure that used to manage the
- *  RTEMS Executive Workspace.
+ *  This is the heap control structure used to manage the RTEMS Executive
+ *  Workspace.
  */
-SCORE_EXTERN Heap_Control _Workspace_Area;  /* executive heap header */
+SCORE_EXTERN Heap_Control _Workspace_Area;
 
 /**
  * @brief Workspace Handler Initialization
  *
  *  This routine performs the initialization necessary for this handler.
  */
-void _Workspace_Handler_initialization(void);
+void _Workspace_Handler_initialization(
+  Heap_Area *areas,
+  size_t area_count,
+  Heap_Initialization_or_extend_handler extend
+);
 
 /**
  * @brief Allocate Memory from Workspace
diff --git a/cpukit/score/inline/rtems/score/heap.inl b/cpukit/score/inline/rtems/score/heap.inl
index b955371..59bdd7b 100644
--- a/cpukit/score/inline/rtems/score/heap.inl
+++ b/cpukit/score/inline/rtems/score/heap.inl
@@ -108,20 +108,6 @@ RTEMS_INLINE_ROUTINE bool _Heap_Is_aligned(
   return (value % alignment) == 0;
 }
 
-RTEMS_INLINE_ROUTINE uintptr_t _Heap_Align_up(
-  uintptr_t value,
-  uintptr_t alignment
-)
-{
-  uintptr_t remainder = value % alignment;
-
-  if ( remainder != 0 ) {
-    return value - remainder + alignment;
-  } else {
-    return value;
-  }
-}
-
 RTEMS_INLINE_ROUTINE uintptr_t _Heap_Align_down(
   uintptr_t value,
   uintptr_t alignment
diff --git a/cpukit/score/src/wkspace.c b/cpukit/score/src/wkspace.c
index 842cade..7e58585 100644
--- a/cpukit/score/src/wkspace.c
+++ b/cpukit/score/src/wkspace.c
@@ -28,28 +28,69 @@
 /*
  *  _Workspace_Handler_initialization
  */
-void _Workspace_Handler_initialization(void)
+void _Workspace_Handler_initialization(
+  Heap_Area *areas,
+  size_t area_count,
+  Heap_Initialization_or_extend_handler extend
+)
 {
-  uintptr_t memory_available = 0;
-  void *starting_address = rtems_configuration_get_work_space_start();
-  uintptr_t size = rtems_configuration_get_work_space_size();
+  Heap_Initialization_or_extend_handler init_or_extend = _Heap_Initialize;
+  uintptr_t remaining = rtems_configuration_get_work_space_size();
+  bool do_zero = rtems_configuration_get_do_zero_of_workspace();
+  bool unified = rtems_configuration_get_unified_work_area();
+  uintptr_t page_size = CPU_HEAP_ALIGNMENT;
+  uintptr_t overhead = _Heap_Area_overhead( page_size );
+  size_t i;
+
+  for (i = 0; i < area_count; ++i) {
+    Heap_Area *area = &areas [i];
+
+    if ( do_zero ) {
+      memset( area->begin, 0, area->size );
+    }
+
+    if ( area->size > overhead ) {
+      uintptr_t space_available;
+      uintptr_t size;
+
+      if ( unified ) {
+        size = area->size;
+      } else {
+        if ( remaining > 0 ) {
+          size = remaining < area->size - overhead ?
+            remaining + overhead : area->size;
+        } else {
+          size = 0;
+        }
+      }
+
+      space_available = (*init_or_extend)(
+        &_Workspace_Area,
+        area->begin,
+        size,
+        page_size
+      );
+
+      area->begin = (char *) area->begin + size;
+      area->size -= size;
 
-  if ( rtems_configuration_get_do_zero_of_workspace() )
-    memset( starting_address, 0, size );
+      if ( space_available < remaining ) {
+        remaining -= space_available;
+      } else {
+        remaining = 0;
+      }
 
-  memory_available = _Heap_Initialize(
-    &_Workspace_Area,
-    starting_address,
-    size,
-    CPU_HEAP_ALIGNMENT
-  );
+      init_or_extend = extend;
+    }
+  }
 
-  if ( memory_available == 0 )
+  if ( remaining > 0 ) {
     _Internal_error_Occurred(
       INTERNAL_ERROR_CORE,
       true,
       INTERNAL_ERROR_TOO_LITTLE_WORKSPACE
     );
+  }
 }
 
 /*
diff --git a/testsuites/libtests/malloc04/init.c b/testsuites/libtests/malloc04/init.c
index 72a397f..00355da 100644
--- a/testsuites/libtests/malloc04/init.c
+++ b/testsuites/libtests/malloc04/init.c
@@ -30,14 +30,20 @@
 #include <rtems/confdefs.h>
 /* end of configuration */
 
+#ifndef CONFIGURE_MALLOC_BSP_SUPPORTS_SBRK
+void *rtems_heap_null_extend(
+  Heap_Control *heap,
+  size_t alloc_size
+)
+{
+  return rtems_heap_extend_via_sbrk( heap, alloc_size );
+}
+#endif
+
 char Malloc_Heap[ 128 ] CPU_STRUCTURE_ALIGNMENT;
 int sbrk_count;
-Heap_Control Heap_Holder;
 Heap_Control TempHeap;
 
-/* Heap variables we need to peek and poke at */
-extern size_t  RTEMS_Malloc_Sbrk_amount;
-
 size_t offset;
 
 void * sbrk(ptrdiff_t incr)
@@ -66,7 +72,8 @@ rtems_task Init(
   rtems_task_argument argument
 )
 {
-  Heap_Control *TempHeap;
+  Heap_Control *real_heap;
+  Heap_Area area;
 
   sbrk_count = 0;
   offset     = 0;
@@ -74,21 +81,26 @@ rtems_task Init(
   puts( "\n\n*** TEST MALLOC 04 ***" );
 
   /* Safe information on real heap */
-  TempHeap = malloc_get_heap_pointer();
-  Heap_Holder = *TempHeap;
-  rtems_malloc_sbrk_helpers = &rtems_malloc_sbrk_helpers_table;
+  real_heap = malloc_get_heap_pointer();
+  malloc_set_heap_pointer( &TempHeap );
+
+  rtems_heap_set_sbrk_amount( 64 );
 
   puts( "Initialize heap with some memory" );
   offset     = 64;
   sbrk_count = 0;
-  RTEMS_Malloc_Initialize( Malloc_Heap, 64, 64 );
+  area.begin = &Malloc_Heap [0];
+  area.size = 64;
+  RTEMS_Malloc_Initialize( &area, 1, NULL );
   p1 = malloc(64);
   p2 = malloc(64);
   p3 = malloc(48);
   p4 = malloc(48);
   
   puts( "Initialize heap with some memory - return address out of heap" );
-  RTEMS_Malloc_Initialize( &Malloc_Heap[1], 64, 64 );
+  area.begin = &Malloc_Heap [1];
+  area.size = 64;
+  RTEMS_Malloc_Initialize( &area, 1, NULL );
   offset     = 64;
   sbrk_count = -1;
   p1 = malloc( 127 );
@@ -96,18 +108,21 @@ rtems_task Init(
   rtems_test_assert( errno == ENOMEM );
   
 
-  RTEMS_Malloc_Initialize( Malloc_Heap, 64, 64 );
+  area.begin = &Malloc_Heap [0];
+  area.size = 64;
+  RTEMS_Malloc_Initialize( &area, 1, NULL );
   puts( "Initialize heap with some unaligned memory" );
   offset     = 65;
   sbrk_count = 0;
-  RTEMS_Malloc_Initialize( &Malloc_Heap[1], 64, 64 );
+  area.begin = &Malloc_Heap [1];
+  area.size = 64;
+  RTEMS_Malloc_Initialize( &area, 1, NULL );
   p1 = malloc(64);
   p2 = malloc(64);
   p3 = malloc(48);
 
   /* Restore information on real heap */
-  malloc_set_heap_pointer( TempHeap );
-  rtems_malloc_sbrk_helpers = NULL;
+  malloc_set_heap_pointer( real_heap );
 
   puts( "*** END OF TEST MALLOC 04 ***" );
 
diff --git a/testsuites/psxtests/psxfatal_support/init.c b/testsuites/psxtests/psxfatal_support/init.c
index c58aeaf..e2ab241 100644
--- a/testsuites/psxtests/psxfatal_support/init.c
+++ b/testsuites/psxtests/psxfatal_support/init.c
@@ -87,13 +87,18 @@ char *Errors_Core[] = {
   "INTERNAL_ERROR_BAD_ATTRIBUTES",
   "INTERNAL_ERROR_IMPLEMENTATION_KEY_CREATE_INCONSISTENCY",
   "INTERNAL_ERROR_IMPLEMENTATION_BLOCKING_OPERATION_CANCEL",
-  "INTERNAL_ERROR_MUTEX_OBTAIN_FROM_BAD_STATE"
+  "INTERNAL_ERROR_MUTEX_OBTAIN_FROM_BAD_STATE",
+  "INTERNAL_ERROR_UNLIMITED_AND_MAXIMUM_IS_0",
+  "INTERNAL_ERROR_SHUTDOWN_WHEN_NOT_UP",
+  "INTERNAL_ERROR_GXX_KEY_ADD_FAILED",
+  "INTERNAL_ERROR_GXX_MUTEX_INIT_FAILED",
+  "INTERNAL_ERROR_NO_MEMORY_FOR_HEAP"
 };
 
 void Put_Error( uint32_t source, uint32_t error )
 {
   if ( source == INTERNAL_ERROR_CORE ) {
-    if ( error >  INTERNAL_ERROR_MUTEX_OBTAIN_FROM_BAD_STATE )
+    if ( error >  INTERNAL_ERROR_NO_MEMORY_FOR_HEAP )
       printk("Unknown Internal Core Error (%d)", error);
     else
       printk( Errors_Core[ error ] );
diff --git a/testsuites/sptests/Makefile.am b/testsuites/sptests/Makefile.am
index 479cdf6..a0dc24a 100644
--- a/testsuites/sptests/Makefile.am
+++ b/testsuites/sptests/Makefile.am
@@ -17,7 +17,7 @@ SUBDIRS = \
     sperror01 sperror02 sperror03 \
     spfatal01 spfatal02 spfatal03 spfatal04 spfatal05 spfatal06 spfatal07 \
     spfatal08 spfatal09 spfatal10 spfatal11 spfatal12 spfatal13 spfatal14 \
-    spfatal15 spfatal16 spfatal17 spfatal18 spfatal19 spfatal20 spfatal21 \
+    spfatal15 spfatal16 spfatal17 spfatal18 spfatal19 spfatal20 \
     spfatal22 spfatal23 spfatal24 spfatal25 \
     spfifo01 spfifo02 spfifo03 spfifo04 spfifo05 \
     spintrcritical01 spintrcritical02 spintrcritical03 spintrcritical04 \
diff --git a/testsuites/sptests/configure.ac b/testsuites/sptests/configure.ac
index 33a0755..32063e2 100644
--- a/testsuites/sptests/configure.ac
+++ b/testsuites/sptests/configure.ac
@@ -139,7 +139,6 @@ spfatal17/Makefile
 spfatal18/Makefile
 spfatal19/Makefile
 spfatal20/Makefile
-spfatal21/Makefile
 spfatal22/Makefile
 spfatal23/Makefile
 spfatal24/Makefile
diff --git a/testsuites/sptests/spfatal06/testcase.h b/testsuites/sptests/spfatal06/testcase.h
index 29669d9..27c615d 100644
--- a/testsuites/sptests/spfatal06/testcase.h
+++ b/testsuites/sptests/spfatal06/testcase.h
@@ -38,6 +38,10 @@ rtems_initialization_tasks_table Initialization_tasks[] = {
 
 void *New_stack_allocate_hook(size_t unused);
 
+#define CONFIGURE_TASK_STACK_ALLOCATOR New_stack_allocate_hook
+
+#define CONFIGURE_TASK_STACK_DEALLOCATOR NULL
+
 void *New_stack_allocate_hook(size_t unused)
 {
   return NULL;
@@ -45,12 +49,5 @@ void *New_stack_allocate_hook(size_t unused)
 
 void force_error()
 {
-  if (Configuration.stack_free_hook != NULL)
-    Configuration.stack_allocate_hook = NULL;
-  else
-    Configuration.stack_allocate_hook = New_stack_allocate_hook;
-
-  rtems_initialize_data_structures();
   /* we will not run this far */
 }
-
diff --git a/testsuites/sptests/spfatal07/testcase.h b/testsuites/sptests/spfatal07/testcase.h
index c95fc0d..77ef6e8 100644
--- a/testsuites/sptests/spfatal07/testcase.h
+++ b/testsuites/sptests/spfatal07/testcase.h
@@ -37,11 +37,15 @@ rtems_initialization_tasks_table Initialization_tasks[] = {
 #define FATAL_ERROR_EXPECTED_ERROR       \
           INTERNAL_ERROR_INTERRUPT_STACK_TOO_SMALL
 
+#if CPU_SIMPLE_VECTORED_INTERRUPTS == TRUE
+  #define CONFIGURE_MEMORY_OVERHEAD (sizeof(ISR_Handler_entry) * ISR_NUMBER_OF_VECTORS)
+#endif
+
 void force_error()
 {
   #if (CPU_ALLOCATE_INTERRUPT_STACK == TRUE)
     Configuration.interrupt_stack_size = (STACK_MINIMUM_SIZE-1);
-    rtems_initialize_data_structures();
+    _ISR_Handler_initialization();
   #else
     printk(
       "WARNING - Test not applicable on this target architecture.\n"
diff --git a/testsuites/sptests/spfatal08/testcase.h b/testsuites/sptests/spfatal08/testcase.h
index 50a831f..83615f5 100644
--- a/testsuites/sptests/spfatal08/testcase.h
+++ b/testsuites/sptests/spfatal08/testcase.h
@@ -9,6 +9,8 @@
  *  http://www.rtems.com/license/LICENSE.
  */
 
+#include <rtems/score/wkspace.h>
+
 /*
  *  Way too much stack space.  Should generate a fatal error
  *  on the init task create.
@@ -39,10 +41,16 @@ char Workspace[ 256 ] CPU_STRUCTURE_ALIGNMENT;
 
 void force_error()
 {
-  rtems_configuration_set_work_space_start( Workspace );
-  rtems_configuration_set_work_space_size( sizeof(Workspace) );
+  Heap_Area area = {
+    .begin = Workspace,
+    .size = sizeof( Workspace )
+  };
+
+  rtems_configuration_set_work_space_size( 0 );
   rtems_configuration_set_stack_space_size( 0 );
 
-  rtems_initialize_data_structures();;
+  _Workspace_Handler_initialization( &area, 1, NULL );
+
+  _Workspace_Allocate_or_fatal_error( 2 * sizeof( Workspace ) );
   /* we will not run this far */
 }
diff --git a/testsuites/sptests/spfatal09/testcase.h b/testsuites/sptests/spfatal09/testcase.h
index eb50c30..dc6dfa9 100644
--- a/testsuites/sptests/spfatal09/testcase.h
+++ b/testsuites/sptests/spfatal09/testcase.h
@@ -14,15 +14,12 @@
 
 #define FATAL_ERROR_TEST_NAME            "9"
 #define FATAL_ERROR_DESCRIPTION          "Bad heap address to malloc"
-#define FATAL_ERROR_EXPECTED_SOURCE      INTERNAL_ERROR_RTEMS_API
-#define FATAL_ERROR_EXPECTED_IS_INTERNAL FALSE
-#define FATAL_ERROR_EXPECTED_ERROR       RTEMS_NO_MEMORY
-
-char Malloc_Heap[ 1 ] CPU_STRUCTURE_ALIGNMENT;
+#define FATAL_ERROR_EXPECTED_SOURCE      INTERNAL_ERROR_CORE
+#define FATAL_ERROR_EXPECTED_IS_INTERNAL TRUE
+#define FATAL_ERROR_EXPECTED_ERROR       INTERNAL_ERROR_NO_MEMORY_FOR_HEAP
 
 void force_error()
 {
-  RTEMS_Malloc_Initialize( Malloc_Heap, sizeof(Malloc_Heap), 0 );
-
+  RTEMS_Malloc_Initialize( NULL, 0, NULL );
   /* we will not run this far */
 }
diff --git a/testsuites/sptests/spfatal12/testcase.h b/testsuites/sptests/spfatal12/testcase.h
index feeec46..73cb7a9 100644
--- a/testsuites/sptests/spfatal12/testcase.h
+++ b/testsuites/sptests/spfatal12/testcase.h
@@ -17,9 +17,8 @@
 
 void force_error()
 {
-  rtems_configuration_set_work_space_size( sizeof(void *) );
-  rtems_configuration_set_stack_space_size( 0 );
-  rtems_initialize_data_structures();
+  Heap_Area area = { .begin = NULL, .size = 0 };
 
+  _Workspace_Handler_initialization( &area, 1, NULL );
   /* we will not run this far */
 }
diff --git a/testsuites/sptests/spfatal21/Makefile.am b/testsuites/sptests/spfatal21/Makefile.am
deleted file mode 100644
index 3a2439a..0000000
--- a/testsuites/sptests/spfatal21/Makefile.am
+++ /dev/null
@@ -1,21 +0,0 @@
-rtems_tests_PROGRAMS = spfatal21
-spfatal21_SOURCES = ../spfatal_support/init.c \
-    ../spfatal_support/system.h ../../support/src/test_support.c testcase.h
-
-dist_rtems_tests_DATA = spfatal21.scn
-dist_rtems_tests_DATA += spfatal21.doc
-
-include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP at .cfg
-include $(top_srcdir)/../automake/compile.am
-include $(top_srcdir)/../automake/leaf.am
-
-AM_CPPFLAGS += -I$(top_srcdir)/../support/include
-
-LINK_OBJS = $(spfatal21_OBJECTS)
-LINK_LIBS = $(spfatal21_LDLIBS)
-
-spfatal21$(EXEEXT): $(spfatal21_OBJECTS) $(spfatal21_DEPENDENCIES)
-	@rm -f spfatal21$(EXEEXT)
-	$(make-exe)
-
-include $(top_srcdir)/../automake/local.am
diff --git a/testsuites/sptests/spfatal21/spfatal21.doc b/testsuites/sptests/spfatal21/spfatal21.doc
deleted file mode 100644
index ba1e65c..0000000
--- a/testsuites/sptests/spfatal21/spfatal21.doc
+++ /dev/null
@@ -1,19 +0,0 @@
-#  COPYRIGHT (c) 1989-2010.
-#  On-Line Applications Research Corporation (OAR).
-#
-#  The license and distribution terms for this file may be
-#  found in the file LICENSE in this distribution or at
-#  http://www.rtems.com/license/LICENSE.
-#
-
-This file describes the directives and concepts tested by this test set.
-
-test set name:  spfatal21
-
-directives:
-
-  malloc_sbrk_initialize
-
-concepts:
-
-+ exercise fatal error when sbrk fails to extend memory on the initial call.
diff --git a/testsuites/sptests/spfatal21/spfatal21.scn b/testsuites/sptests/spfatal21/spfatal21.scn
deleted file mode 100644
index 1ea32a5..0000000
--- a/testsuites/sptests/spfatal21/spfatal21.scn
+++ /dev/null
@@ -1,3 +0,0 @@
-*** TEST FATAL FATAL 21 ***
-Fatal error (sbrk during init fails) hit
-*** END OF TEST FATAL 21 ***
diff --git a/testsuites/sptests/spfatal21/testcase.h b/testsuites/sptests/spfatal21/testcase.h
deleted file mode 100644
index 788f06b..0000000
--- a/testsuites/sptests/spfatal21/testcase.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- *  COPYRIGHT (c) 1989-2012.
- *  On-Line Applications Research Corporation (OAR).
- *
- *  The license and distribution terms for this file may be
- *  found in the file LICENSE in this distribution or at
- *  http://www.rtems.com/license/LICENSE.
- */
-
-#define FATAL_ERROR_TEST_NAME            "FATAL 21"
-#define FATAL_ERROR_DESCRIPTION          "sbrk during init fails"
-#define FATAL_ERROR_EXPECTED_SOURCE      INTERNAL_ERROR_RTEMS_API
-#define FATAL_ERROR_EXPECTED_IS_INTERNAL FALSE
-#define FATAL_ERROR_EXPECTED_ERROR       RTEMS_NO_MEMORY
-
-#include <rtems/libcsupport.h>
-#include <rtems/malloc.h>
-#include <unistd.h>
-
-/* Safe information on real heap */
-extern rtems_malloc_sbrk_functions_t *rtems_malloc_sbrk_helpers;
-extern rtems_malloc_sbrk_functions_t  rtems_malloc_sbrk_helpers_table;
-
-void * sbrk(ptrdiff_t incr)
-{
-  return (void *) -1;
-}
-
-void force_error()
-{
-  rtems_malloc_sbrk_helpers = &rtems_malloc_sbrk_helpers_table;
- 
-  RTEMS_Malloc_Initialize( NULL, 0, 64 );
-}
diff --git a/testsuites/sptests/spfatal_support/init.c b/testsuites/sptests/spfatal_support/init.c
index 923c08f..9822b13 100644
--- a/testsuites/sptests/spfatal_support/init.c
+++ b/testsuites/sptests/spfatal_support/init.c
@@ -88,13 +88,18 @@ char *Errors_Core[] = {
   "INTERNAL_ERROR_BAD_ATTRIBUTES",
   "INTERNAL_ERROR_IMPLEMENTATION_KEY_CREATE_INCONSISTENCY",
   "INTERNAL_ERROR_IMPLEMENTATION_BLOCKING_OPERATION_CANCEL",
-  "INTERNAL_ERROR_MUTEX_OBTAIN_FROM_BAD_STATE"
+  "INTERNAL_ERROR_MUTEX_OBTAIN_FROM_BAD_STATE",
+  "INTERNAL_ERROR_UNLIMITED_AND_MAXIMUM_IS_0",
+  "INTERNAL_ERROR_SHUTDOWN_WHEN_NOT_UP",
+  "INTERNAL_ERROR_GXX_KEY_ADD_FAILED",
+  "INTERNAL_ERROR_GXX_MUTEX_INIT_FAILED",
+  "INTERNAL_ERROR_NO_MEMORY_FOR_HEAP"
 };
 
 void Put_Error( uint32_t source, uint32_t error )
 {
   if ( source == INTERNAL_ERROR_CORE ) {
-    if ( error >  INTERNAL_ERROR_MUTEX_OBTAIN_FROM_BAD_STATE )
+    if ( error >  INTERNAL_ERROR_NO_MEMORY_FOR_HEAP )
       printk("Unknown Internal Core Error (%d)", error);
     else
       printk( Errors_Core[ error ] );
-- 
1.7.7




More information about the devel mailing list