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

Gedare Bloom gedare at rtems.org
Tue Mar 27 20:36:15 UTC 2012


I'm willing to take this patch as-is and consider refactoring it later
to share the code with other BSPs if the feature seems generally
useful. Joel?

-Gedare

On Mon, Feb 6, 2012 at 11:08 AM, Daniel Hellstrom <daniel at gaisler.com> wrote:
> 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