tizen 2.4 release
[kernel/u-boot-tm1.git] / arch / m68k / cpu / mcf5227x / start.S
1 /*
2  * Copyright (C) 2003   Josef Baumgartner <josef.baumgartner@telex.de>
3  * Based on code from Bernhard Kuhn <bkuhn@metrowerks.com>
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21  * MA 02111-1307 USA
22  */
23
24 #include <asm-offsets.h>
25 #include <config.h>
26 #include <timestamp.h>
27 #include "version.h"
28 #include <asm/cache.h>
29
30 #ifndef  CONFIG_IDENT_STRING
31 #define  CONFIG_IDENT_STRING ""
32 #endif
33
34 #define _START  _start
35 #define _FAULT  _fault
36
37 #define SAVE_ALL                                                \
38         move.w  #0x2700,%sr;            /* disable intrs */     \
39         subl    #60,%sp;                /* space for 15 regs */ \
40         moveml  %d0-%d7/%a0-%a6,%sp@;
41
42 #define RESTORE_ALL                                             \
43         moveml  %sp@,%d0-%d7/%a0-%a6;                           \
44         addl    #60,%sp;                /* space for 15 regs */ \
45         rte;
46
47 #if defined(CONFIG_CF_SBF)
48 #define ASM_DRAMINIT    (asm_dram_init - CONFIG_SYS_TEXT_BASE + CONFIG_SYS_INIT_RAM_ADDR)
49 #define ASM_SBF_IMG_HDR (asm_sbf_img_hdr - CONFIG_SYS_TEXT_BASE + CONFIG_SYS_INIT_RAM_ADDR)
50 #endif
51
52 .text
53 /*
54  *      Vector table. This is used for initial platform startup.
55  *      These vectors are to catch any un-intended traps.
56  */
57 _vectors:
58
59 #if defined(CONFIG_CF_SBF)
60 INITSP:         .long   0               /* Initial SP   */
61 INITPC:         .long   ASM_DRAMINIT    /* Initial PC   */
62 #else
63 INITSP:         .long   0       /* Initial SP   */
64 INITPC:         .long   _START  /* Initial PC           */
65 #endif
66
67 vector02:       .long   _FAULT  /* Access Error         */
68 vector03:       .long   _FAULT  /* Address Error        */
69 vector04:       .long   _FAULT  /* Illegal Instruction  */
70 vector05:       .long   _FAULT  /* Reserved             */
71 vector06:       .long   _FAULT  /* Reserved             */
72 vector07:       .long   _FAULT  /* Reserved             */
73 vector08:       .long   _FAULT  /* Privilege Violation  */
74 vector09:       .long   _FAULT  /* Trace                */
75 vector0A:       .long   _FAULT  /* Unimplemented A-Line */
76 vector0B:       .long   _FAULT  /* Unimplemented F-Line */
77 vector0C:       .long   _FAULT  /* Debug Interrupt      */
78 vector0D:       .long   _FAULT  /* Reserved             */
79 vector0E:       .long   _FAULT  /* Format Error         */
80 vector0F:       .long   _FAULT  /* Unitialized Int.     */
81
82 /* Reserved */
83 vector10_17:
84 .long   _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
85
86 vector18:       .long   _FAULT  /* Spurious Interrupt   */
87 vector19:       .long   _FAULT  /* Autovector Level 1   */
88 vector1A:       .long   _FAULT  /* Autovector Level 2   */
89 vector1B:       .long   _FAULT  /* Autovector Level 3   */
90 vector1C:       .long   _FAULT  /* Autovector Level 4   */
91 vector1D:       .long   _FAULT  /* Autovector Level 5   */
92 vector1E:       .long   _FAULT  /* Autovector Level 6   */
93 vector1F:       .long   _FAULT  /* Autovector Level 7   */
94
95 #if !defined(CONFIG_CF_SBF)
96 /* TRAP #0 - #15 */
97 vector20_2F:
98 .long   _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
99 .long   _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
100
101 /* Reserved     */
102 vector30_3F:
103 .long   _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
104 .long   _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
105
106 vector64_127:
107 .long   _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
108 .long   _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
109 .long   _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
110 .long   _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
111 .long   _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
112 .long   _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
113 .long   _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
114 .long   _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
115
116 vector128_191:
117 .long   _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
118 .long   _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
119 .long   _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
120 .long   _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
121 .long   _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
122 .long   _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
123 .long   _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
124 .long   _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
125
126 vector192_255:
127 .long   _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
128 .long   _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
129 .long   _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
130 .long   _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
131 .long   _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
132 .long   _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
133 .long   _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
134 .long   _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
135 #endif
136
137 #if defined(CONFIG_CF_SBF)
138         /* Image header: chksum 4 bytes, len 4 bytes, img dest 4 bytes */
139 asm_sbf_img_hdr:
140         .long   0x00000000      /* checksum, not yet implemented */
141         .long   0x00020000      /* image length */
142         .long   CONFIG_SYS_TEXT_BASE    /* image to be relocated at */
143
144 asm_dram_init:
145         move.l  #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_CTRL), %d0
146         movec   %d0, %RAMBAR1   /* init Rambar */
147         move.l  #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET), %sp
148         clr.l %sp@-
149
150         /* Must disable global address */
151         move.l  #0xFC008000, %a1
152         move.l  #(CONFIG_SYS_CS0_BASE), (%a1)
153         move.l  #0xFC008008, %a1
154         move.l  #(CONFIG_SYS_CS0_CTRL), (%a1)
155         move.l  #0xFC008004, %a1
156         move.l  #(CONFIG_SYS_CS0_MASK), (%a1)
157
158         /*
159          * Dram Initialization
160          * a1, a2, and d0
161          */
162         /* mscr sdram */
163         move.l  #0xFC0A4074, %a1
164         move.b  #(CONFIG_SYS_SDRAM_DRV_STRENGTH), (%a1)
165         nop
166
167         /* SDRAM Chip 0 and 1 */
168         move.l  #0xFC0B8110, %a1
169         move.l  #0xFC0B8114, %a2
170
171         /* calculate the size */
172         move.l  #0x13, %d1
173         move.l  #(CONFIG_SYS_SDRAM_SIZE), %d2
174 #ifdef CONFIG_SYS_SDRAM_BASE1
175         lsr.l   #1, %d2
176 #endif
177
178 dramsz_loop:
179         lsr.l   #1, %d2
180         add.l   #1, %d1
181         cmp.l   #1, %d2
182         bne     dramsz_loop
183
184         /* SDRAM Chip 0 and 1 */
185         move.l  #(CONFIG_SYS_SDRAM_BASE), (%a1)
186         or.l    %d1, (%a1)
187 #ifdef CONFIG_SYS_SDRAM_BASE1
188         move.l  #(CONFIG_SYS_SDRAM_BASE1), (%a2)
189         or.l    %d1, (%a2)
190 #endif
191         nop
192
193         /* dram cfg1 and cfg2 */
194         move.l  #0xFC0B8008, %a1
195         move.l  #(CONFIG_SYS_SDRAM_CFG1), (%a1)
196         nop
197         move.l  #0xFC0B800C, %a2
198         move.l  #(CONFIG_SYS_SDRAM_CFG2), (%a2)
199         nop
200
201         move.l  #0xFC0B8000, %a1        /* Mode */
202         move.l  #0xFC0B8004, %a2        /* Ctrl */
203
204         /* Issue PALL */
205         move.l  #(CONFIG_SYS_SDRAM_CTRL + 2), (%a2)
206         nop
207
208         /* Issue LEMR */
209         move.l  #(CONFIG_SYS_SDRAM_MODE), (%a1)
210         nop
211         move.l  #(CONFIG_SYS_SDRAM_EMOD), (%a1)
212         nop
213
214         move.l  #1000, %d0
215 wait1000:
216         nop
217         subq.l  #1, %d0
218         bne     wait1000
219
220         /* Issue PALL */
221         move.l  #(CONFIG_SYS_SDRAM_CTRL + 2), (%a2)
222         nop
223
224         /* Perform two refresh cycles */
225         move.l  #(CONFIG_SYS_SDRAM_CTRL + 4), %d0
226         nop
227         move.l  %d0, (%a2)
228         move.l  %d0, (%a2)
229         nop
230
231         move.l  #(CONFIG_SYS_SDRAM_CTRL), %d0
232         and.l   #0x7FFFFFFF, %d0
233         or.l    #0x10000c00, %d0
234         move.l  %d0, (%a2)
235         nop
236
237         /*
238          * DSPI Initialization
239          * a0 - general, sram - 0x80008000 - 32, see M52277EVB.h
240          * a1 - dspi status
241          * a2 - dtfr
242          * a3 - drfr
243          * a4 - Dst addr
244          */
245
246         /* Enable pins for DSPI mode - chip-selects are enabled later */
247         move.l  #0xFC0A4036, %a0
248         move.b  #0x3F, %d0
249         move.b  %d0, (%a0)
250
251         /* DSPI CS */
252 #ifdef CONFIG_SYS_DSPI_CS0
253         move.b  (%a0), %d0
254         or.l    #0xC0, %d0
255         move.b  %d0, (%a0)
256 #endif
257 #ifdef CONFIG_SYS_DSPI_CS2
258         move.l  #0xFC0A4037, %a0
259         move.b  (%a0), %d0
260         or.l    #0x10, %d0
261         move.b  %d0, (%a0)
262 #endif
263         nop
264
265         /* Configure DSPI module */
266         move.l  #0xFC05C000, %a0
267         move.l  #0x80FF0C00, (%a0)      /* Master, clear TX/RX FIFO */
268
269         move.l  #0xFC05C00C, %a0
270         move.l  #0x3E000011, (%a0)
271
272         move.l  #0xFC05C034, %a2        /* dtfr */
273         move.l  #0xFC05C03B, %a3        /* drfr */
274
275         move.l  #(ASM_SBF_IMG_HDR + 4), %a1
276         move.l  (%a1)+, %d5
277         move.l  (%a1), %a4
278
279         move.l  #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_SBFHDR_DATA_OFFSET), %a0
280         move.l  #(CONFIG_SYS_SBFHDR_SIZE), %d4
281
282         move.l  #0xFC05C02C, %a1        /* dspi status */
283
284         /* Issue commands and address */
285         move.l  #0x8004000B, %d2        /* Fast Read Cmd */
286         jsr     asm_dspi_wr_status
287         jsr     asm_dspi_rd_status
288
289         move.l  #0x80040000, %d2        /* Address byte 2 */
290         jsr     asm_dspi_wr_status
291         jsr     asm_dspi_rd_status
292
293         move.l  #0x80040000, %d2        /* Address byte 1 */
294         jsr     asm_dspi_wr_status
295         jsr     asm_dspi_rd_status
296
297         move.l  #0x80040000, %d2        /* Address byte 0 */
298         jsr     asm_dspi_wr_status
299         jsr     asm_dspi_rd_status
300
301         move.l  #0x80040000, %d2        /* Dummy Wr and Rd */
302         jsr     asm_dspi_wr_status
303         jsr     asm_dspi_rd_status
304
305         /* Transfer serial boot header to sram */
306 asm_dspi_rd_loop1:
307         move.l  #0x80040000, %d2
308         jsr     asm_dspi_wr_status
309         jsr     asm_dspi_rd_status
310
311         move.b  %d1, (%a0)              /* read, copy to dst */
312
313         add.l   #1, %a0                 /* inc dst by 1 */
314         sub.l   #1, %d4                 /* dec cnt by 1 */
315         bne     asm_dspi_rd_loop1
316
317         /* Transfer u-boot from serial flash to memory */
318 asm_dspi_rd_loop2:
319         move.l  #0x80040000, %d2
320         jsr     asm_dspi_wr_status
321         jsr     asm_dspi_rd_status
322
323         move.b  %d1, (%a4)              /* read, copy to dst */
324
325         add.l   #1, %a4                 /* inc dst by 1 */
326         sub.l   #1, %d5                 /* dec cnt by 1 */
327         bne     asm_dspi_rd_loop2
328
329         move.l  #0x00040000, %d2        /* Terminate */
330         jsr     asm_dspi_wr_status
331         jsr     asm_dspi_rd_status
332
333         /* jump to memory and execute */
334         move.l  #(CONFIG_SYS_TEXT_BASE + 0x400), %a0
335         move.l  %a0, (%a1)
336         jmp     (%a0)
337
338 asm_dspi_wr_status:
339         move.l  (%a1), %d0              /* status */
340         and.l   #0x0000F000, %d0
341         cmp.l   #0x00003000, %d0
342         bgt     asm_dspi_wr_status
343
344         move.l  %d2, (%a2)
345         rts
346
347 asm_dspi_rd_status:
348         move.l  (%a1), %d0              /* status */
349         and.l   #0x000000F0, %d0
350         lsr.l   #4, %d0
351         cmp.l   #0, %d0
352         beq     asm_dspi_rd_status
353
354         move.b  (%a3), %d1
355         rts
356 #endif                  /* CONFIG_CF_SBF */
357
358         .text
359         . = 0x400
360         .globl  _start
361 _start:
362         nop
363         nop
364         move.w #0x2700,%sr              /* Mask off Interrupt */
365
366         /* Set vector base register at the beginning of the Flash */
367 #if defined(CONFIG_CF_SBF)
368         move.l  #CONFIG_SYS_TEXT_BASE, %d0
369         movec   %d0, %VBR
370 #else
371         move.l  #CONFIG_SYS_FLASH_BASE, %d0
372         movec   %d0, %VBR
373
374         move.l  #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_CTRL), %d0
375         movec   %d0, %RAMBAR1
376 #endif
377
378         /* invalidate and disable cache */
379         move.l  #CF_CACR_CINV, %d0      /* Invalidate cache cmd */
380         movec   %d0, %CACR              /* Invalidate cache */
381         move.l  #0, %d0
382         movec   %d0, %ACR0
383         movec   %d0, %ACR1
384
385         /* initialize general use internal ram */
386         move.l #0, %d0
387         move.l #(ICACHE_STATUS), %a1    /* icache */
388         move.l #(DCACHE_STATUS), %a2    /* icache */
389         move.l %d0, (%a1)
390         move.l %d0, (%a2)
391
392         /* set stackpointer to end of internal ram to get some stackspace for
393            the first c-code */
394         move.l  #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET), %sp
395         clr.l %sp@-
396
397         move.l #__got_start, %a5        /* put relocation table address to a5 */
398
399         bsr cpu_init_f                  /* run low-level CPU init code (from flash) */
400         bsr board_init_f                /* run low-level board init code (from flash) */
401
402         /* board_init_f() does not return */
403
404 /*------------------------------------------------------------------------------*/
405
406 /*
407  * void relocate_code (addr_sp, gd, addr_moni)
408  *
409  * This "function" does not return, instead it continues in RAM
410  * after relocating the monitor code.
411  *
412  * r3 = dest
413  * r4 = src
414  * r5 = length in bytes
415  * r6 = cachelinesize
416  */
417         .globl  relocate_code
418 relocate_code:
419         link.w %a6,#0
420         move.l 8(%a6), %sp              /* set new stack pointer */
421
422         move.l 12(%a6), %d0             /* Save copy of Global Data pointer */
423         move.l 16(%a6), %a0             /* Save copy of Destination Address */
424
425         move.l #CONFIG_SYS_MONITOR_BASE, %a1
426         move.l #__init_end, %a2
427         move.l %a0, %a3
428
429         /* copy the code to RAM */
430 1:
431         move.l (%a1)+, (%a3)+
432         cmp.l  %a1,%a2
433         bgt.s    1b
434
435 /*
436  * We are done. Do not return, instead branch to second part of board
437  * initialization, now running from RAM.
438  */
439         move.l  %a0, %a1
440         add.l   #(in_ram - CONFIG_SYS_MONITOR_BASE), %a1
441         jmp     (%a1)
442
443 in_ram:
444
445 clear_bss:
446         /*
447          * Now clear BSS segment
448          */
449         move.l  %a0, %a1
450         add.l   #(_sbss - CONFIG_SYS_MONITOR_BASE),%a1
451         move.l  %a0, %d1
452         add.l   #(_ebss - CONFIG_SYS_MONITOR_BASE),%d1
453 6:
454         clr.l   (%a1)+
455         cmp.l   %a1,%d1
456         bgt.s   6b
457
458         /*
459          * fix got table in RAM
460          */
461         move.l  %a0, %a1
462         add.l   #(__got_start - CONFIG_SYS_MONITOR_BASE),%a1
463         move.l  %a1,%a5                 /* * fix got pointer register a5 */
464
465         move.l  %a0, %a2
466         add.l   #(__got_end - CONFIG_SYS_MONITOR_BASE),%a2
467
468 7:
469         move.l  (%a1),%d1
470         sub.l   #_start,%d1
471         add.l   %a0,%d1
472         move.l  %d1,(%a1)+
473         cmp.l   %a2, %a1
474         bne     7b
475
476         /* calculate relative jump to board_init_r in ram */
477         move.l %a0, %a1
478         add.l #(board_init_r - CONFIG_SYS_MONITOR_BASE), %a1
479
480         /* set parameters for board_init_r */
481         move.l %a0,-(%sp)               /* dest_addr */
482         move.l %d0,-(%sp)               /* gd */
483         jsr     (%a1)
484
485 /*------------------------------------------------------------------------------*/
486 /* exception code */
487         .globl _fault
488 _fault:
489         jmp _fault
490         .globl  _exc_handler
491
492 _exc_handler:
493         SAVE_ALL
494         movel   %sp,%sp@-
495         bsr exc_handler
496         addql   #4,%sp
497         RESTORE_ALL
498
499         .globl  _int_handler
500 _int_handler:
501         SAVE_ALL
502         movel   %sp,%sp@-
503         bsr int_handler
504         addql   #4,%sp
505         RESTORE_ALL
506
507 /*------------------------------------------------------------------------------*/
508
509         .globl  version_string
510 version_string:
511         .ascii U_BOOT_VERSION
512         .ascii " (", U_BOOT_DATE, " - ", U_BOOT_TIME, ")"
513         .ascii CONFIG_IDENT_STRING, "\0"
514         .align 4