1 /* SPDX-License-Identifier: GPL-2.0-or-later */
3 #include <asm/asm-offsets.h>
6 #include <asm/ppc_asm.h>
9 * RTAS is called with MSR IR, DR, EE disabled, and LR in the return address.
11 * Note: r3 is an input parameter to rtas, so don't trash it...
16 stwu r1,-INT_FRAME_SIZE(r1)
18 stw r0,INT_FRAME_SIZE+4(r1)
19 LOAD_REG_ADDR(r4, rtas)
20 lis r6,1f@ha /* physical return address for rtas */
27 li r9,MSR_KERNEL & ~(MSR_IR|MSR_DR)
29 stw r1, THREAD + RTAS_SP(r2)
36 LOAD_REG_IMMEDIATE(r9,MSR_KERNEL)
39 rfi /* Reactivate MMU translation */
41 lwz r8,INT_FRAME_SIZE+4(r1) /* get return address */
42 lwz r9,8(r1) /* original msr value */
43 addi r1,r1,INT_FRAME_SIZE
45 stw r0, THREAD + RTAS_SP(r2)
48 blr /* return to caller */
49 _ASM_NOKPROBE_SYMBOL(enter_rtas)
51 #else /* CONFIG_PPC32 */
52 #include <asm/exception-64s.h>
55 * 32-bit rtas on 64-bit machines has the additional problem that RTAS may
56 * not preserve the upper parts of registers it uses.
61 stdu r1,-SWITCH_FRAME_SIZE(r1) /* Save SP and create stack space. */
63 /* Because RTAS is running in 32b mode, it clobbers the high order half
64 * of all registers that it saves. We therefore save those registers
65 * RTAS might touch to the stack. (r0, r3-r12 are caller saved)
67 SAVE_GPR(2, r1) /* Save the TOC */
68 SAVE_NVGPRS(r1) /* Save the non-volatiles */
81 /* Temporary workaround to clear CR until RTAS can be modified to
89 /* Unfortunately, the stack pointer and the MSR are also clobbered,
90 * so they are saved in the PACA which allows us to restore
91 * our original state after RTAS returns.
94 std r6,PACASAVEDMSR(r13)
96 /* Setup our real return addr */
97 LOAD_REG_ADDR(r4,rtas_return_loc)
98 clrldi r4,r4,2 /* convert to realmode address */
102 LOAD_REG_ADDR(r4, rtas)
103 ld r5,RTASENTRY(r4) /* get the rtas->entry value */
104 ld r4,RTASBASE(r4) /* get the rtas->base value */
107 * RTAS runs in 32-bit big endian real mode, but leave MSR[RI] on as we
108 * may hit NMI (SRESET or MCE) while in RTAS. RTAS should disable RI in
109 * its critical regions (as specified in PAPR+ section 7.2.1). MSR[S]
110 * is not impacted by RFI_TO_KERNEL (only urfid can unset it). So if
111 * MSR[S] is set, it will remain when entering RTAS.
112 * If we're in HV mode, RTAS must also run in HV mode, so extract MSR_HV
113 * from the saved MSR value and insert into the value RTAS will use.
115 extrdi r0, r6, 1, 63 - MSR_HV_LG
116 LOAD_REG_IMMEDIATE(r6, MSR_ME | MSR_RI)
117 insrdi r6, r0, 1, 63 - MSR_HV_LG
120 mtmsrd r0,1 /* disable RI before using SRR0/1 */
125 b . /* prevent speculative execution */
129 /* Set SF before anything. */
130 LOAD_REG_IMMEDIATE(r6, MSR_KERNEL & ~(MSR_IR|MSR_DR))
133 /* relocation is off at this point */
138 ld r3,(1f-0b)(r3) /* get &rtas_restore_regs */
140 ld r1,PACAR1(r13) /* Restore our SP */
141 ld r4,PACASAVEDMSR(r13) /* Restore our MSR */
146 b . /* prevent speculative execution */
147 _ASM_NOKPROBE_SYMBOL(enter_rtas)
148 _ASM_NOKPROBE_SYMBOL(__enter_rtas)
149 _ASM_NOKPROBE_SYMBOL(rtas_return_loc)
152 1: .8byte rtas_restore_regs
155 /* relocation is on at this point */
156 REST_GPR(2, r1) /* Restore the TOC */
157 REST_NVGPRS(r1) /* Restore the non-volatiles */
170 addi r1,r1,SWITCH_FRAME_SIZE /* Unstack our frame */
171 ld r0,16(r1) /* get return address */
174 blr /* return to caller */
176 #endif /* CONFIG_PPC32 */