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

Daniel Hellstrom daniel at gaisler.com
Wed Mar 28 08:46:59 UTC 2012


On 03/27/2012 10:54 PM, Joel Sherrill wrote:
> 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.

I will resend the patch with removed $Id's in all modified and new files, and improve comment.

Thanks,
Daniel

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