xref: /OK3568_Linux_fs/u-boot/arch/m68k/cpu/mcf530x/start.S (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun/*
2*4882a593Smuzhiyun * (C) Copyright 2015  Angelo Dureghello <angelo@sysam.it>
3*4882a593Smuzhiyun * Based on code from Bernhard Kuhn <bkuhn@metrowerks.com>
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * SPDX-License-Identifier:	GPL-2.0+
6*4882a593Smuzhiyun */
7*4882a593Smuzhiyun
8*4882a593Smuzhiyun#include <asm-offsets.h>
9*4882a593Smuzhiyun#include <config.h>
10*4882a593Smuzhiyun#include "version.h"
11*4882a593Smuzhiyun#include <asm/cache.h>
12*4882a593Smuzhiyun
13*4882a593Smuzhiyun#define _START	_start
14*4882a593Smuzhiyun#define _FAULT	_fault
15*4882a593Smuzhiyun
16*4882a593Smuzhiyun
17*4882a593Smuzhiyun.macro  SAVE_ALL
18*4882a593Smuzhiyun	move.w	#0x2700,%sr;		/* disable intrs */
19*4882a593Smuzhiyun	subl	#60,%sp;		/* space for 15 regs */
20*4882a593Smuzhiyun	moveml	%d0-%d7/%a0-%a6,%sp@
21*4882a593Smuzhiyun.endm
22*4882a593Smuzhiyun
23*4882a593Smuzhiyun.macro  RESTORE_ALL
24*4882a593Smuzhiyun	moveml	%sp@,%d0-%d7/%a0-%a6;
25*4882a593Smuzhiyun	addl	#60,%sp;		/* space for 15 regs */
26*4882a593Smuzhiyun	rte
27*4882a593Smuzhiyun.endm
28*4882a593Smuzhiyun
29*4882a593Smuzhiyun/* If we come from a pre-loader we don't need an initial exception
30*4882a593Smuzhiyun * table.
31*4882a593Smuzhiyun */
32*4882a593Smuzhiyun#if !defined(CONFIG_MONITOR_IS_IN_RAM)
33*4882a593Smuzhiyun
34*4882a593Smuzhiyun.text
35*4882a593Smuzhiyun
36*4882a593Smuzhiyun/*
37*4882a593Smuzhiyun * Vector table. This is used for initial platform startup.
38*4882a593Smuzhiyun * These vectors are to catch any un-intended traps.
39*4882a593Smuzhiyun */
40*4882a593Smuzhiyun_vectors:
41*4882a593Smuzhiyun/* Flash offset is 0 until we setup CS0 */
42*4882a593Smuzhiyun.long	0x00000000
43*4882a593Smuzhiyun#if defined(CONFIG_M5307) && \
44*4882a593Smuzhiyun	   (CONFIG_SYS_TEXT_BASE == CONFIG_SYS_INT_FLASH_BASE)
45*4882a593Smuzhiyun.long	_start - CONFIG_SYS_TEXT_BASE
46*4882a593Smuzhiyun#else
47*4882a593Smuzhiyun.long	_START
48*4882a593Smuzhiyun#endif
49*4882a593Smuzhiyun
50*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
51*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
52*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
53*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
54*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
55*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
56*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
57*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
58*4882a593Smuzhiyun
59*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
60*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
61*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
62*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
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
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.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
72*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
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
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.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
82*4882a593Smuzhiyun.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
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*4882a593Smuzhiyun#endif
87*4882a593Smuzhiyun
88*4882a593Smuzhiyun.text
89*4882a593Smuzhiyun
90*4882a593Smuzhiyun.globl _start
91*4882a593Smuzhiyun_start:
92*4882a593Smuzhiyun	nop
93*4882a593Smuzhiyun	nop
94*4882a593Smuzhiyun	move.w	#0x2700,%sr
95*4882a593Smuzhiyun
96*4882a593Smuzhiyun	/* set MBAR address + valid flag */
97*4882a593Smuzhiyun	move.l	#(CONFIG_SYS_MBAR + 1), %d0
98*4882a593Smuzhiyun	move.c	%d0, %MBAR
99*4882a593Smuzhiyun
100*4882a593Smuzhiyun	move.l	#(CONFIG_SYS_INIT_RAM_ADDR + 1), %d0
101*4882a593Smuzhiyun	move.c	%d0, %RAMBAR
102*4882a593Smuzhiyun
103*4882a593Smuzhiyun	/* DS 4.8.2 (Cache Organization) invalidate and disable cache */
104*4882a593Smuzhiyun        move.l	#CF_CACR_CINVA, %d0
105*4882a593Smuzhiyun        movec	%d0, %CACR
106*4882a593Smuzhiyun        move.l	#0, %d0
107*4882a593Smuzhiyun        movec	%d0, %ACR0
108*4882a593Smuzhiyun        movec	%d0, %ACR1
109*4882a593Smuzhiyun
110*4882a593Smuzhiyun	/*
111*4882a593Smuzhiyun	 * if we come from a pre-loader we have no exception table and
112*4882a593Smuzhiyun	 * therefore no VBR to set
113*4882a593Smuzhiyun	 */
114*4882a593Smuzhiyun#if !defined(CONFIG_MONITOR_IS_IN_RAM)
115*4882a593Smuzhiyun	move.l	#CONFIG_SYS_FLASH_BASE, %d0
116*4882a593Smuzhiyun	movec	%d0, %VBR
117*4882a593Smuzhiyun#endif
118*4882a593Smuzhiyun
119*4882a593Smuzhiyun	/* initialize general use internal ram */
120*4882a593Smuzhiyun	move.l	#0, %d0
121*4882a593Smuzhiyun	move.l	#(ICACHE_STATUS), %a1	/* icache */
122*4882a593Smuzhiyun	move.l	#(DCACHE_STATUS), %a2	/* dcache */
123*4882a593Smuzhiyun	move.l	%d0, (%a1)
124*4882a593Smuzhiyun	move.l	%d0, (%a2)
125*4882a593Smuzhiyun
126*4882a593Smuzhiyun	/* put relocation table address to a5 */
127*4882a593Smuzhiyun	move.l	#__got_start, %a5
128*4882a593Smuzhiyun
129*4882a593Smuzhiyun	/* setup stack initially on top of internal static ram  */
130*4882a593Smuzhiyun	move.l	#(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_SIZE), %sp
131*4882a593Smuzhiyun
132*4882a593Smuzhiyun	/*
133*4882a593Smuzhiyun	 * if configured, malloc_f arena will be reserved first,
134*4882a593Smuzhiyun	 * then (and always) gd struct space will be reserved
135*4882a593Smuzhiyun	 */
136*4882a593Smuzhiyun	move.l	%sp, -(%sp)
137*4882a593Smuzhiyun	bsr	board_init_f_alloc_reserve
138*4882a593Smuzhiyun
139*4882a593Smuzhiyun	/* update stack and frame-pointers */
140*4882a593Smuzhiyun	move.l	%d0, %sp
141*4882a593Smuzhiyun	move.l	%sp, %fp
142*4882a593Smuzhiyun
143*4882a593Smuzhiyun	/* initialize reserved area */
144*4882a593Smuzhiyun	move.l	%d0, -(%sp)
145*4882a593Smuzhiyun	bsr	board_init_f_init_reserve
146*4882a593Smuzhiyun
147*4882a593Smuzhiyun	/* run low-level CPU init code (from flash) */
148*4882a593Smuzhiyun	bsr	cpu_init_f
149*4882a593Smuzhiyun
150*4882a593Smuzhiyun	/* run low-level board init code (from flash) */
151*4882a593Smuzhiyun	clr.l	%sp@-
152*4882a593Smuzhiyun	bsr	board_init_f
153*4882a593Smuzhiyun
154*4882a593Smuzhiyun	/* board_init_f() does not return */
155*4882a593Smuzhiyun
156*4882a593Smuzhiyun/******************************************************************************/
157*4882a593Smuzhiyun
158*4882a593Smuzhiyun/*
159*4882a593Smuzhiyun * void relocate_code (addr_sp, gd, addr_moni)
160*4882a593Smuzhiyun *
161*4882a593Smuzhiyun * This "function" does not return, instead it continues in RAM
162*4882a593Smuzhiyun * after relocating the monitor code.
163*4882a593Smuzhiyun *
164*4882a593Smuzhiyun */
165*4882a593Smuzhiyun.globl relocate_code
166*4882a593Smuzhiyunrelocate_code:
167*4882a593Smuzhiyun	link.w	%a6,#0
168*4882a593Smuzhiyun	move.l	8(%a6), %sp	/* set new stack pointer */
169*4882a593Smuzhiyun	move.l	12(%a6), %d0	/* Save copy of Global Data pointer */
170*4882a593Smuzhiyun	move.l	16(%a6), %a0	/* Save copy of Destination Address */
171*4882a593Smuzhiyun
172*4882a593Smuzhiyun	move.l	#CONFIG_SYS_MONITOR_BASE, %a1
173*4882a593Smuzhiyun	move.l	#__init_end, %a2
174*4882a593Smuzhiyun	move.l	%a0, %a3
175*4882a593Smuzhiyun	/* copy the code to RAM */
176*4882a593Smuzhiyun1:
177*4882a593Smuzhiyun	move.l	(%a1)+, (%a3)+
178*4882a593Smuzhiyun	cmp.l	%a1,%a2
179*4882a593Smuzhiyun	bgt.s	1b
180*4882a593Smuzhiyun
181*4882a593Smuzhiyun/*
182*4882a593Smuzhiyun * We are done. Do not return, instead branch to second part of board
183*4882a593Smuzhiyun * initialization, now running from RAM.
184*4882a593Smuzhiyun */
185*4882a593Smuzhiyun	move.l	%a0, %a1
186*4882a593Smuzhiyun	add.l	#(in_ram - CONFIG_SYS_MONITOR_BASE), %a1
187*4882a593Smuzhiyun	jmp	(%a1)
188*4882a593Smuzhiyun
189*4882a593Smuzhiyunin_ram:
190*4882a593Smuzhiyun
191*4882a593Smuzhiyunclear_bss:
192*4882a593Smuzhiyun	/*
193*4882a593Smuzhiyun	 * Now clear BSS segment
194*4882a593Smuzhiyun	 */
195*4882a593Smuzhiyun	move.l	%a0, %a1
196*4882a593Smuzhiyun	add.l	#(_sbss - CONFIG_SYS_MONITOR_BASE), %a1
197*4882a593Smuzhiyun	move.l	%a0, %d1
198*4882a593Smuzhiyun	add.l	#(_ebss - CONFIG_SYS_MONITOR_BASE), %d1
199*4882a593Smuzhiyun6:
200*4882a593Smuzhiyun	clr.l	(%a1)+
201*4882a593Smuzhiyun	cmp.l	%a1,%d1
202*4882a593Smuzhiyun	bgt.s	6b
203*4882a593Smuzhiyun
204*4882a593Smuzhiyun	/*
205*4882a593Smuzhiyun	 * fix got table in RAM
206*4882a593Smuzhiyun	 */
207*4882a593Smuzhiyun	move.l	%a0, %a1
208*4882a593Smuzhiyun	add.l	#(__got_start - CONFIG_SYS_MONITOR_BASE), %a1
209*4882a593Smuzhiyun
210*4882a593Smuzhiyun	/* fix got pointer register a5 */
211*4882a593Smuzhiyun	move.l	%a1,%a5
212*4882a593Smuzhiyun
213*4882a593Smuzhiyun	move.l	%a0, %a2
214*4882a593Smuzhiyun	add.l	#(__got_end - CONFIG_SYS_MONITOR_BASE), %a2
215*4882a593Smuzhiyun
216*4882a593Smuzhiyun7:
217*4882a593Smuzhiyun	move.l	(%a1),%d1
218*4882a593Smuzhiyun	sub.l	#_start, %d1
219*4882a593Smuzhiyun	add.l	%a0,%d1
220*4882a593Smuzhiyun	move.l	%d1,(%a1)+
221*4882a593Smuzhiyun	cmp.l	%a2, %a1
222*4882a593Smuzhiyun	bne	7b
223*4882a593Smuzhiyun
224*4882a593Smuzhiyun	/* calculate relative jump to board_init_r in ram */
225*4882a593Smuzhiyun	move.l	%a0, %a1
226*4882a593Smuzhiyun	add.l	#(board_init_r - CONFIG_SYS_MONITOR_BASE), %a1
227*4882a593Smuzhiyun
228*4882a593Smuzhiyun	/* set parameters for board_init_r */
229*4882a593Smuzhiyun	move.l	%a0,-(%sp)	/* dest_addr */
230*4882a593Smuzhiyun	move.l	%d0,-(%sp)	/* gd */
231*4882a593Smuzhiyun#if defined(DEBUG) && (CONFIG_SYS_TEXT_BASE!=CONFIG_SYS_INT_FLASH_BASE) && \
232*4882a593Smuzhiyun    defined(CONFIG_SYS_HALT_BEFOR_RAM_JUMP)
233*4882a593Smuzhiyun	halt
234*4882a593Smuzhiyun#endif
235*4882a593Smuzhiyun	jsr	(%a1)
236*4882a593Smuzhiyun
237*4882a593Smuzhiyun/******************************************************************************/
238*4882a593Smuzhiyun
239*4882a593Smuzhiyun/* exception code */
240*4882a593Smuzhiyun.globl _fault
241*4882a593Smuzhiyun_fault:
242*4882a593Smuzhiyun	bra	_fault
243*4882a593Smuzhiyun
244*4882a593Smuzhiyun.globl _exc_handler
245*4882a593Smuzhiyun_exc_handler:
246*4882a593Smuzhiyun	SAVE_ALL
247*4882a593Smuzhiyun	movel	%sp,%sp@-
248*4882a593Smuzhiyun	bsr	exc_handler
249*4882a593Smuzhiyun	addql	#4,%sp
250*4882a593Smuzhiyun	RESTORE_ALL
251*4882a593Smuzhiyun
252*4882a593Smuzhiyun.globl _int_handler
253*4882a593Smuzhiyun_int_handler:
254*4882a593Smuzhiyun	SAVE_ALL
255*4882a593Smuzhiyun	movel	%sp,%sp@-
256*4882a593Smuzhiyun	bsr	int_handler
257*4882a593Smuzhiyun	addql	#4,%sp
258*4882a593Smuzhiyun	RESTORE_ALL
259*4882a593Smuzhiyun
260*4882a593Smuzhiyun/******************************************************************************/
261*4882a593Smuzhiyun
262*4882a593Smuzhiyun.globl version_string
263*4882a593Smuzhiyunversion_string:
264*4882a593Smuzhiyun.ascii	U_BOOT_VERSION
265*4882a593Smuzhiyun.ascii	" (", U_BOOT_DATE, " - ", U_BOOT_TIME, ")"
266*4882a593Smuzhiyun.ascii	CONFIG_IDENT_STRING, "\0"
267*4882a593Smuzhiyun.align	4
268