diff options
author | Michael Neuling <mikey@neuling.org> | 2010-05-10 16:28:26 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2010-05-21 03:31:10 -0400 |
commit | f90ece28c1f5b3ec13fe481406857fe92f4bc7d1 (patch) | |
tree | cd79abe5db649fd40be88066cb16a5192a676096 | |
parent | 095c7965f4dc870ed2b65143b1e2610de653416c (diff) |
powerpc/pseries: Add hcall to read 4 ptes at a time in real mode
This adds plpar_pte_read_4_raw() which can be used read 4 PTEs from
PHYP at a time, while in real mode.
It also creates a new hcall9 which can be used in real mode. It's the
same as plpar_hcall9 but minus the tracing hcall statistics which may
require variables outside the RMO.
Signed-off-by: Michael Neuling <mikey@neuling.org>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r-- | arch/powerpc/include/asm/hvcall.h | 1 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/hvCall.S | 38 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/plpar_wrappers.h | 18 |
3 files changed, 57 insertions, 0 deletions
diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h index ebe7493e93e3..5119b7db3142 100644 --- a/arch/powerpc/include/asm/hvcall.h +++ b/arch/powerpc/include/asm/hvcall.h | |||
@@ -282,6 +282,7 @@ long plpar_hcall_raw(unsigned long opcode, unsigned long *retbuf, ...); | |||
282 | */ | 282 | */ |
283 | #define PLPAR_HCALL9_BUFSIZE 9 | 283 | #define PLPAR_HCALL9_BUFSIZE 9 |
284 | long plpar_hcall9(unsigned long opcode, unsigned long *retbuf, ...); | 284 | long plpar_hcall9(unsigned long opcode, unsigned long *retbuf, ...); |
285 | long plpar_hcall9_raw(unsigned long opcode, unsigned long *retbuf, ...); | ||
285 | 286 | ||
286 | /* For hcall instrumentation. One structure per-hcall, per-CPU */ | 287 | /* For hcall instrumentation. One structure per-hcall, per-CPU */ |
287 | struct hcall_stats { | 288 | struct hcall_stats { |
diff --git a/arch/powerpc/platforms/pseries/hvCall.S b/arch/powerpc/platforms/pseries/hvCall.S index 383a5d0e9818..48d20573e4de 100644 --- a/arch/powerpc/platforms/pseries/hvCall.S +++ b/arch/powerpc/platforms/pseries/hvCall.S | |||
@@ -228,3 +228,41 @@ _GLOBAL(plpar_hcall9) | |||
228 | mtcrf 0xff,r0 | 228 | mtcrf 0xff,r0 |
229 | 229 | ||
230 | blr /* return r3 = status */ | 230 | blr /* return r3 = status */ |
231 | |||
232 | /* See plpar_hcall_raw to see why this is needed */ | ||
233 | _GLOBAL(plpar_hcall9_raw) | ||
234 | HMT_MEDIUM | ||
235 | |||
236 | mfcr r0 | ||
237 | stw r0,8(r1) | ||
238 | |||
239 | std r4,STK_PARM(r4)(r1) /* Save ret buffer */ | ||
240 | |||
241 | mr r4,r5 | ||
242 | mr r5,r6 | ||
243 | mr r6,r7 | ||
244 | mr r7,r8 | ||
245 | mr r8,r9 | ||
246 | mr r9,r10 | ||
247 | ld r10,STK_PARM(r11)(r1) /* put arg7 in R10 */ | ||
248 | ld r11,STK_PARM(r12)(r1) /* put arg8 in R11 */ | ||
249 | ld r12,STK_PARM(r13)(r1) /* put arg9 in R12 */ | ||
250 | |||
251 | HVSC /* invoke the hypervisor */ | ||
252 | |||
253 | mr r0,r12 | ||
254 | ld r12,STK_PARM(r4)(r1) | ||
255 | std r4, 0(r12) | ||
256 | std r5, 8(r12) | ||
257 | std r6, 16(r12) | ||
258 | std r7, 24(r12) | ||
259 | std r8, 32(r12) | ||
260 | std r9, 40(r12) | ||
261 | std r10,48(r12) | ||
262 | std r11,56(r12) | ||
263 | std r0, 64(r12) | ||
264 | |||
265 | lwz r0,8(r1) | ||
266 | mtcrf 0xff,r0 | ||
267 | |||
268 | blr /* return r3 = status */ | ||
diff --git a/arch/powerpc/platforms/pseries/plpar_wrappers.h b/arch/powerpc/platforms/pseries/plpar_wrappers.h index 6c4fd2c3f385..d9801117124b 100644 --- a/arch/powerpc/platforms/pseries/plpar_wrappers.h +++ b/arch/powerpc/platforms/pseries/plpar_wrappers.h | |||
@@ -191,6 +191,24 @@ static inline long plpar_pte_read_raw(unsigned long flags, unsigned long ptex, | |||
191 | return rc; | 191 | return rc; |
192 | } | 192 | } |
193 | 193 | ||
194 | /* | ||
195 | * plpar_pte_read_4_raw can be called in real mode. | ||
196 | * ptes must be 8*sizeof(unsigned long) | ||
197 | */ | ||
198 | static inline long plpar_pte_read_4_raw(unsigned long flags, unsigned long ptex, | ||
199 | unsigned long *ptes) | ||
200 | |||
201 | { | ||
202 | long rc; | ||
203 | unsigned long retbuf[PLPAR_HCALL9_BUFSIZE]; | ||
204 | |||
205 | rc = plpar_hcall9_raw(H_READ, retbuf, flags | H_READ_4, ptex); | ||
206 | |||
207 | memcpy(ptes, retbuf, 8*sizeof(unsigned long)); | ||
208 | |||
209 | return rc; | ||
210 | } | ||
211 | |||
194 | static inline long plpar_pte_protect(unsigned long flags, unsigned long ptex, | 212 | static inline long plpar_pte_protect(unsigned long flags, unsigned long ptex, |
195 | unsigned long avpn) | 213 | unsigned long avpn) |
196 | { | 214 | { |