xref: /rk3399_rockchip-uboot/arch/powerpc/cpu/mpc8xx/start.S (revision ba2c5a5c9d478c58277c4b0bb1187a6e82912410)
1*907208c4SChristophe Leroy/*
2*907208c4SChristophe Leroy *  Copyright (C) 1998	Dan Malek <dmalek@jlc.net>
3*907208c4SChristophe Leroy *  Copyright (C) 1999	Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se>
4*907208c4SChristophe Leroy *  Copyright (C) 2000,2001,2002 Wolfgang Denk <wd@denx.de>
5*907208c4SChristophe Leroy *
6*907208c4SChristophe Leroy * SPDX-License-Identifier:	GPL-2.0+
7*907208c4SChristophe Leroy */
8*907208c4SChristophe Leroy
9*907208c4SChristophe Leroy/*  U-Boot - Startup Code for PowerPC based Embedded Boards
10*907208c4SChristophe Leroy *
11*907208c4SChristophe Leroy *
12*907208c4SChristophe Leroy *  The processor starts at 0x00000100 and the code is executed
13*907208c4SChristophe Leroy *  from flash. The code is organized to be at an other address
14*907208c4SChristophe Leroy *  in memory, but as long we don't jump around before relocating,
15*907208c4SChristophe Leroy *  board_init lies at a quite high address and when the cpu has
16*907208c4SChristophe Leroy *  jumped there, everything is ok.
17*907208c4SChristophe Leroy *  This works because the cpu gives the FLASH (CS0) the whole
18*907208c4SChristophe Leroy *  address space at startup, and board_init lies as a echo of
19*907208c4SChristophe Leroy *  the flash somewhere up there in the memory map.
20*907208c4SChristophe Leroy *
21*907208c4SChristophe Leroy *  board_init will change CS0 to be positioned at the correct
22*907208c4SChristophe Leroy *  address and (s)dram will be positioned at address 0
23*907208c4SChristophe Leroy */
24*907208c4SChristophe Leroy#include <asm-offsets.h>
25*907208c4SChristophe Leroy#include <config.h>
26*907208c4SChristophe Leroy#include <mpc8xx.h>
27*907208c4SChristophe Leroy#include <version.h>
28*907208c4SChristophe Leroy
29*907208c4SChristophe Leroy#include <ppc_asm.tmpl>
30*907208c4SChristophe Leroy#include <ppc_defs.h>
31*907208c4SChristophe Leroy
32*907208c4SChristophe Leroy#include <asm/cache.h>
33*907208c4SChristophe Leroy#include <asm/mmu.h>
34*907208c4SChristophe Leroy#include <asm/u-boot.h>
35*907208c4SChristophe Leroy
36*907208c4SChristophe Leroy/* We don't want the  MMU yet.
37*907208c4SChristophe Leroy*/
38*907208c4SChristophe Leroy#undef	MSR_KERNEL
39*907208c4SChristophe Leroy#define MSR_KERNEL ( MSR_ME | MSR_RI )	/* Machine Check and Recoverable Interr. */
40*907208c4SChristophe Leroy
41*907208c4SChristophe Leroy/*
42*907208c4SChristophe Leroy * Set up GOT: Global Offset Table
43*907208c4SChristophe Leroy *
44*907208c4SChristophe Leroy * Use r12 to access the GOT
45*907208c4SChristophe Leroy */
46*907208c4SChristophe Leroy	START_GOT
47*907208c4SChristophe Leroy	GOT_ENTRY(_GOT2_TABLE_)
48*907208c4SChristophe Leroy	GOT_ENTRY(_FIXUP_TABLE_)
49*907208c4SChristophe Leroy
50*907208c4SChristophe Leroy	GOT_ENTRY(_start)
51*907208c4SChristophe Leroy	GOT_ENTRY(_start_of_vectors)
52*907208c4SChristophe Leroy	GOT_ENTRY(_end_of_vectors)
53*907208c4SChristophe Leroy	GOT_ENTRY(transfer_to_handler)
54*907208c4SChristophe Leroy
55*907208c4SChristophe Leroy	GOT_ENTRY(__init_end)
56*907208c4SChristophe Leroy	GOT_ENTRY(__bss_end)
57*907208c4SChristophe Leroy	GOT_ENTRY(__bss_start)
58*907208c4SChristophe Leroy	END_GOT
59*907208c4SChristophe Leroy
60*907208c4SChristophe Leroy/*
61*907208c4SChristophe Leroy * r3 - 1st arg to board_init(): IMMP pointer
62*907208c4SChristophe Leroy * r4 - 2nd arg to board_init(): boot flag
63*907208c4SChristophe Leroy */
64*907208c4SChristophe Leroy	.text
65*907208c4SChristophe Leroy	.long	0x27051956		/* U-Boot Magic Number			*/
66*907208c4SChristophe Leroy	.globl	version_string
67*907208c4SChristophe Leroyversion_string:
68*907208c4SChristophe Leroy	.ascii U_BOOT_VERSION_STRING, "\0"
69*907208c4SChristophe Leroy
70*907208c4SChristophe Leroy	. = EXC_OFF_SYS_RESET
71*907208c4SChristophe Leroy	.globl	_start
72*907208c4SChristophe Leroy_start:
73*907208c4SChristophe Leroy	lis	r3, CONFIG_SYS_IMMR@h		/* position IMMR */
74*907208c4SChristophe Leroy	mtspr	638, r3
75*907208c4SChristophe Leroy
76*907208c4SChristophe Leroy	/* Initialize machine status; enable machine check interrupt		*/
77*907208c4SChristophe Leroy	/*----------------------------------------------------------------------*/
78*907208c4SChristophe Leroy	li	r3, MSR_KERNEL		/* Set ME, RI flags */
79*907208c4SChristophe Leroy	mtmsr	r3
80*907208c4SChristophe Leroy	mtspr	SRR1, r3		/* Make SRR1 match MSR */
81*907208c4SChristophe Leroy
82*907208c4SChristophe Leroy	mfspr	r3, ICR			/* clear Interrupt Cause Register */
83*907208c4SChristophe Leroy
84*907208c4SChristophe Leroy	/* Initialize debug port registers					*/
85*907208c4SChristophe Leroy	/*----------------------------------------------------------------------*/
86*907208c4SChristophe Leroy	xor	r0, r0, r0		/* Clear R0 */
87*907208c4SChristophe Leroy	mtspr	LCTRL1, r0		/* Initialize debug port regs */
88*907208c4SChristophe Leroy	mtspr	LCTRL2, r0
89*907208c4SChristophe Leroy	mtspr	COUNTA, r0
90*907208c4SChristophe Leroy	mtspr	COUNTB, r0
91*907208c4SChristophe Leroy
92*907208c4SChristophe Leroy	/* Reset the caches							*/
93*907208c4SChristophe Leroy	/*----------------------------------------------------------------------*/
94*907208c4SChristophe Leroy
95*907208c4SChristophe Leroy	mfspr	r3, IC_CST		/* Clear error bits */
96*907208c4SChristophe Leroy	mfspr	r3, DC_CST
97*907208c4SChristophe Leroy
98*907208c4SChristophe Leroy	lis	r3, IDC_UNALL@h		/* Unlock all */
99*907208c4SChristophe Leroy	mtspr	IC_CST, r3
100*907208c4SChristophe Leroy	mtspr	DC_CST, r3
101*907208c4SChristophe Leroy
102*907208c4SChristophe Leroy	lis	r3, IDC_INVALL@h	/* Invalidate all */
103*907208c4SChristophe Leroy	mtspr	IC_CST, r3
104*907208c4SChristophe Leroy	mtspr	DC_CST, r3
105*907208c4SChristophe Leroy
106*907208c4SChristophe Leroy	lis	r3, IDC_DISABLE@h	/* Disable data cache */
107*907208c4SChristophe Leroy	mtspr	DC_CST, r3
108*907208c4SChristophe Leroy
109*907208c4SChristophe Leroy	lis	r3, IDC_ENABLE@h	/* Enable instruction cache */
110*907208c4SChristophe Leroy	mtspr	IC_CST, r3
111*907208c4SChristophe Leroy
112*907208c4SChristophe Leroy	/* invalidate all tlb's							*/
113*907208c4SChristophe Leroy	/*----------------------------------------------------------------------*/
114*907208c4SChristophe Leroy
115*907208c4SChristophe Leroy	tlbia
116*907208c4SChristophe Leroy	isync
117*907208c4SChristophe Leroy
118*907208c4SChristophe Leroy	/*
119*907208c4SChristophe Leroy	 * Calculate absolute address in FLASH and jump there
120*907208c4SChristophe Leroy	 *----------------------------------------------------------------------*/
121*907208c4SChristophe Leroy
122*907208c4SChristophe Leroy	lis	r3, CONFIG_SYS_MONITOR_BASE@h
123*907208c4SChristophe Leroy	ori	r3, r3, CONFIG_SYS_MONITOR_BASE@l
124*907208c4SChristophe Leroy	addi	r3, r3, in_flash - _start + EXC_OFF_SYS_RESET
125*907208c4SChristophe Leroy	mtlr	r3
126*907208c4SChristophe Leroy	blr
127*907208c4SChristophe Leroy
128*907208c4SChristophe Leroyin_flash:
129*907208c4SChristophe Leroy
130*907208c4SChristophe Leroy	/* initialize some SPRs that are hard to access from C			*/
131*907208c4SChristophe Leroy	/*----------------------------------------------------------------------*/
132*907208c4SChristophe Leroy
133*907208c4SChristophe Leroy	lis	r3, CONFIG_SYS_IMMR@h		/* pass IMMR as arg1 to C routine */
134*907208c4SChristophe Leroy	ori	r1, r3, CONFIG_SYS_INIT_SP_OFFSET /* set up the stack in internal DPRAM */
135*907208c4SChristophe Leroy	/* Note: R0 is still 0 here */
136*907208c4SChristophe Leroy	stwu	r0, -4(r1)		/* clear final stack frame so that	*/
137*907208c4SChristophe Leroy	stwu	r0, -4(r1)		/* stack backtraces terminate cleanly	*/
138*907208c4SChristophe Leroy
139*907208c4SChristophe Leroy	/*
140*907208c4SChristophe Leroy	 * Disable serialized ifetch and show cycles
141*907208c4SChristophe Leroy	 * (i.e. set processor to normal mode).
142*907208c4SChristophe Leroy	 * This is also a silicon bug workaround, see errata
143*907208c4SChristophe Leroy	 */
144*907208c4SChristophe Leroy
145*907208c4SChristophe Leroy	li	r2, 0x0007
146*907208c4SChristophe Leroy	mtspr	ICTRL, r2
147*907208c4SChristophe Leroy
148*907208c4SChristophe Leroy	/* Set up debug mode entry */
149*907208c4SChristophe Leroy
150*907208c4SChristophe Leroy	lis	r2, CONFIG_SYS_DER@h
151*907208c4SChristophe Leroy	ori	r2, r2, CONFIG_SYS_DER@l
152*907208c4SChristophe Leroy	mtspr	DER, r2
153*907208c4SChristophe Leroy
154*907208c4SChristophe Leroy	/* let the C-code set up the rest					*/
155*907208c4SChristophe Leroy	/*									*/
156*907208c4SChristophe Leroy	/* Be careful to keep code relocatable !				*/
157*907208c4SChristophe Leroy	/*----------------------------------------------------------------------*/
158*907208c4SChristophe Leroy
159*907208c4SChristophe Leroy	GET_GOT			/* initialize GOT access			*/
160*907208c4SChristophe Leroy
161*907208c4SChristophe Leroy	/* r3: IMMR */
162*907208c4SChristophe Leroy	bl	cpu_init_f	/* run low-level CPU init code     (from Flash)	*/
163*907208c4SChristophe Leroy
164*907208c4SChristophe Leroy	bl	board_init_f	/* run 1st part of board init code (from Flash) */
165*907208c4SChristophe Leroy
166*907208c4SChristophe Leroy	/* NOTREACHED - board_init_f() does not return */
167*907208c4SChristophe Leroy
168*907208c4SChristophe Leroy
169*907208c4SChristophe Leroy	.globl	_start_of_vectors
170*907208c4SChristophe Leroy_start_of_vectors:
171*907208c4SChristophe Leroy
172*907208c4SChristophe Leroy/* Machine check */
173*907208c4SChristophe Leroy	STD_EXCEPTION(0x200, MachineCheck, MachineCheckException)
174*907208c4SChristophe Leroy
175*907208c4SChristophe Leroy/* Data Storage exception.  "Never" generated on the 860. */
176*907208c4SChristophe Leroy	STD_EXCEPTION(0x300, DataStorage, UnknownException)
177*907208c4SChristophe Leroy
178*907208c4SChristophe Leroy/* Instruction Storage exception.  "Never" generated on the 860. */
179*907208c4SChristophe Leroy	STD_EXCEPTION(0x400, InstStorage, UnknownException)
180*907208c4SChristophe Leroy
181*907208c4SChristophe Leroy/* External Interrupt exception. */
182*907208c4SChristophe Leroy	STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt)
183*907208c4SChristophe Leroy
184*907208c4SChristophe Leroy/* Alignment exception. */
185*907208c4SChristophe Leroy	. = 0x600
186*907208c4SChristophe LeroyAlignment:
187*907208c4SChristophe Leroy	EXCEPTION_PROLOG(SRR0, SRR1)
188*907208c4SChristophe Leroy	mfspr	r4,DAR
189*907208c4SChristophe Leroy	stw	r4,_DAR(r21)
190*907208c4SChristophe Leroy	mfspr	r5,DSISR
191*907208c4SChristophe Leroy	stw	r5,_DSISR(r21)
192*907208c4SChristophe Leroy	addi	r3,r1,STACK_FRAME_OVERHEAD
193*907208c4SChristophe Leroy	EXC_XFER_TEMPLATE(Alignment, AlignmentException, MSR_KERNEL, COPY_EE)
194*907208c4SChristophe Leroy
195*907208c4SChristophe Leroy/* Program check exception */
196*907208c4SChristophe Leroy	. = 0x700
197*907208c4SChristophe LeroyProgramCheck:
198*907208c4SChristophe Leroy	EXCEPTION_PROLOG(SRR0, SRR1)
199*907208c4SChristophe Leroy	addi	r3,r1,STACK_FRAME_OVERHEAD
200*907208c4SChristophe Leroy	EXC_XFER_TEMPLATE(ProgramCheck, ProgramCheckException,
201*907208c4SChristophe Leroy		MSR_KERNEL, COPY_EE)
202*907208c4SChristophe Leroy
203*907208c4SChristophe Leroy	/* No FPU on MPC8xx.  This exception is not supposed to happen.
204*907208c4SChristophe Leroy	*/
205*907208c4SChristophe Leroy	STD_EXCEPTION(0x800, FPUnavailable, UnknownException)
206*907208c4SChristophe Leroy
207*907208c4SChristophe Leroy	/* I guess we could implement decrementer, and may have
208*907208c4SChristophe Leroy	 * to someday for timekeeping.
209*907208c4SChristophe Leroy	 */
210*907208c4SChristophe Leroy	STD_EXCEPTION(0x900, Decrementer, timer_interrupt)
211*907208c4SChristophe Leroy	STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
212*907208c4SChristophe Leroy	STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
213*907208c4SChristophe Leroy	STD_EXCEPTION(0xc00, SystemCall, UnknownException)
214*907208c4SChristophe Leroy	STD_EXCEPTION(0xd00, SingleStep, UnknownException)
215*907208c4SChristophe Leroy
216*907208c4SChristophe Leroy	STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
217*907208c4SChristophe Leroy	STD_EXCEPTION(0xf00, Trap_0f, UnknownException)
218*907208c4SChristophe Leroy
219*907208c4SChristophe Leroy	/* On the MPC8xx, this is a software emulation interrupt.  It occurs
220*907208c4SChristophe Leroy	 * for all unimplemented and illegal instructions.
221*907208c4SChristophe Leroy	 */
222*907208c4SChristophe Leroy	STD_EXCEPTION(0x1000, SoftEmu, SoftEmuException)
223*907208c4SChristophe Leroy
224*907208c4SChristophe Leroy	STD_EXCEPTION(0x1100, InstructionTLBMiss, UnknownException)
225*907208c4SChristophe Leroy	STD_EXCEPTION(0x1200, DataTLBMiss, UnknownException)
226*907208c4SChristophe Leroy	STD_EXCEPTION(0x1300, InstructionTLBError, UnknownException)
227*907208c4SChristophe Leroy	STD_EXCEPTION(0x1400, DataTLBError, UnknownException)
228*907208c4SChristophe Leroy
229*907208c4SChristophe Leroy	STD_EXCEPTION(0x1500, Reserved5, UnknownException)
230*907208c4SChristophe Leroy	STD_EXCEPTION(0x1600, Reserved6, UnknownException)
231*907208c4SChristophe Leroy	STD_EXCEPTION(0x1700, Reserved7, UnknownException)
232*907208c4SChristophe Leroy	STD_EXCEPTION(0x1800, Reserved8, UnknownException)
233*907208c4SChristophe Leroy	STD_EXCEPTION(0x1900, Reserved9, UnknownException)
234*907208c4SChristophe Leroy	STD_EXCEPTION(0x1a00, ReservedA, UnknownException)
235*907208c4SChristophe Leroy	STD_EXCEPTION(0x1b00, ReservedB, UnknownException)
236*907208c4SChristophe Leroy
237*907208c4SChristophe Leroy	STD_EXCEPTION(0x1c00, DataBreakpoint, UnknownException)
238*907208c4SChristophe Leroy	STD_EXCEPTION(0x1d00, InstructionBreakpoint, DebugException)
239*907208c4SChristophe Leroy	STD_EXCEPTION(0x1e00, PeripheralBreakpoint, UnknownException)
240*907208c4SChristophe Leroy	STD_EXCEPTION(0x1f00, DevPortBreakpoint, UnknownException)
241*907208c4SChristophe Leroy
242*907208c4SChristophe Leroy
243*907208c4SChristophe Leroy	.globl	_end_of_vectors
244*907208c4SChristophe Leroy_end_of_vectors:
245*907208c4SChristophe Leroy
246*907208c4SChristophe Leroy
247*907208c4SChristophe Leroy	. = 0x2000
248*907208c4SChristophe Leroy
249*907208c4SChristophe Leroy/*
250*907208c4SChristophe Leroy * This code finishes saving the registers to the exception frame
251*907208c4SChristophe Leroy * and jumps to the appropriate handler for the exception.
252*907208c4SChristophe Leroy * Register r21 is pointer into trap frame, r1 has new stack pointer.
253*907208c4SChristophe Leroy */
254*907208c4SChristophe Leroy	.globl	transfer_to_handler
255*907208c4SChristophe Leroytransfer_to_handler:
256*907208c4SChristophe Leroy	stw	r22,_NIP(r21)
257*907208c4SChristophe Leroy	lis	r22,MSR_POW@h
258*907208c4SChristophe Leroy	andc	r23,r23,r22
259*907208c4SChristophe Leroy	stw	r23,_MSR(r21)
260*907208c4SChristophe Leroy	SAVE_GPR(7, r21)
261*907208c4SChristophe Leroy	SAVE_4GPRS(8, r21)
262*907208c4SChristophe Leroy	SAVE_8GPRS(12, r21)
263*907208c4SChristophe Leroy	SAVE_8GPRS(24, r21)
264*907208c4SChristophe Leroy	mflr	r23
265*907208c4SChristophe Leroy	andi.	r24,r23,0x3f00		/* get vector offset */
266*907208c4SChristophe Leroy	stw	r24,TRAP(r21)
267*907208c4SChristophe Leroy	li	r22,0
268*907208c4SChristophe Leroy	stw	r22,RESULT(r21)
269*907208c4SChristophe Leroy	mtspr	SPRG2,r22		/* r1 is now kernel sp */
270*907208c4SChristophe Leroy	lwz	r24,0(r23)		/* virtual address of handler */
271*907208c4SChristophe Leroy	lwz	r23,4(r23)		/* where to go when done */
272*907208c4SChristophe Leroy	mtspr	SRR0,r24
273*907208c4SChristophe Leroy	mtspr	SRR1,r20
274*907208c4SChristophe Leroy	mtlr	r23
275*907208c4SChristophe Leroy	SYNC
276*907208c4SChristophe Leroy	rfi				/* jump to handler, enable MMU */
277*907208c4SChristophe Leroy
278*907208c4SChristophe Leroyint_return:
279*907208c4SChristophe Leroy	mfmsr	r28			/* Disable interrupts */
280*907208c4SChristophe Leroy	li	r4,0
281*907208c4SChristophe Leroy	ori	r4,r4,MSR_EE
282*907208c4SChristophe Leroy	andc	r28,r28,r4
283*907208c4SChristophe Leroy	SYNC				/* Some chip revs need this... */
284*907208c4SChristophe Leroy	mtmsr	r28
285*907208c4SChristophe Leroy	SYNC
286*907208c4SChristophe Leroy	lwz	r2,_CTR(r1)
287*907208c4SChristophe Leroy	lwz	r0,_LINK(r1)
288*907208c4SChristophe Leroy	mtctr	r2
289*907208c4SChristophe Leroy	mtlr	r0
290*907208c4SChristophe Leroy	lwz	r2,_XER(r1)
291*907208c4SChristophe Leroy	lwz	r0,_CCR(r1)
292*907208c4SChristophe Leroy	mtspr	XER,r2
293*907208c4SChristophe Leroy	mtcrf	0xFF,r0
294*907208c4SChristophe Leroy	REST_10GPRS(3, r1)
295*907208c4SChristophe Leroy	REST_10GPRS(13, r1)
296*907208c4SChristophe Leroy	REST_8GPRS(23, r1)
297*907208c4SChristophe Leroy	REST_GPR(31, r1)
298*907208c4SChristophe Leroy	lwz	r2,_NIP(r1)		/* Restore environment */
299*907208c4SChristophe Leroy	lwz	r0,_MSR(r1)
300*907208c4SChristophe Leroy	mtspr	SRR0,r2
301*907208c4SChristophe Leroy	mtspr	SRR1,r0
302*907208c4SChristophe Leroy	lwz	r0,GPR0(r1)
303*907208c4SChristophe Leroy	lwz	r2,GPR2(r1)
304*907208c4SChristophe Leroy	lwz	r1,GPR1(r1)
305*907208c4SChristophe Leroy	SYNC
306*907208c4SChristophe Leroy	rfi
307*907208c4SChristophe Leroy
308*907208c4SChristophe Leroy/*------------------------------------------------------------------------------*/
309*907208c4SChristophe Leroy
310*907208c4SChristophe Leroy/*
311*907208c4SChristophe Leroy * void relocate_code (addr_sp, gd, addr_moni)
312*907208c4SChristophe Leroy *
313*907208c4SChristophe Leroy * This "function" does not return, instead it continues in RAM
314*907208c4SChristophe Leroy * after relocating the monitor code.
315*907208c4SChristophe Leroy *
316*907208c4SChristophe Leroy * r3 = dest
317*907208c4SChristophe Leroy * r4 = src
318*907208c4SChristophe Leroy * r5 = length in bytes
319*907208c4SChristophe Leroy * r6 = cachelinesize
320*907208c4SChristophe Leroy */
321*907208c4SChristophe Leroy	.globl	relocate_code
322*907208c4SChristophe Leroyrelocate_code:
323*907208c4SChristophe Leroy	mr	r1,  r3		/* Set new stack pointer		*/
324*907208c4SChristophe Leroy	mr	r9,  r4		/* Save copy of Global Data pointer	*/
325*907208c4SChristophe Leroy	mr	r10, r5		/* Save copy of Destination Address	*/
326*907208c4SChristophe Leroy
327*907208c4SChristophe Leroy	GET_GOT
328*907208c4SChristophe Leroy	mr	r3,  r5				/* Destination Address	*/
329*907208c4SChristophe Leroy	lis	r4, CONFIG_SYS_MONITOR_BASE@h		/* Source      Address	*/
330*907208c4SChristophe Leroy	ori	r4, r4, CONFIG_SYS_MONITOR_BASE@l
331*907208c4SChristophe Leroy	lwz	r5, GOT(__init_end)
332*907208c4SChristophe Leroy	sub	r5, r5, r4
333*907208c4SChristophe Leroy	li	r6, CONFIG_SYS_CACHELINE_SIZE		/* Cache Line Size	*/
334*907208c4SChristophe Leroy
335*907208c4SChristophe Leroy	/*
336*907208c4SChristophe Leroy	 * Fix GOT pointer:
337*907208c4SChristophe Leroy	 *
338*907208c4SChristophe Leroy	 * New GOT-PTR = (old GOT-PTR - CONFIG_SYS_MONITOR_BASE) + Destination Address
339*907208c4SChristophe Leroy	 *
340*907208c4SChristophe Leroy	 * Offset:
341*907208c4SChristophe Leroy	 */
342*907208c4SChristophe Leroy	sub	r15, r10, r4
343*907208c4SChristophe Leroy
344*907208c4SChristophe Leroy	/* First our own GOT */
345*907208c4SChristophe Leroy	add	r12, r12, r15
346*907208c4SChristophe Leroy	/* then the one used by the C code */
347*907208c4SChristophe Leroy	add	r30, r30, r15
348*907208c4SChristophe Leroy
349*907208c4SChristophe Leroy	/*
350*907208c4SChristophe Leroy	 * Now relocate code
351*907208c4SChristophe Leroy	 */
352*907208c4SChristophe Leroy
353*907208c4SChristophe Leroy	cmplw	cr1,r3,r4
354*907208c4SChristophe Leroy	addi	r0,r5,3
355*907208c4SChristophe Leroy	srwi.	r0,r0,2
356*907208c4SChristophe Leroy	beq	cr1,4f		/* In place copy is not necessary	*/
357*907208c4SChristophe Leroy	beq	7f		/* Protect against 0 count		*/
358*907208c4SChristophe Leroy	mtctr	r0
359*907208c4SChristophe Leroy	bge	cr1,2f
360*907208c4SChristophe Leroy
361*907208c4SChristophe Leroy	la	r8,-4(r4)
362*907208c4SChristophe Leroy	la	r7,-4(r3)
363*907208c4SChristophe Leroy1:	lwzu	r0,4(r8)
364*907208c4SChristophe Leroy	stwu	r0,4(r7)
365*907208c4SChristophe Leroy	bdnz	1b
366*907208c4SChristophe Leroy	b	4f
367*907208c4SChristophe Leroy
368*907208c4SChristophe Leroy2:	slwi	r0,r0,2
369*907208c4SChristophe Leroy	add	r8,r4,r0
370*907208c4SChristophe Leroy	add	r7,r3,r0
371*907208c4SChristophe Leroy3:	lwzu	r0,-4(r8)
372*907208c4SChristophe Leroy	stwu	r0,-4(r7)
373*907208c4SChristophe Leroy	bdnz	3b
374*907208c4SChristophe Leroy
375*907208c4SChristophe Leroy/*
376*907208c4SChristophe Leroy * Now flush the cache: note that we must start from a cache aligned
377*907208c4SChristophe Leroy * address. Otherwise we might miss one cache line.
378*907208c4SChristophe Leroy */
379*907208c4SChristophe Leroy4:	cmpwi	r6,0
380*907208c4SChristophe Leroy	add	r5,r3,r5
381*907208c4SChristophe Leroy	beq	7f		/* Always flush prefetch queue in any case */
382*907208c4SChristophe Leroy	subi	r0,r6,1
383*907208c4SChristophe Leroy	andc	r3,r3,r0
384*907208c4SChristophe Leroy	mr	r4,r3
385*907208c4SChristophe Leroy5:	dcbst	0,r4
386*907208c4SChristophe Leroy	add	r4,r4,r6
387*907208c4SChristophe Leroy	cmplw	r4,r5
388*907208c4SChristophe Leroy	blt	5b
389*907208c4SChristophe Leroy	sync			/* Wait for all dcbst to complete on bus */
390*907208c4SChristophe Leroy	mr	r4,r3
391*907208c4SChristophe Leroy6:	icbi	0,r4
392*907208c4SChristophe Leroy	add	r4,r4,r6
393*907208c4SChristophe Leroy	cmplw	r4,r5
394*907208c4SChristophe Leroy	blt	6b
395*907208c4SChristophe Leroy7:	sync			/* Wait for all icbi to complete on bus	*/
396*907208c4SChristophe Leroy	isync
397*907208c4SChristophe Leroy
398*907208c4SChristophe Leroy/*
399*907208c4SChristophe Leroy * We are done. Do not return, instead branch to second part of board
400*907208c4SChristophe Leroy * initialization, now running from RAM.
401*907208c4SChristophe Leroy */
402*907208c4SChristophe Leroy
403*907208c4SChristophe Leroy	addi	r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
404*907208c4SChristophe Leroy	mtlr	r0
405*907208c4SChristophe Leroy	blr
406*907208c4SChristophe Leroy
407*907208c4SChristophe Leroyin_ram:
408*907208c4SChristophe Leroy
409*907208c4SChristophe Leroy	/*
410*907208c4SChristophe Leroy	 * Relocation Function, r12 point to got2+0x8000
411*907208c4SChristophe Leroy	 *
412*907208c4SChristophe Leroy	 * Adjust got2 pointers, no need to check for 0, this code
413*907208c4SChristophe Leroy	 * already puts a few entries in the table.
414*907208c4SChristophe Leroy	 */
415*907208c4SChristophe Leroy	li	r0,__got2_entries@sectoff@l
416*907208c4SChristophe Leroy	la	r3,GOT(_GOT2_TABLE_)
417*907208c4SChristophe Leroy	lwz	r11,GOT(_GOT2_TABLE_)
418*907208c4SChristophe Leroy	mtctr	r0
419*907208c4SChristophe Leroy	sub	r11,r3,r11
420*907208c4SChristophe Leroy	addi	r3,r3,-4
421*907208c4SChristophe Leroy1:	lwzu	r0,4(r3)
422*907208c4SChristophe Leroy	cmpwi	r0,0
423*907208c4SChristophe Leroy	beq-	2f
424*907208c4SChristophe Leroy	add	r0,r0,r11
425*907208c4SChristophe Leroy	stw	r0,0(r3)
426*907208c4SChristophe Leroy2:	bdnz	1b
427*907208c4SChristophe Leroy
428*907208c4SChristophe Leroy	/*
429*907208c4SChristophe Leroy	 * Now adjust the fixups and the pointers to the fixups
430*907208c4SChristophe Leroy	 * in case we need to move ourselves again.
431*907208c4SChristophe Leroy	 */
432*907208c4SChristophe Leroy	li	r0,__fixup_entries@sectoff@l
433*907208c4SChristophe Leroy	lwz	r3,GOT(_FIXUP_TABLE_)
434*907208c4SChristophe Leroy	cmpwi	r0,0
435*907208c4SChristophe Leroy	mtctr	r0
436*907208c4SChristophe Leroy	addi	r3,r3,-4
437*907208c4SChristophe Leroy	beq	4f
438*907208c4SChristophe Leroy3:	lwzu	r4,4(r3)
439*907208c4SChristophe Leroy	lwzux	r0,r4,r11
440*907208c4SChristophe Leroy	cmpwi	r0,0
441*907208c4SChristophe Leroy	add	r0,r0,r11
442*907208c4SChristophe Leroy	stw	r4,0(r3)
443*907208c4SChristophe Leroy	beq-	5f
444*907208c4SChristophe Leroy	stw	r0,0(r4)
445*907208c4SChristophe Leroy5:	bdnz	3b
446*907208c4SChristophe Leroy4:
447*907208c4SChristophe Leroyclear_bss:
448*907208c4SChristophe Leroy	/*
449*907208c4SChristophe Leroy	 * Now clear BSS segment
450*907208c4SChristophe Leroy	 */
451*907208c4SChristophe Leroy	lwz	r3,GOT(__bss_start)
452*907208c4SChristophe Leroy	lwz	r4,GOT(__bss_end)
453*907208c4SChristophe Leroy
454*907208c4SChristophe Leroy	cmplw	0, r3, r4
455*907208c4SChristophe Leroy	beq	6f
456*907208c4SChristophe Leroy
457*907208c4SChristophe Leroy	li	r0, 0
458*907208c4SChristophe Leroy5:
459*907208c4SChristophe Leroy	stw	r0, 0(r3)
460*907208c4SChristophe Leroy	addi	r3, r3, 4
461*907208c4SChristophe Leroy	cmplw	0, r3, r4
462*907208c4SChristophe Leroy	bne	5b
463*907208c4SChristophe Leroy6:
464*907208c4SChristophe Leroy
465*907208c4SChristophe Leroy	mr	r3, r9		/* Global Data pointer		*/
466*907208c4SChristophe Leroy	mr	r4, r10		/* Destination Address		*/
467*907208c4SChristophe Leroy	bl	board_init_r
468*907208c4SChristophe Leroy
469*907208c4SChristophe Leroy	/*
470*907208c4SChristophe Leroy	 * Copy exception vector code to low memory
471*907208c4SChristophe Leroy	 *
472*907208c4SChristophe Leroy	 * r3: dest_addr
473*907208c4SChristophe Leroy	 * r7: source address, r8: end address, r9: target address
474*907208c4SChristophe Leroy	 */
475*907208c4SChristophe Leroy	.globl	trap_init
476*907208c4SChristophe Leroytrap_init:
477*907208c4SChristophe Leroy	mflr	r4			/* save link register		*/
478*907208c4SChristophe Leroy	GET_GOT
479*907208c4SChristophe Leroy	lwz	r7, GOT(_start)
480*907208c4SChristophe Leroy	lwz	r8, GOT(_end_of_vectors)
481*907208c4SChristophe Leroy
482*907208c4SChristophe Leroy	li	r9, 0x100		/* reset vector always at 0x100 */
483*907208c4SChristophe Leroy
484*907208c4SChristophe Leroy	cmplw	0, r7, r8
485*907208c4SChristophe Leroy	bgelr				/* return if r7>=r8 - just in case */
486*907208c4SChristophe Leroy1:
487*907208c4SChristophe Leroy	lwz	r0, 0(r7)
488*907208c4SChristophe Leroy	stw	r0, 0(r9)
489*907208c4SChristophe Leroy	addi	r7, r7, 4
490*907208c4SChristophe Leroy	addi	r9, r9, 4
491*907208c4SChristophe Leroy	cmplw	0, r7, r8
492*907208c4SChristophe Leroy	bne	1b
493*907208c4SChristophe Leroy
494*907208c4SChristophe Leroy	/*
495*907208c4SChristophe Leroy	 * relocate `hdlr' and `int_return' entries
496*907208c4SChristophe Leroy	 */
497*907208c4SChristophe Leroy	li	r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET
498*907208c4SChristophe Leroy	li	r8, Alignment - _start + EXC_OFF_SYS_RESET
499*907208c4SChristophe Leroy2:
500*907208c4SChristophe Leroy	bl	trap_reloc
501*907208c4SChristophe Leroy	addi	r7, r7, 0x100		/* next exception vector	*/
502*907208c4SChristophe Leroy	cmplw	0, r7, r8
503*907208c4SChristophe Leroy	blt	2b
504*907208c4SChristophe Leroy
505*907208c4SChristophe Leroy	li	r7, .L_Alignment - _start + EXC_OFF_SYS_RESET
506*907208c4SChristophe Leroy	bl	trap_reloc
507*907208c4SChristophe Leroy
508*907208c4SChristophe Leroy	li	r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET
509*907208c4SChristophe Leroy	bl	trap_reloc
510*907208c4SChristophe Leroy
511*907208c4SChristophe Leroy	li	r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET
512*907208c4SChristophe Leroy	li	r8, SystemCall - _start + EXC_OFF_SYS_RESET
513*907208c4SChristophe Leroy3:
514*907208c4SChristophe Leroy	bl	trap_reloc
515*907208c4SChristophe Leroy	addi	r7, r7, 0x100		/* next exception vector	*/
516*907208c4SChristophe Leroy	cmplw	0, r7, r8
517*907208c4SChristophe Leroy	blt	3b
518*907208c4SChristophe Leroy
519*907208c4SChristophe Leroy	li	r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET
520*907208c4SChristophe Leroy	li	r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET
521*907208c4SChristophe Leroy4:
522*907208c4SChristophe Leroy	bl	trap_reloc
523*907208c4SChristophe Leroy	addi	r7, r7, 0x100		/* next exception vector	*/
524*907208c4SChristophe Leroy	cmplw	0, r7, r8
525*907208c4SChristophe Leroy	blt	4b
526*907208c4SChristophe Leroy
527*907208c4SChristophe Leroy	mtlr	r4			/* restore link register	*/
528*907208c4SChristophe Leroy	blr
529