linux/arch/mips/kernel/mcount.S
<<
>>
Prefs
   1/*
   2 * MIPS specific _mcount support
   3 *
   4 * This file is subject to the terms and conditions of the GNU General Public
   5 * License.  See the file "COPYING" in the main directory of this archive for
   6 * more details.
   7 *
   8 * Copyright (C) 2009 Lemote Inc. & DSLab, Lanzhou University, China
   9 * Copyright (C) 2010 DSLab, Lanzhou University, China
  10 * Author: Wu Zhangjin <wuzhangjin@gmail.com>
  11 */
  12
  13#include <asm/regdef.h>
  14#include <asm/stackframe.h>
  15#include <asm/ftrace.h>
  16
  17        .text
  18        .set noreorder
  19        .set noat
  20
  21        .macro MCOUNT_SAVE_REGS
  22        PTR_SUBU        sp, PT_SIZE
  23        PTR_S   ra, PT_R31(sp)
  24        PTR_S   AT, PT_R1(sp)
  25        PTR_S   a0, PT_R4(sp)
  26        PTR_S   a1, PT_R5(sp)
  27        PTR_S   a2, PT_R6(sp)
  28        PTR_S   a3, PT_R7(sp)
  29#ifdef CONFIG_64BIT
  30        PTR_S   a4, PT_R8(sp)
  31        PTR_S   a5, PT_R9(sp)
  32        PTR_S   a6, PT_R10(sp)
  33        PTR_S   a7, PT_R11(sp)
  34#endif
  35        .endm
  36
  37        .macro MCOUNT_RESTORE_REGS
  38        PTR_L   ra, PT_R31(sp)
  39        PTR_L   AT, PT_R1(sp)
  40        PTR_L   a0, PT_R4(sp)
  41        PTR_L   a1, PT_R5(sp)
  42        PTR_L   a2, PT_R6(sp)
  43        PTR_L   a3, PT_R7(sp)
  44#ifdef CONFIG_64BIT
  45        PTR_L   a4, PT_R8(sp)
  46        PTR_L   a5, PT_R9(sp)
  47        PTR_L   a6, PT_R10(sp)
  48        PTR_L   a7, PT_R11(sp)
  49        PTR_ADDIU       sp, PT_SIZE
  50#else
  51        PTR_ADDIU       sp, (PT_SIZE + 8)
  52#endif
  53.endm
  54
  55        .macro RETURN_BACK
  56        jr ra
  57         move ra, AT
  58        .endm
  59
  60/*
  61 * The -mmcount-ra-address option of gcc 4.5 uses register $12 to pass
  62 * the location of the parent's return address.
  63 */
  64#define MCOUNT_RA_ADDRESS_REG   $12
  65
  66#ifdef CONFIG_DYNAMIC_FTRACE
  67
  68NESTED(ftrace_caller, PT_SIZE, ra)
  69        .globl _mcount
  70_mcount:
  71        b       ftrace_stub
  72         nop
  73        lw      t1, function_trace_stop
  74        bnez    t1, ftrace_stub
  75         nop
  76
  77        MCOUNT_SAVE_REGS
  78#ifdef KBUILD_MCOUNT_RA_ADDRESS
  79        PTR_S   MCOUNT_RA_ADDRESS_REG, PT_R12(sp)
  80#endif
  81
  82        move    a0, ra          /* arg1: self return address */
  83        .globl ftrace_call
  84ftrace_call:
  85        nop     /* a placeholder for the call to a real tracing function */
  86         move   a1, AT          /* arg2: parent's return address */
  87
  88#ifdef CONFIG_FUNCTION_GRAPH_TRACER
  89        .globl ftrace_graph_call
  90ftrace_graph_call:
  91        nop
  92         nop
  93#endif
  94
  95        MCOUNT_RESTORE_REGS
  96        .globl ftrace_stub
  97ftrace_stub:
  98        RETURN_BACK
  99        END(ftrace_caller)
 100
 101#else   /* ! CONFIG_DYNAMIC_FTRACE */
 102
 103NESTED(_mcount, PT_SIZE, ra)
 104        lw      t1, function_trace_stop
 105        bnez    t1, ftrace_stub
 106         nop
 107        PTR_LA  t1, ftrace_stub
 108        PTR_L   t2, ftrace_trace_function /* Prepare t2 for (1) */
 109        bne     t1, t2, static_trace
 110         nop
 111
 112#ifdef  CONFIG_FUNCTION_GRAPH_TRACER
 113        PTR_L   t3, ftrace_graph_return
 114        bne     t1, t3, ftrace_graph_caller
 115         nop
 116        PTR_LA  t1, ftrace_graph_entry_stub
 117        PTR_L   t3, ftrace_graph_entry
 118        bne     t1, t3, ftrace_graph_caller
 119         nop
 120#endif
 121        b       ftrace_stub
 122         nop
 123
 124static_trace:
 125        MCOUNT_SAVE_REGS
 126
 127        move    a0, ra          /* arg1: self return address */
 128        jalr    t2              /* (1) call *ftrace_trace_function */
 129         move   a1, AT          /* arg2: parent's return address */
 130
 131        MCOUNT_RESTORE_REGS
 132        .globl ftrace_stub
 133ftrace_stub:
 134        RETURN_BACK
 135        END(_mcount)
 136
 137#endif  /* ! CONFIG_DYNAMIC_FTRACE */
 138
 139#ifdef CONFIG_FUNCTION_GRAPH_TRACER
 140
 141NESTED(ftrace_graph_caller, PT_SIZE, ra)
 142#ifndef CONFIG_DYNAMIC_FTRACE
 143        MCOUNT_SAVE_REGS
 144#endif
 145
 146        /* arg1: Get the location of the parent's return address */
 147#ifdef KBUILD_MCOUNT_RA_ADDRESS
 148#ifdef CONFIG_DYNAMIC_FTRACE
 149        PTR_L   a0, PT_R12(sp)
 150#else
 151        move    a0, MCOUNT_RA_ADDRESS_REG
 152#endif
 153        bnez    a0, 1f  /* non-leaf func: stored in MCOUNT_RA_ADDRESS_REG */
 154         nop
 155#endif
 156        PTR_LA  a0, PT_R1(sp)   /* leaf func: the location in current stack */
 1571:
 158
 159        /* arg2: Get self return address */
 160#ifdef CONFIG_DYNAMIC_FTRACE
 161        PTR_L   a1, PT_R31(sp)
 162#else
 163        move    a1, ra
 164#endif
 165
 166        /* arg3: Get frame pointer of current stack */
 167#ifdef CONFIG_FRAME_POINTER
 168        move    a2, fp
 169#else /* ! CONFIG_FRAME_POINTER */
 170#ifdef CONFIG_64BIT
 171        PTR_LA  a2, PT_SIZE(sp)
 172#else
 173        PTR_LA  a2, (PT_SIZE+8)(sp)
 174#endif
 175#endif
 176
 177        jal     prepare_ftrace_return
 178         nop
 179        MCOUNT_RESTORE_REGS
 180        RETURN_BACK
 181        END(ftrace_graph_caller)
 182
 183        .align  2
 184        .globl  return_to_handler
 185return_to_handler:
 186        PTR_SUBU        sp, PT_SIZE
 187        PTR_S   v0, PT_R2(sp)
 188
 189        jal     ftrace_return_to_handler
 190         PTR_S  v1, PT_R3(sp)
 191
 192        /* restore the real parent address: v0 -> ra */
 193        move    ra, v0
 194
 195        PTR_L   v0, PT_R2(sp)
 196        PTR_L   v1, PT_R3(sp)
 197        jr      ra
 198         PTR_ADDIU      sp, PT_SIZE
 199#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
 200
 201        .set at
 202        .set reorder
 203