Index: c/src/exec/score/src/thread.c
===================================================================
--- c/src/exec/score/src/thread.c	(revision 6365f8189896cb4f86b8d3db0a0e9830926b24c7)
+++ c/src/exec/score/src/thread.c	(revision 8faca06664388ed141b2f7b9b5ddcfb0b4577fe8)
@@ -51,4 +51,17 @@
   unsigned32      index;
 
+  /*
+   * BOTH stacks hooks must be set or both must be NULL.
+   * Do not allow mixture.
+   */
+
+  if ( !( ( _CPU_Table.stack_allocate_hook == 0 )
+       == ( _CPU_Table.stack_free_hook == 0 ) ) )
+    _Internal_error_Occurred(
+      INTERNAL_ERROR_CORE,
+      TRUE,
+      INTERNAL_ERROR_BAD_STACK_HOOK
+    );
+
   _Context_Switch_necessary = FALSE;
   _Thread_Executing         = NULL;
@@ -284,4 +297,63 @@
 /*PAGE
  *
+ *  _Thread_Stack_Allocate
+ *
+ *  Allocate the requested stack space for the thread.
+ *  return the actual size allocated after any adjustment
+ *  or return zero if the allocation failed.
+ *  Set the Start.stack field to the address of the stack
+ */
+
+static unsigned32 _Thread_Stack_Allocate(
+  Thread_Control *the_thread,
+  unsigned32 stack_size)
+{
+  void *stack_addr = 0;
+ 
+  if ( !_Stack_Is_enough( stack_size ) )
+    stack_size = STACK_MINIMUM_SIZE;
+ 
+  /*
+   * Call ONLY the CPU table stack allocate hook, _or_ the
+   * the RTEMS workspace allocate.  This is so the stack free
+   * routine can call the correct deallocation routine.
+   */
+  if ( _CPU_Table.stack_allocate_hook )
+  {
+    stack_addr = (*_CPU_Table.stack_allocate_hook)( stack_size );
+  } else {
+    stack_size = _Stack_Adjust_size( stack_size );
+    stack_addr = _Workspace_Allocate( stack_size );
+  }
+ 
+  if ( !stack_addr )
+      stack_size = 0;
+ 
+  the_thread->Start.stack = stack_addr;
+ 
+  return stack_size;
+}
+
+/*
+ *  _Thread_Stack_Free
+ *
+ *  Deallocate the Thread's stack.
+ */
+
+static void _Thread_Stack_Free(void *stack_addr)
+{
+    /*
+     * Call ONLY the CPU table stack free hook, or the
+     * the RTEMS workspace free.  This is so the free
+     * routine properly matches the allocation of the stack.
+     */
+    if ( _CPU_Table.stack_free_hook )
+        (*_CPU_Table.stack_free_hook)( stack_addr );
+    else
+        _Workspace_Free( stack_addr );
+}
+
+/*PAGE
+ *
  *  _Thread_Initialize
  *
@@ -321,10 +393,10 @@
 
   if ( !stack ) {
-    stack = _Workspace_Allocate( actual_stack_size );
- 
-    if ( !stack ) 
-      return FALSE;
-
-    the_thread->Start.stack = stack;
+    actual_stack_size = _Thread_Stack_Allocate( the_thread, stack_size );
+ 
+    if ( !actual_stack_size ) 
+      return FALSE;                     /* stack allocation failed */
+
+    stack = the_thread->Start.stack;
   } else
     the_thread->Start.stack = NULL;
@@ -345,5 +417,5 @@
     if ( !fp_area ) {
       if ( the_thread->Start.stack )
-        (void) _Workspace_Free( the_thread->Start.stack );
+        (void) _Thread_Stack_Free( the_thread->Start.stack );
       return FALSE;
     }
@@ -358,5 +430,5 @@
 
   /*
-   *  Allocate the floating point area for this thread
+   *  Allocate the extensions area for this thread
    */
 
@@ -371,5 +443,5 @@
 
       if ( the_thread->Start.stack )
-        (void) _Workspace_Free( the_thread->Start.stack );
+        (void) _Thread_Stack_Free( the_thread->Start.stack );
 
       return FALSE;
@@ -414,5 +486,5 @@
 
     if ( the_thread->Start.stack )
-      (void) _Workspace_Free( the_thread->Start.stack );
+      (void) _Thread_Stack_Free( the_thread->Start.stack );
 
     return FALSE;
Index: c/src/exec/score/src/wkspace.c
===================================================================
--- c/src/exec/score/src/wkspace.c	(revision 6365f8189896cb4f86b8d3db0a0e9830926b24c7)
+++ c/src/exec/score/src/wkspace.c	(revision 8faca06664388ed141b2f7b9b5ddcfb0b4577fe8)
@@ -23,4 +23,47 @@
 /*PAGE
  *
+ *  _Workspace_Handler_initialization
+ */
+ 
+void _Workspace_Handler_initialization(
+  void       *starting_address,
+  unsigned32  size
+)
+{
+  unsigned32 *zero_out_array;
+  unsigned32  index;
+  unsigned32  memory_available;
+ 
+  if ( !starting_address || !_Addresses_Is_aligned( starting_address ) )
+    _Internal_error_Occurred(
+      INTERNAL_ERROR_CORE,
+      TRUE,
+      INTERNAL_ERROR_INVALID_WORKSPACE_ADDRESS
+    );
+ 
+  if ( _CPU_Table.do_zero_of_workspace ) {
+    for( zero_out_array  = (unsigned32 *) starting_address, index = 0 ;
+         index < size / 4 ;
+         index++ )
+      zero_out_array[ index ] = 0;
+  }
+ 
+  memory_available = _Heap_Initialize(
+    &_Workspace_Area,
+    starting_address,
+    size,
+    CPU_HEAP_ALIGNMENT
+  );
+ 
+  if ( memory_available == 0 )
+    _Internal_error_Occurred(
+      INTERNAL_ERROR_CORE,
+      TRUE,
+      INTERNAL_ERROR_TOO_LITTLE_WORKSPACE
+    );
+}
+
+/*PAGE
+ *
  *  _Workspace_Allocate_or_fatal_error
  *
Index: cpukit/score/src/thread.c
===================================================================
--- cpukit/score/src/thread.c	(revision 6365f8189896cb4f86b8d3db0a0e9830926b24c7)
+++ cpukit/score/src/thread.c	(revision 8faca06664388ed141b2f7b9b5ddcfb0b4577fe8)
@@ -51,4 +51,17 @@
   unsigned32      index;
 
+  /*
+   * BOTH stacks hooks must be set or both must be NULL.
+   * Do not allow mixture.
+   */
+
+  if ( !( ( _CPU_Table.stack_allocate_hook == 0 )
+       == ( _CPU_Table.stack_free_hook == 0 ) ) )
+    _Internal_error_Occurred(
+      INTERNAL_ERROR_CORE,
+      TRUE,
+      INTERNAL_ERROR_BAD_STACK_HOOK
+    );
+
   _Context_Switch_necessary = FALSE;
   _Thread_Executing         = NULL;
@@ -284,4 +297,63 @@
 /*PAGE
  *
+ *  _Thread_Stack_Allocate
+ *
+ *  Allocate the requested stack space for the thread.
+ *  return the actual size allocated after any adjustment
+ *  or return zero if the allocation failed.
+ *  Set the Start.stack field to the address of the stack
+ */
+
+static unsigned32 _Thread_Stack_Allocate(
+  Thread_Control *the_thread,
+  unsigned32 stack_size)
+{
+  void *stack_addr = 0;
+ 
+  if ( !_Stack_Is_enough( stack_size ) )
+    stack_size = STACK_MINIMUM_SIZE;
+ 
+  /*
+   * Call ONLY the CPU table stack allocate hook, _or_ the
+   * the RTEMS workspace allocate.  This is so the stack free
+   * routine can call the correct deallocation routine.
+   */
+  if ( _CPU_Table.stack_allocate_hook )
+  {
+    stack_addr = (*_CPU_Table.stack_allocate_hook)( stack_size );
+  } else {
+    stack_size = _Stack_Adjust_size( stack_size );
+    stack_addr = _Workspace_Allocate( stack_size );
+  }
+ 
+  if ( !stack_addr )
+      stack_size = 0;
+ 
+  the_thread->Start.stack = stack_addr;
+ 
+  return stack_size;
+}
+
+/*
+ *  _Thread_Stack_Free
+ *
+ *  Deallocate the Thread's stack.
+ */
+
+static void _Thread_Stack_Free(void *stack_addr)
+{
+    /*
+     * Call ONLY the CPU table stack free hook, or the
+     * the RTEMS workspace free.  This is so the free
+     * routine properly matches the allocation of the stack.
+     */
+    if ( _CPU_Table.stack_free_hook )
+        (*_CPU_Table.stack_free_hook)( stack_addr );
+    else
+        _Workspace_Free( stack_addr );
+}
+
+/*PAGE
+ *
  *  _Thread_Initialize
  *
@@ -321,10 +393,10 @@
 
   if ( !stack ) {
-    stack = _Workspace_Allocate( actual_stack_size );
- 
-    if ( !stack ) 
-      return FALSE;
-
-    the_thread->Start.stack = stack;
+    actual_stack_size = _Thread_Stack_Allocate( the_thread, stack_size );
+ 
+    if ( !actual_stack_size ) 
+      return FALSE;                     /* stack allocation failed */
+
+    stack = the_thread->Start.stack;
   } else
     the_thread->Start.stack = NULL;
@@ -345,5 +417,5 @@
     if ( !fp_area ) {
       if ( the_thread->Start.stack )
-        (void) _Workspace_Free( the_thread->Start.stack );
+        (void) _Thread_Stack_Free( the_thread->Start.stack );
       return FALSE;
     }
@@ -358,5 +430,5 @@
 
   /*
-   *  Allocate the floating point area for this thread
+   *  Allocate the extensions area for this thread
    */
 
@@ -371,5 +443,5 @@
 
       if ( the_thread->Start.stack )
-        (void) _Workspace_Free( the_thread->Start.stack );
+        (void) _Thread_Stack_Free( the_thread->Start.stack );
 
       return FALSE;
@@ -414,5 +486,5 @@
 
     if ( the_thread->Start.stack )
-      (void) _Workspace_Free( the_thread->Start.stack );
+      (void) _Thread_Stack_Free( the_thread->Start.stack );
 
     return FALSE;
Index: cpukit/score/src/wkspace.c
===================================================================
--- cpukit/score/src/wkspace.c	(revision 6365f8189896cb4f86b8d3db0a0e9830926b24c7)
+++ cpukit/score/src/wkspace.c	(revision 8faca06664388ed141b2f7b9b5ddcfb0b4577fe8)
@@ -23,4 +23,47 @@
 /*PAGE
  *
+ *  _Workspace_Handler_initialization
+ */
+ 
+void _Workspace_Handler_initialization(
+  void       *starting_address,
+  unsigned32  size
+)
+{
+  unsigned32 *zero_out_array;
+  unsigned32  index;
+  unsigned32  memory_available;
+ 
+  if ( !starting_address || !_Addresses_Is_aligned( starting_address ) )
+    _Internal_error_Occurred(
+      INTERNAL_ERROR_CORE,
+      TRUE,
+      INTERNAL_ERROR_INVALID_WORKSPACE_ADDRESS
+    );
+ 
+  if ( _CPU_Table.do_zero_of_workspace ) {
+    for( zero_out_array  = (unsigned32 *) starting_address, index = 0 ;
+         index < size / 4 ;
+         index++ )
+      zero_out_array[ index ] = 0;
+  }
+ 
+  memory_available = _Heap_Initialize(
+    &_Workspace_Area,
+    starting_address,
+    size,
+    CPU_HEAP_ALIGNMENT
+  );
+ 
+  if ( memory_available == 0 )
+    _Internal_error_Occurred(
+      INTERNAL_ERROR_CORE,
+      TRUE,
+      INTERNAL_ERROR_TOO_LITTLE_WORKSPACE
+    );
+}
+
+/*PAGE
+ *
  *  _Workspace_Allocate_or_fatal_error
  *
