xref: /OK3568_Linux_fs/u-boot/arch/m68k/cpu/mcf5445x/start.S (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun/*
2*4882a593Smuzhiyun * Copyright (C) 2003	Josef Baumgartner <josef.baumgartner@telex.de>
3*4882a593Smuzhiyun * Based on code from Bernhard Kuhn <bkuhn@metrowerks.com>
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright 2010-2012 Freescale Semiconductor, Inc.
6*4882a593Smuzhiyun * TsiChung Liew (Tsi-Chung.Liew@freescale.com)
7*4882a593Smuzhiyun *
8*4882a593Smuzhiyun * SPDX-License-Identifier:	GPL-2.0+
9*4882a593Smuzhiyun */
10*4882a593Smuzhiyun
11*4882a593Smuzhiyun#include <common.h>
12*4882a593Smuzhiyun#include <asm-offsets.h>
13*4882a593Smuzhiyun#include <config.h>
14*4882a593Smuzhiyun#include <timestamp.h>
15*4882a593Smuzhiyun#include "version.h"
16*4882a593Smuzhiyun#include <asm/cache.h>
17*4882a593Smuzhiyun
18*4882a593Smuzhiyun#define _START	_start
19*4882a593Smuzhiyun#define _FAULT	_fault
20*4882a593Smuzhiyun
21*4882a593Smuzhiyun#define SAVE_ALL						\
22*4882a593Smuzhiyun	move.w	#0x2700,%sr;		/* disable intrs */	\
23*4882a593Smuzhiyun	subl	#60,%sp;		/* space for 15 regs */ \
24*4882a593Smuzhiyun	moveml	%d0-%d7/%a0-%a6,%sp@;
25*4882a593Smuzhiyun
26*4882a593Smuzhiyun#define RESTORE_ALL						\
27*4882a593Smuzhiyun	moveml	%sp@,%d0-%d7/%a0-%a6;				\
28*4882a593Smuzhiyun	addl	#60,%sp;		/* space for 15 regs */ \
29*4882a593Smuzhiyun	rte;
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun#if defined(CONFIG_SERIAL_BOOT)
32*4882a593Smuzhiyun#define ASM_DRAMINIT	(asm_dram_init - CONFIG_SYS_TEXT_BASE + \
33*4882a593Smuzhiyun	CONFIG_SYS_INIT_RAM_ADDR)
34*4882a593Smuzhiyun#define ASM_DRAMINIT_N	(asm_dram_init - CONFIG_SYS_TEXT_BASE)
35*4882a593Smuzhiyun#define ASM_SBF_IMG_HDR	(asm_sbf_img_hdr - CONFIG_SYS_TEXT_BASE + \
36*4882a593Smuzhiyun	CONFIG_SYS_INIT_RAM_ADDR)
37*4882a593Smuzhiyun#endif
38*4882a593Smuzhiyun
39*4882a593Smuzhiyun.text
40*4882a593Smuzhiyun
41*4882a593Smuzhiyun/*
42*4882a593Smuzhiyun * Vector table. This is used for initial platform startup.
43*4882a593Smuzhiyun * These vectors are to catch any un-intended traps.
44*4882a593Smuzhiyun */
45*4882a593Smuzhiyun_vectors:
46*4882a593Smuzhiyun#if defined(CONFIG_SERIAL_BOOT)
47*4882a593Smuzhiyun
48*4882a593SmuzhiyunINITSP:	.long	0			/* Initial SP	*/
49*4882a593Smuzhiyun#ifdef CONFIG_CF_SBF
50*4882a593SmuzhiyunINITPC:	.long	ASM_DRAMINIT		/* Initial PC 	*/
51*4882a593Smuzhiyun#endif
52*4882a593Smuzhiyun#ifdef CONFIG_SYS_NAND_BOOT
53*4882a593SmuzhiyunINITPC:	.long	ASM_DRAMINIT_N		/* Initial PC 	*/
54*4882a593Smuzhiyun#endif
55*4882a593Smuzhiyun
56*4882a593Smuzhiyun#else
57*4882a593Smuzhiyun
58*4882a593SmuzhiyunINITSP:	.long	0			/* Initial SP	*/
59*4882a593SmuzhiyunINITPC:	.long	_START			/* Initial PC 	*/
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun#endif
62*4882a593Smuzhiyun
63*4882a593Smuzhiyunvector02_0F:
64*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
65*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
66*4882a593Smuzhiyun
67*4882a593Smuzhiyun/* Reserved */
68*4882a593Smuzhiyunvector10_17:
69*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
70*4882a593Smuzhiyun
71*4882a593Smuzhiyunvector18_1F:
72*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
73*4882a593Smuzhiyun
74*4882a593Smuzhiyun#if !defined(CONFIG_SERIAL_BOOT)
75*4882a593Smuzhiyun
76*4882a593Smuzhiyun/* TRAP #0 - #15 */
77*4882a593Smuzhiyunvector20_2F:
78*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
79*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
80*4882a593Smuzhiyun
81*4882a593Smuzhiyun/* Reserved	*/
82*4882a593Smuzhiyunvector30_3F:
83*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
84*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
85*4882a593Smuzhiyun
86*4882a593Smuzhiyunvector64_127:
87*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
88*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
89*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
90*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
91*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
92*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
93*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
94*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
95*4882a593Smuzhiyun
96*4882a593Smuzhiyunvector128_191:
97*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
98*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
99*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
100*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
101*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
102*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
103*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
104*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
105*4882a593Smuzhiyun
106*4882a593Smuzhiyunvector192_255:
107*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
108*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
109*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
110*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
111*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
112*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
113*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
114*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
115*4882a593Smuzhiyun#endif
116*4882a593Smuzhiyun
117*4882a593Smuzhiyun#if defined(CONFIG_SERIAL_BOOT)
118*4882a593Smuzhiyun	/* Image header: chksum 4 bytes, len 4 bytes, img dest 4 bytes */
119*4882a593Smuzhiyunasm_sbf_img_hdr:
120*4882a593Smuzhiyun	.long	0x00000000		/* checksum, not yet implemented */
121*4882a593Smuzhiyun	.long	0x00040000		/* image length */
122*4882a593Smuzhiyun	.long	CONFIG_SYS_TEXT_BASE	/* image to be relocated at */
123*4882a593Smuzhiyun
124*4882a593Smuzhiyunasm_dram_init:
125*4882a593Smuzhiyun	move.w	#0x2700,%sr		/* Mask off Interrupt */
126*4882a593Smuzhiyun
127*4882a593Smuzhiyun#ifdef CONFIG_SYS_NAND_BOOT
128*4882a593Smuzhiyun	/* for assembly stack */
129*4882a593Smuzhiyun	move.l	#(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_CTRL), %d0
130*4882a593Smuzhiyun	movec	%d0, %RAMBAR1
131*4882a593Smuzhiyun
132*4882a593Smuzhiyun	move.l	#(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET), %sp
133*4882a593Smuzhiyun	clr.l	%sp@-
134*4882a593Smuzhiyun#endif
135*4882a593Smuzhiyun
136*4882a593Smuzhiyun#ifdef CONFIG_CF_SBF
137*4882a593Smuzhiyun	move.l	#CONFIG_SYS_INIT_RAM_ADDR, %d0
138*4882a593Smuzhiyun	movec	%d0, %VBR
139*4882a593Smuzhiyun
140*4882a593Smuzhiyun	move.l	#(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_CTRL), %d0
141*4882a593Smuzhiyun	movec	%d0, %RAMBAR1
142*4882a593Smuzhiyun
143*4882a593Smuzhiyun	/* initialize general use internal ram */
144*4882a593Smuzhiyun	move.l	#0, %d0
145*4882a593Smuzhiyun	move.l	#(ICACHE_STATUS), %a1	/* icache */
146*4882a593Smuzhiyun	move.l	#(DCACHE_STATUS), %a2	/* dcache */
147*4882a593Smuzhiyun	move.l	%d0, (%a1)
148*4882a593Smuzhiyun	move.l	%d0, (%a2)
149*4882a593Smuzhiyun
150*4882a593Smuzhiyun	/* invalidate and disable cache */
151*4882a593Smuzhiyun	move.l	#(CONFIG_SYS_ICACHE_INV + CONFIG_SYS_DCACHE_INV), %d0
152*4882a593Smuzhiyun	movec	%d0, %CACR		/* Invalidate cache */
153*4882a593Smuzhiyun	move.l	#0, %d0
154*4882a593Smuzhiyun	movec	%d0, %ACR0
155*4882a593Smuzhiyun	movec	%d0, %ACR1
156*4882a593Smuzhiyun	movec	%d0, %ACR2
157*4882a593Smuzhiyun	movec	%d0, %ACR3
158*4882a593Smuzhiyun
159*4882a593Smuzhiyun	move.l	#(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET), %sp
160*4882a593Smuzhiyun	clr.l	%sp@-
161*4882a593Smuzhiyun
162*4882a593Smuzhiyun#ifdef CONFIG_SYS_CS0_BASE
163*4882a593Smuzhiyun	/* Must disable global address */
164*4882a593Smuzhiyun	move.l	#0xFC008000, %a1
165*4882a593Smuzhiyun	move.l	#(CONFIG_SYS_CS0_BASE), (%a1)
166*4882a593Smuzhiyun	move.l	#0xFC008008, %a1
167*4882a593Smuzhiyun	move.l	#(CONFIG_SYS_CS0_CTRL), (%a1)
168*4882a593Smuzhiyun	move.l	#0xFC008004, %a1
169*4882a593Smuzhiyun	move.l	#(CONFIG_SYS_CS0_MASK), (%a1)
170*4882a593Smuzhiyun#endif
171*4882a593Smuzhiyun#endif /* CONFIG_CF_SBF */
172*4882a593Smuzhiyun
173*4882a593Smuzhiyun#ifdef CONFIG_MCF5441x
174*4882a593Smuzhiyun	/* TC: enable all peripherals,
175*4882a593Smuzhiyun	in the future only enable certain peripherals */
176*4882a593Smuzhiyun	move.l	#0xFC04002D, %a1
177*4882a593Smuzhiyun
178*4882a593Smuzhiyun#if defined(CONFIG_CF_SBF)
179*4882a593Smuzhiyun	move.b	#23, (%a1)		/* dspi */
180*4882a593Smuzhiyun#endif
181*4882a593Smuzhiyun#endif	/* CONFIG_MCF5441x */
182*4882a593Smuzhiyun
183*4882a593Smuzhiyun	/* mandatory board level ddr-sdram init,
184*4882a593Smuzhiyun	 * for both 5441x and 5445x
185*4882a593Smuzhiyun	 */
186*4882a593Smuzhiyun	bsr	sbf_dram_init
187*4882a593Smuzhiyun
188*4882a593Smuzhiyun#ifdef CONFIG_CF_SBF
189*4882a593Smuzhiyun	/*
190*4882a593Smuzhiyun	 * DSPI Initialization
191*4882a593Smuzhiyun	 * a0 - general, sram - 0x80008000 - 32, see M54455EVB.h
192*4882a593Smuzhiyun	 * a1 - dspi status
193*4882a593Smuzhiyun	 * a2 - dtfr
194*4882a593Smuzhiyun	 * a3 - drfr
195*4882a593Smuzhiyun	 * a4 - Dst addr
196*4882a593Smuzhiyun	 */
197*4882a593Smuzhiyun	/* Enable pins for DSPI mode - chip-selects are enabled later */
198*4882a593Smuzhiyunasm_dspi_init:
199*4882a593Smuzhiyun#ifdef CONFIG_MCF5441x
200*4882a593Smuzhiyun	move.l	#0xEC09404E, %a1
201*4882a593Smuzhiyun	move.l	#0xEC09404F, %a2
202*4882a593Smuzhiyun	move.b	#0xFF, (%a1)
203*4882a593Smuzhiyun	move.b	#0x80, (%a2)
204*4882a593Smuzhiyun#endif
205*4882a593Smuzhiyun
206*4882a593Smuzhiyun#ifdef CONFIG_MCF5445x
207*4882a593Smuzhiyun	move.l	#0xFC0A4063, %a0
208*4882a593Smuzhiyun	move.b	#0x7F, (%a0)
209*4882a593Smuzhiyun#endif
210*4882a593Smuzhiyun	/* Configure DSPI module */
211*4882a593Smuzhiyun	move.l	#0xFC05C000, %a0
212*4882a593Smuzhiyun	move.l	#0x80FF0C00, (%a0)	/* Master, clear TX/RX FIFO */
213*4882a593Smuzhiyun
214*4882a593Smuzhiyun	move.l	#0xFC05C00C, %a0
215*4882a593Smuzhiyun#ifdef CONFIG_MCF5441x
216*4882a593Smuzhiyun	move.l	#0x3E000016, (%a0)
217*4882a593Smuzhiyun#endif
218*4882a593Smuzhiyun#ifdef CONFIG_MCF5445x
219*4882a593Smuzhiyun	move.l	#0x3E000011, (%a0)
220*4882a593Smuzhiyun#endif
221*4882a593Smuzhiyun
222*4882a593Smuzhiyun	move.l	#0xFC05C034, %a2	/* dtfr */
223*4882a593Smuzhiyun	move.l	#0xFC05C03B, %a3	/* drfr */
224*4882a593Smuzhiyun
225*4882a593Smuzhiyun	move.l	#(ASM_SBF_IMG_HDR + 4), %a1
226*4882a593Smuzhiyun	move.l	(%a1)+, %d5
227*4882a593Smuzhiyun	move.l	(%a1), %a4
228*4882a593Smuzhiyun
229*4882a593Smuzhiyun	move.l	#(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_SBFHDR_DATA_OFFSET), %a0
230*4882a593Smuzhiyun	move.l	#(CONFIG_SYS_SBFHDR_SIZE), %d4
231*4882a593Smuzhiyun
232*4882a593Smuzhiyun	move.l	#0xFC05C02C, %a1	/* dspi status */
233*4882a593Smuzhiyun
234*4882a593Smuzhiyun	/* Issue commands and address */
235*4882a593Smuzhiyun	move.l	#0x8002000B, %d2	/* Fast Read Cmd */
236*4882a593Smuzhiyun	jsr	asm_dspi_wr_status
237*4882a593Smuzhiyun	jsr	asm_dspi_rd_status
238*4882a593Smuzhiyun
239*4882a593Smuzhiyun	move.l	#0x80020000, %d2	/* Address byte 2 */
240*4882a593Smuzhiyun	jsr	asm_dspi_wr_status
241*4882a593Smuzhiyun	jsr	asm_dspi_rd_status
242*4882a593Smuzhiyun
243*4882a593Smuzhiyun	move.l	#0x80020000, %d2	/* Address byte 1 */
244*4882a593Smuzhiyun	jsr	asm_dspi_wr_status
245*4882a593Smuzhiyun	jsr	asm_dspi_rd_status
246*4882a593Smuzhiyun
247*4882a593Smuzhiyun	move.l	#0x80020000, %d2	/* Address byte 0 */
248*4882a593Smuzhiyun	jsr	asm_dspi_wr_status
249*4882a593Smuzhiyun	jsr	asm_dspi_rd_status
250*4882a593Smuzhiyun
251*4882a593Smuzhiyun	move.l	#0x80020000, %d2	/* Dummy Wr and Rd */
252*4882a593Smuzhiyun	jsr	asm_dspi_wr_status
253*4882a593Smuzhiyun	jsr	asm_dspi_rd_status
254*4882a593Smuzhiyun
255*4882a593Smuzhiyun	/* Transfer serial boot header to sram */
256*4882a593Smuzhiyunasm_dspi_rd_loop1:
257*4882a593Smuzhiyun	move.l	#0x80020000, %d2
258*4882a593Smuzhiyun	jsr	asm_dspi_wr_status
259*4882a593Smuzhiyun	jsr	asm_dspi_rd_status
260*4882a593Smuzhiyun
261*4882a593Smuzhiyun	move.b	%d1, (%a0)		/* read, copy to dst */
262*4882a593Smuzhiyun
263*4882a593Smuzhiyun	add.l	#1, %a0			/* inc dst by 1 */
264*4882a593Smuzhiyun	sub.l	#1, %d4			/* dec cnt by 1 */
265*4882a593Smuzhiyun	bne	asm_dspi_rd_loop1
266*4882a593Smuzhiyun
267*4882a593Smuzhiyun	/* Transfer u-boot from serial flash to memory */
268*4882a593Smuzhiyunasm_dspi_rd_loop2:
269*4882a593Smuzhiyun	move.l	#0x80020000, %d2
270*4882a593Smuzhiyun	jsr	asm_dspi_wr_status
271*4882a593Smuzhiyun	jsr	asm_dspi_rd_status
272*4882a593Smuzhiyun
273*4882a593Smuzhiyun	move.b	%d1, (%a4)		/* read, copy to dst */
274*4882a593Smuzhiyun
275*4882a593Smuzhiyun	add.l	#1, %a4			/* inc dst by 1 */
276*4882a593Smuzhiyun	sub.l	#1, %d5			/* dec cnt by 1 */
277*4882a593Smuzhiyun	bne	asm_dspi_rd_loop2
278*4882a593Smuzhiyun
279*4882a593Smuzhiyun	move.l	#0x00020000, %d2	/* Terminate */
280*4882a593Smuzhiyun	jsr	asm_dspi_wr_status
281*4882a593Smuzhiyun	jsr	asm_dspi_rd_status
282*4882a593Smuzhiyun
283*4882a593Smuzhiyun	/* jump to memory and execute */
284*4882a593Smuzhiyun	move.l	#(CONFIG_SYS_TEXT_BASE + 0x400), %a0
285*4882a593Smuzhiyun	jmp	(%a0)
286*4882a593Smuzhiyun
287*4882a593Smuzhiyunasm_dspi_wr_status:
288*4882a593Smuzhiyun	move.l	(%a1), %d0		/* status */
289*4882a593Smuzhiyun	and.l	#0x0000F000, %d0
290*4882a593Smuzhiyun	cmp.l	#0x00003000, %d0
291*4882a593Smuzhiyun	bgt	asm_dspi_wr_status
292*4882a593Smuzhiyun
293*4882a593Smuzhiyun	move.l	%d2, (%a2)
294*4882a593Smuzhiyun	rts
295*4882a593Smuzhiyun
296*4882a593Smuzhiyunasm_dspi_rd_status:
297*4882a593Smuzhiyun	move.l	(%a1), %d0		/* status */
298*4882a593Smuzhiyun	and.l	#0x000000F0, %d0
299*4882a593Smuzhiyun	lsr.l	#4, %d0
300*4882a593Smuzhiyun	cmp.l	#0, %d0
301*4882a593Smuzhiyun	beq	asm_dspi_rd_status
302*4882a593Smuzhiyun
303*4882a593Smuzhiyun	move.b	(%a3), %d1
304*4882a593Smuzhiyun	rts
305*4882a593Smuzhiyun#endif /* CONFIG_CF_SBF */
306*4882a593Smuzhiyun
307*4882a593Smuzhiyun#ifdef CONFIG_SYS_NAND_BOOT
308*4882a593Smuzhiyun	/* copy 4 boot pages to dram as soon as possible */
309*4882a593Smuzhiyun	/* each page is 996 bytes (1056 total with 60 ECC bytes */
310*4882a593Smuzhiyun	move.l  #0x00000000, %a1	/* src */
311*4882a593Smuzhiyun	move.l	#CONFIG_SYS_TEXT_BASE, %a2		/* dst */
312*4882a593Smuzhiyun	move.l	#0x3E0, %d0		/* sz in long */
313*4882a593Smuzhiyun
314*4882a593Smuzhiyunasm_boot_nand_copy:
315*4882a593Smuzhiyun	move.l	(%a1)+, (%a2)+
316*4882a593Smuzhiyun	subq.l	#1, %d0
317*4882a593Smuzhiyun	bne	asm_boot_nand_copy
318*4882a593Smuzhiyun
319*4882a593Smuzhiyun	/* jump to memory and execute */
320*4882a593Smuzhiyun	move.l	#(asm_nand_init), %a0
321*4882a593Smuzhiyun	jmp	(%a0)
322*4882a593Smuzhiyun
323*4882a593Smuzhiyunasm_nand_init:
324*4882a593Smuzhiyun	/* exit nand boot-mode */
325*4882a593Smuzhiyun	move.l	#0xFC0FFF30, %a1
326*4882a593Smuzhiyun	or.l	#0x00000040, %d1
327*4882a593Smuzhiyun	move.l	%d1, (%a1)
328*4882a593Smuzhiyun
329*4882a593Smuzhiyun	/* initialize general use internal ram */
330*4882a593Smuzhiyun	move.l	#0, %d0
331*4882a593Smuzhiyun	move.l	#(CACR_STATUS), %a1	/* CACR */
332*4882a593Smuzhiyun	move.l	#(ICACHE_STATUS), %a2	/* icache */
333*4882a593Smuzhiyun	move.l	#(DCACHE_STATUS), %a3	/* dcache */
334*4882a593Smuzhiyun	move.l	%d0, (%a1)
335*4882a593Smuzhiyun	move.l	%d0, (%a2)
336*4882a593Smuzhiyun	move.l	%d0, (%a3)
337*4882a593Smuzhiyun
338*4882a593Smuzhiyun	/* invalidate and disable cache */
339*4882a593Smuzhiyun	move.l	#0x01004100, %d0	/* Invalidate cache cmd */
340*4882a593Smuzhiyun	movec	%d0, %CACR		/* Invalidate cache */
341*4882a593Smuzhiyun	move.l	#0, %d0
342*4882a593Smuzhiyun	movec	%d0, %ACR0
343*4882a593Smuzhiyun	movec	%d0, %ACR1
344*4882a593Smuzhiyun	movec	%d0, %ACR2
345*4882a593Smuzhiyun	movec	%d0, %ACR3
346*4882a593Smuzhiyun
347*4882a593Smuzhiyun#ifdef CONFIG_SYS_CS0_BASE
348*4882a593Smuzhiyun	/* Must disable global address */
349*4882a593Smuzhiyun	move.l	#0xFC008000, %a1
350*4882a593Smuzhiyun	move.l	#(CONFIG_SYS_CS0_BASE), (%a1)
351*4882a593Smuzhiyun	move.l	#0xFC008008, %a1
352*4882a593Smuzhiyun	move.l	#(CONFIG_SYS_CS0_CTRL), (%a1)
353*4882a593Smuzhiyun	move.l	#0xFC008004, %a1
354*4882a593Smuzhiyun	move.l	#(CONFIG_SYS_CS0_MASK), (%a1)
355*4882a593Smuzhiyun#endif
356*4882a593Smuzhiyun
357*4882a593Smuzhiyun	/* NAND port configuration */
358*4882a593Smuzhiyun	move.l	#0xEC094048, %a1
359*4882a593Smuzhiyun	move.b	#0xFD, (%a1)+
360*4882a593Smuzhiyun	move.b	#0x5F, (%a1)+
361*4882a593Smuzhiyun	move.b	#0x04, (%a1)+
362*4882a593Smuzhiyun
363*4882a593Smuzhiyun	/* reset nand */
364*4882a593Smuzhiyun	move.l  #0xFC0FFF38, %a1	/* isr */
365*4882a593Smuzhiyun	move.l  #0x000e0000, (%a1)
366*4882a593Smuzhiyun	move.l	#0xFC0FFF08, %a2
367*4882a593Smuzhiyun	move.l	#0x00000000, (%a2)+	/* car */
368*4882a593Smuzhiyun	move.l	#0x11000000, (%a2)+	/* rar */
369*4882a593Smuzhiyun	move.l	#0x00000000, (%a2)+	/* rpt */
370*4882a593Smuzhiyun	move.l	#0x00000000, (%a2)+	/* rai */
371*4882a593Smuzhiyun	move.l  #0xFC0FFF2c, %a2	/* cfg */
372*4882a593Smuzhiyun	move.l  #0x00000000, (%a2)+	/* secsz */
373*4882a593Smuzhiyun	move.l  #0x000e0681, (%a2)+
374*4882a593Smuzhiyun	move.l  #0xFC0FFF04, %a2	/* cmd2 */
375*4882a593Smuzhiyun	move.l  #0xFF404001, (%a2)
376*4882a593Smuzhiyun	move.l  #0x000e0000, (%a1)
377*4882a593Smuzhiyun
378*4882a593Smuzhiyun	move.l	#0x2000, %d1
379*4882a593Smuzhiyun	bsr	asm_delay
380*4882a593Smuzhiyun
381*4882a593Smuzhiyun	/* setup nand */
382*4882a593Smuzhiyun	move.l  #0xFC0FFF00, %a1
383*4882a593Smuzhiyun	move.l  #0x30700000, (%a1)+	/* cmd1 */
384*4882a593Smuzhiyun	move.l  #0x007EF000, (%a1)+	/* cmd2 */
385*4882a593Smuzhiyun
386*4882a593Smuzhiyun	move.l  #0xFC0FFF2C, %a1
387*4882a593Smuzhiyun	move.l  #0x00000841, (%a1)+	/* secsz */
388*4882a593Smuzhiyun	move.l  #0x000e0681, (%a1)+	/* cfg */
389*4882a593Smuzhiyun
390*4882a593Smuzhiyun	move.l	#100, %d4		/* 100 pages ~200KB */
391*4882a593Smuzhiyun	move.l	#4, %d2			/* start at 4 */
392*4882a593Smuzhiyun	move.l  #0xFC0FFF04, %a0	/* cmd2 */
393*4882a593Smuzhiyun	move.l  #0xFC0FFF0C, %a1	/* rar */
394*4882a593Smuzhiyun	move.l	#(CONFIG_SYS_TEXT_BASE + 0xF80), %a2
395*4882a593Smuzhiyun
396*4882a593Smuzhiyunasm_nand_read:
397*4882a593Smuzhiyun	move.l	#0x11000000, %d0	/* rar */
398*4882a593Smuzhiyun	or.l	%d2, %d0
399*4882a593Smuzhiyun	move.l	%d0, (%a1)
400*4882a593Smuzhiyun	add.l	#1, %d2
401*4882a593Smuzhiyun
402*4882a593Smuzhiyun	move.l	(%a0), %d0		/* cmd2 */
403*4882a593Smuzhiyun	or.l	#1, %d0
404*4882a593Smuzhiyun	move.l	%d0, (%a0)
405*4882a593Smuzhiyun
406*4882a593Smuzhiyun	move.l	#0x200, %d1
407*4882a593Smuzhiyun	bsr	asm_delay
408*4882a593Smuzhiyun
409*4882a593Smuzhiyunasm_nand_chk_status:
410*4882a593Smuzhiyun	move.l  #0xFC0FFF38, %a4	/* isr */
411*4882a593Smuzhiyun	move.l	(%a4), %d0
412*4882a593Smuzhiyun	and.l	#0x40000000, %d0
413*4882a593Smuzhiyun	tst.l	%d0
414*4882a593Smuzhiyun	beq	asm_nand_chk_status
415*4882a593Smuzhiyun
416*4882a593Smuzhiyun	move.l  #0xFC0FFF38, %a4	/* isr */
417*4882a593Smuzhiyun	move.l	(%a4), %d0
418*4882a593Smuzhiyun	or.l	#0x000E0000, %d0
419*4882a593Smuzhiyun	move.l	%d0, (%a4)
420*4882a593Smuzhiyun
421*4882a593Smuzhiyun	move.l	#0x200, %d3
422*4882a593Smuzhiyun	move.l	#0xFC0FC000, %a3	/* buf 1 */
423*4882a593Smuzhiyunasm_nand_copy:
424*4882a593Smuzhiyun	move.l	(%a3)+, (%a2)+
425*4882a593Smuzhiyun	subq.l	#1, %d3
426*4882a593Smuzhiyun	bgt	asm_nand_copy
427*4882a593Smuzhiyun
428*4882a593Smuzhiyun	subq.l	#1, %d4
429*4882a593Smuzhiyun	bgt	asm_nand_read
430*4882a593Smuzhiyun
431*4882a593Smuzhiyun	/* jump to memory and execute */
432*4882a593Smuzhiyun	move.l	#(CONFIG_SYS_TEXT_BASE + 0x400), %a0
433*4882a593Smuzhiyun	jmp	(%a0)
434*4882a593Smuzhiyun
435*4882a593Smuzhiyun#endif			/* CONFIG_SYS_NAND_BOOT */
436*4882a593Smuzhiyun
437*4882a593Smuzhiyun.globl asm_delay
438*4882a593Smuzhiyunasm_delay:
439*4882a593Smuzhiyun	nop
440*4882a593Smuzhiyun	subq.l	#1, %d1
441*4882a593Smuzhiyun	bne	asm_delay
442*4882a593Smuzhiyun	rts
443*4882a593Smuzhiyun#endif			/* CONFIG_CF_SBF || CONFIG_NAND_U_BOOT */
444*4882a593Smuzhiyun
445*4882a593Smuzhiyun.text
446*4882a593Smuzhiyun	. = 0x400
447*4882a593Smuzhiyun.globl _start
448*4882a593Smuzhiyun_start:
449*4882a593Smuzhiyun#if !defined(CONFIG_SERIAL_BOOT)
450*4882a593Smuzhiyun	nop
451*4882a593Smuzhiyun	nop
452*4882a593Smuzhiyun	move.w	#0x2700,%sr		/* Mask off Interrupt */
453*4882a593Smuzhiyun
454*4882a593Smuzhiyun	/* Set vector base register at the beginning of the Flash */
455*4882a593Smuzhiyun	move.l	#CONFIG_SYS_FLASH_BASE, %d0
456*4882a593Smuzhiyun	movec	%d0, %VBR
457*4882a593Smuzhiyun
458*4882a593Smuzhiyun	move.l	#(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_CTRL), %d0
459*4882a593Smuzhiyun	movec	%d0, %RAMBAR1
460*4882a593Smuzhiyun
461*4882a593Smuzhiyun	/* initialize general use internal ram */
462*4882a593Smuzhiyun	move.l	#0, %d0
463*4882a593Smuzhiyun	move.l	#(ICACHE_STATUS), %a1	/* icache */
464*4882a593Smuzhiyun	move.l	#(DCACHE_STATUS), %a2	/* dcache */
465*4882a593Smuzhiyun	move.l	%d0, (%a1)
466*4882a593Smuzhiyun	move.l	%d0, (%a2)
467*4882a593Smuzhiyun
468*4882a593Smuzhiyun	/* invalidate and disable cache */
469*4882a593Smuzhiyun	move.l	#(CONFIG_SYS_ICACHE_INV + CONFIG_SYS_DCACHE_INV), %d0
470*4882a593Smuzhiyun	movec	%d0, %CACR		/* Invalidate cache */
471*4882a593Smuzhiyun	move.l	#0, %d0
472*4882a593Smuzhiyun	movec	%d0, %ACR0
473*4882a593Smuzhiyun	movec	%d0, %ACR1
474*4882a593Smuzhiyun	movec	%d0, %ACR2
475*4882a593Smuzhiyun	movec	%d0, %ACR3
476*4882a593Smuzhiyun#else
477*4882a593Smuzhiyun	move.l	#(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_CTRL), %d0
478*4882a593Smuzhiyun	movec	%d0, %RAMBAR1
479*4882a593Smuzhiyun#endif
480*4882a593Smuzhiyun
481*4882a593Smuzhiyun	/* put relocation table address to a5 */
482*4882a593Smuzhiyun	move.l	#__got_start, %a5
483*4882a593Smuzhiyun
484*4882a593Smuzhiyun	/* setup stack initially on top of internal static ram  */
485*4882a593Smuzhiyun	move.l	#(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_SIZE), %sp
486*4882a593Smuzhiyun
487*4882a593Smuzhiyun	/*
488*4882a593Smuzhiyun	 * if configured, malloc_f arena will be reserved first,
489*4882a593Smuzhiyun	 * then (and always) gd struct space will be reserved
490*4882a593Smuzhiyun	 */
491*4882a593Smuzhiyun	move.l	%sp, -(%sp)
492*4882a593Smuzhiyun	move.l	#board_init_f_alloc_reserve, %a1
493*4882a593Smuzhiyun	jsr	(%a1)
494*4882a593Smuzhiyun
495*4882a593Smuzhiyun	/* update stack and frame-pointers */
496*4882a593Smuzhiyun	move.l	%d0, %sp
497*4882a593Smuzhiyun	move.l	%sp, %fp
498*4882a593Smuzhiyun
499*4882a593Smuzhiyun	/* initialize reserved area */
500*4882a593Smuzhiyun	move.l	%d0, -(%sp)
501*4882a593Smuzhiyun	move.l	#board_init_f_init_reserve, %a1
502*4882a593Smuzhiyun	jsr	(%a1)
503*4882a593Smuzhiyun
504*4882a593Smuzhiyun	/* run low-level CPU init code (from flash) */
505*4882a593Smuzhiyun	move.l	#cpu_init_f, %a1
506*4882a593Smuzhiyun	jsr	(%a1)
507*4882a593Smuzhiyun
508*4882a593Smuzhiyun	/* run low-level board init code (from flash) */
509*4882a593Smuzhiyun	clr.l   %sp@-
510*4882a593Smuzhiyun	move.l	#board_init_f, %a1
511*4882a593Smuzhiyun	jsr	(%a1)
512*4882a593Smuzhiyun
513*4882a593Smuzhiyun	/* board_init_f() does not return */
514*4882a593Smuzhiyun
515*4882a593Smuzhiyun/******************************************************************************/
516*4882a593Smuzhiyun
517*4882a593Smuzhiyun/*
518*4882a593Smuzhiyun * void relocate_code (addr_sp, gd, addr_moni)
519*4882a593Smuzhiyun *
520*4882a593Smuzhiyun * This "function" does not return, instead it continues in RAM
521*4882a593Smuzhiyun * after relocating the monitor code.
522*4882a593Smuzhiyun *
523*4882a593Smuzhiyun * r3 = dest
524*4882a593Smuzhiyun * r4 = src
525*4882a593Smuzhiyun * r5 = length in bytes
526*4882a593Smuzhiyun * r6 = cachelinesize
527*4882a593Smuzhiyun */
528*4882a593Smuzhiyun.globl relocate_code
529*4882a593Smuzhiyunrelocate_code:
530*4882a593Smuzhiyun	link.w	%a6,#0
531*4882a593Smuzhiyun	move.l	8(%a6), %sp		/* set new stack pointer */
532*4882a593Smuzhiyun
533*4882a593Smuzhiyun	move.l	12(%a6), %d0		/* Save copy of Global Data pointer */
534*4882a593Smuzhiyun	move.l	16(%a6), %a0		/* Save copy of Destination Address */
535*4882a593Smuzhiyun
536*4882a593Smuzhiyun	move.l	#CONFIG_SYS_MONITOR_BASE, %a1
537*4882a593Smuzhiyun	move.l	#__init_end, %a2
538*4882a593Smuzhiyun	move.l	%a0, %a3
539*4882a593Smuzhiyun
540*4882a593Smuzhiyun	/* copy the code to RAM */
541*4882a593Smuzhiyun1:
542*4882a593Smuzhiyun	move.l	(%a1)+, (%a3)+
543*4882a593Smuzhiyun	cmp.l	%a1,%a2
544*4882a593Smuzhiyun	bgt.s	1b
545*4882a593Smuzhiyun
546*4882a593Smuzhiyun/*
547*4882a593Smuzhiyun * We are done. Do not return, instead branch to second part of board
548*4882a593Smuzhiyun * initialization, now running from RAM.
549*4882a593Smuzhiyun */
550*4882a593Smuzhiyun	move.l	%a0, %a1
551*4882a593Smuzhiyun	add.l	#(in_ram - CONFIG_SYS_MONITOR_BASE), %a1
552*4882a593Smuzhiyun	jmp	(%a1)
553*4882a593Smuzhiyun
554*4882a593Smuzhiyunin_ram:
555*4882a593Smuzhiyun
556*4882a593Smuzhiyunclear_bss:
557*4882a593Smuzhiyun	/*
558*4882a593Smuzhiyun	 * Now clear BSS segment
559*4882a593Smuzhiyun	 */
560*4882a593Smuzhiyun	move.l	%a0, %a1
561*4882a593Smuzhiyun	add.l	#(_sbss - CONFIG_SYS_MONITOR_BASE),%a1
562*4882a593Smuzhiyun	move.l	%a0, %d1
563*4882a593Smuzhiyun	add.l	#(_ebss - CONFIG_SYS_MONITOR_BASE),%d1
564*4882a593Smuzhiyun6:
565*4882a593Smuzhiyun	clr.l	(%a1)+
566*4882a593Smuzhiyun	cmp.l	%a1,%d1
567*4882a593Smuzhiyun	bgt.s	6b
568*4882a593Smuzhiyun
569*4882a593Smuzhiyun	/*
570*4882a593Smuzhiyun	 * fix got table in RAM
571*4882a593Smuzhiyun	 */
572*4882a593Smuzhiyun	move.l	%a0, %a1
573*4882a593Smuzhiyun	add.l	#(__got_start - CONFIG_SYS_MONITOR_BASE),%a1
574*4882a593Smuzhiyun	move.l	%a1,%a5			/* fix got pointer register a5 */
575*4882a593Smuzhiyun
576*4882a593Smuzhiyun	move.l	%a0, %a2
577*4882a593Smuzhiyun	add.l	#(__got_end - CONFIG_SYS_MONITOR_BASE),%a2
578*4882a593Smuzhiyun
579*4882a593Smuzhiyun7:
580*4882a593Smuzhiyun	move.l	(%a1),%d1
581*4882a593Smuzhiyun	sub.l	#_start,%d1
582*4882a593Smuzhiyun	add.l	%a0,%d1
583*4882a593Smuzhiyun	move.l	%d1,(%a1)+
584*4882a593Smuzhiyun	cmp.l	%a2, %a1
585*4882a593Smuzhiyun	bne	7b
586*4882a593Smuzhiyun
587*4882a593Smuzhiyun	/* calculate relative jump to board_init_r in ram */
588*4882a593Smuzhiyun	move.l	%a0, %a1
589*4882a593Smuzhiyun	add.l	#(board_init_r - CONFIG_SYS_MONITOR_BASE), %a1
590*4882a593Smuzhiyun
591*4882a593Smuzhiyun	/* set parameters for board_init_r */
592*4882a593Smuzhiyun	move.l	%a0,-(%sp)		/* dest_addr */
593*4882a593Smuzhiyun	move.l	%d0,-(%sp)		/* gd */
594*4882a593Smuzhiyun	jsr	(%a1)
595*4882a593Smuzhiyun
596*4882a593Smuzhiyun/******************************************************************************/
597*4882a593Smuzhiyun
598*4882a593Smuzhiyun/* exception code */
599*4882a593Smuzhiyun.globl _fault
600*4882a593Smuzhiyun_fault:
601*4882a593Smuzhiyun	bra	_fault
602*4882a593Smuzhiyun
603*4882a593Smuzhiyun.globl _exc_handler
604*4882a593Smuzhiyun_exc_handler:
605*4882a593Smuzhiyun	SAVE_ALL
606*4882a593Smuzhiyun	movel	%sp,%sp@-
607*4882a593Smuzhiyun	bsr	exc_handler
608*4882a593Smuzhiyun	addql	#4,%sp
609*4882a593Smuzhiyun	RESTORE_ALL
610*4882a593Smuzhiyun
611*4882a593Smuzhiyun.globl _int_handler
612*4882a593Smuzhiyun_int_handler:
613*4882a593Smuzhiyun	SAVE_ALL
614*4882a593Smuzhiyun	movel	%sp,%sp@-
615*4882a593Smuzhiyun	bsr	int_handler
616*4882a593Smuzhiyun	addql	#4,%sp
617*4882a593Smuzhiyun	RESTORE_ALL
618*4882a593Smuzhiyun
619*4882a593Smuzhiyun/******************************************************************************/
620*4882a593Smuzhiyun
621*4882a593Smuzhiyun.globl version_string
622*4882a593Smuzhiyunversion_string:
623*4882a593Smuzhiyun.ascii U_BOOT_VERSION_STRING, "\0"
624*4882a593Smuzhiyun.align 4
625