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/arm/gba/startup/bspgetworkarea.c | 20 +-- .../lib/libbsp/i386/pc386/startup/bspgetworkarea.c | 32 +--- .../libbsp/powerpc/shared/startup/bspgetworkarea.c | 51 +----- c/src/lib/libbsp/powerpc/shared/startup/sbrk.c | 47 +++--- .../libbsp/powerpc/tqm8xx/startup/bspgetworkarea.c | 27 ++-- 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 +++++++++++++-------- c/src/lib/libbsp/sparc/erc32/include/bsp.h | 4 +- c/src/lib/libbsp/sparc/leon2/include/bsp.h | 4 +- c/src/lib/libbsp/sparc/leon3/include/bsp.h | 4 +- c/src/lib/libbsp/sparc/shared/bspgetworkarea.c | 27 ++-- .../lib/libbsp/sparc/shared/startup/early_malloc.c | 4 +- c/src/lib/libbsp/sparc64/niagara/Makefile.am | 2 +- .../libbsp/sparc64/shared/startup/bspgetworkarea.c | 91 ----------- c/src/lib/libbsp/sparc64/usiii/Makefile.am | 2 +- cpukit/libcsupport/Makefile.am | 4 +- cpukit/libcsupport/include/rtems/libcsupport.h | 6 - cpukit/libcsupport/include/rtems/malloc.h | 45 ++++-- cpukit/libcsupport/src/malloc.c | 3 +- cpukit/libcsupport/src/malloc_initialize.c | 115 ++++++-------- cpukit/libcsupport/src/malloc_p.h | 5 - cpukit/libcsupport/src/malloc_sbrk_helpers.c | 108 ------------- cpukit/libcsupport/src/mallocinfo.c | 6 +- .../libcsupport/src/rtems_heap_extend_via_sbrk.c | 58 +++++++ cpukit/libcsupport/src/rtems_heap_null_extend.c | 27 ++++ cpukit/libmisc/monitor/mon-config.c | 1 - cpukit/sapi/include/confdefs.h | 9 +- cpukit/sapi/include/rtems/config.h | 10 -- cpukit/sapi/src/exinit.c | 6 - cpukit/score/include/rtems/score/heap.h | 30 ++++ cpukit/score/include/rtems/score/interr.h | 3 +- cpukit/score/include/rtems/score/wkspace.h | 14 +- cpukit/score/inline/rtems/score/heap.inl | 14 -- cpukit/score/src/wkspace.c | 67 ++++++-- doc/bsp_howto/init.t | 58 +++---- testsuites/libtests/malloc04/init.c | 43 +++-- testsuites/psxtests/psxfatal_support/init.c | 9 +- testsuites/sptests/Makefile.am | 2 +- testsuites/sptests/configure.ac | 1 - testsuites/sptests/spfatal06/testcase.h | 11 +- testsuites/sptests/spfatal07/testcase.h | 6 +- testsuites/sptests/spfatal08/testcase.h | 14 +- testsuites/sptests/spfatal09/testcase.h | 11 +- testsuites/sptests/spfatal12/testcase.h | 5 +- testsuites/sptests/spfatal21/Makefile.am | 21 --- testsuites/sptests/spfatal21/spfatal21.doc | 19 --- testsuites/sptests/spfatal21/spfatal21.scn | 3 - testsuites/sptests/spfatal21/testcase.h | 34 ---- testsuites/sptests/spfatal_support/init.c | 9 +- 51 files changed, 543 insertions(+), 904 deletions(-) delete mode 100644 c/src/lib/libbsp/sparc64/shared/startup/bspgetworkarea.c delete mode 100644 cpukit/libcsupport/src/malloc_sbrk_helpers.c create mode 100644 cpukit/libcsupport/src/rtems_heap_extend_via_sbrk.c create mode 100644 cpukit/libcsupport/src/rtems_heap_null_extend.c delete mode 100644 testsuites/sptests/spfatal21/Makefile.am delete mode 100644 testsuites/sptests/spfatal21/spfatal21.doc delete mode 100644 testsuites/sptests/spfatal21/spfatal21.scn delete mode 100644 testsuites/sptests/spfatal21/testcase.h diff --git a/c/src/lib/libbsp/arm/gba/startup/bspgetworkarea.c b/c/src/lib/libbsp/arm/gba/startup/bspgetworkarea.c index abce92f13b..d1c06b14f7 100644 --- a/c/src/lib/libbsp/arm/gba/startup/bspgetworkarea.c +++ b/c/src/lib/libbsp/arm/gba/startup/bspgetworkarea.c @@ -11,21 +11,11 @@ extern void _end; extern void __heap_limit; -/* - * 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) { - *work_area_start = (void *)&_end; - *work_area_size = (uintptr_t)&__heap_limit - (uintptr_t)&_end; - *heap_start = BSP_BOOTCARD_HEAP_USES_WORK_AREA; - *heap_size = BSP_BOOTCARD_HEAP_SIZE_DEFAULT; + void *area_start = (void *)&_end; + uintptr_t area_size = (uintptr_t)&__heap_limit - (uintptr_t)&_end; + + bsp_work_area_initialize_default( area_start, area_size ); } diff --git a/c/src/lib/libbsp/i386/pc386/startup/bspgetworkarea.c b/c/src/lib/libbsp/i386/pc386/startup/bspgetworkarea.c index 8668d45467..f6ff1391ec 100644 --- a/c/src/lib/libbsp/i386/pc386/startup/bspgetworkarea.c +++ b/c/src/lib/libbsp/i386/pc386/startup/bspgetworkarea.c @@ -1,5 +1,5 @@ /* - * 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 m68k BSPs following linkcmds conventions * regarding heap, stack, and workspace allocation. * @@ -120,30 +120,10 @@ void bsp_size_memory(void) bsp_mem_size = topAddr; } -/* - * 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) { - *work_area_start = (void *) rtemsWorkAreaStart; - *work_area_size = (uintptr_t) bsp_mem_size - (uintptr_t) rtemsWorkAreaStart; - *heap_start = BSP_BOOTCARD_HEAP_USES_WORK_AREA; - *heap_size = (uintptr_t) HeapSize; - - #ifdef BSP_GET_WORK_AREA_DEBUG - printk( "bsp_mem_size = 0x%08x\n", bsp_mem_size ); - printk( "rtemsWorkAreaStart = 0x%08x\n", rtemsWorkAreaStart ); - printk( "WorkArea Base = %p\n", *work_area_start ); - printk( "WorkArea Size = 0x%08x\n", *work_area_size ); - printk( "C Program Heap Base = %p\n", *heap_start ); - printk( "C Program Heap Size = 0x%08x\n", *heap_size ); - printk( "End of WorkArea = %p\n", *work_area_start + *work_area_size ); - #endif + void *area_start = (void *) rtemsWorkAreaStart; + uintptr_t work_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/powerpc/shared/startup/bspgetworkarea.c b/c/src/lib/libbsp/powerpc/shared/startup/bspgetworkarea.c index 174cf68df1..02d47c8b98 100644 --- a/c/src/lib/libbsp/powerpc/shared/startup/bspgetworkarea.c +++ b/c/src/lib/libbsp/powerpc/shared/startup/bspgetworkarea.c @@ -4,28 +4,12 @@ * http://www.rtems.com/license/LICENSE. */ -/* #define BSP_GET_WORK_AREA_DEBUG */ - #include #include -#include -#ifdef BSP_GET_WORK_AREA_DEBUG - #include -#endif extern void *__rtems_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 - * 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_size; uintptr_t work_area; @@ -34,36 +18,5 @@ void bsp_get_work_area( rtems_configuration_get_interrupt_stack_size(); work_size = (uintptr_t)BSP_mem_size - work_area; - *work_area_start = (void *)work_area, - *work_area_size = work_size; - *heap_start = BSP_BOOTCARD_HEAP_USES_WORK_AREA; - *heap_size = BSP_BOOTCARD_HEAP_SIZE_DEFAULT; - - /* - * 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_area, work_size); } - diff --git a/c/src/lib/libbsp/powerpc/shared/startup/sbrk.c b/c/src/lib/libbsp/powerpc/shared/startup/sbrk.c index 35ce1f4f06..cd1867d93a 100644 --- a/c/src/lib/libbsp/powerpc/shared/startup/sbrk.c +++ b/c/src/lib/libbsp/powerpc/shared/startup/sbrk.c @@ -61,15 +61,15 @@ * for module code. */ -#include - -#include #include -#include #include -static void * remaining_start=(void*)-1LL; -static uintptr_t remaining_size=0; +#include + +#define INVALID_REMAINING_START ((uintptr_t) -1) + +static uintptr_t remaining_start = INVALID_REMAINING_START; +static uintptr_t remaining_size = 0; /* App. may provide a value by defining the BSP_sbrk_policy * variable. @@ -81,24 +81,24 @@ static uintptr_t remaining_size=0; */ extern uintptr_t BSP_sbrk_policy __attribute__((weak)); -#define LIMIT_32M ((void*)0x02000000) +#define LIMIT_32M 0x02000000 -uintptr_t bsp_sbrk_init( - void *heap_start, - uintptr_t *heap_size_p -) +ptrdiff_t bsp_sbrk_init(Heap_Area *area, uintptr_t min_size) { - uintptr_t rval=0; + uintptr_t rval = 0; uintptr_t policy; + uintptr_t remaining_end; - remaining_start = heap_start; - remaining_size = *heap_size_p; + remaining_start = (uintptr_t) area->begin; + remaining_size = area->size; + remaining_end = remaining_start + remaining_size; if (remaining_start < LIMIT_32M && - remaining_start + remaining_size > LIMIT_32M) { + remaining_end > LIMIT_32M && + min_size <= LIMIT_32M - remaining_start) { /* clip at LIMIT_32M */ - rval = remaining_start + remaining_size - LIMIT_32M; - *heap_size_p = LIMIT_32M - remaining_start; + rval = remaining_end - LIMIT_32M; + area->size = LIMIT_32M - remaining_start; remaining_start = LIMIT_32M; remaining_size = rval; } @@ -106,8 +106,8 @@ uintptr_t bsp_sbrk_init( policy = (0 == &BSP_sbrk_policy ? (uintptr_t)(-1) : BSP_sbrk_policy); switch ( policy ) { case (uintptr_t)(-1): - *heap_size_p += rval; - remaining_start = heap_start + *heap_size_p; + area->size += rval; + remaining_start = (uintptr_t) area->begin + area->size; remaining_size = 0; break; @@ -121,7 +121,7 @@ uintptr_t bsp_sbrk_init( break; } - return rval; + return (ptrdiff_t) (rval <= PTRDIFF_MAX ? rval : rval / 2); } /* @@ -129,14 +129,13 @@ uintptr_t bsp_sbrk_init( * should just use the default implementation in this file. */ void *sbrk(ptrdiff_t incr) __attribute__ (( weak, alias("bsp_sbrk") )); -void *bsp_sbrk(ptrdiff_t incr) +static void *bsp_sbrk(ptrdiff_t incr) { void *rval=(void*)-1; - /* FIXME: BEWARE if size >2G */ - if ( remaining_start != (void*)-1LL && incr <= remaining_size) { + if ( remaining_start != INVALID_REMAINING_START && incr <= remaining_size) { remaining_size-=incr; - rval = remaining_start; + rval = (void *) remaining_start; remaining_start += incr; } else { errno = ENOMEM; diff --git a/c/src/lib/libbsp/powerpc/tqm8xx/startup/bspgetworkarea.c b/c/src/lib/libbsp/powerpc/tqm8xx/startup/bspgetworkarea.c index bd06b70fdd..d9521896f5 100644 --- a/c/src/lib/libbsp/powerpc/tqm8xx/startup/bspgetworkarea.c +++ b/c/src/lib/libbsp/powerpc/tqm8xx/startup/bspgetworkarea.c @@ -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 @@ -24,17 +25,11 @@ #include #include -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) { char *ram_end = (char *) (TQM_BD_INFO.sdram_size - (uint32_t)TopRamReserved); + void *area_start = bsp_work_area_start; + uintptr_t area_size = (uintptr_t) ram_end - (uintptr_t) bsp_work_area_start; - *work_area_start = bsp_work_area_start; - *work_area_size = ram_end - bsp_work_area_start; - *heap_start = BSP_BOOTCARD_HEAP_USES_WORK_AREA; - *heap_size = BSP_BOOTCARD_HEAP_SIZE_DEFAULT; + bsp_work_area_initialize_default( area_start, area_size ); } 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 } diff --git a/c/src/lib/libbsp/sparc/erc32/include/bsp.h b/c/src/lib/libbsp/sparc/erc32/include/bsp.h index 879e7144e0..26d4d2fc27 100644 --- a/c/src/lib/libbsp/sparc/erc32/include/bsp.h +++ b/c/src/lib/libbsp/sparc/erc32/include/bsp.h @@ -81,8 +81,8 @@ 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_get_work_area(). malloc() is called to get memory when this function - * is called after bsp_get_work_area(). + * 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); diff --git a/c/src/lib/libbsp/sparc/leon2/include/bsp.h b/c/src/lib/libbsp/sparc/leon2/include/bsp.h index e96a63ee90..dbefc347f7 100644 --- a/c/src/lib/libbsp/sparc/leon2/include/bsp.h +++ b/c/src/lib/libbsp/sparc/leon2/include/bsp.h @@ -101,8 +101,8 @@ 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_get_work_area(). malloc() is called to get memory when this function - * is called after bsp_get_work_area(). + * 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); diff --git a/c/src/lib/libbsp/sparc/leon3/include/bsp.h b/c/src/lib/libbsp/sparc/leon3/include/bsp.h index d883064660..31e527eb21 100644 --- a/c/src/lib/libbsp/sparc/leon3/include/bsp.h +++ b/c/src/lib/libbsp/sparc/leon3/include/bsp.h @@ -114,8 +114,8 @@ 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_get_work_area(). malloc() is called to get memory when this function - * is called after bsp_get_work_area(). + * 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); diff --git a/c/src/lib/libbsp/sparc/shared/bspgetworkarea.c b/c/src/lib/libbsp/sparc/shared/bspgetworkarea.c index 45d3d0ed87..d799800d61 100644 --- a/c/src/lib/libbsp/sparc/shared/bspgetworkarea.c +++ b/c/src/lib/libbsp/sparc/shared/bspgetworkarea.c @@ -28,24 +28,17 @@ unsigned int early_mem = (unsigned int)&end; * 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) { /* must be identical to STACK_SIZE in start.S */ #define STACK_SIZE (16 * 1024) /* 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; + void *work_area_start = (void *)early_mem; + 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 */ - *heap_start = BSP_BOOTCARD_HEAP_USES_WORK_AREA; - *heap_size = BSP_BOOTCARD_HEAP_SIZE_DEFAULT; - /* * The following may be helpful in debugging what goes wrong when * you are allocating the Work Area in a new BSP. @@ -58,19 +51,17 @@ void bsp_get_work_area( "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 */ + work_area_start, + work_area_size, /* decimal */ + work_area_size, /* hexadecimal */ end, - *heap_start, - *heap_size, sp, ((sp >= *work_area_start && sp <= end) ? " OVERLAPS!" : "") ); printk( "rdb_start = 0x%08x\n", rdb_start ); } #endif + + bsp_work_area_initialize_default(work_area_start, work_area_size); } diff --git a/c/src/lib/libbsp/sparc/shared/startup/early_malloc.c b/c/src/lib/libbsp/sparc/shared/startup/early_malloc.c index 1f968da206..dc89fad04a 100644 --- a/c/src/lib/libbsp/sparc/shared/startup/early_malloc.c +++ b/c/src/lib/libbsp/sparc/shared/startup/early_malloc.c @@ -25,8 +25,8 @@ extern unsigned int early_mem; /* 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_get_work_area(). malloc() is called to get memory when this function - * is called after bsp_get_work_area(). + * 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) { diff --git a/c/src/lib/libbsp/sparc64/niagara/Makefile.am b/c/src/lib/libbsp/sparc64/niagara/Makefile.am index 089649d0e6..c251beed44 100644 --- a/c/src/lib/libbsp/sparc64/niagara/Makefile.am +++ b/c/src/lib/libbsp/sparc64/niagara/Makefile.am @@ -42,7 +42,7 @@ startup_SOURCES = ../../shared/bspclean.c ../../shared/bsplibc.c \ ../../shared/bsppredriverhook.c ../../shared/bsppretaskinghook.c \ ../../shared/bsppost.c \ ../../shared/bootcard.c ../../shared/sbrk.c \ - ../shared/startup/bspgetworkarea.c \ + ../../shared/bspgetworkarea.c \ ../shared/startup/bspstart.c \ ../shared/startup/setvec.c \ ../../shared/gnatinstallhandler.c \ diff --git a/c/src/lib/libbsp/sparc64/shared/startup/bspgetworkarea.c b/c/src/lib/libbsp/sparc64/shared/startup/bspgetworkarea.c deleted file mode 100644 index 84f5777573..0000000000 --- a/c/src/lib/libbsp/sparc64/shared/startup/bspgetworkarea.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * This routine is an implementation of the bsp_get_work_area() - * 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). - * - * 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. - */ - -#include -#include -#ifdef BSP_GET_WORK_AREA_DEBUG - #include -#endif - -/* - * These are provided by the linkcmds for ALL of the BSPs which use this file. - */ -extern char WorkAreaBase[]; -extern char HeapSize[]; -extern char HeapBase[]; - - -/* - * We may get the size information from U-Boot or the linker scripts. - */ -#ifdef HAS_UBOOT - extern bd_t bsp_uboot_board_info; -#else - extern char RamBase[]; - extern char RamSize[]; -#endif /* HAS_UBOOT */ - -/* - * 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 -) -{ - uintptr_t ram_end; - - #ifdef HAS_UBOOT - ram_end = (uintptr_t) bsp_uboot_board_info.bi_memstart + - bsp_uboot_board_info.bi_memsize; - #else - ram_end = (uintptr_t)RamBase + (uintptr_t)RamSize; - #endif - - *work_area_start = WorkAreaBase; - *work_area_size = (uintptr_t) HeapSize; - *heap_start = (void*) HeapBase; - *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( - "bsp_get_work_area\n\r" - "work_area_start = 0x%p\n\r" - "work_area_size = %d 0x%08x\n\r" - "end = 0x%p\n\r" - "heap_start = 0x%p\n\r" - "heap_size = %d\n\r" - "current stack pointer = 0x%p%s\n\r", - *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 -} diff --git a/c/src/lib/libbsp/sparc64/usiii/Makefile.am b/c/src/lib/libbsp/sparc64/usiii/Makefile.am index 6c169e0e64..10c0b35e29 100644 --- a/c/src/lib/libbsp/sparc64/usiii/Makefile.am +++ b/c/src/lib/libbsp/sparc64/usiii/Makefile.am @@ -88,7 +88,7 @@ startup_SOURCES = ../../shared/bspclean.c ../../shared/bsplibc.c \ ../../shared/bspstart.c ../../shared/bsppretaskinghook.c \ ../../shared/bsppost.c \ ../../shared/bootcard.c ../../shared/sbrk.c \ - ../shared/startup/bspgetworkarea.c \ + ../../shared/bspgetworkarea.c \ ../shared/startup/bsppredriverhook.c \ ../shared/startup/setvec.c \ ../../shared/gnatinstallhandler.c \ diff --git a/cpukit/libcsupport/Makefile.am b/cpukit/libcsupport/Makefile.am index 04d2455dfd..703ef60199 100644 --- a/cpukit/libcsupport/Makefile.am +++ b/cpukit/libcsupport/Makefile.am @@ -98,8 +98,10 @@ MALLOC_C_FILES = src/malloc_initialize.c src/calloc.c src/malloc.c \ src/mallocinfo.c src/malloc_walk.c src/malloc_get_statistics.c \ src/malloc_report_statistics.c src/malloc_report_statistics_plugin.c \ src/malloc_statistics_helpers.c src/posix_memalign.c \ - src/rtems_memalign.c src/malloc_deferred.c src/malloc_sbrk_helpers.c \ + src/rtems_memalign.c src/malloc_deferred.c \ src/malloc_dirtier.c src/malloc_p.h src/rtems_malloc.c \ + src/rtems_heap_extend_via_sbrk.c \ + src/rtems_heap_null_extend.c \ src/rtems_heap_extend.c \ src/rtems_heap_greedy.c diff --git a/cpukit/libcsupport/include/rtems/libcsupport.h b/cpukit/libcsupport/include/rtems/libcsupport.h index d2640476df..919b41eea3 100644 --- a/cpukit/libcsupport/include/rtems/libcsupport.h +++ b/cpukit/libcsupport/include/rtems/libcsupport.h @@ -27,12 +27,6 @@ extern "C" { #endif -void RTEMS_Malloc_Initialize( - void *heap_begin, - uintptr_t heap_size, - size_t sbrk_amount -); - extern void malloc_dump(void); extern bool malloc_walk(int source, bool printf_enabled); void malloc_set_heap_pointer(Heap_Control *new_heap); diff --git a/cpukit/libcsupport/include/rtems/malloc.h b/cpukit/libcsupport/include/rtems/malloc.h index d195b9fef1..9d475d33b1 100644 --- a/cpukit/libcsupport/include/rtems/malloc.h +++ b/cpukit/libcsupport/include/rtems/malloc.h @@ -26,6 +26,20 @@ extern "C" { #endif +/** + * @brief C program heap control. + * + * This is the pointer to the heap control structure used to manage the C + * program heap. + */ +extern Heap_Control *RTEMS_Malloc_Heap; + +void RTEMS_Malloc_Initialize( + const Heap_Area *areas, + size_t area_count, + Heap_Initialization_or_extend_handler extend +); + /* * Malloc Statistics Structure */ @@ -54,16 +68,29 @@ extern rtems_malloc_statistics_functions_t rtems_malloc_statistics_helpers_table; extern rtems_malloc_statistics_functions_t *rtems_malloc_statistics_helpers; -/* - * Malloc Heap Extension (sbrk) plugin - */ -typedef struct { - void *(*initialize)(void *, size_t); - void *(*extend)(size_t); -} rtems_malloc_sbrk_functions_t; +extern ptrdiff_t RTEMS_Malloc_Sbrk_amount; + +static inline void rtems_heap_set_sbrk_amount( ptrdiff_t sbrk_amount ) +{ + RTEMS_Malloc_Sbrk_amount = sbrk_amount; +} + +typedef void *(*rtems_heap_extend_handler)( + Heap_Control *heap, + size_t alloc_size +); + +void *rtems_heap_extend_via_sbrk( + Heap_Control *heap, + size_t alloc_size +); + +void *rtems_heap_null_extend( + Heap_Control *heap, + size_t alloc_size +); -extern rtems_malloc_sbrk_functions_t rtems_malloc_sbrk_helpers_table; -extern rtems_malloc_sbrk_functions_t *rtems_malloc_sbrk_helpers; +extern const rtems_heap_extend_handler rtems_malloc_extend_handler; /* * Malloc Plugin to Dirty Memory at Allocation Time diff --git a/cpukit/libcsupport/src/malloc.c b/cpukit/libcsupport/src/malloc.c index 0fff1d011c..dea6f8f3c7 100644 --- a/cpukit/libcsupport/src/malloc.c +++ b/cpukit/libcsupport/src/malloc.c @@ -55,8 +55,7 @@ void *malloc( return_this = _Protected_heap_Allocate( RTEMS_Malloc_Heap, size ); if ( !return_this ) { - if (rtems_malloc_sbrk_helpers) - return_this = (*rtems_malloc_sbrk_helpers->extend)( size ); + return_this = (*rtems_malloc_extend_handler)( RTEMS_Malloc_Heap, size ); if ( !return_this ) { errno = ENOMEM; return (void *) 0; diff --git a/cpukit/libcsupport/src/malloc_initialize.c b/cpukit/libcsupport/src/malloc_initialize.c index fccddd1368..06263bda82 100644 --- a/cpukit/libcsupport/src/malloc_initialize.c +++ b/cpukit/libcsupport/src/malloc_initialize.c @@ -1,11 +1,11 @@ /** * @file * - * @brief Malloc initialization implementation. + * @brief RTEMS_Malloc_Initialize() implementation. */ /* - * COPYRIGHT (c) 1989-2007. + * COPYRIGHT (c) 1989-2012. * On-Line Applications Research Corporation (OAR). * * The license and distribution terms for this file may be @@ -14,93 +14,68 @@ */ #if HAVE_CONFIG_H -#include "config.h" + #include "config.h" #endif -#include #include -#include + #include "malloc_p.h" -/* FIXME: Dummy function */ -#ifndef RTEMS_NEWLIB -void RTEMS_Malloc_Initialize( - void *heap_begin, - uintptr_t heap_size, - size_t sbrk_amount -) -{ -} -#else +#ifdef RTEMS_NEWLIB rtems_malloc_statistics_t rtems_malloc_statistics; void RTEMS_Malloc_Initialize( - void *heap_begin, - uintptr_t heap_size, - size_t sbrk_amount + const Heap_Area *areas, + size_t area_count, + Heap_Initialization_or_extend_handler extend ) { - bool separate_areas = !rtems_configuration_get_unified_work_area(); - /* - * If configured, initialize the statistics support - */ - if ( rtems_malloc_statistics_helpers != NULL ) { - (*rtems_malloc_statistics_helpers->initialize)(); - } + Heap_Control *heap = RTEMS_Malloc_Heap; - /* - * Initialize the optional sbrk support for extending the heap - */ - if ( rtems_malloc_sbrk_helpers != NULL ) { - void *new_heap_begin = (*rtems_malloc_sbrk_helpers->initialize)( - heap_begin, - sbrk_amount - ); - - heap_size -= (uintptr_t) new_heap_begin - (uintptr_t) heap_begin; - heap_begin = new_heap_begin; - } + if ( !rtems_configuration_get_unified_work_area() ) { + Heap_Initialization_or_extend_handler init_or_extend = _Heap_Initialize; + uintptr_t page_size = CPU_HEAP_ALIGNMENT; + size_t i; - /* - * If this system is configured to use the same heap for - * the RTEMS Workspace and C Program Heap, then we need to - * be very very careful about destroying the initialization - * that has already been done. - */ + for (i = 0; i < area_count; ++i) { + const Heap_Area *area = &areas [i]; + uintptr_t space_available = (*init_or_extend)( + heap, + area->begin, + area->size, + page_size + ); - /* - * If the BSP is not clearing out the workspace, then it is most likely - * not clearing out the initial memory for the heap. There is no - * standard supporting zeroing out the heap memory. But much code - * with UNIX history seems to assume that memory malloc'ed during - * initialization (before any free's) is zero'ed. This is true most - * of the time under UNIX because zero'ing memory when it is first - * given to a process eliminates the chance of a process seeing data - * left over from another process. This would be a security violation. - */ + if ( space_available > 0 ) { + init_or_extend = extend; + } + } - if ( separate_areas && rtems_configuration_get_do_zero_of_workspace() ) { - memset( heap_begin, 0, heap_size ); + if ( init_or_extend == _Heap_Initialize ) { + _Internal_error_Occurred( + INTERNAL_ERROR_CORE, + true, + INTERNAL_ERROR_NO_MEMORY_FOR_HEAP + ); + } } /* - * Unfortunately we cannot use assert if this fails because if this - * has failed we do not have a heap and if we do not have a heap - * STDIO cannot work because there will be no buffers. + * If configured, initialize the statistics support */ - - if ( separate_areas ) { - uintptr_t status = _Protected_heap_Initialize( - RTEMS_Malloc_Heap, - heap_begin, - heap_size, - CPU_HEAP_ALIGNMENT - ); - if ( status == 0 ) { - rtems_fatal_error_occurred( RTEMS_NO_MEMORY ); - } + if ( rtems_malloc_statistics_helpers != NULL ) { + (*rtems_malloc_statistics_helpers->initialize)(); } - MSBUMP( space_available, _Protected_heap_Get_size(RTEMS_Malloc_Heap) ); + MSBUMP( space_available, _Protected_heap_Get_size( heap ) ); +} +#else +void RTEMS_Malloc_Initialize( + Heap_Area *areas, + size_t area_count, + Heap_Initialization_or_extend_handler extend +) +{ + /* FIXME: Dummy function */ } #endif diff --git a/cpukit/libcsupport/src/malloc_p.h b/cpukit/libcsupport/src/malloc_p.h index ea0709f0e7..6bd9a495f7 100644 --- a/cpukit/libcsupport/src/malloc_p.h +++ b/cpukit/libcsupport/src/malloc_p.h @@ -22,11 +22,6 @@ #include #include -/* - * Basic management data - */ -extern Heap_Control *RTEMS_Malloc_Heap; - /* * Malloc Statistics Structure */ diff --git a/cpukit/libcsupport/src/malloc_sbrk_helpers.c b/cpukit/libcsupport/src/malloc_sbrk_helpers.c deleted file mode 100644 index 64572a154e..0000000000 --- a/cpukit/libcsupport/src/malloc_sbrk_helpers.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * RTEMS Malloc -- SBRK Support Plugin - * - * COPYRIGHT (c) 1989-2007. - * On-Line Applications Research Corporation (OAR). - * - * 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. - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#include /* sbrk */ - -#include -#include -#include "malloc_p.h" - -#include - -size_t RTEMS_Malloc_Sbrk_amount; - -static void *malloc_sbrk_initialize( - void *starting_address, - size_t length -) -{ - uintptr_t old_address; - uintptr_t uaddress; - - RTEMS_Malloc_Sbrk_amount = length; - - /* - * If the starting address is 0 then we are to attempt to - * get length worth of memory using sbrk. Make sure we - * align the address that we get back. - */ - - if (!starting_address) { - uaddress = (uintptr_t)sbrk(length); - - if (uaddress == (uintptr_t) -1) { - rtems_fatal_error_occurred( RTEMS_NO_MEMORY ); - /* DOES NOT RETURN!!! */ - } - - if (uaddress & (CPU_HEAP_ALIGNMENT-1)) { - old_address = uaddress; - uaddress = (uaddress + CPU_HEAP_ALIGNMENT) & ~(CPU_HEAP_ALIGNMENT-1); - - /* - * adjust the length by whatever we aligned by - */ - length -= uaddress - old_address; - } - - starting_address = (void *)uaddress; - } - return starting_address; -} - -static void *malloc_sbrk_extend_and_allocate( - size_t size -) -{ - uint32_t sbrk_amount; - void *starting_address; - uint32_t the_size; - void *return_this; - - /* - * Round to the "requested sbrk amount" so hopefully we won't have - * to grow again for a while. This effectively does sbrk() calls - * in "page" amounts. - */ - - sbrk_amount = RTEMS_Malloc_Sbrk_amount; - - if ( sbrk_amount == 0 ) - return (void *) 0; - - the_size = ((size + sbrk_amount) / sbrk_amount * sbrk_amount); - - starting_address = (void *) sbrk(the_size); - if ( starting_address == (void*) -1 ) - return (void *) 0; - - if ( !_Protected_heap_Extend( - RTEMS_Malloc_Heap, starting_address, the_size) ) { - sbrk(-the_size); - errno = ENOMEM; - return (void *) 0; - } - - MSBUMP(space_available, the_size); - - return_this = _Protected_heap_Allocate( RTEMS_Malloc_Heap, size ); - return return_this; -} - - -rtems_malloc_sbrk_functions_t rtems_malloc_sbrk_helpers_table = { - malloc_sbrk_initialize, - malloc_sbrk_extend_and_allocate -}; diff --git a/cpukit/libcsupport/src/mallocinfo.c b/cpukit/libcsupport/src/mallocinfo.c index 47aefc3ff4..1532608420 100644 --- a/cpukit/libcsupport/src/mallocinfo.c +++ b/cpukit/libcsupport/src/mallocinfo.c @@ -14,13 +14,9 @@ #include "config.h" #endif -#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__ -#include -#include +#include #include -extern Heap_Control *RTEMS_Malloc_Heap; - /* * Find amount of free heap remaining */ diff --git a/cpukit/libcsupport/src/rtems_heap_extend_via_sbrk.c b/cpukit/libcsupport/src/rtems_heap_extend_via_sbrk.c new file mode 100644 index 0000000000..831626b3d5 --- /dev/null +++ b/cpukit/libcsupport/src/rtems_heap_extend_via_sbrk.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 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 + * http://www.rtems.com/license/LICENSE. + */ + +#if HAVE_CONFIG_H + #include "config.h" +#endif + +#include + +#include + +#include "malloc_p.h" + +ptrdiff_t RTEMS_Malloc_Sbrk_amount; + +void *rtems_heap_extend_via_sbrk( + Heap_Control *heap, + size_t alloc_size +) +{ + ptrdiff_t sbrk_amount = RTEMS_Malloc_Sbrk_amount; + ptrdiff_t sbrk_size = (ptrdiff_t) alloc_size; + ptrdiff_t misaligned = sbrk_size % sbrk_amount; + void *return_this = NULL; + + if ( misaligned != 0 ) { + sbrk_size += sbrk_amount - misaligned; + } + + if ( sbrk_size > 0 && sbrk_amount > 0 ) { + void *area_begin = sbrk( sbrk_size ); + + if ( area_begin != (void *) -1 ) { + bool ok = _Protected_heap_Extend( heap, area_begin, sbrk_size ); + + if ( ok ) { + MSBUMP( space_available, sbrk_size ); + + return_this = _Protected_heap_Allocate( heap, alloc_size ); + } else { + sbrk( -sbrk_size ); + } + } + } + + return return_this; +} diff --git a/cpukit/libcsupport/src/rtems_heap_null_extend.c b/cpukit/libcsupport/src/rtems_heap_null_extend.c new file mode 100644 index 0000000000..a821ef48f9 --- /dev/null +++ b/cpukit/libcsupport/src/rtems_heap_null_extend.c @@ -0,0 +1,27 @@ +/* + * Copyright (c) 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 + * http://www.rtems.com/license/LICENSE. + */ + +#if HAVE_CONFIG_H + #include "config.h" +#endif + +#include + +void *rtems_heap_null_extend( + Heap_Control *heap __attribute__((unused)), + size_t alloc_size __attribute__((unused)) +) +{ + return NULL; +} diff --git a/cpukit/libmisc/monitor/mon-config.c b/cpukit/libmisc/monitor/mon-config.c index 0df87d625f..b5bc31ce9d 100644 --- a/cpukit/libmisc/monitor/mon-config.c +++ b/cpukit/libmisc/monitor/mon-config.c @@ -33,7 +33,6 @@ rtems_monitor_config_canonical( rtems_configuration_table *c = (rtems_configuration_table *) config_void; rtems_api_configuration_table *r = &Configuration_RTEMS_API; - canonical_config->work_space_start = c->work_space_start; canonical_config->work_space_size = c->work_space_size; canonical_config->maximum_tasks = r->maximum_tasks; canonical_config->maximum_timers = r->maximum_timers; diff --git a/cpukit/sapi/include/confdefs.h b/cpukit/sapi/include/confdefs.h index d4f21ca376..09edc97770 100644 --- a/cpukit/sapi/include/confdefs.h +++ b/cpukit/sapi/include/confdefs.h @@ -901,11 +901,11 @@ rtems_fs_init_functions_t rtems_fs_init_helper = * RAM to the malloc family implementation so sbrk()'ing to get * more memory would always fail anyway. */ - rtems_malloc_sbrk_functions_t *rtems_malloc_sbrk_helpers = - #ifndef CONFIGURE_MALLOC_BSP_SUPPORTS_SBRK - NULL; + const rtems_heap_extend_handler rtems_malloc_extend_handler = + #ifdef CONFIGURE_MALLOC_BSP_SUPPORTS_SBRK + rtems_heap_extend_via_sbrk; #else - &rtems_malloc_sbrk_helpers_table; + rtems_heap_null_extend; #endif #endif @@ -2318,7 +2318,6 @@ rtems_fs_init_functions_t rtems_fs_init_helper = * This is the primary Configuration Table for this application. */ rtems_configuration_table Configuration = { - NULL, /* filled in by BSP */ CONFIGURE_EXECUTIVE_RAM_SIZE, /* required RTEMS workspace */ CONFIGURE_STACK_SPACE_SIZE, /* required stack space */ CONFIGURE_MAXIMUM_USER_EXTENSIONS, /* maximum dynamic extensions */ diff --git a/cpukit/sapi/include/rtems/config.h b/cpukit/sapi/include/rtems/config.h index 58b350da76..d0e181c781 100644 --- a/cpukit/sapi/include/rtems/config.h +++ b/cpukit/sapi/include/rtems/config.h @@ -124,10 +124,6 @@ typedef void (*rtems_stack_free_hook)( void *addr ); * + required number of each object type for each API configured */ typedef struct { - /** This field specifies the base address of the RTEMS Workspace. - */ - void *work_space_start; - /** This field specifies the size in bytes of the RTEMS Workspace. */ uintptr_t work_space_size; @@ -266,12 +262,6 @@ extern rtems_configuration_table Configuration; #define rtems_configuration_set_stack_space_size( _size ) \ do { Configuration.stack_space_size = (_size); } while (0) -#define rtems_configuration_get_work_space_start() \ - (Configuration.work_space_start) - -#define rtems_configuration_set_work_space_start( _start ) \ - do { Configuration.work_space_start = (_start); } while (0) - #define rtems_configuration_get_work_space_size() \ (Configuration.work_space_size + \ (rtems_configuration_get_stack_allocator_avoids_work_space() ? \ diff --git a/cpukit/sapi/src/exinit.c b/cpukit/sapi/src/exinit.c index 82e853a142..1aa7e544bb 100644 --- a/cpukit/sapi/src/exinit.c +++ b/cpukit/sapi/src/exinit.c @@ -111,12 +111,6 @@ void rtems_initialize_data_structures(void) _Thread_Dispatch_initialization(); - /* - * Before this is called, we are not allowed to allocate memory - * from the Workspace because it is not initialized. - */ - _Workspace_Handler_initialization(); - #if defined(RTEMS_SMP) _SMP_Handler_initialize(); #endif diff --git a/cpukit/score/include/rtems/score/heap.h b/cpukit/score/include/rtems/score/heap.h index 964386a36f..36ef48f3b6 100644 --- a/cpukit/score/include/rtems/score/heap.h +++ b/cpukit/score/include/rtems/score/heap.h @@ -675,6 +675,36 @@ Heap_Resize_status _Heap_Resize_block( uintptr_t *new_size ); +RTEMS_INLINE_ROUTINE uintptr_t _Heap_Align_up( + uintptr_t value, + uintptr_t alignment +) +{ + uintptr_t remainder = value % alignment; + + if ( remainder != 0 ) { + return value - remainder + alignment; + } else { + return value; + } +} + +/** + * @brief Returns the worst case overhead to manage a memory area. + */ +RTEMS_INLINE_ROUTINE uintptr_t _Heap_Area_overhead( + uintptr_t page_size +) +{ + if ( page_size != 0 ) { + page_size = _Heap_Align_up( page_size, CPU_ALIGNMENT ); + } else { + page_size = CPU_ALIGNMENT; + } + + return 2 * (page_size - 1) + HEAP_BLOCK_HEADER_SIZE; +} + #if !defined(__RTEMS_APPLICATION__) #include diff --git a/cpukit/score/include/rtems/score/interr.h b/cpukit/score/include/rtems/score/interr.h index 19342a3db8..2a21fe01eb 100644 --- a/cpukit/score/include/rtems/score/interr.h +++ b/cpukit/score/include/rtems/score/interr.h @@ -72,7 +72,8 @@ typedef enum { INTERNAL_ERROR_UNLIMITED_AND_MAXIMUM_IS_0, INTERNAL_ERROR_SHUTDOWN_WHEN_NOT_UP, INTERNAL_ERROR_GXX_KEY_ADD_FAILED, - INTERNAL_ERROR_GXX_MUTEX_INIT_FAILED + INTERNAL_ERROR_GXX_MUTEX_INIT_FAILED, + INTERNAL_ERROR_NO_MEMORY_FOR_HEAP } Internal_errors_Core_list; typedef uint32_t Internal_errors_t; diff --git a/cpukit/score/include/rtems/score/wkspace.h b/cpukit/score/include/rtems/score/wkspace.h index 10b80ccaab..db6eb38f96 100644 --- a/cpukit/score/include/rtems/score/wkspace.h +++ b/cpukit/score/include/rtems/score/wkspace.h @@ -36,19 +36,23 @@ extern "C" { #include /** - * @brief Executive Workspace Control + * @brief Executive workspace control. * - * The is the heap control structure that used to manage the - * RTEMS Executive Workspace. + * This is the heap control structure used to manage the RTEMS Executive + * Workspace. */ -SCORE_EXTERN Heap_Control _Workspace_Area; /* executive heap header */ +SCORE_EXTERN Heap_Control _Workspace_Area; /** * @brief Workspace Handler Initialization * * This routine performs the initialization necessary for this handler. */ -void _Workspace_Handler_initialization(void); +void _Workspace_Handler_initialization( + Heap_Area *areas, + size_t area_count, + Heap_Initialization_or_extend_handler extend +); /** * @brief Allocate Memory from Workspace diff --git a/cpukit/score/inline/rtems/score/heap.inl b/cpukit/score/inline/rtems/score/heap.inl index b9553714c4..59bdd7b142 100644 --- a/cpukit/score/inline/rtems/score/heap.inl +++ b/cpukit/score/inline/rtems/score/heap.inl @@ -108,20 +108,6 @@ RTEMS_INLINE_ROUTINE bool _Heap_Is_aligned( return (value % alignment) == 0; } -RTEMS_INLINE_ROUTINE uintptr_t _Heap_Align_up( - uintptr_t value, - uintptr_t alignment -) -{ - uintptr_t remainder = value % alignment; - - if ( remainder != 0 ) { - return value - remainder + alignment; - } else { - return value; - } -} - RTEMS_INLINE_ROUTINE uintptr_t _Heap_Align_down( uintptr_t value, uintptr_t alignment diff --git a/cpukit/score/src/wkspace.c b/cpukit/score/src/wkspace.c index 842cade81b..7e58585173 100644 --- a/cpukit/score/src/wkspace.c +++ b/cpukit/score/src/wkspace.c @@ -28,28 +28,69 @@ /* * _Workspace_Handler_initialization */ -void _Workspace_Handler_initialization(void) +void _Workspace_Handler_initialization( + Heap_Area *areas, + size_t area_count, + Heap_Initialization_or_extend_handler extend +) { - uintptr_t memory_available = 0; - void *starting_address = rtems_configuration_get_work_space_start(); - uintptr_t size = rtems_configuration_get_work_space_size(); + Heap_Initialization_or_extend_handler init_or_extend = _Heap_Initialize; + uintptr_t remaining = rtems_configuration_get_work_space_size(); + bool do_zero = rtems_configuration_get_do_zero_of_workspace(); + bool unified = rtems_configuration_get_unified_work_area(); + uintptr_t page_size = CPU_HEAP_ALIGNMENT; + uintptr_t overhead = _Heap_Area_overhead( page_size ); + size_t i; + + for (i = 0; i < area_count; ++i) { + Heap_Area *area = &areas [i]; + + if ( do_zero ) { + memset( area->begin, 0, area->size ); + } + + if ( area->size > overhead ) { + uintptr_t space_available; + uintptr_t size; + + if ( unified ) { + size = area->size; + } else { + if ( remaining > 0 ) { + size = remaining < area->size - overhead ? + remaining + overhead : area->size; + } else { + size = 0; + } + } + + space_available = (*init_or_extend)( + &_Workspace_Area, + area->begin, + size, + page_size + ); + + area->begin = (char *) area->begin + size; + area->size -= size; - if ( rtems_configuration_get_do_zero_of_workspace() ) - memset( starting_address, 0, size ); + if ( space_available < remaining ) { + remaining -= space_available; + } else { + remaining = 0; + } - memory_available = _Heap_Initialize( - &_Workspace_Area, - starting_address, - size, - CPU_HEAP_ALIGNMENT - ); + init_or_extend = extend; + } + } - if ( memory_available == 0 ) + if ( remaining > 0 ) { _Internal_error_Occurred( INTERNAL_ERROR_CORE, true, INTERNAL_ERROR_TOO_LITTLE_WORKSPACE ); + } } /* diff --git a/doc/bsp_howto/init.t b/doc/bsp_howto/init.t index f0dde45cb3..f91d15f934 100644 --- a/doc/bsp_howto/init.t +++ b/doc/bsp_howto/init.t @@ -147,34 +147,29 @@ The @code{boot_card()} routine performs the following functions: @item It disables processor interrupts. -@item It sets the global program name and command line argument variables +@item It sets the command line argument variables for later use by the application. -@item If the macro is BSP_BOOTCARD_HANDLES_RAM_ALLOCATION is defined, it -will invoke the BSP specific @code{bsp_get_work_area} function to obtain -information on the amount and location of BSP RAM that is available to -be allocated to the C Program Heap and RTEMS Workspace. If the amount -of memory available for the RTEMS Workspace is less than that required -by the application (e.g. @code{rtems_configuration_get_work_space_size()}, -then a message is printed using @code{printk}, @code{bsp_cleanup} is -invoked, and -1 is return to the assembly language start code. BSPs which -use this memory allocation functionality in @code{bootcard.c} -must invoke the RTEMS specific autoconf macro -@code{RTEMS_BSP_BOOTCARD_HANDLES_RAM_ALLOCATION} in the BSP's -@code{configure.ac} file. - @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 +@code{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 }. + @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 enabled. -@item If the macro is BSP_BOOTCARD_HANDLES_RAM_ALLOCATION is defined, -it will calculate the memory available for the C Program Heap and invoke -the initialization routine for the C Library with this information. +@item It invokes the BSP specific routine @code{bsp_libc_init()} to initialize +the C Library. Usually the default implementation in +@code{c/src/lib/libbsp/shared/bsplibc.c} should be sufficient. @item It invokes the BSP specific routine @code{bsp_pretasking_hook}. On most BSPs which utilize the framework, this routine does nothing. @@ -188,9 +183,7 @@ thread in a multiprocessor configuration and execute API specific extensions. @item It invokes the BSP specific routine @code{bsp_predriver_hook}. For -most BSPs, the implementation of this routine does nothing. However, -on some BSPs, required subsystems which utilize the C Library -(e.g. @code{malloc} in particular) may be initialized at this point. +most BSPs, the implementation of this routine does nothing. @item It invokes the RTEMS directive @code{rtems_initialize_device_drivers()} to initialize the statically @@ -255,28 +248,13 @@ routine. @subsection RTEMS Pretasking Callback -The method @code{bsp_pretasking_hook()} is the BSP specific routine -invoked once RTEMS API initialization is complete but before interrupts -and tasking are enabled. No tasks -- not even the IDLE task -- have -been created when this hook is invoked. The pretasking hook is optional +The method @code{bsp_pretasking_hook()} is the BSP specific routine invoked +once RTEMS API initialization is complete but before interrupts and tasking are +enabled. The idle thread exists at this time. The pretasking hook is optional and the user may use the shared version. -The @code{bsp_pretasking_hook()} routine is the appropriate place to -initialize any support components which depend on the RTEMS APIs. -Older BSPs that do not take full advantage of @code{boot_card()} -may initialize the RTEMS C Library in their implementation of -@code{bsp_pretasking_hook()}. This initialization includes the -application heap used by the @code{malloc} family of routines as well -as the reentrancy support for the C Library. - -The routine @code{bsp_libc_init} routine invoked from the -either @code{boot_card()} or (less preferable) the BSP specific -@code{bsp_pretasking_hook()} routine is passed the starting address, -length, and growth amount passed to @code{sbrk}. This "sbrk amount" -is only used if the heap runs out of memory. In this case, the RTEMS -malloc implementation will invoked @code{sbrk} to obtain more memory. -See @ref{Miscellaneous Support Files sbrk() Implementation} for more -details. +The @code{bsp_pretasking_hook()} routine is the appropriate place to initialize +any BSP specific support components which depend on the RTEMS APIs. @subsection RTEMS Predriver Callback diff --git a/testsuites/libtests/malloc04/init.c b/testsuites/libtests/malloc04/init.c index 72a397f6a1..00355dabd4 100644 --- a/testsuites/libtests/malloc04/init.c +++ b/testsuites/libtests/malloc04/init.c @@ -30,14 +30,20 @@ #include /* end of configuration */ +#ifndef CONFIGURE_MALLOC_BSP_SUPPORTS_SBRK +void *rtems_heap_null_extend( + Heap_Control *heap, + size_t alloc_size +) +{ + return rtems_heap_extend_via_sbrk( heap, alloc_size ); +} +#endif + char Malloc_Heap[ 128 ] CPU_STRUCTURE_ALIGNMENT; int sbrk_count; -Heap_Control Heap_Holder; Heap_Control TempHeap; -/* Heap variables we need to peek and poke at */ -extern size_t RTEMS_Malloc_Sbrk_amount; - size_t offset; void * sbrk(ptrdiff_t incr) @@ -66,7 +72,8 @@ rtems_task Init( rtems_task_argument argument ) { - Heap_Control *TempHeap; + Heap_Control *real_heap; + Heap_Area area; sbrk_count = 0; offset = 0; @@ -74,21 +81,26 @@ rtems_task Init( puts( "\n\n*** TEST MALLOC 04 ***" ); /* Safe information on real heap */ - TempHeap = malloc_get_heap_pointer(); - Heap_Holder = *TempHeap; - rtems_malloc_sbrk_helpers = &rtems_malloc_sbrk_helpers_table; + real_heap = malloc_get_heap_pointer(); + malloc_set_heap_pointer( &TempHeap ); + + rtems_heap_set_sbrk_amount( 64 ); puts( "Initialize heap with some memory" ); offset = 64; sbrk_count = 0; - RTEMS_Malloc_Initialize( Malloc_Heap, 64, 64 ); + area.begin = &Malloc_Heap [0]; + area.size = 64; + RTEMS_Malloc_Initialize( &area, 1, NULL ); p1 = malloc(64); p2 = malloc(64); p3 = malloc(48); p4 = malloc(48); puts( "Initialize heap with some memory - return address out of heap" ); - RTEMS_Malloc_Initialize( &Malloc_Heap[1], 64, 64 ); + area.begin = &Malloc_Heap [1]; + area.size = 64; + RTEMS_Malloc_Initialize( &area, 1, NULL ); offset = 64; sbrk_count = -1; p1 = malloc( 127 ); @@ -96,18 +108,21 @@ rtems_task Init( rtems_test_assert( errno == ENOMEM ); - RTEMS_Malloc_Initialize( Malloc_Heap, 64, 64 ); + area.begin = &Malloc_Heap [0]; + area.size = 64; + RTEMS_Malloc_Initialize( &area, 1, NULL ); puts( "Initialize heap with some unaligned memory" ); offset = 65; sbrk_count = 0; - RTEMS_Malloc_Initialize( &Malloc_Heap[1], 64, 64 ); + area.begin = &Malloc_Heap [1]; + area.size = 64; + RTEMS_Malloc_Initialize( &area, 1, NULL ); p1 = malloc(64); p2 = malloc(64); p3 = malloc(48); /* Restore information on real heap */ - malloc_set_heap_pointer( TempHeap ); - rtems_malloc_sbrk_helpers = NULL; + malloc_set_heap_pointer( real_heap ); puts( "*** END OF TEST MALLOC 04 ***" ); diff --git a/testsuites/psxtests/psxfatal_support/init.c b/testsuites/psxtests/psxfatal_support/init.c index c58aeafc64..e2ab2415fa 100644 --- a/testsuites/psxtests/psxfatal_support/init.c +++ b/testsuites/psxtests/psxfatal_support/init.c @@ -87,13 +87,18 @@ char *Errors_Core[] = { "INTERNAL_ERROR_BAD_ATTRIBUTES", "INTERNAL_ERROR_IMPLEMENTATION_KEY_CREATE_INCONSISTENCY", "INTERNAL_ERROR_IMPLEMENTATION_BLOCKING_OPERATION_CANCEL", - "INTERNAL_ERROR_MUTEX_OBTAIN_FROM_BAD_STATE" + "INTERNAL_ERROR_MUTEX_OBTAIN_FROM_BAD_STATE", + "INTERNAL_ERROR_UNLIMITED_AND_MAXIMUM_IS_0", + "INTERNAL_ERROR_SHUTDOWN_WHEN_NOT_UP", + "INTERNAL_ERROR_GXX_KEY_ADD_FAILED", + "INTERNAL_ERROR_GXX_MUTEX_INIT_FAILED", + "INTERNAL_ERROR_NO_MEMORY_FOR_HEAP" }; void Put_Error( uint32_t source, uint32_t error ) { if ( source == INTERNAL_ERROR_CORE ) { - if ( error > INTERNAL_ERROR_MUTEX_OBTAIN_FROM_BAD_STATE ) + if ( error > INTERNAL_ERROR_NO_MEMORY_FOR_HEAP ) printk("Unknown Internal Core Error (%d)", error); else printk( Errors_Core[ error ] ); diff --git a/testsuites/sptests/Makefile.am b/testsuites/sptests/Makefile.am index 479cdf6cd4..a0dc24af36 100644 --- a/testsuites/sptests/Makefile.am +++ b/testsuites/sptests/Makefile.am @@ -17,7 +17,7 @@ SUBDIRS = \ sperror01 sperror02 sperror03 \ spfatal01 spfatal02 spfatal03 spfatal04 spfatal05 spfatal06 spfatal07 \ spfatal08 spfatal09 spfatal10 spfatal11 spfatal12 spfatal13 spfatal14 \ - spfatal15 spfatal16 spfatal17 spfatal18 spfatal19 spfatal20 spfatal21 \ + spfatal15 spfatal16 spfatal17 spfatal18 spfatal19 spfatal20 \ spfatal22 spfatal23 spfatal24 spfatal25 \ spfifo01 spfifo02 spfifo03 spfifo04 spfifo05 \ spintrcritical01 spintrcritical02 spintrcritical03 spintrcritical04 \ diff --git a/testsuites/sptests/configure.ac b/testsuites/sptests/configure.ac index 33a0755615..32063e2221 100644 --- a/testsuites/sptests/configure.ac +++ b/testsuites/sptests/configure.ac @@ -139,7 +139,6 @@ spfatal17/Makefile spfatal18/Makefile spfatal19/Makefile spfatal20/Makefile -spfatal21/Makefile spfatal22/Makefile spfatal23/Makefile spfatal24/Makefile diff --git a/testsuites/sptests/spfatal06/testcase.h b/testsuites/sptests/spfatal06/testcase.h index 29669d96bf..27c615d7e7 100644 --- a/testsuites/sptests/spfatal06/testcase.h +++ b/testsuites/sptests/spfatal06/testcase.h @@ -38,6 +38,10 @@ rtems_initialization_tasks_table Initialization_tasks[] = { void *New_stack_allocate_hook(size_t unused); +#define CONFIGURE_TASK_STACK_ALLOCATOR New_stack_allocate_hook + +#define CONFIGURE_TASK_STACK_DEALLOCATOR NULL + void *New_stack_allocate_hook(size_t unused) { return NULL; @@ -45,12 +49,5 @@ void *New_stack_allocate_hook(size_t unused) void force_error() { - if (Configuration.stack_free_hook != NULL) - Configuration.stack_allocate_hook = NULL; - else - Configuration.stack_allocate_hook = New_stack_allocate_hook; - - rtems_initialize_data_structures(); /* we will not run this far */ } - diff --git a/testsuites/sptests/spfatal07/testcase.h b/testsuites/sptests/spfatal07/testcase.h index c95fc0df48..77ef6e8af7 100644 --- a/testsuites/sptests/spfatal07/testcase.h +++ b/testsuites/sptests/spfatal07/testcase.h @@ -37,11 +37,15 @@ rtems_initialization_tasks_table Initialization_tasks[] = { #define FATAL_ERROR_EXPECTED_ERROR \ INTERNAL_ERROR_INTERRUPT_STACK_TOO_SMALL +#if CPU_SIMPLE_VECTORED_INTERRUPTS == TRUE + #define CONFIGURE_MEMORY_OVERHEAD (sizeof(ISR_Handler_entry) * ISR_NUMBER_OF_VECTORS) +#endif + void force_error() { #if (CPU_ALLOCATE_INTERRUPT_STACK == TRUE) Configuration.interrupt_stack_size = (STACK_MINIMUM_SIZE-1); - rtems_initialize_data_structures(); + _ISR_Handler_initialization(); #else printk( "WARNING - Test not applicable on this target architecture.\n" diff --git a/testsuites/sptests/spfatal08/testcase.h b/testsuites/sptests/spfatal08/testcase.h index 50a831f33f..83615f5b04 100644 --- a/testsuites/sptests/spfatal08/testcase.h +++ b/testsuites/sptests/spfatal08/testcase.h @@ -9,6 +9,8 @@ * http://www.rtems.com/license/LICENSE. */ +#include + /* * Way too much stack space. Should generate a fatal error * on the init task create. @@ -39,10 +41,16 @@ char Workspace[ 256 ] CPU_STRUCTURE_ALIGNMENT; void force_error() { - rtems_configuration_set_work_space_start( Workspace ); - rtems_configuration_set_work_space_size( sizeof(Workspace) ); + Heap_Area area = { + .begin = Workspace, + .size = sizeof( Workspace ) + }; + + rtems_configuration_set_work_space_size( 0 ); rtems_configuration_set_stack_space_size( 0 ); - rtems_initialize_data_structures();; + _Workspace_Handler_initialization( &area, 1, NULL ); + + _Workspace_Allocate_or_fatal_error( 2 * sizeof( Workspace ) ); /* we will not run this far */ } diff --git a/testsuites/sptests/spfatal09/testcase.h b/testsuites/sptests/spfatal09/testcase.h index eb50c30dfd..dc6dfa9f24 100644 --- a/testsuites/sptests/spfatal09/testcase.h +++ b/testsuites/sptests/spfatal09/testcase.h @@ -14,15 +14,12 @@ #define FATAL_ERROR_TEST_NAME "9" #define FATAL_ERROR_DESCRIPTION "Bad heap address to malloc" -#define FATAL_ERROR_EXPECTED_SOURCE INTERNAL_ERROR_RTEMS_API -#define FATAL_ERROR_EXPECTED_IS_INTERNAL FALSE -#define FATAL_ERROR_EXPECTED_ERROR RTEMS_NO_MEMORY - -char Malloc_Heap[ 1 ] CPU_STRUCTURE_ALIGNMENT; +#define FATAL_ERROR_EXPECTED_SOURCE INTERNAL_ERROR_CORE +#define FATAL_ERROR_EXPECTED_IS_INTERNAL TRUE +#define FATAL_ERROR_EXPECTED_ERROR INTERNAL_ERROR_NO_MEMORY_FOR_HEAP void force_error() { - RTEMS_Malloc_Initialize( Malloc_Heap, sizeof(Malloc_Heap), 0 ); - + RTEMS_Malloc_Initialize( NULL, 0, NULL ); /* we will not run this far */ } diff --git a/testsuites/sptests/spfatal12/testcase.h b/testsuites/sptests/spfatal12/testcase.h index feeec46034..73cb7a9616 100644 --- a/testsuites/sptests/spfatal12/testcase.h +++ b/testsuites/sptests/spfatal12/testcase.h @@ -17,9 +17,8 @@ void force_error() { - rtems_configuration_set_work_space_size( sizeof(void *) ); - rtems_configuration_set_stack_space_size( 0 ); - rtems_initialize_data_structures(); + Heap_Area area = { .begin = NULL, .size = 0 }; + _Workspace_Handler_initialization( &area, 1, NULL ); /* we will not run this far */ } diff --git a/testsuites/sptests/spfatal21/Makefile.am b/testsuites/sptests/spfatal21/Makefile.am deleted file mode 100644 index 3a2439ac80..0000000000 --- a/testsuites/sptests/spfatal21/Makefile.am +++ /dev/null @@ -1,21 +0,0 @@ -rtems_tests_PROGRAMS = spfatal21 -spfatal21_SOURCES = ../spfatal_support/init.c \ - ../spfatal_support/system.h ../../support/src/test_support.c testcase.h - -dist_rtems_tests_DATA = spfatal21.scn -dist_rtems_tests_DATA += spfatal21.doc - -include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg -include $(top_srcdir)/../automake/compile.am -include $(top_srcdir)/../automake/leaf.am - -AM_CPPFLAGS += -I$(top_srcdir)/../support/include - -LINK_OBJS = $(spfatal21_OBJECTS) -LINK_LIBS = $(spfatal21_LDLIBS) - -spfatal21$(EXEEXT): $(spfatal21_OBJECTS) $(spfatal21_DEPENDENCIES) - @rm -f spfatal21$(EXEEXT) - $(make-exe) - -include $(top_srcdir)/../automake/local.am diff --git a/testsuites/sptests/spfatal21/spfatal21.doc b/testsuites/sptests/spfatal21/spfatal21.doc deleted file mode 100644 index ba1e65c0f2..0000000000 --- a/testsuites/sptests/spfatal21/spfatal21.doc +++ /dev/null @@ -1,19 +0,0 @@ -# COPYRIGHT (c) 1989-2010. -# On-Line Applications Research Corporation (OAR). -# -# 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. -# - -This file describes the directives and concepts tested by this test set. - -test set name: spfatal21 - -directives: - - malloc_sbrk_initialize - -concepts: - -+ exercise fatal error when sbrk fails to extend memory on the initial call. diff --git a/testsuites/sptests/spfatal21/spfatal21.scn b/testsuites/sptests/spfatal21/spfatal21.scn deleted file mode 100644 index 1ea32a5d3f..0000000000 --- a/testsuites/sptests/spfatal21/spfatal21.scn +++ /dev/null @@ -1,3 +0,0 @@ -*** TEST FATAL FATAL 21 *** -Fatal error (sbrk during init fails) hit -*** END OF TEST FATAL 21 *** diff --git a/testsuites/sptests/spfatal21/testcase.h b/testsuites/sptests/spfatal21/testcase.h deleted file mode 100644 index 788f06be5e..0000000000 --- a/testsuites/sptests/spfatal21/testcase.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * COPYRIGHT (c) 1989-2012. - * On-Line Applications Research Corporation (OAR). - * - * 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 FATAL_ERROR_TEST_NAME "FATAL 21" -#define FATAL_ERROR_DESCRIPTION "sbrk during init fails" -#define FATAL_ERROR_EXPECTED_SOURCE INTERNAL_ERROR_RTEMS_API -#define FATAL_ERROR_EXPECTED_IS_INTERNAL FALSE -#define FATAL_ERROR_EXPECTED_ERROR RTEMS_NO_MEMORY - -#include -#include -#include - -/* Safe information on real heap */ -extern rtems_malloc_sbrk_functions_t *rtems_malloc_sbrk_helpers; -extern rtems_malloc_sbrk_functions_t rtems_malloc_sbrk_helpers_table; - -void * sbrk(ptrdiff_t incr) -{ - return (void *) -1; -} - -void force_error() -{ - rtems_malloc_sbrk_helpers = &rtems_malloc_sbrk_helpers_table; - - RTEMS_Malloc_Initialize( NULL, 0, 64 ); -} diff --git a/testsuites/sptests/spfatal_support/init.c b/testsuites/sptests/spfatal_support/init.c index 923c08f7db..9822b13276 100644 --- a/testsuites/sptests/spfatal_support/init.c +++ b/testsuites/sptests/spfatal_support/init.c @@ -88,13 +88,18 @@ char *Errors_Core[] = { "INTERNAL_ERROR_BAD_ATTRIBUTES", "INTERNAL_ERROR_IMPLEMENTATION_KEY_CREATE_INCONSISTENCY", "INTERNAL_ERROR_IMPLEMENTATION_BLOCKING_OPERATION_CANCEL", - "INTERNAL_ERROR_MUTEX_OBTAIN_FROM_BAD_STATE" + "INTERNAL_ERROR_MUTEX_OBTAIN_FROM_BAD_STATE", + "INTERNAL_ERROR_UNLIMITED_AND_MAXIMUM_IS_0", + "INTERNAL_ERROR_SHUTDOWN_WHEN_NOT_UP", + "INTERNAL_ERROR_GXX_KEY_ADD_FAILED", + "INTERNAL_ERROR_GXX_MUTEX_INIT_FAILED", + "INTERNAL_ERROR_NO_MEMORY_FOR_HEAP" }; void Put_Error( uint32_t source, uint32_t error ) { if ( source == INTERNAL_ERROR_CORE ) { - if ( error > INTERNAL_ERROR_MUTEX_OBTAIN_FROM_BAD_STATE ) + if ( error > INTERNAL_ERROR_NO_MEMORY_FOR_HEAP ) printk("Unknown Internal Core Error (%d)", error); else printk( Errors_Core[ error ] ); -- cgit v1.2.3