~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/powerpc/kernel/rtas_entry.S

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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
 33 1:
 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 */
 40 1:
 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          * 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.
114          */
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
118 
119         li      r0,0
120         mtmsrd  r0,1                    /* disable RI before using SRR0/1 */
121         
122         mtspr   SPRN_SRR0,r5
123         mtspr   SPRN_SRR1,r6
124         RFI_TO_KERNEL
125         b       .       /* prevent speculative execution */
126 rtas_return_loc:
127         FIXUP_ENDIAN
128 
129         /* Set SF before anything. */
130         LOAD_REG_IMMEDIATE(r6, MSR_KERNEL & ~(MSR_IR|MSR_DR))
131         mtmsrd  r6
132 
133         /* relocation is off at this point */
134         GET_PACA(r13)
135 
136         bcl     20,31,$+4
137 0:      mflr    r3
138         ld      r3,(1f-0b)(r3)          /* get &rtas_restore_regs */
139 
140         ld      r1,PACAR1(r13)          /* Restore our SP */
141         ld      r4,PACASAVEDMSR(r13)    /* Restore our MSR */
142 
143         mtspr   SPRN_SRR0,r3
144         mtspr   SPRN_SRR1,r4
145         RFI_TO_KERNEL
146         b       .       /* prevent speculative execution */
147 _ASM_NOKPROBE_SYMBOL(enter_rtas)
148 _ASM_NOKPROBE_SYMBOL(__enter_rtas)
149 _ASM_NOKPROBE_SYMBOL(rtas_return_loc)
150 
151         .align  3
152 1:      .8byte  rtas_restore_regs
153 
154 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 */
158 
159         ld      r4,_CCR(r1)
160         mtcr    r4
161         ld      r5,_CTR(r1)
162         mtctr   r5
163         ld      r6,_XER(r1)
164         mtspr   SPRN_XER,r6
165         ld      r7,_DAR(r1)
166         mtdar   r7
167         ld      r8,_DSISR(r1)
168         mtdsisr r8
169 
170         addi    r1,r1,SWITCH_FRAME_SIZE /* Unstack our frame */
171         ld      r0,16(r1)               /* get return address */
172 
173         mtlr    r0
174         blr                             /* return to caller */
175 
176 #endif /* CONFIG_PPC32 */

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php