summaryrefslogtreecommitdiff
path: root/firmware/target/arm/tms320dm320/crt0.S
blob: e57e28a470fa5261ebd4f13ad2ad771610353bce (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
/***************************************************************************
 *             __________               __   ___.
 *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
 *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
 *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
 *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
 *                     \/            \/     \/    \/            \/
 * $Id$
 *
 * Copyright (C) 2010 by Karl Kurbjun
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 ****************************************************************************/
#include "config.h"
#include "cpu.h"

#define CACHE_NONE  0
#define CACHE_ALL   0x0C
#define BUFFERED    0x04

#define LONG_VECTORS 1

/******************************************************************************
 * vectors:                                                                   *
 *    This is the ARM vector table                                            *
 * Long call exception handlers are used for simplicity between flash         *
 * bootloader and SDRAM main-application.  These need to be copied to address *
 * 0x0 at start.                                                              *
 ******************************************************************************/
.section .vectors,"ax"
.code 32

.global _vectors
@entry:
_vectors:

#if defined(SHORT_VECTORS) /* Use relative branch vectors (64 MB limit) */
   b        _start                    /* Reset Vector            */
   b        undef_instr_handler       /* Undefined instruction   */
   b        software_int_handler      /* Software Vector         */
   b        prefetch_abort_handler    /* Prefetch Abort          */
   b        data_abort_handler        /* Data Abort              */
   b        reserved_handler          /* Reserved/Unused         */
   b        irq_handler               /* IRQ vector              */
   b        fiq_handler               /* FIQ vector              */
#else
#if defined(LONG_VECTORS)
   /* Load the PC with the word values stored below */
   ldr      pc, [pc, #0x18]   /* Reset */
   ldr      pc, [pc, #0x18]   /* Undefined instruction   */
   ldr      pc, [pc, #0x18]   /* Software interrupt      */
   ldr      pc, [pc, #0x18]   /* Prefetch Abort          */
   ldr      pc, [pc, #0x18]   /* Data Abort              */
   ldr      pc, [pc, #0x18]   /* Reserved/Unused         */
   ldr      pc, [pc, #0x18]   /* IRQ                     */
   ldr      pc, [pc, #0x18]   /* FIQ                     */
   
   /* Addresses of the handlers */
   .word    _start
   .word    undef_instr_handler
   .word    software_int_handler
   .word    prefetch_abort_handler
   .word    data_abort_handler
   .word    reserved_handler
   .word    irq_handler
   .word    fiq_handler
#else
    #error Vector type undefined
#endif
#endif

/******************************************************************************
 * _start:                                                                    *
 *    This is the main entry point to the program                             *
 ******************************************************************************/
.section    .init, "ax"
.code       32
.align      0x04
.global     _start
_start:
    /* Go into supervisor state with IRQ's disabled.
     * This register is described in section "A2.5 Program status registers" 
     * of the "ARM Architecture Reference Manual".
     */
    msr     cpsr, #0xd3
    
    /* Disable all the fancy stuff */
    mov     r0, #0
    mcr     p15, 0, r0, c1, c0, 0

    /* Disable data and instruction cache, high vectors (at 0xffff0000 instead
     * of 0x00000000)
     */
    mrc    p15, 0, r0, c1, c0, 0
    /* clear bits 13, 9:8 (--VI --RS) */
    bic    r0, r0, #0x00003300
    /* clear bits 7, 2:0 (B--- -C-M) */
    bic    r0, r0, #0x00000085
    /* make sure bit 2 (A) Align is set */
    orr    r0, r0, #0x00000002
    mcr    p15, 0, r0, c1, c0, 0

    /* Add a few cycles of delay before continuing due to system requirements */
    mov     r0, #0x20
    bl      _delay_cycles

#if defined(BOOTLOADER) && !defined(CREATIVE_ZVx)
    bl      _init_board
#endif

    /* Copy exception handler code to address 0 */
    ldr     r0, =_vectorscopy
    ldr     r1, =_vectorsstart
    ldr     r2, =_vectorsend
    bl      _copy_section

#if !defined(SANSA_CONNECT)
    /* Add some delay time to make sure JTAG can be accessed cleanly */
    mov     r0, #0x100000
    bl      _delay_cycles
#endif

#if defined(BOOTLOADER)
    /* Copy the DRAM */
    ldr     r0, =_dramcopy
    ldr     r1, =_dramstart
    ldr     r2, =_dramend
    bl      _copy_section
#endif

    /* Zero out the IBSS */
    mov     r0, #0
    ldr     r1, =_ibss_start
    ldr     r2, =_ibss_end
    bl      _init_section

    /* Copy the IRAM */
    ldr     r0, =_iramcopy
    ldr     r1, =_iramstart
    ldr     r2, =_iramend
    bl      _copy_section

    /* Zero out the BSS */
    mov     r0, #0
    ldr     r1, =_bss_start
    ldr     r2, =_bss_end
    bl      _init_section

    /* Initialize fiq stack */
    ldr     r0, =0xDEADBEEF
    ldr     r1, =_fiq_stack_end     /* Stack counts backwards, so end is first*/
    ldr     r2, =_fiq_stack_start
    bl      _init_section

    msr     cpsr_c, #0xd1           /* Go into fiq state */
    ldr     sp, =_fiq_stack_start   /* set the fiq stack pointer */

    /* Initialize irq stack */
    ldr     r0, =0xDEADBEEF         /* Can be taken out; left for clarity */
    ldr     r1, =_irq_stack_end     /* Stack counts backwards, so end is first*/
    ldr     r2, =_irq_stack_start
    bl      _init_section

    msr     cpsr_c, #0xd2           /* Go into irq state */
    ldr     sp, =_irq_stack_start   /* set the irq stack pointer */

    /* SVC, ABT, UNDEF share irq stack */
    msr     cpsr_c, #0xd3           /* Go into svc state */
    ldr     sp, =_irq_stack_start /* set svc stack pointer */

    msr     cpsr_c, #0xd7                    /* Go into abort state */
    ldr     sp, =_irq_stack_start   /* set the stack pointer */

    msr     cpsr_c, #0xdb                    /* Go into undefined state */
    ldr     sp, =_irq_stack_start   /* set the stack pointer */

    /* Initialize program stack */
    msr     cpsr_c, #0xdf           /* Go into sys state */

    ldr     r0, =0xDEADBEEF         /* Can be taken out; left for clarity */
    ldr     r1, =_pro_stack_end     /* Stack counts backwards, so end is first*/
    ldr     r2, =_pro_stack_start
    bl      _init_section

    ldr     sp, =_pro_stack_start   /* set the sys stack pointer */

    /* MMU initialization */ 
    bl      ttb_init

    /* Make sure everything is mapped on itself */
    ldr     r0, =0x0
    ldr     r1, =0x0
    ldr     r2, =0x1000
    mov     r3, #CACHE_NONE
    bl      map_section

    /* Enable write-through caching for FLASH */
    ldr     r0, =_flash_start
    ldr     r1, =_flash_start
    ldr     r2, =_flash_sizem
    mov     r3, #(CACHE_ALL & ~BUFFERED)
    bl      map_section

    /* Enable write-back caching for RAM */
    ldr     r0, =_sdram_start
    ldr     r1, =_sdram_start
    ldr     r2, =_sdram_sizem
    mov     r3, #CACHE_ALL
    bl      map_section

    bl      enable_mmu  

    /* Initial setup is complete, go into main */
    ldr      pc, =main

    /* If main returns go into an infinite loop */
    b        _dead_loop

/* Constants go here (from _start - .ltorg): */
.ltorg

/******************************************************************************
 * _init_section:                                                             *
 *    This function initializes a section with the 32-bit value specified.    *
 ******************************************************************************/
.section    .init, "ax"
.code       32
.align      0x04
.global     _init_section
.type       _init_section, %function
/* r0 = init value
 * r1 = start location
 * r2 = end location
 */

/* This function will not run if end is less than or equal to start */
_init_section:
   cmp      r2, r1
   strhi    r0, [r1], #4            /* store and increment start location */
   bhi      _init_section
   bx       lr
.ltorg  
.size       _init_section, .-_init_section

/******************************************************************************
 * _copy_section:                                                             *
 *    This function copies a section to a new location                        *
 ******************************************************************************/
.section    .init, "ax"
.code       32
.align      0x04
.global     _copy_section
.type       _copy_section, %function
/* r0 = source address
 * r1 = destination start address
 * r2 = destination end address
 *
 * r3 is a scratch register
 */

_copy_section:
   cmp      r2, r1
   ldrhi    r3, [r0], #4
   strhi    r3, [r1], #4
   bhi      _copy_section
   bx lr
.ltorg  
.size       _copy_section, .-_copy_section

/******************************************************************************
 * _delay_cycles:                                                             *
 *    This function delays for the specified number of cycles                 *
 ******************************************************************************/
.section    .init, "ax"
.code       32
.align      0x04
.global     _delay_cycles
.type       _delay_cycles, %function
/* r0 = number of cycles to delay */

/* If r0 is zero it will be the maximum length delay */
_delay_cycles:
    subs    r0, r0, #1
    bne     _delay_cycles
    bx      lr
.ltorg  
.size       _delay_cycles, .-_delay_cycles

/******************************************************************************
 * _dead_loop: Something really unexpected happened (like a reserved          *
 * exception).  Just hang.                                                    *
 ******************************************************************************/
_dead_loop:
   b        _dead_loop

.ltorg