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.S101
1 files changed, 58 insertions, 43 deletions
diff --git a/arch/powerpc/platforms/pseries/hvCall.S b/arch/powerpc/platforms/pseries/hvCall.S
index c1427b3634ec..01e95ab18d35 100644
--- a/arch/powerpc/platforms/pseries/hvCall.S
+++ b/arch/powerpc/platforms/pseries/hvCall.S
@@ -14,20 +14,54 @@
14 14
15#define STK_PARM(i) (48 + ((i)-3)*8) 15#define STK_PARM(i) (48 + ((i)-3)*8)
16 16
17#ifdef CONFIG_HCALL_STATS 17#ifdef CONFIG_TRACEPOINTS
18
19 .section ".toc","aw"
20
21 .globl hcall_tracepoint_refcount
22hcall_tracepoint_refcount:
23 .llong 0
24
25 .section ".text"
26
18/* 27/*
19 * precall must preserve all registers. use unused STK_PARM() 28 * precall must preserve all registers. use unused STK_PARM()
20 * areas to save snapshots and opcode. 29 * areas to save snapshots and opcode. We branch around this
30 * in early init (eg when populating the MMU hashtable) by using an
31 * unconditional cpu feature.
21 */ 32 */
22#define HCALL_INST_PRECALL \ 33#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; \ 34BEGIN_FTR_SECTION; \
27 mfspr r0,SPRN_PURR; /* get PURR and */ \ 35 b 1f; \
28 std r0,STK_PARM(r6)(r1); /* save for later */ \ 36END_FTR_SECTION(0, 1); \
29END_FTR_SECTION_IFSET(CPU_FTR_PURR); 37 ld r12,hcall_tracepoint_refcount@toc(r2); \
30 38 cmpdi r12,0; \
39 beq+ 1f; \
40 mflr r0; \
41 std r3,STK_PARM(r3)(r1); \
42 std r4,STK_PARM(r4)(r1); \
43 std r5,STK_PARM(r5)(r1); \
44 std r6,STK_PARM(r6)(r1); \
45 std r7,STK_PARM(r7)(r1); \
46 std r8,STK_PARM(r8)(r1); \
47 std r9,STK_PARM(r9)(r1); \
48 std r10,STK_PARM(r10)(r1); \
49 std r0,16(r1); \
50 stdu r1,-STACK_FRAME_OVERHEAD(r1); \
51 bl .__trace_hcall_entry; \
52 addi r1,r1,STACK_FRAME_OVERHEAD; \
53 ld r0,16(r1); \
54 ld r3,STK_PARM(r3)(r1); \
55 ld r4,STK_PARM(r4)(r1); \
56 ld r5,STK_PARM(r5)(r1); \
57 ld r6,STK_PARM(r6)(r1); \
58 ld r7,STK_PARM(r7)(r1); \
59 ld r8,STK_PARM(r8)(r1); \
60 ld r9,STK_PARM(r9)(r1); \
61 ld r10,STK_PARM(r10)(r1); \
62 mtlr r0; \
631:
64
31/* 65/*
32 * postcall is performed immediately before function return which 66 * postcall is performed immediately before function return which
33 * allows liberal use of volatile registers. We branch around this 67 * allows liberal use of volatile registers. We branch around this
@@ -38,40 +72,21 @@ END_FTR_SECTION_IFSET(CPU_FTR_PURR);
38BEGIN_FTR_SECTION; \ 72BEGIN_FTR_SECTION; \
39 b 1f; \ 73 b 1f; \
40END_FTR_SECTION(0, 1); \ 74END_FTR_SECTION(0, 1); \
41 ld r4,STK_PARM(r3)(r1); /* validate opcode */ \ 75 ld r12,hcall_tracepoint_refcount@toc(r2); \
42 cmpldi cr7,r4,MAX_HCALL_OPCODE; \ 76 cmpdi r12,0; \
43 bgt- cr7,1f; \ 77 beq+ 1f; \
44 \ 78 mflr r0; \
45 /* get time and PURR snapshots after hcall */ \ 79 ld r6,STK_PARM(r3)(r1); \
46 mftb r7; /* timebase after */ \ 80 std r3,STK_PARM(r3)(r1); \
47BEGIN_FTR_SECTION; \ 81 mr r4,r3; \
48 mfspr r8,SPRN_PURR; /* PURR after */ \ 82 mr r3,r6; \
49 ld r6,STK_PARM(r6)(r1); /* PURR before */ \ 83 std r0,16(r1); \
50 subf r6,r6,r8; /* delta */ \ 84 stdu r1,-STACK_FRAME_OVERHEAD(r1); \
51END_FTR_SECTION_IFSET(CPU_FTR_PURR); \ 85 bl .__trace_hcall_exit; \
52 ld r5,STK_PARM(r5)(r1); /* timebase before */ \ 86 addi r1,r1,STACK_FRAME_OVERHEAD; \
53 subf r5,r5,r7; /* time delta */ \ 87 ld r0,16(r1); \
54 \ 88 ld r3,STK_PARM(r3)(r1); \
55 /* calculate address of stat structure r4 = opcode */ \ 89 mtlr r0; \
56 srdi r4,r4,2; /* index into array */ \
57 mulli r4,r4,HCALL_STAT_SIZE; \
58 LOAD_REG_ADDR(r7, per_cpu__hcall_stats); \
59 add r4,r4,r7; \
60 ld r7,PACA_DATA_OFFSET(r13); /* per cpu offset */ \
61 add r4,r4,r7; \
62 \
63 /* update stats */ \
64 ld r7,HCALL_STAT_CALLS(r4); /* count */ \
65 addi r7,r7,1; \
66 std r7,HCALL_STAT_CALLS(r4); \
67 ld r7,HCALL_STAT_TB(r4); /* timebase */ \
68 add r7,r7,r5; \
69 std r7,HCALL_STAT_TB(r4); \
70BEGIN_FTR_SECTION; \
71 ld r7,HCALL_STAT_PURR(r4); /* PURR */ \
72 add r7,r7,r6; \
73 std r7,HCALL_STAT_PURR(r4); \
74END_FTR_SECTION_IFSET(CPU_FTR_PURR); \
751: 901:
76#else 91#else
77#define HCALL_INST_PRECALL 92#define HCALL_INST_PRECALL