bsps: Call bsp_work_area_initialize() early

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.
This commit is contained in:
Sebastian Huber
2015-12-09 08:05:57 +01:00
parent 938ef78cc4
commit 37030e38c6
19 changed files with 59 additions and 125 deletions

View File

@@ -94,6 +94,7 @@ libbsp_a_SOURCES += ../../shared/bspclean.c
libbsp_a_SOURCES += ../../shared/bspgetworkarea.c
libbsp_a_SOURCES += ../../shared/bsplibc.c
libbsp_a_SOURCES += ../../shared/bsppost.c
libbsp_a_SOURCES += ../../shared/bsppretaskinghook.c
libbsp_a_SOURCES += ../../shared/bsppredriverhook.c
libbsp_a_SOURCES += ../../shared/gnatinstallhandler.c
libbsp_a_SOURCES += ../../shared/sbrk.c

View File

@@ -42,7 +42,7 @@ LINKER_SYMBOL( lpc176x_region_heap_1_end );
extern Heap_Control *RTEMS_Malloc_Heap;
#endif
void bsp_pretasking_hook( void )
static void heap_extend( void )
{
#ifdef LPC176X_HEAP_EXTEND
_Heap_Extend( RTEMS_Malloc_Heap,
@@ -86,4 +86,6 @@ void bsp_start( void )
/* DMA */
lpc176x_dma_initialize();
}
heap_extend();
}

View File

@@ -96,6 +96,7 @@ libbsp_a_SOURCES += ../../shared/bootcard.c \
../../shared/bspgetworkarea.c \
../../shared/bsplibc.c \
../../shared/bsppost.c \
../../shared/bsppretaskinghook.c \
../../shared/bsppredriverhook.c \
../../shared/gnatinstallhandler.c \
../../shared/sbrk.c \

View File

@@ -43,7 +43,7 @@
extern Heap_Control *RTEMS_Malloc_Heap;
#endif
void bsp_pretasking_hook(void)
static void heap_extend(void)
{
#ifdef LPC24XX_HEAP_EXTEND
_Heap_Extend(
@@ -91,4 +91,6 @@ void bsp_start(void)
/* DMA */
lpc24xx_dma_initialize();
heap_extend();
}

View File

@@ -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' */

View File

@@ -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 );
}

View File

@@ -57,11 +57,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
*/

View File

@@ -74,16 +74,16 @@ void boot_card(
bsp_boot_cmdline = cmdline;
/*
* Invoke Board Support Package initialization routine written in C.
*/
bsp_start();
/*
* Initialize the RTEMS Workspace and the C Program Heap.
*/
bsp_work_area_initialize();
/*
* Invoke Board Support Package initialization routine written in C.
*/
bsp_start();
/*
* Initialize RTEMS data structures
*/

View File

@@ -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()

View File

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

View File

@@ -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);

View File

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

View File

@@ -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);

View File

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

View File

@@ -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);

View File

@@ -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;
}

View File

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

View File

@@ -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;
}

View File

@@ -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.
@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>}.
@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
@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.
@subsection bsp_start() - BSP Specific Initialization
@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
@file{c/src/lib/libbsp/shared/bspgetworkarea.c} should be sufficient. Custom
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>}.
@example
c/src/lib/libbsp/CPU/BSP/startup/bspstart.c
@end example
@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
@code{bsp_fatal()}.
@subsection RTEMS Pretasking Callback