xref: /linux/arch/powerpc/platforms/pseries/hvCall.S (revision ccea15f45eb0ab12d658f88b5d4be005cb2bb1a7)
1/*
2 * This file contains the generic code to perform a call to the
3 * pSeries LPAR hypervisor.
4 * NOTE: this file will go away when we move to inline this work.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11#include <asm/hvcall.h>
12#include <asm/processor.h>
13#include <asm/ppc_asm.h>
14
15#define STK_PARM(i)     (48 + ((i)-3)*8)
16
17	.text
18
19/* long plpar_hcall(unsigned long opcode,		R3
20			unsigned long arg1,		R4
21			unsigned long arg2,		R5
22			unsigned long arg3,		R6
23			unsigned long arg4,		R7
24			unsigned long *out1,		R8
25			unsigned long *out2,		R9
26			unsigned long *out3);		R10
27 */
28_GLOBAL(plpar_hcall)
29	HMT_MEDIUM
30
31	mfcr	r0
32
33	std	r8,STK_PARM(r8)(r1)	/* Save out ptrs */
34	std	r9,STK_PARM(r9)(r1)
35	std	r10,STK_PARM(r10)(r1)
36
37	stw	r0,8(r1)
38
39	HVSC				/* invoke the hypervisor */
40
41	lwz	r0,8(r1)
42
43	ld	r8,STK_PARM(r8)(r1)	/* Fetch r4-r6 ret args */
44	ld	r9,STK_PARM(r9)(r1)
45	ld	r10,STK_PARM(r10)(r1)
46	std	r4,0(r8)
47	std	r5,0(r9)
48	std	r6,0(r10)
49
50	mtcrf	0xff,r0
51	blr				/* return r3 = status */
52
53
54/* Simple interface with no output values (other than status) */
55_GLOBAL(plpar_hcall_norets)
56	HMT_MEDIUM
57
58	mfcr	r0
59	stw	r0,8(r1)
60
61	HVSC				/* invoke the hypervisor */
62
63	lwz	r0,8(r1)
64	mtcrf	0xff,r0
65	blr				/* return r3 = status */
66
67
68/* long plpar_hcall_8arg_2ret(unsigned long opcode,	R3
69			unsigned long arg1,		R4
70			unsigned long arg2,		R5
71			unsigned long arg3,		R6
72			unsigned long arg4,		R7
73			unsigned long arg5,		R8
74			unsigned long arg6,		R9
75			unsigned long arg7,		R10
76			unsigned long arg8,		112(R1)
77			unsigned long *out1);		120(R1)
78 */
79_GLOBAL(plpar_hcall_8arg_2ret)
80	HMT_MEDIUM
81
82	mfcr	r0
83	ld	r11,STK_PARM(r11)(r1)	/* put arg8 in R11 */
84	stw	r0,8(r1)
85
86	HVSC				/* invoke the hypervisor */
87
88	lwz	r0,8(r1)
89	ld	r10,STK_PARM(r12)(r1)	/* Fetch r4 ret arg */
90	std	r4,0(r10)
91	mtcrf	0xff,r0
92	blr				/* return r3 = status */
93
94
95/* long plpar_hcall_4out(unsigned long opcode,		R3
96		 	unsigned long arg1,		R4
97		 	unsigned long arg2,		R5
98		 	unsigned long arg3,		R6
99		 	unsigned long arg4,		R7
100		 	unsigned long *out1,		R8
101		 	unsigned long *out2,		R9
102		 	unsigned long *out3,		R10
103		 	unsigned long *out4);		112(R1)
104 */
105_GLOBAL(plpar_hcall_4out)
106	HMT_MEDIUM
107
108	mfcr	r0
109	stw	r0,8(r1)
110
111	std	r8,STK_PARM(r8)(r1)	/* Save out ptrs */
112	std	r9,STK_PARM(r9)(r1)
113	std	r10,STK_PARM(r10)(r1)
114
115	HVSC				/* invoke the hypervisor */
116
117	lwz	r0,8(r1)
118
119	ld	r8,STK_PARM(r8)(r1)	/* Fetch r4-r7 ret args */
120	ld	r9,STK_PARM(r9)(r1)
121	ld	r10,STK_PARM(r10)(r1)
122	ld	r11,STK_PARM(r11)(r1)
123	std	r4,0(r8)
124	std	r5,0(r9)
125	std	r6,0(r10)
126	std	r7,0(r11)
127
128	mtcrf	0xff,r0
129	blr				/* return r3 = status */
130
131/* plpar_hcall_7arg_7ret(unsigned long opcode,		R3
132			 unsigned long arg1,		R4
133			 unsigned long arg2,		R5
134			 unsigned long arg3,		R6
135			 unsigned long arg4,		R7
136			 unsigned long arg5,		R8
137			 unsigned long arg6,		R9
138			 unsigned long arg7,		R10
139			 unsigned long *out1,		112(R1)
140			 unsigned long *out2,		110(R1)
141			 unsigned long *out3,		108(R1)
142			 unsigned long *out4,		106(R1)
143			 unsigned long *out5,		104(R1)
144			 unsigned long *out6,		102(R1)
145			 unsigned long *out7);		100(R1)
146*/
147_GLOBAL(plpar_hcall_7arg_7ret)
148	HMT_MEDIUM
149
150	mfcr	r0
151	stw	r0,8(r1)
152
153	HVSC				/* invoke the hypervisor */
154
155	lwz	r0,8(r1)
156
157	ld	r11,STK_PARM(r11)(r1)	/* Fetch r4 ret arg */
158	std	r4,0(r11)
159	ld	r11,STK_PARM(r12)(r1)	/* Fetch r5 ret arg */
160	std	r5,0(r11)
161	ld	r11,STK_PARM(r13)(r1)	/* Fetch r6 ret arg */
162	std	r6,0(r11)
163	ld	r11,STK_PARM(r14)(r1)	/* Fetch r7 ret arg */
164	std	r7,0(r11)
165	ld	r11,STK_PARM(r15)(r1)	/* Fetch r8 ret arg */
166	std	r8,0(r11)
167	ld	r11,STK_PARM(r16)(r1)	/* Fetch r9 ret arg */
168	std	r9,0(r11)
169	ld	r11,STK_PARM(r17)(r1)	/* Fetch r10 ret arg */
170	std	r10,0(r11)
171
172	mtcrf	0xff,r0
173
174	blr				/* return r3 = status */
175
176/* plpar_hcall_9arg_9ret(unsigned long opcode,		R3
177			 unsigned long arg1,		R4
178			 unsigned long arg2,		R5
179			 unsigned long arg3,		R6
180			 unsigned long arg4,		R7
181			 unsigned long arg5,		R8
182			 unsigned long arg6,		R9
183			 unsigned long arg7,		R10
184			 unsigned long arg8,		112(R1)
185			 unsigned long arg9,		110(R1)
186			 unsigned long *out1,		108(R1)
187			 unsigned long *out2,		106(R1)
188			 unsigned long *out3,		104(R1)
189			 unsigned long *out4,		102(R1)
190			 unsigned long *out5,		100(R1)
191			 unsigned long *out6,		 98(R1)
192			 unsigned long *out7);		 96(R1)
193			 unsigned long *out8,		 94(R1)
194		         unsigned long *out9,            92(R1)
195*/
196_GLOBAL(plpar_hcall_9arg_9ret)
197	HMT_MEDIUM
198
199	mfcr	r0
200	stw	r0,8(r1)
201
202	ld	r11,STK_PARM(r11)(r1)	 /* put arg8 in R11 */
203	ld	r12,STK_PARM(r12)(r1)    /* put arg9 in R12 */
204
205	HVSC				/* invoke the hypervisor */
206
207	ld	r0,STK_PARM(r13)(r1)	/* Fetch r4 ret arg */
208	stdx	r4,r0,r0
209	ld	r0,STK_PARM(r14)(r1)	/* Fetch r5 ret arg */
210	stdx	r5,r0,r0
211	ld	r0,STK_PARM(r15)(r1)	/* Fetch r6 ret arg */
212	stdx	r6,r0,r0
213	ld	r0,STK_PARM(r16)(r1)	/* Fetch r7 ret arg */
214	stdx	r7,r0,r0
215	ld	r0,STK_PARM(r17)(r1)	/* Fetch r8 ret arg */
216	stdx	r8,r0,r0
217	ld	r0,STK_PARM(r18)(r1)	/* Fetch r9 ret arg */
218	stdx	r9,r0,r0
219	ld	r0,STK_PARM(r19)(r1)	/* Fetch r10 ret arg */
220	stdx	r10,r0,r0
221	ld	r0,STK_PARM(r20)(r1)	/* Fetch r11 ret arg */
222	stdx	r11,r0,r0
223	ld	r0,STK_PARM(r21)(r1)	/* Fetch r12 ret arg */
224	stdx	r12,r0,r0
225
226	lwz	r0,8(r1)
227	mtcrf	0xff,r0
228
229	blr				/* return r3 = status */
230