@@ -905,24 +905,74 @@ extern "C" long PREFIX(_flen)(FILEHANDLE fh)
905
905
return size;
906
906
}
907
907
908
+
908
909
// Do not compile this code for TFM secure target
909
910
#if !defined(COMPONENT_SPE) || !defined(TARGET_TFM)
910
911
911
- extern " C" char Image$$RW_IRAM1$$ZI$$Limit[];
912
-
913
- 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)
914
- {
915
- uint32_t zi_limit = (uint32_t )Image$$RW_IRAM1$$ZI$$Limit;
916
- uint32_t sp_limit = __current_sp ();
917
-
918
- zi_limit = (zi_limit + 7 ) & ~0x7 ; // ensure zi_limit is 8-byte aligned
912
+ #if defined(TARGET_NUVOTON) || defined(TARGET_RZ_A1XX)
913
+ extern char Image$$ARM_LIB_HEAP$$ZI$$Base[];
914
+ extern char Image$$ARM_LIB_STACK$$ZI$$Base[];
915
+ extern char Image$$ARM_LIB_HEAP$$ZI$$Limit[];
916
+ #define HEAP_BASE (Image$$ARM_LIB_HEAP$$ZI$$Base)
917
+ #define HEAP_LIMIT (Image$$ARM_LIB_HEAP$$ZI$$Limit)
918
+ #define STACK_BASE (Image$$ARM_LIB_STACK$$ZI$$Base)
919
+ #else
920
+ extern char Image$$RW_IRAM1$$ZI$$Limit[];
921
+ extern char Image$$ARM_LIB_STACK$$ZI$$Base[];
922
+ #define HEAP_BASE (Image$$RW_IRAM1$$ZI$$Limit)
923
+ #define HEAP_LIMIT (Image$$ARM_LIB_STACK$$ZI$$Base)
924
+ #define STACK_BASE (Image$$ARM_LIB_STACK$$ZI$$Base)
925
+ #endif
919
926
927
+ extern __value_in_regs struct __initial_stackheap _mbed_user_setup_stackheap (uint32_t R0, uint32_t R1, uint32_t R2, uint32_t R3) {
920
928
struct __initial_stackheap r;
921
- r.heap_base = zi_limit ;
922
- r.heap_limit = sp_limit ;
929
+ r.heap_base = ( uint32_t )HEAP_BASE ;
930
+ r.heap_limit = ( uint32_t )HEAP_LIMIT ;
923
931
return r;
924
932
}
925
933
934
+ #ifndef MBED_CONF_RTOS_PRESENT
935
+
936
+ /* The single region memory model would check stack collision at run time, verifying that
937
+ * the heap pointer is underneath the stack pointer. With two-region memory model/RTOS-less or
938
+ * multiple threads(stacks)/RTOS, the check gets meaningless and we must disable it. */
939
+ #if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
940
+ __asm (" .global __use_two_region_memory\n\t " );
941
+ __asm (" .global __use_no_semihosting\n\t " );
942
+ #else
943
+ #pragma import(__use_two_region_memory)
944
+ #endif
945
+
946
+ /* Fix __user_setup_stackheap and ARM_LIB_STACK/ARM_LIB_HEAP cannot co-exist in RTOS-less build
947
+ *
948
+ * According AN241 (http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dai0241b/index.html),
949
+ * __rt_entry has the following call sequence:
950
+ * 1. _platform_pre_stackheap_init
951
+ * 2. __user_setup_stackheap or setup the Stack Pointer (SP) by another method
952
+ * 3. _platform_post_stackheap_init
953
+ * 4. __rt_lib_init
954
+ * 5. _platform_post_lib_init
955
+ * 6. main()
956
+ * 7. exit()
957
+ *
958
+ * Per our check, when __user_setup_stackheap and ARM_LIB_STACK/ARM_LIB_HEAP co-exist, neither
959
+ * does __user_setup_stackheap get called and nor is ARM_LIB_HEAP used to get heap base/limit,
960
+ * which are required to pass to __rt_lib_init later. To fix the issue, by subclass'ing
961
+ * __rt_lib_init, heap base/limit are replaced with Image$$ARM_LIB_HEAP$$ZI$$Base/Limit if
962
+ * ARM_LIB_HEAP region is defined in scatter file.
963
+ *
964
+ * The overriding __rt_lib_init is needed only for rtos-less code. For rtos code, __rt_entry is
965
+ * overridden and the overriding __rt_lib_init here gets meaningless.
966
+ */
967
+ extern " C" extern __value_in_regs struct __argc_argv $Super$$__rt_lib_init(unsigned heapbase, unsigned heaptop);
968
+
969
+ extern " C" __value_in_regs struct __argc_argv $Sub$$__rt_lib_init (unsigned heapbase, unsigned heaptop)
970
+ {
971
+ return $Super$$__rt_lib_init ((unsigned )HEAP_BASE, (unsigned )HEAP_LIMIT);
972
+ }
973
+
974
+ #endif
975
+
926
976
extern " C" __value_in_regs struct __initial_stackheap __user_setup_stackheap (uint32_t R0, uint32_t R1, uint32_t R2, uint32_t R3)
927
977
{
928
978
return _mbed_user_setup_stackheap (R0, R1, R2, R3);
0 commit comments