From 92b67b18d78f9822dcd58c018c130e4bd986986b Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Fri, 26 Sep 2003 20:43:22 +0000 Subject: 2003-09-26 Till Strauman 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. --- c/src/lib/libbsp/powerpc/shared/ChangeLog | 21 +++++++ c/src/lib/libbsp/powerpc/shared/startup/bspstart.c | 10 +++- c/src/lib/libbsp/powerpc/shared/startup/sbrk.c | 64 ++++++++++++++++++++++ 3 files changed, 93 insertions(+), 2 deletions(-) create mode 100644 c/src/lib/libbsp/powerpc/shared/startup/sbrk.c (limited to 'c/src') diff --git a/c/src/lib/libbsp/powerpc/shared/ChangeLog b/c/src/lib/libbsp/powerpc/shared/ChangeLog index 7443efbdf7..bec24b2a92 100644 --- a/c/src/lib/libbsp/powerpc/shared/ChangeLog +++ b/c/src/lib/libbsp/powerpc/shared/ChangeLog @@ -1,3 +1,24 @@ +2003-09-26 Till Strauman + + 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 PR 497/bsps diff --git a/c/src/lib/libbsp/powerpc/shared/startup/bspstart.c b/c/src/lib/libbsp/powerpc/shared/startup/bspstart.c index 3834c6f255..1927ea96db 100644 --- a/c/src/lib/libbsp/powerpc/shared/startup/bspstart.c +++ b/c/src/lib/libbsp/powerpc/shared/startup/bspstart.c @@ -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 ); diff --git a/c/src/lib/libbsp/powerpc/shared/startup/sbrk.c b/c/src/lib/libbsp/powerpc/shared/startup/sbrk.c new file mode 100644 index 0000000000..276433a5da --- /dev/null +++ b/c/src/lib/libbsp/powerpc/shared/startup/sbrk.c @@ -0,0 +1,64 @@ +/* $Id$ */ + +/* + * sbrk.c + * + * Author: Till Straumann , 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 + +#include +#include +#include +#include + +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; +} + -- cgit v1.2.3