Merge branch 'devel' of master.kernel.org:/home/rmk/linux-2.6-mmc
[linux-2.6] / arch / powerpc / platforms / pseries / hvCall.S
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 */