xref: /openbmc/linux/arch/sparc/lib/mcount.S (revision ecba1060)
1/*
2 * Copyright (C) 2000 Anton Blanchard (anton@linuxcare.com)
3 *
4 * This file implements mcount(), which is used to collect profiling data.
5 * This can also be tweaked for kernel stack overflow detection.
6 */
7
8#include <linux/linkage.h>
9
10#include <asm/ptrace.h>
11#include <asm/thread_info.h>
12
13/*
14 * This is the main variant and is called by C code.  GCC's -pg option
15 * automatically instruments every C function with a call to this.
16 */
17
18#ifdef CONFIG_STACK_DEBUG
19
20#define OVSTACKSIZE	4096		/* lets hope this is enough */
21
22	.data
23	.align		8
24panicstring:
25	.asciz		"Stack overflow\n"
26	.align		8
27ovstack:
28	.skip		OVSTACKSIZE
29#endif
30	.text
31	.align		32
32	.globl		_mcount
33	.type		_mcount,#function
34	.globl		mcount
35	.type		mcount,#function
36_mcount:
37mcount:
38#ifdef CONFIG_STACK_DEBUG
39	/*
40	 * Check whether %sp is dangerously low.
41	 */
42	ldub		[%g6 + TI_FPDEPTH], %g1
43	srl		%g1, 1, %g3
44	add		%g3, 1, %g3
45	sllx		%g3, 8, %g3			! each fpregs frame is 256b
46	add		%g3, 192, %g3
47	add		%g6, %g3, %g3			! where does task_struct+frame end?
48	sub		%g3, STACK_BIAS, %g3
49	cmp		%sp, %g3
50	bg,pt		%xcc, 1f
51	 nop
52	lduh		[%g6 + TI_CPU], %g1
53	sethi		%hi(hardirq_stack), %g3
54	or		%g3, %lo(hardirq_stack), %g3
55	sllx		%g1, 3, %g1
56	ldx		[%g3 + %g1], %g7
57	sub		%g7, STACK_BIAS, %g7
58	cmp		%sp, %g7
59	bleu,pt		%xcc, 2f
60	 sethi		%hi(THREAD_SIZE), %g3
61	add		%g7, %g3, %g7
62	cmp		%sp, %g7
63	blu,pn		%xcc, 1f
642:	 sethi		%hi(softirq_stack), %g3
65	or		%g3, %lo(softirq_stack), %g3
66	ldx		[%g3 + %g1], %g7
67	cmp		%sp, %g7
68	bleu,pt		%xcc, 2f
69	 sethi		%hi(THREAD_SIZE), %g3
70	add		%g7, %g3, %g7
71	cmp		%sp, %g7
72	blu,pn		%xcc, 1f
73	 nop
74	/* If we are already on ovstack, don't hop onto it
75	 * again, we are already trying to output the stack overflow
76	 * message.
77	 */
78	sethi		%hi(ovstack), %g7		! cant move to panic stack fast enough
79	 or		%g7, %lo(ovstack), %g7
80	add		%g7, OVSTACKSIZE, %g3
81	sub		%g3, STACK_BIAS + 192, %g3
82	sub		%g7, STACK_BIAS, %g7
83	cmp		%sp, %g7
84	blu,pn		%xcc, 2f
85	 cmp		%sp, %g3
86	bleu,pn		%xcc, 1f
87	 nop
882:	mov		%g3, %sp
89	sethi		%hi(panicstring), %g3
90	call		prom_printf
91	 or		%g3, %lo(panicstring), %o0
92	call		prom_halt
93	 nop
941:
95#endif
96#ifdef CONFIG_FUNCTION_TRACER
97#ifdef CONFIG_DYNAMIC_FTRACE
98	mov		%o7, %o0
99	.globl		mcount_call
100mcount_call:
101	call		ftrace_stub
102	 mov		%o0, %o7
103#else
104	sethi		%hi(ftrace_trace_function), %g1
105	sethi		%hi(ftrace_stub), %g2
106	ldx		[%g1 + %lo(ftrace_trace_function)], %g1
107	or		%g2, %lo(ftrace_stub), %g2
108	cmp		%g1, %g2
109	be,pn		%icc, 1f
110	 mov		%i7, %o1
111	jmpl		%g1, %g0
112	 mov		%o7, %o0
113	/* not reached */
1141:
115#endif
116#endif
117	retl
118	 nop
119	.size		_mcount,.-_mcount
120	.size		mcount,.-mcount
121
122#ifdef CONFIG_FUNCTION_TRACER
123	.globl		ftrace_stub
124	.type		ftrace_stub,#function
125ftrace_stub:
126	retl
127	 nop
128	.size		ftrace_stub,.-ftrace_stub
129#ifdef CONFIG_DYNAMIC_FTRACE
130	.globl		ftrace_caller
131	.type		ftrace_caller,#function
132ftrace_caller:
133	mov		%i7, %o1
134	mov		%o7, %o0
135	.globl		ftrace_call
136ftrace_call:
137	call		ftrace_stub
138	 mov		%o0, %o7
139	retl
140	 nop
141	.size		ftrace_caller,.-ftrace_caller
142#endif
143#endif
144