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