forked from Imagelibrary/rtems
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:
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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' */
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user