183f608efb81a490436c248923d6b8d63c847200
[linux-2.6-block.git] / arch / powerpc / kernel / trace / ftrace_32.S
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3  * Split from entry_32.S
4  */
5
6 #include <linux/magic.h>
7 #include <asm/reg.h>
8 #include <asm/ppc_asm.h>
9 #include <asm/asm-offsets.h>
10 #include <asm/ftrace.h>
11 #include <asm/export.h>
12
13 _GLOBAL(mcount)
14 _GLOBAL(_mcount)
15         /*
16          * It is required that _mcount on PPC32 must preserve the
17          * link register. But we have r0 to play with. We use r0
18          * to push the return address back to the caller of mcount
19          * into the ctr register, restore the link register and
20          * then jump back using the ctr register.
21          */
22         mflr    r0
23         mtctr   r0
24         lwz     r0, 4(r1)
25         mtlr    r0
26         bctr
27
28 _GLOBAL(ftrace_caller)
29         MCOUNT_SAVE_FRAME
30         /* r3 ends up with link register */
31         subi    r3, r3, MCOUNT_INSN_SIZE
32 .globl ftrace_call
33 ftrace_call:
34         bl      ftrace_stub
35         nop
36 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
37 .globl ftrace_graph_call
38 ftrace_graph_call:
39         b       ftrace_graph_stub
40 _GLOBAL(ftrace_graph_stub)
41 #endif
42         MCOUNT_RESTORE_FRAME
43         /* old link register ends up in ctr reg */
44         bctr
45
46 EXPORT_SYMBOL(_mcount)
47
48 _GLOBAL(ftrace_stub)
49         blr
50
51 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
52 _GLOBAL(ftrace_graph_caller)
53         /* load r4 with local address */
54         lwz     r4, 44(r1)
55         subi    r4, r4, MCOUNT_INSN_SIZE
56
57         /* Grab the LR out of the caller stack frame */
58         lwz     r3,52(r1)
59
60         bl      prepare_ftrace_return
61         nop
62
63         /*
64          * prepare_ftrace_return gives us the address we divert to.
65          * Change the LR in the callers stack frame to this.
66          */
67         stw     r3,52(r1)
68
69         MCOUNT_RESTORE_FRAME
70         /* old link register ends up in ctr reg */
71         bctr
72
73 _GLOBAL(return_to_handler)
74         /* need to save return values */
75         stwu    r1, -32(r1)
76         stw     r3, 20(r1)
77         stw     r4, 16(r1)
78         stw     r31, 12(r1)
79         mr      r31, r1
80
81         bl      ftrace_return_to_handler
82         nop
83
84         /* return value has real return address */
85         mtlr    r3
86
87         lwz     r3, 20(r1)
88         lwz     r4, 16(r1)
89         lwz     r31,12(r1)
90         lwz     r1, 0(r1)
91
92         /* Jump back to real return address */
93         blr
94 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */