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