]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blob - arch/powerpc/platforms/pseries/hvCall.S
powerpc: Remove second definition of STACK_FRAME_OVERHEAD
[mirror_ubuntu-zesty-kernel.git] / arch / powerpc / platforms / pseries / hvCall.S
1 /*
2 * This file contains the generic code to perform a call to the
3 * pSeries LPAR hypervisor.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version
8 * 2 of the License, or (at your option) any later version.
9 */
10 #include <asm/hvcall.h>
11 #include <asm/processor.h>
12 #include <asm/ppc_asm.h>
13 #include <asm/asm-offsets.h>
14 #include <asm/ptrace.h>
15
16 #define STK_PARM(i) (48 + ((i)-3)*8)
17
18 #ifdef CONFIG_TRACEPOINTS
19
20 .section ".toc","aw"
21
22 .globl hcall_tracepoint_refcount
23 hcall_tracepoint_refcount:
24 .llong 0
25
26 .section ".text"
27
28 /*
29 * precall must preserve all registers. use unused STK_PARM()
30 * areas to save snapshots and opcode. We branch around this
31 * in early init (eg when populating the MMU hashtable) by using an
32 * unconditional cpu feature.
33 */
34 #define HCALL_INST_PRECALL(FIRST_REG) \
35 BEGIN_FTR_SECTION; \
36 b 1f; \
37 END_FTR_SECTION(0, 1); \
38 ld r12,hcall_tracepoint_refcount@toc(r2); \
39 cmpdi r12,0; \
40 beq+ 1f; \
41 mflr r0; \
42 std r3,STK_PARM(r3)(r1); \
43 std r4,STK_PARM(r4)(r1); \
44 std r5,STK_PARM(r5)(r1); \
45 std r6,STK_PARM(r6)(r1); \
46 std r7,STK_PARM(r7)(r1); \
47 std r8,STK_PARM(r8)(r1); \
48 std r9,STK_PARM(r9)(r1); \
49 std r10,STK_PARM(r10)(r1); \
50 std r0,16(r1); \
51 addi r4,r1,STK_PARM(FIRST_REG); \
52 stdu r1,-STACK_FRAME_OVERHEAD(r1); \
53 bl .__trace_hcall_entry; \
54 addi r1,r1,STACK_FRAME_OVERHEAD; \
55 ld r0,16(r1); \
56 ld r3,STK_PARM(r3)(r1); \
57 ld r4,STK_PARM(r4)(r1); \
58 ld r5,STK_PARM(r5)(r1); \
59 ld r6,STK_PARM(r6)(r1); \
60 ld r7,STK_PARM(r7)(r1); \
61 ld r8,STK_PARM(r8)(r1); \
62 ld r9,STK_PARM(r9)(r1); \
63 ld r10,STK_PARM(r10)(r1); \
64 mtlr r0; \
65 1:
66
67 /*
68 * postcall is performed immediately before function return which
69 * allows liberal use of volatile registers. We branch around this
70 * in early init (eg when populating the MMU hashtable) by using an
71 * unconditional cpu feature.
72 */
73 #define __HCALL_INST_POSTCALL \
74 BEGIN_FTR_SECTION; \
75 b 1f; \
76 END_FTR_SECTION(0, 1); \
77 ld r12,hcall_tracepoint_refcount@toc(r2); \
78 cmpdi r12,0; \
79 beq+ 1f; \
80 mflr r0; \
81 ld r6,STK_PARM(r3)(r1); \
82 std r3,STK_PARM(r3)(r1); \
83 mr r4,r3; \
84 mr r3,r6; \
85 std r0,16(r1); \
86 stdu r1,-STACK_FRAME_OVERHEAD(r1); \
87 bl .__trace_hcall_exit; \
88 addi r1,r1,STACK_FRAME_OVERHEAD; \
89 ld r0,16(r1); \
90 ld r3,STK_PARM(r3)(r1); \
91 mtlr r0; \
92 1:
93
94 #define HCALL_INST_POSTCALL_NORETS \
95 li r5,0; \
96 __HCALL_INST_POSTCALL
97
98 #define HCALL_INST_POSTCALL(BUFREG) \
99 mr r5,BUFREG; \
100 __HCALL_INST_POSTCALL
101
102 #else
103 #define HCALL_INST_PRECALL(FIRST_ARG)
104 #define HCALL_INST_POSTCALL_NORETS
105 #define HCALL_INST_POSTCALL(BUFREG)
106 #endif
107
108 .text
109
110 _GLOBAL(plpar_hcall_norets)
111 HMT_MEDIUM
112
113 mfcr r0
114 stw r0,8(r1)
115
116 HCALL_INST_PRECALL(r4)
117
118 HVSC /* invoke the hypervisor */
119
120 HCALL_INST_POSTCALL_NORETS
121
122 lwz r0,8(r1)
123 mtcrf 0xff,r0
124 blr /* return r3 = status */
125
126 _GLOBAL(plpar_hcall)
127 HMT_MEDIUM
128
129 mfcr r0
130 stw r0,8(r1)
131
132 HCALL_INST_PRECALL(r5)
133
134 std r4,STK_PARM(r4)(r1) /* Save ret buffer */
135
136 mr r4,r5
137 mr r5,r6
138 mr r6,r7
139 mr r7,r8
140 mr r8,r9
141 mr r9,r10
142
143 HVSC /* invoke the hypervisor */
144
145 ld r12,STK_PARM(r4)(r1)
146 std r4, 0(r12)
147 std r5, 8(r12)
148 std r6, 16(r12)
149 std r7, 24(r12)
150
151 HCALL_INST_POSTCALL(r12)
152
153 lwz r0,8(r1)
154 mtcrf 0xff,r0
155
156 blr /* return r3 = status */
157
158 /*
159 * plpar_hcall_raw can be called in real mode. kexec/kdump need some
160 * hypervisor calls to be executed in real mode. So plpar_hcall_raw
161 * does not access the per cpu hypervisor call statistics variables,
162 * since these variables may not be present in the RMO region.
163 */
164 _GLOBAL(plpar_hcall_raw)
165 HMT_MEDIUM
166
167 mfcr r0
168 stw r0,8(r1)
169
170 std r4,STK_PARM(r4)(r1) /* Save ret buffer */
171
172 mr r4,r5
173 mr r5,r6
174 mr r6,r7
175 mr r7,r8
176 mr r8,r9
177 mr r9,r10
178
179 HVSC /* invoke the hypervisor */
180
181 ld r12,STK_PARM(r4)(r1)
182 std r4, 0(r12)
183 std r5, 8(r12)
184 std r6, 16(r12)
185 std r7, 24(r12)
186
187 lwz r0,8(r1)
188 mtcrf 0xff,r0
189
190 blr /* return r3 = status */
191
192 _GLOBAL(plpar_hcall9)
193 HMT_MEDIUM
194
195 mfcr r0
196 stw r0,8(r1)
197
198 HCALL_INST_PRECALL(r5)
199
200 std r4,STK_PARM(r4)(r1) /* Save ret buffer */
201
202 mr r4,r5
203 mr r5,r6
204 mr r6,r7
205 mr r7,r8
206 mr r8,r9
207 mr r9,r10
208 ld r10,STK_PARM(r11)(r1) /* put arg7 in R10 */
209 ld r11,STK_PARM(r12)(r1) /* put arg8 in R11 */
210 ld r12,STK_PARM(r13)(r1) /* put arg9 in R12 */
211
212 HVSC /* invoke the hypervisor */
213
214 mr r0,r12
215 ld r12,STK_PARM(r4)(r1)
216 std r4, 0(r12)
217 std r5, 8(r12)
218 std r6, 16(r12)
219 std r7, 24(r12)
220 std r8, 32(r12)
221 std r9, 40(r12)
222 std r10,48(r12)
223 std r11,56(r12)
224 std r0, 64(r12)
225
226 HCALL_INST_POSTCALL(r12)
227
228 lwz r0,8(r1)
229 mtcrf 0xff,r0
230
231 blr /* return r3 = status */
232
233 /* See plpar_hcall_raw to see why this is needed */
234 _GLOBAL(plpar_hcall9_raw)
235 HMT_MEDIUM
236
237 mfcr r0
238 stw r0,8(r1)
239
240 std r4,STK_PARM(r4)(r1) /* Save ret buffer */
241
242 mr r4,r5
243 mr r5,r6
244 mr r6,r7
245 mr r7,r8
246 mr r8,r9
247 mr r9,r10
248 ld r10,STK_PARM(r11)(r1) /* put arg7 in R10 */
249 ld r11,STK_PARM(r12)(r1) /* put arg8 in R11 */
250 ld r12,STK_PARM(r13)(r1) /* put arg9 in R12 */
251
252 HVSC /* invoke the hypervisor */
253
254 mr r0,r12
255 ld r12,STK_PARM(r4)(r1)
256 std r4, 0(r12)
257 std r5, 8(r12)
258 std r6, 16(r12)
259 std r7, 24(r12)
260 std r8, 32(r12)
261 std r9, 40(r12)
262 std r10,48(r12)
263 std r11,56(r12)
264 std r0, 64(r12)
265
266 lwz r0,8(r1)
267 mtcrf 0xff,r0
268
269 blr /* return r3 = status */