c9db5f5ea729dc745dfcf779e734aa4ca56960f0
[fw/openocd] / testing / examples / STR710Test / src / crt.s
1 /****************************************************************************
2 *  Copyright (c) 2006 by Michael Fischer. All rights reserved.
3 *
4 *  Redistribution and use in source and binary forms, with or without
5 *  modification, are permitted provided that the following conditions
6 *  are met:
7 *
8 *  1. Redistributions of source code must retain the above copyright
9 *     notice, this list of conditions and the following disclaimer.
10 *  2. Redistributions in binary form must reproduce the above copyright
11 *     notice, this list of conditions and the following disclaimer in the
12 *     documentation and/or other materials provided with the distribution.
13 *  3. Neither the name of the author nor the names of its contributors may
14 *     be used to endorse or promote products derived from this software
15 *     without specific prior written permission.
16 *
17 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
20 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21 *  THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
24 *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25 *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
27 *  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 *  SUCH DAMAGE.
29 *
30 ****************************************************************************
31 *
32 *  History:
33 *
34 *  04.03.06  mifi   First Version
35 *                   This version based on an example from Ethernut and
36 *                   "ARM Cross Development with Eclipse" from James P. Lynch
37 *
38 *  26.01.08  mifi   Change the code of the init section. Here I have used
39 *                   some of the source from the Anglia startup.s
40 *                   Author: Spencer Oliver (www.anglia-designs.com)
41 ****************************************************************************/
42
43 /*
44  * Some defines for the program status registers
45  */
46    ARM_MODE_USER  = 0x10      /* Normal User Mode                                                 */
47    ARM_MODE_FIQ   = 0x11      /* FIQ Fast Interrupts Mode                                     */
48    ARM_MODE_IRQ   = 0x12      /* IRQ Standard Interrupts Mode                         */
49    ARM_MODE_SVC   = 0x13      /* Supervisor Interrupts Mode                           */
50    ARM_MODE_ABORT = 0x17      /* Abort Processing memory Faults Mode              */
51    ARM_MODE_UNDEF = 0x1B      /* Undefined Instructions Mode                      */
52    ARM_MODE_SYS   = 0x1F      /* System Running in Priviledged Operating Mode */
53    ARM_MODE_MASK  = 0x1F
54
55    I_BIT          = 0x80      /* disable IRQ when I bit is set */
56    F_BIT          = 0x40      /* disable IRQ when I bit is set */
57
58 /*
59  * Register Base Address
60  */
61    PRCCU_BASE     = 0xA0000000
62    RCCU_CFR       = 0x08
63    RCCU_PLL1CR    = 0x18
64    PCU_MDIVR      = 0x40
65    PCU_PDIVR      = 0x44
66    PCU_BOOTCR     = 0x50
67
68
69    .section .vectors,"ax"
70    .code 32
71
72 /****************************************************************************/
73 /*               Vector table and reset entry                               */
74 /****************************************************************************/
75 _vectors:
76    ldr pc, ResetAddr    /* Reset                 */
77    ldr pc, UndefAddr    /* Undefined instruction */
78    ldr pc, SWIAddr      /* Software interrupt    */
79    ldr pc, PAbortAddr   /* Prefetch abort        */
80    ldr pc, DAbortAddr   /* Data abort            */
81    ldr pc, ReservedAddr /* Reserved              */
82    ldr pc, IRQAddr      /* IRQ interrupt         */
83    ldr pc, FIQAddr      /* FIQ interrupt         */
84
85
86 ResetAddr:     .word ResetHandler
87 UndefAddr:     .word UndefHandler
88 SWIAddr:       .word SWIHandler
89 PAbortAddr:    .word PAbortHandler
90 DAbortAddr:    .word DAbortHandler
91 ReservedAddr:  .word 0
92 IRQAddr:       .word IRQHandler
93 FIQAddr:       .word FIQHandler
94
95    .ltorg
96
97
98    .section .init, "ax"
99    .code 32
100
101    .global ResetHandler
102    .global ExitFunction
103    .extern main
104 /****************************************************************************/
105 /*                           Reset handler                                  */
106 /****************************************************************************/
107 ResetHandler:
108 /*
109  * Wait for the oscillator is stable
110  */
111    nop
112    nop
113    nop
114    nop
115    nop
116    nop
117    nop
118    nop
119
120 /*
121  * Setup STR71X, for more information about the register
122  * take a look in the STR71x Microcontroller Reference Manual.
123  *
124  * Reference is made to: Rev. 6 March 2005
125  *
126  * 1. Map internal RAM to address 0
127  *    In this case, we are running always in the RAM
128  *    this make no sence. But if we are in flash, we
129  *    can copy the interrupt vectors into the ram and
130  *    switch to RAM mode.
131  *
132  * 2. Setup the PLL, the eval board HITEX STR7 is equipped
133  *    with an external 16MHz oscillator. We want:
134  *
135  *    RCLK:  32MHz = (CLK2 * 16) / 4
136  *    MCLK:  32Mhz
137  *    PCLK1: 32MHz
138  *    PCLK2: 32MHz
139  *
140  */
141
142    /*
143     * 1. Map RAM to the boot memory 0x00000000
144     */
145    ldr   r0, =PRCCU_BASE
146    ldr   r1, =0x01C2
147    str   r1, [r0, #PCU_BOOTCR]
148
149
150    /*
151     * 2. Setup PLL start
152     */
153
154    /* Set the prescaling factor for APB and APB1 group */
155    ldr   r0, =PRCCU_BASE
156    ldr   r1, =0x0000             /* no prescaling PCLKx = RCLK */
157    str   r1, [r0, #PCU_PDIVR]
158
159    /* Set the prescaling factor for the Main System Clock MCLK */
160    ldr   r0, =PRCCU_BASE
161    ldr   r1, =0x0000             /* no prescaling MCLK = RCLK
162    str   r1, [r0, #PCU_MDIVR]
163
164    /* Configure the PLL1 ( * 16 , / 4 ) */
165    ldr   r0, =PRCCU_BASE
166    ldr   r1, =0x0073
167    str   r1, [r0, #RCCU_PLL1CR]
168
169    /* Check if the PLL is locked */
170 pll_lock_loop:
171    ldr   r1, [r0, #RCCU_CFR]
172    tst   r1, #0x0002
173    beq   pll_lock_loop
174
175    /*  Select PLL1_Output as RCLK clock */
176    ldr   r0, =PRCCU_BASE
177    ldr   r1, =0x8009
178    str   r1, [r0, #RCCU_CFR]
179
180    /*
181     * Setup PLL end
182     */
183
184
185    /*
186     * Setup a stack for each mode
187     */
188    msr   CPSR_c, #ARM_MODE_UNDEF | I_BIT | F_BIT   /* Undefined Instruction Mode */
189    ldr   sp, =__stack_und_end__
190
191    msr   CPSR_c, #ARM_MODE_ABORT | I_BIT | F_BIT   /* Abort Mode */
192    ldr   sp, =__stack_abt_end__
193
194    msr   CPSR_c, #ARM_MODE_FIQ | I_BIT | F_BIT     /* FIQ Mode */
195    ldr   sp, =__stack_fiq_end__
196
197    msr   CPSR_c, #ARM_MODE_IRQ | I_BIT | F_BIT     /* IRQ Mode */
198    ldr   sp, =__stack_irq_end__
199
200    msr   CPSR_c, #ARM_MODE_SVC | I_BIT | F_BIT     /* Supervisor Mode */
201    ldr   sp, =__stack_svc_end__
202
203
204    /*
205     * Now init all the sections
206     */
207
208
209    /*
210     * Relocate .data section (Copy from ROM to RAM)
211     */
212          ldr   r1, =_etext
213          ldr   r2, =__data_start
214          ldr   r3, =_edata
215 LoopRel:
216          cmp   r2, r3
217          ldrlo r0, [r1], #4
218          strlo r0, [r2], #4
219          blo   LoopRel
220
221
222    /*
223     * Clear .bss section (Zero init)
224     */
225          mov   r0, #0
226          ldr   r1, =__bss_start__
227          ldr   r2, =__bss_end__
228 LoopZI:
229          cmp   r1, r2
230          strlo r0, [r1], #4
231          blo   LoopZI
232
233
234    /*
235     * Call C++ constructors
236     */
237          ldr     r0, =__ctors_start__
238          ldr     r1, =__ctors_end__
239 ctor_loop:
240          cmp     r0, r1
241          beq     ctor_end
242          ldr     r2, [r0], #4
243          stmfd sp!, {r0-r1}
244          mov     lr, pc
245          mov     pc, r2
246          ldmfd sp!, {r0-r1}
247          b               ctor_loop
248 ctor_end:
249
250
251    /*
252     * Jump to main
253     */
254    mrs   r0, cpsr
255    bic   r0, r0, #I_BIT | F_BIT     /* Enable FIQ and IRQ interrupt */
256    msr   cpsr, r0
257
258    mov   r0, #0 /* No arguments */
259    mov   r1, #0 /* No arguments */
260    ldr   r2, =main
261    mov   lr, pc
262    bx    r2     /* And jump... */
263
264 ExitFunction:
265    nop
266    nop
267    nop
268    b ExitFunction
269
270
271 /****************************************************************************/
272 /*                         Default interrupt handler                        */
273 /****************************************************************************/
274
275 UndefHandler:
276    b UndefHandler
277
278 SWIHandler:
279    b SWIHandler
280
281 PAbortHandler:
282    b PAbortHandler
283
284 DAbortHandler:
285    b DAbortHandler
286
287 IRQHandler:
288    b IRQHandler
289
290 FIQHandler:
291    b FIQHandler
292
293    .weak ExitFunction
294    .weak UndefHandler, PAbortHandler, DAbortHandler
295    .weak IRQHandler, FIQHandler
296
297    .ltorg
298 /*** EOF ***/
299