2013-01-18 15:12:18 +05:30
/ *
* Low L e v e l I n t e r r u p t s / T r a p s / E x c e p t i o n s ( n o n - T L B ) H a n d l i n g f o r A R C
*
* Copyright ( C ) 2 0 0 4 , 2 0 0 7 - 2 0 1 0 , 2 0 1 1 - 2 0 1 2 S y n o p s y s , I n c . ( w w w . s y n o p s y s . c o m )
*
* This p r o g r a m i s f r e e s o f t w a r e ; you can redistribute it and/or modify
* it u n d e r t h e t e r m s o f t h e G N U G e n e r a l P u b l i c L i c e n s e v e r s i o n 2 a s
* published b y t h e F r e e S o f t w a r e F o u n d a t i o n .
*
2013-01-23 16:30:36 +05:30
* vineetg : May 2 0 1 1
* - Userspace u n a l i g n e d a c c e s s e m u l a t i o n
*
2013-01-18 15:12:22 +05:30
* vineetg : Feb 2 0 1 1 ( p t r a c e l o w l e v e l c o d e f i x e s )
* - traced s y s c a l l r e t u r n c o d e ( r0 ) w a s n o t s a v e d i n t o p t _ r e g s f o r r e s t o r i n g
* into u s e r r e g - f i l e w h e n t r a d e d t a s k r e t s t o u s e r s p a c e .
* - syscalls n e e d i n g a r c h - w r a p p e r s ( m a i n l y f o r p a s s i n g s p a s p t _ r e g s )
* were n o t i n v o k i n g p o s t - s y s c a l l t r a c e h o o k ( j u m p i n g d i r e c t l y i n t o
* ret_ f r o m _ s y s t e m _ c a l l )
*
2013-01-18 15:12:18 +05:30
* vineetg : Nov 2 0 1 0 :
* - Vector t a b l e j u m p s ( @8 bytes) converted into branches (@4 bytes)
* - To m a i n t a i n t h e s l o t s i z e o f 8 b y t e s / v e c t o r , a d d e d n o p , w h i c h i s
* not e x e c u t e d a t r u n t i m e .
*
* vineetg : Nov 2 0 0 9 ( E v e r y t h i n g n e e d e d f o r T I F _ R E S T O R E _ S I G M A S K )
* - do_ s i g n a l ( ) i n v o k e d u p o n T I F _ R E S T O R E _ S I G M A S K a s w e l l
* - Wrappers f o r s y s _ { ,r t _ } s i g s u s p e n d ( ) n o l o n g e r n e e d e d a s t h e y d o n ' t
* need p t r e g s a n y m o r e
*
* Vineetg : Oct 2 0 0 9
* - In a r a r e s c e n a r i o , P r o c e s s g e t s a P r i v - V e x c e p t i o n a n d g e t s s c h e d u l e d
* out. S i n c e w e d o n ' t d o F A K E R T I E f o r P r i v - V , C P U e x c p e t i o n s t a t e r e m a i n s
* active ( A E b i t e n a b l e d ) . T h i s c a u s e s a d o u b l e f a u l t f o r a s u b s e q v a l i d
* exception. T h u s F A K E R T I E n e e d e d i n l o w l e v e l P r i v - V i o l a t i o n h a n d l e r .
* Instr E r r o r c o u l d a l s o c a u s e s i m i l a r s c e n a r i o , s o s a m e t h e r e a s w e l l .
*
2013-01-18 15:12:22 +05:30
* Vineetg : March 2 0 0 9 ( S u p p o r t i n g 2 l e v e l s o f I n t e r r u p t s )
*
2013-01-18 15:12:18 +05:30
* Vineetg : Aug 2 8 t h 2 0 0 8 : B u g #94984
* - Zero O v e r h e a d L o o p C o n t e x t s h d b e c l e a r e d w h e n e n t e r i n g I R Q / E X c p / T r a p
* Normally C P U d o e s t h i s a u t o m a t i c a l l y , h o w e v e r w h e n d o i n g F A K E r t i e ,
* we n e e d t o e x p l i c i t l y d o t h i s . T h e p r o b l e m i n m a c r o s
* FAKE_ R E T _ F R O M _ E X C P N a n d F A K E _ R E T _ F R O M _ E X C P N _ L O C K _ I R Q w a s t h a t t h i s b i t
* was b e i n g " C L E A R E D " r a t h e r t h e n " S E T " . S i n c e i t i s L o o p I N H I B I T B i t ,
* setting i t a n d n o t c l e a r i n g i t c l e a r s Z O L c o n t e x t
*
2013-02-11 19:52:57 +05:30
* Vineetg : May 1 6 t h , 2 0 0 8
* - r2 5 n o w c o n t a i n s t h e C u r r e n t T a s k w h e n i n k e r n e l
*
2013-01-18 15:12:18 +05:30
* Vineetg : Dec 2 2 , 2 0 0 7
* Minor S u r g e r y o f L o w L e v e l I S R t o m a k e i t S M P s a f e
* - MMU_ S C R A T C H 0 R e g u s e d f o r f r e e i n g u p r9 i n L e v e l 1 I S R
* - _ current_ t a s k i s m a d e a n a r r a y o f N R _ C P U S
* - Access o f _ c u r r e n t _ t a s k w r a p p e d i n s i d e a m a c r o s o t h a t i f h a r d w a r e
* team a g r e e s f o r a d e d i c a t e d r e g , n o o t h e r c o d e i s t o u c h e d
*
* Amit B h o r , R a h u l T r i v e d i , K a n i k a N e m a , S a m e e r D h a v a l e : C o d i t o T e c h 2 0 0 4
* /
/ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* Function A B I
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*
* Arguments r0 - r7
* Caller S a v e d R e g i s t e r s r0 - r12
* Callee S a v e d R e g i s t e r s r13 - r25
* Global P o i n t e r ( g p ) r26
* Frame P o i n t e r ( f p ) r27
* Stack P o i n t e r ( s p ) r28
* Interrupt l i n k r e g i s t e r ( i l i n k 1 ) r29
* Interrupt l i n k r e g i s t e r ( i l i n k 2 ) r30
* Branch l i n k r e g i s t e r ( b l i n k ) r31
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* /
.cpu A7
;############################ Vector Table #################################
.macro VECTOR lbl
# if 1 / * J u s t i n c a s e , b u i l d b r e a k s * /
j \ l b l
# else
b \ l b l
nop
# endif
.endm
.section .vector , " ax" ,@progbits
.align 4
/ * Each e n t r y i n t h e v e c t o r t a b l e m u s t o c c u p y 2 w o r d s . S i n c e i t i s a j u m p
* across s e c t i o n s ( . v e c t o r t o . t e x t ) w e a r e g a u r a n t e e d t h a t ' j s o m e w h e r e '
* will u s e t h e ' j l i m m ' f o r m o f t h e i n t r s u c t i o n a s l o n g a s s o m e w h e r e i s i n
* a s e c t i o n o t h e r t h a n . v e c t o r .
* /
; ********* Critical System Events **********************
VECTOR r e s _ s e r v i c e ; 0x0, Restart Vector (0x0)
VECTOR m e m _ s e r v i c e ; 0x8, Mem exception (0x1)
VECTOR i n s t r _ s e r v i c e ; 0x10, Instrn Error (0x2)
; ******************** Device ISRs **********************
2013-01-18 15:12:22 +05:30
# ifdef C O N F I G _ A R C _ I R Q 3 _ L V 2
VECTOR h a n d l e _ i n t e r r u p t _ l e v e l 2
# else
2013-01-18 15:12:18 +05:30
VECTOR h a n d l e _ i n t e r r u p t _ l e v e l 1
2013-01-18 15:12:22 +05:30
# endif
2013-01-18 15:12:18 +05:30
VECTOR h a n d l e _ i n t e r r u p t _ l e v e l 1
2013-01-18 15:12:22 +05:30
# ifdef C O N F I G _ A R C _ I R Q 5 _ L V 2
VECTOR h a n d l e _ i n t e r r u p t _ l e v e l 2
# else
2013-01-18 15:12:18 +05:30
VECTOR h a n d l e _ i n t e r r u p t _ l e v e l 1
2013-01-18 15:12:22 +05:30
# endif
2013-01-18 15:12:18 +05:30
2013-01-18 15:12:22 +05:30
# ifdef C O N F I G _ A R C _ I R Q 6 _ L V 2
VECTOR h a n d l e _ i n t e r r u p t _ l e v e l 2
# else
2013-01-18 15:12:18 +05:30
VECTOR h a n d l e _ i n t e r r u p t _ l e v e l 1
2013-01-18 15:12:22 +05:30
# endif
2013-01-18 15:12:18 +05:30
.rept 25
VECTOR h a n d l e _ i n t e r r u p t _ l e v e l 1 ; Other devices
.endr
/* FOR ARC600: timer = 0x3, uart = 0x8, emac = 0x10 */
; ******************** Exceptions **********************
VECTOR E V _ M a c h i n e C h e c k ; 0x100, Fatal Machine check (0x20)
VECTOR E V _ T L B M i s s I ; 0x108, Intruction TLB miss (0x21)
VECTOR E V _ T L B M i s s D ; 0x110, Data TLB miss (0x22)
VECTOR E V _ T L B P r o t V ; 0x118, Protection Violation (0x23)
; or Misaligned Access
VECTOR E V _ P r i v i l e g e V ; 0x120, Privilege Violation (0x24)
VECTOR E V _ T r a p ; 0x128, Trap exception (0x25)
VECTOR E V _ E x t e n s i o n ; 0x130, Extn Intruction Excp (0x26)
.rept 24
VECTOR r e s e r v e d ; Reserved Exceptions
.endr
2014-02-07 13:47:43 +05:30
# include < l i n u x / l i n k a g e . h > / * { E X T R Y ,E X I T } * /
2013-06-11 18:56:54 +05:30
# include < a s m / e n t r y . h > / * S A V E _ A L L _ { I N T 1 ,I N T 2 ,S Y S . . . } * /
2013-01-18 15:12:18 +05:30
# include < a s m / e r r n o . h >
# include < a s m / a r c r e g s . h >
# include < a s m / i r q f l a g s . h >
;##################### Scratch Mem for IRQ stack switching #############
2013-01-18 15:12:25 +05:30
ARCFP_ D A T A i n t 1 _ s a v e d _ r e g
2013-01-18 15:12:18 +05:30
.align 32
.type int1 _ s a v e d _ r e g , @object
.size int1 _ s a v e d _ r e g , 4
int1_saved_reg :
.zero 4
2013-01-18 15:12:22 +05:30
/* Each Interrupt level needs it's own scratch */
# ifdef C O N F I G _ A R C _ C O M P A C T _ I R Q _ L E V E L S
2013-01-18 15:12:25 +05:30
ARCFP_ D A T A i n t 2 _ s a v e d _ r e g
2013-01-18 15:12:22 +05:30
.type int2 _ s a v e d _ r e g , @object
.size int2 _ s a v e d _ r e g , 4
int2_saved_reg :
.zero 4
# endif
2013-01-18 15:12:18 +05:30
; ---------------------------------------------
.section .text , " ax" ,@progbits
res_service : ; processor restart
flag 0 x1 ; not implemented
nop
nop
reserved : ; processor restart
rtie ; jump to processor initializations
;##################### Interrupt Handling ##############################
2013-01-18 15:12:22 +05:30
# ifdef C O N F I G _ A R C _ C O M P A C T _ I R Q _ L E V E L S
; ---------------------------------------------
; Level 2 ISR: Can interrupt a Level 1 ISR
; ---------------------------------------------
2014-02-07 13:47:43 +05:30
ENTRY( h a n d l e _ i n t e r r u p t _ l e v e l 2 )
2013-01-18 15:12:22 +05:30
; TODO-vineetg for SMP this wont work
; free up r9 as scratchpad
st r9 , [ @int2_saved_reg]
;Which mode (user/kernel) was the system in when intr occured
lr r9 , [ s t a t u s32 _ l 2 ]
SWITCH_ T O _ K E R N E L _ S T K
SAVE_ A L L _ I N T 2
;------------------------------------------------------
; if L2 IRQ interrupted a L1 ISR, disable preemption
;------------------------------------------------------
ld r9 , [ s p , P T _ s t a t u s32 ] ; get statu32_l2 (saved in pt_regs)
bbit0 r9 , S T A T U S _ A 1 _ B I T , 1 f ; L1 not active when L2 IRQ, so normal
; A1 is set in status32_l2
; bump thread_info->preempt_count (Disable preemption)
GET_ C U R R _ T H R _ I N F O _ F R O M _ S P r10
ld r9 , [ r10 , T H R E A D _ I N F O _ P R E E M P T _ C O U N T ]
add r9 , r9 , 1
st r9 , [ r10 , T H R E A D _ I N F O _ P R E E M P T _ C O U N T ]
1 :
;------------------------------------------------------
; setup params for Linux common ISR and invoke it
;------------------------------------------------------
lr r0 , [ i c a u s e 2 ]
and r0 , r0 , 0 x1 f
bl. d @arch_do_IRQ
mov r1 , s p
mov r8 ,0 x2
sr r8 , [ A U X _ I R Q _ L V 1 2 ] ; clear bit in Sticky Status Reg
b r e t _ f r o m _ e x c e p t i o n
2014-02-07 13:47:43 +05:30
END( h a n d l e _ i n t e r r u p t _ l e v e l 2 )
2013-01-18 15:12:22 +05:30
# endif
2013-01-18 15:12:18 +05:30
; ---------------------------------------------
; Level 1 ISR
; ---------------------------------------------
2014-02-07 13:47:43 +05:30
ENTRY( h a n d l e _ i n t e r r u p t _ l e v e l 1 )
2013-01-18 15:12:18 +05:30
/* free up r9 as scratchpad */
2013-01-18 15:12:23 +05:30
# ifdef C O N F I G _ S M P
sr r9 , [ A R C _ R E G _ S C R A T C H _ D A T A 0 ]
# else
2013-01-18 15:12:18 +05:30
st r9 , [ @int1_saved_reg]
2013-01-18 15:12:23 +05:30
# endif
2013-01-18 15:12:18 +05:30
;Which mode (user/kernel) was the system in when intr occured
lr r9 , [ s t a t u s32 _ l 1 ]
SWITCH_ T O _ K E R N E L _ S T K
SAVE_ A L L _ I N T 1
lr r0 , [ i c a u s e 1 ]
and r0 , r0 , 0 x1 f
2013-09-06 14:18:17 +05:30
# ifdef C O N F I G _ T R A C E _ I R Q F L A G S
; icause1 needs to be read early, before calling tracing, which
; can clobber scratch regs, hence use of stack to stash it
push r0
TRACE_ A S M _ I R Q _ D I S A B L E
pop r0
# endif
2013-01-18 15:12:18 +05:30
bl. d @arch_do_IRQ
mov r1 , s p
mov r8 ,0 x1
sr r8 , [ A U X _ I R Q _ L V 1 2 ] ; clear bit in Sticky Status Reg
b r e t _ f r o m _ e x c e p t i o n
2014-02-07 13:47:43 +05:30
END( h a n d l e _ i n t e r r u p t _ l e v e l 1 )
2013-01-18 15:12:18 +05:30
;################### Non TLB Exception Handling #############################
; ---------------------------------------------
; Instruction Error Exception Handler
; ---------------------------------------------
2014-02-07 13:47:43 +05:30
ENTRY( i n s t r _ s e r v i c e )
2013-01-18 15:12:18 +05:30
2013-07-09 15:07:13 +05:30
EXCEPTION_ P R O L O G U E
2013-01-18 15:12:18 +05:30
2013-06-12 15:13:40 +05:30
lr r0 , [ e f a ]
mov r1 , s p
2013-01-18 15:12:18 +05:30
FAKE_ R E T _ F R O M _ E X C P N r9
bl d o _ i n s t e r r o r _ o r _ k p r o b e
b r e t _ f r o m _ e x c e p t i o n
2014-02-07 13:47:43 +05:30
END( i n s t r _ s e r v i c e )
2013-01-18 15:12:18 +05:30
; ---------------------------------------------
; Memory Error Exception Handler
; ---------------------------------------------
2014-02-07 13:47:43 +05:30
ENTRY( m e m _ s e r v i c e )
2013-01-18 15:12:18 +05:30
2013-07-09 15:07:13 +05:30
EXCEPTION_ P R O L O G U E
2013-01-18 15:12:18 +05:30
2013-06-12 15:13:40 +05:30
lr r0 , [ e f a ]
mov r1 , s p
2013-07-09 15:07:13 +05:30
FAKE_ R E T _ F R O M _ E X C P N r9
2013-01-18 15:12:18 +05:30
bl d o _ m e m o r y _ e r r o r
b r e t _ f r o m _ e x c e p t i o n
2014-02-07 13:47:43 +05:30
END( m e m _ s e r v i c e )
2013-01-18 15:12:18 +05:30
; ---------------------------------------------
; Machine Check Exception Handler
; ---------------------------------------------
2014-02-07 13:47:43 +05:30
ENTRY( E V _ M a c h i n e C h e c k )
2013-01-18 15:12:18 +05:30
2013-07-09 15:07:13 +05:30
EXCEPTION_ P R O L O G U E
2013-01-18 15:12:18 +05:30
2013-06-12 15:13:40 +05:30
lr r2 , [ e c r ]
lr r0 , [ e f a ]
mov r1 , s p
2013-01-18 15:12:18 +05:30
2013-06-12 15:13:40 +05:30
lsr r3 , r2 , 8
2013-05-28 15:24:30 +05:30
bmsk r3 , r3 , 7
brne r3 , E C R _ C _ M C H K _ D U P _ T L B , 1 f
2013-01-18 15:12:18 +05:30
bl d o _ t l b _ o v e r l a p _ f a u l t
b r e t _ f r o m _ e x c e p t i o n
1 :
; DEAD END: can't do much, display Regs and HALT
SAVE_ C A L L E E _ S A V E D _ U S E R
GET_ C U R R _ T A S K _ F I E L D _ P T R T A S K _ T H R E A D , r10
st s p , [ r10 , T H R E A D _ C A L L E E _ R E G ]
j d o _ m a c h i n e _ c h e c k _ f a u l t
2014-02-07 13:47:43 +05:30
END( E V _ M a c h i n e C h e c k )
2013-01-18 15:12:18 +05:30
; ---------------------------------------------
; Protection Violation Exception Handler
; ---------------------------------------------
2014-02-07 13:47:43 +05:30
ENTRY( E V _ T L B P r o t V )
2013-01-18 15:12:18 +05:30
2013-07-09 15:07:13 +05:30
EXCEPTION_ P R O L O G U E
2013-01-18 15:12:18 +05:30
;---------(3) Save some more regs-----------------
; vineetg: Mar 6th: Random Seg Fault issue #1
; ecr and efa were not saved in case an Intr sneaks in
; after fake rtie
2013-09-18 16:25:40 +05:30
2013-06-12 13:49:02 +05:30
lr r2 , [ e c r ]
2013-09-18 16:25:40 +05:30
lr r0 , [ e f a ] ; Faulting Data address
2013-01-18 15:12:18 +05:30
; --------(4) Return from CPU Exception Mode ---------
; Fake a rtie, but rtie to next label
; That way, subsequently, do_page_fault ( ) executes in pure kernel
; mode with further Exceptions enabled
FAKE_ R E T _ F R O M _ E X C P N r9
2013-09-18 16:25:40 +05:30
mov r1 , s p
2013-01-18 15:12:18 +05:30
;------ (5) Type of Protection Violation? ----------
;
; ProtV Hardware Exception is triggered for Access Faults of 2 types
2013-05-28 15:24:30 +05:30
; -Access Violaton : 00_23_(00|01|02|03)_00
; x r w r+w
; -Unaligned Access : 00_23_04_00
2013-01-18 15:12:18 +05:30
;
2013-05-28 15:24:30 +05:30
bbit1 r2 , E C R _ C _ B I T _ P R O T V _ M I S A L I G _ D A T A , 4 f
2013-01-18 15:12:18 +05:30
;========= (6a) Access Violation Processing ========
bl d o _ p a g e _ f a u l t
b r e t _ f r o m _ e x c e p t i o n
;========== (6b) Non aligned access ============
4 :
2013-01-23 16:30:36 +05:30
SAVE_ C A L L E E _ S A V E D _ U S E R
2013-06-12 15:13:40 +05:30
mov r2 , s p ; callee_regs
2013-01-23 16:30:36 +05:30
2013-01-18 15:12:18 +05:30
bl d o _ m i s a l i g n e d _ a c c e s s
2013-01-23 16:30:36 +05:30
2013-04-06 17:11:58 +05:30
; TBD: optimize - do this only if a callee reg was involved
; either a dst of emulated LD/ST or src with address-writeback
RESTORE_ C A L L E E _ S A V E D _ U S E R
2013-01-23 16:30:36 +05:30
2013-01-18 15:12:18 +05:30
b r e t _ f r o m _ e x c e p t i o n
2014-02-07 13:47:43 +05:30
END( E V _ T L B P r o t V )
2013-01-18 15:12:18 +05:30
; ---------------------------------------------
; Privilege Violation Exception Handler
; ---------------------------------------------
2014-02-07 13:47:43 +05:30
ENTRY( E V _ P r i v i l e g e V )
2013-01-18 15:12:18 +05:30
2013-07-09 15:07:13 +05:30
EXCEPTION_ P R O L O G U E
2013-01-18 15:12:18 +05:30
2013-06-12 15:13:40 +05:30
lr r0 , [ e f a ]
mov r1 , s p
2013-01-18 15:12:18 +05:30
FAKE_ R E T _ F R O M _ E X C P N r9
bl d o _ p r i v i l e g e _ f a u l t
b r e t _ f r o m _ e x c e p t i o n
2014-02-07 13:47:43 +05:30
END( E V _ P r i v i l e g e V )
2013-01-18 15:12:18 +05:30
; ---------------------------------------------
; Extension Instruction Exception Handler
; ---------------------------------------------
2014-02-07 13:47:43 +05:30
ENTRY( E V _ E x t e n s i o n )
2013-01-18 15:12:18 +05:30
2013-07-09 15:07:13 +05:30
EXCEPTION_ P R O L O G U E
2013-01-18 15:12:18 +05:30
2013-06-12 15:13:40 +05:30
lr r0 , [ e f a ]
mov r1 , s p
2013-07-09 15:07:13 +05:30
FAKE_ R E T _ F R O M _ E X C P N r9
2013-01-18 15:12:18 +05:30
bl d o _ e x t e n s i o n _ f a u l t
b r e t _ f r o m _ e x c e p t i o n
2014-02-07 13:47:43 +05:30
END( E V _ E x t e n s i o n )
2013-01-18 15:12:18 +05:30
2013-01-18 15:12:22 +05:30
;######################### System Call Tracing #########################
tracesys :
; save EFA in case tracer wants the PC of traced task
; using ERET won't work since next-PC has already committed
lr r12 , [ e f a ]
GET_ C U R R _ T A S K _ F I E L D _ P T R T A S K _ T H R E A D , r11
2013-03-20 16:53:14 +05:30
st r12 , [ r11 , T H R E A D _ F A U L T _ A D D R ] ; thread.fault_address
2013-01-18 15:12:22 +05:30
; PRE Sys Call Ptrace hook
mov r0 , s p ; pt_regs needed
bl @syscall_trace_entry
; Tracing code now returns the syscall num (orig or modif)
mov r8 , r0
; Do the Sys Call as we normally would.
; Validate the Sys Call number
cmp r8 , N R _ s y s c a l l s
mov. h i r0 , - E N O S Y S
bhi t r a c e s y s _ e x i t
; Restore the sys-call args. Mere invocation of the hook abv could have
; clobbered them (since they are in scratch regs). The tracer could also
; have deliberately changed the syscall args: r0-r7
ld r0 , [ s p , P T _ r0 ]
ld r1 , [ s p , P T _ r1 ]
ld r2 , [ s p , P T _ r2 ]
ld r3 , [ s p , P T _ r3 ]
ld r4 , [ s p , P T _ r4 ]
ld r5 , [ s p , P T _ r5 ]
ld r6 , [ s p , P T _ r6 ]
ld r7 , [ s p , P T _ r7 ]
ld. a s r9 , [ s y s _ c a l l _ t a b l e , r8 ]
jl [ r9 ] ; Entry into Sys Call Handler
tracesys_exit :
st r0 , [ s p , P T _ r0 ] ; sys call return value in pt_regs
;POST Sys Call Ptrace Hook
bl @syscall_trace_exit
b r e t _ f r o m _ e x c e p t i o n ; NOT ret_from_system_call at is saves r0 which
; we'd done before calling post hook above
2013-01-18 15:12:18 +05:30
;################### Break Point TRAP ##########################
; ======= (5b) Trap is due to Break-Point =========
trap_with_param :
2013-02-11 20:01:24 +05:30
; stop_pc info by gdb needs this info
2013-06-12 15:13:40 +05:30
lr r0 , [ e f a ]
mov r1 , s p
2013-01-18 15:12:18 +05:30
; Now that we have read EFA, its safe to do "fake" rtie
; and get out of CPU exception mode
FAKE_ R E T _ F R O M _ E X C P N r11
; Save callee regs in case gdb wants to have a look
; SP will grow up by size of CALLEE Reg-File
; NOTE: clobbers r12
SAVE_ C A L L E E _ S A V E D _ U S E R
; save location of saved Callee Regs @ thread_struct->pc
GET_ C U R R _ T A S K _ F I E L D _ P T R T A S K _ T H R E A D , r10
st s p , [ r10 , T H R E A D _ C A L L E E _ R E G ]
; Call the trap handler
bl d o _ n o n _ s w i _ t r a p
; unwind stack to discard Callee saved Regs
DISCARD_ C A L L E E _ S A V E D _ U S E R
b r e t _ f r o m _ e x c e p t i o n
;##################### Trap Handling ##############################
;
; EV_Trap caused by TRAP_S and TRAP0 instructions.
;------------------------------------------------------------------
; (1) System Calls
; :parameters in r0-r7.
; :r8 has the system call number
; (2) Break Points
;------------------------------------------------------------------
2014-02-07 13:47:43 +05:30
ENTRY( E V _ T r a p )
2013-01-18 15:12:18 +05:30
2013-07-09 15:07:13 +05:30
EXCEPTION_ P R O L O G U E
2013-01-18 15:12:18 +05:30
;------- (4) What caused the Trap --------------
lr r12 , [ e c r ]
2013-05-28 15:24:30 +05:30
bmsk. f 0 , r12 , 7
2013-01-18 15:12:18 +05:30
bnz t r a p _ w i t h _ p a r a m
; ======= (5a) Trap is due to System Call ========
; Before doing anything, return from CPU Exception Mode
FAKE_ R E T _ F R O M _ E X C P N r11
2013-01-18 15:12:22 +05:30
; If syscall tracing ongoing, invoke pre-pos-hooks
GET_ C U R R _ T H R _ I N F O _ F L A G S r10
btst r10 , T I F _ S Y S C A L L _ T R A C E
bnz t r a c e s y s ; this never comes back
2013-01-18 15:12:18 +05:30
;============ This is normal System Call case ==========
; Sys-call num shd not exceed the total system calls avail
cmp r8 , N R _ s y s c a l l s
mov. h i r0 , - E N O S Y S
bhi r e t _ f r o m _ s y s t e m _ c a l l
; Offset into the syscall_table and call handler
ld. a s r9 ,[ s y s _ c a l l _ t a b l e , r8 ]
jl [ r9 ] ; Entry into Sys Call Handler
; fall through to ret_from_system_call
2014-02-07 13:47:43 +05:30
END( E V _ T r a p )
2013-01-18 15:12:18 +05:30
2014-02-07 13:47:43 +05:30
ENTRY( r e t _ f r o m _ s y s t e m _ c a l l )
2013-01-18 15:12:18 +05:30
st r0 , [ s p , P T _ r0 ] ; sys call return value in pt_regs
; fall through yet again to ret_from_exception
;############# Return from Intr/Excp/Trap (Linux Specifics) ##############
;
; If ret to user mode do we need to handle signals, schedule() et al.
2014-02-07 13:47:43 +05:30
ENTRY( r e t _ f r o m _ e x c e p t i o n )
2013-01-18 15:12:18 +05:30
; Pre-{IRQ,Trap,Exception} K/U mode from pt_regs->status32
ld r8 , [ s p , P T _ s t a t u s32 ] ; returning to User/Kernel Mode
bbit0 r8 , S T A T U S _ U _ B I T , r e s u m e _ k e r n e l _ m o d e
; Before returning to User mode check-for-and-complete any pending work
; such as rescheduling/signal-delivery etc.
resume_user_mode_begin :
; Disable IRQs to ensures that chk for pending work itself is atomic
; (and we don't end up missing a NEED_RESCHED/SIGPENDING due to an
; interim IRQ).
IRQ_ D I S A B L E r10
; Fast Path return to user mode if no pending work
GET_ C U R R _ T H R _ I N F O _ F L A G S r9
and. f 0 , r9 , _ T I F _ W O R K _ M A S K
bz r e s t o r e _ r e g s
; --- (Slow Path #1) task preemption ---
bbit0 r9 , T I F _ N E E D _ R E S C H E D , . L c h k _ p e n d _ s i g n a l s
mov b l i n k , r e s u m e _ u s e r _ m o d e _ b e g i n ; tail-call to U mode ret chks
b @schedule ; BTST+Bnz causes relo error in link
.Lchk_pend_signals :
IRQ_ E N A B L E r10
; --- (Slow Path #2) pending signal ---
mov r0 , s p ; pt_regs for arg to do_signal()/do_notify_resume()
2013-09-06 14:18:17 +05:30
GET_ C U R R _ T H R _ I N F O _ F L A G S r9
2013-01-18 15:12:18 +05:30
bbit0 r9 , T I F _ S I G P E N D I N G , . L c h k _ n o t i f y _ r e s u m e
2013-01-18 15:12:19 +05:30
; Normal Trap/IRQ entry only saves Scratch (caller-saved) regs
; in pt_reg since the "C" ABI (kernel code) will automatically
; save/restore callee-saved regs.
;
; However, here we need to explicitly save callee regs because
2013-01-18 15:12:18 +05:30
; (i) If this signal causes coredump - full regfile needed
; (ii) If signal is SIGTRAP/SIGSTOP, task is being traced thus
; tracer might call PEEKUSR(CALLEE reg)
;
; NOTE: SP will grow up by size of CALLEE Reg-File
SAVE_ C A L L E E _ S A V E D _ U S E R ; clobbers r12
; save location of saved Callee Regs @ thread_struct->callee
GET_ C U R R _ T A S K _ F I E L D _ P T R T A S K _ T H R E A D , r10
st s p , [ r10 , T H R E A D _ C A L L E E _ R E G ]
bl @do_signal
2013-01-18 15:12:19 +05:30
; Ideally we want to discard the Callee reg above, however if this was
; a tracing signal, tracer could have done a POKEUSR(CALLEE reg)
RESTORE_ C A L L E E _ S A V E D _ U S E R
2013-01-18 15:12:18 +05:30
b r e s u m e _ u s e r _ m o d e _ b e g i n ; loop back to start of U mode ret
; --- (Slow Path #3) notify_resume ---
.Lchk_notify_resume :
btst r9 , T I F _ N O T I F Y _ R E S U M E
blnz @do_notify_resume
b r e s u m e _ u s e r _ m o d e _ b e g i n ; unconditionally back to U mode ret chks
; for single exit point from this block
resume_kernel_mode :
2014-04-30 15:26:45 +05:30
; Disable Interrupts from this point on
; CONFIG_PREEMPT: This is a must for preempt_schedule_irq()
; !CONFIG_PREEMPT: To ensure restore_regs is intr safe
2013-07-09 17:06:40 +05:30
IRQ_ D I S A B L E r9
2014-04-30 15:26:45 +05:30
# ifdef C O N F I G _ P R E E M P T
2013-01-18 15:12:18 +05:30
; Can't preempt if preemption disabled
GET_ C U R R _ T H R _ I N F O _ F R O M _ S P r10
ld r8 , [ r10 , T H R E A D _ I N F O _ P R E E M P T _ C O U N T ]
brne r8 , 0 , r e s t o r e _ r e g s
; check if this task's NEED_RESCHED flag set
ld r9 , [ r10 , T H R E A D _ I N F O _ F L A G S ]
bbit0 r9 , T I F _ N E E D _ R E S C H E D , r e s t o r e _ r e g s
; Invoke PREEMPTION
bl p r e e m p t _ s c h e d u l e _ i r q
; preempt_schedule_irq() always returns with IRQ disabled
# endif
; fall through
;############# Return from Intr/Excp/Trap (ARC Specifics) ##############
;
; Restore the saved sys context (common exit-path for EXCPN/IRQ/Trap)
; IRQ shd definitely not happen between now and rtie
2013-07-09 17:06:40 +05:30
; All 2 entry points to here already disable interrupts
2013-01-18 15:12:18 +05:30
restore_ r e g s :
2013-09-06 14:18:17 +05:30
TRACE_ A S M _ I R Q _ E N A B L E
2013-07-09 17:06:40 +05:30
lr r10 , [ s t a t u s32 ]
2013-01-18 15:12:18 +05:30
; Restore REG File. In case multiple Events outstanding,
; use the same priorty as rtie: EXCPN, L2 IRQ, L1 IRQ, None
; Note that we use realtime STATUS32 (not pt_regs->status32) to
; decide that.
; if Returning from Exception
bbit0 r10 , S T A T U S _ A E _ B I T , n o t _ e x c e p t i o n
RESTORE_ A L L _ S Y S
rtie
; Not Exception so maybe Interrupts (Level 1 or 2)
not_exception :
2013-01-18 15:12:22 +05:30
# ifdef C O N F I G _ A R C _ C O M P A C T _ I R Q _ L E V E L S
2013-06-11 18:56:54 +05:30
; Level 2 interrupt return Path - from hardware standpoint
2013-01-18 15:12:22 +05:30
bbit0 r10 , S T A T U S _ A 2 _ B I T , n o t _ l e v e l 2 _ i n t e r r u p t
2013-06-11 18:56:54 +05:30
;------------------------------------------------------------------
; However the context returning might not have taken L2 intr itself
; e.g. Task'A' user-code -> L2 intr -> schedule -> 'B' user-code ret
; Special considerations needed for the context which took L2 intr
ld r9 , [ s p , P T _ e v e n t ] ; Ensure this is L2 intr context
brne r9 , e v e n t _ I R Q 2 , 1 4 9 f
2013-01-18 15:12:22 +05:30
;------------------------------------------------------------------
; if L2 IRQ interrupted a L1 ISR, we'd disbaled preemption earlier
; so that sched doesnt move to new task, causing L1 to be delayed
; undeterministically. Now that we've achieved that, lets reset
; things to what they were, before returning from L2 context
;----------------------------------------------------------------
ld r9 , [ s p , P T _ s t a t u s32 ] ; get statu32_l2 (saved in pt_regs)
bbit0 r9 , S T A T U S _ A 1 _ B I T , 1 4 9 f ; L1 not active when L2 IRQ, so normal
; decrement thread_info->preempt_count (re-enable preemption)
GET_ C U R R _ T H R _ I N F O _ F R O M _ S P r10
ld r9 , [ r10 , T H R E A D _ I N F O _ P R E E M P T _ C O U N T ]
; paranoid check, given A1 was active when A2 happened, preempt count
2013-06-11 18:56:54 +05:30
; must not be 0 because we would have incremented it.
2013-01-18 15:12:22 +05:30
; If this does happen we simply HALT as it means a BUG !!!
cmp r9 , 0
bnz 2 f
flag 1
2 :
sub r9 , r9 , 1
st r9 , [ r10 , T H R E A D _ I N F O _ P R E E M P T _ C O U N T ]
149 :
;return from level 2
RESTORE_ A L L _ I N T 2
debug_marker_l2 :
rtie
not_level2_interrupt :
# endif
2013-01-18 15:12:18 +05:30
bbit0 r10 , S T A T U S _ A 1 _ B I T , n o t _ l e v e l 1 _ i n t e r r u p t
;return from level 1
RESTORE_ A L L _ I N T 1
debug_marker_l1 :
rtie
not_level1_interrupt :
;this case is for syscalls or Exceptions (with fake rtie)
RESTORE_ A L L _ S Y S
debug_marker_syscall :
rtie
2014-02-07 13:47:43 +05:30
END( r e t _ f r o m _ e x c e p t i o n )
2013-01-18 15:12:18 +05:30
2014-02-07 13:47:43 +05:30
ENTRY( r e t _ f r o m _ f o r k )
2013-01-18 15:12:18 +05:30
; when the forked child comes here from the __switch_to function
; r0 has the last task pointer.
; put last task in scheduler queue
2013-01-18 15:12:18 +05:30
bl @schedule_tail
; If kernel thread, jump to it's entry-point
ld r9 , [ s p , P T _ s t a t u s32 ]
brne r9 , 0 , 1 f
jl. d [ r14 ]
mov r0 , r13 ; arg to payload
1 :
; special case of kernel_thread entry point returning back due to
; kernel_execve() - pretend return from syscall to ret to userland
b r e t _ f r o m _ e x c e p t i o n
2014-02-07 13:47:43 +05:30
END( r e t _ f r o m _ f o r k )
2013-01-18 15:12:18 +05:30
;################### Special Sys Call Wrappers ##########################
2014-02-07 13:47:43 +05:30
ENTRY( s y s _ c l o n e _ w r a p p e r )
2013-01-18 15:12:18 +05:30
SAVE_ C A L L E E _ S A V E D _ U S E R
bl @sys_clone
DISCARD_ C A L L E E _ S A V E D _ U S E R
2013-01-18 15:12:22 +05:30
GET_ C U R R _ T H R _ I N F O _ F L A G S r10
btst r10 , T I F _ S Y S C A L L _ T R A C E
bnz t r a c e s y s _ e x i t
2013-01-18 15:12:18 +05:30
b r e t _ f r o m _ s y s t e m _ c a l l
2014-02-07 13:47:43 +05:30
END( s y s _ c l o n e _ w r a p p e r )
2013-01-22 17:03:19 +05:30
# ifdef C O N F I G _ A R C _ D W 2 _ U N W I N D
; Workaround for bug 94179 (STAR ):
; Despite -fasynchronous-unwind-tables, linker is not making dwarf2 unwinder
; section (.debug_frame) as loadable. So we force it here.
; This also fixes STAR 9000487933 where the prev-workaround (objcopy --setflag)
; would not work after a clean build due to kernel build system dependencies.
.section .debug_frame , " wa" ,@progbits
# endif