aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/pseries/hvCall.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/platforms/pseries/hvCall.S')
-rw-r--r--arch/powerpc/platforms/pseries/hvCall.S72
1 files changed, 72 insertions, 0 deletions
diff --git a/arch/powerpc/platforms/pseries/hvCall.S b/arch/powerpc/platforms/pseries/hvCall.S
index 9a99b056bd27..c00cfed7af2c 100644
--- a/arch/powerpc/platforms/pseries/hvCall.S
+++ b/arch/powerpc/platforms/pseries/hvCall.S
@@ -10,9 +10,69 @@
10#include <asm/hvcall.h> 10#include <asm/hvcall.h>
11#include <asm/processor.h> 11#include <asm/processor.h>
12#include <asm/ppc_asm.h> 12#include <asm/ppc_asm.h>
13#include <asm/asm-offsets.h>
13 14
14#define STK_PARM(i) (48 + ((i)-3)*8) 15#define STK_PARM(i) (48 + ((i)-3)*8)
15 16
17#ifdef CONFIG_HCALL_STATS
18/*
19 * precall must preserve all registers. use unused STK_PARM()
20 * areas to save snapshots and opcode.
21 */
22#define HCALL_INST_PRECALL \
23 std r3,STK_PARM(r3)(r1); /* save opcode */ \
24 mftb r0; /* get timebase and */ \
25 std r0,STK_PARM(r5)(r1); /* save for later */ \
26BEGIN_FTR_SECTION; \
27 mfspr r0,SPRN_PURR; /* get PURR and */ \
28 std r0,STK_PARM(r6)(r1); /* save for later */ \
29END_FTR_SECTION_IFCLR(CPU_FTR_PURR);
30
31/*
32 * postcall is performed immediately before function return which
33 * allows liberal use of volatile registers.
34 */
35#define HCALL_INST_POSTCALL \
36 ld r4,STK_PARM(r3)(r1); /* validate opcode */ \
37 cmpldi cr7,r4,MAX_HCALL_OPCODE; \
38 bgt- cr7,1f; \
39 \
40 /* get time and PURR snapshots after hcall */ \
41 mftb r7; /* timebase after */ \
42BEGIN_FTR_SECTION; \
43 mfspr r8,SPRN_PURR; /* PURR after */ \
44 ld r6,STK_PARM(r6)(r1); /* PURR before */ \
45 subf r6,r6,r8; /* delta */ \
46END_FTR_SECTION_IFCLR(CPU_FTR_PURR); \
47 ld r5,STK_PARM(r5)(r1); /* timebase before */ \
48 subf r5,r5,r7; /* time delta */ \
49 \
50 /* calculate address of stat structure r4 = opcode */ \
51 srdi r4,r4,2; /* index into array */ \
52 mulli r4,r4,HCALL_STAT_SIZE; \
53 LOAD_REG_ADDR(r7, per_cpu__hcall_stats); \
54 add r4,r4,r7; \
55 ld r7,PACA_DATA_OFFSET(r13); /* per cpu offset */ \
56 add r4,r4,r7; \
57 \
58 /* update stats */ \
59 ld r7,HCALL_STAT_CALLS(r4); /* count */ \
60 addi r7,r7,1; \
61 std r7,HCALL_STAT_CALLS(r4); \
62 ld r7,HCALL_STAT_TB(r4); /* timebase */ \
63 add r7,r7,r5; \
64 std r7,HCALL_STAT_TB(r4); \
65BEGIN_FTR_SECTION; \
66 ld r7,HCALL_STAT_PURR(r4); /* PURR */ \
67 add r7,r7,r6; \
68 std r7,HCALL_STAT_PURR(r4); \
69END_FTR_SECTION_IFCLR(CPU_FTR_PURR); \
701:
71#else
72#define HCALL_INST_PRECALL
73#define HCALL_INST_POSTCALL
74#endif
75
16 .text 76 .text
17 77
18_GLOBAL(plpar_hcall_norets) 78_GLOBAL(plpar_hcall_norets)
@@ -21,8 +81,12 @@ _GLOBAL(plpar_hcall_norets)
21 mfcr r0 81 mfcr r0
22 stw r0,8(r1) 82 stw r0,8(r1)
23 83
84 HCALL_INST_PRECALL
85
24 HVSC /* invoke the hypervisor */ 86 HVSC /* invoke the hypervisor */
25 87
88 HCALL_INST_POSTCALL
89
26 lwz r0,8(r1) 90 lwz r0,8(r1)
27 mtcrf 0xff,r0 91 mtcrf 0xff,r0
28 blr /* return r3 = status */ 92 blr /* return r3 = status */
@@ -33,6 +97,8 @@ _GLOBAL(plpar_hcall)
33 mfcr r0 97 mfcr r0
34 stw r0,8(r1) 98 stw r0,8(r1)
35 99
100 HCALL_INST_PRECALL
101
36 std r4,STK_PARM(r4)(r1) /* Save ret buffer */ 102 std r4,STK_PARM(r4)(r1) /* Save ret buffer */
37 103
38 mr r4,r5 104 mr r4,r5
@@ -50,6 +116,8 @@ _GLOBAL(plpar_hcall)
50 std r6, 16(r12) 116 std r6, 16(r12)
51 std r7, 24(r12) 117 std r7, 24(r12)
52 118
119 HCALL_INST_POSTCALL
120
53 lwz r0,8(r1) 121 lwz r0,8(r1)
54 mtcrf 0xff,r0 122 mtcrf 0xff,r0
55 123
@@ -61,6 +129,8 @@ _GLOBAL(plpar_hcall9)
61 mfcr r0 129 mfcr r0
62 stw r0,8(r1) 130 stw r0,8(r1)
63 131
132 HCALL_INST_PRECALL
133
64 std r4,STK_PARM(r4)(r1) /* Save ret buffer */ 134 std r4,STK_PARM(r4)(r1) /* Save ret buffer */
65 135
66 mr r4,r5 136 mr r4,r5
@@ -86,6 +156,8 @@ _GLOBAL(plpar_hcall9)
86 std r11,56(r12) 156 std r11,56(r12)
87 std r12,64(r12) 157 std r12,64(r12)
88 158
159 HCALL_INST_POSTCALL
160
89 lwz r0,8(r1) 161 lwz r0,8(r1)
90 mtcrf 0xff,r0 162 mtcrf 0xff,r0
91 163