Merge tag 'for-linus-v4.8' of git://github.com/martinbrandenburg/linux
[deliverable/linux.git] / arch / powerpc / platforms / pseries / hvCall.S
CommitLineData
1da177e4 1/*
1da177e4
LT
2 * This file contains the generic code to perform a call to the
3 * pSeries LPAR hypervisor.
1da177e4
LT
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 */
58995a9a 10#include <linux/jump_label.h>
1da177e4
LT
11#include <asm/hvcall.h>
12#include <asm/processor.h>
13#include <asm/ppc_asm.h>
57852a85 14#include <asm/asm-offsets.h>
46f52210 15#include <asm/ptrace.h>
cc1adb5f
AB
16
17 .section ".text"
1da177e4 18
c8cd093a
AB
19#ifdef CONFIG_TRACEPOINTS
20
1bc9e47a 21#ifndef HAVE_JUMP_LABEL
c8cd093a
AB
22 .section ".toc","aw"
23
24 .globl hcall_tracepoint_refcount
25hcall_tracepoint_refcount:
26 .llong 0
27
28 .section ".text"
cc1adb5f 29#endif
c8cd093a 30
57852a85 31/*
44ce6a5e 32 * precall must preserve all registers. use unused STK_PARAM()
cc1adb5f 33 * areas to save snapshots and opcode.
57852a85 34 */
6f26353c 35#define HCALL_INST_PRECALL(FIRST_REG) \
c8cd093a 36 mflr r0; \
44ce6a5e
MN
37 std r3,STK_PARAM(R3)(r1); \
38 std r4,STK_PARAM(R4)(r1); \
39 std r5,STK_PARAM(R5)(r1); \
40 std r6,STK_PARAM(R6)(r1); \
41 std r7,STK_PARAM(R7)(r1); \
42 std r8,STK_PARAM(R8)(r1); \
43 std r9,STK_PARAM(R9)(r1); \
44 std r10,STK_PARAM(R10)(r1); \
c8cd093a 45 std r0,16(r1); \
44ce6a5e 46 addi r4,r1,STK_PARAM(FIRST_REG); \
c8cd093a 47 stdu r1,-STACK_FRAME_OVERHEAD(r1); \
b1576fec 48 bl __trace_hcall_entry; \
aaad4224
AB
49 ld r3,STACK_FRAME_OVERHEAD+STK_PARAM(R3)(r1); \
50 ld r4,STACK_FRAME_OVERHEAD+STK_PARAM(R4)(r1); \
51 ld r5,STACK_FRAME_OVERHEAD+STK_PARAM(R5)(r1); \
52 ld r6,STACK_FRAME_OVERHEAD+STK_PARAM(R6)(r1); \
53 ld r7,STACK_FRAME_OVERHEAD+STK_PARAM(R7)(r1); \
54 ld r8,STACK_FRAME_OVERHEAD+STK_PARAM(R8)(r1); \
55 ld r9,STACK_FRAME_OVERHEAD+STK_PARAM(R9)(r1); \
56 ld r10,STACK_FRAME_OVERHEAD+STK_PARAM(R10)(r1)
c8cd093a 57
57852a85
MK
58/*
59 * postcall is performed immediately before function return which
cc1adb5f 60 * allows liberal use of volatile registers.
57852a85 61 */
6f26353c 62#define __HCALL_INST_POSTCALL \
aaad4224
AB
63 ld r0,STACK_FRAME_OVERHEAD+STK_PARAM(R3)(r1); \
64 std r3,STACK_FRAME_OVERHEAD+STK_PARAM(R3)(r1); \
c8cd093a 65 mr r4,r3; \
aaad4224 66 mr r3,r0; \
b1576fec 67 bl __trace_hcall_exit; \
aaad4224 68 ld r0,STACK_FRAME_OVERHEAD+16(r1); \
c8cd093a 69 addi r1,r1,STACK_FRAME_OVERHEAD; \
44ce6a5e 70 ld r3,STK_PARAM(R3)(r1); \
cc1adb5f 71 mtlr r0
6f26353c
AB
72
73#define HCALL_INST_POSTCALL_NORETS \
74 li r5,0; \
75 __HCALL_INST_POSTCALL
76
77#define HCALL_INST_POSTCALL(BUFREG) \
78 mr r5,BUFREG; \
79 __HCALL_INST_POSTCALL
80
1bc9e47a 81#ifdef HAVE_JUMP_LABEL
cc1adb5f
AB
82#define HCALL_BRANCH(LABEL) \
83 ARCH_STATIC_BRANCH(LABEL, hcall_tracepoint_key)
84#else
85
86/*
87 * We branch around this in early init (eg when populating the MMU
88 * hashtable) by using an unconditional cpu feature.
89 */
90#define HCALL_BRANCH(LABEL) \
91BEGIN_FTR_SECTION; \
92 b 1f; \
93END_FTR_SECTION(0, 1); \
94 ld r12,hcall_tracepoint_refcount@toc(r2); \
95 std r12,32(r1); \
96 cmpdi r12,0; \
97 bne- LABEL; \
981:
99#endif
100
57852a85 101#else
6f26353c
AB
102#define HCALL_INST_PRECALL(FIRST_ARG)
103#define HCALL_INST_POSTCALL_NORETS
104#define HCALL_INST_POSTCALL(BUFREG)
cc1adb5f 105#define HCALL_BRANCH(LABEL)
57852a85
MK
106#endif
107
c1931e21 108_GLOBAL_TOC(plpar_hcall_norets)
eeb24de4
AB
109 HMT_MEDIUM
110
1da177e4
LT
111 mfcr r0
112 stw r0,8(r1)
cc1adb5f 113 HCALL_BRANCH(plpar_hcall_norets_trace)
1da177e4
LT
114 HVSC /* invoke the hypervisor */
115
116 lwz r0,8(r1)
117 mtcrf 0xff,r0
118 blr /* return r3 = status */
119
cc1adb5f
AB
120#ifdef CONFIG_TRACEPOINTS
121plpar_hcall_norets_trace:
122 HCALL_INST_PRECALL(R4)
123 HVSC
124 HCALL_INST_POSTCALL_NORETS
125 lwz r0,8(r1)
126 mtcrf 0xff,r0
127 blr
128#endif
129
c1931e21 130_GLOBAL_TOC(plpar_hcall)
eeb24de4
AB
131 HMT_MEDIUM
132
1da177e4 133 mfcr r0
1da177e4
LT
134 stw r0,8(r1)
135
cc1adb5f 136 HCALL_BRANCH(plpar_hcall_trace)
57852a85 137
44ce6a5e 138 std r4,STK_PARAM(R4)(r1) /* Save ret buffer */
1da177e4 139
b9377ffc
AB
140 mr r4,r5
141 mr r5,r6
142 mr r6,r7
143 mr r7,r8
144 mr r8,r9
145 mr r9,r10
1da177e4
LT
146
147 HVSC /* invoke the hypervisor */
148
44ce6a5e 149 ld r12,STK_PARAM(R4)(r1)
b9377ffc
AB
150 std r4, 0(r12)
151 std r5, 8(r12)
152 std r6, 16(r12)
153 std r7, 24(r12)
b13a96cf 154
cc1adb5f
AB
155 lwz r0,8(r1)
156 mtcrf 0xff,r0
157
158 blr /* return r3 = status */
159
160#ifdef CONFIG_TRACEPOINTS
161plpar_hcall_trace:
162 HCALL_INST_PRECALL(R5)
163
164 std r4,STK_PARAM(R4)(r1)
165 mr r0,r4
166
167 mr r4,r5
168 mr r5,r6
169 mr r6,r7
170 mr r7,r8
171 mr r8,r9
172 mr r9,r10
173
174 HVSC
175
176 ld r12,STK_PARAM(R4)(r1)
177 std r4,0(r12)
178 std r5,8(r12)
179 std r6,16(r12)
180 std r7,24(r12)
181
6f26353c 182 HCALL_INST_POSTCALL(r12)
57852a85 183
b13a96cf 184 lwz r0,8(r1)
b13a96cf
HS
185 mtcrf 0xff,r0
186
cc1adb5f
AB
187 blr
188#endif
b13a96cf 189
b4aea36b
MK
190/*
191 * plpar_hcall_raw can be called in real mode. kexec/kdump need some
192 * hypervisor calls to be executed in real mode. So plpar_hcall_raw
193 * does not access the per cpu hypervisor call statistics variables,
194 * since these variables may not be present in the RMO region.
195 */
196_GLOBAL(plpar_hcall_raw)
197 HMT_MEDIUM
198
199 mfcr r0
200 stw r0,8(r1)
201
44ce6a5e 202 std r4,STK_PARAM(R4)(r1) /* Save ret buffer */
b4aea36b
MK
203
204 mr r4,r5
205 mr r5,r6
206 mr r6,r7
207 mr r7,r8
208 mr r8,r9
209 mr r9,r10
210
211 HVSC /* invoke the hypervisor */
212
44ce6a5e 213 ld r12,STK_PARAM(R4)(r1)
b4aea36b
MK
214 std r4, 0(r12)
215 std r5, 8(r12)
216 std r6, 16(r12)
217 std r7, 24(r12)
218
219 lwz r0,8(r1)
220 mtcrf 0xff,r0
221
222 blr /* return r3 = status */
223
c1931e21 224_GLOBAL_TOC(plpar_hcall9)
b13a96cf
HS
225 HMT_MEDIUM
226
227 mfcr r0
228 stw r0,8(r1)
229
cc1adb5f 230 HCALL_BRANCH(plpar_hcall9_trace)
57852a85 231
44ce6a5e 232 std r4,STK_PARAM(R4)(r1) /* Save ret buffer */
b9377ffc
AB
233
234 mr r4,r5
235 mr r5,r6
236 mr r6,r7
237 mr r7,r8
238 mr r8,r9
239 mr r9,r10
44ce6a5e
MN
240 ld r10,STK_PARAM(R11)(r1) /* put arg7 in R10 */
241 ld r11,STK_PARAM(R12)(r1) /* put arg8 in R11 */
242 ld r12,STK_PARAM(R13)(r1) /* put arg9 in R12 */
b13a96cf
HS
243
244 HVSC /* invoke the hypervisor */
245
ab87e8dc 246 mr r0,r12
44ce6a5e 247 ld r12,STK_PARAM(R4)(r1)
b9377ffc
AB
248 std r4, 0(r12)
249 std r5, 8(r12)
250 std r6, 16(r12)
251 std r7, 24(r12)
252 std r8, 32(r12)
253 std r9, 40(r12)
254 std r10,48(r12)
255 std r11,56(r12)
ab87e8dc 256 std r0, 64(r12)
b13a96cf 257
cc1adb5f
AB
258 lwz r0,8(r1)
259 mtcrf 0xff,r0
260
261 blr /* return r3 = status */
262
263#ifdef CONFIG_TRACEPOINTS
264plpar_hcall9_trace:
265 HCALL_INST_PRECALL(R5)
266
267 std r4,STK_PARAM(R4)(r1)
268 mr r0,r4
269
270 mr r4,r5
271 mr r5,r6
272 mr r6,r7
273 mr r7,r8
274 mr r8,r9
275 mr r9,r10
aaad4224
AB
276 ld r10,STACK_FRAME_OVERHEAD+STK_PARAM(R11)(r1)
277 ld r11,STACK_FRAME_OVERHEAD+STK_PARAM(R12)(r1)
278 ld r12,STACK_FRAME_OVERHEAD+STK_PARAM(R13)(r1)
cc1adb5f
AB
279
280 HVSC
281
282 mr r0,r12
aaad4224 283 ld r12,STACK_FRAME_OVERHEAD+STK_PARAM(R4)(r1)
cc1adb5f
AB
284 std r4,0(r12)
285 std r5,8(r12)
286 std r6,16(r12)
287 std r7,24(r12)
288 std r8,32(r12)
289 std r9,40(r12)
290 std r10,48(r12)
291 std r11,56(r12)
292 std r0,64(r12)
293
6f26353c 294 HCALL_INST_POSTCALL(r12)
57852a85 295
b13a96cf
HS
296 lwz r0,8(r1)
297 mtcrf 0xff,r0
298
cc1adb5f
AB
299 blr
300#endif
f90ece28
MN
301
302/* See plpar_hcall_raw to see why this is needed */
303_GLOBAL(plpar_hcall9_raw)
304 HMT_MEDIUM
305
306 mfcr r0
307 stw r0,8(r1)
308
44ce6a5e 309 std r4,STK_PARAM(R4)(r1) /* Save ret buffer */
f90ece28
MN
310
311 mr r4,r5
312 mr r5,r6
313 mr r6,r7
314 mr r7,r8
315 mr r8,r9
316 mr r9,r10
44ce6a5e
MN
317 ld r10,STK_PARAM(R11)(r1) /* put arg7 in R10 */
318 ld r11,STK_PARAM(R12)(r1) /* put arg8 in R11 */
319 ld r12,STK_PARAM(R13)(r1) /* put arg9 in R12 */
f90ece28
MN
320
321 HVSC /* invoke the hypervisor */
322
323 mr r0,r12
44ce6a5e 324 ld r12,STK_PARAM(R4)(r1)
f90ece28
MN
325 std r4, 0(r12)
326 std r5, 8(r12)
327 std r6, 16(r12)
328 std r7, 24(r12)
329 std r8, 32(r12)
330 std r9, 40(r12)
331 std r10,48(r12)
332 std r11,56(r12)
333 std r0, 64(r12)
334
335 lwz r0,8(r1)
336 mtcrf 0xff,r0
337
338 blr /* return r3 = status */
This page took 0.814277 seconds and 5 git commands to generate.