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