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