arm64: dts: qcom: sm8550: add TRNG node
[linux-modified.git] / arch / powerpc / kernel / rtas_entry.S
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 */