[PATCH 12] SPARC BSPs: bsp_early_malloc() routine for startup memory allocation
Daniel Hellstrom
daniel at gaisler.com
Mon Feb 6 16:08:20 UTC 2012
On 02/06/2012 04:45 PM, Gedare Bloom wrote:
> On Mon, Feb 6, 2012 at 9:15 AM, Daniel Hellstrom<daniel at gaisler.com> wrote:
>> If bsp_early_malloc() is called early during boot room will be
>> allocated after BSS END. If the function is called after boot
>> is will call malloc() instead. The returned memory is not freeable
>> and always 8-byte aligned.
>>
>> If the bsp_early_malloc() isn't called the function is not
>> dragged in and the workspace will be unmodified in size.
>>
>> Signed-off-by: Daniel Hellstrom<daniel at gaisler.com>
>> ---
>> c/src/lib/libbsp/sparc/erc32/Makefile.am | 2 +-
>> c/src/lib/libbsp/sparc/erc32/include/bsp.h | 3 +
>> c/src/lib/libbsp/sparc/leon2/Makefile.am | 3 +-
>> c/src/lib/libbsp/sparc/leon2/include/bsp.h | 3 +
>> c/src/lib/libbsp/sparc/leon3/Makefile.am | 2 +-
>> c/src/lib/libbsp/sparc/leon3/include/bsp.h | 3 +
>> c/src/lib/libbsp/sparc/shared/bspgetworkarea.c | 10 ++++-
>> .../lib/libbsp/sparc/shared/startup/early_malloc.c | 44 ++++++++++++++++++++
>> 8 files changed, 65 insertions(+), 5 deletions(-)
>> create mode 100644 c/src/lib/libbsp/sparc/shared/startup/early_malloc.c
>>
>> diff --git a/c/src/lib/libbsp/sparc/erc32/Makefile.am b/c/src/lib/libbsp/sparc/erc32/Makefile.am
>> index cecfe14..e70310d 100644
>> --- a/c/src/lib/libbsp/sparc/erc32/Makefile.am
>> +++ b/c/src/lib/libbsp/sparc/erc32/Makefile.am
>> @@ -38,7 +38,7 @@ libbsp_a_SOURCES += ../../shared/bspclean.c ../../shared/bsplibc.c \
>> ../../shared/bspstart.c ../../shared/bootcard.c ../../shared/bspinit.c \
>> ../../shared/sbrk.c startup/setvec.c startup/spurious.c \
>> startup/erc32mec.c startup/boardinit.S startup/bspidle.c \
>> - startup/bspdelay.c
>> + startup/bspdelay.c ../../sparc/shared/startup/early_malloc.c
>> # ISR Handler
>> libbsp_a_SOURCES += ../../sparc/shared/irq_asm.S
>> # gnatsupp
>> diff --git a/c/src/lib/libbsp/sparc/erc32/include/bsp.h b/c/src/lib/libbsp/sparc/erc32/include/bsp.h
>> index 8655732..8075e8e 100644
>> --- a/c/src/lib/libbsp/sparc/erc32/include/bsp.h
>> +++ b/c/src/lib/libbsp/sparc/erc32/include/bsp.h
>> @@ -81,6 +81,9 @@ void BSP_fatal_return( void );
>>
>> void bsp_spurious_initialize( void );
>>
>> +/* Allocate 8-byte aligned non-freeable pre-malloc memory */
>> +void *bsp_early_malloc(int size);
>> +
>> #ifdef __cplusplus
>> }
>> #endif
>> diff --git a/c/src/lib/libbsp/sparc/leon2/Makefile.am b/c/src/lib/libbsp/sparc/leon2/Makefile.am
>> index 9df3c7d..6e2697f 100644
>> --- a/c/src/lib/libbsp/sparc/leon2/Makefile.am
>> +++ b/c/src/lib/libbsp/sparc/leon2/Makefile.am
>> @@ -55,7 +55,8 @@ libbsp_a_SOURCES += ../../shared/bspclean.c ../../shared/bsplibc.c \
>> startup/bspstart.c ../../sparc/shared/bsppretaskinghook.c \
>> ../../sparc/shared/bspgetworkarea.c ../../shared/bootcard.c \
>> ../../shared/sbrk.c startup/setvec.c startup/spurious.c startup/bspidle.c \
>> - ../../shared/bspinit.c startup/bspdelay.c
>> + ../../shared/bspinit.c startup/bspdelay.c \
>> + ../../sparc/shared/startup/early_malloc.c
>> # ISR Handler
>> libbsp_a_SOURCES += ../../sparc/shared/irq_asm.S
>> # gnatsupp
>> diff --git a/c/src/lib/libbsp/sparc/leon2/include/bsp.h b/c/src/lib/libbsp/sparc/leon2/include/bsp.h
>> index 34e31ce..b0695cb 100644
>> --- a/c/src/lib/libbsp/sparc/leon2/include/bsp.h
>> +++ b/c/src/lib/libbsp/sparc/leon2/include/bsp.h
>> @@ -94,6 +94,9 @@ void BSP_fatal_return( void );
>>
>> void bsp_spurious_initialize( void );
>>
>> +/* Allocate 8-byte aligned non-freeable pre-malloc memory */
>> +void *bsp_early_malloc(int size);
>> +
>> #ifdef __cplusplus
>> }
>> #endif
>> diff --git a/c/src/lib/libbsp/sparc/leon3/Makefile.am b/c/src/lib/libbsp/sparc/leon3/Makefile.am
>> index 8eae306..dc24051 100644
>> --- a/c/src/lib/libbsp/sparc/leon3/Makefile.am
>> +++ b/c/src/lib/libbsp/sparc/leon3/Makefile.am
>> @@ -38,7 +38,7 @@ libbsp_a_SOURCES += ../../shared/bspclean.c ../../shared/bsplibc.c \
>> ../../sparc/shared/bsppretaskinghook.c ../../shared/bsppredriverhook.c \
>> ../../sparc/shared/bspgetworkarea.c ../../shared/sbrk.c startup/setvec.c \
>> startup/spurious.c startup/bspidle.S startup/bspdelay.c \
>> - ../../shared/bspinit.c
>> + ../../shared/bspinit.c ../../sparc/shared/startup/early_malloc.c
>>
>> # ISR Handler
>> libbsp_a_SOURCES += ../../sparc/shared/irq_asm.S
>> diff --git a/c/src/lib/libbsp/sparc/leon3/include/bsp.h b/c/src/lib/libbsp/sparc/leon3/include/bsp.h
>> index 89b36d4..70ab8b3 100644
>> --- a/c/src/lib/libbsp/sparc/leon3/include/bsp.h
>> +++ b/c/src/lib/libbsp/sparc/leon3/include/bsp.h
>> @@ -104,6 +104,9 @@ void BSP_fatal_return( void );
>>
>> void bsp_spurious_initialize( void );
>>
>> +/* Allocate 8-byte aligned non-freeable pre-malloc memory */
>> +void *bsp_early_malloc(int size);
>> +
>> #ifdef __cplusplus
>> }
>> #endif
>> diff --git a/c/src/lib/libbsp/sparc/shared/bspgetworkarea.c b/c/src/lib/libbsp/sparc/shared/bspgetworkarea.c
>> index c6e1491..580a911 100644
>> --- a/c/src/lib/libbsp/sparc/shared/bspgetworkarea.c
>> +++ b/c/src/lib/libbsp/sparc/shared/bspgetworkarea.c
>> @@ -22,6 +22,9 @@
>> /* Tells us where to put the workspace in case remote debugger is present. */
>> extern uint32_t rdb_start;
>>
>> +/* Must be aligned to 8, _end is aligned to 8 */
>> +unsigned int early_mem = (unsigned int)&end;
>> +
>> /*
>> * This method returns the base address and size of the area which
>> * is to be allocated between the RTEMS Workspace and the C Program
>> @@ -37,8 +40,11 @@ void bsp_get_work_area(
>> /* must be identical to STACK_SIZE in start.S */
>> #define STACK_SIZE (16 * 1024)
>>
>> - *work_area_start =&end;
>> - *work_area_size = (void *)rdb_start - (void *)&end - STACK_SIZE;
>> + /* Early dynamic memory allocator is placed just above _end */
>> + *work_area_start = (void *)early_mem;
>> + *work_area_size = (void *)rdb_start - (void *)early_mem - STACK_SIZE;
>> + early_mem = ~0; /* Signal bsp_early_malloc not to be used anymore */
>> +
>> *heap_start = BSP_BOOTCARD_HEAP_USES_WORK_AREA;
>> *heap_size = BSP_BOOTCARD_HEAP_SIZE_DEFAULT;
>>
>> diff --git a/c/src/lib/libbsp/sparc/shared/startup/early_malloc.c b/c/src/lib/libbsp/sparc/shared/startup/early_malloc.c
>> new file mode 100644
>> index 0000000..c6abaca
>> --- /dev/null
>> +++ b/c/src/lib/libbsp/sparc/shared/startup/early_malloc.c
>> @@ -0,0 +1,44 @@
>> +/*
>> + * Early dynamic memory allocation (not freeable) for BSP
>> + * boot routines. Minimum alignment 8 bytes. Memory is
>> + * allocated after _end, it will shrink the workspace.
>> + *
>> + * COPYRIGHT (c) 2011.
>> + * Aeroflex Gaisler AB
>> + *
>> + * The license and distribution terms for this file may be
>> + * found in the file LICENSE in this distribution or at
>> + * http://www.rtems.com/license/LICENSE.
>> + *
>> + * $Id: early_malloc.c
>> + */
>> +
>> +#include<bsp.h>
>> +#include<stdlib.h>
>> +
>> +/* Tells us where to put the workspace in case remote debugger is present. */
>> +extern uint32_t rdb_start;
>> +
>> +/* Must be aligned to 8 */
>> +extern unsigned int early_mem;
>> +
>> +/* must be identical to STACK_SIZE in start.S */
>> +#define STACK_SIZE (16 * 1024)
>> +
>> +void *bsp_early_malloc(int size)
>> +{
>> + void *start;
>> +
>> + /* Not early anymore? */
>> + if (early_mem == ~0)
>> + return malloc(size);
>> +
>> + size = (size + 7)& ~0x7;
>> + if (rdb_start - STACK_SIZE - early_mem< size)
>> + return NULL;
>> +
>> + start = (void *)early_mem;
>> + early_mem += size;
>> +
>> + return start;
>> +}
>> --
>> 1.7.0.4
>>
>> _______________________________________________
>> rtems-devel mailing list
>> rtems-devel at rtems.org
>> http://www.rtems.org/mailman/listinfo/rtems-devel
> This looks OK to me. Basic bump allocation for early dynamic memory.
> workspace is properly adjusted. If the BSP exhausts memory then RTEMS
> should fail gracefully during bootup when it detects the workspace is
> not big enough.
>
> I wonder if there would be any use in having this early memory
> mechanism available on every BSP? For what do you use it?
I will use it later in a AMBA Plug&Play layer patch.
The LEON3/4 is plug and play, one never knows how many cores are available on boot, the PnP layers scan the plug&play info and creates one "RAM structure" description per PnP entry. Before this was
made by allocating a worst-case structure in leon3/amba/amba.c (amba_confarea_type amba_conf) which could hold lots of RAM descriptions. However on small systems its a waste, and on very large systems
it breaks. Using malloc() would require BSP initialization too late and malloc() wastes 4 or 8-bytes per allocation of memory that we never would have freed anyway.
It can probably be useful for other BSPs as well.
Daniel
More information about the devel
mailing list