summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2003-09-26 20:43:22 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2003-09-26 20:43:22 +0000
commit92b67b18d78f9822dcd58c018c130e4bd986986b (patch)
treedf313cd1b79049b08ed607e2861947c5fcc2a845 /c/src/lib/libbsp
parent2003-09-26 Till Straumann <strauman@slac.stanford.edu> (diff)
downloadrtems-92b67b18d78f9822dcd58c018c130e4bd986986b.tar.bz2
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.
Diffstat (limited to 'c/src/lib/libbsp')
-rw-r--r--c/src/lib/libbsp/powerpc/shared/ChangeLog21
-rw-r--r--c/src/lib/libbsp/powerpc/shared/startup/bspstart.c10
-rw-r--r--c/src/lib/libbsp/powerpc/shared/startup/sbrk.c64
3 files changed, 93 insertions, 2 deletions
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 <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
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 <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;
+}
+