Commit | Line | Data |
---|---|---|
2874c5fd | 1 | /* SPDX-License-Identifier: GPL-2.0-or-later */ |
7853f9c0 NR |
2 | /* |
3 | * Split from entry_32.S | |
7853f9c0 NR |
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 | ||
7853f9c0 NR |
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 | |
7853f9c0 | 45 | |
7853f9c0 NR |
46 | EXPORT_SYMBOL(_mcount) |
47 | ||
48 | _GLOBAL(ftrace_stub) | |
49 | blr | |
50 | ||
51 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | |
52 | _GLOBAL(ftrace_graph_caller) | |
370011a2 | 53 | addi r5, r1, 48 |
7853f9c0 NR |
54 | /* load r4 with local address */ |
55 | lwz r4, 44(r1) | |
56 | subi r4, r4, MCOUNT_INSN_SIZE | |
57 | ||
58 | /* Grab the LR out of the caller stack frame */ | |
59 | lwz r3,52(r1) | |
60 | ||
61 | bl prepare_ftrace_return | |
62 | nop | |
63 | ||
64 | /* | |
65 | * prepare_ftrace_return gives us the address we divert to. | |
66 | * Change the LR in the callers stack frame to this. | |
67 | */ | |
68 | stw r3,52(r1) | |
69 | ||
70 | MCOUNT_RESTORE_FRAME | |
71 | /* old link register ends up in ctr reg */ | |
72 | bctr | |
73 | ||
74 | _GLOBAL(return_to_handler) | |
75 | /* need to save return values */ | |
76 | stwu r1, -32(r1) | |
77 | stw r3, 20(r1) | |
78 | stw r4, 16(r1) | |
79 | stw r31, 12(r1) | |
80 | mr r31, r1 | |
81 | ||
82 | bl ftrace_return_to_handler | |
83 | nop | |
84 | ||
85 | /* return value has real return address */ | |
86 | mtlr r3 | |
87 | ||
88 | lwz r3, 20(r1) | |
89 | lwz r4, 16(r1) | |
90 | lwz r31,12(r1) | |
91 | lwz r1, 0(r1) | |
92 | ||
93 | /* Jump back to real return address */ | |
94 | blr | |
95 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ |