rtas_entry.S (4103B)
1/* SPDX-License-Identifier: GPL-2.0-or-later */ 2 3#include <asm/asm-offsets.h> 4#include <asm/bug.h> 5#include <asm/page.h> 6#include <asm/ppc_asm.h> 7 8/* 9 * RTAS is called with MSR IR, DR, EE disabled, and LR in the return address. 10 * 11 * Note: r3 is an input parameter to rtas, so don't trash it... 12 */ 13 14#ifdef CONFIG_PPC32 15_GLOBAL(enter_rtas) 16 stwu r1,-INT_FRAME_SIZE(r1) 17 mflr r0 18 stw r0,INT_FRAME_SIZE+4(r1) 19 LOAD_REG_ADDR(r4, rtas) 20 lis r6,1f@ha /* physical return address for rtas */ 21 addi r6,r6,1f@l 22 tophys(r6,r6) 23 lwz r8,RTASENTRY(r4) 24 lwz r4,RTASBASE(r4) 25 mfmsr r9 26 stw r9,8(r1) 27 li r9,MSR_KERNEL & ~(MSR_IR|MSR_DR) 28 mtlr r6 29 stw r1, THREAD + RTAS_SP(r2) 30 mtspr SPRN_SRR0,r8 31 mtspr SPRN_SRR1,r9 32 rfi 331: 34 lis r8, 1f@h 35 ori r8, r8, 1f@l 36 LOAD_REG_IMMEDIATE(r9,MSR_KERNEL) 37 mtspr SPRN_SRR0,r8 38 mtspr SPRN_SRR1,r9 39 rfi /* Reactivate MMU translation */ 401: 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 44 li r0,0 45 stw r0, THREAD + RTAS_SP(r2) 46 mtlr r8 47 mtmsr r9 48 blr /* return to caller */ 49_ASM_NOKPROBE_SYMBOL(enter_rtas) 50 51#else /* CONFIG_PPC32 */ 52#include <asm/exception-64s.h> 53 54/* 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. 57 */ 58_GLOBAL(enter_rtas) 59 mflr r0 60 std r0,16(r1) 61 stdu r1,-SWITCH_FRAME_SIZE(r1) /* Save SP and create stack space. */ 62 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) 66 */ 67 SAVE_GPR(2, r1) /* Save the TOC */ 68 SAVE_NVGPRS(r1) /* Save the non-volatiles */ 69 70 mfcr r4 71 std r4,_CCR(r1) 72 mfctr r5 73 std r5,_CTR(r1) 74 mfspr r6,SPRN_XER 75 std r6,_XER(r1) 76 mfdar r7 77 std r7,_DAR(r1) 78 mfdsisr r8 79 std r8,_DSISR(r1) 80 81 /* Temporary workaround to clear CR until RTAS can be modified to 82 * ignore all bits. 83 */ 84 li r0,0 85 mtcr r0 86 87 mfmsr r6 88 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. 92 */ 93 std r1,PACAR1(r13) 94 std r6,PACASAVEDMSR(r13) 95 96 /* Setup our real return addr */ 97 LOAD_REG_ADDR(r4,rtas_return_loc) 98 clrldi r4,r4,2 /* convert to realmode address */ 99 mtlr r4 100 101__enter_rtas: 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 */ 105 106 /* 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 */ 113 LOAD_REG_IMMEDIATE(r6, MSR_ME | MSR_RI) 114 115 li r0,0 116 mtmsrd r0,1 /* disable RI before using SRR0/1 */ 117 118 mtspr SPRN_SRR0,r5 119 mtspr SPRN_SRR1,r6 120 RFI_TO_KERNEL 121 b . /* prevent speculative execution */ 122rtas_return_loc: 123 FIXUP_ENDIAN 124 125 /* Set SF before anything. */ 126 LOAD_REG_IMMEDIATE(r6, MSR_KERNEL & ~(MSR_IR|MSR_DR)) 127 mtmsrd r6 128 129 /* relocation is off at this point */ 130 GET_PACA(r13) 131 132 bcl 20,31,$+4 1330: mflr r3 134 ld r3,(1f-0b)(r3) /* get &rtas_restore_regs */ 135 136 ld r1,PACAR1(r13) /* Restore our SP */ 137 ld r4,PACASAVEDMSR(r13) /* Restore our MSR */ 138 139 mtspr SPRN_SRR0,r3 140 mtspr SPRN_SRR1,r4 141 RFI_TO_KERNEL 142 b . /* prevent speculative execution */ 143_ASM_NOKPROBE_SYMBOL(enter_rtas) 144_ASM_NOKPROBE_SYMBOL(__enter_rtas) 145_ASM_NOKPROBE_SYMBOL(rtas_return_loc) 146 147 .align 3 1481: .8byte rtas_restore_regs 149 150rtas_restore_regs: 151 /* relocation is on at this point */ 152 REST_GPR(2, r1) /* Restore the TOC */ 153 REST_NVGPRS(r1) /* Restore the non-volatiles */ 154 155 ld r4,_CCR(r1) 156 mtcr r4 157 ld r5,_CTR(r1) 158 mtctr r5 159 ld r6,_XER(r1) 160 mtspr SPRN_XER,r6 161 ld r7,_DAR(r1) 162 mtdar r7 163 ld r8,_DSISR(r1) 164 mtdsisr r8 165 166 addi r1,r1,SWITCH_FRAME_SIZE /* Unstack our frame */ 167 ld r0,16(r1) /* get return address */ 168 169 mtlr r0 170 blr /* return to caller */ 171 172#endif /* CONFIG_PPC32 */