xref: /freebsd/sys/powerpc/ofw/ofwcall64.S (revision 95ee2897e98f5d444f26ed2334cc7c439f9c16c6)
117879090SNathan Whitehorn/*-
217879090SNathan Whitehorn * Copyright (C) 2009-2011 Nathan Whitehorn
317879090SNathan Whitehorn * All rights reserved.
417879090SNathan Whitehorn *
517879090SNathan Whitehorn * Redistribution and use in source and binary forms, with or without
617879090SNathan Whitehorn * modification, are permitted provided that the following conditions
717879090SNathan Whitehorn * are met:
817879090SNathan Whitehorn * 1. Redistributions of source code must retain the above copyright
917879090SNathan Whitehorn *    notice, this list of conditions and the following disclaimer.
1017879090SNathan Whitehorn * 2. Redistributions in binary form must reproduce the above copyright
1117879090SNathan Whitehorn *    notice, this list of conditions and the following disclaimer in the
1217879090SNathan Whitehorn *    documentation and/or other materials provided with the distribution.
1317879090SNathan Whitehorn *
1417879090SNathan Whitehorn * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1517879090SNathan Whitehorn * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1617879090SNathan Whitehorn * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1717879090SNathan Whitehorn * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
1817879090SNathan Whitehorn * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
1917879090SNathan Whitehorn * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
2017879090SNathan Whitehorn * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
2117879090SNathan Whitehorn * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
2217879090SNathan Whitehorn * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
2317879090SNathan Whitehorn * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2417879090SNathan Whitehorn */
2517879090SNathan Whitehorn
2617879090SNathan Whitehorn#include <sys/syscall.h>
2717879090SNathan Whitehorn
2817879090SNathan Whitehorn#include <machine/trap.h>
2917879090SNathan Whitehorn#include <machine/param.h>
3017879090SNathan Whitehorn#include <machine/spr.h>
3117879090SNathan Whitehorn#include <machine/asm.h>
3217879090SNathan Whitehorn
334efb1ca7SBrandon Bergren#include "opt_platform.h"
344efb1ca7SBrandon Bergren
3517879090SNathan Whitehorn#define	OFWSTKSZ	4096		/* 4K Open Firmware stack */
3617879090SNathan Whitehorn
3717879090SNathan Whitehorn/*
3817879090SNathan Whitehorn * Globals
3917879090SNathan Whitehorn */
4017879090SNathan Whitehorn	.data
4117879090SNathan Whitehorn	.align	4
4217879090SNathan Whitehornofwstk:
4317879090SNathan Whitehorn	.space	OFWSTKSZ
4417879090SNathan Whitehornrtas_regsave:
458864f359SNathan Whitehorn	.space	32 /* 4 * sizeof(register_t) */
4617879090SNathan WhitehornGLOBAL(ofmsr)
4717879090SNathan Whitehorn	.llong  0, 0, 0, 0, 0		/* msr/sprg0-3 used in Open Firmware */
4817879090SNathan WhitehornGLOBAL(rtasmsr)
4917879090SNathan Whitehorn	.llong	0
5017879090SNathan WhitehornGLOBAL(openfirmware_entry)
5117879090SNathan Whitehorn	.llong	0			/* Open Firmware entry point */
5217879090SNathan WhitehornGLOBAL(rtas_entry)
5317879090SNathan Whitehorn	.llong	0			/* RTAS entry point */
5417879090SNathan Whitehorn
559cecb88cSNathan WhitehornTOC_ENTRY(ofmsr)
569cecb88cSNathan WhitehornTOC_ENTRY(ofwstk)
579cecb88cSNathan WhitehornTOC_ENTRY(rtasmsr)
589cecb88cSNathan WhitehornTOC_ENTRY(openfirmware_entry)
599cecb88cSNathan WhitehornTOC_ENTRY(rtas_entry)
609cecb88cSNathan WhitehornTOC_ENTRY(rtas_regsave)
619cecb88cSNathan Whitehorn
6217879090SNathan Whitehorn/*
6317879090SNathan Whitehorn * Open Firmware Real-mode Entry Point. This is a huge pain.
6417879090SNathan Whitehorn */
6517879090SNathan Whitehorn
669eab2f14SAndreas ToblerASENTRY_NOPROF(ofwcall)
678864f359SNathan Whitehorn	mflr	%r8
688864f359SNathan Whitehorn	std	%r8,16(%r1)
6917879090SNathan Whitehorn	stdu	%r1,-208(%r1)
7017879090SNathan Whitehorn
7117879090SNathan Whitehorn	/*
7217879090SNathan Whitehorn	 * We need to save the following, because OF's register save/
7317879090SNathan Whitehorn	 * restore code assumes that the contents of registers are
7417879090SNathan Whitehorn	 * at most 32 bits wide: lr, cr, r2, r13-r31, the old MSR. These
7517879090SNathan Whitehorn	 * get placed in that order in the stack.
7617879090SNathan Whitehorn	 */
7717879090SNathan Whitehorn
7817879090SNathan Whitehorn	mfcr	%r4
7917879090SNathan Whitehorn	std	%r4,48(%r1)
8017879090SNathan Whitehorn	std	%r13,56(%r1)
8117879090SNathan Whitehorn	std	%r14,64(%r1)
8217879090SNathan Whitehorn	std	%r15,72(%r1)
8317879090SNathan Whitehorn	std	%r16,80(%r1)
8417879090SNathan Whitehorn	std	%r17,88(%r1)
8517879090SNathan Whitehorn	std	%r18,96(%r1)
8617879090SNathan Whitehorn	std	%r19,104(%r1)
8717879090SNathan Whitehorn	std	%r20,112(%r1)
8817879090SNathan Whitehorn	std	%r21,120(%r1)
8917879090SNathan Whitehorn	std	%r22,128(%r1)
9017879090SNathan Whitehorn	std	%r23,136(%r1)
9117879090SNathan Whitehorn	std	%r24,144(%r1)
9217879090SNathan Whitehorn	std	%r25,152(%r1)
9317879090SNathan Whitehorn	std	%r26,160(%r1)
9417879090SNathan Whitehorn	std	%r27,168(%r1)
9517879090SNathan Whitehorn	std	%r28,176(%r1)
9617879090SNathan Whitehorn	std	%r29,184(%r1)
9717879090SNathan Whitehorn	std	%r30,192(%r1)
9817879090SNathan Whitehorn	std	%r31,200(%r1)
9917879090SNathan Whitehorn
10017879090SNathan Whitehorn	/* Record the old MSR */
10117879090SNathan Whitehorn	mfmsr	%r6
10217879090SNathan Whitehorn
10317879090SNathan Whitehorn	/* read client interface handler */
1040499e9c6SJustin Hibbits	addis	%r4,%r2,TOC_REF(openfirmware_entry)@ha
1050499e9c6SJustin Hibbits	ld	%r4,TOC_REF(openfirmware_entry)@l(%r4)
1069cecb88cSNathan Whitehorn	ld	%r4,0(%r4)
1079cecb88cSNathan Whitehorn
1089cecb88cSNathan Whitehorn	/* Get OF stack pointer */
1090499e9c6SJustin Hibbits	addis	%r7,%r2,TOC_REF(ofwstk)@ha
1100499e9c6SJustin Hibbits	ld	%r7,TOC_REF(ofwstk)@l(%r7)
1118864f359SNathan Whitehorn	addi	%r7,%r7,OFWSTKSZ-40
11217879090SNathan Whitehorn
11317879090SNathan Whitehorn	/*
11417879090SNathan Whitehorn	 * Set the MSR to the OF value. This has the side effect of disabling
11517879090SNathan Whitehorn	 * exceptions, which is important for the next few steps.
116a6625592SBrandon Bergren	 * This does NOT, however, cause us to switch endianness.
11717879090SNathan Whitehorn	 */
11817879090SNathan Whitehorn
1190499e9c6SJustin Hibbits	addis	%r5,%r2,TOC_REF(ofmsr)@ha
1200499e9c6SJustin Hibbits	ld	%r5,TOC_REF(ofmsr)@l(%r5)
1219cecb88cSNathan Whitehorn	ld	%r5,0(%r5)
1224efb1ca7SBrandon Bergren#if defined(__LITTLE_ENDIAN__) && defined(QEMU)
1234efb1ca7SBrandon Bergren	/* QEMU hack: qemu does not emulate mtmsrd correctly! */
1244efb1ca7SBrandon Bergren	ori	%r5,%r5,1	/* Leave PSR_LE set */
1254efb1ca7SBrandon Bergren#endif
12617879090SNathan Whitehorn	mtmsrd	%r5
12717879090SNathan Whitehorn	isync
12817879090SNathan Whitehorn
12917879090SNathan Whitehorn	/*
13017879090SNathan Whitehorn	 * Set up OF stack. This needs to be accessible in real mode and
13117879090SNathan Whitehorn	 * use the 32-bit ABI stack frame format. The pointer to the current
13217879090SNathan Whitehorn	 * kernel stack is placed at the very top of the stack along with
13317879090SNathan Whitehorn	 * the old MSR so we can get them back later.
13417879090SNathan Whitehorn	 */
13517879090SNathan Whitehorn	mr	%r5,%r1
1369cecb88cSNathan Whitehorn	mr	%r1,%r7
13717879090SNathan Whitehorn	std	%r5,8(%r1)	/* Save real stack pointer */
13817879090SNathan Whitehorn	std	%r2,16(%r1)	/* Save old TOC */
13917879090SNathan Whitehorn	std	%r6,24(%r1)	/* Save old MSR */
1408864f359SNathan Whitehorn	std	%r8,32(%r1)	/* Save high 32-bits of the kernel's PC */
1418864f359SNathan Whitehorn
14217879090SNathan Whitehorn	li	%r5,0
14317879090SNathan Whitehorn	stw	%r5,4(%r1)
14417879090SNathan Whitehorn	stw	%r5,0(%r1)
14517879090SNathan Whitehorn
146a6625592SBrandon Bergren#ifdef __LITTLE_ENDIAN__
147a6625592SBrandon Bergren	/* Atomic context switch w/ endian change */
148a6625592SBrandon Bergren	mtmsrd	%r5, 1	/* Clear PSL_EE|PSL_RI */
149a6625592SBrandon Bergren	addis	%r5,%r2,TOC_REF(ofmsr)@ha
150a6625592SBrandon Bergren	ld	%r5,TOC_REF(ofmsr)@l(%r5)
151a6625592SBrandon Bergren	ld	%r5,0(%r5)
152a6625592SBrandon Bergren	mtsrr0	%r4
153a6625592SBrandon Bergren	mtsrr1	%r5
154a6625592SBrandon Bergren	LOAD_LR_NIA
155a6625592SBrandon Bergren1:
156a6625592SBrandon Bergren	mflr	%r5
157a6625592SBrandon Bergren	addi	%r5, %r5, (2f-1b)
158a6625592SBrandon Bergren	mtlr	%r5
159a6625592SBrandon Bergren	li	%r5, 0
160a6625592SBrandon Bergren	rfid
161a6625592SBrandon Bergren2:
162a6625592SBrandon Bergren	RETURN_TO_NATIVE_ENDIAN
163a6625592SBrandon Bergren#else
16417879090SNathan Whitehorn	/* Finally, branch to OF */
16517879090SNathan Whitehorn	mtctr	%r4
16617879090SNathan Whitehorn	bctrl
167a6625592SBrandon Bergren#endif
16817879090SNathan Whitehorn
1698864f359SNathan Whitehorn	/* Reload stack pointer, MSR, and reference PC from the OFW stack */
1708864f359SNathan Whitehorn	ld	%r7,32(%r1)
17117879090SNathan Whitehorn	ld	%r6,24(%r1)
17217879090SNathan Whitehorn	ld	%r2,16(%r1)
17317879090SNathan Whitehorn	ld	%r1,8(%r1)
17417879090SNathan Whitehorn
1758864f359SNathan Whitehorn	/* Get back to the MSR/PC we want, using the cached high bits of PC */
1768864f359SNathan Whitehorn	mtsrr1	%r6
1778864f359SNathan Whitehorn	clrrdi	%r7,%r7,32
1788864f359SNathan Whitehorn	bl	1f
1798864f359SNathan Whitehorn1:	mflr	%r8
1808864f359SNathan Whitehorn	or	%r8,%r8,%r7
1818864f359SNathan Whitehorn	addi	%r8,%r8,2f-1b
1828864f359SNathan Whitehorn	mtsrr0	%r8
1838864f359SNathan Whitehorn	rfid			/* Turn on MMU, exceptions, and 64-bit mode */
18417879090SNathan Whitehorn
1858864f359SNathan Whitehorn2:
18617879090SNathan Whitehorn	/* Sign-extend the return value from OF */
18717879090SNathan Whitehorn	extsw	%r3,%r3
18817879090SNathan Whitehorn
18917879090SNathan Whitehorn	/* Restore all the non-volatile registers */
19017879090SNathan Whitehorn	ld	%r5,48(%r1)
19117879090SNathan Whitehorn	mtcr	%r5
19217879090SNathan Whitehorn	ld	%r13,56(%r1)
19317879090SNathan Whitehorn	ld	%r14,64(%r1)
19417879090SNathan Whitehorn	ld	%r15,72(%r1)
19517879090SNathan Whitehorn	ld	%r16,80(%r1)
19617879090SNathan Whitehorn	ld	%r17,88(%r1)
19717879090SNathan Whitehorn	ld	%r18,96(%r1)
19817879090SNathan Whitehorn	ld	%r19,104(%r1)
19917879090SNathan Whitehorn	ld	%r20,112(%r1)
20017879090SNathan Whitehorn	ld	%r21,120(%r1)
20117879090SNathan Whitehorn	ld	%r22,128(%r1)
20217879090SNathan Whitehorn	ld	%r23,136(%r1)
20317879090SNathan Whitehorn	ld	%r24,144(%r1)
20417879090SNathan Whitehorn	ld	%r25,152(%r1)
20517879090SNathan Whitehorn	ld	%r26,160(%r1)
20617879090SNathan Whitehorn	ld	%r27,168(%r1)
20717879090SNathan Whitehorn	ld	%r28,176(%r1)
20817879090SNathan Whitehorn	ld	%r29,184(%r1)
20917879090SNathan Whitehorn	ld	%r30,192(%r1)
21017879090SNathan Whitehorn	ld	%r31,200(%r1)
21117879090SNathan Whitehorn
21217879090SNathan Whitehorn	/* Restore the stack and link register */
21317879090SNathan Whitehorn	ld	%r1,0(%r1)
21417879090SNathan Whitehorn	ld	%r0,16(%r1)
21517879090SNathan Whitehorn	mtlr 	%r0
21617879090SNathan Whitehorn	blr
217*78599c32SConrad MeyerASEND(ofwcall)
21817879090SNathan Whitehorn
21917879090SNathan Whitehorn/*
22017879090SNathan Whitehorn * RTAS 32-bit Entry Point. Similar to the OF one, but simpler (no separate
22117879090SNathan Whitehorn * stack)
22217879090SNathan Whitehorn *
22317879090SNathan Whitehorn * C prototype: int rtascall(void *callbuffer, void *rtas_privdat);
22417879090SNathan Whitehorn */
22517879090SNathan Whitehorn
2269eab2f14SAndreas ToblerASENTRY_NOPROF(rtascall)
2278864f359SNathan Whitehorn	mflr	%r9
2288864f359SNathan Whitehorn	std	%r9,16(%r1)
22917879090SNathan Whitehorn	stdu	%r1,-208(%r1)
23017879090SNathan Whitehorn
23117879090SNathan Whitehorn	/*
23217879090SNathan Whitehorn	 * We need to save the following, because RTAS's register save/
23317879090SNathan Whitehorn	 * restore code assumes that the contents of registers are
23417879090SNathan Whitehorn	 * at most 32 bits wide: lr, cr, r2, r13-r31, the old MSR. These
23517879090SNathan Whitehorn	 * get placed in that order in the stack.
23617879090SNathan Whitehorn	 */
23717879090SNathan Whitehorn
23817879090SNathan Whitehorn	mfcr	%r5
23917879090SNathan Whitehorn	std	%r5,48(%r1)
24017879090SNathan Whitehorn	std	%r13,56(%r1)
24117879090SNathan Whitehorn	std	%r14,64(%r1)
24217879090SNathan Whitehorn	std	%r15,72(%r1)
24317879090SNathan Whitehorn	std	%r16,80(%r1)
24417879090SNathan Whitehorn	std	%r17,88(%r1)
24517879090SNathan Whitehorn	std	%r18,96(%r1)
24617879090SNathan Whitehorn	std	%r19,104(%r1)
24717879090SNathan Whitehorn	std	%r20,112(%r1)
24817879090SNathan Whitehorn	std	%r21,120(%r1)
24917879090SNathan Whitehorn	std	%r22,128(%r1)
25017879090SNathan Whitehorn	std	%r23,136(%r1)
25117879090SNathan Whitehorn	std	%r24,144(%r1)
25217879090SNathan Whitehorn	std	%r25,152(%r1)
25317879090SNathan Whitehorn	std	%r26,160(%r1)
25417879090SNathan Whitehorn	std	%r27,168(%r1)
25517879090SNathan Whitehorn	std	%r28,176(%r1)
25617879090SNathan Whitehorn	std	%r29,184(%r1)
25717879090SNathan Whitehorn	std	%r30,192(%r1)
25817879090SNathan Whitehorn	std	%r31,200(%r1)
25917879090SNathan Whitehorn
26017879090SNathan Whitehorn	/* Record the old MSR */
26117879090SNathan Whitehorn	mfmsr	%r6
26217879090SNathan Whitehorn
2639cecb88cSNathan Whitehorn	/* Read RTAS entry and reg save area pointers */
2640499e9c6SJustin Hibbits	addis	%r5,%r2,TOC_REF(rtas_entry)@ha
2650499e9c6SJustin Hibbits	ld	%r5,TOC_REF(rtas_entry)@l(%r5)
2669cecb88cSNathan Whitehorn	ld	%r5,0(%r5)
2670499e9c6SJustin Hibbits	addis	%r8,%r2,TOC_REF(rtas_regsave)@ha
2680499e9c6SJustin Hibbits	ld	%r8,TOC_REF(rtas_regsave)@l(%r8)
26917879090SNathan Whitehorn
27017879090SNathan Whitehorn	/*
27117879090SNathan Whitehorn	 * Set the MSR to the RTAS value. This has the side effect of disabling
27217879090SNathan Whitehorn	 * exceptions, which is important for the next few steps.
27317879090SNathan Whitehorn	 */
27417879090SNathan Whitehorn
2750499e9c6SJustin Hibbits	addis	%r7,%r2,TOC_REF(rtasmsr)@ha
2760499e9c6SJustin Hibbits	ld	%r7,TOC_REF(rtasmsr)@l(%r7)
2779cecb88cSNathan Whitehorn	ld	%r7,0(%r7)
2784efb1ca7SBrandon Bergren#ifdef	__LITTLE_ENDIAN__
2794efb1ca7SBrandon Bergren	/* QEMU hack: qemu does not emulate mtmsrd correctly! */
2804efb1ca7SBrandon Bergren	ori	%r7,%r7,1	/* Leave PSR_LE set */
2814efb1ca7SBrandon Bergren#endif
28217879090SNathan Whitehorn	mtmsrd	%r7
28317879090SNathan Whitehorn	isync
28417879090SNathan Whitehorn
28517879090SNathan Whitehorn	/*
28617879090SNathan Whitehorn	 * Set up RTAS register save area, so that we can get back all of
28717879090SNathan Whitehorn	 * our 64-bit pointers. Save our stack pointer, the TOC, and the MSR.
28817879090SNathan Whitehorn	 * Put this in r1, since RTAS is obliged to save it. Kernel globals
28917879090SNathan Whitehorn	 * are below 4 GB, so this is safe.
29017879090SNathan Whitehorn	 */
29117879090SNathan Whitehorn	mr	%r7,%r1
2929cecb88cSNathan Whitehorn	mr	%r1,%r8
29317879090SNathan Whitehorn	std	%r7,0(%r1)	/* Save 64-bit stack pointer */
29417879090SNathan Whitehorn	std	%r2,8(%r1)	/* Save TOC */
29517879090SNathan Whitehorn	std	%r6,16(%r1)	/* Save MSR */
2968864f359SNathan Whitehorn	std	%r9,24(%r1)	/* Save reference PC for high 32 bits */
29717879090SNathan Whitehorn
298d20d17f6SBrandon Bergren#ifdef __LITTLE_ENDIAN__
299d20d17f6SBrandon Bergren	/* Atomic context switch w/ endian change */
300d20d17f6SBrandon Bergren	li	%r7, 0
301d20d17f6SBrandon Bergren	mtmsrd	%r7, 1	/* Clear PSL_EE|PSL_RI */
302d20d17f6SBrandon Bergren	addis	%r7,%r2,TOC_REF(rtasmsr)@ha
303d20d17f6SBrandon Bergren	ld	%r7,TOC_REF(rtasmsr)@l(%r7)
304d20d17f6SBrandon Bergren	ld	%r7,0(%r7)
305d20d17f6SBrandon Bergren	mtsrr0	%r5
306d20d17f6SBrandon Bergren	mtsrr1	%r7
307d20d17f6SBrandon Bergren	LOAD_LR_NIA
308d20d17f6SBrandon Bergren1:
309d20d17f6SBrandon Bergren	mflr	%r5
310d20d17f6SBrandon Bergren	addi	%r5, %r5, (2f-1b)
311d20d17f6SBrandon Bergren	mtlr	%r5
312d20d17f6SBrandon Bergren	li	%r5, 0
313d20d17f6SBrandon Bergren	rfid
314d20d17f6SBrandon Bergren2:
315d20d17f6SBrandon Bergren	RETURN_TO_NATIVE_ENDIAN
316d20d17f6SBrandon Bergren#else
31717879090SNathan Whitehorn	/* Finally, branch to RTAS */
31817879090SNathan Whitehorn	mtctr	%r5
31917879090SNathan Whitehorn	bctrl
320d20d17f6SBrandon Bergren#endif
32117879090SNathan Whitehorn
32217879090SNathan Whitehorn	/*
3238864f359SNathan Whitehorn	 * Reload stack pointer, MSR, reg PC from the reg save area in r1. We
3248864f359SNathan Whitehorn	 * are running in 32-bit mode at this point, so it doesn't matter if r1
32517879090SNathan Whitehorn	 * has become sign-extended.
32617879090SNathan Whitehorn	 */
3278864f359SNathan Whitehorn	ld	%r7,24(%r1)
32817879090SNathan Whitehorn	ld	%r6,16(%r1)
32917879090SNathan Whitehorn	ld	%r2,8(%r1)
33017879090SNathan Whitehorn	ld	%r1,0(%r1)
33117879090SNathan Whitehorn
3328864f359SNathan Whitehorn	/*
3338864f359SNathan Whitehorn	 * Get back to the right PC. We need to atomically re-enable
3348864f359SNathan Whitehorn	 * exceptions, 64-bit mode, and the MMU. One thing that has likely
3358864f359SNathan Whitehorn	 * happened is that, if we were running in the high-memory direct
3368864f359SNathan Whitehorn	 * map, we no longer are as a result of LR truncation in RTAS.
3378864f359SNathan Whitehorn	 * Fix this by copying the high-order bits of the LR at function
3388864f359SNathan Whitehorn	 * entry onto the current PC and then jumping there while flipping
3398864f359SNathan Whitehorn	 * all the MSR bits.
3408864f359SNathan Whitehorn	 */
3418864f359SNathan Whitehorn	mtsrr1	%r6
3428864f359SNathan Whitehorn	clrrdi	%r7,%r7,32
3438864f359SNathan Whitehorn	bl	1f
3448864f359SNathan Whitehorn1:	mflr	%r8
3458864f359SNathan Whitehorn	or	%r8,%r8,%r7
3468864f359SNathan Whitehorn	addi	%r8,%r8,2f-1b
3478864f359SNathan Whitehorn	mtsrr0	%r8
3488864f359SNathan Whitehorn	rfid			/* Turn on MMU, exceptions, and 64-bit mode */
34917879090SNathan Whitehorn
3508864f359SNathan Whitehorn2:
35117879090SNathan Whitehorn	/* Sign-extend the return value from RTAS */
35217879090SNathan Whitehorn	extsw	%r3,%r3
35317879090SNathan Whitehorn
35417879090SNathan Whitehorn	/* Restore all the non-volatile registers */
35517879090SNathan Whitehorn	ld	%r5,48(%r1)
35617879090SNathan Whitehorn	mtcr	%r5
35717879090SNathan Whitehorn	ld	%r13,56(%r1)
35817879090SNathan Whitehorn	ld	%r14,64(%r1)
35917879090SNathan Whitehorn	ld	%r15,72(%r1)
36017879090SNathan Whitehorn	ld	%r16,80(%r1)
36117879090SNathan Whitehorn	ld	%r17,88(%r1)
36217879090SNathan Whitehorn	ld	%r18,96(%r1)
36317879090SNathan Whitehorn	ld	%r19,104(%r1)
36417879090SNathan Whitehorn	ld	%r20,112(%r1)
36517879090SNathan Whitehorn	ld	%r21,120(%r1)
36617879090SNathan Whitehorn	ld	%r22,128(%r1)
36717879090SNathan Whitehorn	ld	%r23,136(%r1)
36817879090SNathan Whitehorn	ld	%r24,144(%r1)
36917879090SNathan Whitehorn	ld	%r25,152(%r1)
37017879090SNathan Whitehorn	ld	%r26,160(%r1)
37117879090SNathan Whitehorn	ld	%r27,168(%r1)
37217879090SNathan Whitehorn	ld	%r28,176(%r1)
37317879090SNathan Whitehorn	ld	%r29,184(%r1)
37417879090SNathan Whitehorn	ld	%r30,192(%r1)
37517879090SNathan Whitehorn	ld	%r31,200(%r1)
37617879090SNathan Whitehorn
37717879090SNathan Whitehorn	/* Restore the stack and link register */
37817879090SNathan Whitehorn	ld	%r1,0(%r1)
37917879090SNathan Whitehorn	ld	%r0,16(%r1)
38017879090SNathan Whitehorn	mtlr 	%r0
38117879090SNathan Whitehorn	blr
382*78599c32SConrad MeyerASEND(rtascall)
383