xref: /openbmc/linux/arch/parisc/kernel/head.S (revision 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2)
1*1da177e4SLinus Torvalds/* This file is subject to the terms and conditions of the GNU General Public
2*1da177e4SLinus Torvalds * License.  See the file "COPYING" in the main directory of this archive
3*1da177e4SLinus Torvalds * for more details.
4*1da177e4SLinus Torvalds *
5*1da177e4SLinus Torvalds * Copyright (C) 1999 by Helge Deller
6*1da177e4SLinus Torvalds * Copyright 1999 SuSE GmbH (Philipp Rumpf)
7*1da177e4SLinus Torvalds * Copyright 1999 Philipp Rumpf (prumpf@tux.org)
8*1da177e4SLinus Torvalds * Copyright 2000 Hewlett Packard (Paul Bame, bame@puffin.external.hp.com)
9*1da177e4SLinus Torvalds * Copyright (C) 2001 Grant Grundler (Hewlett Packard)
10*1da177e4SLinus Torvalds * Copyright (C) 2004 Kyle McMartin <kyle@debian.org>
11*1da177e4SLinus Torvalds *
12*1da177e4SLinus Torvalds * Initial Version 04-23-1999 by Helge Deller <deller@gmx.de>
13*1da177e4SLinus Torvalds */
14*1da177e4SLinus Torvalds
15*1da177e4SLinus Torvalds#include <linux/autoconf.h>	/* for CONFIG_SMP */
16*1da177e4SLinus Torvalds
17*1da177e4SLinus Torvalds#include <asm/offsets.h>
18*1da177e4SLinus Torvalds#include <asm/psw.h>
19*1da177e4SLinus Torvalds#include <asm/pdc.h>
20*1da177e4SLinus Torvalds
21*1da177e4SLinus Torvalds#include <asm/assembly.h>
22*1da177e4SLinus Torvalds#include <asm/pgtable.h>
23*1da177e4SLinus Torvalds
24*1da177e4SLinus Torvalds	.level	LEVEL
25*1da177e4SLinus Torvalds
26*1da177e4SLinus Torvalds	.data
27*1da177e4SLinus Torvalds
28*1da177e4SLinus Torvalds	.export boot_args
29*1da177e4SLinus Torvaldsboot_args:
30*1da177e4SLinus Torvalds	.word 0 /* arg0 */
31*1da177e4SLinus Torvalds	.word 0 /* arg1 */
32*1da177e4SLinus Torvalds	.word 0 /* arg2 */
33*1da177e4SLinus Torvalds	.word 0 /* arg3 */
34*1da177e4SLinus Torvalds
35*1da177e4SLinus Torvalds	.text
36*1da177e4SLinus Torvalds	.align	4
37*1da177e4SLinus Torvalds	.import init_thread_union,data
38*1da177e4SLinus Torvalds	.import fault_vector_20,code    /* IVA parisc 2.0 32 bit */
39*1da177e4SLinus Torvalds#ifndef __LP64__
40*1da177e4SLinus Torvalds        .import fault_vector_11,code    /* IVA parisc 1.1 32 bit */
41*1da177e4SLinus Torvalds	.import	$global$		/* forward declaration */
42*1da177e4SLinus Torvalds#endif /*!LP64*/
43*1da177e4SLinus Torvalds	.export stext
44*1da177e4SLinus Torvalds	.export _stext,data		/* Kernel want it this way! */
45*1da177e4SLinus Torvalds_stext:
46*1da177e4SLinus Torvaldsstext:
47*1da177e4SLinus Torvalds	.proc
48*1da177e4SLinus Torvalds	.callinfo
49*1da177e4SLinus Torvalds
50*1da177e4SLinus Torvalds	/* Make sure sr4-sr7 are set to zero for the kernel address space */
51*1da177e4SLinus Torvalds	mtsp	%r0,%sr4
52*1da177e4SLinus Torvalds	mtsp	%r0,%sr5
53*1da177e4SLinus Torvalds	mtsp	%r0,%sr6
54*1da177e4SLinus Torvalds	mtsp	%r0,%sr7
55*1da177e4SLinus Torvalds
56*1da177e4SLinus Torvalds	/* Clear BSS (shouldn't the boot loader do this?) */
57*1da177e4SLinus Torvalds
58*1da177e4SLinus Torvalds	.import __bss_start,data
59*1da177e4SLinus Torvalds	.import __bss_stop,data
60*1da177e4SLinus Torvalds
61*1da177e4SLinus Torvalds	load32		PA(__bss_start),%r3
62*1da177e4SLinus Torvalds	load32		PA(__bss_stop),%r4
63*1da177e4SLinus Torvalds$bss_loop:
64*1da177e4SLinus Torvalds	cmpb,<<,n       %r3,%r4,$bss_loop
65*1da177e4SLinus Torvalds	stw,ma          %r0,4(%r3)
66*1da177e4SLinus Torvalds
67*1da177e4SLinus Torvalds	/* Save away the arguments the boot loader passed in (32 bit args) */
68*1da177e4SLinus Torvalds	load32		PA(boot_args),%r1
69*1da177e4SLinus Torvalds	stw,ma          %arg0,4(%r1)
70*1da177e4SLinus Torvalds	stw,ma          %arg1,4(%r1)
71*1da177e4SLinus Torvalds	stw,ma          %arg2,4(%r1)
72*1da177e4SLinus Torvalds	stw,ma          %arg3,4(%r1)
73*1da177e4SLinus Torvalds
74*1da177e4SLinus Torvalds	/* Initialize startup VM. Just map first 8/16 MB of memory */
75*1da177e4SLinus Torvalds	load32		PA(swapper_pg_dir),%r4
76*1da177e4SLinus Torvalds	mtctl		%r4,%cr24	/* Initialize kernel root pointer */
77*1da177e4SLinus Torvalds	mtctl		%r4,%cr25	/* Initialize user root pointer */
78*1da177e4SLinus Torvalds
79*1da177e4SLinus Torvalds#ifdef __LP64__
80*1da177e4SLinus Torvalds	/* Set pmd in pgd */
81*1da177e4SLinus Torvalds	load32		PA(pmd0),%r5
82*1da177e4SLinus Torvalds	shrd            %r5,PxD_VALUE_SHIFT,%r3
83*1da177e4SLinus Torvalds        ldo             (PxD_FLAG_PRESENT+PxD_FLAG_VALID)(%r3),%r3
84*1da177e4SLinus Torvalds	stw		%r3,ASM_PGD_ENTRY*ASM_PGD_ENTRY_SIZE(%r4)
85*1da177e4SLinus Torvalds	ldo		ASM_PMD_ENTRY*ASM_PMD_ENTRY_SIZE(%r5),%r4
86*1da177e4SLinus Torvalds#else
87*1da177e4SLinus Torvalds	/* 2-level page table, so pmd == pgd */
88*1da177e4SLinus Torvalds        ldo             ASM_PGD_ENTRY*ASM_PGD_ENTRY_SIZE(%r4),%r4
89*1da177e4SLinus Torvalds#endif
90*1da177e4SLinus Torvalds
91*1da177e4SLinus Torvalds	/* Fill in pmd with enough pte directories */
92*1da177e4SLinus Torvalds	load32		PA(pg0),%r1
93*1da177e4SLinus Torvalds	SHRREG		%r1,PxD_VALUE_SHIFT,%r3
94*1da177e4SLinus Torvalds	ldo		(PxD_FLAG_PRESENT+PxD_FLAG_VALID)(%r3),%r3
95*1da177e4SLinus Torvalds
96*1da177e4SLinus Torvalds	ldi		ASM_PT_INITIAL,%r1
97*1da177e4SLinus Torvalds
98*1da177e4SLinus Torvalds1:
99*1da177e4SLinus Torvalds	stw		%r3,0(%r4)
100*1da177e4SLinus Torvalds	ldo		(ASM_PAGE_SIZE >> PxD_VALUE_SHIFT)(%r3),%r3
101*1da177e4SLinus Torvalds	addib,>		-1,%r1,1b
102*1da177e4SLinus Torvalds#ifdef __LP64__
103*1da177e4SLinus Torvalds	ldo             ASM_PMD_ENTRY_SIZE(%r4),%r4
104*1da177e4SLinus Torvalds#else
105*1da177e4SLinus Torvalds	ldo             ASM_PGD_ENTRY_SIZE(%r4),%r4
106*1da177e4SLinus Torvalds#endif
107*1da177e4SLinus Torvalds
108*1da177e4SLinus Torvalds
109*1da177e4SLinus Torvalds	/* Now initialize the PTEs themselves */
110*1da177e4SLinus Torvalds	ldo		_PAGE_KERNEL(%r0),%r3 /* Hardwired 0 phys addr start */
111*1da177e4SLinus Torvalds	load32		PA(pg0),%r1
112*1da177e4SLinus Torvalds
113*1da177e4SLinus Torvalds$pgt_fill_loop:
114*1da177e4SLinus Torvalds	STREGM          %r3,ASM_PTE_ENTRY_SIZE(%r1)
115*1da177e4SLinus Torvalds	ldo		ASM_PAGE_SIZE(%r3),%r3
116*1da177e4SLinus Torvalds	bb,>=		%r3,31-KERNEL_INITIAL_ORDER,$pgt_fill_loop
117*1da177e4SLinus Torvalds	nop
118*1da177e4SLinus Torvalds
119*1da177e4SLinus Torvalds	/* Load the return address...er...crash 'n burn */
120*1da177e4SLinus Torvalds	copy		%r0,%r2
121*1da177e4SLinus Torvalds
122*1da177e4SLinus Torvalds	/* And the RFI Target address too */
123*1da177e4SLinus Torvalds	load32		start_kernel,%r11
124*1da177e4SLinus Torvalds
125*1da177e4SLinus Torvalds	/* And the initial task pointer */
126*1da177e4SLinus Torvalds	load32		init_thread_union,%r6
127*1da177e4SLinus Torvalds	mtctl           %r6,%cr30
128*1da177e4SLinus Torvalds
129*1da177e4SLinus Torvalds	/* And the stack pointer too */
130*1da177e4SLinus Torvalds	ldo             THREAD_SZ_ALGN(%r6),%sp
131*1da177e4SLinus Torvalds
132*1da177e4SLinus Torvalds	/* And the interrupt stack */
133*1da177e4SLinus Torvalds	load32		interrupt_stack,%r6
134*1da177e4SLinus Torvalds	mtctl           %r6,%cr31
135*1da177e4SLinus Torvalds
136*1da177e4SLinus Torvalds#ifdef CONFIG_SMP
137*1da177e4SLinus Torvalds	/* Set the smp rendevous address into page zero.
138*1da177e4SLinus Torvalds	** It would be safer to do this in init_smp_config() but
139*1da177e4SLinus Torvalds	** it's just way easier to deal with here because
140*1da177e4SLinus Torvalds	** of 64-bit function ptrs and the address is local to this file.
141*1da177e4SLinus Torvalds	*/
142*1da177e4SLinus Torvalds	load32		PA(smp_slave_stext),%r10
143*1da177e4SLinus Torvalds	stw		%r10,0x10(%r0)	/* MEM_RENDEZ */
144*1da177e4SLinus Torvalds	stw		%r0,0x28(%r0)	/* MEM_RENDEZ_HI - assume addr < 4GB */
145*1da177e4SLinus Torvalds
146*1da177e4SLinus Torvalds	/* FALLTHROUGH */
147*1da177e4SLinus Torvalds	.procend
148*1da177e4SLinus Torvalds
149*1da177e4SLinus Torvalds	/*
150*1da177e4SLinus Torvalds	** Code Common to both Monarch and Slave processors.
151*1da177e4SLinus Torvalds	** Entry:
152*1da177e4SLinus Torvalds	**
153*1da177e4SLinus Torvalds	**  1.1:
154*1da177e4SLinus Torvalds	**    %r11 must contain RFI target address.
155*1da177e4SLinus Torvalds	**    %r25/%r26 args to pass to target function
156*1da177e4SLinus Torvalds	**    %r2  in case rfi target decides it didn't like something
157*1da177e4SLinus Torvalds	**
158*1da177e4SLinus Torvalds	**  2.0w:
159*1da177e4SLinus Torvalds	**    %r3  PDCE_PROC address
160*1da177e4SLinus Torvalds	**    %r11 RFI target address
161*1da177e4SLinus Torvalds	**
162*1da177e4SLinus Torvalds	** Caller must init: SR4-7, %sp, %r10, %cr24/25,
163*1da177e4SLinus Torvalds	*/
164*1da177e4SLinus Torvaldscommon_stext:
165*1da177e4SLinus Torvalds	.proc
166*1da177e4SLinus Torvalds	.callinfo
167*1da177e4SLinus Torvalds#else
168*1da177e4SLinus Torvalds	/* Clear PDC entry point - we won't use it */
169*1da177e4SLinus Torvalds	stw		%r0,0x10(%r0)	/* MEM_RENDEZ */
170*1da177e4SLinus Torvalds	stw		%r0,0x28(%r0)	/* MEM_RENDEZ_HI */
171*1da177e4SLinus Torvalds#endif /*CONFIG_SMP*/
172*1da177e4SLinus Torvalds
173*1da177e4SLinus Torvalds#ifdef __LP64__
174*1da177e4SLinus Torvalds	tophys_r1	%sp
175*1da177e4SLinus Torvalds
176*1da177e4SLinus Torvalds	/* Save the rfi target address */
177*1da177e4SLinus Torvalds	ldd             TI_TASK-THREAD_SZ_ALGN(%sp), %r10
178*1da177e4SLinus Torvalds	tophys_r1       %r10
179*1da177e4SLinus Torvalds	std             %r11,  TASK_PT_GR11(%r10)
180*1da177e4SLinus Torvalds	/* Switch to wide mode Superdome doesn't support narrow PDC
181*1da177e4SLinus Torvalds	** calls.
182*1da177e4SLinus Torvalds	*/
183*1da177e4SLinus Torvalds1:	mfia            %rp             /* clear upper part of pcoq */
184*1da177e4SLinus Torvalds	ldo             2f-1b(%rp),%rp
185*1da177e4SLinus Torvalds	depdi           0,31,32,%rp
186*1da177e4SLinus Torvalds	bv              (%rp)
187*1da177e4SLinus Torvalds	ssm             PSW_SM_W,%r0
188*1da177e4SLinus Torvalds
189*1da177e4SLinus Torvalds        /* Set Wide mode as the "Default" (eg for traps)
190*1da177e4SLinus Torvalds        ** First trap occurs *right* after (or part of) rfi for slave CPUs.
191*1da177e4SLinus Torvalds        ** Someday, palo might not do this for the Monarch either.
192*1da177e4SLinus Torvalds        */
193*1da177e4SLinus Torvalds2:
194*1da177e4SLinus Torvalds#define MEM_PDC_LO 0x388
195*1da177e4SLinus Torvalds#define MEM_PDC_HI 0x35C
196*1da177e4SLinus Torvalds	ldw             MEM_PDC_LO(%r0),%r3
197*1da177e4SLinus Torvalds	ldw             MEM_PDC_HI(%r0),%r6
198*1da177e4SLinus Torvalds	depd            %r6, 31, 32, %r3        /* move to upper word */
199*1da177e4SLinus Torvalds
200*1da177e4SLinus Torvalds	ldo             PDC_PSW(%r0),%arg0              /* 21 */
201*1da177e4SLinus Torvalds	ldo             PDC_PSW_SET_DEFAULTS(%r0),%arg1 /* 2 */
202*1da177e4SLinus Torvalds	ldo             PDC_PSW_WIDE_BIT(%r0),%arg2     /* 2 */
203*1da177e4SLinus Torvalds	load32          PA(stext_pdc_ret), %rp
204*1da177e4SLinus Torvalds	bv              (%r3)
205*1da177e4SLinus Torvalds	copy            %r0,%arg3
206*1da177e4SLinus Torvalds
207*1da177e4SLinus Torvaldsstext_pdc_ret:
208*1da177e4SLinus Torvalds	/* restore rfi target address*/
209*1da177e4SLinus Torvalds	ldd             TI_TASK-THREAD_SZ_ALGN(%sp), %r10
210*1da177e4SLinus Torvalds	tophys_r1       %r10
211*1da177e4SLinus Torvalds	ldd             TASK_PT_GR11(%r10), %r11
212*1da177e4SLinus Torvalds	tovirt_r1       %sp
213*1da177e4SLinus Torvalds#endif
214*1da177e4SLinus Torvalds
215*1da177e4SLinus Torvalds	/* PARANOID: clear user scratch/user space SR's */
216*1da177e4SLinus Torvalds	mtsp	%r0,%sr0
217*1da177e4SLinus Torvalds	mtsp	%r0,%sr1
218*1da177e4SLinus Torvalds	mtsp	%r0,%sr2
219*1da177e4SLinus Torvalds	mtsp	%r0,%sr3
220*1da177e4SLinus Torvalds
221*1da177e4SLinus Torvalds	/* Initialize Protection Registers */
222*1da177e4SLinus Torvalds	mtctl	%r0,%cr8
223*1da177e4SLinus Torvalds	mtctl	%r0,%cr9
224*1da177e4SLinus Torvalds	mtctl	%r0,%cr12
225*1da177e4SLinus Torvalds	mtctl	%r0,%cr13
226*1da177e4SLinus Torvalds
227*1da177e4SLinus Torvalds	/* Prepare to RFI! Man all the cannons! */
228*1da177e4SLinus Torvalds
229*1da177e4SLinus Torvalds	/* Initialize the global data pointer */
230*1da177e4SLinus Torvalds	loadgp
231*1da177e4SLinus Torvalds
232*1da177e4SLinus Torvalds	/* Set up our interrupt table.  HPMCs might not work after this!
233*1da177e4SLinus Torvalds	 *
234*1da177e4SLinus Torvalds	 * We need to install the correct iva for PA1.1 or PA2.0. The
235*1da177e4SLinus Torvalds	 * following short sequence of instructions can determine this
236*1da177e4SLinus Torvalds	 * (without being illegal on a PA1.1 machine).
237*1da177e4SLinus Torvalds	 */
238*1da177e4SLinus Torvalds#ifndef __LP64__
239*1da177e4SLinus Torvalds	ldi		32,%r10
240*1da177e4SLinus Torvalds	mtctl		%r10,%cr11
241*1da177e4SLinus Torvalds	.level 2.0
242*1da177e4SLinus Torvalds	mfctl,w		%cr11,%r10
243*1da177e4SLinus Torvalds	.level 1.1
244*1da177e4SLinus Torvalds	comib,<>,n	0,%r10,$is_pa20
245*1da177e4SLinus Torvalds	ldil		L%PA(fault_vector_11),%r10
246*1da177e4SLinus Torvalds	b		$install_iva
247*1da177e4SLinus Torvalds	ldo		R%PA(fault_vector_11)(%r10),%r10
248*1da177e4SLinus Torvalds
249*1da177e4SLinus Torvalds$is_pa20:
250*1da177e4SLinus Torvalds	.level		LEVEL /* restore 1.1 || 2.0w */
251*1da177e4SLinus Torvalds#endif /*!LP64*/
252*1da177e4SLinus Torvalds	load32		PA(fault_vector_20),%r10
253*1da177e4SLinus Torvalds
254*1da177e4SLinus Torvalds$install_iva:
255*1da177e4SLinus Torvalds	mtctl		%r10,%cr14
256*1da177e4SLinus Torvalds
257*1da177e4SLinus Torvalds#ifdef __LP64__
258*1da177e4SLinus Torvalds	b		aligned_rfi
259*1da177e4SLinus Torvalds	nop
260*1da177e4SLinus Torvalds
261*1da177e4SLinus Torvalds	.align          256
262*1da177e4SLinus Torvaldsaligned_rfi:
263*1da177e4SLinus Torvalds	ssm             0,0
264*1da177e4SLinus Torvalds	nop             /* 1 */
265*1da177e4SLinus Torvalds	nop             /* 2 */
266*1da177e4SLinus Torvalds	nop             /* 3 */
267*1da177e4SLinus Torvalds	nop             /* 4 */
268*1da177e4SLinus Torvalds	nop             /* 5 */
269*1da177e4SLinus Torvalds	nop             /* 6 */
270*1da177e4SLinus Torvalds	nop             /* 7 */
271*1da177e4SLinus Torvalds	nop             /* 8 */
272*1da177e4SLinus Torvalds#endif
273*1da177e4SLinus Torvalds
274*1da177e4SLinus Torvalds#ifdef __LP64__ /* move to psw.h? */
275*1da177e4SLinus Torvalds#define		PSW_BITS	PSW_Q+PSW_I+PSW_D+PSW_P+PSW_R
276*1da177e4SLinus Torvalds#else
277*1da177e4SLinus Torvalds#define		PSW_BITS	PSW_SM_Q
278*1da177e4SLinus Torvalds#endif
279*1da177e4SLinus Torvalds
280*1da177e4SLinus Torvalds$rfi:
281*1da177e4SLinus Torvalds	/* turn off troublesome PSW bits */
282*1da177e4SLinus Torvalds	rsm		PSW_BITS,%r0
283*1da177e4SLinus Torvalds
284*1da177e4SLinus Torvalds	/* kernel PSW:
285*1da177e4SLinus Torvalds	 *  - no interruptions except HPMC and TOC (which are handled by PDC)
286*1da177e4SLinus Torvalds	 *  - Q bit set (IODC / PDC interruptions)
287*1da177e4SLinus Torvalds	 *  - big-endian
288*1da177e4SLinus Torvalds	 *  - virtually mapped
289*1da177e4SLinus Torvalds	 */
290*1da177e4SLinus Torvalds	load32		KERNEL_PSW,%r10
291*1da177e4SLinus Torvalds	mtctl		%r10,%ipsw
292*1da177e4SLinus Torvalds
293*1da177e4SLinus Torvalds	/* Set the space pointers for the post-RFI world
294*1da177e4SLinus Torvalds	** Clear the two-level IIA Space Queue, effectively setting
295*1da177e4SLinus Torvalds	** Kernel space.
296*1da177e4SLinus Torvalds	*/
297*1da177e4SLinus Torvalds	mtctl		%r0,%cr17	/* Clear IIASQ tail */
298*1da177e4SLinus Torvalds	mtctl		%r0,%cr17	/* Clear IIASQ head */
299*1da177e4SLinus Torvalds
300*1da177e4SLinus Torvalds	/* Load RFI target into PC queue */
301*1da177e4SLinus Torvalds	mtctl		%r11,%cr18	/* IIAOQ head */
302*1da177e4SLinus Torvalds	ldo		4(%r11),%r11
303*1da177e4SLinus Torvalds	mtctl		%r11,%cr18	/* IIAOQ tail */
304*1da177e4SLinus Torvalds
305*1da177e4SLinus Torvalds	/* Jump to hyperspace */
306*1da177e4SLinus Torvalds	rfi
307*1da177e4SLinus Torvalds	nop
308*1da177e4SLinus Torvalds
309*1da177e4SLinus Torvalds	.procend
310*1da177e4SLinus Torvalds
311*1da177e4SLinus Torvalds#ifdef CONFIG_SMP
312*1da177e4SLinus Torvalds
313*1da177e4SLinus Torvalds	.import smp_init_current_idle_task,data
314*1da177e4SLinus Torvalds	.import	smp_callin,code
315*1da177e4SLinus Torvalds
316*1da177e4SLinus Torvalds#ifndef __LP64__
317*1da177e4SLinus Torvaldssmp_callin_rtn:
318*1da177e4SLinus Torvalds        .proc
319*1da177e4SLinus Torvalds	.callinfo
320*1da177e4SLinus Torvalds	break	1,1		/*  Break if returned from start_secondary */
321*1da177e4SLinus Torvalds	nop
322*1da177e4SLinus Torvalds	nop
323*1da177e4SLinus Torvalds        .procend
324*1da177e4SLinus Torvalds#endif /*!LP64*/
325*1da177e4SLinus Torvalds
326*1da177e4SLinus Torvalds/***************************************************************************
327*1da177e4SLinus Torvalds* smp_slave_stext is executed by all non-monarch Processors when the Monarch
328*1da177e4SLinus Torvalds* pokes the slave CPUs in smp.c:smp_boot_cpus().
329*1da177e4SLinus Torvalds*
330*1da177e4SLinus Torvalds* Once here, registers values are initialized in order to branch to virtual
331*1da177e4SLinus Torvalds* mode. Once all available/eligible CPUs are in virtual mode, all are
332*1da177e4SLinus Torvalds* released and start out by executing their own idle task.
333*1da177e4SLinus Torvalds*****************************************************************************/
334*1da177e4SLinus Torvaldssmp_slave_stext:
335*1da177e4SLinus Torvalds        .proc
336*1da177e4SLinus Torvalds	.callinfo
337*1da177e4SLinus Torvalds
338*1da177e4SLinus Torvalds	/*
339*1da177e4SLinus Torvalds	** Initialize Space registers
340*1da177e4SLinus Torvalds	*/
341*1da177e4SLinus Torvalds	mtsp	   %r0,%sr4
342*1da177e4SLinus Torvalds	mtsp	   %r0,%sr5
343*1da177e4SLinus Torvalds	mtsp	   %r0,%sr6
344*1da177e4SLinus Torvalds	mtsp	   %r0,%sr7
345*1da177e4SLinus Torvalds
346*1da177e4SLinus Torvalds	/*  Initialize the SP - monarch sets up smp_init_current_idle_task */
347*1da177e4SLinus Torvalds	load32		PA(smp_init_current_idle_task),%sp
348*1da177e4SLinus Torvalds	LDREG		0(%sp),%sp	/* load task address */
349*1da177e4SLinus Torvalds	tophys_r1	%sp
350*1da177e4SLinus Torvalds	LDREG		TASK_THREAD_INFO(%sp),%sp
351*1da177e4SLinus Torvalds	mtctl           %sp,%cr30       /* store in cr30 */
352*1da177e4SLinus Torvalds	ldo             THREAD_SZ_ALGN(%sp),%sp
353*1da177e4SLinus Torvalds
354*1da177e4SLinus Torvalds	/* point CPU to kernel page tables */
355*1da177e4SLinus Torvalds	load32		PA(swapper_pg_dir),%r4
356*1da177e4SLinus Torvalds	mtctl		%r4,%cr24	/* Initialize kernel root pointer */
357*1da177e4SLinus Torvalds	mtctl		%r4,%cr25	/* Initialize user root pointer */
358*1da177e4SLinus Torvalds
359*1da177e4SLinus Torvalds#ifdef __LP64__
360*1da177e4SLinus Torvalds	/* Setup PDCE_PROC entry */
361*1da177e4SLinus Torvalds	copy            %arg0,%r3
362*1da177e4SLinus Torvalds#else
363*1da177e4SLinus Torvalds	/* Load RFI *return* address in case smp_callin bails */
364*1da177e4SLinus Torvalds	load32		smp_callin_rtn,%r2
365*1da177e4SLinus Torvalds#endif
366*1da177e4SLinus Torvalds
367*1da177e4SLinus Torvalds	/* Load RFI target address.  */
368*1da177e4SLinus Torvalds	load32		smp_callin,%r11
369*1da177e4SLinus Torvalds
370*1da177e4SLinus Torvalds	/* ok...common code can handle the rest */
371*1da177e4SLinus Torvalds	b		common_stext
372*1da177e4SLinus Torvalds	nop
373*1da177e4SLinus Torvalds
374*1da177e4SLinus Torvalds	.procend
375*1da177e4SLinus Torvalds#endif /* CONFIG_SMP */
376*1da177e4SLinus Torvalds#ifndef __LP64__
377*1da177e4SLinus Torvalds	.data
378*1da177e4SLinus Torvalds
379*1da177e4SLinus Torvalds	.align	4
380*1da177e4SLinus Torvalds	.export	$global$,data
381*1da177e4SLinus Torvalds
382*1da177e4SLinus Torvalds	.type	$global$,@object
383*1da177e4SLinus Torvalds	.size	$global$,4
384*1da177e4SLinus Torvalds$global$:
385*1da177e4SLinus Torvalds	.word 0
386*1da177e4SLinus Torvalds#endif /*!LP64*/
387