xref: /OK3568_Linux_fs/u-boot/arch/powerpc/cpu/mpc86xx/start.S (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun/*
2*4882a593Smuzhiyun * Copyright 2004, 2007, 2011 Freescale Semiconductor.
3*4882a593Smuzhiyun * Srikanth Srinivasan <srikanth.srinivaan@freescale.com>
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * SPDX-License-Identifier:	GPL-2.0+
6*4882a593Smuzhiyun */
7*4882a593Smuzhiyun
8*4882a593Smuzhiyun/*  U-Boot - Startup Code for 86xx PowerPC based Embedded Boards
9*4882a593Smuzhiyun *
10*4882a593Smuzhiyun *
11*4882a593Smuzhiyun *  The processor starts at 0xfff00100 and the code is executed
12*4882a593Smuzhiyun *  from flash. The code is organized to be at an other address
13*4882a593Smuzhiyun *  in memory, but as long we don't jump around before relocating.
14*4882a593Smuzhiyun *  board_init lies at a quite high address and when the cpu has
15*4882a593Smuzhiyun *  jumped there, everything is ok.
16*4882a593Smuzhiyun */
17*4882a593Smuzhiyun#include <asm-offsets.h>
18*4882a593Smuzhiyun#include <config.h>
19*4882a593Smuzhiyun#include <mpc86xx.h>
20*4882a593Smuzhiyun#include <version.h>
21*4882a593Smuzhiyun
22*4882a593Smuzhiyun#include <ppc_asm.tmpl>
23*4882a593Smuzhiyun#include <ppc_defs.h>
24*4882a593Smuzhiyun
25*4882a593Smuzhiyun#include <asm/cache.h>
26*4882a593Smuzhiyun#include <asm/mmu.h>
27*4882a593Smuzhiyun#include <asm/u-boot.h>
28*4882a593Smuzhiyun
29*4882a593Smuzhiyun/*
30*4882a593Smuzhiyun * Need MSR_DR | MSR_IR enabled to access I/O (printf) in exceptions
31*4882a593Smuzhiyun */
32*4882a593Smuzhiyun
33*4882a593Smuzhiyun/*
34*4882a593Smuzhiyun * Set up GOT: Global Offset Table
35*4882a593Smuzhiyun *
36*4882a593Smuzhiyun * Use r12 to access the GOT
37*4882a593Smuzhiyun */
38*4882a593Smuzhiyun	START_GOT
39*4882a593Smuzhiyun	GOT_ENTRY(_GOT2_TABLE_)
40*4882a593Smuzhiyun	GOT_ENTRY(_FIXUP_TABLE_)
41*4882a593Smuzhiyun
42*4882a593Smuzhiyun	GOT_ENTRY(_start)
43*4882a593Smuzhiyun	GOT_ENTRY(_start_of_vectors)
44*4882a593Smuzhiyun	GOT_ENTRY(_end_of_vectors)
45*4882a593Smuzhiyun	GOT_ENTRY(transfer_to_handler)
46*4882a593Smuzhiyun
47*4882a593Smuzhiyun	GOT_ENTRY(__init_end)
48*4882a593Smuzhiyun	GOT_ENTRY(__bss_end)
49*4882a593Smuzhiyun	GOT_ENTRY(__bss_start)
50*4882a593Smuzhiyun	END_GOT
51*4882a593Smuzhiyun
52*4882a593Smuzhiyun/*
53*4882a593Smuzhiyun * r3 - 1st arg to board_init(): IMMP pointer
54*4882a593Smuzhiyun * r4 - 2nd arg to board_init(): boot flag
55*4882a593Smuzhiyun */
56*4882a593Smuzhiyun	.text
57*4882a593Smuzhiyun	.long	0x27051956		/* U-Boot Magic Number */
58*4882a593Smuzhiyun	.globl	version_string
59*4882a593Smuzhiyunversion_string:
60*4882a593Smuzhiyun	.ascii U_BOOT_VERSION_STRING, "\0"
61*4882a593Smuzhiyun
62*4882a593Smuzhiyun	. = EXC_OFF_SYS_RESET
63*4882a593Smuzhiyun	.globl	_start
64*4882a593Smuzhiyun_start:
65*4882a593Smuzhiyun	b	boot_cold
66*4882a593Smuzhiyun
67*4882a593Smuzhiyun	/* the boot code is located below the exception table */
68*4882a593Smuzhiyun
69*4882a593Smuzhiyun	.globl	_start_of_vectors
70*4882a593Smuzhiyun_start_of_vectors:
71*4882a593Smuzhiyun
72*4882a593Smuzhiyun/* Machine check */
73*4882a593Smuzhiyun	STD_EXCEPTION(0x200, MachineCheck, MachineCheckException)
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun/* Data Storage exception. */
76*4882a593Smuzhiyun	STD_EXCEPTION(0x300, DataStorage, UnknownException)
77*4882a593Smuzhiyun
78*4882a593Smuzhiyun/* Instruction Storage exception. */
79*4882a593Smuzhiyun	STD_EXCEPTION(0x400, InstStorage, UnknownException)
80*4882a593Smuzhiyun
81*4882a593Smuzhiyun/* External Interrupt exception. */
82*4882a593Smuzhiyun	STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt)
83*4882a593Smuzhiyun
84*4882a593Smuzhiyun/* Alignment exception. */
85*4882a593Smuzhiyun	. = 0x600
86*4882a593SmuzhiyunAlignment:
87*4882a593Smuzhiyun	EXCEPTION_PROLOG(SRR0, SRR1)
88*4882a593Smuzhiyun	mfspr	r4,DAR
89*4882a593Smuzhiyun	stw	r4,_DAR(r21)
90*4882a593Smuzhiyun	mfspr	r5,DSISR
91*4882a593Smuzhiyun	stw	r5,_DSISR(r21)
92*4882a593Smuzhiyun	addi	r3,r1,STACK_FRAME_OVERHEAD
93*4882a593Smuzhiyun	EXC_XFER_TEMPLATE(Alignment, AlignmentException, MSR_KERNEL, COPY_EE)
94*4882a593Smuzhiyun
95*4882a593Smuzhiyun/* Program check exception */
96*4882a593Smuzhiyun	. = 0x700
97*4882a593SmuzhiyunProgramCheck:
98*4882a593Smuzhiyun	EXCEPTION_PROLOG(SRR0, SRR1)
99*4882a593Smuzhiyun	addi	r3,r1,STACK_FRAME_OVERHEAD
100*4882a593Smuzhiyun	EXC_XFER_TEMPLATE(ProgramCheck, ProgramCheckException,
101*4882a593Smuzhiyun		MSR_KERNEL, COPY_EE)
102*4882a593Smuzhiyun
103*4882a593Smuzhiyun	STD_EXCEPTION(0x800, FPUnavailable, UnknownException)
104*4882a593Smuzhiyun
105*4882a593Smuzhiyun	/* I guess we could implement decrementer, and may have
106*4882a593Smuzhiyun	 * to someday for timekeeping.
107*4882a593Smuzhiyun	 */
108*4882a593Smuzhiyun	STD_EXCEPTION(0x900, Decrementer, timer_interrupt)
109*4882a593Smuzhiyun	STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
110*4882a593Smuzhiyun	STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
111*4882a593Smuzhiyun	STD_EXCEPTION(0xc00, SystemCall, UnknownException)
112*4882a593Smuzhiyun	STD_EXCEPTION(0xd00, SingleStep, UnknownException)
113*4882a593Smuzhiyun	STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
114*4882a593Smuzhiyun	STD_EXCEPTION(0xf00, Trap_0f, UnknownException)
115*4882a593Smuzhiyun	STD_EXCEPTION(0x1000, SoftEmu, SoftEmuException)
116*4882a593Smuzhiyun	STD_EXCEPTION(0x1100, InstructionTLBMiss, UnknownException)
117*4882a593Smuzhiyun	STD_EXCEPTION(0x1200, DataTLBMiss, UnknownException)
118*4882a593Smuzhiyun	STD_EXCEPTION(0x1300, InstructionTLBError, UnknownException)
119*4882a593Smuzhiyun	STD_EXCEPTION(0x1400, DataTLBError, UnknownException)
120*4882a593Smuzhiyun	STD_EXCEPTION(0x1500, Reserved5, UnknownException)
121*4882a593Smuzhiyun	STD_EXCEPTION(0x1600, Reserved6, UnknownException)
122*4882a593Smuzhiyun	STD_EXCEPTION(0x1700, Reserved7, UnknownException)
123*4882a593Smuzhiyun	STD_EXCEPTION(0x1800, Reserved8, UnknownException)
124*4882a593Smuzhiyun	STD_EXCEPTION(0x1900, Reserved9, UnknownException)
125*4882a593Smuzhiyun	STD_EXCEPTION(0x1a00, ReservedA, UnknownException)
126*4882a593Smuzhiyun	STD_EXCEPTION(0x1b00, ReservedB, UnknownException)
127*4882a593Smuzhiyun	STD_EXCEPTION(0x1c00, DataBreakpoint, UnknownException)
128*4882a593Smuzhiyun	STD_EXCEPTION(0x1d00, InstructionBreakpoint, UnknownException)
129*4882a593Smuzhiyun	STD_EXCEPTION(0x1e00, PeripheralBreakpoint, UnknownException)
130*4882a593Smuzhiyun	STD_EXCEPTION(0x1f00, DevPortBreakpoint, UnknownException)
131*4882a593Smuzhiyun
132*4882a593Smuzhiyun	.globl	_end_of_vectors
133*4882a593Smuzhiyun_end_of_vectors:
134*4882a593Smuzhiyun
135*4882a593Smuzhiyun	. = 0x2000
136*4882a593Smuzhiyun
137*4882a593Smuzhiyunboot_cold:
138*4882a593Smuzhiyun	/*
139*4882a593Smuzhiyun	 * NOTE: Only Cpu 0 will ever come here.  Other cores go to an
140*4882a593Smuzhiyun	 * address specified by the BPTR
141*4882a593Smuzhiyun	 */
142*4882a593Smuzhiyun1:
143*4882a593Smuzhiyun#ifdef CONFIG_SYS_RAMBOOT
144*4882a593Smuzhiyun	/* disable everything */
145*4882a593Smuzhiyun	li	r0, 0
146*4882a593Smuzhiyun	mtspr	HID0, r0
147*4882a593Smuzhiyun	sync
148*4882a593Smuzhiyun	mtmsr	0
149*4882a593Smuzhiyun#endif
150*4882a593Smuzhiyun
151*4882a593Smuzhiyun	/* Invalidate BATs */
152*4882a593Smuzhiyun	bl	invalidate_bats
153*4882a593Smuzhiyun	sync
154*4882a593Smuzhiyun	/* Invalidate all of TLB before MMU turn on */
155*4882a593Smuzhiyun	bl      clear_tlbs
156*4882a593Smuzhiyun	sync
157*4882a593Smuzhiyun
158*4882a593Smuzhiyun#ifdef CONFIG_SYS_L2
159*4882a593Smuzhiyun	/* init the L2 cache */
160*4882a593Smuzhiyun	lis	r3, L2_INIT@h
161*4882a593Smuzhiyun	ori	r3, r3, L2_INIT@l
162*4882a593Smuzhiyun	mtspr	l2cr, r3
163*4882a593Smuzhiyun	/* invalidate the L2 cache */
164*4882a593Smuzhiyun	bl	l2cache_invalidate
165*4882a593Smuzhiyun	sync
166*4882a593Smuzhiyun#endif
167*4882a593Smuzhiyun
168*4882a593Smuzhiyun	/*
169*4882a593Smuzhiyun	 * Calculate absolute address in FLASH and jump there
170*4882a593Smuzhiyun	 *------------------------------------------------------*/
171*4882a593Smuzhiyun	lis	r3, CONFIG_SYS_MONITOR_BASE_EARLY@h
172*4882a593Smuzhiyun	ori	r3, r3, CONFIG_SYS_MONITOR_BASE_EARLY@l
173*4882a593Smuzhiyun	addi	r3, r3, in_flash - _start + EXC_OFF_SYS_RESET
174*4882a593Smuzhiyun	mtlr	r3
175*4882a593Smuzhiyun	blr
176*4882a593Smuzhiyun
177*4882a593Smuzhiyunin_flash:
178*4882a593Smuzhiyun	/* let the C-code set up the rest			*/
179*4882a593Smuzhiyun	/*							*/
180*4882a593Smuzhiyun	/* Be careful to keep code relocatable !		*/
181*4882a593Smuzhiyun	/*------------------------------------------------------*/
182*4882a593Smuzhiyun	/* perform low-level init */
183*4882a593Smuzhiyun
184*4882a593Smuzhiyun	/* enable extended addressing */
185*4882a593Smuzhiyun	bl	enable_ext_addr
186*4882a593Smuzhiyun
187*4882a593Smuzhiyun	/* setup the bats */
188*4882a593Smuzhiyun	bl	early_bats
189*4882a593Smuzhiyun
190*4882a593Smuzhiyun	/*
191*4882a593Smuzhiyun	 * Cache must be enabled here for stack-in-cache trick.
192*4882a593Smuzhiyun	 * This means we need to enable the BATS.
193*4882a593Smuzhiyun	 * Cache should be turned on after BATs, since by default
194*4882a593Smuzhiyun	 * everything is write-through.
195*4882a593Smuzhiyun	 */
196*4882a593Smuzhiyun
197*4882a593Smuzhiyun	/* enable address translation */
198*4882a593Smuzhiyun	mfmsr	r5
199*4882a593Smuzhiyun	ori	r5, r5, (MSR_IR | MSR_DR)
200*4882a593Smuzhiyun	lis	r3,addr_trans_enabled@h
201*4882a593Smuzhiyun	ori	r3, r3, addr_trans_enabled@l
202*4882a593Smuzhiyun	mtspr	SPRN_SRR0,r3
203*4882a593Smuzhiyun	mtspr	SPRN_SRR1,r5
204*4882a593Smuzhiyun	rfi
205*4882a593Smuzhiyun
206*4882a593Smuzhiyunaddr_trans_enabled:
207*4882a593Smuzhiyun	/* enable and invalidate the data cache */
208*4882a593Smuzhiyun/*	bl	l1dcache_enable */
209*4882a593Smuzhiyun	bl	dcache_enable
210*4882a593Smuzhiyun	sync
211*4882a593Smuzhiyun
212*4882a593Smuzhiyun#if 1
213*4882a593Smuzhiyun	bl	icache_enable
214*4882a593Smuzhiyun#endif
215*4882a593Smuzhiyun
216*4882a593Smuzhiyun#ifdef CONFIG_SYS_INIT_RAM_LOCK
217*4882a593Smuzhiyun	bl	lock_ram_in_cache
218*4882a593Smuzhiyun	sync
219*4882a593Smuzhiyun#endif
220*4882a593Smuzhiyun
221*4882a593Smuzhiyun#if (CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR)
222*4882a593Smuzhiyun	bl      setup_ccsrbar
223*4882a593Smuzhiyun#endif
224*4882a593Smuzhiyun
225*4882a593Smuzhiyun	/* set up the stack pointer in our newly created
226*4882a593Smuzhiyun	 * cache-ram (r1) */
227*4882a593Smuzhiyun	lis	r1, (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET)@h
228*4882a593Smuzhiyun	ori	r1, r1, (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET)@l
229*4882a593Smuzhiyun
230*4882a593Smuzhiyun	li	r0, 0		/* Make room for stack frame header and */
231*4882a593Smuzhiyun	stwu	r0, -4(r1)	/* clear final stack frame so that	*/
232*4882a593Smuzhiyun	stwu	r0, -4(r1)	/* stack backtraces terminate cleanly	*/
233*4882a593Smuzhiyun
234*4882a593Smuzhiyun	GET_GOT			/* initialize GOT access	*/
235*4882a593Smuzhiyun
236*4882a593Smuzhiyun	/* run low-level CPU init code	   (from Flash) */
237*4882a593Smuzhiyun	bl	cpu_init_f
238*4882a593Smuzhiyun	sync
239*4882a593Smuzhiyun
240*4882a593Smuzhiyun#ifdef	RUN_DIAG
241*4882a593Smuzhiyun
242*4882a593Smuzhiyun	/* Load PX_AUX register address in r4 */
243*4882a593Smuzhiyun	lis	r4, PIXIS_BASE@h
244*4882a593Smuzhiyun	ori	r4, r4, 0x6
245*4882a593Smuzhiyun	/* Load contents of PX_AUX in r3 bits 24 to 31*/
246*4882a593Smuzhiyun	lbz	r3, 0(r4)
247*4882a593Smuzhiyun
248*4882a593Smuzhiyun	/* Mask and obtain the bit in r3 */
249*4882a593Smuzhiyun	rlwinm. r3, r3, 0, 24, 24
250*4882a593Smuzhiyun	/* If not zero, jump and continue with u-boot */
251*4882a593Smuzhiyun	bne	diag_done
252*4882a593Smuzhiyun
253*4882a593Smuzhiyun	/* Load back contents of PX_AUX in r3 bits 24 to 31 */
254*4882a593Smuzhiyun	lbz	r3, 0(r4)
255*4882a593Smuzhiyun	/* Set the MSB of the register value */
256*4882a593Smuzhiyun	ori	r3, r3, 0x80
257*4882a593Smuzhiyun	/* Write value in r3 back to PX_AUX */
258*4882a593Smuzhiyun	stb	r3, 0(r4)
259*4882a593Smuzhiyun
260*4882a593Smuzhiyun	/* Get the address to jump to in r3*/
261*4882a593Smuzhiyun	lis	r3, CONFIG_SYS_DIAG_ADDR@h
262*4882a593Smuzhiyun	ori	r3, r3, CONFIG_SYS_DIAG_ADDR@l
263*4882a593Smuzhiyun
264*4882a593Smuzhiyun	/* Load the LR with the branch address */
265*4882a593Smuzhiyun	mtlr	r3
266*4882a593Smuzhiyun
267*4882a593Smuzhiyun	/* Branch to diagnostic */
268*4882a593Smuzhiyun	blr
269*4882a593Smuzhiyun
270*4882a593Smuzhiyundiag_done:
271*4882a593Smuzhiyun#endif
272*4882a593Smuzhiyun
273*4882a593Smuzhiyun/*	bl	l2cache_enable */
274*4882a593Smuzhiyun
275*4882a593Smuzhiyun	/* run 1st part of board init code (from Flash)	  */
276*4882a593Smuzhiyun	li	r3, 0		/* clear boot_flag for calling board_init_f */
277*4882a593Smuzhiyun	bl	board_init_f
278*4882a593Smuzhiyun	sync
279*4882a593Smuzhiyun
280*4882a593Smuzhiyun	/* NOTREACHED - board_init_f() does not return */
281*4882a593Smuzhiyun
282*4882a593Smuzhiyun	.globl	invalidate_bats
283*4882a593Smuzhiyuninvalidate_bats:
284*4882a593Smuzhiyun
285*4882a593Smuzhiyun	li	r0, 0
286*4882a593Smuzhiyun	/* invalidate BATs */
287*4882a593Smuzhiyun	mtspr	IBAT0U, r0
288*4882a593Smuzhiyun	mtspr	IBAT1U, r0
289*4882a593Smuzhiyun	mtspr	IBAT2U, r0
290*4882a593Smuzhiyun	mtspr	IBAT3U, r0
291*4882a593Smuzhiyun	mtspr	IBAT4U, r0
292*4882a593Smuzhiyun	mtspr	IBAT5U, r0
293*4882a593Smuzhiyun	mtspr	IBAT6U, r0
294*4882a593Smuzhiyun	mtspr	IBAT7U, r0
295*4882a593Smuzhiyun
296*4882a593Smuzhiyun	isync
297*4882a593Smuzhiyun	mtspr	DBAT0U, r0
298*4882a593Smuzhiyun	mtspr	DBAT1U, r0
299*4882a593Smuzhiyun	mtspr	DBAT2U, r0
300*4882a593Smuzhiyun	mtspr	DBAT3U, r0
301*4882a593Smuzhiyun	mtspr	DBAT4U, r0
302*4882a593Smuzhiyun	mtspr	DBAT5U, r0
303*4882a593Smuzhiyun	mtspr	DBAT6U, r0
304*4882a593Smuzhiyun	mtspr	DBAT7U, r0
305*4882a593Smuzhiyun
306*4882a593Smuzhiyun	isync
307*4882a593Smuzhiyun	sync
308*4882a593Smuzhiyun	blr
309*4882a593Smuzhiyun
310*4882a593Smuzhiyun#define CONFIG_BAT_PAIR(n) \
311*4882a593Smuzhiyun	lis	r4, CONFIG_SYS_IBAT##n##L@h; 		\
312*4882a593Smuzhiyun	ori	r4, r4, CONFIG_SYS_IBAT##n##L@l; 	\
313*4882a593Smuzhiyun	lis	r3, CONFIG_SYS_IBAT##n##U@h; 		\
314*4882a593Smuzhiyun	ori	r3, r3, CONFIG_SYS_IBAT##n##U@l; 	\
315*4882a593Smuzhiyun	mtspr	IBAT##n##L, r4; 			\
316*4882a593Smuzhiyun	mtspr	IBAT##n##U, r3; 			\
317*4882a593Smuzhiyun	lis	r4, CONFIG_SYS_DBAT##n##L@h; 		\
318*4882a593Smuzhiyun	ori	r4, r4, CONFIG_SYS_DBAT##n##L@l; 	\
319*4882a593Smuzhiyun	lis	r3, CONFIG_SYS_DBAT##n##U@h; 		\
320*4882a593Smuzhiyun	ori	r3, r3, CONFIG_SYS_DBAT##n##U@l; 	\
321*4882a593Smuzhiyun	mtspr	DBAT##n##L, r4;				\
322*4882a593Smuzhiyun	mtspr	DBAT##n##U, r3;
323*4882a593Smuzhiyun
324*4882a593Smuzhiyun/*
325*4882a593Smuzhiyun * setup_bats:
326*4882a593Smuzhiyun *
327*4882a593Smuzhiyun * Set up the final BAT registers now that setup is done.
328*4882a593Smuzhiyun *
329*4882a593Smuzhiyun * Assumes that:
330*4882a593Smuzhiyun *	1) Address translation is enabled upon entry
331*4882a593Smuzhiyun *	2) The boot rom is still accessible via 1:1 translation
332*4882a593Smuzhiyun */
333*4882a593Smuzhiyun	.globl setup_bats
334*4882a593Smuzhiyunsetup_bats:
335*4882a593Smuzhiyun	mflr	r5
336*4882a593Smuzhiyun	sync
337*4882a593Smuzhiyun
338*4882a593Smuzhiyun	/*
339*4882a593Smuzhiyun	 * When we disable address translation, we will get 1:1 (VA==PA)
340*4882a593Smuzhiyun	 * translation.  The only place we know for sure is safe for that is
341*4882a593Smuzhiyun	 * the bootrom where we originally started out.  Pop back into there.
342*4882a593Smuzhiyun	 */
343*4882a593Smuzhiyun	lis	r4, CONFIG_SYS_MONITOR_BASE_EARLY@h
344*4882a593Smuzhiyun	ori	r4, r4, CONFIG_SYS_MONITOR_BASE_EARLY@l
345*4882a593Smuzhiyun	addi	r4, r4, trans_disabled - _start + EXC_OFF_SYS_RESET
346*4882a593Smuzhiyun
347*4882a593Smuzhiyun	/* disable address translation */
348*4882a593Smuzhiyun	mfmsr	r3
349*4882a593Smuzhiyun	rlwinm	r3, r3, 0, 28, 25
350*4882a593Smuzhiyun	mtspr	SRR0, r4
351*4882a593Smuzhiyun	mtspr	SRR1, r3
352*4882a593Smuzhiyun	rfi
353*4882a593Smuzhiyun
354*4882a593Smuzhiyuntrans_disabled:
355*4882a593Smuzhiyun#if defined(CONFIG_SYS_DBAT0U) && defined(CONFIG_SYS_DBAT0L) \
356*4882a593Smuzhiyun	&& defined(CONFIG_SYS_IBAT0U) && defined(CONFIG_SYS_IBAT0L)
357*4882a593Smuzhiyun	CONFIG_BAT_PAIR(0)
358*4882a593Smuzhiyun#endif
359*4882a593Smuzhiyun	CONFIG_BAT_PAIR(1)
360*4882a593Smuzhiyun	CONFIG_BAT_PAIR(2)
361*4882a593Smuzhiyun	CONFIG_BAT_PAIR(3)
362*4882a593Smuzhiyun	CONFIG_BAT_PAIR(4)
363*4882a593Smuzhiyun	CONFIG_BAT_PAIR(5)
364*4882a593Smuzhiyun	CONFIG_BAT_PAIR(6)
365*4882a593Smuzhiyun	CONFIG_BAT_PAIR(7)
366*4882a593Smuzhiyun
367*4882a593Smuzhiyun	sync
368*4882a593Smuzhiyun	isync
369*4882a593Smuzhiyun
370*4882a593Smuzhiyun	/* Turn translation back on and return */
371*4882a593Smuzhiyun	mfmsr	r3
372*4882a593Smuzhiyun	ori	r3, r3, (MSR_IR | MSR_DR)
373*4882a593Smuzhiyun	mtspr	SPRN_SRR0,r5
374*4882a593Smuzhiyun	mtspr	SPRN_SRR1,r3
375*4882a593Smuzhiyun	rfi
376*4882a593Smuzhiyun
377*4882a593Smuzhiyun/*
378*4882a593Smuzhiyun * early_bats:
379*4882a593Smuzhiyun *
380*4882a593Smuzhiyun * Set up bats needed early on - this is usually the BAT for the
381*4882a593Smuzhiyun * stack-in-cache, the Flash, and CCSR space
382*4882a593Smuzhiyun */
383*4882a593Smuzhiyun	.globl  early_bats
384*4882a593Smuzhiyunearly_bats:
385*4882a593Smuzhiyun	/* IBAT 3 */
386*4882a593Smuzhiyun	lis	r4, CONFIG_SYS_IBAT3L@h
387*4882a593Smuzhiyun	ori     r4, r4, CONFIG_SYS_IBAT3L@l
388*4882a593Smuzhiyun	lis	r3, CONFIG_SYS_IBAT3U@h
389*4882a593Smuzhiyun	ori     r3, r3, CONFIG_SYS_IBAT3U@l
390*4882a593Smuzhiyun	mtspr   IBAT3L, r4
391*4882a593Smuzhiyun	mtspr   IBAT3U, r3
392*4882a593Smuzhiyun	isync
393*4882a593Smuzhiyun
394*4882a593Smuzhiyun	/* DBAT 3 */
395*4882a593Smuzhiyun	lis	r4, CONFIG_SYS_DBAT3L@h
396*4882a593Smuzhiyun	ori     r4, r4, CONFIG_SYS_DBAT3L@l
397*4882a593Smuzhiyun	lis	r3, CONFIG_SYS_DBAT3U@h
398*4882a593Smuzhiyun	ori     r3, r3, CONFIG_SYS_DBAT3U@l
399*4882a593Smuzhiyun	mtspr   DBAT3L, r4
400*4882a593Smuzhiyun	mtspr   DBAT3U, r3
401*4882a593Smuzhiyun	isync
402*4882a593Smuzhiyun
403*4882a593Smuzhiyun	/* IBAT 5 */
404*4882a593Smuzhiyun	lis	r4, CONFIG_SYS_IBAT5L@h
405*4882a593Smuzhiyun	ori     r4, r4, CONFIG_SYS_IBAT5L@l
406*4882a593Smuzhiyun	lis	r3, CONFIG_SYS_IBAT5U@h
407*4882a593Smuzhiyun	ori     r3, r3, CONFIG_SYS_IBAT5U@l
408*4882a593Smuzhiyun	mtspr   IBAT5L, r4
409*4882a593Smuzhiyun	mtspr   IBAT5U, r3
410*4882a593Smuzhiyun	isync
411*4882a593Smuzhiyun
412*4882a593Smuzhiyun	/* DBAT 5 */
413*4882a593Smuzhiyun	lis	r4, CONFIG_SYS_DBAT5L@h
414*4882a593Smuzhiyun	ori     r4, r4, CONFIG_SYS_DBAT5L@l
415*4882a593Smuzhiyun	lis	r3, CONFIG_SYS_DBAT5U@h
416*4882a593Smuzhiyun	ori     r3, r3, CONFIG_SYS_DBAT5U@l
417*4882a593Smuzhiyun	mtspr   DBAT5L, r4
418*4882a593Smuzhiyun	mtspr   DBAT5U, r3
419*4882a593Smuzhiyun	isync
420*4882a593Smuzhiyun
421*4882a593Smuzhiyun	/* IBAT 6 */
422*4882a593Smuzhiyun	lis	r4, CONFIG_SYS_IBAT6L_EARLY@h
423*4882a593Smuzhiyun	ori     r4, r4, CONFIG_SYS_IBAT6L_EARLY@l
424*4882a593Smuzhiyun	lis	r3, CONFIG_SYS_IBAT6U_EARLY@h
425*4882a593Smuzhiyun	ori     r3, r3, CONFIG_SYS_IBAT6U_EARLY@l
426*4882a593Smuzhiyun	mtspr   IBAT6L, r4
427*4882a593Smuzhiyun	mtspr   IBAT6U, r3
428*4882a593Smuzhiyun	isync
429*4882a593Smuzhiyun
430*4882a593Smuzhiyun	/* DBAT 6 */
431*4882a593Smuzhiyun	lis	r4, CONFIG_SYS_DBAT6L_EARLY@h
432*4882a593Smuzhiyun	ori     r4, r4, CONFIG_SYS_DBAT6L_EARLY@l
433*4882a593Smuzhiyun	lis	r3, CONFIG_SYS_DBAT6U_EARLY@h
434*4882a593Smuzhiyun	ori     r3, r3, CONFIG_SYS_DBAT6U_EARLY@l
435*4882a593Smuzhiyun	mtspr   DBAT6L, r4
436*4882a593Smuzhiyun	mtspr   DBAT6U, r3
437*4882a593Smuzhiyun	isync
438*4882a593Smuzhiyun
439*4882a593Smuzhiyun#if(CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR)
440*4882a593Smuzhiyun	/* IBAT 7 */
441*4882a593Smuzhiyun	lis	r4, CONFIG_SYS_CCSR_DEFAULT_IBATL@h
442*4882a593Smuzhiyun	ori     r4, r4, CONFIG_SYS_CCSR_DEFAULT_IBATL@l
443*4882a593Smuzhiyun	lis	r3, CONFIG_SYS_CCSR_DEFAULT_IBATU@h
444*4882a593Smuzhiyun	ori     r3, r3, CONFIG_SYS_CCSR_DEFAULT_IBATU@l
445*4882a593Smuzhiyun	mtspr   IBAT7L, r4
446*4882a593Smuzhiyun	mtspr   IBAT7U, r3
447*4882a593Smuzhiyun	isync
448*4882a593Smuzhiyun
449*4882a593Smuzhiyun	/* DBAT 7 */
450*4882a593Smuzhiyun	lis	r4, CONFIG_SYS_CCSR_DEFAULT_DBATL@h
451*4882a593Smuzhiyun	ori     r4, r4, CONFIG_SYS_CCSR_DEFAULT_DBATL@l
452*4882a593Smuzhiyun	lis	r3, CONFIG_SYS_CCSR_DEFAULT_DBATU@h
453*4882a593Smuzhiyun	ori     r3, r3, CONFIG_SYS_CCSR_DEFAULT_DBATU@l
454*4882a593Smuzhiyun	mtspr   DBAT7L, r4
455*4882a593Smuzhiyun	mtspr   DBAT7U, r3
456*4882a593Smuzhiyun	isync
457*4882a593Smuzhiyun#endif
458*4882a593Smuzhiyun	blr
459*4882a593Smuzhiyun
460*4882a593Smuzhiyun	.globl clear_tlbs
461*4882a593Smuzhiyunclear_tlbs:
462*4882a593Smuzhiyun	addis   r3, 0, 0x0000
463*4882a593Smuzhiyun	addis   r5, 0, 0x4
464*4882a593Smuzhiyun	isync
465*4882a593Smuzhiyuntlblp:
466*4882a593Smuzhiyun	tlbie   r3
467*4882a593Smuzhiyun	sync
468*4882a593Smuzhiyun	addi    r3, r3, 0x1000
469*4882a593Smuzhiyun	cmp     0, 0, r3, r5
470*4882a593Smuzhiyun	blt tlblp
471*4882a593Smuzhiyun	blr
472*4882a593Smuzhiyun
473*4882a593Smuzhiyun	.globl disable_addr_trans
474*4882a593Smuzhiyundisable_addr_trans:
475*4882a593Smuzhiyun	/* disable address translation */
476*4882a593Smuzhiyun	mflr	r4
477*4882a593Smuzhiyun	mfmsr	r3
478*4882a593Smuzhiyun	andi.	r0, r3, (MSR_IR | MSR_DR)
479*4882a593Smuzhiyun	beqlr
480*4882a593Smuzhiyun	andc	r3, r3, r0
481*4882a593Smuzhiyun	mtspr	SRR0, r4
482*4882a593Smuzhiyun	mtspr	SRR1, r3
483*4882a593Smuzhiyun	rfi
484*4882a593Smuzhiyun
485*4882a593Smuzhiyun/*
486*4882a593Smuzhiyun * This code finishes saving the registers to the exception frame
487*4882a593Smuzhiyun * and jumps to the appropriate handler for the exception.
488*4882a593Smuzhiyun * Register r21 is pointer into trap frame, r1 has new stack pointer.
489*4882a593Smuzhiyun */
490*4882a593Smuzhiyun	.globl	transfer_to_handler
491*4882a593Smuzhiyuntransfer_to_handler:
492*4882a593Smuzhiyun	stw	r22,_NIP(r21)
493*4882a593Smuzhiyun	lis	r22,MSR_POW@h
494*4882a593Smuzhiyun	andc	r23,r23,r22
495*4882a593Smuzhiyun	stw	r23,_MSR(r21)
496*4882a593Smuzhiyun	SAVE_GPR(7, r21)
497*4882a593Smuzhiyun	SAVE_4GPRS(8, r21)
498*4882a593Smuzhiyun	SAVE_8GPRS(12, r21)
499*4882a593Smuzhiyun	SAVE_8GPRS(24, r21)
500*4882a593Smuzhiyun	mflr	r23
501*4882a593Smuzhiyun	andi.	r24,r23,0x3f00		/* get vector offset */
502*4882a593Smuzhiyun	stw	r24,TRAP(r21)
503*4882a593Smuzhiyun	li	r22,0
504*4882a593Smuzhiyun	stw	r22,RESULT(r21)
505*4882a593Smuzhiyun	mtspr	SPRG2,r22		/* r1 is now kernel sp */
506*4882a593Smuzhiyun	lwz	r24,0(r23)		/* virtual address of handler */
507*4882a593Smuzhiyun	lwz	r23,4(r23)		/* where to go when done */
508*4882a593Smuzhiyun	mtspr	SRR0,r24
509*4882a593Smuzhiyun	mtspr	SRR1,r20
510*4882a593Smuzhiyun	mtlr	r23
511*4882a593Smuzhiyun	SYNC
512*4882a593Smuzhiyun	rfi				/* jump to handler, enable MMU */
513*4882a593Smuzhiyun
514*4882a593Smuzhiyunint_return:
515*4882a593Smuzhiyun	mfmsr	r28		/* Disable interrupts */
516*4882a593Smuzhiyun	li	r4,0
517*4882a593Smuzhiyun	ori	r4,r4,MSR_EE
518*4882a593Smuzhiyun	andc	r28,r28,r4
519*4882a593Smuzhiyun	SYNC			/* Some chip revs need this... */
520*4882a593Smuzhiyun	mtmsr	r28
521*4882a593Smuzhiyun	SYNC
522*4882a593Smuzhiyun	lwz	r2,_CTR(r1)
523*4882a593Smuzhiyun	lwz	r0,_LINK(r1)
524*4882a593Smuzhiyun	mtctr	r2
525*4882a593Smuzhiyun	mtlr	r0
526*4882a593Smuzhiyun	lwz	r2,_XER(r1)
527*4882a593Smuzhiyun	lwz	r0,_CCR(r1)
528*4882a593Smuzhiyun	mtspr	XER,r2
529*4882a593Smuzhiyun	mtcrf	0xFF,r0
530*4882a593Smuzhiyun	REST_10GPRS(3, r1)
531*4882a593Smuzhiyun	REST_10GPRS(13, r1)
532*4882a593Smuzhiyun	REST_8GPRS(23, r1)
533*4882a593Smuzhiyun	REST_GPR(31, r1)
534*4882a593Smuzhiyun	lwz	r2,_NIP(r1)	/* Restore environment */
535*4882a593Smuzhiyun	lwz	r0,_MSR(r1)
536*4882a593Smuzhiyun	mtspr	SRR0,r2
537*4882a593Smuzhiyun	mtspr	SRR1,r0
538*4882a593Smuzhiyun	lwz	r0,GPR0(r1)
539*4882a593Smuzhiyun	lwz	r2,GPR2(r1)
540*4882a593Smuzhiyun	lwz	r1,GPR1(r1)
541*4882a593Smuzhiyun	SYNC
542*4882a593Smuzhiyun	rfi
543*4882a593Smuzhiyun
544*4882a593Smuzhiyun	.globl	dc_read
545*4882a593Smuzhiyundc_read:
546*4882a593Smuzhiyun	blr
547*4882a593Smuzhiyun
548*4882a593Smuzhiyun
549*4882a593Smuzhiyun/*
550*4882a593Smuzhiyun * Function:	in8
551*4882a593Smuzhiyun * Description:	Input 8 bits
552*4882a593Smuzhiyun */
553*4882a593Smuzhiyun	.globl	in8
554*4882a593Smuzhiyunin8:
555*4882a593Smuzhiyun	lbz	r3,0x0000(r3)
556*4882a593Smuzhiyun	blr
557*4882a593Smuzhiyun
558*4882a593Smuzhiyun/*
559*4882a593Smuzhiyun * Function:	out8
560*4882a593Smuzhiyun * Description:	Output 8 bits
561*4882a593Smuzhiyun */
562*4882a593Smuzhiyun	.globl	out8
563*4882a593Smuzhiyunout8:
564*4882a593Smuzhiyun	stb	r4,0x0000(r3)
565*4882a593Smuzhiyun	blr
566*4882a593Smuzhiyun
567*4882a593Smuzhiyun/*
568*4882a593Smuzhiyun * Function:	out16
569*4882a593Smuzhiyun * Description:	Output 16 bits
570*4882a593Smuzhiyun */
571*4882a593Smuzhiyun	.globl	out16
572*4882a593Smuzhiyunout16:
573*4882a593Smuzhiyun	sth	r4,0x0000(r3)
574*4882a593Smuzhiyun	blr
575*4882a593Smuzhiyun
576*4882a593Smuzhiyun/*
577*4882a593Smuzhiyun * Function:	out16r
578*4882a593Smuzhiyun * Description:	Byte reverse and output 16 bits
579*4882a593Smuzhiyun */
580*4882a593Smuzhiyun	.globl	out16r
581*4882a593Smuzhiyunout16r:
582*4882a593Smuzhiyun	sthbrx	r4,r0,r3
583*4882a593Smuzhiyun	blr
584*4882a593Smuzhiyun
585*4882a593Smuzhiyun/*
586*4882a593Smuzhiyun * Function:	out32
587*4882a593Smuzhiyun * Description:	Output 32 bits
588*4882a593Smuzhiyun */
589*4882a593Smuzhiyun	.globl	out32
590*4882a593Smuzhiyunout32:
591*4882a593Smuzhiyun	stw	r4,0x0000(r3)
592*4882a593Smuzhiyun	blr
593*4882a593Smuzhiyun
594*4882a593Smuzhiyun/*
595*4882a593Smuzhiyun * Function:	out32r
596*4882a593Smuzhiyun * Description:	Byte reverse and output 32 bits
597*4882a593Smuzhiyun */
598*4882a593Smuzhiyun	.globl	out32r
599*4882a593Smuzhiyunout32r:
600*4882a593Smuzhiyun	stwbrx	r4,r0,r3
601*4882a593Smuzhiyun	blr
602*4882a593Smuzhiyun
603*4882a593Smuzhiyun/*
604*4882a593Smuzhiyun * Function:	in16
605*4882a593Smuzhiyun * Description:	Input 16 bits
606*4882a593Smuzhiyun */
607*4882a593Smuzhiyun	.globl	in16
608*4882a593Smuzhiyunin16:
609*4882a593Smuzhiyun	lhz	r3,0x0000(r3)
610*4882a593Smuzhiyun	blr
611*4882a593Smuzhiyun
612*4882a593Smuzhiyun/*
613*4882a593Smuzhiyun * Function:	in16r
614*4882a593Smuzhiyun * Description:	Input 16 bits and byte reverse
615*4882a593Smuzhiyun */
616*4882a593Smuzhiyun	.globl	in16r
617*4882a593Smuzhiyunin16r:
618*4882a593Smuzhiyun	lhbrx	r3,r0,r3
619*4882a593Smuzhiyun	blr
620*4882a593Smuzhiyun
621*4882a593Smuzhiyun/*
622*4882a593Smuzhiyun * Function:	in32
623*4882a593Smuzhiyun * Description:	Input 32 bits
624*4882a593Smuzhiyun */
625*4882a593Smuzhiyun	.globl	in32
626*4882a593Smuzhiyunin32:
627*4882a593Smuzhiyun	lwz	3,0x0000(3)
628*4882a593Smuzhiyun	blr
629*4882a593Smuzhiyun
630*4882a593Smuzhiyun/*
631*4882a593Smuzhiyun * Function:	in32r
632*4882a593Smuzhiyun * Description:	Input 32 bits and byte reverse
633*4882a593Smuzhiyun */
634*4882a593Smuzhiyun	.globl	in32r
635*4882a593Smuzhiyunin32r:
636*4882a593Smuzhiyun	lwbrx	r3,r0,r3
637*4882a593Smuzhiyun	blr
638*4882a593Smuzhiyun
639*4882a593Smuzhiyun/*
640*4882a593Smuzhiyun * void relocate_code (addr_sp, gd, addr_moni)
641*4882a593Smuzhiyun *
642*4882a593Smuzhiyun * This "function" does not return, instead it continues in RAM
643*4882a593Smuzhiyun * after relocating the monitor code.
644*4882a593Smuzhiyun *
645*4882a593Smuzhiyun * r3 = dest
646*4882a593Smuzhiyun * r4 = src
647*4882a593Smuzhiyun * r5 = length in bytes
648*4882a593Smuzhiyun * r6 = cachelinesize
649*4882a593Smuzhiyun */
650*4882a593Smuzhiyun	.globl	relocate_code
651*4882a593Smuzhiyunrelocate_code:
652*4882a593Smuzhiyun
653*4882a593Smuzhiyun	mr	r1,  r3		/* Set new stack pointer		*/
654*4882a593Smuzhiyun	mr	r9,  r4		/* Save copy of Global Data pointer	*/
655*4882a593Smuzhiyun	mr	r10, r5		/* Save copy of Destination Address	*/
656*4882a593Smuzhiyun
657*4882a593Smuzhiyun	GET_GOT
658*4882a593Smuzhiyun	mr	r3,  r5				/* Destination Address	*/
659*4882a593Smuzhiyun	lis	r4, CONFIG_SYS_MONITOR_BASE@h		/* Source      Address	*/
660*4882a593Smuzhiyun	ori	r4, r4, CONFIG_SYS_MONITOR_BASE@l
661*4882a593Smuzhiyun	lwz	r5, GOT(__init_end)
662*4882a593Smuzhiyun	sub	r5, r5, r4
663*4882a593Smuzhiyun	li	r6, CONFIG_SYS_CACHELINE_SIZE		/* Cache Line Size	*/
664*4882a593Smuzhiyun
665*4882a593Smuzhiyun	/*
666*4882a593Smuzhiyun	 * Fix GOT pointer:
667*4882a593Smuzhiyun	 *
668*4882a593Smuzhiyun	 * New GOT-PTR = (old GOT-PTR - CONFIG_SYS_MONITOR_BASE) + Destination Address
669*4882a593Smuzhiyun	 *
670*4882a593Smuzhiyun	 * Offset:
671*4882a593Smuzhiyun	 */
672*4882a593Smuzhiyun	sub	r15, r10, r4
673*4882a593Smuzhiyun
674*4882a593Smuzhiyun	/* First our own GOT */
675*4882a593Smuzhiyun	add	r12, r12, r15
676*4882a593Smuzhiyun	/* then the one used by the C code */
677*4882a593Smuzhiyun	add	r30, r30, r15
678*4882a593Smuzhiyun
679*4882a593Smuzhiyun	/*
680*4882a593Smuzhiyun	 * Now relocate code
681*4882a593Smuzhiyun	 */
682*4882a593Smuzhiyun	cmplw	cr1,r3,r4
683*4882a593Smuzhiyun	addi	r0,r5,3
684*4882a593Smuzhiyun	srwi.	r0,r0,2
685*4882a593Smuzhiyun	beq	cr1,4f		/* In place copy is not necessary	*/
686*4882a593Smuzhiyun	beq	7f		/* Protect against 0 count		*/
687*4882a593Smuzhiyun	mtctr	r0
688*4882a593Smuzhiyun	bge	cr1,2f
689*4882a593Smuzhiyun
690*4882a593Smuzhiyun	la	r8,-4(r4)
691*4882a593Smuzhiyun	la	r7,-4(r3)
692*4882a593Smuzhiyun1:	lwzu	r0,4(r8)
693*4882a593Smuzhiyun	stwu	r0,4(r7)
694*4882a593Smuzhiyun	bdnz	1b
695*4882a593Smuzhiyun	b	4f
696*4882a593Smuzhiyun
697*4882a593Smuzhiyun2:	slwi	r0,r0,2
698*4882a593Smuzhiyun	add	r8,r4,r0
699*4882a593Smuzhiyun	add	r7,r3,r0
700*4882a593Smuzhiyun3:	lwzu	r0,-4(r8)
701*4882a593Smuzhiyun	stwu	r0,-4(r7)
702*4882a593Smuzhiyun	bdnz	3b
703*4882a593Smuzhiyun/*
704*4882a593Smuzhiyun * Now flush the cache: note that we must start from a cache aligned
705*4882a593Smuzhiyun * address. Otherwise we might miss one cache line.
706*4882a593Smuzhiyun */
707*4882a593Smuzhiyun4:	cmpwi	r6,0
708*4882a593Smuzhiyun	add	r5,r3,r5
709*4882a593Smuzhiyun	beq	7f		/* Always flush prefetch queue in any case */
710*4882a593Smuzhiyun	subi	r0,r6,1
711*4882a593Smuzhiyun	andc	r3,r3,r0
712*4882a593Smuzhiyun	mr	r4,r3
713*4882a593Smuzhiyun5:	dcbst	0,r4
714*4882a593Smuzhiyun	add	r4,r4,r6
715*4882a593Smuzhiyun	cmplw	r4,r5
716*4882a593Smuzhiyun	blt	5b
717*4882a593Smuzhiyun	sync			/* Wait for all dcbst to complete on bus */
718*4882a593Smuzhiyun	mr	r4,r3
719*4882a593Smuzhiyun6:	icbi	0,r4
720*4882a593Smuzhiyun	add	r4,r4,r6
721*4882a593Smuzhiyun	cmplw	r4,r5
722*4882a593Smuzhiyun	blt	6b
723*4882a593Smuzhiyun7:	sync			/* Wait for all icbi to complete on bus */
724*4882a593Smuzhiyun	isync
725*4882a593Smuzhiyun
726*4882a593Smuzhiyun/*
727*4882a593Smuzhiyun * We are done. Do not return, instead branch to second part of board
728*4882a593Smuzhiyun * initialization, now running from RAM.
729*4882a593Smuzhiyun */
730*4882a593Smuzhiyun	addi	r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
731*4882a593Smuzhiyun	mtlr	r0
732*4882a593Smuzhiyun	blr
733*4882a593Smuzhiyun
734*4882a593Smuzhiyunin_ram:
735*4882a593Smuzhiyun	/*
736*4882a593Smuzhiyun	 * Relocation Function, r12 point to got2+0x8000
737*4882a593Smuzhiyun	 *
738*4882a593Smuzhiyun	 * Adjust got2 pointers, no need to check for 0, this code
739*4882a593Smuzhiyun	 * already puts a few entries in the table.
740*4882a593Smuzhiyun	 */
741*4882a593Smuzhiyun	li	r0,__got2_entries@sectoff@l
742*4882a593Smuzhiyun	la	r3,GOT(_GOT2_TABLE_)
743*4882a593Smuzhiyun	lwz	r11,GOT(_GOT2_TABLE_)
744*4882a593Smuzhiyun	mtctr	r0
745*4882a593Smuzhiyun	sub	r11,r3,r11
746*4882a593Smuzhiyun	addi	r3,r3,-4
747*4882a593Smuzhiyun1:	lwzu	r0,4(r3)
748*4882a593Smuzhiyun	cmpwi	r0,0
749*4882a593Smuzhiyun	beq-	2f
750*4882a593Smuzhiyun	add	r0,r0,r11
751*4882a593Smuzhiyun	stw	r0,0(r3)
752*4882a593Smuzhiyun2:	bdnz	1b
753*4882a593Smuzhiyun
754*4882a593Smuzhiyun	/*
755*4882a593Smuzhiyun	 * Now adjust the fixups and the pointers to the fixups
756*4882a593Smuzhiyun	 * in case we need to move ourselves again.
757*4882a593Smuzhiyun	 */
758*4882a593Smuzhiyun	li	r0,__fixup_entries@sectoff@l
759*4882a593Smuzhiyun	lwz	r3,GOT(_FIXUP_TABLE_)
760*4882a593Smuzhiyun	cmpwi	r0,0
761*4882a593Smuzhiyun	mtctr	r0
762*4882a593Smuzhiyun	addi	r3,r3,-4
763*4882a593Smuzhiyun	beq	4f
764*4882a593Smuzhiyun3:	lwzu	r4,4(r3)
765*4882a593Smuzhiyun	lwzux	r0,r4,r11
766*4882a593Smuzhiyun	cmpwi	r0,0
767*4882a593Smuzhiyun	add	r0,r0,r11
768*4882a593Smuzhiyun	stw	r4,0(r3)
769*4882a593Smuzhiyun	beq-	5f
770*4882a593Smuzhiyun	stw	r0,0(r4)
771*4882a593Smuzhiyun5:	bdnz	3b
772*4882a593Smuzhiyun4:
773*4882a593Smuzhiyun/* clear_bss: */
774*4882a593Smuzhiyun	/*
775*4882a593Smuzhiyun	 * Now clear BSS segment
776*4882a593Smuzhiyun	 */
777*4882a593Smuzhiyun	lwz	r3,GOT(__bss_start)
778*4882a593Smuzhiyun	lwz	r4,GOT(__bss_end)
779*4882a593Smuzhiyun
780*4882a593Smuzhiyun	cmplw	0, r3, r4
781*4882a593Smuzhiyun	beq	6f
782*4882a593Smuzhiyun
783*4882a593Smuzhiyun	li	r0, 0
784*4882a593Smuzhiyun5:
785*4882a593Smuzhiyun	stw	r0, 0(r3)
786*4882a593Smuzhiyun	addi	r3, r3, 4
787*4882a593Smuzhiyun	cmplw	0, r3, r4
788*4882a593Smuzhiyun	bne	5b
789*4882a593Smuzhiyun6:
790*4882a593Smuzhiyun	mr	r3, r9		/* Init Date pointer		*/
791*4882a593Smuzhiyun	mr	r4, r10		/* Destination Address		*/
792*4882a593Smuzhiyun	bl	board_init_r
793*4882a593Smuzhiyun
794*4882a593Smuzhiyun	/* not reached - end relocate_code */
795*4882a593Smuzhiyun/*-----------------------------------------------------------------------*/
796*4882a593Smuzhiyun
797*4882a593Smuzhiyun	/*
798*4882a593Smuzhiyun	 * Copy exception vector code to low memory
799*4882a593Smuzhiyun	 *
800*4882a593Smuzhiyun	 * r3: dest_addr
801*4882a593Smuzhiyun	 * r7: source address, r8: end address, r9: target address
802*4882a593Smuzhiyun	 */
803*4882a593Smuzhiyun	.globl	trap_init
804*4882a593Smuzhiyuntrap_init:
805*4882a593Smuzhiyun	mflr	r4			/* save link register		*/
806*4882a593Smuzhiyun	GET_GOT
807*4882a593Smuzhiyun	lwz	r7, GOT(_start)
808*4882a593Smuzhiyun	lwz	r8, GOT(_end_of_vectors)
809*4882a593Smuzhiyun
810*4882a593Smuzhiyun	li	r9, 0x100		/* reset vector always at 0x100 */
811*4882a593Smuzhiyun
812*4882a593Smuzhiyun	cmplw	0, r7, r8
813*4882a593Smuzhiyun	bgelr				/* return if r7>=r8 - just in case */
814*4882a593Smuzhiyun1:
815*4882a593Smuzhiyun	lwz	r0, 0(r7)
816*4882a593Smuzhiyun	stw	r0, 0(r9)
817*4882a593Smuzhiyun	addi	r7, r7, 4
818*4882a593Smuzhiyun	addi	r9, r9, 4
819*4882a593Smuzhiyun	cmplw	0, r7, r8
820*4882a593Smuzhiyun	bne	1b
821*4882a593Smuzhiyun
822*4882a593Smuzhiyun	/*
823*4882a593Smuzhiyun	 * relocate `hdlr' and `int_return' entries
824*4882a593Smuzhiyun	 */
825*4882a593Smuzhiyun	li	r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET
826*4882a593Smuzhiyun	li	r8, Alignment - _start + EXC_OFF_SYS_RESET
827*4882a593Smuzhiyun2:
828*4882a593Smuzhiyun	bl	trap_reloc
829*4882a593Smuzhiyun	addi	r7, r7, 0x100		/* next exception vector	*/
830*4882a593Smuzhiyun	cmplw	0, r7, r8
831*4882a593Smuzhiyun	blt	2b
832*4882a593Smuzhiyun
833*4882a593Smuzhiyun	li	r7, .L_Alignment - _start + EXC_OFF_SYS_RESET
834*4882a593Smuzhiyun	bl	trap_reloc
835*4882a593Smuzhiyun
836*4882a593Smuzhiyun	li	r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET
837*4882a593Smuzhiyun	bl	trap_reloc
838*4882a593Smuzhiyun
839*4882a593Smuzhiyun	li	r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET
840*4882a593Smuzhiyun	li	r8, SystemCall - _start + EXC_OFF_SYS_RESET
841*4882a593Smuzhiyun3:
842*4882a593Smuzhiyun	bl	trap_reloc
843*4882a593Smuzhiyun	addi	r7, r7, 0x100		/* next exception vector	*/
844*4882a593Smuzhiyun	cmplw	0, r7, r8
845*4882a593Smuzhiyun	blt	3b
846*4882a593Smuzhiyun
847*4882a593Smuzhiyun	li	r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET
848*4882a593Smuzhiyun	li	r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET
849*4882a593Smuzhiyun4:
850*4882a593Smuzhiyun	bl	trap_reloc
851*4882a593Smuzhiyun	addi	r7, r7, 0x100		/* next exception vector	*/
852*4882a593Smuzhiyun	cmplw	0, r7, r8
853*4882a593Smuzhiyun	blt	4b
854*4882a593Smuzhiyun
855*4882a593Smuzhiyun	/* enable execptions from RAM vectors */
856*4882a593Smuzhiyun	mfmsr	r7
857*4882a593Smuzhiyun	li	r8,MSR_IP
858*4882a593Smuzhiyun	andc	r7,r7,r8
859*4882a593Smuzhiyun	ori	r7,r7,MSR_ME		/* Enable Machine Check */
860*4882a593Smuzhiyun	mtmsr	r7
861*4882a593Smuzhiyun
862*4882a593Smuzhiyun	mtlr	r4			/* restore link register	*/
863*4882a593Smuzhiyun	blr
864*4882a593Smuzhiyun
865*4882a593Smuzhiyun.globl enable_ext_addr
866*4882a593Smuzhiyunenable_ext_addr:
867*4882a593Smuzhiyun	mfspr	r0, HID0
868*4882a593Smuzhiyun	lis	r0, (HID0_HIGH_BAT_EN | HID0_XBSEN | HID0_XAEN)@h
869*4882a593Smuzhiyun	ori	r0, r0, (HID0_HIGH_BAT_EN | HID0_XBSEN | HID0_XAEN)@l
870*4882a593Smuzhiyun	mtspr	HID0, r0
871*4882a593Smuzhiyun	sync
872*4882a593Smuzhiyun	isync
873*4882a593Smuzhiyun	blr
874*4882a593Smuzhiyun
875*4882a593Smuzhiyun#if (CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR)
876*4882a593Smuzhiyun.globl setup_ccsrbar
877*4882a593Smuzhiyunsetup_ccsrbar:
878*4882a593Smuzhiyun	/* Special sequence needed to update CCSRBAR itself */
879*4882a593Smuzhiyun	lis	r4, CONFIG_SYS_CCSRBAR_DEFAULT@h
880*4882a593Smuzhiyun	ori	r4, r4, CONFIG_SYS_CCSRBAR_DEFAULT@l
881*4882a593Smuzhiyun
882*4882a593Smuzhiyun	lis	r5, CONFIG_SYS_CCSRBAR_PHYS_LOW@h
883*4882a593Smuzhiyun	ori	r5, r5, CONFIG_SYS_CCSRBAR_PHYS_LOW@l
884*4882a593Smuzhiyun	srwi	r5,r5,12
885*4882a593Smuzhiyun	li	r6, CONFIG_SYS_CCSRBAR_PHYS_HIGH@l
886*4882a593Smuzhiyun	rlwimi	r5,r6,20,8,11
887*4882a593Smuzhiyun	stw	r5, 0(r4) /* Store physical value of CCSR */
888*4882a593Smuzhiyun	isync
889*4882a593Smuzhiyun
890*4882a593Smuzhiyun	lis	r5, CONFIG_SYS_TEXT_BASE@h
891*4882a593Smuzhiyun	ori	r5,r5,CONFIG_SYS_TEXT_BASE@l
892*4882a593Smuzhiyun	lwz	r5, 0(r5)
893*4882a593Smuzhiyun	isync
894*4882a593Smuzhiyun
895*4882a593Smuzhiyun	/* Use VA of CCSR to do read */
896*4882a593Smuzhiyun	lis	r3, CONFIG_SYS_CCSRBAR@h
897*4882a593Smuzhiyun	lwz	r5, CONFIG_SYS_CCSRBAR@l(r3)
898*4882a593Smuzhiyun	isync
899*4882a593Smuzhiyun
900*4882a593Smuzhiyun	blr
901*4882a593Smuzhiyun#endif
902*4882a593Smuzhiyun
903*4882a593Smuzhiyun#ifdef CONFIG_SYS_INIT_RAM_LOCK
904*4882a593Smuzhiyunlock_ram_in_cache:
905*4882a593Smuzhiyun	/* Allocate Initial RAM in data cache.
906*4882a593Smuzhiyun	 */
907*4882a593Smuzhiyun	lis	r3, (CONFIG_SYS_INIT_RAM_ADDR & ~31)@h
908*4882a593Smuzhiyun	ori	r3, r3, (CONFIG_SYS_INIT_RAM_ADDR & ~31)@l
909*4882a593Smuzhiyun	li	r4, ((CONFIG_SYS_INIT_RAM_SIZE & ~31) + \
910*4882a593Smuzhiyun		     (CONFIG_SYS_INIT_RAM_ADDR & 31) + 31) / 32
911*4882a593Smuzhiyun	mtctr	r4
912*4882a593Smuzhiyun1:
913*4882a593Smuzhiyun	dcbz	r0, r3
914*4882a593Smuzhiyun	addi	r3, r3, 32
915*4882a593Smuzhiyun	bdnz	1b
916*4882a593Smuzhiyun#if 1
917*4882a593Smuzhiyun/* Lock the data cache */
918*4882a593Smuzhiyun	mfspr	r0, HID0
919*4882a593Smuzhiyun	ori	r0, r0, 0x1000
920*4882a593Smuzhiyun	sync
921*4882a593Smuzhiyun	mtspr	HID0, r0
922*4882a593Smuzhiyun	sync
923*4882a593Smuzhiyun	blr
924*4882a593Smuzhiyun#endif
925*4882a593Smuzhiyun#if 0
926*4882a593Smuzhiyun	/* Lock the first way of the data cache */
927*4882a593Smuzhiyun	mfspr	r0, LDSTCR
928*4882a593Smuzhiyun	ori	r0, r0, 0x0080
929*4882a593Smuzhiyun#if defined(CONFIG_ALTIVEC)
930*4882a593Smuzhiyun	dssall
931*4882a593Smuzhiyun#endif
932*4882a593Smuzhiyun	sync
933*4882a593Smuzhiyun	mtspr	LDSTCR, r0
934*4882a593Smuzhiyun	sync
935*4882a593Smuzhiyun	isync
936*4882a593Smuzhiyun	blr
937*4882a593Smuzhiyun#endif
938*4882a593Smuzhiyun
939*4882a593Smuzhiyun.globl unlock_ram_in_cache
940*4882a593Smuzhiyununlock_ram_in_cache:
941*4882a593Smuzhiyun	/* invalidate the INIT_RAM section */
942*4882a593Smuzhiyun	lis	r3, (CONFIG_SYS_INIT_RAM_ADDR & ~31)@h
943*4882a593Smuzhiyun	ori	r3, r3, (CONFIG_SYS_INIT_RAM_ADDR & ~31)@l
944*4882a593Smuzhiyun	li	r4, ((CONFIG_SYS_INIT_RAM_SIZE & ~31) + \
945*4882a593Smuzhiyun		     (CONFIG_SYS_INIT_RAM_ADDR & 31) + 31) / 32
946*4882a593Smuzhiyun	mtctr	r4
947*4882a593Smuzhiyun1:	icbi	r0, r3
948*4882a593Smuzhiyun	addi	r3, r3, 32
949*4882a593Smuzhiyun	bdnz	1b
950*4882a593Smuzhiyun	sync			/* Wait for all icbi to complete on bus */
951*4882a593Smuzhiyun	isync
952*4882a593Smuzhiyun#if 1
953*4882a593Smuzhiyun/* Unlock the data cache and invalidate it */
954*4882a593Smuzhiyun	mfspr	r0, HID0
955*4882a593Smuzhiyun	li	r3,0x1000
956*4882a593Smuzhiyun	andc	r0,r0,r3
957*4882a593Smuzhiyun	li	r3,0x0400
958*4882a593Smuzhiyun	or	r0,r0,r3
959*4882a593Smuzhiyun	sync
960*4882a593Smuzhiyun	mtspr	HID0, r0
961*4882a593Smuzhiyun	sync
962*4882a593Smuzhiyun	blr
963*4882a593Smuzhiyun#endif
964*4882a593Smuzhiyun#if 0
965*4882a593Smuzhiyun	/* Unlock the first way of the data cache */
966*4882a593Smuzhiyun	mfspr	r0, LDSTCR
967*4882a593Smuzhiyun	li	r3,0x0080
968*4882a593Smuzhiyun	andc	r0,r0,r3
969*4882a593Smuzhiyun#ifdef CONFIG_ALTIVEC
970*4882a593Smuzhiyun	dssall
971*4882a593Smuzhiyun#endif
972*4882a593Smuzhiyun	sync
973*4882a593Smuzhiyun	mtspr	LDSTCR, r0
974*4882a593Smuzhiyun	sync
975*4882a593Smuzhiyun	isync
976*4882a593Smuzhiyun	li	r3,0x0400
977*4882a593Smuzhiyun	or	r0,r0,r3
978*4882a593Smuzhiyun	sync
979*4882a593Smuzhiyun	mtspr	HID0, r0
980*4882a593Smuzhiyun	sync
981*4882a593Smuzhiyun	blr
982*4882a593Smuzhiyun#endif
983*4882a593Smuzhiyun#endif
984