xref: /OK3568_Linux_fs/u-boot/arch/m68k/cpu/mcf532x/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 * (C) Copyright 2004-2008 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 <asm-offsets.h>
12*4882a593Smuzhiyun#include <config.h>
13*4882a593Smuzhiyun#include "version.h"
14*4882a593Smuzhiyun#include <asm/cache.h>
15*4882a593Smuzhiyun
16*4882a593Smuzhiyun#define _START	_start
17*4882a593Smuzhiyun#define _FAULT	_fault
18*4882a593Smuzhiyun
19*4882a593Smuzhiyun#define SAVE_ALL						\
20*4882a593Smuzhiyun	move.w	#0x2700,%sr;		/* disable intrs */	\
21*4882a593Smuzhiyun	subl	#60,%sp;		/* space for 15 regs */ \
22*4882a593Smuzhiyun	moveml	%d0-%d7/%a0-%a6,%sp@;
23*4882a593Smuzhiyun
24*4882a593Smuzhiyun#define RESTORE_ALL						\
25*4882a593Smuzhiyun	moveml	%sp@,%d0-%d7/%a0-%a6;				\
26*4882a593Smuzhiyun	addl	#60,%sp;		/* space for 15 regs */ \
27*4882a593Smuzhiyun	rte;
28*4882a593Smuzhiyun
29*4882a593Smuzhiyun#if !defined(CONFIG_MONITOR_IS_IN_RAM)
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun.text
32*4882a593Smuzhiyun
33*4882a593Smuzhiyun/*
34*4882a593Smuzhiyun * Vector table. This is used for initial platform startup.
35*4882a593Smuzhiyun * These vectors are to catch any un-intended traps.
36*4882a593Smuzhiyun */
37*4882a593Smuzhiyun_vectors:
38*4882a593SmuzhiyunINITSP:	.long	0x00000000		/* Initial SP	*/
39*4882a593SmuzhiyunINITPC:	.long	_START			/* Initial PC		*/
40*4882a593Smuzhiyun
41*4882a593Smuzhiyunvector02_0F:
42*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
43*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
44*4882a593Smuzhiyun
45*4882a593Smuzhiyun/* Reserved */
46*4882a593Smuzhiyunvector10_17:
47*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
48*4882a593Smuzhiyun
49*4882a593Smuzhiyunvector18_1F:
50*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
51*4882a593Smuzhiyun
52*4882a593Smuzhiyun/* TRAP #0 - #15 */
53*4882a593Smuzhiyunvector20_2F:
54*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
55*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun/* Reserved	*/
58*4882a593Smuzhiyunvector30_3F:
59*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
60*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
61*4882a593Smuzhiyun
62*4882a593Smuzhiyunvector64_127:
63*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
64*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
65*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
66*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
67*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
68*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
69*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
70*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
71*4882a593Smuzhiyun
72*4882a593Smuzhiyunvector128_191:
73*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
74*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
75*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
76*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
77*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
78*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
79*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
80*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
81*4882a593Smuzhiyun
82*4882a593Smuzhiyunvector192_255:
83*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
84*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
85*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
86*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
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#endif /* !defined(CONFIG_MONITOR_IS_IN_RAM) */
92*4882a593Smuzhiyun
93*4882a593Smuzhiyun.text
94*4882a593Smuzhiyun
95*4882a593Smuzhiyun.globl _start
96*4882a593Smuzhiyun_start:
97*4882a593Smuzhiyun	nop
98*4882a593Smuzhiyun	nop
99*4882a593Smuzhiyun	move.w	#0x2700,%sr	/* Mask off Interrupt */
100*4882a593Smuzhiyun
101*4882a593Smuzhiyun#if !defined(CONFIG_MONITOR_IS_IN_RAM)
102*4882a593Smuzhiyun	/* Set vector base register at the beginning of the Flash */
103*4882a593Smuzhiyun	move.l	#CONFIG_SYS_FLASH_BASE, %d0
104*4882a593Smuzhiyun	movec	%d0, %VBR
105*4882a593Smuzhiyun#endif
106*4882a593Smuzhiyun
107*4882a593Smuzhiyun	move.l	#(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_CTRL), %d0
108*4882a593Smuzhiyun	movec	%d0, %RAMBAR1
109*4882a593Smuzhiyun
110*4882a593Smuzhiyun	/* invalidate and disable cache */
111*4882a593Smuzhiyun	move.l	#CF_CACR_CINVA, %d0		/* Invalidate cache cmd */
112*4882a593Smuzhiyun	movec	%d0, %CACR			/* Invalidate cache */
113*4882a593Smuzhiyun	move.l	#0, %d0
114*4882a593Smuzhiyun	movec	%d0, %ACR0
115*4882a593Smuzhiyun	movec	%d0, %ACR1
116*4882a593Smuzhiyun
117*4882a593Smuzhiyun#ifdef CONFIG_MCF5301x
118*4882a593Smuzhiyun	move.l	#(0xFC0a0010), %a0
119*4882a593Smuzhiyun	move.w	(%a0), %d0
120*4882a593Smuzhiyun	and.l	%d0, 0xEFFF
121*4882a593Smuzhiyun
122*4882a593Smuzhiyun	move.w	%d0, (%a0)
123*4882a593Smuzhiyun#endif
124*4882a593Smuzhiyun
125*4882a593Smuzhiyun	/* initialize general use internal ram */
126*4882a593Smuzhiyun	move.l	#0, %d0
127*4882a593Smuzhiyun	move.l	#(ICACHE_STATUS), %a1	/* icache */
128*4882a593Smuzhiyun	move.l	#(DCACHE_STATUS), %a2	/* icache */
129*4882a593Smuzhiyun	move.l	%d0, (%a1)
130*4882a593Smuzhiyun	move.l	%d0, (%a2)
131*4882a593Smuzhiyun
132*4882a593Smuzhiyun	/* put relocation table address to a5 */
133*4882a593Smuzhiyun	move.l	#__got_start, %a5
134*4882a593Smuzhiyun
135*4882a593Smuzhiyun	/* setup stack initially on top of internal static ram  */
136*4882a593Smuzhiyun	move.l  #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_SIZE), %sp
137*4882a593Smuzhiyun
138*4882a593Smuzhiyun	/*
139*4882a593Smuzhiyun	 * if configured, malloc_f arena will be reserved first,
140*4882a593Smuzhiyun	 * then (and always) gd struct space will be reserved
141*4882a593Smuzhiyun	 */
142*4882a593Smuzhiyun	move.l	%sp, -(%sp)
143*4882a593Smuzhiyun	move.l	#board_init_f_alloc_reserve, %a1
144*4882a593Smuzhiyun	jsr	(%a1)
145*4882a593Smuzhiyun
146*4882a593Smuzhiyun	/* update stack and frame-pointers */
147*4882a593Smuzhiyun	move.l  %d0, %sp
148*4882a593Smuzhiyun	move.l  %sp, %fp
149*4882a593Smuzhiyun
150*4882a593Smuzhiyun	/* initialize reserved area */
151*4882a593Smuzhiyun	move.l	%d0, -(%sp)
152*4882a593Smuzhiyun	move.l	#board_init_f_init_reserve, %a1
153*4882a593Smuzhiyun	jsr	(%a1)
154*4882a593Smuzhiyun
155*4882a593Smuzhiyun	/* run low-level CPU init code (from flash) */
156*4882a593Smuzhiyun	move.l	#cpu_init_f, %a1
157*4882a593Smuzhiyun	jsr	(%a1)
158*4882a593Smuzhiyun
159*4882a593Smuzhiyun	/* run low-level board init code (from flash) */
160*4882a593Smuzhiyun	clr.l   %sp@-
161*4882a593Smuzhiyun	move.l #board_init_f, %a1
162*4882a593Smuzhiyun	jsr (%a1)
163*4882a593Smuzhiyun
164*4882a593Smuzhiyun	/* board_init_f() does not return */
165*4882a593Smuzhiyun
166*4882a593Smuzhiyun/******************************************************************************/
167*4882a593Smuzhiyun
168*4882a593Smuzhiyun/*
169*4882a593Smuzhiyun * void relocate_code (addr_sp, gd, addr_moni)
170*4882a593Smuzhiyun *
171*4882a593Smuzhiyun * This "function" does not return, instead it continues in RAM
172*4882a593Smuzhiyun * after relocating the monitor code.
173*4882a593Smuzhiyun *
174*4882a593Smuzhiyun * r3 = dest
175*4882a593Smuzhiyun * r4 = src
176*4882a593Smuzhiyun * r5 = length in bytes
177*4882a593Smuzhiyun * r6 = cachelinesize
178*4882a593Smuzhiyun */
179*4882a593Smuzhiyun.globl relocate_code
180*4882a593Smuzhiyunrelocate_code:
181*4882a593Smuzhiyun	link.w	%a6,#0
182*4882a593Smuzhiyun	move.l	8(%a6), %sp		/* set new stack pointer */
183*4882a593Smuzhiyun
184*4882a593Smuzhiyun	move.l	12(%a6), %d0		/* Save copy of Global Data pointer */
185*4882a593Smuzhiyun	move.l	16(%a6), %a0		/* Save copy of Destination Address */
186*4882a593Smuzhiyun
187*4882a593Smuzhiyun	move.l	#CONFIG_SYS_MONITOR_BASE, %a1
188*4882a593Smuzhiyun	move.l	#__init_end, %a2
189*4882a593Smuzhiyun	move.l	%a0, %a3
190*4882a593Smuzhiyun
191*4882a593Smuzhiyun	/* copy the code to RAM */
192*4882a593Smuzhiyun1:
193*4882a593Smuzhiyun	move.l	(%a1)+, (%a3)+
194*4882a593Smuzhiyun	cmp.l	%a1,%a2
195*4882a593Smuzhiyun	bgt.s	1b
196*4882a593Smuzhiyun
197*4882a593Smuzhiyun/*
198*4882a593Smuzhiyun * We are done. Do not return, instead branch to second part of board
199*4882a593Smuzhiyun * initialization, now running from RAM.
200*4882a593Smuzhiyun */
201*4882a593Smuzhiyun	move.l	%a0, %a1
202*4882a593Smuzhiyun	add.l	#(in_ram - CONFIG_SYS_MONITOR_BASE), %a1
203*4882a593Smuzhiyun	jmp	(%a1)
204*4882a593Smuzhiyun
205*4882a593Smuzhiyunin_ram:
206*4882a593Smuzhiyun
207*4882a593Smuzhiyunclear_bss:
208*4882a593Smuzhiyun	/*
209*4882a593Smuzhiyun	 * Now clear BSS segment
210*4882a593Smuzhiyun	 */
211*4882a593Smuzhiyun	move.l	%a0, %a1
212*4882a593Smuzhiyun	add.l	#(_sbss - CONFIG_SYS_MONITOR_BASE),%a1
213*4882a593Smuzhiyun	move.l	%a0, %d1
214*4882a593Smuzhiyun	add.l	#(_ebss - CONFIG_SYS_MONITOR_BASE),%d1
215*4882a593Smuzhiyun6:
216*4882a593Smuzhiyun	clr.l	(%a1)+
217*4882a593Smuzhiyun	cmp.l	%a1,%d1
218*4882a593Smuzhiyun	bgt.s	6b
219*4882a593Smuzhiyun
220*4882a593Smuzhiyun	/*
221*4882a593Smuzhiyun	 * fix got table in RAM
222*4882a593Smuzhiyun	 */
223*4882a593Smuzhiyun	move.l	%a0, %a1
224*4882a593Smuzhiyun	add.l	#(__got_start - CONFIG_SYS_MONITOR_BASE),%a1
225*4882a593Smuzhiyun	move.l	%a1,%a5			/* fix got pointer register a5 */
226*4882a593Smuzhiyun
227*4882a593Smuzhiyun	move.l	%a0, %a2
228*4882a593Smuzhiyun	add.l	#(__got_end - CONFIG_SYS_MONITOR_BASE),%a2
229*4882a593Smuzhiyun
230*4882a593Smuzhiyun7:
231*4882a593Smuzhiyun	move.l	(%a1),%d1
232*4882a593Smuzhiyun	sub.l	#_start,%d1
233*4882a593Smuzhiyun	add.l	%a0,%d1
234*4882a593Smuzhiyun	move.l	%d1,(%a1)+
235*4882a593Smuzhiyun	cmp.l	%a2, %a1
236*4882a593Smuzhiyun	bne	7b
237*4882a593Smuzhiyun
238*4882a593Smuzhiyun	/* calculate relative jump to board_init_r in ram */
239*4882a593Smuzhiyun	move.l	%a0, %a1
240*4882a593Smuzhiyun	add.l	#(board_init_r - CONFIG_SYS_MONITOR_BASE), %a1
241*4882a593Smuzhiyun
242*4882a593Smuzhiyun	/* set parameters for board_init_r */
243*4882a593Smuzhiyun	move.l	%a0,-(%sp)		/* dest_addr */
244*4882a593Smuzhiyun	move.l	%d0,-(%sp)		/* gd */
245*4882a593Smuzhiyun	jsr	(%a1)
246*4882a593Smuzhiyun
247*4882a593Smuzhiyun/******************************************************************************/
248*4882a593Smuzhiyun
249*4882a593Smuzhiyun/* exception code */
250*4882a593Smuzhiyun.globl _fault
251*4882a593Smuzhiyun_fault:
252*4882a593Smuzhiyun	bra _fault
253*4882a593Smuzhiyun
254*4882a593Smuzhiyun.globl _exc_handler
255*4882a593Smuzhiyun_exc_handler:
256*4882a593Smuzhiyun	SAVE_ALL
257*4882a593Smuzhiyun	movel	%sp,%sp@-
258*4882a593Smuzhiyun	bsr	exc_handler
259*4882a593Smuzhiyun	addql	#4,%sp
260*4882a593Smuzhiyun	RESTORE_ALL
261*4882a593Smuzhiyun
262*4882a593Smuzhiyun.globl _int_handler
263*4882a593Smuzhiyun_int_handler:
264*4882a593Smuzhiyun	SAVE_ALL
265*4882a593Smuzhiyun	movel	%sp,%sp@-
266*4882a593Smuzhiyun	bsr	int_handler
267*4882a593Smuzhiyun	addql	#4,%sp
268*4882a593Smuzhiyun	RESTORE_ALL
269*4882a593Smuzhiyun
270*4882a593Smuzhiyun/******************************************************************************/
271*4882a593Smuzhiyun
272*4882a593Smuzhiyun.globl version_string
273*4882a593Smuzhiyunversion_string:
274*4882a593Smuzhiyun.ascii U_BOOT_VERSION_STRING, "\0"
275*4882a593Smuzhiyun.align 4
276