1- /**************************************************************************/ /**
2- * @file startup_M2351.c
3- * @version V2.00
4- * $Revision: 9 $
5- * $Date: 16/08/27 12:33p $
6- * @brief Startup Source File
1+ /*
2+ * Copyright (c) 2018-2019, Nuvoton Technology Corporation
73 *
8- * @note
9- * Copyright (C) 2016 Nuvoton Technology Corp. All rights reserved.
4+ * SPDX-License-Identifier: Apache-2.0
105 *
11- ******************************************************************************/
6+ * Licensed under the Apache License, Version 2.0 (the "License");
7+ * you may not use this file except in compliance with the License.
8+ * You may obtain a copy of the License at
9+ *
10+ * http://www.apache.org/licenses/LICENSE-2.0
11+ *
12+ * Unless required by applicable law or agreed to in writing, software
13+ * distributed under the License is distributed on an "AS IS" BASIS,
14+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+ * See the License for the specific language governing permissions and
16+ * limitations under the License.
17+ */
1218
1319#include "M2351.h"
1420
1521/* Suppress warning messages */
16- #if defined(__CC_ARM )
17- // Suppress warning message: extended constant initialiser used
22+ #if defined(__ARMCC_VERSION )
23+ // Suppress warning message: extended constant initializer used
1824#pragma diag_suppress 1296
1925#elif defined(__ICCARM__ )
26+ // Suppress warning message Pe1665
27+ #pragma diag_suppress=Pe1665
2028#elif defined(__GNUC__ )
2129#endif
2230
2331/* Macro Definitions */
24- #if defined(__CC_ARM )
32+ #if defined(__ARMCC_VERSION )
2533#define WEAK __attribute__ ((weak))
2634#define ALIAS (f ) __attribute__ ((weak, alias(#f)))
2735
@@ -46,22 +54,22 @@ void FUN(void) __attribute__ ((weak, alias(#FUN_ALIAS)));
4654
4755#endif
4856
49-
5057/* Initialize segments */
51- #if defined(__CC_ARM ) || (defined( __ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6010050 ) )
58+ #if defined(__ARMCC_VERSION )
5259extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Limit ;
5360extern void __main (void );
5461#elif defined(__ICCARM__ )
62+ extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Limit ;
63+ extern uint32_t CSTACK$$Limit ;
5564void __iar_program_start (void );
5665#elif defined(__GNUC__ )
66+ extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Limit ;
5767extern uint32_t __StackTop ;
58- extern uint32_t __etext ;
59- extern uint32_t __data_start__ ;
60- extern uint32_t __data_end__ ;
61- extern uint32_t __bss_start__ ;
62- extern uint32_t __bss_end__ ;
68+ extern uint32_t __copy_table_start__ ;
69+ extern uint32_t __copy_table_end__ ;
70+ extern uint32_t __zero_table_start__ ;
71+ extern uint32_t __zero_table_end__ ;
6372
64- extern void uvisor_init (void );
6573#if defined(TOOLCHAIN_GCC_ARM )
6674extern void _start (void );
6775#else
@@ -87,7 +95,7 @@ WEAK_ALIAS_FUNC(SysTick_Handler, Default_Handler)
8795WEAK_ALIAS_FUNC (BOD_IRQHandler , Default_Handler ) // 0: Brown Out detection
8896WEAK_ALIAS_FUNC (IRC_IRQHandler , Default_Handler ) // 1: Internal RC
8997WEAK_ALIAS_FUNC (PWRWU_IRQHandler , Default_Handler ) // 2: Power down wake up
90- WEAK_ALIAS_FUNC (SRAM_IRQHandler , Default_Handler ) // 3: SRAM
98+ WEAK_ALIAS_FUNC (SRAM_IRQHandler , Default_Handler ) // 3: SRAM
9199WEAK_ALIAS_FUNC (CLKFAIL_IRQHandler , Default_Handler ) // 4: Clock detection fail
92100 // 5: Reserved
93101WEAK_ALIAS_FUNC (RTC_IRQHandler , Default_Handler ) // 6: Real Time Clock
@@ -106,16 +114,16 @@ WEAK_ALIAS_FUNC(GPC_IRQHandler, Default_Handler) // 18: GPIO Port C
106114WEAK_ALIAS_FUNC (GPD_IRQHandler , Default_Handler ) // 19: GPIO Port D
107115WEAK_ALIAS_FUNC (GPE_IRQHandler , Default_Handler ) // 20: GPIO Port E
108116WEAK_ALIAS_FUNC (GPF_IRQHandler , Default_Handler ) // 21: GPIO Port F
109- WEAK_ALIAS_FUNC (QSPI0_IRQHandler , Default_Handler ) // 22: SPI0
117+ WEAK_ALIAS_FUNC (QSPI0_IRQHandler , Default_Handler ) // 22: SPI0
110118WEAK_ALIAS_FUNC (SPI0_IRQHandler , Default_Handler ) // 23: SPI1
111119WEAK_ALIAS_FUNC (BRAKE0_IRQHandler , Default_Handler ) // 24:
112- WEAK_ALIAS_FUNC (EPWM0_P0_IRQHandler , Default_Handler ) // 25:
113- WEAK_ALIAS_FUNC (EPWM0_P1_IRQHandler , Default_Handler ) // 26:
114- WEAK_ALIAS_FUNC (EPWM0_P2_IRQHandler , Default_Handler ) // 27:
120+ WEAK_ALIAS_FUNC (EPWM0_P0_IRQHandler , Default_Handler ) // 25:
121+ WEAK_ALIAS_FUNC (EPWM0_P1_IRQHandler , Default_Handler ) // 26:
122+ WEAK_ALIAS_FUNC (EPWM0_P2_IRQHandler , Default_Handler ) // 27:
115123WEAK_ALIAS_FUNC (BRAKE1_IRQHandler , Default_Handler ) // 28:
116- WEAK_ALIAS_FUNC (EPWM1_P0_IRQHandler , Default_Handler ) // 29:
117- WEAK_ALIAS_FUNC (EPWM1_P1_IRQHandler , Default_Handler ) // 30:
118- WEAK_ALIAS_FUNC (EPWM1_P2_IRQHandler , Default_Handler ) // 31:
124+ WEAK_ALIAS_FUNC (EPWM1_P0_IRQHandler , Default_Handler ) // 29:
125+ WEAK_ALIAS_FUNC (EPWM1_P1_IRQHandler , Default_Handler ) // 30:
126+ WEAK_ALIAS_FUNC (EPWM1_P2_IRQHandler , Default_Handler ) // 31:
119127WEAK_ALIAS_FUNC (TMR0_IRQHandler , Default_Handler ) // 32: Timer 0
120128WEAK_ALIAS_FUNC (TMR1_IRQHandler , Default_Handler ) // 33: Timer 1
121129WEAK_ALIAS_FUNC (TMR2_IRQHandler , Default_Handler ) // 34: Timer 2
@@ -124,7 +132,7 @@ WEAK_ALIAS_FUNC(UART0_IRQHandler, Default_Handler) // 36: UART0
124132WEAK_ALIAS_FUNC (UART1_IRQHandler , Default_Handler ) // 37: UART1
125133WEAK_ALIAS_FUNC (I2C0_IRQHandler , Default_Handler ) // 38: I2C0
126134WEAK_ALIAS_FUNC (I2C1_IRQHandler , Default_Handler ) // 39: I2C1
127- WEAK_ALIAS_FUNC (PDMA0_IRQHandler , Default_Handler ) // 40: Peripheral DMA
135+ WEAK_ALIAS_FUNC (PDMA0_IRQHandler , Default_Handler ) // 40: Peripheral DMA
128136WEAK_ALIAS_FUNC (DAC_IRQHandler , Default_Handler ) // 41: DAC
129137WEAK_ALIAS_FUNC (EADC0_IRQHandler , Default_Handler ) // 42: ADC0 interrupt source 0
130138WEAK_ALIAS_FUNC (EADC1_IRQHandler , Default_Handler ) // 43: ADC0 interrupt source 1
@@ -177,26 +185,24 @@ WEAK_ALIAS_FUNC(DSRC_IRQHandler, Default_Handler) // 97:
177185WEAK_ALIAS_FUNC (PDMA1_IRQHandler , Default_Handler ) // 98:
178186WEAK_ALIAS_FUNC (SCU_IRQHandler , Default_Handler ) // 99:
179187 // 100: Reserved
180- WEAK_ALIAS_FUNC (TRNG_IRQHandler , Default_Handler ) // 101:
188+ WEAK_ALIAS_FUNC (TRNG_IRQHandler , Default_Handler ) // 101:
181189
182190
183191/* Vector table */
184- #if defined(__CC_ARM ) || (defined( __ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6010050 ) )
185- __attribute__ ((section ("RESET" )))
192+ #if defined(__ARMCC_VERSION )
193+ __attribute__ ((section ("RESET" ), used ))
186194const uint32_t __vector_handlers [] = {
187195#elif defined(__ICCARM__ )
188- extern uint32_t CSTACK$$Limit ;
189196const uint32_t __vector_table [] @ ".intvec" = {
190197#elif defined(__GNUC__ )
191198__attribute__ ((section (".vector_table" )))
192199const uint32_t __vector_handlers [ ] = {
193200#endif
194201
195202 /* Configure Initial Stack Pointer, using linker-generated symbols */
196- #if defined(__CC_ARM ) || (defined( __ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6010050 ) )
203+ #if defined(__ARMCC_VERSION )
197204 (uint32_t ) & Image$$ARM_LIB_STACK$$ZI$$Limit ,
198205#elif defined(__ICCARM__ )
199- //(uint32_t) __sfe("CSTACK"),
200206 (uint32_t ) & CSTACK$$Limit ,
201207#elif defined(__GNUC__ )
202208 (uint32_t ) & __StackTop ,
@@ -323,12 +329,48 @@ const uint32_t __vector_handlers[] = {
323329 (uint32_t ) TRNG_IRQHandler , // 101:
324330};
325331
326- /**
327- * \brief This is the code that gets called on processor reset.
332+ /* Some reset handler code cannot implement in pure C. Implement it in inline/embedded assembly.
333+ *
334+ * Reset_Handler:
335+ * For non-secure PSA/non-secure non-PSA/secure non-PSA, jump directly to Reset_Handler_1
336+ * For secure PSA, switch from MSP to PSP, then jump to Reset_Handler_1
337+ *
338+ * Reset_Handler_1:
339+ * Platform initialization
340+ * C/C++ runtime initialization
341+ */
342+
343+ /* Forward declaration */
344+ void Reset_Handler_1 (void );
345+
346+ /* Add '__attribute__((naked))' here to make sure compiler does not generate prologue and
347+ * epilogue sequences for Reset_Handler. We don't want MSP is updated by compiler-generated
348+ * code during stack switch.
349+ *
350+ * Don't allow extended assembly in naked functions:
351+ * The compiler only supports basic __asm statements in __attribute__((naked))
352+ * functions. Using extended assembly, parameter references or mixing C code with
353+ * __asm statements might not work reliably.
328354 */
329- void Reset_Handler (void )
355+ __attribute__((naked )) void Reset_Handler (void )
356+ {
357+ #if defined(__GNUC__ )
358+ __asm(".syntax unified \n" );
359+ #endif
360+
361+ /* Jump to Reset_Handler_1 */
362+ #if !defined(__ICCARM__ )
363+ __asm("movw r0, #:lower16:Reset_Handler_1 \n" );
364+ __asm("movt r0, #:upper16:Reset_Handler_1 \n" );
365+ #else
366+ __asm("mov32 r0, Reset_Handler_1 \n" );
367+ #endif
368+ __asm("bx r0 \n" );
369+ }
370+
371+ void Reset_Handler_1 (void )
330372{
331- #if defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3U )
373+ #if defined(__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3U )
332374 /* Disable register write-protection function */
333375 SYS_UnlockReg ();
334376
@@ -339,38 +381,61 @@ void Reset_Handler(void)
339381 SYS_LockReg ();
340382#endif
341383
342- /**
343- * SystemInit() must be called at the very start.
344- */
384+ /* SystemInit() must be called at the very start. */
345385 SystemInit ();
346386
347- #if defined(__CC_ARM ) || (defined( __ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6010050 ) )
387+ #if defined(__ARMCC_VERSION )
348388 __main ();
349389
350390#elif defined(__ICCARM__ )
351391 __iar_program_start ();
352392
353393#elif defined(__GNUC__ )
354- uint32_t * src_ind = (uint32_t * ) & __etext ;
355- uint32_t * dst_ind = (uint32_t * ) & __data_start__ ;
356- uint32_t * dst_end = (uint32_t * ) & __data_end__ ;
357-
358- /* Move .data section from ROM to RAM */
359- if (src_ind != dst_ind ) {
360- for (; dst_ind < dst_end ;) {
361- * dst_ind ++ = * src_ind ++ ;
394+ /* Move (multiple) .data section(s) from ROM to RAM */
395+ {
396+ /* Struct of copy table entry which must match linker script */
397+ typedef struct copy_table_entry_ {
398+ uint32_t src ; // Address to copy from
399+ uint32_t dst ; // Address to copy to
400+ uint32_t size ; // Copy size in bytes
401+ } copy_table_entry ;
402+
403+ copy_table_entry * copy_table_ind = (copy_table_entry * ) & __copy_table_start__ ;
404+ copy_table_entry * copy_table_end = (copy_table_entry * ) & __copy_table_end__ ;
405+
406+ for (; copy_table_ind != copy_table_end ; copy_table_ind ++ ) {
407+ uint32_t * src_ind = (uint32_t * ) copy_table_ind -> src ;
408+ uint32_t * src_end = (uint32_t * ) (copy_table_ind -> src + copy_table_ind -> size );
409+ uint32_t * dst_ind = (uint32_t * ) copy_table_ind -> dst ;
410+ if (src_ind != dst_ind ) {
411+ for (; src_ind < src_end ;) {
412+ * dst_ind ++ = * src_ind ++ ;
413+ }
414+ }
362415 }
363416 }
364-
365- /* Initialize .bss section to zero */
366- dst_ind = (uint32_t * ) & __bss_start__ ;
367- dst_end = (uint32_t * ) & __bss_end__ ;
368- if (dst_ind != dst_end ) {
369- for (; dst_ind < dst_end ;) {
370- * dst_ind ++ = 0 ;
417+
418+ /* Initialize (multiple) .bss sections to zero */
419+ {
420+ /* Struct of zero table entry which must match linker script */
421+ typedef struct zero_table_entry_ {
422+ uint32_t start ; // Address to start zero'ing
423+ uint32_t size ; // Zero size in bytes
424+ } zero_table_entry ;
425+
426+ zero_table_entry * zero_table_ind = (zero_table_entry * ) & __zero_table_start__ ;
427+ zero_table_entry * zero_table_end = (zero_table_entry * ) & __zero_table_end__ ;
428+
429+ for (; zero_table_ind != zero_table_end ; zero_table_ind ++ ) {
430+ uint32_t * dst_ind = (uint32_t * ) zero_table_ind -> start ;
431+ uint32_t * dst_end = (uint32_t * ) (zero_table_ind -> start + zero_table_ind -> size );
432+
433+ for (; dst_ind < dst_end ; ) {
434+ * dst_ind ++ = 0 ;
435+ }
371436 }
372437 }
373-
438+
374439 _start ();
375440
376441#endif
@@ -386,18 +451,3 @@ void Default_Handler(void)
386451{
387452 while (1 );
388453}
389-
390- #if 0
391- #if defined(__CC_ARM )
392- uint32_t GetPC (void )
393- {
394- uint32_t val = 0 ;
395- __asm {
396- MOV R0 , #0 // dumy
397- //MOV R0, LR // Except R0~R12, SP/LR/PC cannot be read or directly modified in inline assembly code
398- MOV val , R0
399- }
400- return val ;
401- }
402- #endif
403- #endif
0 commit comments