xref: /linux/arch/parisc/kernel/head.S (revision 0ea5c948cb64bab5bc7a5516774eb8536f05aa0d)
11da177e4SLinus Torvalds/* This file is subject to the terms and conditions of the GNU General Public
21da177e4SLinus Torvalds * License.  See the file "COPYING" in the main directory of this archive
31da177e4SLinus Torvalds * for more details.
41da177e4SLinus Torvalds *
58e9e9844SHelge Deller * Copyright (C) 1999-2007 by Helge Deller <deller@gmx.de>
61da177e4SLinus Torvalds * Copyright 1999 SuSE GmbH (Philipp Rumpf)
71da177e4SLinus Torvalds * Copyright 1999 Philipp Rumpf (prumpf@tux.org)
81da177e4SLinus Torvalds * Copyright 2000 Hewlett Packard (Paul Bame, bame@puffin.external.hp.com)
91da177e4SLinus Torvalds * Copyright (C) 2001 Grant Grundler (Hewlett Packard)
101da177e4SLinus Torvalds * Copyright (C) 2004 Kyle McMartin <kyle@debian.org>
111da177e4SLinus Torvalds *
121da177e4SLinus Torvalds * Initial Version 04-23-1999 by Helge Deller <deller@gmx.de>
131da177e4SLinus Torvalds */
141da177e4SLinus Torvalds
150013a854SSam Ravnborg#include <asm/asm-offsets.h>
161da177e4SLinus Torvalds#include <asm/psw.h>
171da177e4SLinus Torvalds#include <asm/pdc.h>
181da177e4SLinus Torvalds
191da177e4SLinus Torvalds#include <asm/assembly.h>
201da177e4SLinus Torvalds
218e9e9844SHelge Deller#include <linux/linkage.h>
220c634cc6SHelge Deller#include <linux/init.h>
2365fddcfcSMike Rapoport#include <linux/pgtable.h>
248e9e9844SHelge Deller
25591d2108SHelge Deller	.level	1.1
261da177e4SLinus Torvalds
270c634cc6SHelge Deller	__INITDATA
288e9e9844SHelge DellerENTRY(boot_args)
291da177e4SLinus Torvalds	.word 0 /* arg0 */
301da177e4SLinus Torvalds	.word 0 /* arg1 */
311da177e4SLinus Torvalds	.word 0 /* arg2 */
321da177e4SLinus Torvalds	.word 0 /* arg3 */
338e9e9844SHelge DellerEND(boot_args)
341da177e4SLinus Torvalds
351138a72cSKyle McMartin	__HEAD
361138a72cSKyle McMartin
371da177e4SLinus Torvalds	.align	4
382214c0e7SHelge Deller	.import init_task,data
392214c0e7SHelge Deller	.import init_stack,data
401da177e4SLinus Torvalds	.import fault_vector_20,code    /* IVA parisc 2.0 32 bit */
41413059f2SGrant Grundler#ifndef CONFIG_64BIT
421da177e4SLinus Torvalds        .import fault_vector_11,code    /* IVA parisc 1.1 32 bit */
431da177e4SLinus Torvalds	.import	$global$		/* forward declaration */
44413059f2SGrant Grundler#endif /*!CONFIG_64BIT*/
45161bd3bfSHelge DellerENTRY(parisc_kernel_start)
461da177e4SLinus Torvalds	.proc
471da177e4SLinus Torvalds	.callinfo
481da177e4SLinus Torvalds
491da177e4SLinus Torvalds	/* Make sure sr4-sr7 are set to zero for the kernel address space */
501da177e4SLinus Torvalds	mtsp	%r0,%sr4
511da177e4SLinus Torvalds	mtsp	%r0,%sr5
521da177e4SLinus Torvalds	mtsp	%r0,%sr6
531da177e4SLinus Torvalds	mtsp	%r0,%sr7
541da177e4SLinus Torvalds
551da177e4SLinus Torvalds	/* Clear BSS (shouldn't the boot loader do this?) */
561da177e4SLinus Torvalds
571da177e4SLinus Torvalds	.import __bss_start,data
581da177e4SLinus Torvalds	.import __bss_stop,data
591da177e4SLinus Torvalds
601da177e4SLinus Torvalds	load32		PA(__bss_start),%r3
611da177e4SLinus Torvalds	load32		PA(__bss_stop),%r4
621da177e4SLinus Torvalds$bss_loop:
631da177e4SLinus Torvalds	cmpb,<<,n       %r3,%r4,$bss_loop
641da177e4SLinus Torvalds	stw,ma          %r0,4(%r3)
651da177e4SLinus Torvalds
661da177e4SLinus Torvalds	/* Save away the arguments the boot loader passed in (32 bit args) */
671da177e4SLinus Torvalds	load32		PA(boot_args),%r1
681da177e4SLinus Torvalds	stw,ma          %arg0,4(%r1)
691da177e4SLinus Torvalds	stw,ma          %arg1,4(%r1)
701da177e4SLinus Torvalds	stw,ma          %arg2,4(%r1)
711da177e4SLinus Torvalds	stw,ma          %arg3,4(%r1)
721da177e4SLinus Torvalds
73*a406b8b4SHelge Deller#if defined(CONFIG_PA20)
74*a406b8b4SHelge Deller	/* check for 64-bit capable CPU as required by current kernel */
75591d2108SHelge Deller	ldi		32,%r10
76591d2108SHelge Deller	mtctl		%r10,%cr11
77591d2108SHelge Deller	.level 2.0
78591d2108SHelge Deller	mfctl,w		%cr11,%r10
79591d2108SHelge Deller	.level 1.1
80591d2108SHelge Deller	comib,<>,n	0,%r10,$cpu_ok
81591d2108SHelge Deller
82591d2108SHelge Deller	load32		PA(msg1),%arg0
83591d2108SHelge Deller	ldi		msg1_end-msg1,%arg1
84591d2108SHelge Deller$iodc_panic:
85591d2108SHelge Deller	copy		%arg0, %r10
86591d2108SHelge Deller	copy		%arg1, %r11
87591d2108SHelge Deller	load32		PA(init_stack),%sp
88591d2108SHelge Deller#define MEM_CONS 0x3A0
89591d2108SHelge Deller	ldw		MEM_CONS+32(%r0),%arg0	// HPA
90591d2108SHelge Deller	ldi		ENTRY_IO_COUT,%arg1
91591d2108SHelge Deller	ldw		MEM_CONS+36(%r0),%arg2	// SPA
92591d2108SHelge Deller	ldw		MEM_CONS+8(%r0),%arg3	// layers
93591d2108SHelge Deller	load32		PA(__bss_start),%r1
94591d2108SHelge Deller	stw		%r1,-52(%sp)		// arg4
95591d2108SHelge Deller	stw		%r0,-56(%sp)		// arg5
96591d2108SHelge Deller	stw		%r10,-60(%sp)		// arg6 = ptr to text
97591d2108SHelge Deller	stw		%r11,-64(%sp)		// arg7 = len
98591d2108SHelge Deller	stw		%r0,-68(%sp)		// arg8
99591d2108SHelge Deller	load32		PA(.iodc_panic_ret), %rp
100591d2108SHelge Deller	ldw		MEM_CONS+40(%r0),%r1	// ENTRY_IODC
101591d2108SHelge Deller	bv,n		(%r1)
102591d2108SHelge Deller.iodc_panic_ret:
103591d2108SHelge Deller	b .				/* wait endless with ... */
104591d2108SHelge Deller	or		%r10,%r10,%r10	/* qemu idle sleep */
105591d2108SHelge Dellermsg1:	.ascii "Can't boot kernel which was built for PA8x00 CPUs on this machine.\r\n"
106591d2108SHelge Dellermsg1_end:
107591d2108SHelge Deller
108591d2108SHelge Deller$cpu_ok:
109591d2108SHelge Deller#endif
110591d2108SHelge Deller
111591d2108SHelge Deller	.level	PA_ASM_LEVEL
112591d2108SHelge Deller
113332b42e4SHelge Deller	/* Initialize startup VM. Just map first 16/32 MB of memory */
1141da177e4SLinus Torvalds	load32		PA(swapper_pg_dir),%r4
1151da177e4SLinus Torvalds	mtctl		%r4,%cr24	/* Initialize kernel root pointer */
1161da177e4SLinus Torvalds	mtctl		%r4,%cr25	/* Initialize user root pointer */
1171da177e4SLinus Torvalds
118f24ffde4SKirill A. Shutemov#if CONFIG_PGTABLE_LEVELS == 3
1191da177e4SLinus Torvalds	/* Set pmd in pgd */
1201da177e4SLinus Torvalds	load32		PA(pmd0),%r5
1211da177e4SLinus Torvalds	shrd            %r5,PxD_VALUE_SHIFT,%r3
1221da177e4SLinus Torvalds	ldo		(PxD_FLAG_PRESENT+PxD_FLAG_VALID)(%r3),%r3
1231da177e4SLinus Torvalds	stw		%r3,ASM_PGD_ENTRY*ASM_PGD_ENTRY_SIZE(%r4)
1241da177e4SLinus Torvalds	ldo		ASM_PMD_ENTRY*ASM_PMD_ENTRY_SIZE(%r5),%r4
1251da177e4SLinus Torvalds#else
1261da177e4SLinus Torvalds	/* 2-level page table, so pmd == pgd */
1271da177e4SLinus Torvalds	ldo		ASM_PGD_ENTRY*ASM_PGD_ENTRY_SIZE(%r4),%r4
1281da177e4SLinus Torvalds#endif
1291da177e4SLinus Torvalds
1301da177e4SLinus Torvalds	/* Fill in pmd with enough pte directories */
1311da177e4SLinus Torvalds	load32		PA(pg0),%r1
1321da177e4SLinus Torvalds	SHRREG		%r1,PxD_VALUE_SHIFT,%r3
1331da177e4SLinus Torvalds	ldo		(PxD_FLAG_PRESENT+PxD_FLAG_VALID)(%r3),%r3
1341da177e4SLinus Torvalds
1351da177e4SLinus Torvalds	ldi		ASM_PT_INITIAL,%r1
1361da177e4SLinus Torvalds
1371da177e4SLinus Torvalds1:
1381da177e4SLinus Torvalds	stw		%r3,0(%r4)
13980af0876SKyle McMartin	ldo		(PAGE_SIZE >> PxD_VALUE_SHIFT)(%r3),%r3
1401da177e4SLinus Torvalds	addib,>		-1,%r1,1b
141f24ffde4SKirill A. Shutemov#if CONFIG_PGTABLE_LEVELS == 3
1421da177e4SLinus Torvalds	ldo             ASM_PMD_ENTRY_SIZE(%r4),%r4
1431da177e4SLinus Torvalds#else
1441da177e4SLinus Torvalds	ldo             ASM_PGD_ENTRY_SIZE(%r4),%r4
1451da177e4SLinus Torvalds#endif
1461da177e4SLinus Torvalds
1471da177e4SLinus Torvalds
148d7dd2ff1SJames Bottomley	/* Now initialize the PTEs themselves.  We use RWX for
149d7dd2ff1SJames Bottomley	 * everything ... it will get remapped correctly later */
150d7dd2ff1SJames Bottomley	ldo		0+_PAGE_KERNEL_RWX(%r0),%r3 /* Hardwired 0 phys addr start */
151332b42e4SHelge Deller	load32		(1<<(KERNEL_INITIAL_ORDER-PAGE_SHIFT)),%r11 /* PFN count */
1521da177e4SLinus Torvalds	load32		PA(pg0),%r1
1531da177e4SLinus Torvalds
1541da177e4SLinus Torvalds$pgt_fill_loop:
1551da177e4SLinus Torvalds	STREGM          %r3,ASM_PTE_ENTRY_SIZE(%r1)
1562fd83038SHelge Deller	ldo		(1<<PFN_PTE_SHIFT)(%r3),%r3 /* add one PFN */
1572fd83038SHelge Deller	addib,>		-1,%r11,$pgt_fill_loop
1581da177e4SLinus Torvalds	nop
1591da177e4SLinus Torvalds
1601da177e4SLinus Torvalds	/* Load the return address...er...crash 'n burn */
1611da177e4SLinus Torvalds	copy		%r0,%r2
1621da177e4SLinus Torvalds
1631da177e4SLinus Torvalds	/* And the RFI Target address too */
164089d5528SKyle McMartin	load32		start_parisc,%r11
1651da177e4SLinus Torvalds
1661da177e4SLinus Torvalds	/* And the initial task pointer */
1672214c0e7SHelge Deller	load32		init_task,%r6
1681da177e4SLinus Torvalds	mtctl           %r6,%cr30
1691da177e4SLinus Torvalds
1701da177e4SLinus Torvalds	/* And the stack pointer too */
1712214c0e7SHelge Deller	load32		init_stack,%sp
1722214c0e7SHelge Deller	tophys_r1	%sp
173366dd4eaSHelge Deller#if defined(CONFIG_64BIT) && defined(CONFIG_FUNCTION_TRACER)
174366dd4eaSHelge Deller	.import _mcount,data
175366dd4eaSHelge Deller	/* initialize mcount FPTR */
176366dd4eaSHelge Deller	/* Get the global data pointer */
177366dd4eaSHelge Deller	loadgp
178366dd4eaSHelge Deller	load32		PA(_mcount), %r10
179366dd4eaSHelge Deller	std		%dp,0x18(%r10)
180366dd4eaSHelge Deller#endif
181366dd4eaSHelge Deller
1820ed1fe4aSHelge Deller#define MEM_PDC_LO 0x388
1830ed1fe4aSHelge Deller#define MEM_PDC_HI 0x35C
184eda20521SHelge Deller#ifdef CONFIG_64BIT
185eda20521SHelge Deller	/* Get PDCE_PROC for monarch CPU. */
1860ed1fe4aSHelge Deller	ldw             MEM_PDC_LO(%r0),%r3
1870ed1fe4aSHelge Deller	ldw             MEM_PDC_HI(%r0),%r10
1880ed1fe4aSHelge Deller	depd            %r10, 31, 32, %r3        /* move to upper word */
1890ed1fe4aSHelge Deller#endif
1900ed1fe4aSHelge Deller
1910ed1fe4aSHelge Deller
1921da177e4SLinus Torvalds#ifdef CONFIG_SMP
19325985edcSLucas De Marchi	/* Set the smp rendezvous address into page zero.
1941da177e4SLinus Torvalds	** It would be safer to do this in init_smp_config() but
1951da177e4SLinus Torvalds	** it's just way easier to deal with here because
1961da177e4SLinus Torvalds	** of 64-bit function ptrs and the address is local to this file.
1971da177e4SLinus Torvalds	*/
1981da177e4SLinus Torvalds	load32		PA(smp_slave_stext),%r10
1991da177e4SLinus Torvalds	stw		%r10,0x10(%r0)	/* MEM_RENDEZ */
2001da177e4SLinus Torvalds	stw		%r0,0x28(%r0)	/* MEM_RENDEZ_HI - assume addr < 4GB */
2011da177e4SLinus Torvalds
2021da177e4SLinus Torvalds	/* FALLTHROUGH */
2031da177e4SLinus Torvalds	.procend
2041da177e4SLinus Torvalds
205ca45ec3cSHelge Deller#ifdef CONFIG_HOTPLUG_CPU
206ca45ec3cSHelge Deller	/* common_stext is far away in another section... jump there */
207ca45ec3cSHelge Deller	load32		PA(common_stext), %rp
208ca45ec3cSHelge Deller	bv,n		(%rp)
209ca45ec3cSHelge Deller
210ca45ec3cSHelge Deller	/* common_stext and smp_slave_stext needs to be in text section */
211ca45ec3cSHelge Deller	.text
212ca45ec3cSHelge Deller#endif
213ca45ec3cSHelge Deller
2141da177e4SLinus Torvalds	/*
2151da177e4SLinus Torvalds	** Code Common to both Monarch and Slave processors.
2161da177e4SLinus Torvalds	** Entry:
2171da177e4SLinus Torvalds	**
2181da177e4SLinus Torvalds	**  1.1:
2191da177e4SLinus Torvalds	**    %r11 must contain RFI target address.
2201da177e4SLinus Torvalds	**    %r25/%r26 args to pass to target function
2211da177e4SLinus Torvalds	**    %r2  in case rfi target decides it didn't like something
2221da177e4SLinus Torvalds	**
2231da177e4SLinus Torvalds	**  2.0w:
2241da177e4SLinus Torvalds	**    %r3  PDCE_PROC address
2251da177e4SLinus Torvalds	**    %r11 RFI target address
2261da177e4SLinus Torvalds	**
2271da177e4SLinus Torvalds	** Caller must init: SR4-7, %sp, %r10, %cr24/25,
2281da177e4SLinus Torvalds	*/
2291da177e4SLinus Torvaldscommon_stext:
2301da177e4SLinus Torvalds	.proc
2311da177e4SLinus Torvalds	.callinfo
2321da177e4SLinus Torvalds#else
2331da177e4SLinus Torvalds	/* Clear PDC entry point - we won't use it */
2341da177e4SLinus Torvalds	stw		%r0,0x10(%r0)	/* MEM_RENDEZ */
2351da177e4SLinus Torvalds	stw		%r0,0x28(%r0)	/* MEM_RENDEZ_HI */
2361da177e4SLinus Torvalds#endif /*CONFIG_SMP*/
2371da177e4SLinus Torvalds
238413059f2SGrant Grundler#ifdef CONFIG_64BIT
2392214c0e7SHelge Deller	mfctl		%cr30,%r6		/* PCX-W2 firmware bug */
2402214c0e7SHelge Deller	tophys_r1	%r6
2411da177e4SLinus Torvalds
2421da177e4SLinus Torvalds	/* Save the rfi target address */
2432214c0e7SHelge Deller	STREG		%r11,  TASK_PT_GR11(%r6)
2441da177e4SLinus Torvalds	/* Switch to wide mode Superdome doesn't support narrow PDC
2451da177e4SLinus Torvalds	** calls.
2461da177e4SLinus Torvalds	*/
2471da177e4SLinus Torvalds1:	mfia            %rp             /* clear upper part of pcoq */
2481da177e4SLinus Torvalds	ldo             2f-1b(%rp),%rp
2491da177e4SLinus Torvalds	depdi           0,31,32,%rp
2501da177e4SLinus Torvalds	bv              (%rp)
2511da177e4SLinus Torvalds	ssm             PSW_SM_W,%r0
2521da177e4SLinus Torvalds
2531da177e4SLinus Torvalds        /* Set Wide mode as the "Default" (eg for traps)
2541da177e4SLinus Torvalds        ** First trap occurs *right* after (or part of) rfi for slave CPUs.
2551da177e4SLinus Torvalds        ** Someday, palo might not do this for the Monarch either.
2561da177e4SLinus Torvalds        */
2571da177e4SLinus Torvalds2:
25854e181e0SHelge Deller
2591da177e4SLinus Torvalds	ldo             PDC_PSW(%r0),%arg0              /* 21 */
2601da177e4SLinus Torvalds	ldo             PDC_PSW_SET_DEFAULTS(%r0),%arg1 /* 2 */
2611da177e4SLinus Torvalds	ldo             PDC_PSW_WIDE_BIT(%r0),%arg2     /* 2 */
2621da177e4SLinus Torvalds	load32          PA(stext_pdc_ret), %rp
2631da177e4SLinus Torvalds	bv              (%r3)
2641da177e4SLinus Torvalds	copy            %r0,%arg3
2651da177e4SLinus Torvalds
2661da177e4SLinus Torvaldsstext_pdc_ret:
2672214c0e7SHelge Deller	LDREG		TASK_PT_GR11(%r6), %r11
2682214c0e7SHelge Deller	tovirt_r1	%r6
26954e181e0SHelge Deller	mtctl		%r6,%cr30		/* restore task thread info */
2701da177e4SLinus Torvalds#endif
2711da177e4SLinus Torvalds
272eda20521SHelge Deller#ifndef CONFIG_64BIT
273eda20521SHelge Deller	/* clear all BTLBs */
274eda20521SHelge Deller	ldi		PDC_BLOCK_TLB,%arg0
275eda20521SHelge Deller	load32          PA(stext_pdc_btlb_ret), %rp
276eda20521SHelge Deller	ldw             MEM_PDC_LO(%r0),%r3
277eda20521SHelge Deller	bv              (%r3)
278eda20521SHelge Deller	ldi		PDC_BTLB_PURGE_ALL,%arg1
279eda20521SHelge Dellerstext_pdc_btlb_ret:
280eda20521SHelge Deller#endif
281eda20521SHelge Deller
2821da177e4SLinus Torvalds	/* PARANOID: clear user scratch/user space SR's */
2831da177e4SLinus Torvalds	mtsp	%r0,%sr0
2841da177e4SLinus Torvalds	mtsp	%r0,%sr1
2851da177e4SLinus Torvalds	mtsp	%r0,%sr2
2861da177e4SLinus Torvalds	mtsp	%r0,%sr3
2871da177e4SLinus Torvalds
2881da177e4SLinus Torvalds	/* Initialize Protection Registers */
2891da177e4SLinus Torvalds	mtctl	%r0,%cr8
2901da177e4SLinus Torvalds	mtctl	%r0,%cr9
2911da177e4SLinus Torvalds	mtctl	%r0,%cr12
2921da177e4SLinus Torvalds	mtctl	%r0,%cr13
2931da177e4SLinus Torvalds
2941da177e4SLinus Torvalds	/* Initialize the global data pointer */
2951da177e4SLinus Torvalds	loadgp
2961da177e4SLinus Torvalds
2971da177e4SLinus Torvalds	/* Set up our interrupt table.  HPMCs might not work after this!
2981da177e4SLinus Torvalds	 *
2991da177e4SLinus Torvalds	 * We need to install the correct iva for PA1.1 or PA2.0. The
3001da177e4SLinus Torvalds	 * following short sequence of instructions can determine this
3011da177e4SLinus Torvalds	 * (without being illegal on a PA1.1 machine).
3021da177e4SLinus Torvalds	 */
303413059f2SGrant Grundler#ifndef CONFIG_64BIT
3041da177e4SLinus Torvalds	ldi		32,%r10
3051da177e4SLinus Torvalds	mtctl		%r10,%cr11
3061da177e4SLinus Torvalds	.level 2.0
3071da177e4SLinus Torvalds	mfctl,w		%cr11,%r10
3081da177e4SLinus Torvalds	.level 1.1
3091da177e4SLinus Torvalds	comib,<>,n	0,%r10,$is_pa20
3101da177e4SLinus Torvalds	ldil		L%PA(fault_vector_11),%r10
3111da177e4SLinus Torvalds	b		$install_iva
3121da177e4SLinus Torvalds	ldo		R%PA(fault_vector_11)(%r10),%r10
3131da177e4SLinus Torvalds
3141da177e4SLinus Torvalds$is_pa20:
3151829dda0SHelge Deller	.level		PA_ASM_LEVEL /* restore 1.1 || 2.0w */
316413059f2SGrant Grundler#endif /*!CONFIG_64BIT*/
3171da177e4SLinus Torvalds	load32		PA(fault_vector_20),%r10
3181da177e4SLinus Torvalds
3191da177e4SLinus Torvalds$install_iva:
3201da177e4SLinus Torvalds	mtctl		%r10,%cr14
3211da177e4SLinus Torvalds
322896a3756SGrant Grundler	b		aligned_rfi  /* Prepare to RFI! Man all the cannons! */
3231da177e4SLinus Torvalds	nop
3241da177e4SLinus Torvalds
325896a3756SGrant Grundler	.align 128
3261da177e4SLinus Torvaldsaligned_rfi:
327896a3756SGrant Grundler	pcxt_ssm_bug
3281da177e4SLinus Torvalds
3290ed1fe4aSHelge Deller	copy		%r3, %arg0	/* PDCE_PROC for smp_callin() */
3300ed1fe4aSHelge Deller
331896a3756SGrant Grundler	rsm		PSW_SM_QUIET,%r0	/* off troublesome PSW bits */
332896a3756SGrant Grundler	/* Don't need NOPs, have 8 compliant insn before rfi */
3331da177e4SLinus Torvalds
3341da177e4SLinus Torvalds	mtctl		%r0,%cr17	/* Clear IIASQ tail */
3351da177e4SLinus Torvalds	mtctl		%r0,%cr17	/* Clear IIASQ head */
3361da177e4SLinus Torvalds
3371da177e4SLinus Torvalds	/* Load RFI target into PC queue */
3381da177e4SLinus Torvalds	mtctl		%r11,%cr18	/* IIAOQ head */
3391da177e4SLinus Torvalds	ldo		4(%r11),%r11
3401da177e4SLinus Torvalds	mtctl		%r11,%cr18	/* IIAOQ tail */
3411da177e4SLinus Torvalds
342896a3756SGrant Grundler	load32		KERNEL_PSW,%r10
343896a3756SGrant Grundler	mtctl		%r10,%ipsw
344896a3756SGrant Grundler
3452214c0e7SHelge Deller	tovirt_r1	%sp
3462214c0e7SHelge Deller
347896a3756SGrant Grundler	/* Jump through hyperspace to Virt Mode */
3481da177e4SLinus Torvalds	rfi
3491da177e4SLinus Torvalds	nop
3501da177e4SLinus Torvalds
3511da177e4SLinus Torvalds	.procend
3521da177e4SLinus Torvalds
3531da177e4SLinus Torvalds#ifdef CONFIG_SMP
3541da177e4SLinus Torvalds
3551da177e4SLinus Torvalds	.import smp_init_current_idle_task,data
3561da177e4SLinus Torvalds	.import	smp_callin,code
3571da177e4SLinus Torvalds
358413059f2SGrant Grundler#ifndef CONFIG_64BIT
3591da177e4SLinus Torvaldssmp_callin_rtn:
3601da177e4SLinus Torvalds        .proc
3611da177e4SLinus Torvalds	.callinfo
3621da177e4SLinus Torvalds	break	1,1		/*  Break if returned from start_secondary */
3631da177e4SLinus Torvalds	nop
3641da177e4SLinus Torvalds	nop
3651da177e4SLinus Torvalds        .procend
366413059f2SGrant Grundler#endif /*!CONFIG_64BIT*/
3671da177e4SLinus Torvalds
3681da177e4SLinus Torvalds/***************************************************************************
3691da177e4SLinus Torvalds* smp_slave_stext is executed by all non-monarch Processors when the Monarch
3701da177e4SLinus Torvalds* pokes the slave CPUs in smp.c:smp_boot_cpus().
3711da177e4SLinus Torvalds*
3721da177e4SLinus Torvalds* Once here, registers values are initialized in order to branch to virtual
3731da177e4SLinus Torvalds* mode. Once all available/eligible CPUs are in virtual mode, all are
3741da177e4SLinus Torvalds* released and start out by executing their own idle task.
3751da177e4SLinus Torvalds*****************************************************************************/
3761da177e4SLinus Torvaldssmp_slave_stext:
3771da177e4SLinus Torvalds        .proc
3781da177e4SLinus Torvalds	.callinfo
3791da177e4SLinus Torvalds
3801da177e4SLinus Torvalds	/*
3811da177e4SLinus Torvalds	** Initialize Space registers
3821da177e4SLinus Torvalds	*/
3831da177e4SLinus Torvalds	mtsp	   %r0,%sr4
3841da177e4SLinus Torvalds	mtsp	   %r0,%sr5
3851da177e4SLinus Torvalds	mtsp	   %r0,%sr6
3861da177e4SLinus Torvalds	mtsp	   %r0,%sr7
3871da177e4SLinus Torvalds
3886b1370aeSSven Schnelle#ifdef CONFIG_64BIT
3896b1370aeSSven Schnelle	/*
3906b1370aeSSven Schnelle	 *  Enable Wide mode early, in case the task_struct for the idle
3916b1370aeSSven Schnelle	 *  task in smp_init_current_idle_task was allocated above 4GB.
3926b1370aeSSven Schnelle	 */
3936b1370aeSSven Schnelle1:	mfia            %rp             /* clear upper part of pcoq */
3946b1370aeSSven Schnelle	ldo             2f-1b(%rp),%rp
3956b1370aeSSven Schnelle	depdi           0,31,32,%rp
3966b1370aeSSven Schnelle	bv              (%rp)
3976b1370aeSSven Schnelle	ssm             PSW_SM_W,%r0
3986b1370aeSSven Schnelle2:
3996b1370aeSSven Schnelle#endif
4006b1370aeSSven Schnelle
4011da177e4SLinus Torvalds	/*  Initialize the SP - monarch sets up smp_init_current_idle_task */
4022214c0e7SHelge Deller	load32		PA(smp_init_current_idle_task),%r6
4032214c0e7SHelge Deller	LDREG		0(%r6),%r6
4042214c0e7SHelge Deller	mtctl		%r6,%cr30
4052214c0e7SHelge Deller	tophys_r1	%r6
4062214c0e7SHelge Deller	LDREG           TASK_STACK(%r6),%sp
4071da177e4SLinus Torvalds	tophys_r1	%sp
4082214c0e7SHelge Deller	ldo		FRAME_SIZE(%sp),%sp
4091da177e4SLinus Torvalds
4101da177e4SLinus Torvalds	/* point CPU to kernel page tables */
4111da177e4SLinus Torvalds	load32		PA(swapper_pg_dir),%r4
4121da177e4SLinus Torvalds	mtctl		%r4,%cr24	/* Initialize kernel root pointer */
4131da177e4SLinus Torvalds	mtctl		%r4,%cr25	/* Initialize user root pointer */
4141da177e4SLinus Torvalds
415413059f2SGrant Grundler#ifdef CONFIG_64BIT
4161da177e4SLinus Torvalds	/* Setup PDCE_PROC entry */
4171da177e4SLinus Torvalds	copy            %arg0,%r3
4181da177e4SLinus Torvalds#else
4191da177e4SLinus Torvalds	/* Load RFI *return* address in case smp_callin bails */
4201da177e4SLinus Torvalds	load32		smp_callin_rtn,%r2
4211da177e4SLinus Torvalds#endif
4221da177e4SLinus Torvalds
4231da177e4SLinus Torvalds	/* Load RFI target address.  */
4241da177e4SLinus Torvalds	load32		smp_callin,%r11
4251da177e4SLinus Torvalds
4261da177e4SLinus Torvalds	/* ok...common code can handle the rest */
4271da177e4SLinus Torvalds	b		common_stext
4281da177e4SLinus Torvalds	nop
4291da177e4SLinus Torvalds
4301da177e4SLinus Torvalds	.procend
4311da177e4SLinus Torvalds#endif /* CONFIG_SMP */
4328e9e9844SHelge Deller
433413059f2SGrant Grundler#ifndef CONFIG_64BIT
434dc1b3c0dSHelge Deller	.section .data..ro_after_init
4351da177e4SLinus Torvalds
4361da177e4SLinus Torvalds	.align	4
4371da177e4SLinus Torvalds	.export	$global$,data
4381da177e4SLinus Torvalds
4391da177e4SLinus Torvalds	.type	$global$,@object
4401da177e4SLinus Torvalds	.size	$global$,4
4411da177e4SLinus Torvalds$global$:
4421da177e4SLinus Torvalds	.word 0
443413059f2SGrant Grundler#endif /*!CONFIG_64BIT*/
444