1/*
2 * arch/ppc64/kernel/pSeries_hvCall.S
3 *
4 * This file contains the generic code to perform a call to the
5 * pSeries LPAR hypervisor.
6 * NOTE: this file will go away when we move to inline this work.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version
11 * 2 of the License, or (at your option) any later version.
12 */
13#include <asm/hvcall.h>
14#include <asm/processor.h>
15#include <asm/ppc_asm.h>
16
17#define STK_PARM(i)     (48 + ((i)-3)*8)
18
19	.text
20
21/* long plpar_hcall(unsigned long opcode,		R3
22			unsigned long arg1,		R4
23			unsigned long arg2,		R5
24			unsigned long arg3,		R6
25			unsigned long arg4,		R7
26			unsigned long *out1,		R8
27			unsigned long *out2,		R9
28			unsigned long *out3);		R10
29 */
30_GLOBAL(plpar_hcall)
31	HMT_MEDIUM
32
33	mfcr	r0
34
35	std	r8,STK_PARM(r8)(r1)	/* Save out ptrs */
36	std	r9,STK_PARM(r9)(r1)
37	std	r10,STK_PARM(r10)(r1)
38
39	stw	r0,8(r1)
40
41	HVSC				/* invoke the hypervisor */
42
43	lwz	r0,8(r1)
44
45	ld	r8,STK_PARM(r8)(r1)	/* Fetch r4-r6 ret args */
46	ld	r9,STK_PARM(r9)(r1)
47	ld	r10,STK_PARM(r10)(r1)
48	std	r4,0(r8)
49	std	r5,0(r9)
50	std	r6,0(r10)
51
52	mtcrf	0xff,r0
53	blr				/* return r3 = status */
54
55
56/* Simple interface with no output values (other than status) */
57_GLOBAL(plpar_hcall_norets)
58	HMT_MEDIUM
59
60	mfcr	r0
61	stw	r0,8(r1)
62
63	HVSC				/* invoke the hypervisor */
64
65	lwz	r0,8(r1)
66	mtcrf	0xff,r0
67	blr				/* return r3 = status */
68
69
70/* long plpar_hcall_8arg_2ret(unsigned long opcode,	R3
71			unsigned long arg1,		R4
72			unsigned long arg2,		R5
73			unsigned long arg3,		R6
74			unsigned long arg4,		R7
75			unsigned long arg5,		R8
76			unsigned long arg6,		R9
77			unsigned long arg7,		R10
78			unsigned long arg8,		112(R1)
79			unsigned long *out1);		120(R1)
80 */
81_GLOBAL(plpar_hcall_8arg_2ret)
82	HMT_MEDIUM
83
84	mfcr	r0
85	ld	r11,STK_PARM(r11)(r1)	/* put arg8 in R11 */
86	stw	r0,8(r1)
87
88	HVSC				/* invoke the hypervisor */
89
90	lwz	r0,8(r1)
91	ld	r10,STK_PARM(r12)(r1)	/* Fetch r4 ret arg */
92	std	r4,0(r10)
93	mtcrf	0xff,r0
94	blr				/* return r3 = status */
95
96
97/* long plpar_hcall_4out(unsigned long opcode,		R3
98		 	unsigned long arg1,		R4
99		 	unsigned long arg2,		R5
100		 	unsigned long arg3,		R6
101		 	unsigned long arg4,		R7
102		 	unsigned long *out1,		R8
103		 	unsigned long *out2,		R9
104		 	unsigned long *out3,		R10
105		 	unsigned long *out4);		112(R1)
106 */
107_GLOBAL(plpar_hcall_4out)
108	HMT_MEDIUM
109
110	mfcr	r0
111	stw	r0,8(r1)
112
113	std	r8,STK_PARM(r8)(r1)	/* Save out ptrs */
114	std	r9,STK_PARM(r9)(r1)
115	std	r10,STK_PARM(r10)(r1)
116
117	HVSC				/* invoke the hypervisor */
118
119	lwz	r0,8(r1)
120
121	ld	r8,STK_PARM(r8)(r1)	/* Fetch r4-r7 ret args */
122	ld	r9,STK_PARM(r9)(r1)
123	ld	r10,STK_PARM(r10)(r1)
124	ld	r11,STK_PARM(r11)(r1)
125	std	r4,0(r8)
126	std	r5,0(r9)
127	std	r6,0(r10)
128	std	r7,0(r11)
129
130	mtcrf	0xff,r0
131	blr				/* return r3 = status */
132