From 47a3cd8f73780bad3eff5135f0eb58e8c98af91d Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Thu, 9 Aug 2012 16:48:00 +0200 Subject: score: Work area initialization API change The work areas (RTEMS work space and C program heap) will be initialized now in a separate step and are no longer part of rtems_initialize_data_structures(). Initialization is performed with tables of Heap_Area entries. This allows usage of scattered memory areas present on various small scale micro-controllers. The sbrk() support API changes also. The bsp_sbrk_init() must now deal with a minimum size for the first memory chunk to take the configured work space size into account. --- c/src/lib/libbsp/shared/bootcard.c | 118 +------------------ c/src/lib/libbsp/shared/bspgetworkarea.c | 54 +-------- c/src/lib/libbsp/shared/bsplibc.c | 8 +- c/src/lib/libbsp/shared/include/bootcard.h | 175 ++++++++++++++++++----------- 4 files changed, 119 insertions(+), 236 deletions(-) (limited to 'c/src/lib/libbsp/shared') diff --git a/c/src/lib/libbsp/shared/bootcard.c b/c/src/lib/libbsp/shared/bootcard.c index 189b463cc0..33ad0ee128 100644 --- a/c/src/lib/libbsp/shared/bootcard.c +++ b/c/src/lib/libbsp/shared/bootcard.c @@ -63,41 +63,6 @@ */ const char *bsp_boot_cmdline; -/* - * These are the prototypes and helper routines which are used - * when the BSP lets the framework handle RAM allocation between - * the RTEMS Workspace and C Program Heap. - */ -static void bootcard_bsp_libc_helper( - void *work_area_start, - uintptr_t work_area_size, - void *heap_start, - uintptr_t heap_size, - uintptr_t sbrk_amount -) -{ - if ( heap_start == BSP_BOOTCARD_HEAP_USES_WORK_AREA ) { - if ( !rtems_configuration_get_unified_work_area() ) { - uintptr_t work_space_size = rtems_configuration_get_work_space_size(); - - heap_start = (char *) work_area_start + work_space_size; - - if (heap_size == BSP_BOOTCARD_HEAP_SIZE_DEFAULT) { - uintptr_t heap_size_default = work_area_size - work_space_size; - - heap_size = heap_size_default; - } - } else { - heap_start = work_area_start; - if (heap_size == BSP_BOOTCARD_HEAP_SIZE_DEFAULT) { - heap_size = work_area_size; - } - } - } - - bsp_libc_init(heap_start, heap_size, sbrk_amount); -} - /* * This is the initialization framework routine that weaves together * calls to RTEMS and the BSP in the proper sequence to initialize @@ -109,12 +74,6 @@ uint32_t boot_card( ) { rtems_interrupt_level bsp_isr_level; - void *work_area_start = NULL; - uintptr_t work_area_size = 0; - void *heap_start = NULL; - uintptr_t heap_size = 0; - uintptr_t sbrk_amount = 0; - uintptr_t work_space_size = 0; uint32_t status = 0; /* @@ -138,74 +97,9 @@ uint32_t boot_card( bsp_start(); /* - * Find out where the block of memory the BSP will use for - * the RTEMS Workspace and the C Program Heap is. + * Initialize the RTEMS Workspace and the C Program Heap. */ - bsp_get_work_area(&work_area_start, &work_area_size, - &heap_start, &heap_size); - -#ifdef CONFIGURE_MALLOC_BSP_SUPPORTS_SBRK - /* This routine may reduce the work area size with the - * option to extend it later via sbrk(). If the application - * was configured w/o CONFIGURE_MALLOC_BSP_SUPPORTS_SBRK then - * omit this step. - */ - if ( rtems_malloc_sbrk_helpers ) { - sbrk_amount = bsp_sbrk_init(work_area_start, &work_area_size); - work_space_size = rtems_configuration_get_work_space_size(); - if ( work_area_size < work_space_size && sbrk_amount > 0 ) { - /* Need to use sbrk right now */ - uintptr_t sbrk_now; - - sbrk_now = (work_space_size - work_area_size) / sbrk_amount; - sbrk( sbrk_now * sbrk_amount ); - } - } -#else - if ( rtems_malloc_sbrk_helpers ) { - printk("Configuration error!\n" - "Application was configured with CONFIGURE_MALLOC_BSP_SUPPORTS_SBRK\n" - "but BSP was configured w/o sbrk support\n"); - status = 1; - bsp_cleanup( status ); - return status; - } -#endif - - /* - * If the user has configured a set of objects which will require more - * workspace than is actually available, print a message indicating - * such and return to the invoking initialization code. - * - * NOTE: Output from printk() may not work at this point on some BSPs. - * - * NOTE: Use cast to (void *) and %p since these are uintptr_t types. - */ - work_space_size = rtems_configuration_get_work_space_size(); - if ( work_area_size <= work_space_size ) { - printk( - "bootcard: work space too big for work area: %p >= %p\n", - (void *) work_space_size, - (void *) work_area_size - ); - status = 1; - bsp_cleanup( status ); - return status; - } - - if ( !rtems_configuration_get_unified_work_area() ) { - rtems_configuration_set_work_space_start( work_area_start ); - } else { - rtems_configuration_set_work_space_start( work_area_start ); - rtems_configuration_set_work_space_size( work_area_size ); - if ( !rtems_configuration_get_stack_allocator_avoids_work_space() ) { - rtems_configuration_set_stack_space_size( 0 ); - } - } - - #if (BSP_DIRTY_MEMORY == 1) - memset( work_area_start, 0xCF, work_area_size ); - #endif + bsp_work_area_initialize(); /* * Initialize RTEMS data structures @@ -216,13 +110,7 @@ uint32_t boot_card( * Initialize the C library for those BSPs using the shared * framework. */ - bootcard_bsp_libc_helper( - work_area_start, - work_area_size, - heap_start, - heap_size, - sbrk_amount - ); + bsp_libc_init(); /* * Let the BSP do any required initialization now that RTEMS diff --git a/c/src/lib/libbsp/shared/bspgetworkarea.c b/c/src/lib/libbsp/shared/bspgetworkarea.c index a2ad2e93ce..4122c9b358 100644 --- a/c/src/lib/libbsp/shared/bspgetworkarea.c +++ b/c/src/lib/libbsp/shared/bspgetworkarea.c @@ -1,25 +1,20 @@ /* - * This routine is an implementation of the bsp_get_work_area() + * This routine is an implementation of the bsp_work_area_initialize() * that can be used by all BSPs following linkcmds conventions * regarding heap, stack, and workspace allocation. * * COPYRIGHT (c) 1989-2008. * On-Line Applications Research Corporation (OAR). * - * Copyright (c) 2011 embedded brains GmbH. + * Copyright (c) 2011-2012 embedded brains GmbH. * * 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. */ -/* #define BSP_GET_WORK_AREA_DEBUG */ - #include #include -#ifdef BSP_GET_WORK_AREA_DEBUG - #include -#endif #ifdef BSP_INTERRUPT_STACK_AT_WORK_AREA_BEGIN #include #endif @@ -32,7 +27,6 @@ * These are provided by the linkcmds for ALL of the BSPs which use this file. */ extern char WorkAreaBase[]; -extern char HeapSize[]; /* * We may get the size information from U-Boot or the linker scripts. @@ -44,17 +38,7 @@ extern char HeapSize[]; extern char RamSize[]; #endif -/* - * This method returns the base address and size of the area which - * is to be allocated between the RTEMS Workspace and the C Program - * Heap. - */ -void bsp_get_work_area( - void **work_area_start, - uintptr_t *work_area_size, - void **heap_start, - uintptr_t *heap_size -) +void bsp_work_area_initialize(void) { uintptr_t work_base = (uintptr_t) WorkAreaBase; uintptr_t ram_end; @@ -70,35 +54,5 @@ void bsp_get_work_area( work_base += Configuration.interrupt_stack_size; #endif - *work_area_start = (void *) work_base; - *work_area_size = ram_end - work_base; - *heap_start = BSP_BOOTCARD_HEAP_USES_WORK_AREA; - *heap_size = (uintptr_t) HeapSize; - - /* - * The following may be helpful in debugging what goes wrong when - * you are allocating the Work Area in a new BSP. - */ - #ifdef BSP_GET_WORK_AREA_DEBUG - { - void *sp = __builtin_frame_address(0); - void *end = *work_area_start + *work_area_size; - printk( - "work_area_start = 0x%p\n" - "work_area_size = %d 0x%08x\n" - "end = 0x%p\n" - "heap_start = 0x%p\n" - "heap_size = %d\n" - "current stack pointer = 0x%p%s\n", - *work_area_start, - *work_area_size, /* decimal */ - *work_area_size, /* hexadecimal */ - end, - *heap_start, - *heap_size, - sp, - ((sp >= *work_area_start && sp <= end) ? " OVERLAPS!" : "") - ); - } - #endif + bsp_work_area_initialize_default( (void *) work_base, ram_end - work_base ); } diff --git a/c/src/lib/libbsp/shared/bsplibc.c b/c/src/lib/libbsp/shared/bsplibc.c index 90ba6132b1..181dcff303 100644 --- a/c/src/lib/libbsp/shared/bsplibc.c +++ b/c/src/lib/libbsp/shared/bsplibc.c @@ -9,14 +9,8 @@ #include -void bsp_libc_init( - void *heap_begin, - uintptr_t heap_size, - size_t sbrk_amount -) +void bsp_libc_init(void) { - RTEMS_Malloc_Initialize( heap_begin, heap_size, sbrk_amount ); - /* * Init the RTEMS libio facility to provide UNIX-like system * calls for use by newlib (ie: provide open, close, etc) diff --git a/c/src/lib/libbsp/shared/include/bootcard.h b/c/src/lib/libbsp/shared/include/bootcard.h index 69717b2903..751e77aa77 100644 --- a/c/src/lib/libbsp/shared/include/bootcard.h +++ b/c/src/lib/libbsp/shared/include/bootcard.h @@ -7,12 +7,13 @@ */ /* - * Copyright (c) 2008 - * Embedded Brains GmbH - * Obere Lagerstr. 30 - * D-82178 Puchheim - * Germany - * rtems@embedded-brains.de + * Copyright (c) 2008-2012 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Obere Lagerstr. 30 + * 82178 Puchheim + * Germany + * * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at @@ -25,22 +26,13 @@ * @brief Board support package dependent code. */ -/** - * @defgroup bsp_bootcard Bootcard - * - * @ingroup bsp_kit - * - * @brief Standard system startup. - * - * @{ - */ - #ifndef LIBBSP_SHARED_BOOTCARD_H #define LIBBSP_SHARED_BOOTCARD_H -#include -#include -#include +#include + +#include +#include #include @@ -48,6 +40,16 @@ extern "C" { #endif /* __cplusplus */ +/** + * @defgroup bsp_bootcard Bootcard + * + * @ingroup bsp_kit + * + * @brief Standard system startup. + * + * @{ + */ + /** * @brief Global pointer to the command line of boot_card(). */ @@ -65,45 +67,6 @@ void bsp_cleanup(uint32_t status); void bsp_reset(void); -/** - * @brief Should be used as the heap begin address in bsp_get_work_area() if - * the heap area is contained in the work area. - */ -#define BSP_BOOTCARD_HEAP_USES_WORK_AREA NULL - -/** - * @brief Should be used to request the default heap size in bsp_get_work_area(). - * - * In case that the heap area is contained in the work area this heap size - * value indicates that the area outside the work space should be used as heap - * space. - */ -#define BSP_BOOTCARD_HEAP_SIZE_DEFAULT 0 - -void bsp_get_work_area( - void **work_area_begin, - uintptr_t *work_area_size, - void **heap_begin, - uintptr_t *heap_size -); - -/** - * @brief Gives the BSP a chance to reduce the work area size with sbrk() adding more later. - * - * bsp_sbrk_init() may reduce the work area size passed in. The routine - * returns the 'sbrk_amount' to be used when extending the heap. - * Note that the return value may be zero. - * - */ - -#ifdef CONFIGURE_MALLOC_BSP_SUPPORTS_SBRK -uintptr_t bsp_sbrk_init( - void *work_area_begin, - uintptr_t *work_area_size_p -); -#endif - - /** * @brief Standard system initialization procedure. * @@ -120,11 +83,10 @@ uintptr_t bsp_sbrk_init( * - disable interrupts, interrupts will be enabled during the first context * switch * - bsp_start() - more advanced initialization - * - obtain information on BSP memory via bsp_get_work_area() and allocate - * RTEMS Workspace + * - bsp_work_area_initialize() - initialize the RTEMS Workspace and the C + * Program Heap * - rtems_initialize_data_structures() - * - allocate memory for C Program Heap - * - initialize C Library and C Program Heap + * - initialize C Library * - bsp_pretasking_hook() * - if defined( RTEMS_DEBUG ) * - rtems_debug_enable( RTEMS_DEBUG_ALL_MASK ) @@ -147,9 +109,94 @@ uintptr_t bsp_sbrk_init( */ uint32_t boot_card(const char *cmdline); -/** @} */ +#ifdef CONFIGURE_MALLOC_BSP_SUPPORTS_SBRK + /** + * @brief Gives the BSP a chance to reduce the work area size with sbrk() + * adding more later. + * + * bsp_sbrk_init() may reduce the work area size passed in. The routine + * returns the 'sbrk_amount' to be used when extending the heap. Note that + * the return value may be zero. + * + * In case the @a area size is altered, then the remaining size of the + * @a area must be greater than or equal to @a min_size. + */ + ptrdiff_t bsp_sbrk_init(Heap_Area *area, uintptr_t min_size); +#endif -void bsp_libc_init(void *heap_begin, uintptr_t heap_size, size_t sbrk_amount); +static inline void bsp_work_area_initialize_default( + void *area_begin, + uintptr_t area_size +) +{ + Heap_Area area = { + .begin = area_begin, + .size = area_size + }; + + #if BSP_DIRTY_MEMORY == 1 + memset(area.begin, 0xCF, area.size); + #endif + + #ifdef CONFIGURE_MALLOC_BSP_SUPPORTS_SBRK + { + uintptr_t overhead = _Heap_Area_overhead(CPU_HEAP_ALIGNMENT); + uintptr_t work_space_size = rtems_configuration_get_work_space_size(); + ptrdiff_t sbrk_amount = bsp_sbrk_init( + &area, + work_space_size + + overhead + + (rtems_configuration_get_unified_work_area() ? 0 : overhead) + ); + + rtems_heap_set_sbrk_amount(sbrk_amount); + } + #endif + + /* + * The following may be helpful in debugging what goes wrong when + * you are allocating the Work Area in a new BSP. + */ + #ifdef BSP_GET_WORK_AREA_DEBUG + { + void *sp = __builtin_frame_address(0); + void *end = (char *) area.begin + area.size; + printk( + "work_area_start = 0x%p\n" + "work_area_size = %lu 0x%08lx\n" + "end = 0x%p\n" + "current stack pointer = 0x%p%s\n", + area.begin, + (unsigned long) area.size, /* decimal */ + (unsigned long) area.size, /* hexadecimal */ + end, + sp, + (uintptr_t) sp >= (uintptr_t) area.begin + && (uintptr_t) sp <= (uintptr_t) end ? + " OVERLAPS!" : "" + ); + } + #endif + + _Workspace_Handler_initialization(&area, 1, NULL); + + #ifdef BSP_GET_WORK_AREA_DEBUG + printk( + "heap_start = 0x%p\n" + "heap_size = %lu\n", + area.begin, + (unsigned long) area.size + ); + #endif + + RTEMS_Malloc_Initialize(&area, 1, NULL); +} + +void bsp_work_area_initialize(void); + +void bsp_libc_init(void); + +/** @} */ #ifdef __cplusplus } -- cgit v1.2.3