mirror of https://github.com/Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
287 lines
5.2 KiB
287 lines
5.2 KiB
/* SPDX-License-Identifier: GPL-2.0 |
|
* |
|
* arch/sh/lib/mcount.S |
|
* |
|
* Copyright (C) 2008, 2009 Paul Mundt |
|
* Copyright (C) 2008, 2009 Matt Fleming |
|
*/ |
|
#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 |
|
/* |
|
* Perform diagnostic checks on the state of the kernel stack. |
|
* |
|
* Check for stack overflow. If there is less than 1KB free |
|
* then it has overflowed. |
|
* |
|
* Make sure the stack pointer contains a valid address. Valid |
|
* addresses for kernel stacks are anywhere after the bss |
|
* (after __bss_stop) and anywhere in init_thread_union (init_stack). |
|
*/ |
|
#define STACK_CHECK() \ |
|
mov #(THREAD_SIZE >> 10), r0; \ |
|
shll8 r0; \ |
|
shll2 r0; \ |
|
\ |
|
/* r1 = sp & (THREAD_SIZE - 1) */ \ |
|
mov #-1, r1; \ |
|
add r0, r1; \ |
|
and r15, r1; \ |
|
\ |
|
mov #TI_SIZE, r3; \ |
|
mov #(STACK_WARN >> 8), r2; \ |
|
shll8 r2; \ |
|
add r3, r2; \ |
|
\ |
|
/* Is the stack overflowing? */ \ |
|
cmp/hi r2, r1; \ |
|
bf stack_panic; \ |
|
\ |
|
/* If sp > __bss_stop then we're OK. */ \ |
|
mov.l .L_ebss, r1; \ |
|
cmp/hi r1, r15; \ |
|
bt 1f; \ |
|
\ |
|
/* If sp < init_stack, we're not OK. */ \ |
|
mov.l .L_init_thread_union, r1; \ |
|
cmp/hs r1, r15; \ |
|
bf stack_panic; \ |
|
\ |
|
/* If sp > init_stack && sp < __bss_stop, not OK. */ \ |
|
add r0, r1; \ |
|
cmp/hs r1, r15; \ |
|
bt stack_panic; \ |
|
1: |
|
#else |
|
#define STACK_CHECK() |
|
#endif /* CONFIG_STACK_DEBUG */ |
|
|
|
.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 /* CONFIG_FUNCTION_GRAPH_TRACER */ |
|
|
|
.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 |
|
/* |
|
* NOTE: Do not move either ftrace_graph_call or ftrace_caller |
|
* as this will affect the calculation of GRAPH_INSN_OFFSET. |
|
*/ |
|
.globl ftrace_graph_call |
|
ftrace_graph_call: |
|
mov.l .Lskip_trace, r0 |
|
jmp @r0 |
|
nop |
|
|
|
.align 2 |
|
.Lskip_trace: |
|
.long skip_trace |
|
#endif /* CONFIG_FUNCTION_GRAPH_TRACER */ |
|
|
|
.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 /* CONFIG_FUNCTION_GRAPH_TRACER */ |
|
#endif /* CONFIG_DYNAMIC_FTRACE */ |
|
|
|
.align 2 |
|
|
|
/* |
|
* NOTE: From here on the locations of the .Lftrace_stub label and |
|
* ftrace_stub itself are fixed. Adding additional data here will skew |
|
* the displacement for the memory table and break the block replacement. |
|
* Place new labels either after the ftrace_stub body, or before |
|
* ftrace_caller. You have been warned. |
|
*/ |
|
.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: |
|
/* |
|
* MCOUNT_ENTER() pushed 5 registers onto the stack, so |
|
* the stack address containing our return address is |
|
* r15 + 20. |
|
*/ |
|
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: |
|
/* |
|
* Save the return values. |
|
*/ |
|
mov.l r0, @-r15 |
|
mov.l r1, @-r15 |
|
|
|
mov #0, r4 |
|
|
|
mov.l .Lftrace_return_to_handler, r0 |
|
jsr @r0 |
|
nop |
|
|
|
/* |
|
* The return value from ftrace_return_handler has the real |
|
* address that we should return to. |
|
*/ |
|
lds r0, pr |
|
mov.l @r15+, r1 |
|
rts |
|
mov.l @r15+, r0 |
|
|
|
|
|
.align 2 |
|
.Lftrace_return_to_handler: |
|
.long ftrace_return_to_handler |
|
#endif /* CONFIG_FUNCTION_GRAPH_TRACER */ |
|
#endif /* CONFIG_FUNCTION_TRACER */ |
|
|
|
#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 /* CONFIG_STACK_DEBUG */
|
|
|