diff options
author | Anton Blanchard <anton@samba.org> | 2006-07-18 18:01:28 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2006-08-01 02:19:15 -0400 |
commit | b9377ffc3a03cde558d76349a262a1adbb6d3112 (patch) | |
tree | c61fcdb732d06c64b9c5634953e46cefdf6af846 | |
parent | 57cad8084e0837e0f2c97da789ec9b3f36809be9 (diff) |
[POWERPC] clean up pseries hcall interfaces
Our pseries hcall interfaces are out of control:
plpar_hcall_norets
plpar_hcall
plpar_hcall_8arg_2ret
plpar_hcall_4out
plpar_hcall_7arg_7ret
plpar_hcall_9arg_9ret
Create 3 interfaces to cover all cases:
plpar_hcall_norets: 7 arguments no returns
plpar_hcall: 6 arguments 4 returns
plpar_hcall9: 9 arguments 9 returns
There are only 2 cases in the kernel that need plpar_hcall9, hopefully
we can keep it that way.
Pass in a buffer to stash return parameters so we avoid the &dummy1,
&dummy2 madness.
Signed-off-by: Anton Blanchard <anton@samba.org>
--
Signed-off-by: Paul Mackerras <paulus@samba.org>
-rw-r--r-- | arch/powerpc/kernel/lparcfg.c | 18 | ||||
-rw-r--r-- | arch/powerpc/kernel/rtas.c | 11 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/hvCall.S | 207 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/hvconsole.c | 5 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/lpar.c | 12 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/plpar_wrappers.h | 97 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/xics.c | 22 | ||||
-rw-r--r-- | drivers/net/ibmveth.c | 3 | ||||
-rw-r--r-- | drivers/net/ibmveth.h | 17 | ||||
-rw-r--r-- | include/asm-powerpc/hvcall.h | 105 |
10 files changed, 184 insertions, 313 deletions
diff --git a/arch/powerpc/kernel/lparcfg.c b/arch/powerpc/kernel/lparcfg.c index 3ce3a2d56fa8..41c05dcd68f4 100644 --- a/arch/powerpc/kernel/lparcfg.c +++ b/arch/powerpc/kernel/lparcfg.c | |||
@@ -182,8 +182,14 @@ static unsigned int h_get_ppp(unsigned long *entitled, | |||
182 | unsigned long *resource) | 182 | unsigned long *resource) |
183 | { | 183 | { |
184 | unsigned long rc; | 184 | unsigned long rc; |
185 | rc = plpar_hcall_4out(H_GET_PPP, 0, 0, 0, 0, entitled, unallocated, | 185 | unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; |
186 | aggregation, resource); | 186 | |
187 | rc = plpar_hcall(H_GET_PPP, retbuf); | ||
188 | |||
189 | *entitled = retbuf[0]; | ||
190 | *unallocated = retbuf[1]; | ||
191 | *aggregation = retbuf[2]; | ||
192 | *resource = retbuf[3]; | ||
187 | 193 | ||
188 | log_plpar_hcall_return(rc, "H_GET_PPP"); | 194 | log_plpar_hcall_return(rc, "H_GET_PPP"); |
189 | 195 | ||
@@ -193,8 +199,12 @@ static unsigned int h_get_ppp(unsigned long *entitled, | |||
193 | static void h_pic(unsigned long *pool_idle_time, unsigned long *num_procs) | 199 | static void h_pic(unsigned long *pool_idle_time, unsigned long *num_procs) |
194 | { | 200 | { |
195 | unsigned long rc; | 201 | unsigned long rc; |
196 | unsigned long dummy; | 202 | unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; |
197 | rc = plpar_hcall(H_PIC, 0, 0, 0, 0, pool_idle_time, num_procs, &dummy); | 203 | |
204 | rc = plpar_hcall(H_PIC, retbuf); | ||
205 | |||
206 | *pool_idle_time = retbuf[0]; | ||
207 | *num_procs = retbuf[1]; | ||
198 | 208 | ||
199 | if (rc != H_AUTHORITY) | 209 | if (rc != H_AUTHORITY) |
200 | log_plpar_hcall_return(rc, "H_PIC"); | 210 | log_plpar_hcall_return(rc, "H_PIC"); |
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index 10e10be324c9..14353b8789dd 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c | |||
@@ -668,15 +668,14 @@ static int rtas_ibm_suspend_me(struct rtas_args *args) | |||
668 | int i; | 668 | int i; |
669 | long state; | 669 | long state; |
670 | long rc; | 670 | long rc; |
671 | unsigned long dummy; | 671 | unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; |
672 | |||
673 | struct rtas_suspend_me_data data; | 672 | struct rtas_suspend_me_data data; |
674 | 673 | ||
675 | /* Make sure the state is valid */ | 674 | /* Make sure the state is valid */ |
676 | rc = plpar_hcall(H_VASI_STATE, | 675 | rc = plpar_hcall(H_VASI_STATE, retbuf, |
677 | ((u64)args->args[0] << 32) | args->args[1], | 676 | ((u64)args->args[0] << 32) | args->args[1]); |
678 | 0, 0, 0, | 677 | |
679 | &state, &dummy, &dummy); | 678 | state = retbuf[0]; |
680 | 679 | ||
681 | if (rc) { | 680 | if (rc) { |
682 | printk(KERN_ERR "rtas_ibm_suspend_me: vasi_state returned %ld\n",rc); | 681 | printk(KERN_ERR "rtas_ibm_suspend_me: vasi_state returned %ld\n",rc); |
diff --git a/arch/powerpc/platforms/pseries/hvCall.S b/arch/powerpc/platforms/pseries/hvCall.S index c9ff547f9d25..9a99b056bd27 100644 --- a/arch/powerpc/platforms/pseries/hvCall.S +++ b/arch/powerpc/platforms/pseries/hvCall.S | |||
@@ -1,7 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * This file contains the generic code to perform a call to the | 2 | * This file contains the generic code to perform a call to the |
3 | * pSeries LPAR hypervisor. | 3 | * pSeries LPAR hypervisor. |
4 | * NOTE: this file will go away when we move to inline this work. | ||
5 | * | 4 | * |
6 | * This program is free software; you can redistribute it and/or | 5 | * This program is free software; you can redistribute it and/or |
7 | * modify it under the terms of the GNU General Public License | 6 | * modify it under the terms of the GNU General Public License |
@@ -16,42 +15,6 @@ | |||
16 | 15 | ||
17 | .text | 16 | .text |
18 | 17 | ||
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) | 18 | _GLOBAL(plpar_hcall_norets) |
56 | HMT_MEDIUM | 19 | HMT_MEDIUM |
57 | 20 | ||
@@ -64,164 +27,64 @@ _GLOBAL(plpar_hcall_norets) | |||
64 | mtcrf 0xff,r0 | 27 | mtcrf 0xff,r0 |
65 | blr /* return r3 = status */ | 28 | blr /* return r3 = status */ |
66 | 29 | ||
67 | 30 | _GLOBAL(plpar_hcall) | |
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 | 31 | HMT_MEDIUM |
81 | 32 | ||
82 | mfcr r0 | 33 | mfcr r0 |
83 | ld r11,STK_PARM(r11)(r1) /* put arg8 in R11 */ | ||
84 | stw r0,8(r1) | 34 | stw r0,8(r1) |
85 | 35 | ||
86 | HVSC /* invoke the hypervisor */ | 36 | std r4,STK_PARM(r4)(r1) /* Save ret buffer */ |
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 | 37 | ||
111 | std r8,STK_PARM(r8)(r1) /* Save out ptrs */ | 38 | mr r4,r5 |
112 | std r9,STK_PARM(r9)(r1) | 39 | mr r5,r6 |
113 | std r10,STK_PARM(r10)(r1) | 40 | mr r6,r7 |
41 | mr r7,r8 | ||
42 | mr r8,r9 | ||
43 | mr r9,r10 | ||
114 | 44 | ||
115 | HVSC /* invoke the hypervisor */ | 45 | HVSC /* invoke the hypervisor */ |
116 | 46 | ||
117 | lwz r0,8(r1) | 47 | ld r12,STK_PARM(r4)(r1) |
118 | 48 | std r4, 0(r12) | |
119 | ld r8,STK_PARM(r8)(r1) /* Fetch r4-r7 ret args */ | 49 | std r5, 8(r12) |
120 | ld r9,STK_PARM(r9)(r1) | 50 | std r6, 16(r12) |
121 | ld r10,STK_PARM(r10)(r1) | 51 | std r7, 24(r12) |
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 | 52 | ||
155 | lwz r0,8(r1) | 53 | 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 | 54 | mtcrf 0xff,r0 |
173 | 55 | ||
174 | blr /* return r3 = status */ | 56 | blr /* return r3 = status */ |
175 | 57 | ||
176 | /* plpar_hcall_9arg_9ret(unsigned long opcode, R3 | 58 | _GLOBAL(plpar_hcall9) |
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 | 59 | HMT_MEDIUM |
198 | 60 | ||
199 | mfcr r0 | 61 | mfcr r0 |
200 | stw r0,8(r1) | 62 | stw r0,8(r1) |
201 | 63 | ||
202 | ld r11,STK_PARM(r11)(r1) /* put arg8 in R11 */ | 64 | std r4,STK_PARM(r4)(r1) /* Save ret buffer */ |
203 | ld r12,STK_PARM(r12)(r1) /* put arg9 in R12 */ | 65 | |
66 | mr r4,r5 | ||
67 | mr r5,r6 | ||
68 | mr r6,r7 | ||
69 | mr r7,r8 | ||
70 | mr r8,r9 | ||
71 | mr r9,r10 | ||
72 | ld r10,STK_PARM(r11)(r1) /* put arg7 in R10 */ | ||
73 | ld r11,STK_PARM(r12)(r1) /* put arg8 in R11 */ | ||
74 | ld r12,STK_PARM(r13)(r1) /* put arg9 in R12 */ | ||
204 | 75 | ||
205 | HVSC /* invoke the hypervisor */ | 76 | HVSC /* invoke the hypervisor */ |
206 | 77 | ||
207 | ld r0,STK_PARM(r13)(r1) /* Fetch r4 ret arg */ | 78 | ld r12,STK_PARM(r4)(r1) |
208 | stdx r4,r0,r0 | 79 | std r4, 0(r12) |
209 | ld r0,STK_PARM(r14)(r1) /* Fetch r5 ret arg */ | 80 | std r5, 8(r12) |
210 | stdx r5,r0,r0 | 81 | std r6, 16(r12) |
211 | ld r0,STK_PARM(r15)(r1) /* Fetch r6 ret arg */ | 82 | std r7, 24(r12) |
212 | stdx r6,r0,r0 | 83 | std r8, 32(r12) |
213 | ld r0,STK_PARM(r16)(r1) /* Fetch r7 ret arg */ | 84 | std r9, 40(r12) |
214 | stdx r7,r0,r0 | 85 | std r10,48(r12) |
215 | ld r0,STK_PARM(r17)(r1) /* Fetch r8 ret arg */ | 86 | std r11,56(r12) |
216 | stdx r8,r0,r0 | 87 | std r12,64(r12) |
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 | 88 | ||
226 | lwz r0,8(r1) | 89 | lwz r0,8(r1) |
227 | mtcrf 0xff,r0 | 90 | mtcrf 0xff,r0 |
diff --git a/arch/powerpc/platforms/pseries/hvconsole.c b/arch/powerpc/platforms/pseries/hvconsole.c index a72a987f1d4d..3f6a89b09816 100644 --- a/arch/powerpc/platforms/pseries/hvconsole.c +++ b/arch/powerpc/platforms/pseries/hvconsole.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <asm/hvcall.h> | 28 | #include <asm/hvcall.h> |
29 | #include <asm/hvconsole.h> | 29 | #include <asm/hvconsole.h> |
30 | #include "plpar_wrappers.h" | ||
30 | 31 | ||
31 | /** | 32 | /** |
32 | * hvc_get_chars - retrieve characters from firmware for denoted vterm adatper | 33 | * hvc_get_chars - retrieve characters from firmware for denoted vterm adatper |
@@ -40,9 +41,9 @@ int hvc_get_chars(uint32_t vtermno, char *buf, int count) | |||
40 | { | 41 | { |
41 | unsigned long got; | 42 | unsigned long got; |
42 | 43 | ||
43 | if (plpar_hcall(H_GET_TERM_CHAR, vtermno, 0, 0, 0, &got, | 44 | if (plpar_get_term_char(vtermno, &got, buf) == H_SUCCESS) |
44 | (unsigned long *)buf, (unsigned long *)buf+1) == H_SUCCESS) | ||
45 | return got; | 45 | return got; |
46 | |||
46 | return 0; | 47 | return 0; |
47 | } | 48 | } |
48 | 49 | ||
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c index 4cb7ff227f72..6cbf14266d5e 100644 --- a/arch/powerpc/platforms/pseries/lpar.c +++ b/arch/powerpc/platforms/pseries/lpar.c | |||
@@ -48,13 +48,11 @@ | |||
48 | #define DBG_LOW(fmt...) do { } while(0) | 48 | #define DBG_LOW(fmt...) do { } while(0) |
49 | #endif | 49 | #endif |
50 | 50 | ||
51 | /* in pSeries_hvCall.S */ | 51 | /* in hvCall.S */ |
52 | EXPORT_SYMBOL(plpar_hcall); | 52 | EXPORT_SYMBOL(plpar_hcall); |
53 | EXPORT_SYMBOL(plpar_hcall_4out); | 53 | EXPORT_SYMBOL(plpar_hcall9); |
54 | EXPORT_SYMBOL(plpar_hcall_norets); | 54 | EXPORT_SYMBOL(plpar_hcall_norets); |
55 | EXPORT_SYMBOL(plpar_hcall_8arg_2ret); | 55 | |
56 | EXPORT_SYMBOL(plpar_hcall_7arg_7ret); | ||
57 | EXPORT_SYMBOL(plpar_hcall_9arg_9ret); | ||
58 | extern void pSeries_find_serial_port(void); | 56 | extern void pSeries_find_serial_port(void); |
59 | 57 | ||
60 | 58 | ||
@@ -277,7 +275,6 @@ long pSeries_lpar_hpte_insert(unsigned long hpte_group, | |||
277 | unsigned long flags; | 275 | unsigned long flags; |
278 | unsigned long slot; | 276 | unsigned long slot; |
279 | unsigned long hpte_v, hpte_r; | 277 | unsigned long hpte_v, hpte_r; |
280 | unsigned long dummy0, dummy1; | ||
281 | 278 | ||
282 | if (!(vflags & HPTE_V_BOLTED)) | 279 | if (!(vflags & HPTE_V_BOLTED)) |
283 | DBG_LOW("hpte_insert(group=%lx, va=%016lx, pa=%016lx, " | 280 | DBG_LOW("hpte_insert(group=%lx, va=%016lx, pa=%016lx, " |
@@ -302,8 +299,7 @@ long pSeries_lpar_hpte_insert(unsigned long hpte_group, | |||
302 | if (rflags & (_PAGE_GUARDED|_PAGE_NO_CACHE)) | 299 | if (rflags & (_PAGE_GUARDED|_PAGE_NO_CACHE)) |
303 | hpte_r &= ~_PAGE_COHERENT; | 300 | hpte_r &= ~_PAGE_COHERENT; |
304 | 301 | ||
305 | lpar_rc = plpar_hcall(H_ENTER, flags, hpte_group, hpte_v, | 302 | lpar_rc = plpar_pte_enter(flags, hpte_group, hpte_v, hpte_r, &slot); |
306 | hpte_r, &slot, &dummy0, &dummy1); | ||
307 | if (unlikely(lpar_rc == H_PTEG_FULL)) { | 303 | if (unlikely(lpar_rc == H_PTEG_FULL)) { |
308 | if (!(vflags & HPTE_V_BOLTED)) | 304 | if (!(vflags & HPTE_V_BOLTED)) |
309 | DBG_LOW(" full\n"); | 305 | DBG_LOW(" full\n"); |
diff --git a/arch/powerpc/platforms/pseries/plpar_wrappers.h b/arch/powerpc/platforms/pseries/plpar_wrappers.h index 3bd1b3e06003..ebd15de7597e 100644 --- a/arch/powerpc/platforms/pseries/plpar_wrappers.h +++ b/arch/powerpc/platforms/pseries/plpar_wrappers.h | |||
@@ -5,20 +5,17 @@ | |||
5 | 5 | ||
6 | static inline long poll_pending(void) | 6 | static inline long poll_pending(void) |
7 | { | 7 | { |
8 | unsigned long dummy; | 8 | return plpar_hcall_norets(H_POLL_PENDING); |
9 | return plpar_hcall(H_POLL_PENDING, 0, 0, 0, 0, &dummy, &dummy, &dummy); | ||
10 | } | 9 | } |
11 | 10 | ||
12 | static inline long prod_processor(void) | 11 | static inline long prod_processor(void) |
13 | { | 12 | { |
14 | plpar_hcall_norets(H_PROD); | 13 | return plpar_hcall_norets(H_PROD); |
15 | return 0; | ||
16 | } | 14 | } |
17 | 15 | ||
18 | static inline long cede_processor(void) | 16 | static inline long cede_processor(void) |
19 | { | 17 | { |
20 | plpar_hcall_norets(H_CEDE); | 18 | return plpar_hcall_norets(H_CEDE); |
21 | return 0; | ||
22 | } | 19 | } |
23 | 20 | ||
24 | static inline long vpa_call(unsigned long flags, unsigned long cpu, | 21 | static inline long vpa_call(unsigned long flags, unsigned long cpu, |
@@ -42,21 +39,47 @@ static inline long register_vpa(unsigned long cpu, unsigned long vpa) | |||
42 | 39 | ||
43 | extern void vpa_init(int cpu); | 40 | extern void vpa_init(int cpu); |
44 | 41 | ||
42 | static inline long plpar_pte_enter(unsigned long flags, | ||
43 | unsigned long hpte_group, unsigned long hpte_v, | ||
44 | unsigned long hpte_r, unsigned long *slot) | ||
45 | { | ||
46 | long rc; | ||
47 | unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; | ||
48 | |||
49 | rc = plpar_hcall(H_ENTER, retbuf, flags, hpte_group, hpte_v, hpte_r); | ||
50 | |||
51 | *slot = retbuf[0]; | ||
52 | |||
53 | return rc; | ||
54 | } | ||
55 | |||
45 | static inline long plpar_pte_remove(unsigned long flags, unsigned long ptex, | 56 | static inline long plpar_pte_remove(unsigned long flags, unsigned long ptex, |
46 | unsigned long avpn, unsigned long *old_pteh_ret, | 57 | unsigned long avpn, unsigned long *old_pteh_ret, |
47 | unsigned long *old_ptel_ret) | 58 | unsigned long *old_ptel_ret) |
48 | { | 59 | { |
49 | unsigned long dummy; | 60 | long rc; |
50 | return plpar_hcall(H_REMOVE, flags, ptex, avpn, 0, old_pteh_ret, | 61 | unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; |
51 | old_ptel_ret, &dummy); | 62 | |
63 | rc = plpar_hcall(H_REMOVE, retbuf, flags, ptex, avpn); | ||
64 | |||
65 | *old_pteh_ret = retbuf[0]; | ||
66 | *old_ptel_ret = retbuf[1]; | ||
67 | |||
68 | return rc; | ||
52 | } | 69 | } |
53 | 70 | ||
54 | static inline long plpar_pte_read(unsigned long flags, unsigned long ptex, | 71 | static inline long plpar_pte_read(unsigned long flags, unsigned long ptex, |
55 | unsigned long *old_pteh_ret, unsigned long *old_ptel_ret) | 72 | unsigned long *old_pteh_ret, unsigned long *old_ptel_ret) |
56 | { | 73 | { |
57 | unsigned long dummy; | 74 | long rc; |
58 | return plpar_hcall(H_READ, flags, ptex, 0, 0, old_pteh_ret, | 75 | unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; |
59 | old_ptel_ret, &dummy); | 76 | |
77 | rc = plpar_hcall(H_READ, retbuf, flags, ptex); | ||
78 | |||
79 | *old_pteh_ret = retbuf[0]; | ||
80 | *old_ptel_ret = retbuf[1]; | ||
81 | |||
82 | return rc; | ||
60 | } | 83 | } |
61 | 84 | ||
62 | static inline long plpar_pte_protect(unsigned long flags, unsigned long ptex, | 85 | static inline long plpar_pte_protect(unsigned long flags, unsigned long ptex, |
@@ -68,9 +91,14 @@ static inline long plpar_pte_protect(unsigned long flags, unsigned long ptex, | |||
68 | static inline long plpar_tce_get(unsigned long liobn, unsigned long ioba, | 91 | static inline long plpar_tce_get(unsigned long liobn, unsigned long ioba, |
69 | unsigned long *tce_ret) | 92 | unsigned long *tce_ret) |
70 | { | 93 | { |
71 | unsigned long dummy; | 94 | long rc; |
72 | return plpar_hcall(H_GET_TCE, liobn, ioba, 0, 0, tce_ret, &dummy, | 95 | unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; |
73 | &dummy); | 96 | |
97 | rc = plpar_hcall(H_GET_TCE, retbuf, liobn, ioba); | ||
98 | |||
99 | *tce_ret = retbuf[0]; | ||
100 | |||
101 | return rc; | ||
74 | } | 102 | } |
75 | 103 | ||
76 | static inline long plpar_tce_put(unsigned long liobn, unsigned long ioba, | 104 | static inline long plpar_tce_put(unsigned long liobn, unsigned long ioba, |
@@ -94,9 +122,17 @@ static inline long plpar_tce_stuff(unsigned long liobn, unsigned long ioba, | |||
94 | static inline long plpar_get_term_char(unsigned long termno, | 122 | static inline long plpar_get_term_char(unsigned long termno, |
95 | unsigned long *len_ret, char *buf_ret) | 123 | unsigned long *len_ret, char *buf_ret) |
96 | { | 124 | { |
125 | long rc; | ||
126 | unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; | ||
97 | unsigned long *lbuf = (unsigned long *)buf_ret; /* TODO: alignment? */ | 127 | unsigned long *lbuf = (unsigned long *)buf_ret; /* TODO: alignment? */ |
98 | return plpar_hcall(H_GET_TERM_CHAR, termno, 0, 0, 0, len_ret, | 128 | |
99 | lbuf + 0, lbuf + 1); | 129 | rc = plpar_hcall(H_GET_TERM_CHAR, retbuf, termno); |
130 | |||
131 | *len_ret = retbuf[0]; | ||
132 | lbuf[0] = retbuf[1]; | ||
133 | lbuf[1] = retbuf[2]; | ||
134 | |||
135 | return rc; | ||
100 | } | 136 | } |
101 | 137 | ||
102 | static inline long plpar_put_term_char(unsigned long termno, unsigned long len, | 138 | static inline long plpar_put_term_char(unsigned long termno, unsigned long len, |
@@ -107,4 +143,31 @@ static inline long plpar_put_term_char(unsigned long termno, unsigned long len, | |||
107 | lbuf[1]); | 143 | lbuf[1]); |
108 | } | 144 | } |
109 | 145 | ||
146 | static inline long plpar_eoi(unsigned long xirr) | ||
147 | { | ||
148 | return plpar_hcall_norets(H_EOI, xirr); | ||
149 | } | ||
150 | |||
151 | static inline long plpar_cppr(unsigned long cppr) | ||
152 | { | ||
153 | return plpar_hcall_norets(H_CPPR, cppr); | ||
154 | } | ||
155 | |||
156 | static inline long plpar_ipi(unsigned long servernum, unsigned long mfrr) | ||
157 | { | ||
158 | return plpar_hcall_norets(H_IPI, servernum, mfrr); | ||
159 | } | ||
160 | |||
161 | static inline long plpar_xirr(unsigned long *xirr_ret) | ||
162 | { | ||
163 | long rc; | ||
164 | unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; | ||
165 | |||
166 | rc = plpar_hcall(H_XIRR, retbuf); | ||
167 | |||
168 | *xirr_ret = retbuf[0]; | ||
169 | |||
170 | return rc; | ||
171 | } | ||
172 | |||
110 | #endif /* _PSERIES_PLPAR_WRAPPERS_H */ | 173 | #endif /* _PSERIES_PLPAR_WRAPPERS_H */ |
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c index 1eab4688be17..c88ec63129f3 100644 --- a/arch/powerpc/platforms/pseries/xics.c +++ b/arch/powerpc/platforms/pseries/xics.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <asm/i8259.h> | 34 | #include <asm/i8259.h> |
35 | 35 | ||
36 | #include "xics.h" | 36 | #include "xics.h" |
37 | #include "plpar_wrappers.h" | ||
37 | 38 | ||
38 | #define XICS_IPI 2 | 39 | #define XICS_IPI 2 |
39 | #define XICS_IRQ_SPURIOUS 0 | 40 | #define XICS_IRQ_SPURIOUS 0 |
@@ -110,27 +111,6 @@ static inline void direct_qirr_info(int n_cpu, u8 value) | |||
110 | /* LPAR low level accessors */ | 111 | /* LPAR low level accessors */ |
111 | 112 | ||
112 | 113 | ||
113 | static inline long plpar_eoi(unsigned long xirr) | ||
114 | { | ||
115 | return plpar_hcall_norets(H_EOI, xirr); | ||
116 | } | ||
117 | |||
118 | static inline long plpar_cppr(unsigned long cppr) | ||
119 | { | ||
120 | return plpar_hcall_norets(H_CPPR, cppr); | ||
121 | } | ||
122 | |||
123 | static inline long plpar_ipi(unsigned long servernum, unsigned long mfrr) | ||
124 | { | ||
125 | return plpar_hcall_norets(H_IPI, servernum, mfrr); | ||
126 | } | ||
127 | |||
128 | static inline long plpar_xirr(unsigned long *xirr_ret) | ||
129 | { | ||
130 | unsigned long dummy; | ||
131 | return plpar_hcall(H_XIRR, 0, 0, 0, 0, xirr_ret, &dummy, &dummy); | ||
132 | } | ||
133 | |||
134 | static inline unsigned int lpar_xirr_info_get(int n_cpu) | 114 | static inline unsigned int lpar_xirr_info_get(int n_cpu) |
135 | { | 115 | { |
136 | unsigned long lpar_rc; | 116 | unsigned long lpar_rc; |
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index 0464e78f733a..e56eac88b809 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c | |||
@@ -702,7 +702,8 @@ static int ibmveth_start_xmit(struct sk_buff *skb, struct net_device *netdev) | |||
702 | desc[3].desc, | 702 | desc[3].desc, |
703 | desc[4].desc, | 703 | desc[4].desc, |
704 | desc[5].desc, | 704 | desc[5].desc, |
705 | correlator); | 705 | correlator, |
706 | &correlator); | ||
706 | } while ((lpar_rc == H_BUSY) && (retry_count--)); | 707 | } while ((lpar_rc == H_BUSY) && (retry_count--)); |
707 | 708 | ||
708 | if(lpar_rc != H_SUCCESS && lpar_rc != H_DROPPED) { | 709 | if(lpar_rc != H_SUCCESS && lpar_rc != H_DROPPED) { |
diff --git a/drivers/net/ibmveth.h b/drivers/net/ibmveth.h index 149191cef2f0..f5b25bff1540 100644 --- a/drivers/net/ibmveth.h +++ b/drivers/net/ibmveth.h | |||
@@ -51,8 +51,21 @@ | |||
51 | #define h_add_logical_lan_buffer(ua, buf) \ | 51 | #define h_add_logical_lan_buffer(ua, buf) \ |
52 | plpar_hcall_norets(H_ADD_LOGICAL_LAN_BUFFER, ua, buf) | 52 | plpar_hcall_norets(H_ADD_LOGICAL_LAN_BUFFER, ua, buf) |
53 | 53 | ||
54 | #define h_send_logical_lan(ua, buf1, buf2, buf3, buf4, buf5, buf6, correlator) \ | 54 | static inline long h_send_logical_lan(unsigned long unit_address, |
55 | plpar_hcall_8arg_2ret(H_SEND_LOGICAL_LAN, ua, buf1, buf2, buf3, buf4, buf5, buf6, correlator, &correlator) | 55 | unsigned long desc1, unsigned long desc2, unsigned long desc3, |
56 | unsigned long desc4, unsigned long desc5, unsigned long desc6, | ||
57 | unsigned long corellator_in, unsigned long *corellator_out) | ||
58 | { | ||
59 | long rc; | ||
60 | unsigned long retbuf[PLPAR_HCALL9_BUFSIZE]; | ||
61 | |||
62 | rc = plpar_hcall9(H_SEND_LOGICAL_LAN, retbuf, unit_address, desc1, | ||
63 | desc2, desc3, desc4, desc5, desc6, corellator_in); | ||
64 | |||
65 | *corellator_out = retbuf[0]; | ||
66 | |||
67 | return rc; | ||
68 | } | ||
56 | 69 | ||
57 | #define h_multicast_ctrl(ua, cmd, mac) \ | 70 | #define h_multicast_ctrl(ua, cmd, mac) \ |
58 | plpar_hcall_norets(H_MULTICAST_CTRL, ua, cmd, mac) | 71 | plpar_hcall_norets(H_MULTICAST_CTRL, ua, cmd, mac) |
diff --git a/include/asm-powerpc/hvcall.h b/include/asm-powerpc/hvcall.h index f07ae50cbc2c..63ce1ac8c1f4 100644 --- a/include/asm-powerpc/hvcall.h +++ b/include/asm-powerpc/hvcall.h | |||
@@ -212,94 +212,39 @@ | |||
212 | 212 | ||
213 | #ifndef __ASSEMBLY__ | 213 | #ifndef __ASSEMBLY__ |
214 | 214 | ||
215 | /* plpar_hcall() -- Generic call interface using above opcodes | 215 | /** |
216 | * plpar_hcall_norets: - Make a pseries hypervisor call with no return arguments | ||
217 | * @opcode: The hypervisor call to make. | ||
216 | * | 218 | * |
217 | * The actual call interface is a hypervisor call instruction with | 219 | * This call supports up to 7 arguments and only returns the status of |
218 | * the opcode in R3 and input args in R4-R7. | 220 | * the hcall. Use this version where possible, its slightly faster than |
219 | * Status is returned in R3 with variable output values in R4-R11. | 221 | * the other plpar_hcalls. |
220 | * Only H_PTE_READ with H_READ_4 uses R6-R11 so we ignore it for now | ||
221 | * and return only two out args which MUST ALWAYS BE PROVIDED. | ||
222 | */ | ||
223 | long plpar_hcall(unsigned long opcode, | ||
224 | unsigned long arg1, | ||
225 | unsigned long arg2, | ||
226 | unsigned long arg3, | ||
227 | unsigned long arg4, | ||
228 | unsigned long *out1, | ||
229 | unsigned long *out2, | ||
230 | unsigned long *out3); | ||
231 | |||
232 | /* Same as plpar_hcall but for those opcodes that return no values | ||
233 | * other than status. Slightly more efficient. | ||
234 | */ | 222 | */ |
235 | long plpar_hcall_norets(unsigned long opcode, ...); | 223 | long plpar_hcall_norets(unsigned long opcode, ...); |
236 | 224 | ||
237 | /* | 225 | /** |
238 | * Special hcall interface for ibmveth support. | 226 | * plpar_hcall: - Make a pseries hypervisor call |
239 | * Takes 8 input parms. Returns a rc and stores the | 227 | * @opcode: The hypervisor call to make. |
240 | * R4 return value in *out1. | 228 | * @retbuf: Buffer to store up to 4 return arguments in. |
241 | */ | ||
242 | long plpar_hcall_8arg_2ret(unsigned long opcode, | ||
243 | unsigned long arg1, | ||
244 | unsigned long arg2, | ||
245 | unsigned long arg3, | ||
246 | unsigned long arg4, | ||
247 | unsigned long arg5, | ||
248 | unsigned long arg6, | ||
249 | unsigned long arg7, | ||
250 | unsigned long arg8, | ||
251 | unsigned long *out1); | ||
252 | |||
253 | /* plpar_hcall_4out() | ||
254 | * | 229 | * |
255 | * same as plpar_hcall except with 4 output arguments. | 230 | * This call supports up to 6 arguments and 4 return arguments. Use |
231 | * PLPAR_HCALL_BUFSIZE to size the return argument buffer. | ||
256 | * | 232 | * |
233 | * Used for all but the craziest of phyp interfaces (see plpar_hcall9) | ||
257 | */ | 234 | */ |
258 | long plpar_hcall_4out(unsigned long opcode, | 235 | #define PLPAR_HCALL_BUFSIZE 4 |
259 | unsigned long arg1, | 236 | long plpar_hcall(unsigned long opcode, unsigned long *retbuf, ...); |
260 | unsigned long arg2, | ||
261 | unsigned long arg3, | ||
262 | unsigned long arg4, | ||
263 | unsigned long *out1, | ||
264 | unsigned long *out2, | ||
265 | unsigned long *out3, | ||
266 | unsigned long *out4); | ||
267 | 237 | ||
268 | long plpar_hcall_7arg_7ret(unsigned long opcode, | 238 | /** |
269 | unsigned long arg1, | 239 | * plpar_hcall9: - Make a pseries hypervisor call with up to 9 return arguments |
270 | unsigned long arg2, | 240 | * @opcode: The hypervisor call to make. |
271 | unsigned long arg3, | 241 | * @retbuf: Buffer to store up to 9 return arguments in. |
272 | unsigned long arg4, | 242 | * |
273 | unsigned long arg5, | 243 | * This call supports up to 9 arguments and 9 return arguments. Use |
274 | unsigned long arg6, | 244 | * PLPAR_HCALL9_BUFSIZE to size the return argument buffer. |
275 | unsigned long arg7, | 245 | */ |
276 | unsigned long *out1, | 246 | #define PLPAR_HCALL9_BUFSIZE 9 |
277 | unsigned long *out2, | 247 | long plpar_hcall9(unsigned long opcode, unsigned long *retbuf, ...); |
278 | unsigned long *out3, | ||
279 | unsigned long *out4, | ||
280 | unsigned long *out5, | ||
281 | unsigned long *out6, | ||
282 | unsigned long *out7); | ||
283 | |||
284 | long plpar_hcall_9arg_9ret(unsigned long opcode, | ||
285 | unsigned long arg1, | ||
286 | unsigned long arg2, | ||
287 | unsigned long arg3, | ||
288 | unsigned long arg4, | ||
289 | unsigned long arg5, | ||
290 | unsigned long arg6, | ||
291 | unsigned long arg7, | ||
292 | unsigned long arg8, | ||
293 | unsigned long arg9, | ||
294 | unsigned long *out1, | ||
295 | unsigned long *out2, | ||
296 | unsigned long *out3, | ||
297 | unsigned long *out4, | ||
298 | unsigned long *out5, | ||
299 | unsigned long *out6, | ||
300 | unsigned long *out7, | ||
301 | unsigned long *out8, | ||
302 | unsigned long *out9); | ||
303 | 248 | ||
304 | #endif /* __ASSEMBLY__ */ | 249 | #endif /* __ASSEMBLY__ */ |
305 | #endif /* __KERNEL__ */ | 250 | #endif /* __KERNEL__ */ |