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