1/* 2 * Split from entry_32.S 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation; either version 7 * 2 of the License, or (at your option) any later version. 8 */ 9 10#include <linux/magic.h> 11#include <asm/reg.h> 12#include <asm/ppc_asm.h> 13#include <asm/asm-offsets.h> 14#include <asm/ftrace.h> 15#include <asm/export.h> 16 17#ifdef CONFIG_DYNAMIC_FTRACE 18_GLOBAL(mcount) 19_GLOBAL(_mcount) 20 /* 21 * It is required that _mcount on PPC32 must preserve the 22 * link register. But we have r0 to play with. We use r0 23 * to push the return address back to the caller of mcount 24 * into the ctr register, restore the link register and 25 * then jump back using the ctr register. 26 */ 27 mflr r0 28 mtctr r0 29 lwz r0, 4(r1) 30 mtlr r0 31 bctr 32 33_GLOBAL(ftrace_caller) 34 MCOUNT_SAVE_FRAME 35 /* r3 ends up with link register */ 36 subi r3, r3, MCOUNT_INSN_SIZE 37.globl ftrace_call 38ftrace_call: 39 bl ftrace_stub 40 nop 41#ifdef CONFIG_FUNCTION_GRAPH_TRACER 42.globl ftrace_graph_call 43ftrace_graph_call: 44 b ftrace_graph_stub 45_GLOBAL(ftrace_graph_stub) 46#endif 47 MCOUNT_RESTORE_FRAME 48 /* old link register ends up in ctr reg */ 49 bctr 50#else 51_GLOBAL(mcount) 52_GLOBAL(_mcount) 53 54 MCOUNT_SAVE_FRAME 55 56 subi r3, r3, MCOUNT_INSN_SIZE 57 LOAD_REG_ADDR(r5, ftrace_trace_function) 58 lwz r5,0(r5) 59 60 mtctr r5 61 bctrl 62 nop 63 64#ifdef CONFIG_FUNCTION_GRAPH_TRACER 65 b ftrace_graph_caller 66#endif 67 MCOUNT_RESTORE_FRAME 68 bctr 69#endif 70EXPORT_SYMBOL(_mcount) 71 72_GLOBAL(ftrace_stub) 73 blr 74 75#ifdef CONFIG_FUNCTION_GRAPH_TRACER 76_GLOBAL(ftrace_graph_caller) 77 /* load r4 with local address */ 78 lwz r4, 44(r1) 79 subi r4, r4, MCOUNT_INSN_SIZE 80 81 /* Grab the LR out of the caller stack frame */ 82 lwz r3,52(r1) 83 84 bl prepare_ftrace_return 85 nop 86 87 /* 88 * prepare_ftrace_return gives us the address we divert to. 89 * Change the LR in the callers stack frame to this. 90 */ 91 stw r3,52(r1) 92 93 MCOUNT_RESTORE_FRAME 94 /* old link register ends up in ctr reg */ 95 bctr 96 97_GLOBAL(return_to_handler) 98 /* need to save return values */ 99 stwu r1, -32(r1) 100 stw r3, 20(r1) 101 stw r4, 16(r1) 102 stw r31, 12(r1) 103 mr r31, r1 104 105 bl ftrace_return_to_handler 106 nop 107 108 /* return value has real return address */ 109 mtlr r3 110 111 lwz r3, 20(r1) 112 lwz r4, 16(r1) 113 lwz r31,12(r1) 114 lwz r1, 0(r1) 115 116 /* Jump back to real return address */ 117 blr 118#endif /* CONFIG_FUNCTION_GRAPH_TRACER */ 119