[PATCH 12] SPARC BSPs: bsp_early_malloc() routine for startup memory allocation

Joel Sherrill joel.sherrill at OARcorp.com
Mon Feb 6 15:58:00 UTC 2012


On 02/06/2012 09:45 AM, 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?
At this point, every BSP should be following the same model
for memory allocation. After the work area[1] are provided
by the BSP to boot_card(), then they are split into RTEMS
Workspace and C Program Heap[2]. If you bump the C Program
Heap start address and bring down the size, it will work on
all BSPs.

Hmmm.. even with that, you wouldn't be able to reliably do
this until after the call to memset() around line 210 in
bootcard.c. By that time, you are about to call
rtems_initialize_data_structures() and than you immediately
call bootcard_bsp_libc_helper(). At that point you can
malloc().

So IMO there isn't much window of usefulness for a generic
solution.

I have to follow Gedare with the "what are you trying to do?
and when?"

[1] The framework allows for the BSP to provide separate
memory regions for the RTEMS Workspace and C Program
Heap. This should still work but would need review.

[2] You would have to be careful this works with unified
memory allocation configured.  In this case, the entire
Work Area is given to RTEMS for Workspace and that heap
is also the C Program Heap.
> _______________________________________________
> rtems-devel mailing list
> rtems-devel at rtems.org
> http://www.rtems.org/mailman/listinfo/rtems-devel


-- 
Joel Sherrill, Ph.D.             Director of Research&   Development
joel.sherrill at OARcorp.com        On-Line Applications Research
Ask me about RTEMS: a free RTOS  Huntsville AL 35805
     Support Available             (256) 722-9985





More information about the devel mailing list