forked from Imagelibrary/rtems
2003-09-26 Till Strauman <strauman@slac.stanford.edu>
PR 496/bsps * startup/sbrk.c: New file. * startup/bspstart.c: This patch implements 'sbrk' for the powerpc-shared BSP to work around what's known as the '32Mb problem' in combination with run-time loaded code. GCC normally generates (PowerPC) code doing 'short jumps' which requires all text segments being in the same 32Mb area of memory. However, some run-time loaders use (e.g. heap-) memory violating the stated limitation on hardware with more than 32Mb of memory. (NOTE: portable loaders are probably not even aware of this GCC/CPU specific problem.) This patch implements a simple workaround: At boot time, the system is only provided with 32Mb of memory. The user is supposed to load all necessary modules prior to that limit being exhausted. Once that happens, newlib/malloc end up trying to 'sbrk()' for more memory and the implementation provided by this patch will then make the rest of the physical memory available.
This commit is contained in:
@@ -1,3 +1,24 @@
|
||||
2003-09-26 Till Strauman <strauman@slac.stanford.edu>
|
||||
|
||||
PR 496/bsps
|
||||
* startup/sbrk.c: New file.
|
||||
* startup/bspstart.c: This patch implements 'sbrk'
|
||||
for the powerpc-shared BSP to work around what's known as the
|
||||
'32Mb problem' in combination with run-time loaded code.
|
||||
GCC normally generates (PowerPC) code doing 'short jumps' which
|
||||
requires all text segments being in the same 32Mb area of memory.
|
||||
However, some run-time loaders use (e.g. heap-) memory violating the
|
||||
stated limitation on hardware with more than 32Mb of memory.
|
||||
(NOTE: portable loaders are probably not even aware of this
|
||||
GCC/CPU specific problem.)
|
||||
|
||||
This patch implements a simple workaround: At boot time, the system is
|
||||
only provided with 32Mb of memory. The user is supposed to load all
|
||||
necessary modules prior to that limit being exhausted. Once that
|
||||
happens, newlib/malloc end up trying to 'sbrk()' for more memory and
|
||||
the implementation provided by this patch will then make the rest of
|
||||
the physical memory available.
|
||||
|
||||
2003-09-26 Till Straumann <strauman@slac.stanford.edu>
|
||||
|
||||
PR 497/bsps
|
||||
|
||||
@@ -132,6 +132,8 @@ void bsp_pretasking_hook(void)
|
||||
{
|
||||
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,10 +141,14 @@ void bsp_pretasking_hook(void)
|
||||
|
||||
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\n", heap_start, heap_size);
|
||||
printk(" HEAP start %x size %x (%x bytes spared for sbrk)\n", heap_start, heap_size, heap_sbrk_spared);
|
||||
#endif
|
||||
bsp_libc_init((void *) heap_start, heap_size, 0);
|
||||
|
||||
bsp_libc_init((void *) 0, heap_size, heap_sbrk_spared);
|
||||
|
||||
|
||||
#ifdef RTEMS_DEBUG
|
||||
rtems_debug_enable( RTEMS_DEBUG_ALL_MASK );
|
||||
|
||||
64
c/src/lib/libbsp/powerpc/shared/startup/sbrk.c
Normal file
64
c/src/lib/libbsp/powerpc/shared/startup/sbrk.c
Normal file
@@ -0,0 +1,64 @@
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user