[PATCH 2/2] bsps: Call bsp_work_area_initialize() early

Gedare Bloom gedare at rtems.org
Wed Dec 9 12:39:52 UTC 2015


ok. Joel, you may need to tweak any slides you have on the boot sequence. ;)

On Wed, Dec 9, 2015 at 3:15 AM, Sebastian Huber
<sebastian.huber at embedded-brains.de> wrote:
> Call bsp_work_area_initialize() before bsp_start().  This allows
> bsp_start() to use malloc() etc. which is beneficial for systems with a
> plug-and-play hardware enumeration.
>
> Update #2408.
> ---
>  c/src/lib/libbsp/i386/pc386/include/bsp.h          |  2 -
>  .../lib/libbsp/i386/pc386/startup/bspgetworkarea.c | 13 ++++--
>  c/src/lib/libbsp/i386/pc386/startup/bspstart.c     |  5 ---
>  c/src/lib/libbsp/shared/bootcard.c                 |  8 ++--
>  c/src/lib/libbsp/shared/include/bootcard.h         |  2 +-
>  c/src/lib/libbsp/sparc/erc32/Makefile.am           |  1 -
>  c/src/lib/libbsp/sparc/erc32/include/bsp.h         |  7 ----
>  c/src/lib/libbsp/sparc/leon2/Makefile.am           |  1 -
>  c/src/lib/libbsp/sparc/leon2/include/bsp.h         |  7 ----
>  c/src/lib/libbsp/sparc/leon3/Makefile.am           |  3 +-
>  c/src/lib/libbsp/sparc/leon3/include/bsp.h         |  7 ----
>  c/src/lib/libbsp/sparc/shared/amba/ambapp.c        | 10 ++---
>  .../libbsp/sparc/shared/startup/bspgetworkarea.c   |  8 +---
>  .../lib/libbsp/sparc/shared/startup/early_malloc.c | 47 ---------------------
>  doc/bsp_howto/init.t                               | 49 ++++++++++++----------
>  15 files changed, 49 insertions(+), 121 deletions(-)
>  delete mode 100644 c/src/lib/libbsp/sparc/shared/startup/early_malloc.c
>
> diff --git a/c/src/lib/libbsp/i386/pc386/include/bsp.h b/c/src/lib/libbsp/i386/pc386/include/bsp.h
> index 5a82ac2..d9f24e4 100644
> --- a/c/src/lib/libbsp/i386/pc386/include/bsp.h
> +++ b/c/src/lib/libbsp/i386/pc386/include/bsp.h
> @@ -187,8 +187,6 @@ void Calibrate_loop_1ms(void);           /* from 'timer.c'  */
>
>  void rtems_irq_mngt_init(void);          /* from 'irq_init.c' */
>
> -void bsp_size_memory(void);              /* from 'bspstart.c' */
> -
>  #if (BSP_IS_EDISON == 0)
>    void Clock_driver_install_handler(void);             /* from 'ckinit.c'  */
>    void Clock_driver_support_initialize_hardware(void); /* from 'ckinit.c'  */
> diff --git a/c/src/lib/libbsp/i386/pc386/startup/bspgetworkarea.c b/c/src/lib/libbsp/i386/pc386/startup/bspgetworkarea.c
> index 2e4bf5c..5207bac 100644
> --- a/c/src/lib/libbsp/i386/pc386/startup/bspgetworkarea.c
> +++ b/c/src/lib/libbsp/i386/pc386/startup/bspgetworkarea.c
> @@ -52,7 +52,7 @@ uint32_t bsp_mem_size = 0;
>  /* Size of stack used during initialization. Defined in 'start.s'.  */
>  extern uint32_t _stack_size;
>
> -void bsp_size_memory(void)
> +static void bsp_size_memory(void)
>  {
>    uintptr_t topAddr;
>
> @@ -126,8 +126,15 @@ void bsp_size_memory(void)
>
>  void bsp_work_area_initialize(void)
>  {
> -  void *area_start = (void *) rtemsWorkAreaStart;
> -  uintptr_t area_size  = (uintptr_t) bsp_mem_size - (uintptr_t) rtemsWorkAreaStart;
> +  void *area_start;
> +  uintptr_t area_size;
>
> +  /*
> +   *  We need to determine how much memory there is in the system.
> +   */
> +  bsp_size_memory();
> +
> +  area_start = (void *) rtemsWorkAreaStart;
> +  area_size  = (uintptr_t) bsp_mem_size - (uintptr_t) rtemsWorkAreaStart;
>    bsp_work_area_initialize_default( area_start, area_size );
>  }
> diff --git a/c/src/lib/libbsp/i386/pc386/startup/bspstart.c b/c/src/lib/libbsp/i386/pc386/startup/bspstart.c
> index 9b1be64..ac871f0 100644
> --- a/c/src/lib/libbsp/i386/pc386/startup/bspstart.c
> +++ b/c/src/lib/libbsp/i386/pc386/startup/bspstart.c
> @@ -58,11 +58,6 @@ static void bsp_pci_initialize_helper(void)
>  static void bsp_start_default( void )
>  {
>    /*
> -   *  We need to determine how much memory there is in the system.
> -   */
> -  bsp_size_memory();
> -
> -  /*
>     * Turn off watchdog
>     */
>  #if (BSP_IS_EDISON == 1)
> diff --git a/c/src/lib/libbsp/shared/bootcard.c b/c/src/lib/libbsp/shared/bootcard.c
> index eeb5746..cbeb7b2 100644
> --- a/c/src/lib/libbsp/shared/bootcard.c
> +++ b/c/src/lib/libbsp/shared/bootcard.c
> @@ -75,14 +75,14 @@ void boot_card(
>    bsp_boot_cmdline = cmdline;
>
>    /*
> -   * Invoke Board Support Package initialization routine written in C.
> +   *  Initialize the RTEMS Workspace and the C Program Heap.
>     */
> -  bsp_start();
> +  bsp_work_area_initialize();
>
>    /*
> -   *  Initialize the RTEMS Workspace and the C Program Heap.
> +   * Invoke Board Support Package initialization routine written in C.
>     */
> -  bsp_work_area_initialize();
> +  bsp_start();
>
>    /*
>     *  Initialize RTEMS data structures
> diff --git a/c/src/lib/libbsp/shared/include/bootcard.h b/c/src/lib/libbsp/shared/include/bootcard.h
> index 93d5041..7c0d3f1 100644
> --- a/c/src/lib/libbsp/shared/include/bootcard.h
> +++ b/c/src/lib/libbsp/shared/include/bootcard.h
> @@ -78,9 +78,9 @@ void bsp_reset(void);
>   *
>   * - disable interrupts, interrupts will be enabled during the first context
>   *   switch
> - * - bsp_start() - more advanced initialization
>   * - bsp_work_area_initialize() - initialize the RTEMS Workspace and the C
>   *   Program Heap
> + * - bsp_start() - more advanced initialization
>   * - rtems_initialize_data_structures()
>   * - initialize C Library
>   * - bsp_pretasking_hook()
> diff --git a/c/src/lib/libbsp/sparc/erc32/Makefile.am b/c/src/lib/libbsp/sparc/erc32/Makefile.am
> index b00853a..f0465b0 100644
> --- a/c/src/lib/libbsp/sparc/erc32/Makefile.am
> +++ b/c/src/lib/libbsp/sparc/erc32/Makefile.am
> @@ -43,7 +43,6 @@ libbsp_a_SOURCES += startup/erc32mec.c
>  libbsp_a_SOURCES += startup/boardinit.S
>  libbsp_a_SOURCES += startup/bspidle.c
>  libbsp_a_SOURCES += startup/bspdelay.c
> -libbsp_a_SOURCES += ../../sparc/shared/startup/early_malloc.c
>  libbsp_a_SOURCES += ../../sparc/shared/startup/bsp_fatal_exit.c
>  libbsp_a_SOURCES += ../../sparc/shared/startup/bsp_fatal_halt.c
>  # ISR Handler
> diff --git a/c/src/lib/libbsp/sparc/erc32/include/bsp.h b/c/src/lib/libbsp/sparc/erc32/include/bsp.h
> index 942a873..8633634 100644
> --- a/c/src/lib/libbsp/sparc/erc32/include/bsp.h
> +++ b/c/src/lib/libbsp/sparc/erc32/include/bsp.h
> @@ -93,13 +93,6 @@ void BSP_fatal_exit(uint32_t error);
>
>  void bsp_spurious_initialize( void );
>
> -/* Allocate 8-byte aligned non-freeable pre-malloc() memory. The function
> - * can be called at any time. The work-area will shrink when called before
> - * bsp_work_area_initialize(). malloc() is called to get memory when this
> - * function is called after bsp_work_area_initialize().
> - */
> -void *bsp_early_malloc(int size);
> -
>  /* Interrupt Service Routine (ISR) pointer */
>  typedef void (*bsp_shared_isr)(void *arg);
>
> diff --git a/c/src/lib/libbsp/sparc/leon2/Makefile.am b/c/src/lib/libbsp/sparc/leon2/Makefile.am
> index 7eada59..2b5d195 100644
> --- a/c/src/lib/libbsp/sparc/leon2/Makefile.am
> +++ b/c/src/lib/libbsp/sparc/leon2/Makefile.am
> @@ -42,7 +42,6 @@ libbsp_a_SOURCES += startup/setvec.c
>  libbsp_a_SOURCES += startup/spurious.c
>  libbsp_a_SOURCES += startup/bspidle.c
>  libbsp_a_SOURCES += startup/bspdelay.c
> -libbsp_a_SOURCES += ../../sparc/shared/startup/early_malloc.c
>  libbsp_a_SOURCES += ../../sparc/shared/startup/bsp_fatal_exit.c
>  libbsp_a_SOURCES += ../../sparc/shared/startup/bsp_fatal_halt.c
>
> diff --git a/c/src/lib/libbsp/sparc/leon2/include/bsp.h b/c/src/lib/libbsp/sparc/leon2/include/bsp.h
> index 09cf7f7..acc310a 100644
> --- a/c/src/lib/libbsp/sparc/leon2/include/bsp.h
> +++ b/c/src/lib/libbsp/sparc/leon2/include/bsp.h
> @@ -117,13 +117,6 @@ void BSP_fatal_exit(uint32_t error);
>
>  void bsp_spurious_initialize( void );
>
> -/* Allocate 8-byte aligned non-freeable pre-malloc() memory. The function
> - * can be called at any time. The work-area will shrink when called before
> - * bsp_work_area_initialize(). malloc() is called to get memory when this
> - * function is called after bsp_work_area_initialize().
> - */
> -void *bsp_early_malloc(int size);
> -
>  /* Interrupt Service Routine (ISR) pointer */
>  typedef void (*bsp_shared_isr)(void *arg);
>
> diff --git a/c/src/lib/libbsp/sparc/leon3/Makefile.am b/c/src/lib/libbsp/sparc/leon3/Makefile.am
> index d261f99..95f10eb 100644
> --- a/c/src/lib/libbsp/sparc/leon3/Makefile.am
> +++ b/c/src/lib/libbsp/sparc/leon3/Makefile.am
> @@ -38,8 +38,7 @@ libbsp_a_SOURCES += ../../shared/bsplibc.c \
>      ../../shared/bsppretaskinghook.c startup/bsppredriver.c \
>      ../../sparc/shared/startup/bspgetworkarea.c ../../shared/sbrk.c \
>      startup/setvec.c \
> -    startup/spurious.c startup/bspidle.S startup/bspdelay.c \
> -    ../../sparc/shared/startup/early_malloc.c
> +    startup/spurious.c startup/bspidle.S startup/bspdelay.c
>  libbsp_a_SOURCES += startup/cpucounter.c
>  libbsp_a_SOURCES += ../../sparc/shared/startup/bsp_fatal_exit.c
>  libbsp_a_SOURCES += startup/bsp_fatal_halt.c
> diff --git a/c/src/lib/libbsp/sparc/leon3/include/bsp.h b/c/src/lib/libbsp/sparc/leon3/include/bsp.h
> index 5642e14..1397716 100644
> --- a/c/src/lib/libbsp/sparc/leon3/include/bsp.h
> +++ b/c/src/lib/libbsp/sparc/leon3/include/bsp.h
> @@ -140,13 +140,6 @@ void bsp_spurious_initialize( void );
>   */
>  void rtems_bsp_delay(int usecs);
>
> -/* Allocate 8-byte aligned non-freeable pre-malloc() memory. The function
> - * can be called at any time. The work-area will shrink when called before
> - * bsp_work_area_initialize(). malloc() is called to get memory when this
> - * function is called after bsp_work_area_initialize().
> - */
> -void *bsp_early_malloc(int size);
> -
>  /* Interrupt Service Routine (ISR) pointer */
>  typedef void (*bsp_shared_isr)(void *arg);
>
> diff --git a/c/src/lib/libbsp/sparc/shared/amba/ambapp.c b/c/src/lib/libbsp/sparc/shared/amba/ambapp.c
> index dba56c1..e4f1aac 100644
> --- a/c/src/lib/libbsp/sparc/shared/amba/ambapp.c
> +++ b/c/src/lib/libbsp/sparc/shared/amba/ambapp.c
> @@ -23,18 +23,16 @@
>  /* Allocate one AMBA device */
>  static struct ambapp_dev *ambapp_alloc_dev_struct(int dev_type)
>  {
> -  int size = sizeof(struct ambapp_dev);
>    struct ambapp_dev *dev;
> +  size_t size = sizeof(*dev);
>
>    if (dev_type == DEV_APB_SLV)
>      size += sizeof(struct ambapp_apb_info);
>    else
>      size += sizeof(struct ambapp_ahb_info); /* AHB */
> -  dev = (struct ambapp_dev *)bsp_early_malloc(size);
> -  if (dev == NULL)
> -    return NULL;
> -  memset(dev, 0 , size);
> -  dev->dev_type = dev_type;
> +  dev = (struct ambapp_dev *)calloc(1, size);
> +  if (dev != NULL)
> +    dev->dev_type = dev_type;
>    return dev;
>  }
>
> diff --git a/c/src/lib/libbsp/sparc/shared/startup/bspgetworkarea.c b/c/src/lib/libbsp/sparc/shared/startup/bspgetworkarea.c
> index a68d295..b05113d 100644
> --- a/c/src/lib/libbsp/sparc/shared/startup/bspgetworkarea.c
> +++ b/c/src/lib/libbsp/sparc/shared/startup/bspgetworkarea.c
> @@ -20,9 +20,6 @@
>  /* 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
> @@ -34,10 +31,9 @@ void bsp_work_area_initialize(void)
>    #define STACK_SIZE (16 * 1024)
>
>    /* Early dynamic memory allocator is placed just above _end  */
> -  void *work_area_start = (void *)early_mem;
> +  void *work_area_start = (void *)&end;
>    uintptr_t work_area_size  =
> -    (uintptr_t)rdb_start - (uintptr_t)early_mem - STACK_SIZE;
> -  early_mem        = ~0; /* Signal bsp_early_malloc not to be used anymore */
> +    (uintptr_t)rdb_start - (uintptr_t)&end - STACK_SIZE;
>
>    /*
>     *  The following may be helpful in debugging what goes wrong when
> diff --git a/c/src/lib/libbsp/sparc/shared/startup/early_malloc.c b/c/src/lib/libbsp/sparc/shared/startup/early_malloc.c
> deleted file mode 100644
> index 911a7b0..0000000
> --- a/c/src/lib/libbsp/sparc/shared/startup/early_malloc.c
> +++ /dev/null
> @@ -1,47 +0,0 @@
> -/*
> - *  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.org/license/LICENSE.
> - */
> -
> -#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)
> -
> -/* Allocate 8-byte aligned non-freeable pre-malloc() memory. The function
> - * can be called at any time. The work-area will shrink when called before
> - * bsp_work_area_initialize(). malloc() is called to get memory when this function
> - * is called after bsp_work_area_initialize().
> - */
> -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;
> -}
> diff --git a/doc/bsp_howto/init.t b/doc/bsp_howto/init.t
> index 55e1e05..d557df6 100644
> --- a/doc/bsp_howto/init.t
> +++ b/doc/bsp_howto/init.t
> @@ -148,10 +148,6 @@ The @code{boot_card()} routine performs the following functions:
>  @item It sets the command line argument variables
>  for later use by the application.
>
> - at item It invokes the BSP specific routine @code{bsp_start()} which is
> -written in C and thus able to perform more advanced initialization.
> -Often MMU and bus initialization occurs here.
> -
>  @item It invokes the BSP specific routine @code{bsp_work_area_initialize()}
>  which is supposed to initialize the RTEMS Workspace and the C Program Heap.
>  Usually the default implementation in
> @@ -160,6 +156,12 @@ implementations can use @code{bsp_work_area_initialize_default()} or
>  @code{bsp_work_area_initialize_with_table()} available as inline functions from
>  @code{#include <bsp/bootcard.h>}.
>
> + at item It invokes the BSP specific routine @code{bsp_start()} which is
> +written in C and thus able to perform more advanced initialization.
> +Often MMU, bus and interrupt controller initialization occurs here.  Since the
> +RTEMS Workspace and the C Program Heap was already initialized by
> + at code{bsp_work_area_initialize()}, this routine may use @code{malloc()}, etc.
> +
>  @item It invokes the RTEMS directive
>  @code{rtems_initialize_data_structures()} to initialize the RTEMS
>  executive to a state where objects can be created but tasking is not
> @@ -214,30 +216,33 @@ entered, any C++ Global Constructors will be invoked.
>
>  That's it.  We just went through the entire sequence.
>
> - at subsection bsp_start() - BSP Specific Initialization
> + at subsection bsp_work_area_initialize() - BSP Specific Work Area Initialization
>
>  This is the first BSP specific C routine to execute during system
> -initialization.  This routine often performs required fundamental
> -hardware initialization such as setting bus controller registers
> -that do not have a direct impact on whether or not C code can execute.
> -The source code for this routine is usually found in the following
> -file:
> +initialization.  It must initialize the support for allocating memory from the
> +C Program Heap and RTEMS Workspace commonly referred to as the work areas.
> +Many BSPs place the work areas at the end of RAM although this is certainly not
> +a requirement.  Usually the default implementation in
> + at file{c/src/lib/libbsp/shared/bspgetworkarea.c} should be sufficient.  Custom
> +implementations can use @code{bsp_work_area_initialize_default()} or
> + at code{bsp_work_area_initialize_with_table()} available as inline functions from
> + at code{#include <bsp/bootcard.h>}.
>
> - at example
> -c/src/lib/libbsp/CPU/BSP/startup/bspstart.c
> - at end example
> + at subsection bsp_start() - BSP Specific Initialization
>
> -On older BSPs not using @code{boot_card()}'s support for allocating memory
> -to the C Program Heap and RTEMS Workspace, one of the most important
> -functions performed by this routine is determining where the RTEMS
> -Workspace is to be located in memory.  All RTEMS objects and task stacks
> -will be allocated from this Workspace.  The RTEMS Workspace is distinct
> -from the application heap used for @code{malloc()}.  Many BSPs place
> -the RTEMS Workspace area at the end of RAM although this is certainly
> -not a requirement.
> +This is the second BSP specific C routine to execute during system
> +initialization.  It is called right after @code{bsp_work_area_initialize()}.
> +The @code{bsp_start()} routine often performs required fundamental hardware
> +initialization such as setting bus controller registers that do not have a
> +direct impact on whether or not C code can execute.  The interrupt controllers
> +are usually initialized here.  The source code for this routine is usually
> +found in the file @file{c/src/lib/libbsp/$@{CPU@}/$@{BSP@}/startup/bspstart.c}.
> +It is not allowed to create any operating system objects, e.g. RTEMS
> +semaphores.
>
>  After completing execution, this routine returns to the @code{boot_card()}
> -routine.
> +routine.  In case of errors, the initialization should be terminated via
> + at code{bsp_fatal()}.
>
>  @subsection RTEMS Pretasking Callback
>
> --
> 1.8.4.5
>
> _______________________________________________
> devel mailing list
> devel at rtems.org
> http://lists.rtems.org/mailman/listinfo/devel



More information about the devel mailing list