Merge branch 'master' of git://git.denx.de/u-boot-sh
[platform/kernel/u-boot.git] / arch / m68k / cpu / mcf5227x / start.S
1 /* SPDX-License-Identifier: GPL-2.0+ */
2 /*
3  * Copyright (C) 2003   Josef Baumgartner <josef.baumgartner@telex.de>
4  * Based on code from Bernhard Kuhn <bkuhn@metrowerks.com>
5  */
6
7 #include <asm-offsets.h>
8 #include <config.h>
9 #include "version.h"
10 #include <asm/cache.h>
11
12 #define _START  _start
13 #define _FAULT  _fault
14
15 #define SAVE_ALL                                                \
16         move.w  #0x2700,%sr;            /* disable intrs */     \
17         subl    #60,%sp;                /* space for 15 regs */ \
18         moveml  %d0-%d7/%a0-%a6,%sp@;
19
20 #define RESTORE_ALL                                             \
21         moveml  %sp@,%d0-%d7/%a0-%a6;                           \
22         addl    #60,%sp;                /* space for 15 regs */ \
23         rte;
24
25 #if defined(CONFIG_CF_SBF)
26 #define ASM_DRAMINIT    (asm_dram_init - CONFIG_SYS_TEXT_BASE + \
27         CONFIG_SYS_INIT_RAM_ADDR)
28 #define ASM_SBF_IMG_HDR (asm_sbf_img_hdr - CONFIG_SYS_TEXT_BASE + \
29         CONFIG_SYS_INIT_RAM_ADDR)
30 #endif
31
32 .text
33
34 /*
35  * Vector table. This is used for initial platform startup.
36  * These vectors are to catch any un-intended traps.
37  */
38 _vectors:
39 #if defined(CONFIG_CF_SBF)
40 INITSP: .long   0                       /* Initial SP   */
41 INITPC: .long   ASM_DRAMINIT            /* Initial PC   */
42 #else
43 INITSP: .long   0                       /* Initial SP   */
44 INITPC: .long   _START                  /* Initial PC   */
45 #endif
46
47 vector02_0F:
48 .long   _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
49 .long   _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
50
51 /* Reserved */
52 vector10_17:
53 .long   _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
54
55 vector18_1F:
56 .long   _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
57
58 #if !defined(CONFIG_CF_SBF)
59 /* TRAP #0 - #15 */
60 vector20_2F:
61 .long   _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
62 .long   _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
63
64 /* Reserved     */
65 vector30_3F:
66 .long   _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
67 .long   _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
68
69 vector64_127:
70 .long   _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
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
79 vector128_191:
80 .long   _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
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
89 vector192_255:
90 .long   _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
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 #endif
99
100 #if defined(CONFIG_CF_SBF)
101         /* Image header: chksum 4 bytes, len 4 bytes, img dest 4 bytes */
102 asm_sbf_img_hdr:
103         .long   0x00000000              /* checksum, not yet implemented */
104         .long   0x00020000              /* image length */
105         .long   CONFIG_SYS_TEXT_BASE    /* image to be relocated at */
106
107 asm_dram_init:
108         move.l  #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_CTRL), %d0
109         movec   %d0, %RAMBAR1           /* init Rambar */
110
111         move.l  #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET), %sp
112         clr.l   %sp@-
113
114         /* Must disable global address */
115         move.l  #0xFC008000, %a1
116         move.l  #(CONFIG_SYS_CS0_BASE), (%a1)
117         move.l  #0xFC008008, %a1
118         move.l  #(CONFIG_SYS_CS0_CTRL), (%a1)
119         move.l  #0xFC008004, %a1
120         move.l  #(CONFIG_SYS_CS0_MASK), (%a1)
121
122         /*
123          * Dram Initialization
124          * a1, a2, and d0
125          */
126         move.l  #0xFC0A4074, %a1
127         move.b  #(CONFIG_SYS_SDRAM_DRV_STRENGTH), (%a1)
128         nop
129
130         /* SDRAM Chip 0 and 1 */
131         move.l  #0xFC0B8110, %a1
132         move.l  #0xFC0B8114, %a2
133
134         /* calculate the size */
135         move.l  #0x13, %d1
136         move.l  #(CONFIG_SYS_SDRAM_SIZE), %d2
137 #ifdef CONFIG_SYS_SDRAM_BASE1
138         lsr.l   #1, %d2
139 #endif
140
141 dramsz_loop:
142         lsr.l   #1, %d2
143         add.l   #1, %d1
144         cmp.l   #1, %d2
145         bne     dramsz_loop
146
147         /* SDRAM Chip 0 and 1 */
148         move.l  #(CONFIG_SYS_SDRAM_BASE), (%a1)
149         or.l    %d1, (%a1)
150 #ifdef CONFIG_SYS_SDRAM_BASE1
151         move.l  #(CONFIG_SYS_SDRAM_BASE1), (%a2)
152         or.l    %d1, (%a2)
153 #endif
154         nop
155
156         /* dram cfg1 and cfg2 */
157         move.l  #0xFC0B8008, %a1
158         move.l  #(CONFIG_SYS_SDRAM_CFG1), (%a1)
159         nop
160         move.l  #0xFC0B800C, %a2
161         move.l  #(CONFIG_SYS_SDRAM_CFG2), (%a2)
162         nop
163
164         move.l  #0xFC0B8000, %a1        /* Mode */
165         move.l  #0xFC0B8004, %a2        /* Ctrl */
166
167         /* Issue PALL */
168         move.l  #(CONFIG_SYS_SDRAM_CTRL + 2), (%a2)
169         nop
170
171         /* Issue LEMR */
172         move.l  #(CONFIG_SYS_SDRAM_MODE), (%a1)
173         nop
174         move.l  #(CONFIG_SYS_SDRAM_EMOD), (%a1)
175         nop
176
177         move.l  #1000, %d0
178 wait1000:
179         nop
180         subq.l  #1, %d0
181         bne     wait1000
182
183         /* Issue PALL */
184         move.l  #(CONFIG_SYS_SDRAM_CTRL + 2), (%a2)
185         nop
186
187         /* Perform two refresh cycles */
188         move.l  #(CONFIG_SYS_SDRAM_CTRL + 4), %d0
189         nop
190         move.l  %d0, (%a2)
191         move.l  %d0, (%a2)
192         nop
193
194         move.l  #(CONFIG_SYS_SDRAM_CTRL), %d0
195         and.l   #0x7FFFFFFF, %d0
196         or.l    #0x10000c00, %d0
197         move.l  %d0, (%a2)
198         nop
199
200         /*
201          * DSPI Initialization
202          * a0 - general, sram - 0x80008000 - 32, see M52277EVB.h
203          * a1 - dspi status
204          * a2 - dtfr
205          * a3 - drfr
206          * a4 - Dst addr
207          */
208
209         /* Enable pins for DSPI mode - chip-selects are enabled later */
210         move.l  #0xFC0A4036, %a0
211         move.b  #0x3F, %d0
212         move.b  %d0, (%a0)
213
214         /* DSPI CS */
215 #ifdef CONFIG_SYS_DSPI_CS0
216         move.b  (%a0), %d0
217         or.l    #0xC0, %d0
218         move.b  %d0, (%a0)
219 #endif
220 #ifdef CONFIG_SYS_DSPI_CS2
221         move.l  #0xFC0A4037, %a0
222         move.b  (%a0), %d0
223         or.l    #0x10, %d0
224         move.b  %d0, (%a0)
225 #endif
226         nop
227
228         /* Configure DSPI module */
229         move.l  #0xFC05C000, %a0
230         move.l  #0x80FF0C00, (%a0)      /* Master, clear TX/RX FIFO */
231
232         move.l  #0xFC05C00C, %a0
233         move.l  #0x3E000011, (%a0)
234
235         move.l  #0xFC05C034, %a2        /* dtfr */
236         move.l  #0xFC05C03B, %a3        /* drfr */
237
238         move.l  #(ASM_SBF_IMG_HDR + 4), %a1
239         move.l  (%a1)+, %d5
240         move.l  (%a1), %a4
241
242         move.l  #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_SBFHDR_DATA_OFFSET), %a0
243         move.l  #(CONFIG_SYS_SBFHDR_SIZE), %d4
244
245         move.l  #0xFC05C02C, %a1        /* dspi status */
246
247         /* Issue commands and address */
248         move.l  #0x8004000B, %d2        /* Fast Read Cmd */
249         jsr     asm_dspi_wr_status
250         jsr     asm_dspi_rd_status
251
252         move.l  #0x80040000, %d2        /* Address byte 2 */
253         jsr     asm_dspi_wr_status
254         jsr     asm_dspi_rd_status
255
256         move.l  #0x80040000, %d2        /* Address byte 1 */
257         jsr     asm_dspi_wr_status
258         jsr     asm_dspi_rd_status
259
260         move.l  #0x80040000, %d2        /* Address byte 0 */
261         jsr     asm_dspi_wr_status
262         jsr     asm_dspi_rd_status
263
264         move.l  #0x80040000, %d2        /* Dummy Wr and Rd */
265         jsr     asm_dspi_wr_status
266         jsr     asm_dspi_rd_status
267
268         /* Transfer serial boot header to sram */
269 asm_dspi_rd_loop1:
270         move.l  #0x80040000, %d2
271         jsr     asm_dspi_wr_status
272         jsr     asm_dspi_rd_status
273
274         move.b  %d1, (%a0)              /* read, copy to dst */
275
276         add.l   #1, %a0                 /* inc dst by 1 */
277         sub.l   #1, %d4                 /* dec cnt by 1 */
278         bne     asm_dspi_rd_loop1
279
280         /* Transfer u-boot from serial flash to memory */
281 asm_dspi_rd_loop2:
282         move.l  #0x80040000, %d2
283         jsr     asm_dspi_wr_status
284         jsr     asm_dspi_rd_status
285
286         move.b  %d1, (%a4)              /* read, copy to dst */
287
288         add.l   #1, %a4                 /* inc dst by 1 */
289         sub.l   #1, %d5                 /* dec cnt by 1 */
290         bne     asm_dspi_rd_loop2
291
292         move.l  #0x00040000, %d2        /* Terminate */
293         jsr     asm_dspi_wr_status
294         jsr     asm_dspi_rd_status
295
296         /* jump to memory and execute */
297         move.l  #(CONFIG_SYS_TEXT_BASE + 0x400), %a0
298         move.l  %a0, (%a1)
299         jmp     (%a0)
300
301 asm_dspi_wr_status:
302         move.l  (%a1), %d0              /* status */
303         and.l   #0x0000F000, %d0
304         cmp.l   #0x00003000, %d0
305         bgt     asm_dspi_wr_status
306
307         move.l  %d2, (%a2)
308         rts
309
310 asm_dspi_rd_status:
311         move.l  (%a1), %d0              /* status */
312         and.l   #0x000000F0, %d0
313         lsr.l   #4, %d0
314         cmp.l   #0, %d0
315         beq     asm_dspi_rd_status
316
317         move.b  (%a3), %d1
318         rts
319 #endif /* CONFIG_CF_SBF */
320
321 .text
322         . = 0x400
323 .globl _start
324 _start:
325         nop
326         nop
327         move.w  #0x2700,%sr             /* Mask off Interrupt */
328
329         /* Set vector base register at the beginning of the Flash */
330 #if defined(CONFIG_CF_SBF)
331         move.l  #CONFIG_SYS_TEXT_BASE, %d0
332         movec   %d0, %VBR
333 #else
334         move.l  #CONFIG_SYS_FLASH_BASE, %d0
335         movec   %d0, %VBR
336
337         move.l  #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_CTRL), %d0
338         movec   %d0, %RAMBAR1
339 #endif
340
341         /* invalidate and disable cache */
342         move.l  #CF_CACR_CINV, %d0      /* Invalidate cache cmd */
343         movec   %d0, %CACR              /* Invalidate cache */
344         move.l  #0, %d0
345         movec   %d0, %ACR0
346         movec   %d0, %ACR1
347
348         /* initialize general use internal ram */
349         move.l  #0, %d0
350         move.l  #(ICACHE_STATUS), %a1   /* icache */
351         move.l  #(DCACHE_STATUS), %a2   /* icache */
352         move.l  %d0, (%a1)
353         move.l  %d0, (%a2)
354
355         /* put relocation table address to a5 */
356         move.l  #__got_start, %a5
357
358         /* setup stack initially on top of internal static ram  */
359         move.l  #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_SIZE), %sp
360
361         /*
362          * if configured, malloc_f arena will be reserved first,
363          * then (and always) gd struct space will be reserved
364          */
365         move.l  %sp, -(%sp)
366         bsr     board_init_f_alloc_reserve
367
368         /* update stack and frame-pointers */
369         move.l  %d0, %sp
370         move.l  %sp, %fp
371
372         /* initialize reserved area */
373         move.l  %d0, -(%sp)
374         bsr     board_init_f_init_reserve
375
376         /* run low-level CPU init code (from flash) */
377         bsr     cpu_init_f
378         clr.l   %sp@-
379
380         /* run low-level board init code (from flash) */
381         move.l  #board_init_f, %a1
382         jsr     (%a1)
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