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:
Joel Sherrill
2003-09-26 20:43:22 +00:00
parent fca113c373
commit 92b67b18d7
3 changed files with 93 additions and 2 deletions

View File

@@ -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

View File

@@ -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 );

View 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;
}