xref: /openbmc/u-boot/arch/m68k/cpu/mcf5227x/start.S (revision 85187b80)
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)
40INITSP:	.long	0			/* Initial SP	*/
41INITPC:	.long	ASM_DRAMINIT		/* Initial PC 	*/
42#else
43INITSP:	.long	0			/* Initial SP	*/
44INITPC:	.long	_START			/* Initial PC 	*/
45#endif
46
47vector02_0F:
48.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
49.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
50
51/* Reserved */
52vector10_17:
53.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
54
55vector18_1F:
56.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
57
58#if !defined(CONFIG_CF_SBF)
59/* TRAP #0 - #15 */
60vector20_2F:
61.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
62.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
63
64/* Reserved	*/
65vector30_3F:
66.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
67.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
68
69vector64_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
79vector128_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
89vector192_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 */
102asm_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
107asm_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
141dramsz_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
178wait1000:
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 */
269asm_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 */
281asm_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
301asm_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
310asm_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	bsr	board_init_f
382
383	/* board_init_f() does not return */
384
385/******************************************************************************/
386
387/*
388 * void relocate_code (addr_sp, gd, addr_moni)
389 *
390 * This "function" does not return, instead it continues in RAM
391 * after relocating the monitor code.
392 *
393 * r3 = dest
394 * r4 = src
395 * r5 = length in bytes
396 * r6 = cachelinesize
397 */
398.globl relocate_code
399relocate_code:
400	link.w	%a6,#0
401	move.l	8(%a6), %sp		/* set new stack pointer */
402
403	move.l	12(%a6), %d0		/* Save copy of Global Data pointer */
404	move.l	16(%a6), %a0		/* Save copy of Destination Address */
405
406	move.l	#CONFIG_SYS_MONITOR_BASE, %a1
407	move.l	#__init_end, %a2
408	move.l	%a0, %a3
409
410	/* copy the code to RAM */
4111:
412	move.l	(%a1)+, (%a3)+
413	cmp.l	%a1,%a2
414	bgt.s	1b
415
416/*
417 * We are done. Do not return, instead branch to second part of board
418 * initialization, now running from RAM.
419 */
420	move.l	%a0, %a1
421	add.l	#(in_ram - CONFIG_SYS_MONITOR_BASE), %a1
422	jmp	(%a1)
423
424in_ram:
425
426clear_bss:
427	/*
428	 * Now clear BSS segment
429	 */
430	move.l	%a0, %a1
431	add.l	#(_sbss - CONFIG_SYS_MONITOR_BASE),%a1
432	move.l	%a0, %d1
433	add.l	#(_ebss - CONFIG_SYS_MONITOR_BASE),%d1
4346:
435	clr.l	(%a1)+
436	cmp.l	%a1,%d1
437	bgt.s	6b
438
439	/*
440	 * fix got table in RAM
441	 */
442	move.l	%a0, %a1
443	add.l	#(__got_start - CONFIG_SYS_MONITOR_BASE),%a1
444	move.l	%a1,%a5			/* fix got pointer register a5 */
445
446	move.l	%a0, %a2
447	add.l	#(__got_end - CONFIG_SYS_MONITOR_BASE),%a2
448
4497:
450	move.l	(%a1),%d1
451	sub.l	#_start,%d1
452	add.l	%a0,%d1
453	move.l	%d1,(%a1)+
454	cmp.l	%a2, %a1
455	bne	7b
456
457	/* calculate relative jump to board_init_r in ram */
458	move.l	%a0, %a1
459	add.l	#(board_init_r - CONFIG_SYS_MONITOR_BASE), %a1
460
461	/* set parameters for board_init_r */
462	move.l	%a0,-(%sp)		/* dest_addr */
463	move.l	%d0,-(%sp)		/* gd */
464	jsr	(%a1)
465
466/******************************************************************************/
467
468/* exception code */
469.globl _fault
470_fault:
471	bra	_fault
472
473.globl _exc_handler
474_exc_handler:
475	SAVE_ALL
476	movel	%sp,%sp@-
477	bsr	exc_handler
478	addql	#4,%sp
479	RESTORE_ALL
480
481.globl _int_handler
482_int_handler:
483	SAVE_ALL
484	movel	%sp,%sp@-
485	bsr	int_handler
486	addql	#4,%sp
487	RESTORE_ALL
488
489/******************************************************************************/
490
491.globl version_string
492version_string:
493.ascii U_BOOT_VERSION_STRING, "\0"
494.align 4
495