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