hvCall.S (f1615bbe9be4def59c3b3eaddb60722efeed16c2) hvCall.S (cc1adb5f32557f10f48e8febbef7278a2db9d593)
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>
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#include <asm/jump_label.h>
16
17 .section ".text"
15
16#ifdef CONFIG_TRACEPOINTS
17
18
19#ifdef CONFIG_TRACEPOINTS
20
21#ifndef CONFIG_JUMP_LABEL
18 .section ".toc","aw"
19
20 .globl hcall_tracepoint_refcount
21hcall_tracepoint_refcount:
22 .llong 0
23
24 .section ".text"
22 .section ".toc","aw"
23
24 .globl hcall_tracepoint_refcount
25hcall_tracepoint_refcount:
26 .llong 0
27
28 .section ".text"
29#endif
25
26/*
27 * precall must preserve all registers. use unused STK_PARAM()
30
31/*
32 * precall must preserve all registers. use unused STK_PARAM()
28 * areas to save snapshots and opcode. We branch around this
29 * in early init (eg when populating the MMU hashtable) by using an
30 * unconditional cpu feature.
33 * areas to save snapshots and opcode.
31 */
32#define HCALL_INST_PRECALL(FIRST_REG) \
34 */
35#define HCALL_INST_PRECALL(FIRST_REG) \
33BEGIN_FTR_SECTION; \
34 b 1f; \
35END_FTR_SECTION(0, 1); \
36 ld r12,hcall_tracepoint_refcount@toc(r2); \
37 std r12,32(r1); \
38 cmpdi r12,0; \
39 beq+ 1f; \
40 mflr r0; \
41 std r3,STK_PARAM(R3)(r1); \
42 std r4,STK_PARAM(R4)(r1); \
43 std r5,STK_PARAM(R5)(r1); \
44 std r6,STK_PARAM(R6)(r1); \
45 std r7,STK_PARAM(R7)(r1); \
46 std r8,STK_PARAM(R8)(r1); \
47 std r9,STK_PARAM(R9)(r1); \

--- 7 unchanged lines hidden (view full) ---

55 ld r3,STK_PARAM(R3)(r1); \
56 ld r4,STK_PARAM(R4)(r1); \
57 ld r5,STK_PARAM(R5)(r1); \
58 ld r6,STK_PARAM(R6)(r1); \
59 ld r7,STK_PARAM(R7)(r1); \
60 ld r8,STK_PARAM(R8)(r1); \
61 ld r9,STK_PARAM(R9)(r1); \
62 ld r10,STK_PARAM(R10)(r1); \
36 mflr r0; \
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); \

--- 7 unchanged lines hidden (view full) ---

51 ld r3,STK_PARAM(R3)(r1); \
52 ld r4,STK_PARAM(R4)(r1); \
53 ld r5,STK_PARAM(R5)(r1); \
54 ld r6,STK_PARAM(R6)(r1); \
55 ld r7,STK_PARAM(R7)(r1); \
56 ld r8,STK_PARAM(R8)(r1); \
57 ld r9,STK_PARAM(R9)(r1); \
58 ld r10,STK_PARAM(R10)(r1); \
63 mtlr r0; \
641:
59 mtlr r0
65
66/*
67 * postcall is performed immediately before function return which
60
61/*
62 * postcall is performed immediately before function return which
68 * allows liberal use of volatile registers. We branch around this
69 * in early init (eg when populating the MMU hashtable) by using an
70 * unconditional cpu feature.
63 * allows liberal use of volatile registers.
71 */
72#define __HCALL_INST_POSTCALL \
64 */
65#define __HCALL_INST_POSTCALL \
73BEGIN_FTR_SECTION; \
74 b 1f; \
75END_FTR_SECTION(0, 1); \
76 ld r12,32(r1); \
77 cmpdi r12,0; \
78 beq+ 1f; \
79 mflr r0; \
80 ld r6,STK_PARAM(R3)(r1); \
81 std r3,STK_PARAM(R3)(r1); \
82 mr r4,r3; \
83 mr r3,r6; \
84 std r0,16(r1); \
85 stdu r1,-STACK_FRAME_OVERHEAD(r1); \
86 bl __trace_hcall_exit; \
87 addi r1,r1,STACK_FRAME_OVERHEAD; \
88 ld r0,16(r1); \
89 ld r3,STK_PARAM(R3)(r1); \
66 mflr r0; \
67 ld r6,STK_PARAM(R3)(r1); \
68 std r3,STK_PARAM(R3)(r1); \
69 mr r4,r3; \
70 mr r3,r6; \
71 std r0,16(r1); \
72 stdu r1,-STACK_FRAME_OVERHEAD(r1); \
73 bl __trace_hcall_exit; \
74 addi r1,r1,STACK_FRAME_OVERHEAD; \
75 ld r0,16(r1); \
76 ld r3,STK_PARAM(R3)(r1); \
90 mtlr r0; \
911:
77 mtlr r0
92
93#define HCALL_INST_POSTCALL_NORETS \
94 li r5,0; \
95 __HCALL_INST_POSTCALL
96
97#define HCALL_INST_POSTCALL(BUFREG) \
98 mr r5,BUFREG; \
99 __HCALL_INST_POSTCALL
100
78
79#define HCALL_INST_POSTCALL_NORETS \
80 li r5,0; \
81 __HCALL_INST_POSTCALL
82
83#define HCALL_INST_POSTCALL(BUFREG) \
84 mr r5,BUFREG; \
85 __HCALL_INST_POSTCALL
86
87#ifdef CONFIG_JUMP_LABEL
88#define HCALL_BRANCH(LABEL) \
89 ARCH_STATIC_BRANCH(LABEL, hcall_tracepoint_key)
101#else
90#else
91
92/*
93 * We branch around this in early init (eg when populating the MMU
94 * hashtable) by using an unconditional cpu feature.
95 */
96#define HCALL_BRANCH(LABEL) \
97BEGIN_FTR_SECTION; \
98 b 1f; \
99END_FTR_SECTION(0, 1); \
100 ld r12,hcall_tracepoint_refcount@toc(r2); \
101 std r12,32(r1); \
102 cmpdi r12,0; \
103 bne- LABEL; \
1041:
105#endif
106
107#else
102#define HCALL_INST_PRECALL(FIRST_ARG)
103#define HCALL_INST_POSTCALL_NORETS
104#define HCALL_INST_POSTCALL(BUFREG)
108#define HCALL_INST_PRECALL(FIRST_ARG)
109#define HCALL_INST_POSTCALL_NORETS
110#define HCALL_INST_POSTCALL(BUFREG)
111#define HCALL_BRANCH(LABEL)
105#endif
106
112#endif
113
107 .text
108
109_GLOBAL_TOC(plpar_hcall_norets)
110 HMT_MEDIUM
111
112 mfcr r0
113 stw r0,8(r1)
114_GLOBAL_TOC(plpar_hcall_norets)
115 HMT_MEDIUM
116
117 mfcr r0
118 stw r0,8(r1)
114
115 HCALL_INST_PRECALL(R4)
116
119 HCALL_BRANCH(plpar_hcall_norets_trace)
117 HVSC /* invoke the hypervisor */
118
120 HVSC /* invoke the hypervisor */
121
119 HCALL_INST_POSTCALL_NORETS
120
121 lwz r0,8(r1)
122 mtcrf 0xff,r0
123 blr /* return r3 = status */
124
122 lwz r0,8(r1)
123 mtcrf 0xff,r0
124 blr /* return r3 = status */
125
126#ifdef CONFIG_TRACEPOINTS
127plpar_hcall_norets_trace:
128 HCALL_INST_PRECALL(R4)
129 HVSC
130 HCALL_INST_POSTCALL_NORETS
131 lwz r0,8(r1)
132 mtcrf 0xff,r0
133 blr
134#endif
135
125_GLOBAL_TOC(plpar_hcall)
126 HMT_MEDIUM
127
128 mfcr r0
129 stw r0,8(r1)
130
136_GLOBAL_TOC(plpar_hcall)
137 HMT_MEDIUM
138
139 mfcr r0
140 stw r0,8(r1)
141
131 HCALL_INST_PRECALL(R5)
142 HCALL_BRANCH(plpar_hcall_trace)
132
133 std r4,STK_PARAM(R4)(r1) /* Save ret buffer */
134
135 mr r4,r5
136 mr r5,r6
137 mr r6,r7
138 mr r7,r8
139 mr r8,r9
140 mr r9,r10
141
142 HVSC /* invoke the hypervisor */
143
144 ld r12,STK_PARAM(R4)(r1)
145 std r4, 0(r12)
146 std r5, 8(r12)
147 std r6, 16(r12)
148 std r7, 24(r12)
149
143
144 std r4,STK_PARAM(R4)(r1) /* Save ret buffer */
145
146 mr r4,r5
147 mr r5,r6
148 mr r6,r7
149 mr r7,r8
150 mr r8,r9
151 mr r9,r10
152
153 HVSC /* invoke the hypervisor */
154
155 ld r12,STK_PARAM(R4)(r1)
156 std r4, 0(r12)
157 std r5, 8(r12)
158 std r6, 16(r12)
159 std r7, 24(r12)
160
161 lwz r0,8(r1)
162 mtcrf 0xff,r0
163
164 blr /* return r3 = status */
165
166#ifdef CONFIG_TRACEPOINTS
167plpar_hcall_trace:
168 HCALL_INST_PRECALL(R5)
169
170 std r4,STK_PARAM(R4)(r1)
171 mr r0,r4
172
173 mr r4,r5
174 mr r5,r6
175 mr r6,r7
176 mr r7,r8
177 mr r8,r9
178 mr r9,r10
179
180 HVSC
181
182 ld r12,STK_PARAM(R4)(r1)
183 std r4,0(r12)
184 std r5,8(r12)
185 std r6,16(r12)
186 std r7,24(r12)
187
150 HCALL_INST_POSTCALL(r12)
151
152 lwz r0,8(r1)
153 mtcrf 0xff,r0
154
188 HCALL_INST_POSTCALL(r12)
189
190 lwz r0,8(r1)
191 mtcrf 0xff,r0
192
155 blr /* return r3 = status */
193 blr
194#endif
156
157/*
158 * plpar_hcall_raw can be called in real mode. kexec/kdump need some
159 * hypervisor calls to be executed in real mode. So plpar_hcall_raw
160 * does not access the per cpu hypervisor call statistics variables,
161 * since these variables may not be present in the RMO region.
162 */
163_GLOBAL(plpar_hcall_raw)

--- 25 unchanged lines hidden (view full) ---

189 blr /* return r3 = status */
190
191_GLOBAL_TOC(plpar_hcall9)
192 HMT_MEDIUM
193
194 mfcr r0
195 stw r0,8(r1)
196
195
196/*
197 * plpar_hcall_raw can be called in real mode. kexec/kdump need some
198 * hypervisor calls to be executed in real mode. So plpar_hcall_raw
199 * does not access the per cpu hypervisor call statistics variables,
200 * since these variables may not be present in the RMO region.
201 */
202_GLOBAL(plpar_hcall_raw)

--- 25 unchanged lines hidden (view full) ---

228 blr /* return r3 = status */
229
230_GLOBAL_TOC(plpar_hcall9)
231 HMT_MEDIUM
232
233 mfcr r0
234 stw r0,8(r1)
235
197 HCALL_INST_PRECALL(R5)
236 HCALL_BRANCH(plpar_hcall9_trace)
198
199 std r4,STK_PARAM(R4)(r1) /* Save ret buffer */
200
201 mr r4,r5
202 mr r5,r6
203 mr r6,r7
204 mr r7,r8
205 mr r8,r9

--- 11 unchanged lines hidden (view full) ---

217 std r6, 16(r12)
218 std r7, 24(r12)
219 std r8, 32(r12)
220 std r9, 40(r12)
221 std r10,48(r12)
222 std r11,56(r12)
223 std r0, 64(r12)
224
237
238 std r4,STK_PARAM(R4)(r1) /* Save ret buffer */
239
240 mr r4,r5
241 mr r5,r6
242 mr r6,r7
243 mr r7,r8
244 mr r8,r9

--- 11 unchanged lines hidden (view full) ---

256 std r6, 16(r12)
257 std r7, 24(r12)
258 std r8, 32(r12)
259 std r9, 40(r12)
260 std r10,48(r12)
261 std r11,56(r12)
262 std r0, 64(r12)
263
264 lwz r0,8(r1)
265 mtcrf 0xff,r0
266
267 blr /* return r3 = status */
268
269#ifdef CONFIG_TRACEPOINTS
270plpar_hcall9_trace:
271 HCALL_INST_PRECALL(R5)
272
273 std r4,STK_PARAM(R4)(r1)
274 mr r0,r4
275
276 mr r4,r5
277 mr r5,r6
278 mr r6,r7
279 mr r7,r8
280 mr r8,r9
281 mr r9,r10
282 ld r10,STK_PARAM(R11)(r1)
283 ld r11,STK_PARAM(R12)(r1)
284 ld r12,STK_PARAM(R13)(r1)
285
286 HVSC
287
288 mr r0,r12
289 ld r12,STK_PARAM(R4)(r1)
290 std r4,0(r12)
291 std r5,8(r12)
292 std r6,16(r12)
293 std r7,24(r12)
294 std r8,32(r12)
295 std r9,40(r12)
296 std r10,48(r12)
297 std r11,56(r12)
298 std r0,64(r12)
299
225 HCALL_INST_POSTCALL(r12)
226
227 lwz r0,8(r1)
228 mtcrf 0xff,r0
229
300 HCALL_INST_POSTCALL(r12)
301
302 lwz r0,8(r1)
303 mtcrf 0xff,r0
304
230 blr /* return r3 = status */
305 blr
306#endif
231
232/* See plpar_hcall_raw to see why this is needed */
233_GLOBAL(plpar_hcall9_raw)
234 HMT_MEDIUM
235
236 mfcr r0
237 stw r0,8(r1)
238

--- 30 unchanged lines hidden ---
307
308/* See plpar_hcall_raw to see why this is needed */
309_GLOBAL(plpar_hcall9_raw)
310 HMT_MEDIUM
311
312 mfcr r0
313 stw r0,8(r1)
314

--- 30 unchanged lines hidden ---