~ubuntu-branches/ubuntu/maverick/u-boot-omap3/maverick

« back to all changes in this revision

Viewing changes to cpu/lh7a40x/start.S

  • Committer: Bazaar Package Importer
  • Author(s): Oliver Grawert
  • Date: 2010-03-22 15:06:23 UTC
  • Revision ID: james.westby@ubuntu.com-20100322150623-i21g8rgiyl5dohag
Tags: upstream-2010.3git20100315
ImportĀ upstreamĀ versionĀ 2010.3git20100315

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  armboot - Startup Code for ARM920 CPU-core
 
3
 *
 
4
 *  Copyright (c) 2001  Marius Grļæ½ger <mag@sysgo.de>
 
5
 *  Copyright (c) 2002  Alex Zļæ½pke <azu@sysgo.de>
 
6
 *  Copyright (c) 2002  Gary Jennejohn <garyj@denx.de>
 
7
 *
 
8
 * See file CREDITS for list of people who contributed to this
 
9
 * project.
 
10
 *
 
11
 * This program is free software; you can redistribute it and/or
 
12
 * modify it under the terms of the GNU General Public License as
 
13
 * published by the Free Software Foundation; either version 2 of
 
14
 * the License, or (at your option) any later version.
 
15
 *
 
16
 * This program is distributed in the hope that it will be useful,
 
17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
19
 * GNU General Public License for more details.
 
20
 *
 
21
 * You should have received a copy of the GNU General Public License
 
22
 * along with this program; if not, write to the Free Software
 
23
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 
24
 * MA 02111-1307 USA
 
25
 */
 
26
 
 
27
 
 
28
#include <config.h>
 
29
#include <version.h>
 
30
 
 
31
 
 
32
/*
 
33
 *************************************************************************
 
34
 *
 
35
 * Jump vector table as in table 3.1 in [1]
 
36
 *
 
37
 *************************************************************************
 
38
 */
 
39
 
 
40
 
 
41
.globl _start
 
42
_start: b       reset
 
43
        ldr     pc, _undefined_instruction
 
44
        ldr     pc, _software_interrupt
 
45
        ldr     pc, _prefetch_abort
 
46
        ldr     pc, _data_abort
 
47
        ldr     pc, _not_used
 
48
        ldr     pc, _irq
 
49
        ldr     pc, _fiq
 
50
 
 
51
_undefined_instruction: .word undefined_instruction
 
52
_software_interrupt:    .word software_interrupt
 
53
_prefetch_abort:        .word prefetch_abort
 
54
_data_abort:            .word data_abort
 
55
_not_used:              .word not_used
 
56
_irq:                   .word irq
 
57
_fiq:                   .word fiq
 
58
 
 
59
        .balignl 16,0xdeadbeef
 
60
 
 
61
 
 
62
/*
 
63
 *************************************************************************
 
64
 *
 
65
 * Startup Code (reset vector)
 
66
 *
 
67
 * do important init only if we don't start from memory!
 
68
 * relocate armboot to ram
 
69
 * setup stack
 
70
 * jump to second stage
 
71
 *
 
72
 *************************************************************************
 
73
 */
 
74
 
 
75
_TEXT_BASE:
 
76
        .word   TEXT_BASE
 
77
 
 
78
.globl _armboot_start
 
79
_armboot_start:
 
80
        .word _start
 
81
 
 
82
/*
 
83
 * These are defined in the board-specific linker script.
 
84
 */
 
85
.globl _bss_start
 
86
_bss_start:
 
87
        .word __bss_start
 
88
 
 
89
.globl _bss_end
 
90
_bss_end:
 
91
        .word _end
 
92
 
 
93
#ifdef CONFIG_USE_IRQ
 
94
/* IRQ stack memory (calculated at run-time) */
 
95
.globl IRQ_STACK_START
 
96
IRQ_STACK_START:
 
97
        .word   0x0badc0de
 
98
 
 
99
/* IRQ stack memory (calculated at run-time) */
 
100
.globl FIQ_STACK_START
 
101
FIQ_STACK_START:
 
102
        .word 0x0badc0de
 
103
#endif
 
104
 
 
105
 
 
106
/*
 
107
 * the actual reset code
 
108
 */
 
109
 
 
110
reset:
 
111
        /*
 
112
         * set the cpu to SVC32 mode
 
113
         */
 
114
        mrs     r0,cpsr
 
115
        bic     r0,r0,#0x1f
 
116
        orr     r0,r0,#0xd3
 
117
        msr     cpsr,r0
 
118
 
 
119
#define pWDTCTL         0x80001400  /* Watchdog Timer control register */
 
120
#define pINTENC         0x8000050C  /* Interupt-Controller enable clear register */
 
121
#define pCLKSET         0x80000420  /* clock divisor register */
 
122
 
 
123
        /* disable watchdog, set watchdog control register to
 
124
         * all zeros (default reset)
 
125
         */
 
126
        ldr     r0, =pWDTCTL
 
127
        mov     r1, #0x0
 
128
        str     r1, [r0]
 
129
 
 
130
        /*
 
131
         * mask all IRQs by setting all bits in the INTENC register (default)
 
132
         */
 
133
        mov     r1, #0xffffffff
 
134
        ldr     r0, =pINTENC
 
135
        str     r1, [r0]
 
136
 
 
137
        /* FCLK:HCLK:PCLK = 1:2:2 */
 
138
        /* default FCLK is 200 MHz, using 14.7456 MHz fin */
 
139
        ldr     r0, =pCLKSET
 
140
        ldr r1, =0x0004ee39
 
141
@       ldr r1, =0x0005ee39     @ 1: 2: 4
 
142
        str     r1, [r0]
 
143
 
 
144
        /*
 
145
         * we do sys-critical inits only at reboot,
 
146
         * not when booting from ram!
 
147
         */
 
148
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
 
149
        bl      cpu_init_crit
 
150
#endif
 
151
 
 
152
#ifndef CONFIG_SKIP_RELOCATE_UBOOT
 
153
relocate:                               /* relocate U-Boot to RAM           */
 
154
        adr     r0, _start              /* r0 <- current position of code   */
 
155
        ldr     r1, _TEXT_BASE          /* test if we run from flash or RAM */
 
156
        cmp     r0, r1                  /* don't reloc during debug         */
 
157
        beq     stack_setup
 
158
 
 
159
        ldr     r2, _armboot_start
 
160
        ldr     r3, _bss_start
 
161
        sub     r2, r3, r2              /* r2 <- size of armboot            */
 
162
        add     r2, r0, r2              /* r2 <- source end address         */
 
163
 
 
164
copy_loop:
 
165
        ldmia   r0!, {r3-r10}           /* copy from source address [r0]    */
 
166
        stmia   r1!, {r3-r10}           /* copy to   target address [r1]    */
 
167
        cmp     r0, r2                  /* until source end addreee [r2]    */
 
168
        blt     copy_loop               /* a 'ble' here actually copies     */
 
169
                                        /*   four bytes of bss              */
 
170
#endif  /* CONFIG_SKIP_RELOCATE_UBOOT */
 
171
 
 
172
        /* Set up the stack                                                 */
 
173
stack_setup:
 
174
        ldr     r0, _TEXT_BASE          /* upper 128 KiB: relocated uboot   */
 
175
        sub     r0, r0, #CONFIG_SYS_MALLOC_LEN  /* malloc area                      */
 
176
        sub     r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo                        */
 
177
#ifdef CONFIG_USE_IRQ
 
178
        sub     r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
 
179
#endif
 
180
        sub     sp, r0, #12             /* leave 3 words for abort-stack    */
 
181
 
 
182
clear_bss:
 
183
        ldr     r0, _bss_start          /* find start of bss segment        */
 
184
        @add    r0, r0, #4              /* start at first byte of bss       */
 
185
                                        /*   why inc. 4 bytes past then?    */
 
186
        ldr     r1, _bss_end            /* stop here                        */
 
187
        mov     r2, #0x00000000         /* clear                            */
 
188
 
 
189
clbss_l:str     r2, [r0]                /* clear loop...                    */
 
190
        add     r0, r0, #4
 
191
        cmp     r0, r1
 
192
        ble     clbss_l
 
193
 
 
194
        ldr     pc, _start_armboot
 
195
 
 
196
_start_armboot: .word start_armboot
 
197
 
 
198
 
 
199
/*
 
200
 *************************************************************************
 
201
 *
 
202
 * CPU_init_critical registers
 
203
 *
 
204
 * setup important registers
 
205
 * setup memory timing
 
206
 *
 
207
 *************************************************************************
 
208
 */
 
209
 
 
210
 
 
211
cpu_init_crit:
 
212
        /*
 
213
         * flush v4 I/D caches
 
214
         */
 
215
        mov     r0, #0
 
216
        mcr     p15, 0, r0, c7, c7, 0   /* flush v3/v4 cache */
 
217
        mcr     p15, 0, r0, c8, c7, 0   /* flush v4 TLB */
 
218
 
 
219
        /*
 
220
         * disable MMU stuff and caches
 
221
         */
 
222
        mrc     p15, 0, r0, c1, c0, 0
 
223
        bic     r0, r0, #0x00002300     @ clear bits 13, 9:8 (--V- --RS)
 
224
        bic     r0, r0, #0x00000087     @ clear bits 7, 2:0 (B--- -CAM)
 
225
        orr     r0, r0, #0x00000002     @ set bit 2 (A) Align
 
226
        orr     r0, r0, #0x00001000     @ set bit 12 (I) I-Cache
 
227
        orr     r0, r0, #0x40000000     @ set bit 30 (nF) notFastBus
 
228
        mcr     p15, 0, r0, c1, c0, 0
 
229
 
 
230
 
 
231
        /*
 
232
         * before relocating, we have to setup RAM timing
 
233
         * because memory timing is board-dependend, you will
 
234
         * find a lowlevel_init.S in your board directory.
 
235
         */
 
236
        mov     ip, lr
 
237
        bl      lowlevel_init
 
238
        mov     lr, ip
 
239
 
 
240
        mov     pc, lr
 
241
 
 
242
 
 
243
/*
 
244
 *************************************************************************
 
245
 *
 
246
 * Interrupt handling
 
247
 *
 
248
 *************************************************************************
 
249
 */
 
250
 
 
251
@
 
252
@ IRQ stack frame.
 
253
@
 
254
#define S_FRAME_SIZE    72
 
255
 
 
256
#define S_OLD_R0        68
 
257
#define S_PSR           64
 
258
#define S_PC            60
 
259
#define S_LR            56
 
260
#define S_SP            52
 
261
 
 
262
#define S_IP            48
 
263
#define S_FP            44
 
264
#define S_R10           40
 
265
#define S_R9            36
 
266
#define S_R8            32
 
267
#define S_R7            28
 
268
#define S_R6            24
 
269
#define S_R5            20
 
270
#define S_R4            16
 
271
#define S_R3            12
 
272
#define S_R2            8
 
273
#define S_R1            4
 
274
#define S_R0            0
 
275
 
 
276
#define MODE_SVC 0x13
 
277
#define I_BIT    0x80
 
278
 
 
279
/*
 
280
 * use bad_save_user_regs for abort/prefetch/undef/swi ...
 
281
 * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
 
282
 */
 
283
 
 
284
        .macro  bad_save_user_regs
 
285
        sub     sp, sp, #S_FRAME_SIZE
 
286
        stmia   sp, {r0 - r12}                  @ Calling r0-r12
 
287
        ldr     r2, _armboot_start
 
288
        sub     r2, r2, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN)
 
289
        sub     r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8)  @ set base 2 words into abort stack
 
290
        ldmia   r2, {r2 - r3}                   @ get pc, cpsr
 
291
        add     r0, sp, #S_FRAME_SIZE           @ restore sp_SVC
 
292
 
 
293
        add     r5, sp, #S_SP
 
294
        mov     r1, lr
 
295
        stmia   r5, {r0 - r3}                   @ save sp_SVC, lr_SVC, pc, cpsr
 
296
        mov     r0, sp
 
297
        .endm
 
298
 
 
299
        .macro  irq_save_user_regs
 
300
        sub     sp, sp, #S_FRAME_SIZE
 
301
        stmia   sp, {r0 - r12}                  @ Calling r0-r12
 
302
        add     r8, sp, #S_PC
 
303
        stmdb   r8, {sp, lr}^                   @ Calling SP, LR
 
304
        str     lr, [r8, #0]                    @ Save calling PC
 
305
        mrs     r6, spsr
 
306
        str     r6, [r8, #4]                    @ Save CPSR
 
307
        str     r0, [r8, #8]                    @ Save OLD_R0
 
308
        mov     r0, sp
 
309
        .endm
 
310
 
 
311
        .macro  irq_restore_user_regs
 
312
        ldmia   sp, {r0 - lr}^                  @ Calling r0 - lr
 
313
        mov     r0, r0
 
314
        ldr     lr, [sp, #S_PC]                 @ Get PC
 
315
        add     sp, sp, #S_FRAME_SIZE
 
316
        subs    pc, lr, #4                      @ return & move spsr_svc into cpsr
 
317
        .endm
 
318
 
 
319
        .macro get_bad_stack
 
320
        ldr     r13, _armboot_start             @ setup our mode stack
 
321
        sub     r13, r13, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN)
 
322
        sub     r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ reserved a couple spots in abort stack
 
323
 
 
324
        str     lr, [r13]                       @ save caller lr / spsr
 
325
        mrs     lr, spsr
 
326
        str     lr, [r13, #4]
 
327
 
 
328
        mov     r13, #MODE_SVC                  @ prepare SVC-Mode
 
329
        @ msr   spsr_c, r13
 
330
        msr     spsr, r13
 
331
        mov     lr, pc
 
332
        movs    pc, lr
 
333
        .endm
 
334
 
 
335
        .macro get_irq_stack                    @ setup IRQ stack
 
336
        ldr     sp, IRQ_STACK_START
 
337
        .endm
 
338
 
 
339
        .macro get_fiq_stack                    @ setup FIQ stack
 
340
        ldr     sp, FIQ_STACK_START
 
341
        .endm
 
342
 
 
343
/*
 
344
 * exception handlers
 
345
 */
 
346
        .align  5
 
347
undefined_instruction:
 
348
        get_bad_stack
 
349
        bad_save_user_regs
 
350
        bl      do_undefined_instruction
 
351
 
 
352
        .align  5
 
353
software_interrupt:
 
354
        get_bad_stack
 
355
        bad_save_user_regs
 
356
        bl      do_software_interrupt
 
357
 
 
358
        .align  5
 
359
prefetch_abort:
 
360
        get_bad_stack
 
361
        bad_save_user_regs
 
362
        bl      do_prefetch_abort
 
363
 
 
364
        .align  5
 
365
data_abort:
 
366
        get_bad_stack
 
367
        bad_save_user_regs
 
368
        bl      do_data_abort
 
369
 
 
370
        .align  5
 
371
not_used:
 
372
        get_bad_stack
 
373
        bad_save_user_regs
 
374
        bl      do_not_used
 
375
 
 
376
#ifdef CONFIG_USE_IRQ
 
377
 
 
378
        .align  5
 
379
irq:
 
380
        get_irq_stack
 
381
        irq_save_user_regs
 
382
        bl      do_irq
 
383
        irq_restore_user_regs
 
384
 
 
385
        .align  5
 
386
fiq:
 
387
        get_fiq_stack
 
388
        /* someone ought to write a more effiction fiq_save_user_regs */
 
389
        irq_save_user_regs
 
390
        bl      do_fiq
 
391
        irq_restore_user_regs
 
392
 
 
393
#else
 
394
 
 
395
        .align  5
 
396
irq:
 
397
        get_bad_stack
 
398
        bad_save_user_regs
 
399
        bl      do_irq
 
400
 
 
401
        .align  5
 
402
fiq:
 
403
        get_bad_stack
 
404
        bad_save_user_regs
 
405
        bl      do_fiq
 
406
 
 
407
#endif
 
408
 
 
409
        .align  5
 
410
.globl reset_cpu
 
411
reset_cpu:
 
412
        bl      disable_interrupts
 
413
 
 
414
        /* Disable watchdog */
 
415
        ldr     r1, =pWDTCTL
 
416
        mov     r3, #0
 
417
        str     r3, [r1]
 
418
 
 
419
        /* reset counter */
 
420
        ldr     r3, =0x00001984
 
421
        str     r3, [r1, #4]
 
422
 
 
423
        /* Enable the watchdog */
 
424
        mov     r3, #1
 
425
        str     r3, [r1]
 
426
 
 
427
_loop_forever:
 
428
        b       _loop_forever