powerpc: Fix usage of register macros getting ready for %r0 change
[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 */
10#include <asm/hvcall.h>
11#include <asm/processor.h>
12#include <asm/ppc_asm.h>
57852a85 13#include <asm/asm-offsets.h>
46f52210 14#include <asm/ptrace.h>
1da177e4
LT
15
16#define STK_PARM(i) (48 + ((i)-3)*8)
17
c8cd093a
AB
18#ifdef CONFIG_TRACEPOINTS
19
20 .section ".toc","aw"
21
22 .globl hcall_tracepoint_refcount
23hcall_tracepoint_refcount:
24 .llong 0
25
26 .section ".text"
27
57852a85
MK
28/*
29 * precall must preserve all registers. use unused STK_PARM()
c8cd093a
AB
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.
57852a85 33 */
6f26353c 34#define HCALL_INST_PRECALL(FIRST_REG) \
57852a85 35BEGIN_FTR_SECTION; \
c8cd093a
AB
36 b 1f; \
37END_FTR_SECTION(0, 1); \
38 ld r12,hcall_tracepoint_refcount@toc(r2); \
ebb7f616 39 std r12,32(r1); \
c8cd093a
AB
40 cmpdi r12,0; \
41 beq+ 1f; \
42 mflr r0; \
c75df6f9
MN
43 std r3,STK_PARM(R3)(r1); \
44 std r4,STK_PARM(R4)(r1); \
45 std r5,STK_PARM(R5)(r1); \
46 std r6,STK_PARM(R6)(r1); \
47 std r7,STK_PARM(R7)(r1); \
48 std r8,STK_PARM(R8)(r1); \
49 std r9,STK_PARM(R9)(r1); \
50 std r10,STK_PARM(R10)(r1); \
c8cd093a 51 std r0,16(r1); \
6f26353c 52 addi r4,r1,STK_PARM(FIRST_REG); \
c8cd093a
AB
53 stdu r1,-STACK_FRAME_OVERHEAD(r1); \
54 bl .__trace_hcall_entry; \
55 addi r1,r1,STACK_FRAME_OVERHEAD; \
56 ld r0,16(r1); \
c75df6f9
MN
57 ld r3,STK_PARM(R3)(r1); \
58 ld r4,STK_PARM(R4)(r1); \
59 ld r5,STK_PARM(R5)(r1); \
60 ld r6,STK_PARM(R6)(r1); \
61 ld r7,STK_PARM(R7)(r1); \
62 ld r8,STK_PARM(R8)(r1); \
63 ld r9,STK_PARM(R9)(r1); \
64 ld r10,STK_PARM(R10)(r1); \
c8cd093a
AB
65 mtlr r0; \
661:
67
57852a85
MK
68/*
69 * postcall is performed immediately before function return which
4f5fa2fb
AB
70 * allows liberal use of volatile registers. We branch around this
71 * in early init (eg when populating the MMU hashtable) by using an
72 * unconditional cpu feature.
57852a85 73 */
6f26353c 74#define __HCALL_INST_POSTCALL \
4f5fa2fb
AB
75BEGIN_FTR_SECTION; \
76 b 1f; \
77END_FTR_SECTION(0, 1); \
ebb7f616 78 ld r12,32(r1); \
c8cd093a
AB
79 cmpdi r12,0; \
80 beq+ 1f; \
81 mflr r0; \
c75df6f9
MN
82 ld r6,STK_PARM(R3)(r1); \
83 std r3,STK_PARM(R3)(r1); \
c8cd093a
AB
84 mr r4,r3; \
85 mr r3,r6; \
86 std r0,16(r1); \
87 stdu r1,-STACK_FRAME_OVERHEAD(r1); \
88 bl .__trace_hcall_exit; \
89 addi r1,r1,STACK_FRAME_OVERHEAD; \
90 ld r0,16(r1); \
c75df6f9 91 ld r3,STK_PARM(R3)(r1); \
c8cd093a 92 mtlr r0; \
57852a85 931:
6f26353c
AB
94
95#define HCALL_INST_POSTCALL_NORETS \
96 li r5,0; \
97 __HCALL_INST_POSTCALL
98
99#define HCALL_INST_POSTCALL(BUFREG) \
100 mr r5,BUFREG; \
101 __HCALL_INST_POSTCALL
102
57852a85 103#else
6f26353c
AB
104#define HCALL_INST_PRECALL(FIRST_ARG)
105#define HCALL_INST_POSTCALL_NORETS
106#define HCALL_INST_POSTCALL(BUFREG)
57852a85
MK
107#endif
108
1da177e4
LT
109 .text
110
1da177e4 111_GLOBAL(plpar_hcall_norets)
eeb24de4
AB
112 HMT_MEDIUM
113
1da177e4
LT
114 mfcr r0
115 stw r0,8(r1)
116
c75df6f9 117 HCALL_INST_PRECALL(R4)
57852a85 118
1da177e4
LT
119 HVSC /* invoke the hypervisor */
120
6f26353c 121 HCALL_INST_POSTCALL_NORETS
57852a85 122
1da177e4
LT
123 lwz r0,8(r1)
124 mtcrf 0xff,r0
125 blr /* return r3 = status */
126
b9377ffc 127_GLOBAL(plpar_hcall)
eeb24de4
AB
128 HMT_MEDIUM
129
1da177e4 130 mfcr r0
1da177e4
LT
131 stw r0,8(r1)
132
c75df6f9 133 HCALL_INST_PRECALL(R5)
57852a85 134
c75df6f9 135 std r4,STK_PARM(R4)(r1) /* Save ret buffer */
1da177e4 136
b9377ffc
AB
137 mr r4,r5
138 mr r5,r6
139 mr r6,r7
140 mr r7,r8
141 mr r8,r9
142 mr r9,r10
1da177e4
LT
143
144 HVSC /* invoke the hypervisor */
145
c75df6f9 146 ld r12,STK_PARM(R4)(r1)
b9377ffc
AB
147 std r4, 0(r12)
148 std r5, 8(r12)
149 std r6, 16(r12)
150 std r7, 24(r12)
b13a96cf 151
6f26353c 152 HCALL_INST_POSTCALL(r12)
57852a85 153
b13a96cf 154 lwz r0,8(r1)
b13a96cf
HS
155 mtcrf 0xff,r0
156
157 blr /* return r3 = status */
158
b4aea36b
MK
159/*
160 * plpar_hcall_raw can be called in real mode. kexec/kdump need some
161 * hypervisor calls to be executed in real mode. So plpar_hcall_raw
162 * does not access the per cpu hypervisor call statistics variables,
163 * since these variables may not be present in the RMO region.
164 */
165_GLOBAL(plpar_hcall_raw)
166 HMT_MEDIUM
167
168 mfcr r0
169 stw r0,8(r1)
170
c75df6f9 171 std r4,STK_PARM(R4)(r1) /* Save ret buffer */
b4aea36b
MK
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 /* invoke the hypervisor */
181
c75df6f9 182 ld r12,STK_PARM(R4)(r1)
b4aea36b
MK
183 std r4, 0(r12)
184 std r5, 8(r12)
185 std r6, 16(r12)
186 std r7, 24(r12)
187
188 lwz r0,8(r1)
189 mtcrf 0xff,r0
190
191 blr /* return r3 = status */
192
b9377ffc 193_GLOBAL(plpar_hcall9)
b13a96cf
HS
194 HMT_MEDIUM
195
196 mfcr r0
197 stw r0,8(r1)
198
c75df6f9 199 HCALL_INST_PRECALL(R5)
57852a85 200
c75df6f9 201 std r4,STK_PARM(R4)(r1) /* Save ret buffer */
b9377ffc
AB
202
203 mr r4,r5
204 mr r5,r6
205 mr r6,r7
206 mr r7,r8
207 mr r8,r9
208 mr r9,r10
c75df6f9
MN
209 ld r10,STK_PARM(R11)(r1) /* put arg7 in R10 */
210 ld r11,STK_PARM(R12)(r1) /* put arg8 in R11 */
211 ld r12,STK_PARM(R13)(r1) /* put arg9 in R12 */
b13a96cf
HS
212
213 HVSC /* invoke the hypervisor */
214
ab87e8dc 215 mr r0,r12
c75df6f9 216 ld r12,STK_PARM(R4)(r1)
b9377ffc
AB
217 std r4, 0(r12)
218 std r5, 8(r12)
219 std r6, 16(r12)
220 std r7, 24(r12)
221 std r8, 32(r12)
222 std r9, 40(r12)
223 std r10,48(r12)
224 std r11,56(r12)
ab87e8dc 225 std r0, 64(r12)
b13a96cf 226
6f26353c 227 HCALL_INST_POSTCALL(r12)
57852a85 228
b13a96cf
HS
229 lwz r0,8(r1)
230 mtcrf 0xff,r0
231
232 blr /* return r3 = status */
f90ece28
MN
233
234/* See plpar_hcall_raw to see why this is needed */
235_GLOBAL(plpar_hcall9_raw)
236 HMT_MEDIUM
237
238 mfcr r0
239 stw r0,8(r1)
240
c75df6f9 241 std r4,STK_PARM(R4)(r1) /* Save ret buffer */
f90ece28
MN
242
243 mr r4,r5
244 mr r5,r6
245 mr r6,r7
246 mr r7,r8
247 mr r8,r9
248 mr r9,r10
c75df6f9
MN
249 ld r10,STK_PARM(R11)(r1) /* put arg7 in R10 */
250 ld r11,STK_PARM(R12)(r1) /* put arg8 in R11 */
251 ld r12,STK_PARM(R13)(r1) /* put arg9 in R12 */
f90ece28
MN
252
253 HVSC /* invoke the hypervisor */
254
255 mr r0,r12
c75df6f9 256 ld r12,STK_PARM(R4)(r1)
f90ece28
MN
257 std r4, 0(r12)
258 std r5, 8(r12)
259 std r6, 16(r12)
260 std r7, 24(r12)
261 std r8, 32(r12)
262 std r9, 40(r12)
263 std r10,48(r12)
264 std r11,56(r12)
265 std r0, 64(r12)
266
267 lwz r0,8(r1)
268 mtcrf 0xff,r0
269
270 blr /* return r3 = status */
This page took 0.920019 seconds and 5 git commands to generate.