 Sbrk implementation for RTEMS/MVME23xx to work around
 the 32M problem...

 Author: Till Straumann <strauman@slac.stanford.edu>

 To apply this patch, run
  
  patch -p0 < <this file> 

 in the RTEMS top directory.

*** c/src/lib/libbsp/powerpc/shared/startup/bspstart.c.orig	2003-09-18 09:04:32.000000000 -0700
--- c/src/lib/libbsp/powerpc/shared/startup/bspstart.c	2003-09-18 09:15:28.000000000 -0700
***************
*** 132,137 ****
--- 132,139 ----
  {
      rtems_unsigned32        heap_start;    
      rtems_unsigned32        heap_size;
+     rtems_unsigned32        heap_sbrk_spared;
+ 	extern rtems_unsigned32 _bsp_sbrk_init(rtems_unsigned32, *rtems_unsigned32);
  
      heap_start = ((rtems_unsigned32) __rtems_end) +INIT_STACK_SIZE + INTR_STACK_SIZE;
      if (heap_start & (CPU_ALIGNMENT-1))
***************
*** 139,148 ****
  
      heap_size = (BSP_mem_size - heap_start) - BSP_Configuration.work_space_size;
  
  #ifdef SHOW_MORE_INIT_SETTINGS
!     printk(" HEAP start %x  size %x\n", heap_start, heap_size);
  #endif    
!     bsp_libc_init((void *) heap_start, heap_size, 0);
  
  #ifdef RTEMS_DEBUG
      rtems_debug_enable( RTEMS_DEBUG_ALL_MASK );
--- 141,154 ----
  
      heap_size = (BSP_mem_size - heap_start) - BSP_Configuration.work_space_size;
  
+ 	heap_sbrk_spared=_bsp_sbrk_init(heap_start, &heap_size);
+ 
  #ifdef SHOW_MORE_INIT_SETTINGS
!    	printk(" HEAP start %x  size %x (%x bytes spared for sbrk)\n", heap_start, heap_size, heap_sbrk_spared);
  #endif    
! 
!     bsp_libc_init((void *) 0, heap_size, heap_sbrk_spared);
! 
  
  #ifdef RTEMS_DEBUG
      rtems_debug_enable( RTEMS_DEBUG_ALL_MASK );
*** c/src/lib/libbsp/powerpc/shared/startup/sbrk.c.orig	1969-12-31 16:00:00.000000000 -0800
--- c/src/lib/libbsp/powerpc/shared/startup/sbrk.c	2003-09-18 09:15:39.000000000 -0700
***************
*** 0 ****
--- 1,61 ----
+ /* $Id: sbrk.c,v 1.2 2002/10/30 00:56:27 till Exp $ */
+ 
+ /*
+  *  sbrk.c
+  *
+  *  Author: Till Straumann <strauman@slac.stanford.edu>, 2002
+  *  
+  *  Hack around the 32bit powerpc 32M problem:
+  *
+  *  GCC by default uses relative branches which can not jump
+  *  farther than 32M. Hence all program text is confined to
+  *  a single 32M segment.
+  *  This hack gives the RTEMS malloc region all memory below
+  *  32M at startup. Only when this region is exhausted will sbrk
+  *  add more memory. Loading modules may fail at that point, hence
+  *  the user is expected to load all modules at startup _prior_
+  *  to malloc()ing lots of memory...
+  *
+  *  NOTE: it would probably be better to have a separate region
+  *        for module code.
+  */
+ 
+ #include <rtems.h>
+ 
+ #include <signal.h>
+ #include <errno.h>
+ #include <sys/types.h>
+ #include <unistd.h>
+ 
+ static rtems_unsigned32 remaining_start=0;
+ static rtems_unsigned32 remaining_size=0;
+ 
+ #define LIMIT_32M	0x02000000
+ 
+ rtems_unsigned32
+ _bsp_sbrk_init(rtems_unsigned32 heap_start, rtems_unsigned32 *heap_size_p)
+ {
+ rtems_unsigned32 rval=0;
+ 	remaining_start=heap_start;
+ 	remaining_size =*heap_size_p;
+ 	if (remaining_start < LIMIT_32M && remaining_start + remaining_size > LIMIT_32M) {
+ 		/* clip at LIMIT_32M */
+ 		rval = remaining_start + remaining_size - LIMIT_32M;
+ 		*heap_size_p = LIMIT_32M - remaining_start;	
+ 	}
+ 	return rval;
+ }
+ 
+ void * sbrk(ptrdiff_t incr)
+ {
+ void *rval=(void*)-1;
+ 	if (incr <= remaining_size) {
+ 		remaining_size-=incr;
+ 		rval = (void*)remaining_start;
+ 		remaining_start+=incr;
+ 	} else {
+   		errno = ENOMEM;
+ 	}
+ 	return rval;
+ }
+ 
