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 * (C) Copyright 2004-2008 Freescale Semiconductor, Inc.
7 * TsiChung Liew (Tsi-Chung.Liew@freescale.com)
8 */
9
10#include <asm-offsets.h>
11#include <config.h>
12#include <asm/cache.h>
13
14#define _START	_start
15#define _FAULT	_fault
16
17#define SAVE_ALL						\
18	move.w	#0x2700,%sr;		/* disable intrs */	\
19	subl	#60,%sp;		/* space for 15 regs */ \
20	moveml	%d0-%d7/%a0-%a6,%sp@;
21
22#define RESTORE_ALL						\
23	moveml	%sp@,%d0-%d7/%a0-%a6;				\
24	addl	#60,%sp;		/* space for 15 regs */ \
25	rte;
26
27#if !defined(CONFIG_MONITOR_IS_IN_RAM)
28
29.text
30
31/*
32 * Vector table. This is used for initial platform startup.
33 * These vectors are to catch any un-intended traps.
34 */
35_vectors:
36INITSP:	.long	0x00000000		/* Initial SP	*/
37INITPC:	.long	_START			/* Initial PC		*/
38
39vector02_0F:
40.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
41.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
42
43/* Reserved */
44vector10_17:
45.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
46
47vector18_1F:
48.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
49
50/* TRAP #0 - #15 */
51vector20_2F:
52.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
53.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
54
55/* Reserved	*/
56vector30_3F:
57.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
58.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
59
60vector64_127:
61.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
62.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
63.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
64.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
65.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
66.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
67.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
68.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
69
70vector128_191:
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.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
79
80vector192_255:
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.long	_FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT
89#endif /* !defined(CONFIG_MONITOR_IS_IN_RAM) */
90
91.text
92
93.globl _start
94_start:
95	nop
96	nop
97	move.w	#0x2700,%sr	/* Mask off Interrupt */
98
99#if !defined(CONFIG_MONITOR_IS_IN_RAM)
100	/* Set vector base register at the beginning of the Flash */
101	move.l	#CFG_SYS_FLASH_BASE, %d0
102	movec	%d0, %VBR
103#endif
104
105	move.l	#(CFG_SYS_INIT_RAM_ADDR + CFG_SYS_INIT_RAM_CTRL), %d0
106	movec	%d0, %RAMBAR1
107
108	/* invalidate and disable cache */
109	move.l	#CF_CACR_CINVA, %d0		/* Invalidate cache cmd */
110	movec	%d0, %CACR			/* Invalidate cache */
111	move.l	#0, %d0
112	movec	%d0, %ACR0
113	movec	%d0, %ACR1
114
115#ifdef CONFIG_MCF5301x
116	move.l	#(0xFC0a0010), %a0
117	move.w	(%a0), %d0
118	and.l	%d0, 0xEFFF
119
120	move.w	%d0, (%a0)
121#endif
122
123	/* initialize general use internal ram */
124	move.l	#0, %d0
125	move.l	#(ICACHE_STATUS), %a1	/* icache */
126	move.l	#(DCACHE_STATUS), %a2	/* icache */
127	move.l	%d0, (%a1)
128	move.l	%d0, (%a2)
129
130	/* put relocation table address to a5 */
131	move.l	#__got_start, %a5
132
133	/* setup stack initially on top of internal static ram  */
134	move.l  #(CFG_SYS_INIT_RAM_ADDR + CFG_SYS_INIT_RAM_SIZE), %sp
135
136	/*
137	 * if configured, malloc_f arena will be reserved first,
138	 * then (and always) gd struct space will be reserved
139	 */
140	move.l	%sp, -(%sp)
141	move.l	#board_init_f_alloc_reserve, %a1
142	jsr	(%a1)
143
144	/* update stack and frame-pointers */
145	move.l  %d0, %sp
146	move.l  %sp, %fp
147
148	/* initialize reserved area */
149	move.l	%d0, -(%sp)
150	move.l	#board_init_f_init_reserve, %a1
151	jsr	(%a1)
152
153	/* run low-level CPU init code (from flash) */
154	move.l	#cpu_init_f, %a1
155	jsr	(%a1)
156
157	/* run low-level board init code (from flash) */
158	clr.l   %sp@-
159	move.l #board_init_f, %a1
160	jsr (%a1)
161
162	/* board_init_f() does not return */
163
164/******************************************************************************/
165
166/*
167 * void relocate_code(addr_sp, gd, addr_moni)
168 *
169 * This "function" does not return, instead it continues in RAM
170 * after relocating the monitor code.
171 *
172 * r3 = dest
173 * r4 = src
174 * r5 = length in bytes
175 * r6 = cachelinesize
176 */
177.globl relocate_code
178relocate_code:
179	link.w	%a6,#0
180	move.l	8(%a6), %sp		/* set new stack pointer */
181
182	move.l	12(%a6), %d0		/* Save copy of Global Data pointer */
183	move.l	16(%a6), %a0		/* Save copy of Destination Address */
184
185	move.l	#CONFIG_SYS_MONITOR_BASE, %a1
186	move.l	#__init_end, %a2
187	move.l	%a0, %a3
188
189	/* copy the code to RAM */
1901:
191	move.l	(%a1)+, (%a3)+
192	cmp.l	%a1,%a2
193	bgt.s	1b
194
195#define R_68K_32	1
196#define R_68K_RELATIVE	22
197
198	move.l #(__rel_dyn_start), %a1
199	move.l #(__rel_dyn_end), %a2
200
201fixloop:
202	move.l	(%a1)+, %d1	/* Elf32_Rela r_offset */
203	move.l	(%a1)+, %d2	/* Elf32_Rela r_info */
204	move.l	(%a1)+, %d3	/* Elf32_Rela r_addend */
205
206	andi.l	#0xff, %d2
207	cmp.l	#R_68K_32, %d2
208	beq.s	fixup
209	cmp.l	#R_68K_RELATIVE, %d2
210	beq.s	fixup
211
212	bra	fixnext
213
214fixup:
215	/* relative fix: store addend plus offset at dest location */
216	move.l	%a0, %a3
217	add.l	%d1, %a3
218	sub.l   #CONFIG_SYS_MONITOR_BASE, %a3
219	move.l	(%a3), %d4
220	add.l	%a0, %d4
221	sub.l   #CONFIG_SYS_MONITOR_BASE, %d4
222	move.l	%d4, (%a3)
223
224fixnext:
225	cmp.l	%a1, %a2
226	bge.s	fixloop
227
228/*
229 * We are done. Do not return, instead branch to second part of board
230 * initialization, now running from RAM.
231 */
232	move.l	%a0, %a1
233	add.l	#(in_ram - CONFIG_SYS_MONITOR_BASE), %a1
234	jmp	(%a1)
235
236in_ram:
237
238clear_bss:
239	/*
240	 * Now clear BSS segment
241	 */
242	move.l	#(_sbss), %a1
243	move.l	#(_ebss), %d1
2446:
245	clr.l	(%a1)+
246	cmp.l	%a1,%d1
247	bgt.s	6b
248
249	/*
250	 * fix got table in RAM
251	 */
252	move.l	#(__got_start), %a5	/* fix got pointer register a5 */
253
254	/* calculate relative jump to board_init_r in ram */
255	move.l	#(board_init_r), %a1
256
257	/* set parameters for board_init_r */
258	move.l	%a0,-(%sp)		/* dest_addr */
259	move.l	%d0,-(%sp)		/* gd */
260	jsr	(%a1)
261
262/******************************************************************************/
263
264/* exception code */
265.globl _fault
266_fault:
267	bra _fault
268
269.globl _exc_handler
270_exc_handler:
271	SAVE_ALL
272	movel	%sp,%sp@-
273	bsr	exc_handler
274	addql	#4,%sp
275	RESTORE_ALL
276
277.globl _int_handler
278_int_handler:
279	SAVE_ALL
280	movel	%sp,%sp@-
281	bsr	int_handler
282	addql	#4,%sp
283	RESTORE_ALL
284
285/******************************************************************************/
286
287.align 4
288