Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * MIPS specific _mcount support
0003  *
0004  * This file is subject to the terms and conditions of the GNU General Public
0005  * License.  See the file "COPYING" in the main directory of this archive for
0006  * more details.
0007  *
0008  * Copyright (C) 2009 Lemote Inc. & DSLab, Lanzhou University, China
0009  * Copyright (C) 2010 DSLab, Lanzhou University, China
0010  * Author: Wu Zhangjin <wuzhangjin@gmail.com>
0011  */
0012 
0013 #include <asm/export.h>
0014 #include <asm/regdef.h>
0015 #include <asm/stackframe.h>
0016 #include <asm/ftrace.h>
0017 
0018     .text
0019     .set noreorder
0020     .set noat
0021 
0022     .macro MCOUNT_SAVE_REGS
0023     PTR_SUBU    sp, PT_SIZE
0024     PTR_S   ra, PT_R31(sp)
0025     PTR_S   AT, PT_R1(sp)
0026     PTR_S   a0, PT_R4(sp)
0027     PTR_S   a1, PT_R5(sp)
0028     PTR_S   a2, PT_R6(sp)
0029     PTR_S   a3, PT_R7(sp)
0030 #ifdef CONFIG_64BIT
0031     PTR_S   a4, PT_R8(sp)
0032     PTR_S   a5, PT_R9(sp)
0033     PTR_S   a6, PT_R10(sp)
0034     PTR_S   a7, PT_R11(sp)
0035 #endif
0036     .endm
0037 
0038     .macro MCOUNT_RESTORE_REGS
0039     PTR_L   ra, PT_R31(sp)
0040     PTR_L   AT, PT_R1(sp)
0041     PTR_L   a0, PT_R4(sp)
0042     PTR_L   a1, PT_R5(sp)
0043     PTR_L   a2, PT_R6(sp)
0044     PTR_L   a3, PT_R7(sp)
0045 #ifdef CONFIG_64BIT
0046     PTR_L   a4, PT_R8(sp)
0047     PTR_L   a5, PT_R9(sp)
0048     PTR_L   a6, PT_R10(sp)
0049     PTR_L   a7, PT_R11(sp)
0050 #endif
0051     PTR_ADDIU   sp, PT_SIZE
0052     .endm
0053 
0054     .macro RETURN_BACK
0055     jr ra
0056      move ra, AT
0057     .endm
0058 
0059 /*
0060  * The -mmcount-ra-address option of gcc 4.5 uses register $12 to pass
0061  * the location of the parent's return address.
0062  */
0063 #define MCOUNT_RA_ADDRESS_REG   $12
0064 
0065 #ifdef CONFIG_DYNAMIC_FTRACE
0066 
0067 NESTED(ftrace_caller, PT_SIZE, ra)
0068     .globl _mcount
0069 _mcount:
0070 EXPORT_SYMBOL(_mcount)
0071     b   ftrace_stub
0072 #ifdef CONFIG_32BIT
0073      addiu sp,sp,8
0074 #else
0075      nop
0076 #endif
0077 
0078     /* When tracing is activated, it calls ftrace_caller+8 (aka here) */
0079     MCOUNT_SAVE_REGS
0080 #ifdef KBUILD_MCOUNT_RA_ADDRESS
0081     PTR_S   MCOUNT_RA_ADDRESS_REG, PT_R12(sp)
0082 #endif
0083 
0084     PTR_SUBU a0, ra, 8  /* arg1: self address */
0085     PTR_LA   t1, _stext
0086     sltu     t2, a0, t1 /* t2 = (a0 < _stext) */
0087     PTR_LA   t1, _etext
0088     sltu     t3, t1, a0 /* t3 = (a0 > _etext) */
0089     or       t1, t2, t3
0090     beqz     t1, ftrace_call
0091      nop
0092 #if defined(KBUILD_MCOUNT_RA_ADDRESS) && defined(CONFIG_32BIT)
0093     PTR_SUBU a0, a0, 16 /* arg1: adjust to module's recorded callsite */
0094 #else
0095     PTR_SUBU a0, a0, 12
0096 #endif
0097 
0098     .globl ftrace_call
0099 ftrace_call:
0100     nop /* a placeholder for the call to a real tracing function */
0101      move   a1, AT      /* arg2: parent's return address */
0102 
0103 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
0104     .globl ftrace_graph_call
0105 ftrace_graph_call:
0106     nop
0107      nop
0108 #endif
0109 
0110     MCOUNT_RESTORE_REGS
0111     .globl ftrace_stub
0112 ftrace_stub:
0113     RETURN_BACK
0114     END(ftrace_caller)
0115 
0116 #else   /* ! CONFIG_DYNAMIC_FTRACE */
0117 
0118 NESTED(_mcount, PT_SIZE, ra)
0119 EXPORT_SYMBOL(_mcount)
0120     PTR_LA  t1, ftrace_stub
0121     PTR_L   t2, ftrace_trace_function /* Prepare t2 for (1) */
0122     beq t1, t2, fgraph_trace
0123      nop
0124 
0125     MCOUNT_SAVE_REGS
0126 
0127     move    a0, ra      /* arg1: self return address */
0128     jalr    t2      /* (1) call *ftrace_trace_function */
0129      move   a1, AT      /* arg2: parent's return address */
0130 
0131     MCOUNT_RESTORE_REGS
0132 
0133 fgraph_trace:
0134 #ifdef  CONFIG_FUNCTION_GRAPH_TRACER
0135     PTR_LA  t1, ftrace_stub
0136     PTR_L   t3, ftrace_graph_return
0137     bne t1, t3, ftrace_graph_caller
0138      nop
0139     PTR_LA  t1, ftrace_graph_entry_stub
0140     PTR_L   t3, ftrace_graph_entry
0141     bne t1, t3, ftrace_graph_caller
0142      nop
0143 #endif
0144 
0145 #ifdef CONFIG_32BIT
0146     addiu sp, sp, 8
0147 #endif
0148 
0149     .globl ftrace_stub
0150 ftrace_stub:
0151     RETURN_BACK
0152     END(_mcount)
0153 
0154 #endif  /* ! CONFIG_DYNAMIC_FTRACE */
0155 
0156 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
0157 
0158 NESTED(ftrace_graph_caller, PT_SIZE, ra)
0159 #ifndef CONFIG_DYNAMIC_FTRACE
0160     MCOUNT_SAVE_REGS
0161 #endif
0162 
0163     /* arg1: Get the location of the parent's return address */
0164 #ifdef KBUILD_MCOUNT_RA_ADDRESS
0165 #ifdef CONFIG_DYNAMIC_FTRACE
0166     PTR_L   a0, PT_R12(sp)
0167 #else
0168     move    a0, MCOUNT_RA_ADDRESS_REG
0169 #endif
0170     bnez    a0, 1f  /* non-leaf func: stored in MCOUNT_RA_ADDRESS_REG */
0171      nop
0172 #endif
0173     PTR_LA  a0, PT_R1(sp)   /* leaf func: the location in current stack */
0174 1:
0175 
0176     /* arg2: Get self return address */
0177 #ifdef CONFIG_DYNAMIC_FTRACE
0178     PTR_L   a1, PT_R31(sp)
0179 #else
0180     move    a1, ra
0181 #endif
0182 
0183     /* arg3: Get frame pointer of current stack */
0184 #ifdef CONFIG_64BIT
0185     PTR_LA  a2, PT_SIZE(sp)
0186 #else
0187     PTR_LA  a2, (PT_SIZE+8)(sp)
0188 #endif
0189 
0190     jal prepare_ftrace_return
0191      nop
0192     MCOUNT_RESTORE_REGS
0193 #ifndef CONFIG_DYNAMIC_FTRACE
0194 #ifdef CONFIG_32BIT
0195     addiu sp, sp, 8
0196 #endif
0197 #endif
0198     RETURN_BACK
0199     END(ftrace_graph_caller)
0200 
0201     .align  2
0202     .globl  return_to_handler
0203 return_to_handler:
0204     PTR_SUBU    sp, PT_SIZE
0205     PTR_S   v0, PT_R2(sp)
0206 
0207     jal ftrace_return_to_handler
0208      PTR_S  v1, PT_R3(sp)
0209 
0210     /* restore the real parent address: v0 -> ra */
0211     move    ra, v0
0212 
0213     PTR_L   v0, PT_R2(sp)
0214     PTR_L   v1, PT_R3(sp)
0215     jr  ra
0216      PTR_ADDIU  sp, PT_SIZE
0217 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
0218 
0219     .set at
0220     .set reorder