2009-06-12 22:01:00 +08:00
/ *
* arch/ s c o r e / k e r n e l / e n t r y . S
*
* Score P r o c e s s o r v e r s i o n .
*
* Copyright ( C ) 2 0 0 9 S u n p l u s C o r e T e c h n o l o g y C o . , L t d .
* Chen L i q i n < l i q i n . c h e n @sunplusct.com>
* Lennox W u < l e n n o x . w u @sunplusct.com>
*
* 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 a s p u b l i s h e d b y
* the F r e e S o f t w a r e F o u n d a t i o n ; either version 2 of the License, or
* ( at y o u r o p t i o n ) a n y l a t e r v e r s i o n .
*
* This p r o g r a m i s d i s t r i b u t e d i n t h e h o p e t h a t i t w i l l b e u s e f u l ,
* but W I T H O U T A N Y W A R R A N T Y ; without even the implied warranty of
* MERCHANTABILITY o r F I T N E S S F O R A P A R T I C U L A R P U R P O S E . S e e t h e
* GNU G e n e r a l P u b l i c L i c e n s e f o r m o r e d e t a i l s .
*
* You s h o u l d h a v e r e c e i v e d a c o p y 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
* along w i t h t h i s p r o g r a m ; if not, see the file COPYING, or write
* to 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 , I n c . ,
* 5 1 Franklin S t , F i f t h F l o o r , B o s t o n , M A 0 2 1 1 0 - 1 3 0 1 U S A
* /
2009-06-19 13:53:49 +08:00
# include < l i n u x / e r r . h >
2009-06-12 22:01:00 +08:00
# include < l i n u x / i n i t . h >
# include < l i n u x / l i n k a g e . h >
# include < a s m / a s m m a c r o . h >
# include < a s m / t h r e a d _ i n f o . h >
# include < a s m / u n i s t d . h >
/ *
* disable i n t e r r u p t s .
* /
.macro disable_irq
mfcr r8 , c r0
srli r8 , r8 , 1
slli r8 , r8 , 1
mtcr r8 , c r0
nop
nop
nop
nop
nop
.endm
/ *
* enable i n t e r r u p t s .
* /
.macro enable_irq
mfcr r8 , c r0
ori r8 , 1
mtcr r8 , c r0
nop
nop
nop
nop
nop
.endm
_ _ INIT
ENTRY( d e b u g _ e x c e p t i o n _ v e c t o r )
nop!
nop!
nop!
nop!
nop!
nop!
nop!
nop!
ENTRY( g e n e r a l _ e x c e p t i o n _ v e c t o r ) # s h o u l d m o v e t o a d d r 0x200
j g e n e r a l _ e x c e p t i o n
nop!
nop!
nop!
nop!
nop!
nop!
ENTRY( i n t e r r u p t _ e x c e p t i o n _ v e c t o r ) # s h o u l d m o v e t o a d d r 0x210
j i n t e r r u p t _ e x c e p t i o n
nop!
nop!
nop!
nop!
nop!
nop!
.section " .text " , " ax"
.align 2 ;
general_exception :
mfcr r31 , c r2
nop
la r30 , e x c e p t i o n _ h a n d l e r s
andi r31 , 0 x1 f # g e t e c r . e x c _ c o d e
slli r31 , r31 , 2
add r30 , r30 , r31
lw r30 , [ r30 ]
br r30
interrupt_exception :
SAVE_ A L L
mfcr r4 , c r2
nop
lw r16 , [ r28 , T I _ R E G S ]
sw r0 , [ r28 , T I _ R E G S ]
la r3 , r e t _ f r o m _ i r q
srli r4 , r4 , 1 8 # g e t e c r . i p [ 7 : 2 ] , i n t e r r u p t N o .
mv r5 , r0
j d o _ I R Q
ENTRY( h a n d l e _ n m i ) # N M I # 1
SAVE_ A L L
mv r4 , r0
la r8 , n m i _ e x c e p t i o n _ h a n d l e r
brl r8
j r e s t o r e _ a l l
ENTRY( h a n d l e _ a d e l i n s n ) # A d E L - i n s t r u c t i o n # 2
SAVE_ A L L
mfcr r8 , c r6
nop
nop
sw r8 , [ r0 , P T _ E M A ]
mv r4 , r0
la r8 , d o _ a d e l i n s n
brl r8
mv r4 , r0
j r e t _ f r o m _ e x c e p t i o n
nop
ENTRY( h a n d l e _ i b e ) # B u s E L - i n s t r u c t i o n # 5
SAVE_ A L L
mv r4 , r0
la r8 , d o _ b e
brl r8
mv r4 , r0
j r e t _ f r o m _ e x c e p t i o n
nop
ENTRY( h a n d l e _ p e l ) # P - E L # 6
SAVE_ A L L
mv r4 , r0
la r8 , d o _ p e l
brl r8
mv r4 , r0
j r e t _ f r o m _ e x c e p t i o n
nop
ENTRY( h a n d l e _ c c u ) # C C U # 8
SAVE_ A L L
mv r4 , r0
la r8 , d o _ c c u
brl r8
mv r4 , r0
j r e t _ f r o m _ e x c e p t i o n
nop
ENTRY( h a n d l e _ r i ) # R I # 9
SAVE_ A L L
mv r4 , r0
la r8 , d o _ r i
brl r8
mv r4 , r0
j r e t _ f r o m _ e x c e p t i o n
nop
ENTRY( h a n d l e _ t r ) # T r a p # 10
SAVE_ A L L
mv r4 , r0
la r8 , d o _ t r
brl r8
mv r4 , r0
j r e t _ f r o m _ e x c e p t i o n
nop
ENTRY( h a n d l e _ a d e d a t a ) # A d E S - i n s t r u c t i o n # 12
SAVE_ A L L
mfcr r8 , c r6
nop
nop
sw r8 , [ r0 , P T _ E M A ]
mv r4 , r0
la r8 , d o _ a d e d a t a
brl r8
mv r4 , r0
j r e t _ f r o m _ e x c e p t i o n
nop
ENTRY( h a n d l e _ c e e ) # C e E # 16
SAVE_ A L L
mv r4 , r0
la r8 , d o _ c e e
brl r8
mv r4 , r0
j r e t _ f r o m _ e x c e p t i o n
nop
ENTRY( h a n d l e _ c p e ) # C p E # 17
SAVE_ A L L
mv r4 , r0
la r8 , d o _ c p e
brl r8
mv r4 , r0
j r e t _ f r o m _ e x c e p t i o n
nop
ENTRY( h a n d l e _ d b e ) # B u s E L - d a t a # 18
SAVE_ A L L
mv r4 , r0
la r8 , d o _ b e
brl r8
mv r4 , r0
j r e t _ f r o m _ e x c e p t i o n
nop
ENTRY( h a n d l e _ r e s e r v e d ) # o t h e r s
SAVE_ A L L
mv r4 , r0
la r8 , d o _ r e s e r v e d
brl r8
mv r4 , r0
j r e t _ f r o m _ e x c e p t i o n
nop
# ifndef C O N F I G _ P R E E M P T
# define r e s u m e _ k e r n e l r e s t o r e _ a l l
# else
# define _ _ r e t _ f r o m _ i r q r e t _ f r o m _ e x c e p t i o n
# endif
.align 2
# ifndef C O N F I G _ P R E E M P T
ENTRY( r e t _ f r o m _ e x c e p t i o n )
disable_ i r q # p r e e m p t s t o p
nop
j _ _ r e t _ f r o m _ i r q
nop
# endif
ENTRY( r e t _ f r o m _ i r q )
sw r16 , [ r28 , T I _ R E G S ]
ENTRY( _ _ r e t _ f r o m _ i r q )
lw r8 , [ r0 , P T _ P S R ] # r e t u r n i n g t o k e r n e l m o d e ?
andri. c r8 , r8 , K U _ U S E R
beq r e s u m e _ k e r n e l
resume_userspace :
disable_ i r q
lw r6 , [ r28 , T I _ F L A G S ] # c u r r e n t - > w o r k
li r8 , _ T I F _ W O R K _ M A S K
and. c r8 , r8 , r6 # i g n o r i n g s y s c a l l _ t r a c e
bne w o r k _ p e n d i n g
nop
j r e s t o r e _ a l l
nop
# ifdef C O N F I G _ P R E E M P T
resume_kernel :
disable_ i r q
lw r8 , [ r28 , T I _ P R E _ C O U N T ]
cmpz. c r8
bne r8 , r e s t o r e _ a l l
need_resched :
lw r8 , [ r28 , T I _ F L A G S ]
andri. c r9 , r8 , _ T I F _ N E E D _ R E S C H E D
beq r e s t o r e _ a l l
lw r8 , [ r28 , P T _ P S R ] # I n t e r r u p t s o f f ?
andri. c r8 , r8 , 1
beq r e s t o r e _ a l l
bl p r e e m p t _ s c h e d u l e _ i r q
nop
j n e e d _ r e s c h e d
nop
# endif
ENTRY( r e t _ f r o m _ f o r k )
bl s c h e d u l e _ t a i l # r 4 =struct t a s k _ s t r u c t * p r e v
ENTRY( s y s c a l l _ e x i t )
nop
disable_ i r q
lw r6 , [ r28 , T I _ F L A G S ] # c u r r e n t - > w o r k
li r8 , _ T I F _ W O R K _ M A S K
and. c r8 , r6 , r8
bne s y s c a l l _ e x i t _ w o r k
ENTRY( r e s t o r e _ a l l ) # r e s t o r e f u l l f r a m e
RESTORE_ A L L _ A N D _ R E T
work_pending :
andri. c r8 , r6 , _ T I F _ N E E D _ R E S C H E D # r 6 i s p r e l o a d e d w i t h T I _ F L A G S
beq w o r k _ n o t i f y s i g
work_resched :
bl s c h e d u l e
nop
disable_ i r q
lw r6 , [ r28 , T I _ F L A G S ]
li r8 , _ T I F _ W O R K _ M A S K
and. c r8 , r6 , r8 # i s t h e r e a n y w o r k t o b e d o n e
# other t h a n s y s c a l l t r a c i n g ?
beq r e s t o r e _ a l l
andri. c r8 , r6 , _ T I F _ N E E D _ R E S C H E D
bne w o r k _ r e s c h e d
work_notifysig :
mv r4 , r0
li r5 , 0
bl d o _ n o t i f y _ r e s u m e # r 6 a l r e a d y l o a d e d
nop
j r e s u m e _ u s e r s p a c e
nop
ENTRY( s y s c a l l _ e x i t _ w o r k )
li r8 , _ T I F _ S Y S C A L L _ T R A C E
and. c r8 , r8 , r6 # r 6 i s p r e l o a d e d w i t h T I _ F L A G S
beq w o r k _ p e n d i n g # t r a c e b i t s e t ?
nop
enable_ i r q
mv r4 , r0
li r5 , 1
bl d o _ s y s c a l l _ t r a c e
nop
b r e s u m e _ u s e r s p a c e
nop
.macro save_context reg
sw r12 , [ \ r e g , T H R E A D _ R E G 1 2 ] ;
sw r13 , [ \ r e g , T H R E A D _ R E G 1 3 ] ;
sw r14 , [ \ r e g , T H R E A D _ R E G 1 4 ] ;
sw r15 , [ \ r e g , T H R E A D _ R E G 1 5 ] ;
sw r16 , [ \ r e g , T H R E A D _ R E G 1 6 ] ;
sw r17 , [ \ r e g , T H R E A D _ R E G 1 7 ] ;
sw r18 , [ \ r e g , T H R E A D _ R E G 1 8 ] ;
sw r19 , [ \ r e g , T H R E A D _ R E G 1 9 ] ;
sw r20 , [ \ r e g , T H R E A D _ R E G 2 0 ] ;
sw r21 , [ \ r e g , T H R E A D _ R E G 2 1 ] ;
sw r29 , [ \ r e g , T H R E A D _ R E G 2 9 ] ;
sw r2 , [ \ r e g , T H R E A D _ R E G 2 ] ;
sw r0 , [ \ r e g , T H R E A D _ R E G 0 ]
.endm
.macro restore_context reg
lw r12 , [ \ r e g , T H R E A D _ R E G 1 2 ] ;
lw r13 , [ \ r e g , T H R E A D _ R E G 1 3 ] ;
lw r14 , [ \ r e g , T H R E A D _ R E G 1 4 ] ;
lw r15 , [ \ r e g , T H R E A D _ R E G 1 5 ] ;
lw r16 , [ \ r e g , T H R E A D _ R E G 1 6 ] ;
lw r17 , [ \ r e g , T H R E A D _ R E G 1 7 ] ;
lw r18 , [ \ r e g , T H R E A D _ R E G 1 8 ] ;
lw r19 , [ \ r e g , T H R E A D _ R E G 1 9 ] ;
lw r20 , [ \ r e g , T H R E A D _ R E G 2 0 ] ;
lw r21 , [ \ r e g , T H R E A D _ R E G 2 1 ] ;
lw r29 , [ \ r e g , T H R E A D _ R E G 2 9 ] ;
lw r0 , [ \ r e g , T H R E A D _ R E G 0 ] ;
lw r2 , [ \ r e g , T H R E A D _ R E G 2 ] ;
lw r3 , [ \ r e g , T H R E A D _ R E G 3 ]
.endm
/ *
* task_ s t r u c t * r e s u m e ( t a s k _ s t r u c t * p r e v , t a s k _ s t r u c t * n e x t ,
* struct t h r e a d _ i n f o * n e x t _ t i )
* /
ENTRY( r e s u m e )
mfcr r9 , c r0
nop
nop
sw r9 , [ r4 , T H R E A D _ P S R ]
save_ c o n t e x t r4
sw r3 , [ r4 , T H R E A D _ R E G 3 ]
mv r28 , r6
restore_ c o n t e x t r5
mv r8 , r6
addi r8 , K E R N E L _ S T A C K _ S I Z E
subi r8 , 3 2
la r9 , k e r n e l s p ;
sw r8 , [ r9 ] ;
mfcr r9 , c r0
ldis r7 , 0 x00 f f
nop
and r9 , r9 , r7
lw r6 , [ r5 , T H R E A D _ P S R ]
not r7 , r7
and r6 , r6 , r7
or r6 , r6 , r9
mtcr r6 , c r0
nop; nop; nop; nop; nop
br r3
ENTRY( h a n d l e _ s y s )
SAVE_ A L L
2009-06-22 17:10:57 +08:00
sw r8 , [ r0 , 1 6 ] # a r g u m e n t 5 f r o m u s e r r8
sw r9 , [ r0 , 2 0 ] # a r g u m e n t 6 f r o m u s e r r9
2009-06-12 22:01:00 +08:00
enable_ i r q
sw r4 , [ r0 , P T _ O R I G _ R 4 ] #f o r r e s t a r t s y s c a l l
sw r7 , [ r0 , P T _ O R I G _ R 7 ] #f o r r e s t a r t s y s c a l l
sw r27 , [ r0 , P T _ I S _ S Y S C A L L ] # i t f r o m s y s c a l l
lw r9 , [ r0 , P T _ E P C ] # s k i p s y s c a l l o n r e t u r n
addi r9 , 4
sw r9 , [ r0 , P T _ E P C ]
cmpi. c r27 , _ _ N R _ s y s c a l l s # c h e c k s y s c a l l n u m b e r
2012-01-20 14:34:27 -08:00
bgeu i l l e g a l _ s y s c a l l
2009-06-12 22:01:00 +08:00
2009-06-19 11:31:54 +02:00
slli r8 , r27 , 2 # g e t s y s c a l l r o u t i n e
2009-06-12 22:01:00 +08:00
la r11 , s y s _ c a l l _ t a b l e
add r11 , r11 , r8
lw r10 , [ r11 ] # g e t s y s c a l l e n t r y
cmpz. c r10
beq i l l e g a l _ s y s c a l l
lw r8 , [ r28 , T I _ F L A G S ]
li r9 , _ T I F _ S Y S C A L L _ T R A C E
and. c r8 , r8 , r9
bne s y s c a l l _ t r a c e _ e n t r y
brl r10 # D o T h e R e a l s y s t e m c a l l
cmpi. c r4 , 0
blt 1 f
ldi r8 , 0
sw r8 , [ r0 , P T _ R 7 ]
b 2 f
1 :
2009-06-19 13:53:49 +08:00
cmpi. c r4 , - M A X _ E R R N O - 1
2009-06-12 22:01:00 +08:00
ble 2 f
ldi r8 , 0 x1 ;
sw r8 , [ r0 , P T _ R 7 ]
neg r4 , r4
2 :
sw r4 , [ r0 , P T _ R 4 ] # s a v e r e s u l t
syscall_return :
disable_ i r q
lw r6 , [ r28 , T I _ F L A G S ] # c u r r e n t - > w o r k
li r8 , _ T I F _ W O R K _ M A S K
and. c r8 , r6 , r8
bne s y s c a l l _ r e t u r n _ w o r k
j r e s t o r e _ a l l
syscall_return_work :
j s y s c a l l _ e x i t _ w o r k
syscall_trace_entry :
mv r16 , r10
mv r4 , r0
li r5 , 0
bl d o _ s y s c a l l _ t r a c e
mv r8 , r16
lw r4 , [ r0 , P T _ R 4 ] # R e s t o r e a r g u m e n t r e g i s t e r s
lw r5 , [ r0 , P T _ R 5 ]
lw r6 , [ r0 , P T _ R 6 ]
lw r7 , [ r0 , P T _ R 7 ]
brl r8
2009-06-19 13:53:49 +08:00
li r8 , - M A X _ E R R N O - 1
2009-06-12 22:01:00 +08:00
sw r8 , [ r0 , P T _ R 7 ] # s e t e r r o r f l a g
neg r4 , r4 # e r r o r
sw r4 , [ r0 , P T _ R 0 ] # s e t f l a g f o r s y s c a l l
# restarting
1 : sw r4 , [ r0 , P T _ R 2 ] # r e s u l t
j s y s c a l l _ e x i t
illegal_syscall :
ldi r4 , - E N O S Y S # e r r o r
sw r4 , [ r0 , P T _ O R I G _ R 4 ]
sw r4 , [ r0 , P T _ R 4 ]
ldi r9 , 1 # s e t e r r o r f l a g
sw r9 , [ r0 , P T _ R 7 ]
j s y s c a l l _ r e t u r n
ENTRY( s y s _ e x e c v e )
mv r4 , r0
la r8 , s c o r e _ e x e c v e
br r8
ENTRY( s y s _ c l o n e )
mv r4 , r0
la r8 , s c o r e _ c l o n e
br r8
ENTRY( s y s _ r t _ s i g r e t u r n )
mv r4 , r0
la r8 , s c o r e _ r t _ s i g r e t u r n
br r8
ENTRY( s y s _ s i g a l t s t a c k )
mv r4 , r0
la r8 , s c o r e _ s i g a l t s t a c k
br r8
2009-08-30 12:33:30 +08:00
# ifdef _ _ A R C H _ W A N T _ S Y S C A L L _ D E P R E C A T E D
ENTRY( s y s _ f o r k )
mv r4 , r0
la r8 , s c o r e _ f o r k
br r8
ENTRY( s y s _ v f o r k )
mv r4 , r0
la r8 , s c o r e _ v f o r k
br r8
# endif / * _ _ A R C H _ W A N T _ S Y S C A L L _ D E P R E C A T E D * /