blob: 3ce73d0052b17a2b2e934af3daf33499d0afd4ac [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 * This file contains the generic code to perform a call to the
3 * pSeries LPAR hypervisor.
Linus Torvalds1da177e2005-04-16 15:20:36 -07004 *
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>
Mike Kravetz57852a82006-09-06 16:23:12 -070013#include <asm/asm-offsets.h>
Stephen Rothwell46f52212010-11-18 15:06:17 +000014#include <asm/ptrace.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070015
16#define STK_PARM(i) (48 + ((i)-3)*8)
17
Anton Blanchardc8cd0932009-10-26 18:50:29 +000018#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
Mike Kravetz57852a82006-09-06 16:23:12 -070028/*
29 * precall must preserve all registers. use unused STK_PARM()
Anton Blanchardc8cd0932009-10-26 18:50:29 +000030 * 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.
Mike Kravetz57852a82006-09-06 16:23:12 -070033 */
Anton Blanchard6f263532009-10-26 18:51:09 +000034#define HCALL_INST_PRECALL(FIRST_REG) \
Mike Kravetz57852a82006-09-06 16:23:12 -070035BEGIN_FTR_SECTION; \
Anton Blanchardc8cd0932009-10-26 18:50:29 +000036 b 1f; \
37END_FTR_SECTION(0, 1); \
38 ld r12,hcall_tracepoint_refcount@toc(r2); \
Li Zhongebb7f612012-01-07 17:54:52 +000039 std r12,32(r1); \
Anton Blanchardc8cd0932009-10-26 18:50:29 +000040 cmpdi r12,0; \
41 beq+ 1f; \
42 mflr r0; \
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); \
51 std r0,16(r1); \
Anton Blanchard6f263532009-10-26 18:51:09 +000052 addi r4,r1,STK_PARM(FIRST_REG); \
Anton Blanchardc8cd0932009-10-26 18:50:29 +000053 stdu r1,-STACK_FRAME_OVERHEAD(r1); \
54 bl .__trace_hcall_entry; \
55 addi r1,r1,STACK_FRAME_OVERHEAD; \
56 ld r0,16(r1); \
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); \
65 mtlr r0; \
661:
67
Mike Kravetz57852a82006-09-06 16:23:12 -070068/*
69 * postcall is performed immediately before function return which
Anton Blanchard4f5fa2f2007-03-20 14:29:54 -050070 * 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.
Mike Kravetz57852a82006-09-06 16:23:12 -070073 */
Anton Blanchard6f263532009-10-26 18:51:09 +000074#define __HCALL_INST_POSTCALL \
Anton Blanchard4f5fa2f2007-03-20 14:29:54 -050075BEGIN_FTR_SECTION; \
76 b 1f; \
77END_FTR_SECTION(0, 1); \
Li Zhongebb7f612012-01-07 17:54:52 +000078 ld r12,32(r1); \
Anton Blanchardc8cd0932009-10-26 18:50:29 +000079 cmpdi r12,0; \
80 beq+ 1f; \
81 mflr r0; \
82 ld r6,STK_PARM(r3)(r1); \
83 std r3,STK_PARM(r3)(r1); \
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); \
91 ld r3,STK_PARM(r3)(r1); \
92 mtlr r0; \
Mike Kravetz57852a82006-09-06 16:23:12 -0700931:
Anton Blanchard6f263532009-10-26 18:51:09 +000094
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
Mike Kravetz57852a82006-09-06 16:23:12 -0700103#else
Anton Blanchard6f263532009-10-26 18:51:09 +0000104#define HCALL_INST_PRECALL(FIRST_ARG)
105#define HCALL_INST_POSTCALL_NORETS
106#define HCALL_INST_POSTCALL(BUFREG)
Mike Kravetz57852a82006-09-06 16:23:12 -0700107#endif
108
Linus Torvalds1da177e2005-04-16 15:20:36 -0700109 .text
110
Linus Torvalds1da177e2005-04-16 15:20:36 -0700111_GLOBAL(plpar_hcall_norets)
Anton Blanchardeeb24de2005-05-01 08:58:46 -0700112 HMT_MEDIUM
113
Linus Torvalds1da177e2005-04-16 15:20:36 -0700114 mfcr r0
115 stw r0,8(r1)
116
Anton Blanchard6f263532009-10-26 18:51:09 +0000117 HCALL_INST_PRECALL(r4)
Mike Kravetz57852a82006-09-06 16:23:12 -0700118
Linus Torvalds1da177e2005-04-16 15:20:36 -0700119 HVSC /* invoke the hypervisor */
120
Anton Blanchard6f263532009-10-26 18:51:09 +0000121 HCALL_INST_POSTCALL_NORETS
Mike Kravetz57852a82006-09-06 16:23:12 -0700122
Linus Torvalds1da177e2005-04-16 15:20:36 -0700123 lwz r0,8(r1)
124 mtcrf 0xff,r0
125 blr /* return r3 = status */
126
Anton Blanchardb9377ff2006-07-19 08:01:28 +1000127_GLOBAL(plpar_hcall)
Anton Blanchardeeb24de2005-05-01 08:58:46 -0700128 HMT_MEDIUM
129
Linus Torvalds1da177e2005-04-16 15:20:36 -0700130 mfcr r0
131 stw r0,8(r1)
132
Anton Blanchard6f263532009-10-26 18:51:09 +0000133 HCALL_INST_PRECALL(r5)
Mike Kravetz57852a82006-09-06 16:23:12 -0700134
Anton Blanchardb9377ff2006-07-19 08:01:28 +1000135 std r4,STK_PARM(r4)(r1) /* Save ret buffer */
136
137 mr r4,r5
138 mr r5,r6
139 mr r6,r7
140 mr r7,r8
141 mr r8,r9
142 mr r9,r10
Linus Torvalds1da177e2005-04-16 15:20:36 -0700143
144 HVSC /* invoke the hypervisor */
145
Anton Blanchardb9377ff2006-07-19 08:01:28 +1000146 ld r12,STK_PARM(r4)(r1)
147 std r4, 0(r12)
148 std r5, 8(r12)
149 std r6, 16(r12)
150 std r7, 24(r12)
Heiko J Schickb13a96c2006-03-30 22:47:14 +0200151
Anton Blanchard6f263532009-10-26 18:51:09 +0000152 HCALL_INST_POSTCALL(r12)
Mike Kravetz57852a82006-09-06 16:23:12 -0700153
Heiko J Schickb13a96c2006-03-30 22:47:14 +0200154 lwz r0,8(r1)
Heiko J Schickb13a96c2006-03-30 22:47:14 +0200155 mtcrf 0xff,r0
156
157 blr /* return r3 = status */
158
Mohan Kumar Mb4aea362007-03-21 11:21:32 +0530159/*
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
171 std r4,STK_PARM(r4)(r1) /* Save ret buffer */
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
182 ld r12,STK_PARM(r4)(r1)
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
Anton Blanchardb9377ff2006-07-19 08:01:28 +1000193_GLOBAL(plpar_hcall9)
Heiko J Schickb13a96c2006-03-30 22:47:14 +0200194 HMT_MEDIUM
195
196 mfcr r0
197 stw r0,8(r1)
198
Anton Blanchard6f263532009-10-26 18:51:09 +0000199 HCALL_INST_PRECALL(r5)
Mike Kravetz57852a82006-09-06 16:23:12 -0700200
Anton Blanchardb9377ff2006-07-19 08:01:28 +1000201 std r4,STK_PARM(r4)(r1) /* Save ret buffer */
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
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 */
Heiko J Schickb13a96c2006-03-30 22:47:14 +0200212
213 HVSC /* invoke the hypervisor */
214
Anton Blanchardab87e8d2007-01-09 02:37:16 +1100215 mr r0,r12
Anton Blanchardb9377ff2006-07-19 08:01:28 +1000216 ld r12,STK_PARM(r4)(r1)
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)
Anton Blanchardab87e8d2007-01-09 02:37:16 +1100225 std r0, 64(r12)
Heiko J Schickb13a96c2006-03-30 22:47:14 +0200226
Anton Blanchard6f263532009-10-26 18:51:09 +0000227 HCALL_INST_POSTCALL(r12)
Mike Kravetz57852a82006-09-06 16:23:12 -0700228
Heiko J Schickb13a96c2006-03-30 22:47:14 +0200229 lwz r0,8(r1)
230 mtcrf 0xff,r0
231
232 blr /* return r3 = status */
Michael Neulingf90ece22010-05-10 20:28:26 +0000233
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
241 std r4,STK_PARM(r4)(r1) /* Save ret buffer */
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
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 */
252
253 HVSC /* invoke the hypervisor */
254
255 mr r0,r12
256 ld r12,STK_PARM(r4)(r1)
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 */