1/* SPDX-License-Identifier: GPL-2.0-or-later */
2/*
3 *  PowerPC version
4 *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
5 *  Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP
6 *    Copyright (C) 1996 Cort Dougan <cort@cs.nmt.edu>
7 *  Adapted for Power Macintosh by Paul Mackerras.
8 *  Low-level exception handlers and MMU support
9 *  rewritten by Paul Mackerras.
10 *    Copyright (C) 1996 Paul Mackerras.
11 *  MPC8xx modifications Copyright (C) 1997 Dan Malek (dmalek@jlc.net).
12 *
13 *  This file contains the 64-bit prom entry code.
14 */
15#include <asm/asm-offsets.h>
16#ifdef CONFIG_PPC_BOOK3S
17#include <asm/exception-64s.h>
18#else
19#include <asm/exception-64e.h>
20#endif
21#include <asm/ppc_asm.h>
22
23.section ".text","ax",@progbits
24
25_GLOBAL(enter_prom)
26	mflr	r0
27	std	r0,16(r1)
28        stdu	r1,-SWITCH_FRAME_SIZE(r1) /* Save SP and create stack space */
29
30	/* Because PROM is running in 32b mode, it clobbers the high order half
31	 * of all registers that it saves.  We therefore save those registers
32	 * PROM might touch to the stack.  (r0, r3-r13 are caller saved)
33   	 */
34	SAVE_GPR(2, r1)
35	SAVE_GPR(13, r1)
36	SAVE_NVGPRS(r1)
37	mfcr	r10
38	mfmsr	r11
39	std	r10,_CCR(r1)
40	std	r11,_MSR(r1)
41
42	/* Put PROM address in SRR0 */
43	mtsrr0	r4
44
45	/* Setup our trampoline return addr in LR */
46	bcl	20,31,$+4
470:	mflr	r4
48	addi	r4,r4,(1f - 0b)
49       	mtlr	r4
50
51	/* Prepare a 32-bit mode big endian MSR
52	 */
53#ifdef CONFIG_PPC_BOOK3E_64
54	rlwinm	r11,r11,0,1,31
55	mtsrr1	r11
56	rfi
57#else /* CONFIG_PPC_BOOK3E_64 */
58	LOAD_REG_IMMEDIATE(r12, MSR_SF | MSR_LE)
59	andc	r11,r11,r12
60	mtsrr1	r11
61	RFI_TO_KERNEL
62#endif /* CONFIG_PPC_BOOK3E_64 */
63
641:	/* Return from OF */
65	FIXUP_ENDIAN
66
67	/* Just make sure that r1 top 32 bits didn't get
68	 * corrupt by OF
69	 */
70	rldicl	r1,r1,0,32
71
72	/* Restore the MSR (back to 64 bits) */
73	ld	r0,_MSR(r1)
74	MTMSRD(r0)
75        isync
76
77	/* Restore other registers */
78	REST_GPR(2, r1)
79	REST_GPR(13, r1)
80	REST_NVGPRS(r1)
81	ld	r4,_CCR(r1)
82	mtcr	r4
83
84        addi	r1,r1,SWITCH_FRAME_SIZE
85	ld	r0,16(r1)
86	mtlr    r0
87        blr
88