/*1* MIPS specific _mcount support2*3* This file is subject to the terms and conditions of the GNU General Public4* License. See the file "COPYING" in the main directory of this archive for5* more details.6*7* Copyright (C) 2009 Lemote Inc. & DSLab, Lanzhou University, China8* Copyright (C) 2010 DSLab, Lanzhou University, China9* Author: Wu Zhangjin <[email protected]>10*/1112#include <linux/export.h>13#include <asm/regdef.h>14#include <asm/stackframe.h>15#include <asm/ftrace.h>1617.text18.set noreorder19.set noat2021.macro MCOUNT_SAVE_REGS22PTR_SUBU sp, PT_SIZE23PTR_S ra, PT_R31(sp)24PTR_S AT, PT_R1(sp)25PTR_S a0, PT_R4(sp)26PTR_S a1, PT_R5(sp)27PTR_S a2, PT_R6(sp)28PTR_S a3, PT_R7(sp)29#ifdef CONFIG_64BIT30PTR_S a4, PT_R8(sp)31PTR_S a5, PT_R9(sp)32PTR_S a6, PT_R10(sp)33PTR_S a7, PT_R11(sp)34#endif35.endm3637.macro MCOUNT_RESTORE_REGS38PTR_L ra, PT_R31(sp)39PTR_L AT, PT_R1(sp)40PTR_L a0, PT_R4(sp)41PTR_L a1, PT_R5(sp)42PTR_L a2, PT_R6(sp)43PTR_L a3, PT_R7(sp)44#ifdef CONFIG_64BIT45PTR_L a4, PT_R8(sp)46PTR_L a5, PT_R9(sp)47PTR_L a6, PT_R10(sp)48PTR_L a7, PT_R11(sp)49#endif50PTR_ADDIU sp, PT_SIZE51.endm5253.macro RETURN_BACK54jr ra55move ra, AT56.endm5758/*59* The -mmcount-ra-address option of gcc 4.5 uses register $12 to pass60* the location of the parent's return address.61*/62#define MCOUNT_RA_ADDRESS_REG $126364#ifdef CONFIG_DYNAMIC_FTRACE6566NESTED(ftrace_caller, PT_SIZE, ra)67.globl _mcount68_mcount:69EXPORT_SYMBOL(_mcount)70b ftrace_stub71#ifdef CONFIG_32BIT72addiu sp,sp,873#else74nop75#endif7677/* When tracing is activated, it calls ftrace_caller+8 (aka here) */78MCOUNT_SAVE_REGS79#ifdef KBUILD_MCOUNT_RA_ADDRESS80PTR_S MCOUNT_RA_ADDRESS_REG, PT_R12(sp)81#endif8283PTR_SUBU a0, ra, 8 /* arg1: self address */84PTR_LA t1, _stext85sltu t2, a0, t1 /* t2 = (a0 < _stext) */86PTR_LA t1, _etext87sltu t3, t1, a0 /* t3 = (a0 > _etext) */88or t1, t2, t389beqz t1, ftrace_call90nop91#if defined(KBUILD_MCOUNT_RA_ADDRESS) && defined(CONFIG_32BIT)92PTR_SUBU a0, a0, 16 /* arg1: adjust to module's recorded callsite */93#else94PTR_SUBU a0, a0, 1295#endif9697.globl ftrace_call98ftrace_call:99nop /* a placeholder for the call to a real tracing function */100move a1, AT /* arg2: parent's return address */101102#ifdef CONFIG_FUNCTION_GRAPH_TRACER103.globl ftrace_graph_call104ftrace_graph_call:105nop106nop107#endif108109MCOUNT_RESTORE_REGS110.globl ftrace_stub111ftrace_stub:112RETURN_BACK113END(ftrace_caller)114115#else /* ! CONFIG_DYNAMIC_FTRACE */116117NESTED(_mcount, PT_SIZE, ra)118EXPORT_SYMBOL(_mcount)119PTR_LA t1, ftrace_stub120PTR_L t2, ftrace_trace_function /* Prepare t2 for (1) */121beq t1, t2, fgraph_trace122nop123124MCOUNT_SAVE_REGS125126move a0, ra /* arg1: self return address */127jalr t2 /* (1) call *ftrace_trace_function */128move a1, AT /* arg2: parent's return address */129130MCOUNT_RESTORE_REGS131132fgraph_trace:133#ifdef CONFIG_FUNCTION_GRAPH_TRACER134PTR_LA t1, ftrace_stub135PTR_L t3, ftrace_graph_return136bne t1, t3, ftrace_graph_caller137nop138PTR_LA t1, ftrace_graph_entry_stub139PTR_L t3, ftrace_graph_entry140bne t1, t3, ftrace_graph_caller141nop142#endif143144#ifdef CONFIG_32BIT145addiu sp, sp, 8146#endif147148.globl ftrace_stub149ftrace_stub:150RETURN_BACK151END(_mcount)152153#endif /* ! CONFIG_DYNAMIC_FTRACE */154155#ifdef CONFIG_FUNCTION_GRAPH_TRACER156157NESTED(ftrace_graph_caller, PT_SIZE, ra)158#ifndef CONFIG_DYNAMIC_FTRACE159MCOUNT_SAVE_REGS160#endif161162/* arg1: Get the location of the parent's return address */163#ifdef KBUILD_MCOUNT_RA_ADDRESS164#ifdef CONFIG_DYNAMIC_FTRACE165PTR_L a0, PT_R12(sp)166#else167move a0, MCOUNT_RA_ADDRESS_REG168#endif169bnez a0, 1f /* non-leaf func: stored in MCOUNT_RA_ADDRESS_REG */170nop171#endif172PTR_LA a0, PT_R1(sp) /* leaf func: the location in current stack */1731:174175/* arg2: Get self return address */176#ifdef CONFIG_DYNAMIC_FTRACE177PTR_L a1, PT_R31(sp)178#else179move a1, ra180#endif181182/* arg3: Get frame pointer of current stack */183#ifdef CONFIG_64BIT184PTR_LA a2, PT_SIZE(sp)185#else186PTR_LA a2, (PT_SIZE+8)(sp)187#endif188189jal prepare_ftrace_return190nop191MCOUNT_RESTORE_REGS192#ifndef CONFIG_DYNAMIC_FTRACE193#ifdef CONFIG_32BIT194addiu sp, sp, 8195#endif196#endif197RETURN_BACK198END(ftrace_graph_caller)199200.align 2201.globl return_to_handler202return_to_handler:203PTR_SUBU sp, PT_SIZE204PTR_S v0, PT_R2(sp)205206jal ftrace_return_to_handler207PTR_S v1, PT_R3(sp)208209/* restore the real parent address: v0 -> ra */210move ra, v0211212PTR_L v0, PT_R2(sp)213PTR_L v1, PT_R3(sp)214jr ra215PTR_ADDIU sp, PT_SIZE216#endif /* CONFIG_FUNCTION_GRAPH_TRACER */217218.set at219.set reorder220221222