mirror of https://github.com/ARMmbed/mbed-os.git
M2351: Refactor startup file
1. Re-organize to make clear for all targets/toolchains support in single startup file 2. Inline assembly syntax is limited, esp. on IAR. Try paving the way for accessing external symbols still in inline assembly instead of re-write in assembly.pull/12366/head
parent
c168e147d6
commit
9faa236dfc
|
@ -54,18 +54,33 @@ void FUN(void) __attribute__ ((weak, alias(#FUN_ALIAS)));
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Initialize segments */
|
/* Initialize segments */
|
||||||
#if defined(__ARMCC_VERSION)
|
#if defined(__ARMCC_VERSION)
|
||||||
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) && (TFM_LVL > 0)
|
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) && (TFM_LVL > 0)
|
||||||
extern uint32_t Image$$ARM_LIB_STACK_MSP$$ZI$$Limit;
|
extern uint32_t Image$$ARM_LIB_STACK_MSP$$ZI$$Limit;
|
||||||
|
extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Limit;
|
||||||
#else
|
#else
|
||||||
extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Limit;
|
extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Limit;
|
||||||
#endif
|
#endif
|
||||||
extern void __main(void);
|
extern void __main(void);
|
||||||
#elif defined(__ICCARM__)
|
#elif defined(__ICCARM__)
|
||||||
|
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) && (TFM_LVL > 0)
|
||||||
|
extern uint32_t Image$$ARM_LIB_STACK_MSP$$ZI$$Limit;
|
||||||
|
extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Limit;
|
||||||
|
extern uint32_t CSTACK_MSP$$Limit;
|
||||||
|
extern uint32_t CSTACK$$Limit;
|
||||||
|
#else
|
||||||
|
extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Limit;
|
||||||
|
extern uint32_t CSTACK$$Limit;
|
||||||
|
#endif
|
||||||
void __iar_program_start(void);
|
void __iar_program_start(void);
|
||||||
#elif defined(__GNUC__)
|
#elif defined(__GNUC__)
|
||||||
|
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) && (TFM_LVL > 0)
|
||||||
|
extern uint32_t Image$$ARM_LIB_STACK_MSP$$ZI$$Limit;
|
||||||
|
extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Limit;
|
||||||
|
#else
|
||||||
|
extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Limit;
|
||||||
|
#endif
|
||||||
extern uint32_t __StackTop;
|
extern uint32_t __StackTop;
|
||||||
extern uint32_t __copy_table_start__;
|
extern uint32_t __copy_table_start__;
|
||||||
extern uint32_t __copy_table_end__;
|
extern uint32_t __copy_table_end__;
|
||||||
|
@ -195,12 +210,6 @@ WEAK_ALIAS_FUNC(TRNG_IRQHandler, Default_Handler) // 101:
|
||||||
__attribute__ ((section("RESET")))
|
__attribute__ ((section("RESET")))
|
||||||
const uint32_t __vector_handlers[] = {
|
const uint32_t __vector_handlers[] = {
|
||||||
#elif defined(__ICCARM__)
|
#elif defined(__ICCARM__)
|
||||||
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) && (TFM_LVL > 0)
|
|
||||||
extern uint32_t CSTACK_MSP$$Limit;
|
|
||||||
extern uint32_t CSTACK$$Limit;
|
|
||||||
#else
|
|
||||||
extern uint32_t CSTACK$$Limit;
|
|
||||||
#endif
|
|
||||||
const uint32_t __vector_table[] @ ".intvec" = {
|
const uint32_t __vector_table[] @ ".intvec" = {
|
||||||
#elif defined(__GNUC__)
|
#elif defined(__GNUC__)
|
||||||
__attribute__ ((section(".vector_table")))
|
__attribute__ ((section(".vector_table")))
|
||||||
|
@ -347,47 +356,61 @@ const uint32_t __vector_handlers[] = {
|
||||||
(uint32_t) TRNG_IRQHandler, // 101:
|
(uint32_t) TRNG_IRQHandler, // 101:
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
|
|
||||||
|
|
||||||
/* Some reset handler code cannot implement in pure C. Implement it in inline/embedded assembly.
|
/* Some reset handler code cannot implement in pure C. Implement it in inline/embedded assembly.
|
||||||
*
|
*
|
||||||
* Reset_Handler:
|
* Reset_Handler:
|
||||||
* For non-secure PSA/non-secure non-PSA/secure non-PSA, do as usual
|
* For non-secure PSA/non-secure non-PSA/secure non-PSA, jump directly to Reset_Handler_1
|
||||||
* For secure PSA, switch from MSP to PSP, then jump to Reset_Handler_1 for usual work
|
* For secure PSA, switch from MSP to PSP, then jump to Reset_Handler_1
|
||||||
*
|
*
|
||||||
* Reset_Handler_1
|
* Reset_Handler_1:
|
||||||
|
* Platform initialization
|
||||||
* C/C++ runtime initialization
|
* C/C++ runtime initialization
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* Forward declaration */
|
||||||
|
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) && (TFM_LVL > 0)
|
||||||
|
/* Limited by inline assembly syntax, esp. on IAR, we cannot get stack limit
|
||||||
|
* for PSP just from external symbol. To avoid re-write in assembly, We make up
|
||||||
|
* a function here to get this value indirectly. */
|
||||||
|
uint32_t StackLimit_PSP(void);
|
||||||
|
#endif
|
||||||
void Reset_Handler_1(void);
|
void Reset_Handler_1(void);
|
||||||
|
|
||||||
/* Add '__attribute__((naked))' here to make sure compiler does not generate prologue and
|
/* Add '__attribute__((naked))' here to make sure compiler does not generate prologue and
|
||||||
* epilogue sequences for Reset_Handler. We don't want MSP is updated by compiler-generated
|
* epilogue sequences for Reset_Handler. We don't want MSP is updated by compiler-generated
|
||||||
* code during stack switch. */
|
* code during stack switch.
|
||||||
|
*
|
||||||
|
* Don't allow extended assembly in naked functions:
|
||||||
|
* The compiler only supports basic __asm statements in __attribute__((naked))
|
||||||
|
* functions. Using extended assembly, parameter references or mixing C code with
|
||||||
|
* __asm statements might not work reliably.
|
||||||
|
*/
|
||||||
__attribute__((naked)) void Reset_Handler(void)
|
__attribute__((naked)) void Reset_Handler(void)
|
||||||
{
|
{
|
||||||
#if !defined(__ICCARM__)
|
#if defined(__GNUC__)
|
||||||
__asm(".syntax unified \n");
|
__asm(".syntax unified \n");
|
||||||
__asm(".globl Reset_Handler_1 \n");
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Secure TFM requires PSP as boot stack */
|
/* Secure TFM requires PSP as boot stack */
|
||||||
#if TFM_LVL != 0
|
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) && (TFM_LVL > 0)
|
||||||
|
/* Get stack limit for PSP */
|
||||||
#if !defined(__ICCARM__)
|
#if !defined(__ICCARM__)
|
||||||
__asm(".globl Image$$ARM_LIB_STACK$$ZI$$Limit \n");
|
__asm("movw r0, #:lower16:StackLimit_PSP \n");
|
||||||
__asm("movw r0, #:lower16:Image$$ARM_LIB_STACK$$ZI$$Limit \n"); // Initialize PSP
|
__asm("movt r0, #:upper16:StackLimit_PSP \n");
|
||||||
__asm("movt r0, #:upper16:Image$$ARM_LIB_STACK$$ZI$$Limit \n");
|
|
||||||
#else
|
#else
|
||||||
__asm(".globl Image$$ARM_LIB_STACK$$ZI$$Limit \n");
|
__asm("mov32 r0, StackLimit_PSP \n");
|
||||||
__asm("mov32 r0, Image$$ARM_LIB_STACK$$ZI$$Limit \n");
|
|
||||||
#endif
|
#endif
|
||||||
|
__asm("blx r0 \n");
|
||||||
|
|
||||||
|
/* Switch from MSP to PSP */
|
||||||
__asm("msr psp, r0 \n");
|
__asm("msr psp, r0 \n");
|
||||||
__asm("mrs r0, control \n"); // Switch SP to PSP
|
__asm("mrs r0, control \n");
|
||||||
__asm("movs r1, #2 \n");
|
__asm("movs r1, #2 \n");
|
||||||
__asm("orrs r0, r1 \n");
|
__asm("orrs r0, r1 \n");
|
||||||
__asm("msr control, r0 \n");
|
__asm("msr control, r0 \n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Jump to Reset_Handler_1 */
|
||||||
#if !defined(__ICCARM__)
|
#if !defined(__ICCARM__)
|
||||||
__asm("movw r0, #:lower16:Reset_Handler_1 \n");
|
__asm("movw r0, #:lower16:Reset_Handler_1 \n");
|
||||||
__asm("movt r0, #:upper16:Reset_Handler_1 \n");
|
__asm("movt r0, #:upper16:Reset_Handler_1 \n");
|
||||||
|
@ -397,15 +420,27 @@ __attribute__((naked)) void Reset_Handler(void)
|
||||||
__asm("bx r0 \n");
|
__asm("bx r0 \n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) && (TFM_LVL > 0)
|
||||||
|
/* Return stack limit for PSP */
|
||||||
|
uint32_t StackLimit_PSP(void)
|
||||||
|
{
|
||||||
|
uint32_t stacklimit_psp;
|
||||||
|
|
||||||
|
__asm volatile (
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
".syntax unified \n"
|
||||||
|
#endif
|
||||||
|
"mov %[Rd], %[Rn] \n"
|
||||||
|
: [Rd] "=r" (stacklimit_psp) /* comma-separated list of output operands */
|
||||||
|
: [Rn] "r" (&Image$$ARM_LIB_STACK$$ZI$$Limit) /* comma-separated list of input operands */
|
||||||
|
: "cc" /* comma-separated list of clobbered resources */
|
||||||
|
);
|
||||||
|
|
||||||
|
return stacklimit_psp;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void Reset_Handler_1(void)
|
void Reset_Handler_1(void)
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
void Reset_Handler(void)
|
|
||||||
|
|
||||||
#endif /* defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
|
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
#if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
|
#if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
|
||||||
/* Disable register write-protection function */
|
/* Disable register write-protection function */
|
||||||
|
|
Loading…
Reference in New Issue