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