[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