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

Joel Sherrill joel.sherrill at OARcorp.com
Tue Mar 27 20:54:21 UTC 2012


On 03/27/2012 03:36 PM, Gedare Bloom wrote:
> 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?
I don't see any reason not to. The LEON is very dynamic in
the way it finds its on-CPU devices. Most BSPs will not have
this issue. I don't expect many other BSPs to need this
capability.

If other BSPs need something similar, then the bsp_early_malloc()
can likely be implemented in a similar manner based upon how
the memory is allocated on the BSP. There are only a handful
of patterns.  If that happens, we can probably implement one
as a "partner" to bsp_get_workspace() implementations. Since
the SPARC BSPs share a single implementation, I think this is
good enough for now.

Can the method's comments be enhanced to note that it is
ONLY to be used from point X to point Y during the initialization
sequence?

And kill the $Id's. At least one is broken anyway.

--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


-- 
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