1 /******************************************************************************
2  * @file     startup_ARMCA9.c
3  * @brief    CMSIS Device System Source File for Arm Cortex-A9 Device Series
4  * @version  V1.0.1
5  * @date     10. January 2021
6  ******************************************************************************/
7 /*
8  * Copyright (c) 2009-2021 Arm Limited. All rights reserved.
9  *
10  * SPDX-License-Identifier: Apache-2.0
11  *
12  * Licensed under the Apache License, Version 2.0 (the License); you may
13  * not use this file except in compliance with the License.
14  * You may obtain a copy of the License at
15  *
16  * www.apache.org/licenses/LICENSE-2.0
17  *
18  * Unless required by applicable law or agreed to in writing, software
19  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
20  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21  * See the License for the specific language governing permissions and
22  * limitations under the License.
23  */
24 
25 #include <ARMCA9.h>
26 
27 /*----------------------------------------------------------------------------
28   Definitions
29  *----------------------------------------------------------------------------*/
30 #define USR_MODE 0x10            // User mode
31 #define FIQ_MODE 0x11            // Fast Interrupt Request mode
32 #define IRQ_MODE 0x12            // Interrupt Request mode
33 #define SVC_MODE 0x13            // Supervisor mode
34 #define ABT_MODE 0x17            // Abort mode
35 #define UND_MODE 0x1B            // Undefined Instruction mode
36 #define SYS_MODE 0x1F            // System mode
37 
38 /*----------------------------------------------------------------------------
39   Internal References
40  *----------------------------------------------------------------------------*/
41 void Vectors        (void) __attribute__ ((naked, section("RESET")));
42 void Reset_Handler  (void) __attribute__ ((naked));
43 void Default_Handler(void) __attribute__ ((noreturn));
44 
45 /*----------------------------------------------------------------------------
46   Exception / Interrupt Handler
47  *----------------------------------------------------------------------------*/
48 void Undef_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
49 void SVC_Handler   (void) __attribute__ ((weak, alias("Default_Handler")));
50 void PAbt_Handler  (void) __attribute__ ((weak, alias("Default_Handler")));
51 void DAbt_Handler  (void) __attribute__ ((weak, alias("Default_Handler")));
52 void IRQ_Handler   (void) __attribute__ ((weak, alias("Default_Handler")));
53 void FIQ_Handler   (void) __attribute__ ((weak, alias("Default_Handler")));
54 
55 /*----------------------------------------------------------------------------
56   Exception / Interrupt Vector Table
57  *----------------------------------------------------------------------------*/
Vectors(void)58 void Vectors(void) {
59   __ASM volatile(
60   "LDR    PC, =Reset_Handler                        \n"
61   "LDR    PC, =Undef_Handler                        \n"
62   "LDR    PC, =SVC_Handler                          \n"
63   "LDR    PC, =PAbt_Handler                         \n"
64   "LDR    PC, =DAbt_Handler                         \n"
65   "NOP                                              \n"
66   "LDR    PC, =IRQ_Handler                          \n"
67   "LDR    PC, =FIQ_Handler                          \n"
68   );
69 }
70 
71 /*----------------------------------------------------------------------------
72   Reset Handler called on controller reset
73  *----------------------------------------------------------------------------*/
Reset_Handler(void)74 void Reset_Handler(void) {
75   __ASM volatile(
76 
77   // Mask interrupts
78   "CPSID   if                                      \n"
79 
80   // Put any cores other than 0 to sleep
81   "MRC     p15, 0, R0, c0, c0, 5                   \n"  // Read MPIDR
82   "ANDS    R0, R0, #3                              \n"
83   "goToSleep:                                      \n"
84   "WFINE                                           \n"
85   "BNE     goToSleep                               \n"
86 
87   // Reset SCTLR Settings
88   "MRC     p15, 0, R0, c1, c0, 0                   \n"  // Read CP15 System Control register
89   "BIC     R0, R0, #(0x1 << 12)                    \n"  // Clear I bit 12 to disable I Cache
90   "BIC     R0, R0, #(0x1 <<  2)                    \n"  // Clear C bit  2 to disable D Cache
91   "BIC     R0, R0, #0x1                            \n"  // Clear M bit  0 to disable MMU
92   "BIC     R0, R0, #(0x1 << 11)                    \n"  // Clear Z bit 11 to disable branch prediction
93   "BIC     R0, R0, #(0x1 << 13)                    \n"  // Clear V bit 13 to disable hivecs
94   "MCR     p15, 0, R0, c1, c0, 0                   \n"  // Write value back to CP15 System Control register
95   "ISB                                             \n"
96 
97   // Configure ACTLR
98   "MRC     p15, 0, r0, c1, c0, 1                   \n"  // Read CP15 Auxiliary Control Register
99   "ORR     r0, r0, #(1 <<  1)                      \n"  // Enable L2 prefetch hint (UNK/WI since r4p1)
100   "MCR     p15, 0, r0, c1, c0, 1                   \n"  // Write CP15 Auxiliary Control Register
101 
102   // Set Vector Base Address Register (VBAR) to point to this application's vector table
103   "LDR    R0, =Vectors                             \n"
104   "MCR    p15, 0, R0, c12, c0, 0                   \n"
105 
106   // Setup Stack for each exceptional mode
107   "CPS    #0x11                                    \n"
108   "LDR    SP, =Image$$FIQ_STACK$$ZI$$Limit         \n"
109   "CPS    #0x12                                    \n"
110   "LDR    SP, =Image$$IRQ_STACK$$ZI$$Limit         \n"
111   "CPS    #0x13                                    \n"
112   "LDR    SP, =Image$$SVC_STACK$$ZI$$Limit         \n"
113   "CPS    #0x17                                    \n"
114   "LDR    SP, =Image$$ABT_STACK$$ZI$$Limit         \n"
115   "CPS    #0x1B                                    \n"
116   "LDR    SP, =Image$$UND_STACK$$ZI$$Limit         \n"
117   "CPS    #0x1F                                    \n"
118 #if defined ( __GNUC__ )
119   "LDR    SP, =Image$$SYS_STACK$$ZI$$Limit         \n"
120 #else
121   "LDR    SP, =Image$$ARM_LIB_STACK$$ZI$$Limit     \n"
122 #endif
123 
124   // Call SystemInit
125   "BL     SystemInit                               \n"
126 
127   // Unmask interrupts
128   "CPSIE  if                                       \n"
129 
130   // Call __main
131 #if defined ( __GNUC__ )
132   "BL     _start                                  \n"
133 #else
134   "BL     __main                                  \n"
135 #endif
136   );
137 }
138 
139 /*----------------------------------------------------------------------------
140   Default Handler for Exceptions / Interrupts
141  *----------------------------------------------------------------------------*/
Default_Handler(void)142 void Default_Handler(void) {
143   while(1);
144 }
145