2009-11-16 11:40:14 +03:00
/ *
* Low- l e v e l f t r a c e h a n d l i n g
*
* Copyright ( C ) 2 0 0 9 M i c h a l S i m e k < m o n s t r @monstr.eu>
* Copyright ( C ) 2 0 0 9 P e t a L o g i x
*
* This f i l e i s s u b j e c t t o t h e t e r m s a n d c o n d i t i o n s o f t h e G N U G e n e r a l
* Public L i c e n s e . S e e t h e f i l e C O P Y I N G i n t h e m a i n d i r e c t o r y o f t h i s
* archive f o r m o r e d e t a i l s .
* /
# include < l i n u x / l i n k a g e . h >
# define N O A L I G N _ E N T R Y ( n a m e ) . g l o b l n a m e ; name:
/* FIXME MS: I think that I don't need to save all regs */
# define S A V E _ R E G S \
addik r1 , r1 , - 1 2 0 ; \
swi r2 , r1 , 4 ; \
swi r3 , r1 , 8 ; \
swi r4 , r1 , 1 2 ; \
swi r5 , r1 , 1 1 6 ; \
swi r6 , r1 , 1 6 ; \
swi r7 , r1 , 2 0 ; \
swi r8 , r1 , 2 4 ; \
swi r9 , r1 , 2 8 ; \
swi r10 , r1 , 3 2 ; \
swi r11 , r1 , 3 6 ; \
swi r12 , r1 , 4 0 ; \
swi r13 , r1 , 4 4 ; \
swi r14 , r1 , 4 8 ; \
swi r16 , r1 , 5 2 ; \
swi r17 , r1 , 5 6 ; \
swi r18 , r1 , 6 0 ; \
swi r19 , r1 , 6 4 ; \
swi r20 , r1 , 6 8 ; \
swi r21 , r1 , 7 2 ; \
swi r22 , r1 , 7 6 ; \
swi r23 , r1 , 8 0 ; \
swi r24 , r1 , 8 4 ; \
swi r25 , r1 , 8 8 ; \
swi r26 , r1 , 9 2 ; \
swi r27 , r1 , 9 6 ; \
swi r28 , r1 , 1 0 0 ; \
swi r29 , r1 , 1 0 4 ; \
swi r30 , r1 , 1 0 8 ; \
swi r31 , r1 , 1 1 2 ;
# define R E S T O R E _ R E G S \
lwi r2 , r1 , 4 ; \
lwi r3 , r1 , 8 ; \
lwi r4 , r1 , 1 2 ; \
lwi r5 , r1 , 1 1 6 ; \
lwi r6 , r1 , 1 6 ; \
lwi r7 , r1 , 2 0 ; \
lwi r8 , r1 , 2 4 ; \
lwi r9 , r1 , 2 8 ; \
lwi r10 , r1 , 3 2 ; \
lwi r11 , r1 , 3 6 ; \
lwi r12 , r1 , 4 0 ; \
lwi r13 , r1 , 4 4 ; \
lwi r14 , r1 , 4 8 ; \
lwi r16 , r1 , 5 2 ; \
lwi r17 , r1 , 5 6 ; \
lwi r18 , r1 , 6 0 ; \
lwi r19 , r1 , 6 4 ; \
lwi r20 , r1 , 6 8 ; \
lwi r21 , r1 , 7 2 ; \
lwi r22 , r1 , 7 6 ; \
lwi r23 , r1 , 8 0 ; \
lwi r24 , r1 , 8 4 ; \
lwi r25 , r1 , 8 8 ; \
lwi r26 , r1 , 9 2 ; \
lwi r27 , r1 , 9 6 ; \
lwi r28 , r1 , 1 0 0 ; \
lwi r29 , r1 , 1 0 4 ; \
lwi r30 , r1 , 1 0 8 ; \
lwi r31 , r1 , 1 1 2 ; \
addik r1 , r1 , 1 2 0 ;
ENTRY( f t r a c e _ s t u b )
rtsd r15 , 8 ;
nop;
ENTRY( _ m c o u n t )
2009-12-10 16:15:44 +03:00
# ifdef C O N F I G _ D Y N A M I C _ F T R A C E
ENTRY( f t r a c e _ c a l l e r )
/* MS: It is just barrier which is removed from C code */
rtsd r15 , 8
nop
# endif / * C O N F I G _ D Y N A M I C _ F T R A C E * /
2009-11-16 11:40:14 +03:00
SAVE_ R E G S
swi r15 , r1 , 0 ;
2009-11-16 11:55:08 +03:00
/* MS: HAVE_FUNCTION_TRACE_MCOUNT_TEST begin of checking */
lwi r5 , r0 , f u n c t i o n _ t r a c e _ s t o p ;
bneid r5 , e n d ;
nop;
/* MS: HAVE_FUNCTION_TRACE_MCOUNT_TEST end of checking */
2009-11-16 12:32:10 +03:00
# ifdef C O N F I G _ F U N C T I O N _ G R A P H _ T R A C E R
2009-11-16 12:34:15 +03:00
# ifndef C O N F I G _ D Y N A M I C _ F T R A C E
2009-11-16 12:32:10 +03:00
lwi r5 , r0 , f t r a c e _ g r a p h _ r e t u r n ;
addik r6 , r0 , f t r a c e _ s t u b ; /* asm implementation */
cmpu r5 , r5 , r6 ; /* ftrace_graph_return != ftrace_stub */
beqid r5 , e n d _ g r a p h _ t r a c e r ;
nop;
lwi r6 , r0 , f t r a c e _ g r a p h _ e n t r y ;
addik r5 , r0 , f t r a c e _ g r a p h _ e n t r y _ s t u b ; /* implemented in C */
cmpu r5 , r5 , r6 ; /* ftrace_graph_entry != ftrace_graph_entry_stub */
beqid r5 , e n d _ g r a p h _ t r a c e r ;
nop;
2009-11-16 12:34:15 +03:00
# else / * C O N F I G _ D Y N A M I C _ F T R A C E * /
NOALIGN_ E N T R Y ( f t r a c e _ c a l l _ g r a p h )
/* MS: jump over graph function - replaced from C code */
bri e n d _ g r a p h _ t r a c e r
# endif / * C O N F I G _ D Y N A M I C _ F T R A C E * /
2009-11-16 12:32:10 +03:00
addik r5 , r1 , 1 2 0 ; /* MS: load parent addr */
addik r6 , r15 , 0 ; /* MS: load current function addr */
bralid r15 , p r e p a r e _ f t r a c e _ r e t u r n ;
nop;
/* MS: graph was taken that's why - can jump over function trace */
brid e n d ;
nop;
end_graph_tracer :
# endif / * C O N F I G _ F U N C T I O N _ G R A P H _ T R A C E R * /
2009-12-10 16:15:44 +03:00
# ifndef C O N F I G _ D Y N A M I C _ F T R A C E
2009-11-16 11:40:14 +03:00
/* MS: test function trace if is taken or not */
lwi r20 , r0 , f t r a c e _ t r a c e _ f u n c t i o n ;
addik r6 , r0 , f t r a c e _ s t u b ;
cmpu r5 , r20 , r6 ; /* ftrace_trace_function != ftrace_stub */
beqid r5 , e n d ; /* MS: not taken -> jump over */
nop;
2009-12-10 16:15:44 +03:00
# else / * C O N F I G _ D Y N A M I C _ F T R A C E * /
NOALIGN_ E N T R Y ( f t r a c e _ c a l l )
/* instruction for setup imm FUNC_part1, addik r20, r0, FUNC_part2 */
nop
nop
# endif / * C O N F I G _ D Y N A M I C _ F T R A C E * /
2009-11-16 11:40:14 +03:00
/* static normal trace */
lwi r6 , r1 , 1 2 0 ; /* MS: load parent addr */
addik r5 , r15 , 0 ; /* MS: load current function addr */
/* MS: here is dependency on previous code */
brald r15 , r20 ; /* MS: jump to ftrace handler */
nop;
end :
lwi r15 , r1 , 0 ;
RESTORE_ R E G S
rtsd r15 , 8 ; /* MS: jump back */
nop;
2009-11-16 12:32:10 +03:00
# ifdef C O N F I G _ F U N C T I O N _ G R A P H _ T R A C E R
ENTRY( r e t u r n _ t o _ h a n d l e r )
nop; /* MS: just barrier for rtsd r15, 8 */
nop;
SAVE_ R E G S
swi r15 , r1 , 0 ;
/* MS: find out returning address */
bralid r15 , f t r a c e _ r e t u r n _ t o _ h a n d l e r ;
nop;
/ * MS : return v a l u e f r o m f t r a c e _ r e t u r n _ t o _ h a n d l e r i s m y r e t u r n i n g a d d r
* must b e b e f o r e r e s t o r e r e g s b e c a u s e I h a v e t o r e s t o r e r3 c o n t e n t * /
addik r15 , r3 , 0 ;
RESTORE_ R E G S
rtsd r15 , 8 ; /* MS: jump back */
nop;
# endif / * C O N F I G _ F U N C T I O N _ T R A C E R * /