diff options
Diffstat (limited to 'arch/powerpc/platforms/pseries/hvCall.S')
-rw-r--r-- | arch/powerpc/platforms/pseries/hvCall.S | 72 |
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 */ \ | ||
26 | BEGIN_FTR_SECTION; \ | ||
27 | mfspr r0,SPRN_PURR; /* get PURR and */ \ | ||
28 | std r0,STK_PARM(r6)(r1); /* save for later */ \ | ||
29 | END_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 */ \ | ||
42 | BEGIN_FTR_SECTION; \ | ||
43 | mfspr r8,SPRN_PURR; /* PURR after */ \ | ||
44 | ld r6,STK_PARM(r6)(r1); /* PURR before */ \ | ||
45 | subf r6,r6,r8; /* delta */ \ | ||
46 | END_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); \ | ||
65 | BEGIN_FTR_SECTION; \ | ||
66 | ld r7,HCALL_STAT_PURR(r4); /* PURR */ \ | ||
67 | add r7,r7,r6; \ | ||
68 | std r7,HCALL_STAT_PURR(r4); \ | ||
69 | END_FTR_SECTION_IFCLR(CPU_FTR_PURR); \ | ||
70 | 1: | ||
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 | ||