Use 2-region memory model in ARM rtos-less builds.

The following commits: #8039, #9092 added Boot/ISR stack definition to all scatter files (ARM_LIB_STACK).

This has changed memory model for RTOS-less builds to 2-region memory model and caused failure in case of rtos less builds.
This PR defines valid heap/stack regions for rtos-less builds.
pull/9571/head
Przemyslaw Stekiel 2019-01-31 12:49:22 +01:00 committed by deepikabhavnani
parent f4e6db235e
commit a3223275c2
1 changed files with 60 additions and 10 deletions

View File

@ -905,24 +905,74 @@ extern "C" long PREFIX(_flen)(FILEHANDLE fh)
return size;
}
// Do not compile this code for TFM secure target
#if !defined(COMPONENT_SPE) || !defined(TARGET_TFM)
extern "C" char Image$$RW_IRAM1$$ZI$$Limit[];
extern "C" MBED_WEAK __value_in_regs struct __initial_stackheap _mbed_user_setup_stackheap(uint32_t R0, uint32_t R1, uint32_t R2, uint32_t R3)
{
uint32_t zi_limit = (uint32_t)Image$$RW_IRAM1$$ZI$$Limit;
uint32_t sp_limit = __current_sp();
zi_limit = (zi_limit + 7) & ~0x7; // ensure zi_limit is 8-byte aligned
#if defined(TARGET_NUVOTON) || defined(TARGET_RZ_A1XX)
extern char Image$$ARM_LIB_HEAP$$ZI$$Base[];
extern char Image$$ARM_LIB_STACK$$ZI$$Base[];
extern char Image$$ARM_LIB_HEAP$$ZI$$Limit[];
#define HEAP_BASE (Image$$ARM_LIB_HEAP$$ZI$$Base)
#define HEAP_LIMIT (Image$$ARM_LIB_HEAP$$ZI$$Limit)
#define STACK_BASE (Image$$ARM_LIB_STACK$$ZI$$Base)
#else
extern char Image$$RW_IRAM1$$ZI$$Limit[];
extern char Image$$ARM_LIB_STACK$$ZI$$Base[];
#define HEAP_BASE (Image$$RW_IRAM1$$ZI$$Limit)
#define HEAP_LIMIT (Image$$ARM_LIB_STACK$$ZI$$Base)
#define STACK_BASE (Image$$ARM_LIB_STACK$$ZI$$Base)
#endif
extern __value_in_regs struct __initial_stackheap _mbed_user_setup_stackheap(uint32_t R0, uint32_t R1, uint32_t R2, uint32_t R3) {
struct __initial_stackheap r;
r.heap_base = zi_limit;
r.heap_limit = sp_limit;
r.heap_base = (uint32_t)HEAP_BASE;
r.heap_limit = (uint32_t)HEAP_LIMIT;
return r;
}
#ifndef MBED_CONF_RTOS_PRESENT
/* The single region memory model would check stack collision at run time, verifying that
* the heap pointer is underneath the stack pointer. With two-region memory model/RTOS-less or
* multiple threads(stacks)/RTOS, the check gets meaningless and we must disable it. */
#if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
__asm(".global __use_two_region_memory\n\t");
__asm(".global __use_no_semihosting\n\t");
#else
#pragma import(__use_two_region_memory)
#endif
/* Fix __user_setup_stackheap and ARM_LIB_STACK/ARM_LIB_HEAP cannot co-exist in RTOS-less build
*
* According AN241 (http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dai0241b/index.html),
* __rt_entry has the following call sequence:
* 1. _platform_pre_stackheap_init
* 2. __user_setup_stackheap or setup the Stack Pointer (SP) by another method
* 3. _platform_post_stackheap_init
* 4. __rt_lib_init
* 5. _platform_post_lib_init
* 6. main()
* 7. exit()
*
* Per our check, when __user_setup_stackheap and ARM_LIB_STACK/ARM_LIB_HEAP co-exist, neither
* does __user_setup_stackheap get called and nor is ARM_LIB_HEAP used to get heap base/limit,
* which are required to pass to __rt_lib_init later. To fix the issue, by subclass'ing
* __rt_lib_init, heap base/limit are replaced with Image$$ARM_LIB_HEAP$$ZI$$Base/Limit if
* ARM_LIB_HEAP region is defined in scatter file.
*
* The overriding __rt_lib_init is needed only for rtos-less code. For rtos code, __rt_entry is
* overridden and the overriding __rt_lib_init here gets meaningless.
*/
extern "C" extern __value_in_regs struct __argc_argv $Super$$__rt_lib_init(unsigned heapbase, unsigned heaptop);
extern "C" __value_in_regs struct __argc_argv $Sub$$__rt_lib_init (unsigned heapbase, unsigned heaptop)
{
return $Super$$__rt_lib_init((unsigned)HEAP_BASE, (unsigned)HEAP_LIMIT);
}
#endif
extern "C" __value_in_regs struct __initial_stackheap __user_setup_stackheap(uint32_t R0, uint32_t R1, uint32_t R2, uint32_t R3)
{
return _mbed_user_setup_stackheap(R0, R1, R2, R3);