2010-05-28 23:09:12 -04:00
/ *
* Copyright 2 0 1 0 T i l e r a C o r p o r a t i o n . A l l R i g h t s R e s e r v e d .
*
* 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 i t 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
* as p u b l i s h e d 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 , v e r s i o n 2 .
*
* 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 , b u t
* WITHOUT 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 , G O O D T I T L E o r
* NON I N F R I N G E M E N T . S e e 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 f o r
* more d e t a i l s .
*
* Linux i n t e r r u p t v e c t o r s .
* /
# include < l i n u x / l i n k a g e . h >
# include < l i n u x / e r r n o . h >
# include < l i n u x / i n i t . h >
arch/tile: Add driver to enable access to the user dynamic network.
This network (the "UDN") connects all the cpus on the chip in a
wormhole-routed dynamic network. Subrectangles of the chip can
be allocated by a "create" ioctl on /dev/hardwall, and then to access the
UDN in that rectangle, tasks must perform an "activate" ioctl on that
same file object after affinitizing themselves to a single cpu in
the region. Sending a wormhole-routed message that tries to leave
that subrectangle causes all activated tasks to receive a SIGILL
(just as they would if they tried to access the UDN without first
activating themselves to a hardwall rectangle).
The original submission of this code to LKML had the driver
instantiated under /proc/tile/hardwall. Now we just use a character
device for this, conventionally /dev/hardwall. Some futures planning
for the TILE-Gx chip suggests that we may want to have other types of
devices that share the general model of "bind a task to a cpu, then
'activate' a file descriptor on a pseudo-device that gives access to
some hardware resource". As such, we are using a device rather
than, for example, a syscall, to set up and activate this code.
As part of this change, the compat_ptr() declaration was fixed and used
to pass the compat_ioctl argument to the normal ioctl. So far we limit
compat code to 2GB, so the difference between zero-extend and sign-extend
(the latter being correct, eventually) had been overlooked.
Signed-off-by: Chris Metcalf <cmetcalf@tilera.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
2010-06-25 17:00:56 -04:00
# include < l i n u x / u n i s t d . h >
2010-05-28 23:09:12 -04:00
# include < a s m / p t r a c e . h >
# include < a s m / t h r e a d _ i n f o . h >
# include < a s m / i r q f l a g s . h >
# include < a s m / a t o m i c . h >
# include < a s m / a s m - o f f s e t s . h >
# include < h v / h y p e r v i s o r . h >
# include < a r c h / a b i . h >
# include < a r c h / i n t e r r u p t s . h >
# include < a r c h / s p r _ d e f . h >
# ifdef C O N F I G _ P R E E M P T
# error " N o s u p p o r t f o r k e r n e l p r e e m p t i o n c u r r e n t l y "
# endif
2010-10-14 16:23:03 -04:00
# if I N T _ I N T C T R L _ K < 3 2 | | I N T _ I N T C T R L _ K > = 4 8
# error I N T _ I N T C T R L _ K c o d e d t o s e t h i g h i n t e r r u p t m a s k
2010-05-28 23:09:12 -04:00
# endif
# define P T R E G S _ P T R ( r e g , p t r e g ) a d d l i r e g , s p , C _ A B I _ S A V E _ A R E A _ S I Z E + ( p t r e g )
# define P T R E G S _ O F F S E T _ S Y S C A L L P T R E G S _ O F F S E T _ R E G ( T R E G _ S Y S C A L L _ N R )
# if ! C H I P _ H A S _ W H 6 4 ( )
/* By making this an empty macro, we can use wh64 in the code. */
.macro wh64 reg
.endm
# endif
.macro push_reg reg, p t r =sp , d e l t a = - 4
{
sw \ p t r , \ r e g
addli \ p t r , \ p t r , \ d e l t a
}
.endm
.macro pop_reg reg, p t r =sp , d e l t a =4
{
lw \ r e g , \ p t r
addli \ p t r , \ p t r , \ d e l t a
}
.endm
.macro pop_reg_zero reg, z r e g , p t r =sp , d e l t a =4
{
move \ z r e g , z e r o
lw \ r e g , \ p t r
addi \ p t r , \ p t r , \ d e l t a
}
.endm
.macro push_extra_callee_saves reg
PTREGS_ P T R ( \ r e g , P T R E G S _ O F F S E T _ R E G ( 5 1 ) )
push_ r e g r51 , \ r e g
push_ r e g r50 , \ r e g
push_ r e g r49 , \ r e g
push_ r e g r48 , \ r e g
push_ r e g r47 , \ r e g
push_ r e g r46 , \ r e g
push_ r e g r45 , \ r e g
push_ r e g r44 , \ r e g
push_ r e g r43 , \ r e g
push_ r e g r42 , \ r e g
push_ r e g r41 , \ r e g
push_ r e g r40 , \ r e g
push_ r e g r39 , \ r e g
push_ r e g r38 , \ r e g
push_ r e g r37 , \ r e g
push_ r e g r36 , \ r e g
push_ r e g r35 , \ r e g
push_ r e g r34 , \ r e g , P T R E G S _ O F F S E T _ B A S E - P T R E G S _ O F F S E T _ R E G ( 3 4 )
.endm
.macro panic str
.pushsection .rodata , " a"
1 :
.asciz " \ str"
.popsection
{
moveli r0 , l o 1 6 ( 1 b )
}
{
auli r0 , r0 , h a16 ( 1 b )
jal p a n i c
}
.endm
# ifdef _ _ C O L L E C T _ L I N K E R _ F E E D B A C K _ _
.pushsection .text .intvec_feedback , " ax"
intvec_feedback :
.popsection
# endif
/ *
* Default i n t e r r u p t h a n d l e r .
*
* vecnum i s w h e r e w e ' l l p u t t h i s c o d e .
* c_ r o u t i n e i s t h e C r o u t i n e w e ' l l c a l l .
*
* The C r o u t i n e i s p a s s e d t w o a r g u m e n t s :
* - A p o i n t e r t o t h e p t _ r e g s s t a t e .
* - The i n t e r r u p t v e c t o r n u m b e r .
*
* The " p r o c e s s i n g " a r g u m e n t s p e c i f i e s t h e c o d e f o r p r o c e s s i n g
* the i n t e r r u p t . D e f a u l t s t o " h a n d l e _ i n t e r r u p t " .
* /
.macro int_hand vecnum, v e c n a m e , c _ r o u t i n e , p r o c e s s i n g =handle_interrupt
.org ( \ vecnum < < 8 )
intvec_ \ v e c n a m e :
.ifc \ vecnum, I N T _ S W I N T _ 1
blz T R E G _ S Y S C A L L _ N R _ N A M E , s y s _ c m p x c h g
.endif
/* Temporarily save a register so we have somewhere to work. */
2010-10-14 16:23:03 -04:00
mtspr S P R _ S Y S T E M _ S A V E _ K _ 1 , r0
mfspr r0 , S P R _ E X _ C O N T E X T _ K _ 1
2010-05-28 23:09:12 -04:00
/* The cmpxchg code clears sp to force us to reset it here on fault. */
{
bz s p , 2 f
andi r0 , r0 , S P R _ E X _ C O N T E X T _ 1 _ 1 _ _ P L _ M A S K / * m a s k o f f I C S * /
}
.ifc \ vecnum, I N T _ D O U B L E _ F A U L T
/ *
* For d o u b l e - f a u l t s f r o m u s e r - s p a c e , f a l l t h r o u g h t o t h e n o r m a l
* register s a v e a n d s t a c k s e t u p p a t h . O t h e r w i s e , i t ' s t h e
* hypervisor g i v i n g u s o n e l a s t c h a n c e t o d u m p d i a g n o s t i c s , a n d w e
* branch t o t h e k e r n e l _ d o u b l e _ f a u l t r o u t i n e t o d o s o .
* /
bz r0 , 1 f
j _ k e r n e l _ d o u b l e _ f a u l t
1 :
.else
/ *
* If w e ' r e c o m i n g f r o m u s e r - s p a c e , t h e n s e t s p t o t h e t o p o f
* the k e r n e l s t a c k . O t h e r w i s e , a s s u m e s p i s a l r e a d y v a l i d .
* /
{
bnz r0 , 0 f
move r0 , s p
}
.endif
.ifc \ c_ r o u t i n e , d o _ p a g e _ f a u l t
/ *
* The p a g e _ f a u l t h a n d l e r m a y b e d o w n c a l l e d d i r e c t l y b y t h e
* hypervisor e v e n w h e n L i n u x i s r u n n i n g a n d h a s I C S s e t .
*
2010-10-14 16:23:03 -04:00
* In t h i s c a s e t h e c o n t e n t s o f E X _ C O N T E X T _ K _ 1 r e f l e c t t h e
2010-05-28 23:09:12 -04:00
* previous f a u l t a n d c a n ' t b e r e l i e d o n t o c h o o s e w h e t h e r o r
* not t o r e i n i t i a l i z e t h e s t a c k p o i n t e r . S o w e a d d a t e s t
2010-10-14 16:23:03 -04:00
* to s e e w h e t h e r S Y S T E M _ S A V E _ K _ 2 h a s t h e h i g h b i t s e t ,
2010-05-28 23:09:12 -04:00
* and i f s o w e d o n ' t r e i n i t i a l i z e s p , s i n c e w e m u s t b e c o m i n g
* from L i n u x . ( I n f a c t t h e p r e c i s e c a s e i s ! ( v a l & ~ 1 ) ,
* but a n y L i n u x P C h a s t o h a v e t h e h i g h b i t s e t . )
*
2010-10-14 16:23:03 -04:00
* Note t h a t t h e h y p e r v i s o r * a l w a y s * s e t s S Y S T E M _ S A V E _ K _ 2 f o r
2010-05-28 23:09:12 -04:00
* any p a t h t h a t t u r n s i n t o a d o w n c a l l t o o n e o f o u r T L B h a n d l e r s .
* /
2010-10-14 16:23:03 -04:00
mfspr r0 , S P R _ S Y S T E M _ S A V E _ K _ 2
2010-05-28 23:09:12 -04:00
{
blz r0 , 0 f / * h i g h b i t i n S _ S _ 1 _ 2 i s f o r a P C t o u s e * /
move r0 , s p
}
.endif
2 :
/ *
2010-10-14 16:23:03 -04:00
* SYSTEM_ S A V E _ K _ 0 h o l d s t h e c p u n u m b e r i n t h e l o w b i t s , a n d
2010-05-28 23:09:12 -04:00
* the c u r r e n t s t a c k t o p i n t h e h i g h e r b i t s . S o w e r e c o v e r
* our s t a c k t o p b y j u s t m a s k i n g o f f t h e l o w b i t s , t h e n
* point s p a t t h e t o p a l i g n e d a d d r e s s o n t h e a c t u a l s t a c k p a g e .
* /
2010-10-14 16:23:03 -04:00
mfspr r0 , S P R _ S Y S T E M _ S A V E _ K _ 0
2010-05-28 23:09:12 -04:00
mm r0 , r0 , z e r o , L O G 2 _ T H R E A D _ S I Z E , 3 1
0 :
/ *
* Align t h e s t a c k m o d 6 4 s o w e c a n p r o p e r l y p r e d i c t w h a t
* cache l i n e s w e n e e d t o w r i t e - h i n t t o r e d u c e m e m o r y f e t c h
* latency a s w e e n t e r t h e k e r n e l . T h e l a y o u t o f m e m o r y i s
* as f o l l o w s , w i t h c a c h e l i n e 0 a t t h e l o w e s t V A , a n d c a c h e
* line 4 j u s t b e l o w t h e r0 v a l u e t h i s " a n d i " c o m p u t e s .
* Note t h a t w e n e v e r w r i t e t o c a c h e l i n e 4 , a n d w e s k i p
* cache l i n e 1 f o r s y s c a l l s .
*
* cache l i n e 4 : p t r e g s p a d d i n g ( t w o w o r d s )
* cache l i n e 3 : r46 . . . l r , p c , e x1 , f a u l t n u m , o r i g _ r0 , f l a g s , p a d
* cache l i n e 2 : r30 . . . r45
* cache l i n e 1 : r14 . . . r29
* cache l i n e 0 : 2 x f r a m e , r0 . . r13
* /
andi r0 , r0 , - 6 4
/ *
* Push t h e f i r s t f o u r r e g i s t e r s o n t h e s t a c k , s o t h a t w e c a n s e t
* them t o v e c t o r - u n i q u e v a l u e s b e f o r e w e j u m p t o t h e c o m m o n c o d e .
*
* Registers a r e p u s h e d o n t h e s t a c k a s a s t r u c t p t _ r e g s ,
* with t h e s p i n i t i a l l y j u s t a b o v e t h e s t r u c t , a n d w h e n w e ' r e
* done, s p p o i n t s t o t h e b a s e o f t h e s t r u c t , m i n u s
* C_ A B I _ S A V E _ A R E A _ S I Z E , s o w e c a n d i r e c t l y j a l t o C c o d e .
*
* This r o u t i n e s a v e s j u s t t h e f i r s t f o u r r e g i s t e r s , p l u s t h e
* stack c o n t e x t s o w e c a n d o p r o p e r b a c k t r a c i n g r i g h t a w a y ,
* and d e f e r s t o h a n d l e _ i n t e r r u p t t o s a v e t h e r e s t .
* The b a c k t r a c e r n e e d s p c , e x1 , l r , s p , r52 , a n d f a u l t n u m .
* /
addli r0 , r0 , P T R E G S _ O F F S E T _ L R - ( P T R E G S _ S I Z E + K S T K _ P T R E G S _ G A P )
wh6 4 r0 / * c a c h e l i n e 3 * /
{
sw r0 , l r
addli r0 , r0 , P T R E G S _ O F F S E T _ S P - P T R E G S _ O F F S E T _ L R
}
{
sw r0 , s p
addli s p , r0 , P T R E G S _ O F F S E T _ R E G ( 5 2 ) - P T R E G S _ O F F S E T _ S P
}
{
sw s p , r52
addli s p , s p , P T R E G S _ O F F S E T _ R E G ( 1 ) - P T R E G S _ O F F S E T _ R E G ( 5 2 )
}
wh6 4 s p / * c a c h e l i n e 0 * /
{
sw s p , r1
addli s p , s p , P T R E G S _ O F F S E T _ R E G ( 2 ) - P T R E G S _ O F F S E T _ R E G ( 1 )
}
{
sw s p , r2
addli s p , s p , P T R E G S _ O F F S E T _ R E G ( 3 ) - P T R E G S _ O F F S E T _ R E G ( 2 )
}
{
sw s p , r3
addli s p , s p , P T R E G S _ O F F S E T _ P C - P T R E G S _ O F F S E T _ R E G ( 3 )
}
2010-10-14 16:23:03 -04:00
mfspr r0 , S P R _ E X _ C O N T E X T _ K _ 0
2010-05-28 23:09:12 -04:00
.ifc \ processing,h a n d l e _ s y s c a l l
/ *
* Bump t h e s a v e d P C b y o n e b u n d l e s o t h a t w h e n w e r e t u r n , w e w o n ' t
* execute t h e s a m e s w i n t i n s t r u c t i o n a g a i n . W e n e e d t o d o t h i s w h i l e
* we' r e i n t h e c r i t i c a l s e c t i o n .
* /
addi r0 , r0 , 8
.endif
{
sw s p , r0
addli s p , s p , P T R E G S _ O F F S E T _ E X 1 - P T R E G S _ O F F S E T _ P C
}
2010-10-14 16:23:03 -04:00
mfspr r0 , S P R _ E X _ C O N T E X T _ K _ 1
2010-05-28 23:09:12 -04:00
{
sw s p , r0
addi s p , s p , P T R E G S _ O F F S E T _ F A U L T N U M - P T R E G S _ O F F S E T _ E X 1
/ *
* Use r0 f o r s y s c a l l s s o i t ' s a t e m p o r a r y ; use r1 for interrupts
* so t h a t i t g e t s p a s s e d t h r o u g h u n c h a n g e d t o t h e h a n d l e r r o u t i n e .
* Note t h a t t h e . i f c o n d i t i o n a l c o n f u s i n g l y s p a n s b u n d l e s .
* /
.ifc \ processing,h a n d l e _ s y s c a l l
movei r0 , \ v e c n u m
}
{
sw s p , r0
.else
movei r1 , \ v e c n u m
}
{
sw s p , r1
.endif
addli s p , s p , P T R E G S _ O F F S E T _ R E G ( 0 ) - P T R E G S _ O F F S E T _ F A U L T N U M
}
2010-10-14 16:23:03 -04:00
mfspr r0 , S P R _ S Y S T E M _ S A V E _ K _ 1 / * O r i g i n a l r0 * /
2010-05-28 23:09:12 -04:00
{
sw s p , r0
addi s p , s p , - P T R E G S _ O F F S E T _ R E G ( 0 ) - 4
}
{
sw s p , z e r o / * w r i t e z e r o i n t o " N e x t S P " f r a m e p o i n t e r * /
addi s p , s p , - 4 / * l e a v e S P p o i n t i n g a t b o t t o m o f f r a m e * /
}
.ifc \ processing,h a n d l e _ s y s c a l l
j h a n d l e _ s y s c a l l
.else
/ *
* Capture p e r - i n t e r r u p t S P R c o n t e x t t o r e g i s t e r s .
* We o v e r l o a d t h e m e a n i n g o f r3 o n t h i s p a t h s u c h t h a t i f i t s b i t 3 1
* is s e t , w e h a v e t o m a s k a l l i n t e r r u p t s i n c l u d i n g N M I s b e f o r e
* clearing t h e i n t e r r u p t c r i t i c a l s e c t i o n b i t .
* See d i s c u s s i o n b e l o w a t " f i n i s h _ i n t e r r u p t _ s a v e " .
* /
.ifc \ c_ r o u t i n e , d o _ p a g e _ f a u l t
2010-10-14 16:23:03 -04:00
mfspr r2 , S P R _ S Y S T E M _ S A V E _ K _ 3 / * a d d r e s s o f p a g e f a u l t * /
mfspr r3 , S P R _ S Y S T E M _ S A V E _ K _ 2 / * i n f o a b o u t p a g e f a u l t * /
2010-05-28 23:09:12 -04:00
.else
.ifc \ vecnum, I N T _ D O U B L E _ F A U L T
{
2010-10-14 16:23:03 -04:00
mfspr r2 , S P R _ S Y S T E M _ S A V E _ K _ 2 / * d o u b l e f a u l t i n f o f r o m H V * /
2010-05-28 23:09:12 -04:00
movei r3 , 0
}
.else
.ifc \ c_ r o u t i n e , d o _ t r a p
{
mfspr r2 , G P V _ R E A S O N
movei r3 , 0
}
.else
.ifc \ c_ r o u t i n e , o p _ h a n d l e _ p e r f _ i n t e r r u p t
{
mfspr r2 , P E R F _ C O U N T _ S T S
movei r3 , - 1 / * n o t u s e d , b u t s e t f o r c o n s i s t e n c y * /
}
.else
# if C H I P _ H A S _ A U X _ P E R F _ C O U N T E R S ( )
.ifc \ c_ r o u t i n e , o p _ h a n d l e _ a u x _ p e r f _ i n t e r r u p t
{
mfspr r2 , A U X _ P E R F _ C O U N T _ S T S
movei r3 , - 1 / * n o t u s e d , b u t s e t f o r c o n s i s t e n c y * /
}
.else
# endif
movei r3 , 0
# if C H I P _ H A S _ A U X _ P E R F _ C O U N T E R S ( )
.endif
# endif
.endif
.endif
.endif
.endif
/* Put function pointer in r0 */
moveli r0 , l o 1 6 ( \ c _ r o u t i n e )
{
auli r0 , r0 , h a16 ( \ c _ r o u t i n e )
j \ p r o c e s s i n g
}
.endif
ENDPROC( i n t v e c _ \ v e c n a m e )
# ifdef _ _ C O L L E C T _ L I N K E R _ F E E D B A C K _ _
.pushsection .text .intvec_feedback , " ax"
.org ( \ vecnum < < 5 )
FEEDBACK_ E N T E R _ E X P L I C I T ( i n t v e c _ \ v e c n a m e , . i n t r p t 1 , 1 < < 8 )
jrp l r
.popsection
# endif
.endm
/ *
* Save t h e r e s t o f t h e r e g i s t e r s t h a t w e d i d n ' t s a v e i n t h e a c t u a l
* vector i t s e l f . W e c a n ' t u s e r0 - r10 i n c l u s i v e h e r e .
* /
.macro finish_ i n t e r r u p t _ s a v e , f u n c t i o n
/* If it's a syscall, save a proper orig_r0, otherwise just zero. */
PTREGS_ P T R ( r52 , P T R E G S _ O F F S E T _ O R I G _ R 0 )
{
.ifc \ function,h a n d l e _ s y s c a l l
sw r52 , r0
.else
sw r52 , z e r o
.endif
PTREGS_ P T R ( r52 , P T R E G S _ O F F S E T _ T P )
}
/ *
* For o r d i n a r y s y s c a l l s , w e s a v e n e i t h e r c a l l e r - n o r c a l l e e -
* save r e g i s t e r s , s i n c e t h e s y s c a l l i n v o k e r d o e s n ' t e x p e c t t h e
* caller- s a v e s t o b e s a v e d , a n d t h e c a l l e d k e r n e l f u n c t i o n s w i l l
* take c a r e o f s a v i n g t h e c a l l e e - s a v e s f o r u s .
*
* For i n t e r r u p t s w e s a v e j u s t t h e c a l l e r - s a v e r e g i s t e r s . S a v i n g
* them i s r e q u i r e d ( s i n c e t h e " c a l l e r " c a n ' t s a v e t h e m ) . A g a i n ,
* the c a l l e d k e r n e l f u n c t i o n s w i l l r e s t o r e t h e c a l l e e - s a v e
* registers f o r u s a p p r o p r i a t e l y .
*
* On r e t u r n , w e n o r m a l l y r e s t o r e n o t h i n g s p e c i a l f o r s y s c a l l s ,
* and j u s t t h e c a l l e r - s a v e r e g i s t e r s f o r i n t e r r u p t s .
*
* However, t h e r e a r e s o m e i m p o r t a n t c a v e a t s t o a l l t h i s :
*
* - We a l w a y s s a v e a f e w c a l l e e - s a v e r e g i s t e r s t o g i v e u s
* some s c r a t c h p a d r e g i s t e r s t o c a r r y a c r o s s f u n c t i o n c a l l s .
*
* - fork/ v f o r k / e t c r e q u i r e u s t o s a v e a l l t h e c a l l e e - s a v e
* registers, w h i c h w e d o i n P T R E G S _ S Y S C A L L _ A L L _ R E G S , b e l o w .
*
* - We a l w a y s s a v e r0 . . r5 a n d r10 f o r s y s c a l l s , s i n c e w e n e e d
* to r e l o a d t h e m a b i t l a t e r f o r t h e a c t u a l k e r n e l c a l l , a n d
* since w e m i g h t n e e d t h e m f o r - E R E S T A R T N O I N T R , e t c .
*
* - Before i n v o k i n g a s i g n a l h a n d l e r , w e s a v e t h e u n s a v e d
* callee- s a v e r e g i s t e r s s o t h e y a r e v i s i b l e t o t h e
* signal h a n d l e r o r a n y p t r a c e r .
*
* - If t h e u n s a v e d c a l l e e - s a v e r e g i s t e r s a r e m o d i f i e d , w e s e t
* a b i t i n p t _ r e g s s o w e k n o w t o r e l o a d t h e m f r o m p t _ r e g s
* and n o t j u s t r e l y o n t h e k e r n e l f u n c t i o n u n w i n d i n g .
* ( Done f o r p t r a c e r e g i s t e r w r i t e s a n d S A _ S I G I N F O h a n d l e r . )
* /
{
sw r52 , t p
PTREGS_ P T R ( r52 , P T R E G S _ O F F S E T _ R E G ( 3 3 ) )
}
wh6 4 r52 / * c a c h e l i n e 2 * /
push_ r e g r33 , r52
push_ r e g r32 , r52
push_ r e g r31 , r52
.ifc \ function,h a n d l e _ s y s c a l l
push_ r e g r30 , r52 , P T R E G S _ O F F S E T _ S Y S C A L L - P T R E G S _ O F F S E T _ R E G ( 3 0 )
push_ r e g T R E G _ S Y S C A L L _ N R _ N A M E , r52 , \
PTREGS_ O F F S E T _ R E G ( 5 ) - P T R E G S _ O F F S E T _ S Y S C A L L
.else
push_ r e g r30 , r52 , P T R E G S _ O F F S E T _ R E G ( 2 9 ) - P T R E G S _ O F F S E T _ R E G ( 3 0 )
wh6 4 r52 / * c a c h e l i n e 1 * /
push_ r e g r29 , r52
push_ r e g r28 , r52
push_ r e g r27 , r52
push_ r e g r26 , r52
push_ r e g r25 , r52
push_ r e g r24 , r52
push_ r e g r23 , r52
push_ r e g r22 , r52
push_ r e g r21 , r52
push_ r e g r20 , r52
push_ r e g r19 , r52
push_ r e g r18 , r52
push_ r e g r17 , r52
push_ r e g r16 , r52
push_ r e g r15 , r52
push_ r e g r14 , r52
push_ r e g r13 , r52
push_ r e g r12 , r52
push_ r e g r11 , r52
push_ r e g r10 , r52
push_ r e g r9 , r52
push_ r e g r8 , r52
push_ r e g r7 , r52
push_ r e g r6 , r52
.endif
push_ r e g r5 , r52
sw r52 , r4
/* Load tp with our per-cpu offset. */
# ifdef C O N F I G _ S M P
{
2010-10-14 16:23:03 -04:00
mfspr r20 , S P R _ S Y S T E M _ S A V E _ K _ 0
2010-05-28 23:09:12 -04:00
moveli r21 , l o 1 6 ( _ _ p e r _ c p u _ o f f s e t )
}
{
auli r21 , r21 , h a16 ( _ _ p e r _ c p u _ o f f s e t )
mm r20 , r20 , z e r o , 0 , L O G 2 _ T H R E A D _ S I Z E - 1
}
s2 a r20 , r20 , r21
lw t p , r20
# else
move t p , z e r o
# endif
/ *
* If w e w i l l b e r e t u r n i n g t o t h e k e r n e l , w e w i l l n e e d t o
* reset t h e i n t e r r u p t m a s k s t o t h e s t a t e t h e y h a d b e f o r e .
* Set D I S A B L E _ I R Q i n f l a g s i f f w e c a m e f r o m P L 1 w i t h i r q s d i s a b l e d .
* We l o a d f l a g s i n r32 h e r e s o w e c a n j u m p t o . L r e s t o r e _ r e g s
* directly a f t e r d o _ p a g e _ f a u l t _ i c s ( ) i f n e c e s s a r y .
* /
2010-10-14 16:23:03 -04:00
mfspr r32 , S P R _ E X _ C O N T E X T _ K _ 1
2010-05-28 23:09:12 -04:00
{
andi r32 , r32 , S P R _ E X _ C O N T E X T _ 1 _ 1 _ _ P L _ M A S K / * m a s k o f f I C S * /
PTREGS_ P T R ( r21 , P T R E G S _ O F F S E T _ F L A G S )
}
bzt r32 , 1 f / * z e r o i f f r o m u s e r s p a c e * /
IRQS_ D I S A B L E D ( r32 ) / * z e r o i f i r q s e n a b l e d * /
# if P T _ F L A G S _ D I S A B L E _ I R Q ! = 1
# error V a l u e o f I R Q S _ D I S A B L E D u s e d t o s e t P T _ F L A G S _ D I S A B L E _ I R Q ; fix
# endif
1 :
.ifnc \ function,h a n d l e _ s y s c a l l
/* Record the fact that we saved the caller-save registers above. */
ori r32 , r32 , P T _ F L A G S _ C A L L E R _ S A V E S
.endif
sw r21 , r32
# ifdef _ _ C O L L E C T _ L I N K E R _ F E E D B A C K _ _
/ *
* Notify t h e f e e d b a c k r o u t i n e s t h a t w e w e r e i n t h e
* appropriate f i x e d i n t e r r u p t v e c t o r a r e a . N o t e t h a t w e
* still h a v e I C S s e t a t t h i s p o i n t , s o w e c a n ' t i n v o k e a n y
* atomic o p e r a t i o n s o r w e w i l l p a n i c . T h e f e e d b a c k
* routines i n t e r n a l l y p r e s e r v e r0 . . r10 a n d r30 u p .
* /
.ifnc \ function,h a n d l e _ s y s c a l l
shli r20 , r1 , 5
.else
moveli r20 , I N T _ S W I N T _ 1 < < 5
.endif
addli r20 , r20 , l o 1 6 ( i n t v e c _ f e e d b a c k )
auli r20 , r20 , h a16 ( i n t v e c _ f e e d b a c k )
jalr r20
/* And now notify the feedback routines that we are here. */
FEEDBACK_ E N T E R ( \ f u n c t i o n )
# endif
/ *
* we' v e c a p t u r e d e n o u g h s t a t e t o t h e s t a c k ( i n c l u d i n g i n
* particular o u r E X _ C O N T E X T s t a t e ) t h a t w e c a n n o w r e l e a s e
* the i n t e r r u p t c r i t i c a l s e c t i o n a n d r e p l a c e i t w i t h o u r
* standard " i n t e r r u p t s d i s a b l e d " m a s k v a l u e . T h i s a l l o w s
* synchronous i n t e r r u p t s ( a n d p r o f i l e i n t e r r u p t s ) t o p u n c h
* through f r o m t h i s p o i n t o n w a r d s .
*
* If b i t 3 1 o f r3 i s s e t d u r i n g a n o n - N M I i n t e r r u p t , w e k n o w w e
* are o n t h e p a t h w h e r e t h e h y p e r v i s o r h a s p u n c h e d t h r o u g h o u r
* ICS w i t h a p a g e f a u l t , s o w e c a l l o u t t o d o _ p a g e _ f a u l t _ i c s ( )
* to f i g u r e o u t w h a t t o d o w i t h i t . I f t h e f a u l t w a s i n
* an a t o m i c o p , w e u n l o c k t h e a t o m i c l o c k , a d j u s t t h e
* saved r e g i s t e r s t a t e a l i t t l e , a n d r e t u r n " z e r o " i n r4 ,
* falling t h r o u g h i n t o t h e n o r m a l p a g e - f a u l t i n t e r r u p t c o d e .
* If t h e f a u l t w a s i n a k e r n e l - s p a c e a t o m i c o p e r a t i o n , t h e n
* do_ p a g e _ f a u l t _ i c s ( ) r e s o l v e s i t i t s e l f , r e t u r n s " o n e " i n r4 ,
* and a s a r e s u l t g o e s d i r e c t l y t o r e s t o r i n g r e g i s t e r s a n d i r e t ,
* without t r y i n g t o a d j u s t t h e i n t e r r u p t m a s k s a t a l l .
* The d o _ p a g e _ f a u l t _ i c s ( ) A P I i n v o l v e s p a s s i n g a n d r e t u r n i n g
* a f i v e - w o r d s t r u c t ( i n r e g i s t e r s ) t o a v o i d w r i t i n g t h e
* save a n d r e s t o r e c o d e h e r e .
* /
.ifc \ function,h a n d l e _ n m i
IRQ_ D I S A B L E _ A L L ( r20 )
.else
.ifnc \ function,h a n d l e _ s y s c a l l
bgezt r3 , 1 f
{
PTREGS_ P T R ( r0 , P T R E G S _ O F F S E T _ B A S E )
jal d o _ p a g e _ f a u l t _ i c s
}
FEEDBACK_ R E E N T E R ( \ f u n c t i o n )
bzt r4 , 1 f
j . L r e s t o r e _ r e g s
1 :
.endif
IRQ_ D I S A B L E ( r20 , r21 )
.endif
mtspr I N T E R R U P T _ C R I T I C A L _ S E C T I O N , z e r o
# if C H I P _ H A S _ W H 6 4 ( )
/ *
* Prepare t h e f i r s t 2 5 6 s t a c k b y t e s t o b e r a p i d l y a c c e s s i b l e
* without h a v i n g t o f e t c h t h e b a c k g r o u n d d a t a . W e d o n ' t r e a l l y
* know h o w f a r t o w r i t e - h i n t , b u t k e r n e l s t a c k s g e n e r a l l y
* aren' t t h a t b i g , a n d w r i t e - h i n t i n g h e r e d o e s t a k e s o m e t i m e .
* /
addi r52 , s p , - 6 4
{
wh6 4 r52
addi r52 , r52 , - 6 4
}
{
wh6 4 r52
addi r52 , r52 , - 6 4
}
{
wh6 4 r52
addi r52 , r52 , - 6 4
}
wh6 4 r52
# endif
# ifdef C O N F I G _ T R A C E _ I R Q F L A G S
.ifnc \ function,h a n d l e _ n m i
/ *
* We f i n a l l y h a v e e n o u g h s t a t e s e t u p t o n o t i f y t h e i r q
* tracing c o d e t h a t i r q s w e r e d i s a b l e d o n e n t r y t o t h e h a n d l e r .
* The T R A C E _ I R Q S _ O F F c a l l c l o b b e r s r e g i s t e r s r0 - r29 .
* For s y s c a l l s , w e a l r e a d y h a v e t h e r e g i s t e r s t a t e s a v e d a w a y
* on t h e s t a c k , s o w e d o n ' t b o t h e r t o d o a n y r e g i s t e r s a v e s h e r e ,
* and l a t e r w e p o p t h e r e g i s t e r s b a c k o f f t h e k e r n e l s t a c k .
* For i n t e r r u p t h a n d l e r s , s a v e r0 - r3 i n c a l l e e - s a v e d r e g i s t e r s .
* /
.ifnc \ function,h a n d l e _ s y s c a l l
{ move r30 , r0 ; move r31, r1 }
{ move r32 , r2 ; move r33, r3 }
.endif
TRACE_ I R Q S _ O F F
.ifnc \ function,h a n d l e _ s y s c a l l
{ move r0 , r30 ; move r1, r31 }
{ move r2 , r32 ; move r3, r33 }
.endif
.endif
# endif
.endm
.macro check_ s i n g l e _ s t e p p i n g , k i n d , n o t _ s i n g l e _ s t e p p i n g
/ *
* Check f o r s i n g l e s t e p p i n g i n u s e r - l e v e l p r i v
* kind c a n b e " n o r m a l " , " i l l " , o r " s y s c a l l "
* At e n d , i f f a l l - t h r u
* r29 : thread_ i n f o - > s t e p _ s t a t e
* r28 : & pt_ r e g s - > p c
* r27 : pt_ r e g s - > p c
* r26 : thread_ i n f o - > s t e p _ s t a t e - > b u f f e r
* /
/* Check for single stepping */
GET_ T H R E A D _ I N F O ( r29 )
{
/* Get pointer to field holding step state */
addi r29 , r29 , T H R E A D _ I N F O _ S T E P _ S T A T E _ O F F S E T
/* Get pointer to EX1 in register state */
PTREGS_ P T R ( r27 , P T R E G S _ O F F S E T _ E X 1 )
}
{
/* Get pointer to field holding PC */
PTREGS_ P T R ( r28 , P T R E G S _ O F F S E T _ P C )
/* Load the pointer to the step state */
lw r29 , r29
}
/* Load EX1 */
lw r27 , r27
{
/* Points to flags */
addi r23 , r29 , S I N G L E S T E P _ S T A T E _ F L A G S _ O F F S E T
/* No single stepping if there is no step state structure */
bzt r29 , \ n o t _ s i n g l e _ s t e p p i n g
}
{
/* mask off ICS and any other high bits */
andi r27 , r27 , S P R _ E X _ C O N T E X T _ 1 _ 1 _ _ P L _ M A S K
/* Load pointer to single step instruction buffer */
lw r26 , r29
}
/* Check priv state */
bnz r27 , \ n o t _ s i n g l e _ s t e p p i n g
/* Get flags */
lw r22 , r23
{
/* Branch if single-step mode not enabled */
bbnst r22 , \ n o t _ s i n g l e _ s t e p p i n g
/* Clear enabled flag */
andi r22 , r22 , ~ S I N G L E S T E P _ S T A T E _ M A S K _ I S _ E N A B L E D
}
.ifc \ kind,n o r m a l
{
/* Load PC */
lw r27 , r28
/* Point to the entry containing the original PC */
addi r24 , r29 , S I N G L E S T E P _ S T A T E _ O R I G _ P C _ O F F S E T
}
{
/* Disable single stepping flag */
sw r23 , r22
}
{
/* Get the original pc */
lw r24 , r24
/* See if the PC is at the start of the single step buffer */
seq r25 , r26 , r27
}
/ *
* NOTE : it i s r e a l l y e x p e c t e d t h a t t h e P C b e i n t h e s i n g l e s t e p b u f f e r
* at t h i s p o i n t
* /
bzt r25 , \ n o t _ s i n g l e _ s t e p p i n g
/* Restore the original PC */
sw r28 , r24
.else
.ifc \ kind,s y s c a l l
{
/* Load PC */
lw r27 , r28
/* Point to the entry containing the next PC */
addi r24 , r29 , S I N G L E S T E P _ S T A T E _ N E X T _ P C _ O F F S E T
}
{
/* Increment the stopped PC by the bundle size */
addi r26 , r26 , 8
/* Disable single stepping flag */
sw r23 , r22
}
{
/* Get the next pc */
lw r24 , r24
/ *
* See i f t h e P C i s o n e b u n d l e p a s t t h e s t a r t o f t h e
* single s t e p b u f f e r
* /
seq r25 , r26 , r27
}
{
/ *
* NOTE : it i s r e a l l y e x p e c t e d t h a t t h e P C b e i n t h e
* single s t e p b u f f e r a t t h i s p o i n t
* /
bzt r25 , \ n o t _ s i n g l e _ s t e p p i n g
}
/* Set to the next PC */
sw r28 , r24
.else
{
/* Point to 3rd bundle in buffer */
addi r25 , r26 , 1 6
/* Load PC */
lw r27 , r28
}
{
/* Disable single stepping flag */
sw r23 , r22
/* See if the PC is in the single step buffer */
slte_ u r24 , r26 , r27
}
{
slte_ u r25 , r27 , r25
/ *
* NOTE : it i s r e a l l y e x p e c t e d t h a t t h e P C b e i n t h e
* single s t e p b u f f e r a t t h i s p o i n t
* /
bzt r24 , \ n o t _ s i n g l e _ s t e p p i n g
}
bzt r25 , \ n o t _ s i n g l e _ s t e p p i n g
.endif
.endif
.endm
/ *
* Redispatch a d o w n c a l l .
* /
.macro dc_dispatch vecnum, v e c n a m e
.org ( \ vecnum < < 8 )
intvec_ \ v e c n a m e :
j h v _ d o w n c a l l _ d i s p a t c h
ENDPROC( i n t v e c _ \ v e c n a m e )
.endm
/ *
* Common c o d e f o r m o s t i n t e r r u p t s . T h e C f u n c t i o n w e ' r e e v e n t u a l l y
* going t o i s i n r0 , a n d t h e f a u l t n u m i s i n r1 ; the original
* values f o r t h o s e r e g i s t e r s a r e o n t h e s t a c k .
* /
.pushsection .text .handle_interrupt , " ax"
handle_interrupt :
finish_ i n t e r r u p t _ s a v e h a n d l e _ i n t e r r u p t
/ *
* Check f o r i f w e a r e s i n g l e s t e p p i n g i n u s e r l e v e l . I f s o , t h e n
* we n e e d t o r e s t o r e t h e P C .
* /
check_ s i n g l e _ s t e p p i n g n o r m a l , . L d i s p a t c h _ i n t e r r u p t
.Ldispatch_interrupt :
/* Jump to the C routine; it should enable irqs as soon as possible. */
{
jalr r0
PTREGS_ P T R ( r0 , P T R E G S _ O F F S E T _ B A S E )
}
FEEDBACK_ R E E N T E R ( h a n d l e _ i n t e r r u p t )
{
movei r30 , 0 / * n o t a n N M I * /
j i n t e r r u p t _ r e t u r n
}
STD_ E N D P R O C ( h a n d l e _ i n t e r r u p t )
/ *
* This r o u t i n e t a k e s a b o o l e a n i n r30 i n d i c a t i n g i f t h i s i s a n N M I .
* If s o , w e a l s o e x p e c t a b o o l e a n i n r31 i n d i c a t i n g w h e t h e r t o
* re- e n a b l e t h e o p r o f i l e i n t e r r u p t s .
* /
STD_ E N T R Y ( i n t e r r u p t _ r e t u r n )
/* If we're resuming to kernel space, don't check thread flags. */
{
bnz r30 , . L r e s t o r e _ a l l / * N M I s d o n ' t s p e c i a l - c a s e u s e r - s p a c e * /
PTREGS_ P T R ( r29 , P T R E G S _ O F F S E T _ E X 1 )
}
lw r29 , r29
andi r29 , r29 , S P R _ E X _ C O N T E X T _ 1 _ 1 _ _ P L _ M A S K / * m a s k o f f I C S * /
{
bzt r29 , . L r e s u m e _ u s e r s p a c e
PTREGS_ P T R ( r29 , P T R E G S _ O F F S E T _ P C )
}
/* If we're resuming to _cpu_idle_nap, bump PC forward by 8. */
{
lw r28 , r29
moveli r27 , l o 1 6 ( _ c p u _ i d l e _ n a p )
}
{
auli r27 , r27 , h a16 ( _ c p u _ i d l e _ n a p )
}
{
seq r27 , r27 , r28
}
{
bbns r27 , . L r e s t o r e _ a l l
addi r28 , r28 , 8
}
sw r29 , r28
j . L r e s t o r e _ a l l
.Lresume_userspace :
FEEDBACK_ R E E N T E R ( i n t e r r u p t _ r e t u r n )
/ *
* Disable i n t e r r u p t s s o a s t o m a k e s u r e w e d o n ' t
* miss a n i n t e r r u p t t h a t s e t s a n y o f t h e t h r e a d f l a g s ( l i k e
* need_ r e s c h e d o r s i g p e n d i n g ) b e t w e e n s a m p l i n g a n d t h e i r e t .
* Routines l i k e s c h e d u l e ( ) o r d o _ s i g n a l ( ) m a y r e - e n a b l e
* interrupts b e f o r e r e t u r n i n g .
* /
IRQ_ D I S A B L E ( r20 , r21 )
TRACE_ I R Q S _ O F F / * N o t e : c l o b b e r s r e g i s t e r s r0 - r29 * /
/* Get base of stack in r32; note r30/31 are used as arguments here. */
GET_ T H R E A D _ I N F O ( r32 )
/* Check to see if there is any work to do before returning to user. */
{
addi r29 , r32 , T H R E A D _ I N F O _ F L A G S _ O F F S E T
moveli r28 , l o 1 6 ( _ T I F _ A L L W O R K _ M A S K )
}
{
lw r29 , r29
auli r28 , r28 , h a16 ( _ T I F _ A L L W O R K _ M A S K )
}
and r28 , r29 , r28
bnz r28 , . L w o r k _ p e n d i n g
/ *
* In t h e N M I c a s e w e
* omit t h e c a l l t o s i n g l e _ p r o c e s s _ c h e c k _ n o h z , w h i c h n o r m a l l y c h e c k s
* to s e e i f w e s h o u l d s t a r t o r s t o p t h e s c h e d u l e r t i c k , b e c a u s e
* we c a n ' t c a l l a r b i t r a r y L i n u x c o d e f r o m a n N M I c o n t e x t .
* We a l w a y s c a l l t h e h o m e c a c h e T L B d e f e r r a l c o d e t o r e - t r i g g e r
* the d e f e r r a l m e c h a n i s m .
*
* The o t h e r c h u n k o f r e s p o n s i b i l i t y t h i s c o d e h a s i s t o r e s e t t h e
* interrupt m a s k s a p p r o p r i a t e l y t o r e s e t i r q s a n d N M I s . W e h a v e
* to c a l l T R A C E _ I R Q S _ O F F a n d T R A C E _ I R Q S _ O N t o s u p p o r t a l l t h e
* lockdep- t y p e s t u f f , b u t w e c a n ' t s e t I C S u n t i l a f t e r w a r d s , s i n c e
* ICS c a n o n l y b e u s e d i n v e r y t i g h t c h u n k s o f c o d e t o a v o i d
* tripping o v e r v a r i o u s a s s e r t i o n s t h a t i t i s o f f .
*
* ( There i s w h a t l o o k s l i k e a w i n d o w o f v u l n e r a b i l i t y h e r e s i n c e
* we m i g h t t a k e a p r o f i l e i n t e r r u p t b e t w e e n t h e t w o S P R w r i t e s
* that s e t t h e m a s k , b u t s i n c e w e w r i t e t h e l o w S P R w o r d f i r s t ,
* and o u r i n t e r r u p t e n t r y c o d e c h e c k s t h e l o w S P R w o r d , a n y
* profile i n t e r r u p t w i l l a c t u a l l y d i s a b l e i n t e r r u p t s i n b o t h S P R s
* before r e t u r n i n g , w h i c h i s O K . )
* /
.Lrestore_all :
PTREGS_ P T R ( r0 , P T R E G S _ O F F S E T _ E X 1 )
{
lw r0 , r0
PTREGS_ P T R ( r32 , P T R E G S _ O F F S E T _ F L A G S )
}
{
andi r0 , r0 , S P R _ E X _ C O N T E X T _ 1 _ 1 _ _ P L _ M A S K
lw r32 , r32
}
bnz r0 , 1 f
j 2 f
# if P T _ F L A G S _ D I S A B L E _ I R Q ! = 1
# error A s s u m i n g P T _ F L A G S _ D I S A B L E _ I R Q = = 1 s o w e c a n u s e b b n s t b e l o w
# endif
1 : bbnst r32 , 2 f
IRQ_ D I S A B L E ( r20 ,r21 )
TRACE_ I R Q S _ O F F
movei r0 , 1
mtspr I N T E R R U P T _ C R I T I C A L _ S E C T I O N , r0
bzt r30 , . L r e s t o r e _ r e g s
j 3 f
2 : TRACE_ I R Q S _ O N
movei r0 , 1
mtspr I N T E R R U P T _ C R I T I C A L _ S E C T I O N , r0
IRQ_ E N A B L E ( r20 , r21 )
bzt r30 , . L r e s t o r e _ r e g s
3 :
/ *
* We n o w c o m m i t t o r e t u r n i n g f r o m t h i s i n t e r r u p t , s i n c e w e w i l l b e
* doing t h i n g s l i k e s e t t i n g E X _ C O N T E X T S P R s a n d u n w i n d i n g t h e s t a c k
* frame. N o c a l l s s h o u l d b e m a d e t o a n y o t h e r c o d e a f t e r t h i s p o i n t .
* This c o d e s h o u l d o n l y b e e n t e r e d w i t h I C S s e t .
* r3 2 m u s t s t i l l b e s e t t o p t r e g s . f l a g s .
* We l a u n c h l o a d s t o e a c h c a c h e l i n e s e p a r a t e l y f i r s t , s o w e c a n
* get s o m e p a r a l l e l i s m o u t o f t h e m e m o r y s u b s y s t e m .
* We s t a r t z e r o i n g c a l l e r - s a v e d r e g i s t e r s t h r o u g h o u t , s i n c e
* that w i l l s a v e s o m e c y c l e s i f t h i s t u r n s o u t t o b e a s y s c a l l .
* /
.Lrestore_regs :
FEEDBACK_ R E E N T E R ( i n t e r r u p t _ r e t u r n ) / * c a l l e d f r o m e l s e w h e r e * /
/ *
* Rotate s o w e h a v e o n e h i g h b i t a n d o n e l o w b i t t o t e s t .
* - low b i t s a y s w h e t h e r t o r e s t o r e a l l t h e c a l l e e - s a v e d r e g i s t e r s ,
* or j u s t r30 - r33 , a n d r52 u p .
* - high b i t ( i . e . s i g n b i t ) s a y s w h e t h e r t o r e s t o r e a l l t h e
* caller- s a v e d r e g i s t e r s , o r j u s t r0 .
* /
# if P T _ F L A G S _ C A L L E R _ S A V E S ! = 2 | | P T _ F L A G S _ R E S T O R E _ R E G S ! = 4
# error R o t a t e t r i c k d o e s n o t w o r k : - )
# endif
{
rli r20 , r32 , 3 0
PTREGS_ P T R ( s p , P T R E G S _ O F F S E T _ R E G ( 0 ) )
}
/ *
* Load c a c h e l i n e s 0 , 2 , a n d 3 i n t h a t o r d e r , t h e n u s e
* the l a s t l o a d e d v a l u e , w h i c h m a k e s i t l i k e l y t h a t t h e o t h e r
* cache l i n e s h a v e a l s o l o a d e d , a t w h i c h p o i n t w e s h o u l d b e
* able t o s a f e l y r e a d a l l t h e r e m a i n i n g w o r d s o n t h o s e c a c h e
* lines w i t h o u t w a i t i n g f o r t h e m e m o r y s u b s y s t e m .
* /
2010-08-13 16:37:00 -04:00
pop_ r e g _ z e r o r0 , r28 , s p , P T R E G S _ O F F S E T _ R E G ( 3 0 ) - P T R E G S _ O F F S E T _ R E G ( 0 )
2010-05-28 23:09:12 -04:00
pop_ r e g _ z e r o r30 , r2 , s p , P T R E G S _ O F F S E T _ P C - P T R E G S _ O F F S E T _ R E G ( 3 0 )
pop_ r e g _ z e r o r21 , r3 , s p , P T R E G S _ O F F S E T _ E X 1 - P T R E G S _ O F F S E T _ P C
pop_ r e g _ z e r o l r , r4 , s p , P T R E G S _ O F F S E T _ R E G ( 5 2 ) - P T R E G S _ O F F S E T _ E X 1
{
2010-10-14 16:23:03 -04:00
mtspr S P R _ E X _ C O N T E X T _ K _ 0 , r21
2010-05-28 23:09:12 -04:00
move r5 , z e r o
}
{
2010-10-14 16:23:03 -04:00
mtspr S P R _ E X _ C O N T E X T _ K _ 1 , l r
2010-05-28 23:09:12 -04:00
andi l r , l r , S P R _ E X _ C O N T E X T _ 1 _ 1 _ _ P L _ M A S K / * m a s k o f f I C S * /
}
/* Restore callee-saveds that we actually use. */
pop_ r e g _ z e r o r52 , r6 , s p , P T R E G S _ O F F S E T _ R E G ( 3 1 ) - P T R E G S _ O F F S E T _ R E G ( 5 2 )
pop_ r e g _ z e r o r31 , r7
pop_ r e g _ z e r o r32 , r8
pop_ r e g _ z e r o r33 , r9 , s p , P T R E G S _ O F F S E T _ R E G ( 2 9 ) - P T R E G S _ O F F S E T _ R E G ( 3 3 )
/ *
* If w e m o d i f i e d o t h e r c a l l e e - s a v e d s , r e s t o r e t h e m n o w .
* This i s r a r e , b u t c o u l d b e v i a p t r a c e o r s i g n a l h a n d l e r .
* /
{
move r10 , z e r o
bbs r20 , . L r e s t o r e _ c a l l e e s
}
.Lcontinue_restore_regs :
/* Check if we're returning from a syscall. */
{
move r11 , z e r o
blzt r20 , 1 f / * n o , s o g o r e s t o r e c a l l e e - s a v e r e g i s t e r s * /
}
/ *
* Check i f w e ' r e r e t u r n i n g t o u s e r s p a c e .
* Note t h a t i f w e ' r e n o t , w e d o n ' t w o r r y a b o u t z e r o i n g e v e r y t h i n g .
* /
{
addli s p , s p , P T R E G S _ O F F S E T _ L R - P T R E G S _ O F F S E T _ R E G ( 2 9 )
bnz l r , . L k e r n e l _ r e t u r n
}
/ *
* On r e t u r n f r o m s y s c a l l , w e ' v e r e s t o r e d r0 f r o m p t _ r e g s , b u t w e
* clear t h e r e m a i n d e r o f t h e c a l l e r - s a v e d r e g i s t e r s . W e c o u l d
* restore t h e s y s c a l l a r g u m e n t s , b u t t h e r e ' s n o t m u c h p o i n t ,
* and i t e n s u r e s u s e r p r o g r a m s a r e n ' t t r y i n g t o u s e t h e
* caller- s a v e s i f w e c l e a r t h e m , a s w e l l a s a v o i d i n g l e a k i n g
* kernel p o i n t e r s i n t o u s e r s p a c e .
* /
pop_ r e g _ z e r o l r , r12 , s p , P T R E G S _ O F F S E T _ T P - P T R E G S _ O F F S E T _ L R
pop_ r e g _ z e r o t p , r13 , s p , P T R E G S _ O F F S E T _ S P - P T R E G S _ O F F S E T _ T P
{
lw s p , s p
move r14 , z e r o
move r15 , z e r o
}
{ move r16 , z e r o ; move r17, zero }
{ move r18 , z e r o ; move r19, zero }
{ move r20 , z e r o ; move r21, zero }
{ move r22 , z e r o ; move r23, zero }
{ move r24 , z e r o ; move r25, zero }
{ move r26 , z e r o ; move r27, zero }
2010-08-13 16:37:00 -04:00
/* Set r1 to errno if we are returning an error, otherwise zero. */
{
2010-10-14 15:14:29 -04:00
moveli r29 , 4 0 9 6
2010-08-13 16:37:00 -04:00
sub r1 , z e r o , r0
}
slt_ u r29 , r1 , r29
{
mnz r1 , r29 , r1
move r29 , z e r o
}
2010-05-28 23:09:12 -04:00
iret
/ *
* Not a s y s c a l l , s o r e s t o r e c a l l e r - s a v e d r e g i s t e r s .
* First k i c k o f f a l o a d f o r c a c h e l i n e 1 , w h i c h w e ' r e t o u c h i n g
* for t h e f i r s t t i m e h e r e .
* /
.align 64
1 : pop_ r e g r29 , s p , P T R E G S _ O F F S E T _ R E G ( 1 ) - P T R E G S _ O F F S E T _ R E G ( 2 9 )
pop_ r e g r1
pop_ r e g r2
pop_ r e g r3
pop_ r e g r4
pop_ r e g r5
pop_ r e g r6
pop_ r e g r7
pop_ r e g r8
pop_ r e g r9
pop_ r e g r10
pop_ r e g r11
pop_ r e g r12
pop_ r e g r13
pop_ r e g r14
pop_ r e g r15
pop_ r e g r16
pop_ r e g r17
pop_ r e g r18
pop_ r e g r19
pop_ r e g r20
pop_ r e g r21
pop_ r e g r22
pop_ r e g r23
pop_ r e g r24
pop_ r e g r25
pop_ r e g r26
pop_ r e g r27
pop_ r e g r28 , s p , P T R E G S _ O F F S E T _ L R - P T R E G S _ O F F S E T _ R E G ( 2 8 )
/* r29 already restored above */
bnz l r , . L k e r n e l _ r e t u r n
pop_ r e g l r , s p , P T R E G S _ O F F S E T _ T P - P T R E G S _ O F F S E T _ L R
pop_ r e g t p , s p , P T R E G S _ O F F S E T _ S P - P T R E G S _ O F F S E T _ T P
lw s p , s p
iret
/ *
* We c a n ' t r e s t o r e t p w h e n i n k e r n e l m o d e , s i n c e a t h r e a d m i g h t
* have m i g r a t e d f r o m a n o t h e r c p u a n d b r o u g h t a s t a l e t p v a l u e .
* /
.Lkernel_return :
pop_ r e g l r , s p , P T R E G S _ O F F S E T _ S P - P T R E G S _ O F F S E T _ L R
lw s p , s p
iret
/* Restore callee-saved registers from r34 to r51. */
.Lrestore_callees :
addli s p , s p , P T R E G S _ O F F S E T _ R E G ( 3 4 ) - P T R E G S _ O F F S E T _ R E G ( 2 9 )
pop_ r e g r34
pop_ r e g r35
pop_ r e g r36
pop_ r e g r37
pop_ r e g r38
pop_ r e g r39
pop_ r e g r40
pop_ r e g r41
pop_ r e g r42
pop_ r e g r43
pop_ r e g r44
pop_ r e g r45
pop_ r e g r46
pop_ r e g r47
pop_ r e g r48
pop_ r e g r49
pop_ r e g r50
pop_ r e g r51 , s p , P T R E G S _ O F F S E T _ R E G ( 2 9 ) - P T R E G S _ O F F S E T _ R E G ( 5 1 )
j . L c o n t i n u e _ r e s t o r e _ r e g s
.Lwork_pending :
/* Mask the reschedule flag */
andi r28 , r29 , _ T I F _ N E E D _ R E S C H E D
{
/ *
* If t h e N E E D _ R E S C H E D f l a g i s c a l l e d , w e c a l l s c h e d u l e ( ) , w h i c h
* may d r o p t h i s c o n t e x t r i g h t h e r e a n d g o d o s o m e t h i n g e l s e .
* On r e t u r n , j u m p b a c k t o . L r e s u m e _ u s e r s p a c e a n d r e c h e c k .
* /
bz r28 , . L a s y n c _ t l b
/* Mask the async-tlb flag */
andi r28 , r29 , _ T I F _ A S Y N C _ T L B
}
jal s c h e d u l e
FEEDBACK_ R E E N T E R ( i n t e r r u p t _ r e t u r n )
/* Reload the flags and check again */
j . L r e s u m e _ u s e r s p a c e
.Lasync_tlb :
{
bz r28 , . L n e e d _ s i g p e n d i n g
/* Mask the sigpending flag */
andi r28 , r29 , _ T I F _ S I G P E N D I N G
}
PTREGS_ P T R ( r0 , P T R E G S _ O F F S E T _ B A S E )
jal d o _ a s y n c _ p a g e _ f a u l t
FEEDBACK_ R E E N T E R ( i n t e r r u p t _ r e t u r n )
/ *
* Go r e s t a r t t h e " r e s u m e u s e r s p a c e " p r o c e s s . W e m a y h a v e
* fired a s i g n a l , a n d w e n e e d t o d i s a b l e i n t e r r u p t s a g a i n .
* /
j . L r e s u m e _ u s e r s p a c e
.Lneed_sigpending :
/ *
* At t h i s p o i n t w e a r e e i t h e r d o i n g s i g n a l h a n d l i n g o r s i n g l e - s t e p ,
* so e i t h e r w a y m a k e s u r e w e h a v e a l l t h e r e g i s t e r s s a v e d .
* /
push_ e x t r a _ c a l l e e _ s a v e s r0
{
/* If no signal pending, skip to singlestep check */
bz r28 , . L n e e d _ s i n g l e s t e p
/* Mask the singlestep flag */
andi r28 , r29 , _ T I F _ S I N G L E S T E P
}
jal d o _ s i g n a l
FEEDBACK_ R E E N T E R ( i n t e r r u p t _ r e t u r n )
/* Reload the flags and check again */
j . L r e s u m e _ u s e r s p a c e
.Lneed_singlestep :
{
/* Get a pointer to the EX1 field */
PTREGS_ P T R ( r29 , P T R E G S _ O F F S E T _ E X 1 )
/* If we get here, our bit must be set. */
bz r28 , . L w o r k _ c o n f u s i o n
}
/* If we are in priv mode, don't single step */
lw r28 , r29
andi r28 , r28 , S P R _ E X _ C O N T E X T _ 1 _ 1 _ _ P L _ M A S K / * m a s k o f f I C S * /
bnz r28 , . L r e s t o r e _ a l l
/* Allow interrupts within the single step code */
TRACE_ I R Q S _ O N / * N o t e : c l o b b e r s r e g i s t e r s r0 - r29 * /
IRQ_ E N A B L E ( r20 , r21 )
/* try to single-step the current instruction */
PTREGS_ P T R ( r0 , P T R E G S _ O F F S E T _ B A S E )
jal s i n g l e _ s t e p _ o n c e
FEEDBACK_ R E E N T E R ( i n t e r r u p t _ r e t u r n )
/* Re-disable interrupts. TRACE_IRQS_OFF in .Lrestore_all. */
IRQ_ D I S A B L E ( r20 ,r21 )
j . L r e s t o r e _ a l l
.Lwork_confusion :
move r0 , r28
panic " t h r e a d _ i n f o a l l w o r k f l a g s u n h a n d l e d o n u s e r s p a c e r e s u m e : % #x "
STD_ E N D P R O C ( i n t e r r u p t _ r e t u r n )
/ *
2010-10-14 16:23:03 -04:00
* This i n t e r r u p t v a r i a n t c l e a r s t h e I N T _ I N T C T R L _ K i n t e r r u p t m a s k b i t
2010-05-28 23:09:12 -04:00
* before r e t u r n i n g , s o w e c a n p r o p e r l y g e t m o r e d o w n c a l l s .
* /
.pushsection .text .handle_interrupt_downcall , " ax"
handle_interrupt_downcall :
finish_ i n t e r r u p t _ s a v e h a n d l e _ i n t e r r u p t _ d o w n c a l l
check_ s i n g l e _ s t e p p i n g n o r m a l , . L d i s p a t c h _ d o w n c a l l
.Ldispatch_downcall :
2010-10-14 16:23:03 -04:00
/* Clear INTCTRL_K from the set of interrupts we ever enable. */
2010-05-28 23:09:12 -04:00
GET_ I N T E R R U P T S _ E N A B L E D _ M A S K _ P T R ( r30 )
{
addi r30 , r30 , 4
2010-10-14 16:23:03 -04:00
movei r31 , I N T _ M A S K ( I N T _ I N T C T R L _ K )
2010-05-28 23:09:12 -04:00
}
{
lw r20 , r30
nor r21 , r31 , z e r o
}
and r20 , r20 , r21
sw r30 , r20
{
jalr r0
PTREGS_ P T R ( r0 , P T R E G S _ O F F S E T _ B A S E )
}
FEEDBACK_ R E E N T E R ( h a n d l e _ i n t e r r u p t _ d o w n c a l l )
2010-10-14 16:23:03 -04:00
/* Allow INTCTRL_K to be enabled next time we enable interrupts. */
2010-05-28 23:09:12 -04:00
lw r20 , r30
or r20 , r20 , r31
sw r30 , r20
{
movei r30 , 0 / * n o t a n N M I * /
j i n t e r r u p t _ r e t u r n
}
STD_ E N D P R O C ( h a n d l e _ i n t e r r u p t _ d o w n c a l l )
/ *
* Some i n t e r r u p t s d o n ' t c h e c k f o r s i n g l e s t e p p i n g
* /
.pushsection .text .handle_interrupt_no_single_step , " ax"
handle_interrupt_no_single_step :
finish_ i n t e r r u p t _ s a v e h a n d l e _ i n t e r r u p t _ n o _ s i n g l e _ s t e p
{
jalr r0
PTREGS_ P T R ( r0 , P T R E G S _ O F F S E T _ B A S E )
}
FEEDBACK_ R E E N T E R ( h a n d l e _ i n t e r r u p t _ n o _ s i n g l e _ s t e p )
{
movei r30 , 0 / * n o t a n N M I * /
j i n t e r r u p t _ r e t u r n
}
STD_ E N D P R O C ( h a n d l e _ i n t e r r u p t _ n o _ s i n g l e _ s t e p )
/ *
* " NMI" i n t e r r u p t s m a s k A L L i n t e r r u p t s b e f o r e c a l l i n g t h e
* handler, a n d d o n ' t c h e c k t h r e a d f l a g s , e t c . , o n t h e w a y
* back o u t . I n g e n e r a l , t h e o n l y t h i n g s w e d o h e r e f o r N M I s
* are t h e r e g i s t e r s a v e / r e s t o r e , f i x i n g t h e P C i f w e w e r e
* doing s i n g l e s t e p , a n d t h e d a t a p l a n e k e r n e l - T L B m a n a g e m e n t .
* We d o n ' t ( f o r e x a m p l e ) d e a l w i t h s t a r t / s t o p o f t h e s c h e d t i c k .
* /
.pushsection .text .handle_nmi , " ax"
handle_nmi :
finish_ i n t e r r u p t _ s a v e h a n d l e _ n m i
check_ s i n g l e _ s t e p p i n g n o r m a l , . L d i s p a t c h _ n m i
.Ldispatch_nmi :
{
jalr r0
PTREGS_ P T R ( r0 , P T R E G S _ O F F S E T _ B A S E )
}
FEEDBACK_ R E E N T E R ( h a n d l e _ n m i )
j i n t e r r u p t _ r e t u r n
STD_ E N D P R O C ( h a n d l e _ n m i )
/ *
* Parallel c o d e f o r s y s c a l l s t o h a n d l e _ i n t e r r u p t .
* /
.pushsection .text .handle_syscall , " ax"
handle_syscall :
finish_ i n t e r r u p t _ s a v e h a n d l e _ s y s c a l l
/ *
* Check f o r i f w e a r e s i n g l e s t e p p i n g i n u s e r l e v e l . I f s o , t h e n
* we n e e d t o r e s t o r e t h e P C .
* /
check_ s i n g l e _ s t e p p i n g s y s c a l l , . L d i s p a t c h _ s y s c a l l
.Ldispatch_syscall :
/* Enable irqs. */
TRACE_ I R Q S _ O N
IRQ_ E N A B L E ( r20 , r21 )
/* Bump the counter for syscalls made on this tile. */
moveli r20 , l o 1 6 ( i r q _ s t a t + I R Q _ C P U S T A T _ S Y S C A L L _ C O U N T _ O F F S E T )
auli r20 , r20 , h a16 ( i r q _ s t a t + I R Q _ C P U S T A T _ S Y S C A L L _ C O U N T _ O F F S E T )
add r20 , r20 , t p
lw r21 , r20
addi r21 , r21 , 1
sw r20 , r21
/* Trace syscalls, if requested. */
GET_ T H R E A D _ I N F O ( r31 )
addi r31 , r31 , T H R E A D _ I N F O _ F L A G S _ O F F S E T
lw r30 , r31
andi r30 , r30 , _ T I F _ S Y S C A L L _ T R A C E
bzt r30 , . L r e s t o r e _ s y s c a l l _ r e g s
jal d o _ s y s c a l l _ t r a c e
FEEDBACK_ R E E N T E R ( h a n d l e _ s y s c a l l )
/ *
* We a l w a y s r e l o a d o u r r e g i s t e r s f r o m t h e s t a c k a t t h i s
* point. T h e y m i g h t b e v a l i d , i f w e d i d n ' t b u i l d w i t h
* TRACE_ I R Q F L A G S , a n d t h i s i s n ' t a d a t a p l a n e t i l e , a n d w e ' r e n o t
* doing s y s c a l l t r a c i n g , b u t t h e r e a r e e n o u g h c a s e s n o w t h a t i t
* seems s i m p l e s t j u s t t o d o t h e r e l o a d u n c o n d i t i o n a l l y .
* /
.Lrestore_syscall_regs :
PTREGS_ P T R ( r11 , P T R E G S _ O F F S E T _ R E G ( 0 ) )
pop_ r e g r0 , r11
pop_ r e g r1 , r11
pop_ r e g r2 , r11
pop_ r e g r3 , r11
pop_ r e g r4 , r11
pop_ r e g r5 , r11 , P T R E G S _ O F F S E T _ S Y S C A L L - P T R E G S _ O F F S E T _ R E G ( 5 )
pop_ r e g T R E G _ S Y S C A L L _ N R _ N A M E , r11
/* Ensure that the syscall number is within the legal range. */
moveli r21 , _ _ N R _ s y s c a l l s
{
slt_ u r21 , T R E G _ S Y S C A L L _ N R _ N A M E , r21
moveli r20 , l o 1 6 ( s y s _ c a l l _ t a b l e )
}
{
bbns r21 , . L i n v a l i d _ s y s c a l l
auli r20 , r20 , h a16 ( s y s _ c a l l _ t a b l e )
}
s2 a r20 , T R E G _ S Y S C A L L _ N R _ N A M E , r20
lw r20 , r20
/* Jump to syscall handler. */
jalr r20 ; .Lhandle_syscall_link:
FEEDBACK_ R E E N T E R ( h a n d l e _ s y s c a l l )
/ *
* Write o u r r0 o n t o t h e s t a c k s o i t g e t s r e s t o r e d i n s t e a d
* of w h a t e v e r t h e u s e r h a d t h e r e b e f o r e .
* /
PTREGS_ P T R ( r29 , P T R E G S _ O F F S E T _ R E G ( 0 ) )
sw r29 , r0
/* Do syscall trace again, if requested. */
lw r30 , r31
andi r30 , r30 , _ T I F _ S Y S C A L L _ T R A C E
bzt r30 , 1 f
jal d o _ s y s c a l l _ t r a c e
FEEDBACK_ R E E N T E R ( h a n d l e _ s y s c a l l )
1 : j . L r e s u m e _ u s e r s p a c e / * j u m p i n t o m i d d l e o f i n t e r r u p t _ r e t u r n * /
.Linvalid_syscall :
/* Report an invalid syscall back to the user program */
{
PTREGS_ P T R ( r29 , P T R E G S _ O F F S E T _ R E G ( 0 ) )
movei r28 , - E N O S Y S
}
sw r29 , r28
j . L r e s u m e _ u s e r s p a c e / * j u m p i n t o m i d d l e o f i n t e r r u p t _ r e t u r n * /
STD_ E N D P R O C ( h a n d l e _ s y s c a l l )
/* Return the address for oprofile to suppress in backtraces. */
STD_ E N T R Y _ S E C T I O N ( h a n d l e _ s y s c a l l _ l i n k _ a d d r e s s , . t e x t . h a n d l e _ s y s c a l l )
lnk r0
{
addli r0 , r0 , . L h a n d l e _ s y s c a l l _ l i n k - .
jrp l r
}
STD_ E N D P R O C ( h a n d l e _ s y s c a l l _ l i n k _ a d d r e s s )
STD_ E N T R Y ( r e t _ f r o m _ f o r k )
jal s i m _ n o t i f y _ f o r k
jal s c h e d u l e _ t a i l
FEEDBACK_ R E E N T E R ( r e t _ f r o m _ f o r k )
j . L r e s u m e _ u s e r s p a c e / * j u m p i n t o m i d d l e o f i n t e r r u p t _ r e t u r n * /
STD_ E N D P R O C ( r e t _ f r o m _ f o r k )
/ *
* Code f o r i l l i n t e r r u p t .
* /
.pushsection .text .handle_ill , " ax"
handle_ill :
finish_ i n t e r r u p t _ s a v e h a n d l e _ i l l
/ *
* Check f o r i f w e a r e s i n g l e s t e p p i n g i n u s e r l e v e l . I f s o , t h e n
* we n e e d t o r e s t o r e t h e P C .
* /
check_ s i n g l e _ s t e p p i n g i l l , . L d i s p a t c h _ n o r m a l _ i l l
{
/* See if the PC is the 1st bundle in the buffer */
seq r25 , r27 , r26
/* Point to the 2nd bundle in the buffer */
addi r26 , r26 , 8
}
{
/* Point to the original pc */
addi r24 , r29 , S I N G L E S T E P _ S T A T E _ O R I G _ P C _ O F F S E T
/* Branch if the PC is the 1st bundle in the buffer */
bnz r25 , 3 f
}
{
/* See if the PC is the 2nd bundle of the buffer */
seq r25 , r27 , r26
/* Set PC to next instruction */
addi r24 , r29 , S I N G L E S T E P _ S T A T E _ N E X T _ P C _ O F F S E T
}
{
/* Point to flags */
addi r25 , r29 , S I N G L E S T E P _ S T A T E _ F L A G S _ O F F S E T
/* Branch if PC is in the second bundle */
bz r25 , 2 f
}
/* Load flags */
lw r25 , r25
{
/ *
* Get t h e o f f s e t f o r t h e r e g i s t e r t o r e s t o r e
* Note : the l o w e r b o u n d i s 2 , s o w e h a v e i m p l i c i t s c a l i n g b y 4 .
* No m u l t i p l i c a t i o n o f t h e r e g i s t e r n u m b e r b y t h e s i z e o f a r e g i s t e r
* is n e e d e d .
* /
mm r27 , r25 , z e r o , S I N G L E S T E P _ S T A T E _ T A R G E T _ L B , \
SINGLESTEP_ S T A T E _ T A R G E T _ U B
/* Mask Rewrite_LR */
andi r25 , r25 , S I N G L E S T E P _ S T A T E _ M A S K _ U P D A T E
}
{
addi r29 , r29 , S I N G L E S T E P _ S T A T E _ U P D A T E _ V A L U E _ O F F S E T
/* Don't rewrite temp register */
bz r25 , 3 f
}
{
/* Get the temp value */
lw r29 , r29
/* Point to where the register is stored */
add r27 , r27 , s p
}
/* Add in the C ABI save area size to the register offset */
addi r27 , r27 , C _ A B I _ S A V E _ A R E A _ S I Z E
/* Restore the user's register with the temp value */
sw r27 , r29
j 3 f
2 :
/* Must be in the third bundle */
addi r24 , r29 , S I N G L E S T E P _ S T A T E _ B R A N C H _ N E X T _ P C _ O F F S E T
3 :
/* set PC and continue */
lw r26 , r24
sw r28 , r26
2010-10-14 16:32:41 -04:00
/ *
* Clear T I F _ S I N G L E S T E P t o p r e v e n t r e c u r s i o n i f w e e x e c u t e a n i l l .
* The n o r m a l n o n - a r c h f l o w r e d u n d a n t l y c l e a r s T I F _ S I N G L E S T E P , b u t w e
* need t o c l e a r i t h e r e a n d c a n ' t r e a l l y i m p o s e o n a l l o t h e r a r c h e s .
* So w h a t ' s a n o t h e r w r i t e b e t w e e n f r i e n d s ?
* /
2010-05-28 23:09:12 -04:00
GET_ T H R E A D _ I N F O ( r0 )
addi r1 , r0 , T H R E A D _ I N F O _ F L A G S _ O F F S E T
{
lw r2 , r1
addi r0 , r0 , T H R E A D _ I N F O _ T A S K _ O F F S E T / * c u r r e n t l y a n o - o p * /
}
andi r2 , r2 , ~ _ T I F _ S I N G L E S T E P
sw r1 , r2
/* Issue a sigtrap */
{
lw r0 , r0 / * i n d i r e c t t h r u t h r e a d _ i n f o t o g e t t a s k _ i n f o * /
addi r1 , s p , C _ A B I _ S A V E _ A R E A _ S I Z E / * p u t p t r e g s p o i n t e r i n t o r1 * /
move r2 , z e r o / * l o a d e r r o r c o d e i n t o r2 * /
}
jal s e n d _ s i g t r a p / * i s s u e a S I G T R A P * /
FEEDBACK_ R E E N T E R ( h a n d l e _ i l l )
j . L r e s u m e _ u s e r s p a c e / * j u m p i n t o m i d d l e o f i n t e r r u p t _ r e t u r n * /
.Ldispatch_normal_ill :
{
jalr r0
PTREGS_ P T R ( r0 , P T R E G S _ O F F S E T _ B A S E )
}
FEEDBACK_ R E E N T E R ( h a n d l e _ i l l )
{
movei r30 , 0 / * n o t a n N M I * /
j i n t e r r u p t _ r e t u r n
}
STD_ E N D P R O C ( h a n d l e _ i l l )
/* Various stub interrupt handlers and syscall handlers */
STD_ E N T R Y _ L O C A L ( _ k e r n e l _ d o u b l e _ f a u l t )
2010-10-14 16:23:03 -04:00
mfspr r1 , S P R _ E X _ C O N T E X T _ K _ 0
2010-05-28 23:09:12 -04:00
move r2 , l r
move r3 , s p
move r4 , r52
addi s p , s p , - C _ A B I _ S A V E _ A R E A _ S I Z E
j k e r n e l _ d o u b l e _ f a u l t
STD_ E N D P R O C ( _ k e r n e l _ d o u b l e _ f a u l t )
STD_ E N T R Y _ L O C A L ( b a d _ i n t r )
2010-10-14 16:23:03 -04:00
mfspr r2 , S P R _ E X _ C O N T E X T _ K _ 0
2010-05-28 23:09:12 -04:00
panic " U n h a n d l e d i n t e r r u p t % #x : P C % # l x "
STD_ E N D P R O C ( b a d _ i n t r )
/* Put address of pt_regs in reg and jump. */
# define P T R E G S _ S Y S C A L L ( x , r e g ) \
2010-10-14 14:34:33 -04:00
STD_ E N T R Y ( _ ## x ) ; \
2010-05-28 23:09:12 -04:00
{ \
PTREGS_ P T R ( r e g , P T R E G S _ O F F S E T _ B A S E ) ; \
2010-10-14 14:34:33 -04:00
j x \
2010-05-28 23:09:12 -04:00
} ; \
2010-10-14 14:34:33 -04:00
STD_ E N D P R O C ( _ ## x )
2010-05-28 23:09:12 -04:00
PTREGS_ S Y S C A L L ( s y s _ e x e c v e , r3 )
PTREGS_ S Y S C A L L ( s y s _ s i g a l t s t a c k , r2 )
PTREGS_ S Y S C A L L ( s y s _ r t _ s i g r e t u r n , r0 )
2010-10-14 14:34:33 -04:00
PTREGS_ S Y S C A L L ( s y s _ c m p x c h g _ b a d a d d r , r1 )
2010-05-28 23:09:12 -04:00
2010-10-14 14:34:33 -04:00
/* Save additional callee-saves to pt_regs, put address in r4 and jump. */
STD_ E N T R Y ( _ s y s _ c l o n e )
push_ e x t r a _ c a l l e e _ s a v e s r4
j s y s _ c l o n e
STD_ E N D P R O C ( _ s y s _ c l o n e )
2010-05-28 23:09:12 -04:00
/ *
* This e n t r y p o i n t i s t a k e n f o r t h e c m p x c h g a n d a t o m i c _ u p d a t e f a s t
* swints. W e m a y w i s h t o g e n e r a l i z e i t t o o t h e r f a s t s w i n t s a t s o m e
* point, b u t f o r n o w t h e r e a r e j u s t t w o v e r y s i m i l a r o n e s , w h i c h
* makes i t f a s t e r .
*
* The f a s t s w i n t c o d e i s d e s i g n e d t o h a v e a s m a l l f o o t p r i n t . I t d o e s
* not s a v e o r r e s t o r e a n y G P R s , c o u n t i n g o n t h e c a l l e r - s a v e r e g i s t e r s
* to b e a v a i l a b l e t o i t o n e n t r y . I t d o e s n o t m o d i f y a n y c a l l e e - s a v e
* registers ( i n c l u d i n g " l r " ) . I t d o e s n o t c h e c k w h a t P L i t i s b e i n g
* called a t , s o y o u ' d b e t t e r n o t c a l l i t o t h e r t h a n a t P L 0 .
2010-10-14 14:42:58 -04:00
* The < a t o m i c . h > w r a p p e r a s s u m e s i t o n l y c l o b b e r s r20 - r29 , s o i f
* it e v e r i s n e c e s s a r y t o u s e m o r e r e g i s t e r s , b e a w a r e .
2010-05-28 23:09:12 -04:00
*
* It d o e s n o t u s e t h e s t a c k , b u t s i n c e i t m i g h t b e r e - i n t e r r u p t e d b y
* a p a g e f a u l t w h i c h w o u l d a s s u m e t h e s t a c k w a s v a l i d , i t d o e s
* save/ r e s t o r e t h e s t a c k p o i n t e r a n d z e r o i t o u t t o m a k e s u r e i t g e t s r e s e t .
* Since w e a l w a y s k e e p i n t e r r u p t s d i s a b l e d , t h e h y p e r v i s o r w o n ' t
2010-10-14 16:23:03 -04:00
* clobber o u r E X _ C O N T E X T _ K _ x r e g i s t e r s , s o w e d o n ' t s a v e / r e s t o r e t h e m
2010-05-28 23:09:12 -04:00
* ( other t h a n t o a d v a n c e t h e P C o n r e t u r n ) .
*
* We h a v e t o m a n u a l l y v a l i d a t e t h e u s e r v s k e r n e l a d d r e s s r a n g e
* ( since a t P L 1 w e c a n r e a d / w r i t e b o t h ) , a n d f o r p e r f o r m a n c e r e a s o n s
* we d o n ' t a l l o w c m p x c h g o n t h e f c00 0 0 0 0 m e m o r y r e g i o n , s i n c e w e o n l y
* validate t h a t t h e u s e r a d d r e s s i s b e l o w P A G E _ O F F S E T .
*
* We p l a c e i t i n t h e _ _ H E A D s e c t i o n t o e n s u r e i t i s r e l a t i v e l y
* near t o t h e i n t v e c _ S W I N T _ 1 c o d e ( r e a c h a b l e b y a c o n d i t i o n a l b r a n c h ) .
*
* Must m a t c h r e g i s t e r u s a g e i n d o _ p a g e _ f a u l t ( ) .
* /
_ _ HEAD
.align 64
/* Align much later jump on the start of a cache line. */
# if ! A T O M I C _ L O C K S _ F O U N D _ V I A _ T A B L E ( )
nop; nop
# endif
ENTRY( s y s _ c m p x c h g )
/ *
* Save " s p " a n d s e t i t z e r o f o r a n y p o s s i b l e p a g e f a u l t .
*
* HACK : We w a n t t o b o t h z e r o s p a n d c h e c k r0 ' s a l i g n m e n t ,
* so w e d o b o t h a t o n c e . I f " s p " b e c o m e s n o n z e r o w e
* know r0 i s u n a l i g n e d a n d b r a n c h t o t h e e r r o r h a n d l e r t h a t
* restores s p , s o t h i s i s O K .
*
* ICS i s d i s a b l e d r i g h t n o w s o h a v i n g a g a r b a g e b u t n o n z e r o
* sp i s O K , s i n c e w e w o n ' t e x e c u t e a n y f a u l t i n g i n s t r u c t i o n s
* when i t i s n o n z e r o .
* /
{
move r27 , s p
andi s p , r0 , 3
}
/ *
* Get t h e l o c k a d d r e s s i n A T O M I C _ L O C K _ R E G , a n d a l s o v a l i d a t e t h a t t h e
* address i s l e s s t h a n P A G E _ O F F S E T , s i n c e t h a t w o n ' t t r a p a t P L 1 .
* We o n l y u s e b i t s l e s s t h a n P A G E _ S H I F T t o a v o i d h a v i n g t o w o r r y
* about a l i a s i n g a m o n g m u l t i p l e m a p p i n g s o f t h e s a m e p h y s i c a l p a g e ,
* and w e i g n o r e t h e l o w 3 b i t s s o w e h a v e o n e l o c k t h a t c o v e r s
* both a c m p x c h g 6 4 ( ) a n d a c m p x c h g ( ) o n e i t h e r i t s l o w o r h i g h w o r d .
* NOTE : this c o d e m u s t m a t c h _ _ a t o m i c _ h a s h e d _ l o c k ( ) i n l i b / a t o m i c . c .
* /
# if A T O M I C _ L O C K S _ F O U N D _ V I A _ T A B L E ( )
{
/* Check for unaligned input. */
bnz s p , . L c m p x c h g _ b a d a d d r
mm r25 , r0 , z e r o , 3 , P A G E _ S H I F T - 1
}
{
crc3 2 _ 3 2 r25 , z e r o , r25
moveli r21 , l o 1 6 ( a t o m i c _ l o c k _ p t r )
}
{
auli r21 , r21 , h a16 ( a t o m i c _ l o c k _ p t r )
auli r23 , z e r o , h i 1 6 ( P A G E _ O F F S E T ) / * h u g e p a g e - a l i g n e d * /
}
{
shri r20 , r25 , 3 2 - A T O M I C _ H A S H _ L 1 _ S H I F T
slt_ u r23 , r0 , r23
/ *
* Ensure t h a t t h e T L B i s l o a d e d b e f o r e w e t a k e o u t t h e l o c k .
* On T I L E P r o , t h i s w i l l s t a r t f e t c h i n g t h e v a l u e a l l t h e w a y
* into o u r L 1 a s w e l l ( a n d i f i t g e t s m o d i f i e d b e f o r e w e
* grab t h e l o c k , i t w i l l b e i n v a l i d a t e d f r o m o u r c a c h e
* before w e r e l o a d i t ) . O n t i l e 6 4 , w e ' l l s t a r t f e t c h i n g i t
* into o u r L 1 i f w e ' r e t h e h o m e , a n d i f w e ' r e n o t , w e ' l l
* still a t l e a s t s t a r t f e t c h i n g i t i n t o t h e h o m e ' s L 2 .
* /
lw r26 , r0
}
{
s2 a r21 , r20 , r21
bbns r23 , . L c m p x c h g _ b a d a d d r
}
{
lw r21 , r21
seqi r23 , T R E G _ S Y S C A L L _ N R _ N A M E , _ _ N R _ F A S T _ c m p x c h g 6 4
andi r25 , r25 , A T O M I C _ H A S H _ L 2 _ S I Z E - 1
}
{
/* Branch away at this point if we're doing a 64-bit cmpxchg. */
bbs r23 , . L c m p x c h g 6 4
andi r23 , r0 , 7 / * P r e c o m p u t e a l i g n m e n t f o r c m p x c h g 6 4 . * /
}
{
/ *
* We v e r y c a r e f u l l y a l i g n t h e c o d e t h a t a c t u a l l y r u n s w i t h
* the l o c k h e l d ( n i n e b u n d l e s ) s o t h a t w e k n o w i t i s a l l i n
* the i c a c h e w h e n w e s t a r t . T h i s i n s t r u c t i o n ( t h e j u m p ) i s
* at t h e s t a r t o f t h e f i r s t c a c h e l i n e , a d d r e s s z e r o m o d 6 4 ;
* we j u m p t o s o m e w h e r e i n t h e s e c o n d c a c h e l i n e t o i s s u e t h e
* tns, t h e n j u m p b a c k t o f i n i s h u p .
* /
s2 a A T O M I C _ L O C K _ R E G _ N A M E , r25 , r21
j . L c m p x c h g 3 2 _ t n s
}
# else / * A T O M I C _ L O C K S _ F O U N D _ V I A _ T A B L E ( ) * /
{
/* Check for unaligned input. */
bnz s p , . L c m p x c h g _ b a d a d d r
auli r23 , z e r o , h i 1 6 ( P A G E _ O F F S E T ) / * h u g e p a g e - a l i g n e d * /
}
{
/ *
* Slide b i t s i n t o p o s i t i o n f o r ' m m ' . W e w a n t t o i g n o r e
* the l o w 3 b i t s o f r0 , a n d c o n s i d e r o n l y t h e n e x t
* ATOMIC_ H A S H _ S H I F T b i t s .
* Because o f C p o i n t e r a r i t h m e t i c , w e w a n t t o c o m p u t e t h i s :
*
* ( ( char* ) a t o m i c _ l o c k s +
* ( ( ( r0 > > 3 ) & ( 1 < < ( A T O M I C _ H A S H _ S I Z E - 1 ) ) ) < < 2 ) )
*
* Instead o f t w o s h i f t s w e j u s t " > > 1 " , a n d u s e ' m m '
* to i g n o r e t h e l o w a n d h i g h b i t s w e d o n ' t w a n t .
* /
shri r25 , r0 , 1
slt_ u r23 , r0 , r23
/ *
* Ensure t h a t t h e T L B i s l o a d e d b e f o r e w e t a k e o u t t h e l o c k .
* On t i l e p r o , t h i s w i l l s t a r t f e t c h i n g t h e v a l u e a l l t h e w a y
* into o u r L 1 a s w e l l ( a n d i f i t g e t s m o d i f i e d b e f o r e w e
* grab t h e l o c k , i t w i l l b e i n v a l i d a t e d f r o m o u r c a c h e
* before w e r e l o a d i t ) . O n t i l e 6 4 , w e ' l l s t a r t f e t c h i n g i t
* into o u r L 1 i f w e ' r e t h e h o m e , a n d i f w e ' r e n o t , w e ' l l
* still a t l e a s t s t a r t f e t c h i n g i t i n t o t h e h o m e ' s L 2 .
* /
lw r26 , r0
}
{
/* atomic_locks is page aligned so this suffices to get its addr. */
auli r21 , z e r o , h i 1 6 ( a t o m i c _ l o c k s )
bbns r23 , . L c m p x c h g _ b a d a d d r
}
{
/ *
* Insert t h e h a s h b i t s i n t o t h e p a g e - a l i g n e d p o i n t e r .
* ATOMIC_ H A S H _ S H I F T i s s o b i g t h a t w e d o n ' t a c t u a l l y h a s h
* the u n m a s k e d a d d r e s s b i t s , a s t h a t m a y c a u s e u n n e c e s s a r y
* collisions.
* /
mm A T O M I C _ L O C K _ R E G _ N A M E , r25 , r21 , 2 , ( A T O M I C _ H A S H _ S H I F T + 2 ) - 1
seqi r23 , T R E G _ S Y S C A L L _ N R _ N A M E , _ _ N R _ F A S T _ c m p x c h g 6 4
}
{
/* Branch away at this point if we're doing a 64-bit cmpxchg. */
bbs r23 , . L c m p x c h g 6 4
andi r23 , r0 , 7 / * P r e c o m p u t e a l i g n m e n t f o r c m p x c h g 6 4 . * /
}
{
/ *
* We v e r y c a r e f u l l y a l i g n t h e c o d e t h a t a c t u a l l y r u n s w i t h
* the l o c k h e l d ( n i n e b u n d l e s ) s o t h a t w e k n o w i t i s a l l i n
* the i c a c h e w h e n w e s t a r t . T h i s i n s t r u c t i o n ( t h e j u m p ) i s
* at t h e s t a r t o f t h e f i r s t c a c h e l i n e , a d d r e s s z e r o m o d 6 4 ;
* we j u m p t o s o m e w h e r e i n t h e s e c o n d c a c h e l i n e t o i s s u e t h e
* tns, t h e n j u m p b a c k t o f i n i s h u p .
* /
j . L c m p x c h g 3 2 _ t n s
}
# endif / * A T O M I C _ L O C K S _ F O U N D _ V I A _ T A B L E ( ) * /
ENTRY( _ _ s y s _ c m p x c h g _ g r a b _ l o c k )
/ *
* Perform t h e a c t u a l c m p x c h g o r a t o m i c _ u p d a t e .
* Note t h a t _ _ f u t e x _ m a r k _ u n l o c k e d ( ) i n u C l i b c r e l i e s o n
* atomic_ u p d a t e ( ) t o a l w a y s p e r f o r m a n " m f " , s o d o n ' t m a k e
* it o p t i o n a l o r c o n d i t i o n a l w i t h o u t m o d i f y i n g t h a t c o d e .
* /
.Ldo_cmpxchg32 :
{
lw r21 , r0
seqi r23 , T R E G _ S Y S C A L L _ N R _ N A M E , _ _ N R _ F A S T _ a t o m i c _ u p d a t e
move r24 , r2
}
{
seq r22 , r21 , r1 / * S e e i f c m p x c h g m a t c h e s . * /
and r25 , r21 , r1 / * I f a t o m i c _ u p d a t e , c o m p u t e ( * m e m & m a s k ) * /
}
{
or r22 , r22 , r23 / * S k i p c o m p a r e b r a n c h f o r a t o m i c _ u p d a t e . * /
add r25 , r25 , r2 / * C o m p u t e ( * m e m & m a s k ) + a d d e n d . * /
}
{
mvnz r24 , r23 , r25 / * U s e a t o m i c _ u p d a t e v a l u e i f a p p r o p r i a t e . * /
bbns r22 , . L c m p x c h g 3 2 _ m i s m a t c h
}
sw r0 , r24
/* Do slow mtspr here so the following "mf" waits less. */
{
move s p , r27
2010-10-14 16:23:03 -04:00
mtspr S P R _ E X _ C O N T E X T _ K _ 0 , r28
2010-05-28 23:09:12 -04:00
}
mf
/* The following instruction is the start of the second cache line. */
{
move r0 , r21
sw A T O M I C _ L O C K _ R E G _ N A M E , z e r o
}
iret
/* Duplicated code here in the case where we don't overlap "mf" */
.Lcmpxchg32_mismatch :
{
move r0 , r21
sw A T O M I C _ L O C K _ R E G _ N A M E , z e r o
}
{
move s p , r27
2010-10-14 16:23:03 -04:00
mtspr S P R _ E X _ C O N T E X T _ K _ 0 , r28
2010-05-28 23:09:12 -04:00
}
iret
/ *
* The l o c k i n g c o d e i s t h e s a m e f o r 3 2 - b i t c m p x c h g / a t o m i c _ u p d a t e ,
* and f o r 6 4 - b i t c m p x c h g . W e p r o v i d e i t a s a m a c r o a n d p u t
* it i n t o b o t h v e r s i o n s . W e c a n ' t s h a r e t h e c o d e l i t e r a l l y
* since i t d e p e n d s o n h a v i n g t h e r i g h t b r a n c h - b a c k a d d r e s s .
* Note t h a t t h e f i r s t f e w i n s t r u c t i o n s s h o u l d s h a r e t h e c a c h e
* line w i t h t h e s e c o n d h a l f o f t h e a c t u a l l o c k e d c o d e .
* /
.macro cmpxchg_ l o c k , b i t w i d t h
/* Lock; if we succeed, jump back up to the read-modify-write. */
# ifdef C O N F I G _ S M P
tns r21 , A T O M I C _ L O C K _ R E G _ N A M E
# else
/ *
* Non- S M P p r e s e r v e s a l l t h e l o c k i n f r a s t r u c t u r e , t o k e e p t h e
* code s i m p l e r f o r t h e i n t e r e s t i n g ( S M P ) c a s e . H o w e v e r , w e d o
* one s m a l l o p t i m i z a t i o n h e r e a n d i n a t o m i c _ a s m . S , w h i c h i s
* to f a k e o u t a c q u i r i n g t h e a c t u a l l o c k i n t h e a t o m i c _ l o c k t a b l e .
* /
movei r21 , 0
# endif
/* Issue the slow SPR here while the tns result is in flight. */
2010-10-14 16:23:03 -04:00
mfspr r28 , S P R _ E X _ C O N T E X T _ K _ 0
2010-05-28 23:09:12 -04:00
{
addi r28 , r28 , 8 / * r e t u r n t o t h e i n s t r u c t i o n a f t e r t h e s w i n t 1 * /
bzt r21 , . L d o _ c m p x c h g \ b i t w i d t h
}
/ *
* The p r e c e d i n g i n s t r u c t i o n i s t h e l a s t t h i n g t h a t m u s t b e
* on t h e s e c o n d c a c h e l i n e .
* /
# ifdef C O N F I G _ S M P
/ *
* We f a i l e d t o a c q u i r e t h e t n s l o c k o n o u r f i r s t t r y . N o w u s e
* bounded e x p o n e n t i a l b a c k o f f t o r e t r y , l i k e _ _ a t o m i c _ s p i n l o c k ( ) .
* /
{
moveli r23 , 2 0 4 8 / * m a x i m u m b a c k o f f t i m e i n c y c l e s * /
moveli r25 , 3 2 / * s t a r t i n g b a c k o f f t i m e i n c y c l e s * /
}
1 : mfspr r26 , C Y C L E _ L O W / * g e t s t a r t p o i n t f o r t h i s b a c k o f f * /
2 : mfspr r22 , C Y C L E _ L O W / * t e s t t o s e e i f w e ' v e b a c k e d o f f e n o u g h * /
sub r22 , r22 , r26
slt r22 , r22 , r25
bbst r22 , 2 b
{
shli r25 , r25 , 1 / * d o u b l e t h e b a c k o f f ; retry the tns */
tns r21 , A T O M I C _ L O C K _ R E G _ N A M E
}
slt r26 , r23 , r25 / * i s t h e p r o p o s e d b a c k o f f t o o b i g ? * /
{
mvnz r25 , r26 , r23
bzt r21 , . L d o _ c m p x c h g \ b i t w i d t h
}
j 1 b
# endif / * C O N F I G _ S M P * /
.endm
.Lcmpxchg32_tns :
cmpxchg_ l o c k 3 2
/ *
* This c o d e i s i n v o k e d f r o m s y s _ c m p x c h g a f t e r m o s t o f t h e
* preconditions h a v e b e e n c h e c k e d . W e s t i l l n e e d t o c h e c k
* that r0 i s 8 - b y t e a l i g n e d , s i n c e i f i t ' s n o t w e w o n ' t
* actually b e a t o m i c . H o w e v e r , A T O M I C _ L O C K _ R E G h a s t h e a t o m i c
* lock p o i n t e r a n d r27 / r28 h a v e t h e s a v e d S P / P C .
* r2 3 i s h o l d i n g " r0 & 7 " s o w e c a n t e s t f o r a l i g n m e n t .
* The c o m p a r e v a l u e i s i n r2 / r3 ; the new value is in r4/r5.
* On r e t u r n , w e m u s t p u t t h e o l d v a l u e i n r0 / r1 .
* /
.align 64
.Lcmpxchg64 :
{
# if A T O M I C _ L O C K S _ F O U N D _ V I A _ T A B L E ( )
s2 a A T O M I C _ L O C K _ R E G _ N A M E , r25 , r21
# endif
bzt r23 , . L c m p x c h g 6 4 _ t n s
}
j . L c m p x c h g _ b a d a d d r
.Ldo_cmpxchg64 :
{
lw r21 , r0
addi r25 , r0 , 4
}
{
lw r1 , r25
}
seq r26 , r21 , r2
{
bz r26 , . L c m p x c h g 6 4 _ m i s m a t c h
seq r26 , r1 , r3
}
{
bz r26 , . L c m p x c h g 6 4 _ m i s m a t c h
}
sw r0 , r4
sw r25 , r5
/ *
* The 3 2 - b i t p a t h p r o v i d e s o p t i m i z e d " m a t c h " a n d " m i s m a t c h "
* iret p a t h s , b u t w e d o n ' t h a v e e n o u g h b u n d l e s i n t h i s c a c h e l i n e
* to d o t h a t , s o w e j u s t m a k e e v e n t h e " m i s m a t c h " p a t h d o a n " m f " .
* /
.Lcmpxchg64_mismatch :
{
move s p , r27
2010-10-14 16:23:03 -04:00
mtspr S P R _ E X _ C O N T E X T _ K _ 0 , r28
2010-05-28 23:09:12 -04:00
}
mf
{
move r0 , r21
sw A T O M I C _ L O C K _ R E G _ N A M E , z e r o
}
iret
.Lcmpxchg64_tns :
cmpxchg_ l o c k 6 4
/ *
* Reset s p a n d r e v e c t o r t o s y s _ c m p x c h g _ b a d a d d r ( ) , w h i c h w i l l
* just r a i s e t h e a p p r o p r i a t e s i g n a l a n d e x i t . D o i n g i t t h i s
* way m e a n s w e d o n ' t h a v e t o d u p l i c a t e t h e c o d e i n i n t v e c . S ' s
* int_ h a n d m a c r o t h a t l o c a t e s t h e t o p o f t h e s t a c k .
* /
.Lcmpxchg_badaddr :
{
moveli T R E G _ S Y S C A L L _ N R _ N A M E , _ _ N R _ c m p x c h g _ b a d a d d r
move s p , r27
}
j i n t v e c _ S W I N T _ 1
ENDPROC( s y s _ c m p x c h g )
ENTRY( _ _ s y s _ c m p x c h g _ e n d )
/* The single-step support may need to read all the registers. */
int_unalign :
push_ e x t r a _ c a l l e e _ s a v e s r0
j d o _ t r a p
/* Include .intrpt1 array of interrupt vectors */
.section " .intrpt1 " , " ax"
# define o p _ h a n d l e _ p e r f _ i n t e r r u p t b a d _ i n t r
# define o p _ h a n d l e _ a u x _ p e r f _ i n t e r r u p t b a d _ i n t r
arch/tile: Add driver to enable access to the user dynamic network.
This network (the "UDN") connects all the cpus on the chip in a
wormhole-routed dynamic network. Subrectangles of the chip can
be allocated by a "create" ioctl on /dev/hardwall, and then to access the
UDN in that rectangle, tasks must perform an "activate" ioctl on that
same file object after affinitizing themselves to a single cpu in
the region. Sending a wormhole-routed message that tries to leave
that subrectangle causes all activated tasks to receive a SIGILL
(just as they would if they tried to access the UDN without first
activating themselves to a hardwall rectangle).
The original submission of this code to LKML had the driver
instantiated under /proc/tile/hardwall. Now we just use a character
device for this, conventionally /dev/hardwall. Some futures planning
for the TILE-Gx chip suggests that we may want to have other types of
devices that share the general model of "bind a task to a cpu, then
'activate' a file descriptor on a pseudo-device that gives access to
some hardware resource". As such, we are using a device rather
than, for example, a syscall, to set up and activate this code.
As part of this change, the compat_ptr() declaration was fixed and used
to pass the compat_ioctl argument to the normal ioctl. So far we limit
compat code to 2GB, so the difference between zero-extend and sign-extend
(the latter being correct, eventually) had been overlooked.
Signed-off-by: Chris Metcalf <cmetcalf@tilera.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
2010-06-25 17:00:56 -04:00
# ifndef C O N F I G _ H A R D W A L L
2010-05-28 23:09:12 -04:00
# define d o _ h a r d w a l l _ t r a p b a d _ i n t r
arch/tile: Add driver to enable access to the user dynamic network.
This network (the "UDN") connects all the cpus on the chip in a
wormhole-routed dynamic network. Subrectangles of the chip can
be allocated by a "create" ioctl on /dev/hardwall, and then to access the
UDN in that rectangle, tasks must perform an "activate" ioctl on that
same file object after affinitizing themselves to a single cpu in
the region. Sending a wormhole-routed message that tries to leave
that subrectangle causes all activated tasks to receive a SIGILL
(just as they would if they tried to access the UDN without first
activating themselves to a hardwall rectangle).
The original submission of this code to LKML had the driver
instantiated under /proc/tile/hardwall. Now we just use a character
device for this, conventionally /dev/hardwall. Some futures planning
for the TILE-Gx chip suggests that we may want to have other types of
devices that share the general model of "bind a task to a cpu, then
'activate' a file descriptor on a pseudo-device that gives access to
some hardware resource". As such, we are using a device rather
than, for example, a syscall, to set up and activate this code.
As part of this change, the compat_ptr() declaration was fixed and used
to pass the compat_ioctl argument to the normal ioctl. So far we limit
compat code to 2GB, so the difference between zero-extend and sign-extend
(the latter being correct, eventually) had been overlooked.
Signed-off-by: Chris Metcalf <cmetcalf@tilera.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
2010-06-25 17:00:56 -04:00
# endif
2010-05-28 23:09:12 -04:00
int_ h a n d I N T _ I T L B _ M I S S , I T L B _ M I S S , \
do_ p a g e _ f a u l t , h a n d l e _ i n t e r r u p t _ n o _ s i n g l e _ s t e p
int_ h a n d I N T _ M E M _ E R R O R , M E M _ E R R O R , b a d _ i n t r
int_ h a n d I N T _ I L L , I L L , d o _ t r a p , h a n d l e _ i l l
int_ h a n d I N T _ G P V , G P V , d o _ t r a p
int_ h a n d I N T _ S N _ A C C E S S , S N _ A C C E S S , d o _ t r a p
int_ h a n d I N T _ I D N _ A C C E S S , I D N _ A C C E S S , d o _ t r a p
int_ h a n d I N T _ U D N _ A C C E S S , U D N _ A C C E S S , d o _ t r a p
int_ h a n d I N T _ I D N _ R E F I L L , I D N _ R E F I L L , b a d _ i n t r
int_ h a n d I N T _ U D N _ R E F I L L , U D N _ R E F I L L , b a d _ i n t r
int_ h a n d I N T _ I D N _ C O M P L E T E , I D N _ C O M P L E T E , b a d _ i n t r
int_ h a n d I N T _ U D N _ C O M P L E T E , U D N _ C O M P L E T E , b a d _ i n t r
int_ h a n d I N T _ S W I N T _ 3 , S W I N T _ 3 , d o _ t r a p
int_ h a n d I N T _ S W I N T _ 2 , S W I N T _ 2 , d o _ t r a p
int_ h a n d I N T _ S W I N T _ 1 , S W I N T _ 1 , S Y S C A L L , h a n d l e _ s y s c a l l
int_ h a n d I N T _ S W I N T _ 0 , S W I N T _ 0 , d o _ t r a p
int_ h a n d I N T _ U N A L I G N _ D A T A , U N A L I G N _ D A T A , i n t _ u n a l i g n
int_ h a n d I N T _ D T L B _ M I S S , D T L B _ M I S S , d o _ p a g e _ f a u l t
int_ h a n d I N T _ D T L B _ A C C E S S , D T L B _ A C C E S S , d o _ p a g e _ f a u l t
int_ h a n d I N T _ D M A T L B _ M I S S , D M A T L B _ M I S S , d o _ p a g e _ f a u l t
int_ h a n d I N T _ D M A T L B _ A C C E S S , D M A T L B _ A C C E S S , d o _ p a g e _ f a u l t
int_ h a n d I N T _ S N I T L B _ M I S S , S N I T L B _ M I S S , d o _ p a g e _ f a u l t
int_ h a n d I N T _ S N _ N O T I F Y , S N _ N O T I F Y , b a d _ i n t r
int_ h a n d I N T _ S N _ F I R E W A L L , S N _ F I R E W A L L , d o _ h a r d w a l l _ t r a p
int_ h a n d I N T _ I D N _ F I R E W A L L , I D N _ F I R E W A L L , b a d _ i n t r
int_ h a n d I N T _ U D N _ F I R E W A L L , U D N _ F I R E W A L L , d o _ h a r d w a l l _ t r a p
int_ h a n d I N T _ T I L E _ T I M E R , T I L E _ T I M E R , d o _ t i m e r _ i n t e r r u p t
int_ h a n d I N T _ I D N _ T I M E R , I D N _ T I M E R , b a d _ i n t r
int_ h a n d I N T _ U D N _ T I M E R , U D N _ T I M E R , b a d _ i n t r
int_ h a n d I N T _ D M A _ N O T I F Y , D M A _ N O T I F Y , b a d _ i n t r
int_ h a n d I N T _ I D N _ C A , I D N _ C A , b a d _ i n t r
int_ h a n d I N T _ U D N _ C A , U D N _ C A , b a d _ i n t r
int_ h a n d I N T _ I D N _ A V A I L , I D N _ A V A I L , b a d _ i n t r
int_ h a n d I N T _ U D N _ A V A I L , U D N _ A V A I L , b a d _ i n t r
int_ h a n d I N T _ P E R F _ C O U N T , P E R F _ C O U N T , \
op_ h a n d l e _ p e r f _ i n t e r r u p t , h a n d l e _ n m i
int_ h a n d I N T _ I N T C T R L _ 3 , I N T C T R L _ 3 , b a d _ i n t r
2010-10-14 16:23:03 -04:00
# if C O N F I G _ K E R N E L _ P L = = 2
dc_ d i s p a t c h I N T _ I N T C T R L _ 2 , I N T C T R L _ 2
int_ h a n d I N T _ I N T C T R L _ 1 , I N T C T R L _ 1 , b a d _ i n t r
# else
2010-05-28 23:09:12 -04:00
int_ h a n d I N T _ I N T C T R L _ 2 , I N T C T R L _ 2 , b a d _ i n t r
dc_ d i s p a t c h I N T _ I N T C T R L _ 1 , I N T C T R L _ 1
2010-10-14 16:23:03 -04:00
# endif
2010-05-28 23:09:12 -04:00
int_ h a n d I N T _ I N T C T R L _ 0 , I N T C T R L _ 0 , b a d _ i n t r
int_ h a n d I N T _ M E S S A G E _ R C V _ D W N C L , M E S S A G E _ R C V _ D W N C L , \
hv_ m e s s a g e _ i n t r , h a n d l e _ i n t e r r u p t _ d o w n c a l l
int_ h a n d I N T _ D E V _ I N T R _ D W N C L , D E V _ I N T R _ D W N C L , \
tile_ d e v _ i n t r , h a n d l e _ i n t e r r u p t _ d o w n c a l l
int_ h a n d I N T _ I _ A S I D , I _ A S I D , b a d _ i n t r
int_ h a n d I N T _ D _ A S I D , D _ A S I D , b a d _ i n t r
int_ h a n d I N T _ D M A T L B _ M I S S _ D W N C L , D M A T L B _ M I S S _ D W N C L , \
do_ p a g e _ f a u l t , h a n d l e _ i n t e r r u p t _ d o w n c a l l
int_ h a n d I N T _ S N I T L B _ M I S S _ D W N C L , S N I T L B _ M I S S _ D W N C L , \
do_ p a g e _ f a u l t , h a n d l e _ i n t e r r u p t _ d o w n c a l l
int_ h a n d I N T _ D M A T L B _ A C C E S S _ D W N C L , D M A T L B _ A C C E S S _ D W N C L , \
do_ p a g e _ f a u l t , h a n d l e _ i n t e r r u p t _ d o w n c a l l
int_ h a n d I N T _ S N _ C P L , S N _ C P L , b a d _ i n t r
int_ h a n d I N T _ D O U B L E _ F A U L T , D O U B L E _ F A U L T , d o _ t r a p
# if C H I P _ H A S _ A U X _ P E R F _ C O U N T E R S ( )
int_ h a n d I N T _ A U X _ P E R F _ C O U N T , A U X _ P E R F _ C O U N T , \
op_ h a n d l e _ a u x _ p e r f _ i n t e r r u p t , h a n d l e _ n m i
# endif
/* Synthetic interrupt delivered only by the simulator */
int_ h a n d I N T _ B R E A K P O I N T , B R E A K P O I N T , d o _ b r e a k p o i n t