#include <asm/ftrace.h>
#include <asm/thread_info.h>
#include <asm/asm-offsets.h>
#define MCOUNT_ENTER() \
mov.l r4, @-r15; \
mov.l r5, @-r15; \
mov.l r6, @-r15; \
mov.l r7, @-r15; \
sts.l pr, @-r15; \
\
mov.l @(20,r15),r4; \
sts pr, r5
#define MCOUNT_LEAVE() \
lds.l @r15+, pr; \
mov.l @r15+, r7; \
mov.l @r15+, r6; \
mov.l @r15+, r5; \
rts; \
mov.l @r15+, r4
#ifdef CONFIG_STACK_DEBUG
#define STACK_CHECK() \
mov #(THREAD_SIZE >> 10), r0; \
shll8 r0; \
shll2 r0; \
\
\
mov #-1, r1; \
add r0, r1; \
and r15, r1; \
\
mov #TI_SIZE, r3; \
mov #(STACK_WARN >> 8), r2; \
shll8 r2; \
add r3, r2; \
\
\
cmp/hi r2, r1; \
bf stack_panic; \
\
\
mov.l .L_ebss, r1; \
cmp/hi r1, r15; \
bt 1f; \
\
\
mov.l .L_init_thread_union, r1; \
cmp/hs r1, r15; \
bf stack_panic; \
\
\
add r0, r1; \
cmp/hs r1, r15; \
bt stack_panic; \
1:
#else
#define STACK_CHECK()
#endif
.align 2
.globl _mcount
.type _mcount,@function
.globl mcount
.type mcount,@function
_mcount:
mcount:
STACK_CHECK()
#ifndef CONFIG_FUNCTION_TRACER
rts
nop
#else
MCOUNT_ENTER()
#ifdef CONFIG_DYNAMIC_FTRACE
.globl mcount_call
mcount_call:
mov.l .Lftrace_stub, r6
#else
mov.l .Lftrace_trace_function, r6
mov.l ftrace_stub, r7
cmp/eq r6, r7
bt skip_trace
mov.l @r6, r6
#endif
jsr @r6
nop
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
mov.l .Lftrace_graph_return, r6
mov.l .Lftrace_stub, r7
cmp/eq r6, r7
bt 1f
mov.l .Lftrace_graph_caller, r0
jmp @r0
nop
1:
mov.l .Lftrace_graph_entry, r6
mov.l .Lftrace_graph_entry_stub, r7
cmp/eq r6, r7
bt skip_trace
mov.l .Lftrace_graph_caller, r0
jmp @r0
nop
.align 2
.Lftrace_graph_return:
.long ftrace_graph_return
.Lftrace_graph_entry:
.long ftrace_graph_entry
.Lftrace_graph_entry_stub:
.long ftrace_graph_entry_stub
.Lftrace_graph_caller:
.long ftrace_graph_caller
#endif
.globl skip_trace
skip_trace:
MCOUNT_LEAVE()
.align 2
.Lftrace_trace_function:
.long ftrace_trace_function
#ifdef CONFIG_DYNAMIC_FTRACE
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
.globl ftrace_graph_call
ftrace_graph_call:
mov.l .Lskip_trace, r0
jmp @r0
nop
.align 2
.Lskip_trace:
.long skip_trace
#endif
.globl ftrace_caller
ftrace_caller:
MCOUNT_ENTER()
.globl ftrace_call
ftrace_call:
mov.l .Lftrace_stub, r6
jsr @r6
nop
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
bra ftrace_graph_call
nop
#else
MCOUNT_LEAVE()
#endif
#endif
.align 2
.Lftrace_stub:
.long ftrace_stub
.globl ftrace_stub
ftrace_stub:
rts
nop
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
.globl ftrace_graph_caller
ftrace_graph_caller:
mov.l 2f, r1
jmp @r1
nop
1:
mov #20, r0
add r15, r0
mov r0, r4
mov.l .Lprepare_ftrace_return, r0
jsr @r0
nop
MCOUNT_LEAVE()
.align 2
2: .long skip_trace
.Lprepare_ftrace_return:
.long prepare_ftrace_return
.globl return_to_handler
return_to_handler:
mov.l r0, @-r15
mov.l r1, @-r15
mov #0, r4
mov.l .Lftrace_return_to_handler, r0
jsr @r0
nop
lds r0, pr
mov.l @r15+, r1
rts
mov.l @r15+, r0
.align 2
.Lftrace_return_to_handler:
.long ftrace_return_to_handler
#endif
#endif
#ifdef CONFIG_STACK_DEBUG
.globl stack_panic
stack_panic:
mov.l .Ldump_stack, r0
jsr @r0
nop
mov.l .Lpanic, r0
jsr @r0
mov.l .Lpanic_s, r4
rts
nop
.align 2
.L_init_thread_union:
.long init_thread_union
.L_ebss:
.long __bss_stop
.Lpanic:
.long panic
.Lpanic_s:
.long .Lpanic_str
.Ldump_stack:
.long dump_stack
.section .rodata
.align 2
.Lpanic_str:
.string "Stack error"
#endif