2008-05-19 16:53:02 -07:00
/ *
2005-04-16 15:20:36 -07:00
* wof. S : S p a r c w i n d o w o v e r f l o w h a n d l e r .
*
* Copyright ( C ) 1 9 9 5 D a v i d S . M i l l e r ( d a v e m @caip.rutgers.edu)
* /
# include < a s m / c o n t r e g s . h >
# include < a s m / p a g e . h >
# include < a s m / p t r a c e . h >
# include < a s m / p s r . h >
# include < a s m / s m p . h >
# include < a s m / a s i . h >
# include < a s m / w i n m a c r o . 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 >
/ * WARNING : This r o u t i n e i s h a i r y a n d _ v e r y _ c o m p l i c a t e d , b u t i t
* must b e a s f a s t a s p o s s i b l e a s i t h a n d l e s t h e a l l o c a t i o n
* of r e g i s t e r w i n d o w s t o t h e u s e r a n d k e r n e l . I f y o u t o u c h
* this c o d e b e _ v e r y _ c a r e f u l a s m a n y o t h e r p i e c e s o f t h e
* kernel d e p e n d u p o n h o w t h i s c o d e b e h a v e s . Y o u h a v e b e e n
* duly w a r n e d . . .
* /
/ * We d e f i n e m a c r o ' s f o r r e g i s t e r s w h i c h h a v e a f i x e d
* meaning t h r o u g h o u t t h i s e n t i r e r o u t i n e . T h e ' T ' i n
* the c o m m e n t s m e a n t h a t t h e r e g i s t e r c a n o n l y b e
* accessed w h e n i n t h e ' t r a p ' w i n d o w , ' G ' m e a n s
* accessible i n a n y w i n d o w . D o n o t c h a n g e t h e s e r e g i s t e r s
* after t h e y h a v e b e e n s e t , u n t i l y o u a r e r e a d y t o r e t u r n
* from t h e t r a p .
* /
# define t _ p s r l 0 / * % p s r a t t r a p t i m e T * /
# define t _ p c l 1 / * P C f o r t r a p r e t u r n T * /
# define t _ n p c l 2 / * N P C f o r t r a p r e t u r n T * /
# define t _ w i m l 3 / * % w i m a t t r a p t i m e T * /
# define s a v e d _ g 5 l 5 / * G l o b a l s a v e r e g i s t e r T * /
# define s a v e d _ g 6 l 6 / * G l o b a l s a v e r e g i s t e r T * /
# define c u r p t r g 6 / * G e t s s e t t o ' c u r r e n t ' t h e n s t a y s G * /
/* Now registers whose values can change within the handler. */
# define t w i n _ t m p l 4 / * T e m p r e g , o n l y u s a b l e i n t r a p w i n d o w T * /
# define g l o b _ t m p g 5 / * G l o b a l t e m p o r a r y r e g , u s a b l e a n y w h e r e G * /
.text
.align 4
/* BEGINNING OF PATCH INSTRUCTIONS */
/ * On a 7 - w i n d o w S p a r c t h e b o o t c o d e p a t c h e s s p n w i n _ *
* instructions w i t h t h e f o l l o w i n g o n e s .
* /
.globl spnwin_ p a t c h1 _ 7 w i n , s p n w i n _ p a t c h2 _ 7 w i n , s p n w i n _ p a t c h3 _ 7 w i n
spnwin_patch1_7win : sll % t _ w i m , 6 , % g l o b _ t m p
spnwin_patch2_7win : and % g l o b _ t m p , 0 x7 f , % g l o b _ t m p
spnwin_patch3_7win : and % t w i n _ t m p , 0 x7 f , % t w i n _ t m p
/* END OF PATCH INSTRUCTIONS */
/ * The t r a p e n t r y p o i n t h a s d o n e t h e f o l l o w i n g :
*
* rd % p s r , % l 0
* rd % w i m , % l 3
* b s p i l l _ w i n d o w _ e n t r y
* andcc % l 0 , P S R _ P S , % g 0
* /
/ * Datum c u r r e n t _ t h r e a d _ i n f o - > u w i n m a s k c o n t a i n s a t a l l t i m e s a b i t m a s k
* where i f a n y u s e r w i n d o w s a r e a c t i v e , a t l e a s t o n e b i t w i l l
* be s e t i n t o m a s k . I f n o u s e r w i n d o w s a r e a c t i v e , t h e b i t m a s k
* will b e a l l z e r o e s .
* /
.globl spill_window_entry
.globl spnwin_ p a t c h1 , s p n w i n _ p a t c h2 , s p n w i n _ p a t c h3
spill_window_entry :
/* LOCATION: Trap Window */
mov % g 5 , % s a v e d _ g 5 ! s a v e a w a y g l o b a l t e m p r e g i s t e r
mov % g 6 , % s a v e d _ g 6 ! s a v e a w a y ' c u r r e n t ' p t r r e g i s t e r
/ * Compute w h a t t h e n e w % w i m w i l l b e i f w e s a v e t h e
* window p r o p e r l y i n t h i s t r a p h a n d l e r .
*
* newwim = ( ( % w i m > > 1 ) | ( % w i m < < ( n w i n d o w s - 1 ) ) ) ;
* /
srl % t _ w i m , 0 x1 , % t w i n _ t m p
spnwin_patch1 : sll % t _ w i m , 7 , % g l o b _ t m p
or % g l o b _ t m p , % t w i n _ t m p , % g l o b _ t m p
spnwin_patch2 : and % g l o b _ t m p , 0 x f f , % g l o b _ t m p
/ * The t r a p e n t r y p o i n t h a s s e t t h e c o n d i t i o n c o d e s
* up f o r u s t o s e e i f t h i s i s f r o m u s e r o r k e r n e l .
* Get t h e l o a d o f ' c u r p t r ' o u t o f t h e w a y .
* /
LOAD_ C U R R E N T ( c u r p t r , t w i n _ t m p )
andcc % t _ p s r , P S R _ P S , % g 0
be,a s p w i n _ f r o m u s e r ! a l l u s e r w i n s , b r a n c h
save % g 0 , % g 0 , % g 0 ! G o w h e r e s a v i n g w i l l o c c u r
/* See if any user windows are active in the set. */
ld [ % c u r p t r + T I _ U W I N M A S K ] , % t w i n _ t m p ! g r a b w i n m a s k
orcc % g 0 , % t w i n _ t m p , % g 0 ! c h e c k f o r s e t b i t s
bne s p w i n _ e x i s t _ u w i n s ! y e p , t h e r e a r e s o m e
andn % t w i n _ t m p , % g l o b _ t m p , % t w i n _ t m p ! c o m p u t e n e w u w i n m a s k
/ * Save i n t o t h e w i n d o w w h i c h m u s t b e s a v e d a n d d o i t .
* Basically i f w e a r e h e r e , t h i s m e a n s t h a t w e t r a p p e d
* from k e r n e l m o d e w i t h o n l y k e r n e l w i n d o w s i n t h e r e g i s t e r
* file.
* /
save % g 0 , % g 0 , % g 0 ! s a v e i n t o t h e w i n d o w t o s t a s h a w a y
wr % g l o b _ t m p , 0 x0 , % w i m ! s e t n e w % w i m , t h i s i s s a f e n o w
spwin_no_userwins_from_kernel :
/* LOCATION: Window to be saved */
STORE_ W I N D O W ( s p ) ! s t a s h t h e w i n d o w
restore % g 0 , % g 0 , % g 0 ! g o b a c k i n t o t r a p w i n d o w
/* LOCATION: Trap window */
mov % s a v e d _ g 5 , % g 5 ! r e s t o r e % g l o b _ t m p
mov % s a v e d _ g 6 , % g 6 ! r e s t o r e % c u r p t r
wr % t _ p s r , 0 x0 , % p s r ! r e s t o r e c o n d i t i o n c o d e s i n % p s r
WRITE_ P A U S E ! w a s t e s o m e t i m e
jmp % t _ p c ! R e t u r n f r o m t r a p
rett % t _ n p c ! w e a r e d o n e
spwin_exist_uwins :
/* LOCATION: Trap window */
/ * Wow, u s e r w i n d o w s h a v e t o b e d e a l t w i t h , t h i s i s d i r t y
* and m e s s y a s a l l h e l l . A n d d i f f i c u l t t o f o l l o w i f y o u
* are a p p r o a c h i n g t h e i n f a m o u s r e g i s t e r w i n d o w t r a p h a n d l i n g
* problem f o r t h e f i r s t t i m e . D O N ' T L O O K !
*
* Note t h a t h o w t h e e x e c u t i o n p a t h w o r k s o u t , t h e n e w % w i m
* will b e l e f t f o r u s i n t h e g l o b a l t e m p o r a r y r e g i s t e r ,
* % glob_ t m p . W e c a n n o t s e t t h e n e w % w i m f i r s t b e c a u s e w e
* need t o s a v e i n t o t h e a p p r o p r i a t e w i n d o w w i t h o u t i n d u c i n g
* a t r a p ( t r a p s a r e o f f , w e ' d g e t a w a t c h d o g w h e e e ) . . .
* But f i r s t , s t o r e t h e n e w u s e r w i n d o w m a s k c a l c u l a t e d
* above.
* /
st % t w i n _ t m p , [ % c u r p t r + T I _ U W I N M A S K ]
save % g 0 , % g 0 , % g 0 ! G o t o w h e r e t h e s a v i n g w i l l o c c u r
spwin_fromuser :
/* LOCATION: Window to be saved */
wr % g l o b _ t m p , 0 x0 , % w i m ! N o w i t i s s a f e t o s e t n e w % w i m
/* LOCATION: Window to be saved */
/ * This i n s t r u c t i o n b r a n c h e s t o a r o u t i n e w h i c h w i l l c h e c k
* to v a l i d i t y o f t h e u s e r s s t a c k p o i n t e r b y w h a t e v e r m e a n s
* are n e c e s s a r y . T h i s m e a n s t h a t t h i s i s a r c h i t e c t u r e
* specific a n d t h u s t h i s b r a n c h i n s t r u c t i o n w i l l n e e d t o
* be p a t c h e d a t b o o t t i m e o n c e t h e m a c h i n e t y p e i s k n o w n .
* This r o u t i n e _ s h a l l n o t _ t o u c h % c u r p t r u n d e r a n y
* circumstances w h a t s o e v e r ! I t w i l l b r a n c h b a c k t o t h e
* label ' s p w i n _ g o o d _ u s t a c k ' i f t h e s t a c k i s o k b u t s t i l l
* needs t o b e d u m p e d ( S R M M U f o r i n s t a n c e w i l l n o t n e e d t o
* do t h i s ) o r ' s p w i n _ f i n i s h _ u p ' i f t h e s t a c k i s o k a n d t h e
* registers h a v e a l r e a d y b e e n s a v e d . I f t h e s t a c k i s f o u n d
* to b e b o g u s f o r s o m e r e a s o n t h e r o u t i n e s h a l l b r a n c h t o
* the l a b e l ' s p w i n _ u s e r _ s t a c k _ i s _ b o l i x e d ' w h i c h w i l l t a k e
* care o f t h i n g s a t t h a t p o i n t .
* /
2012-05-11 11:35:11 +00:00
b s p w i n _ s r m m u _ s t a c k c h k
andcc % s p , 0 x7 , % g 0
2005-04-16 15:20:36 -07:00
spwin_good_ustack :
/* LOCATION: Window to be saved */
/ * The u s e r s s t a c k i s o k a n d w e c a n s a f e l y s a v e i t a t
* % sp.
* /
STORE_ W I N D O W ( s p )
spwin_finish_up :
restore % g 0 , % g 0 , % g 0 / * B a c k t o t r a p w i n d o w . * /
/* LOCATION: Trap window */
/ * We h a v e s p i l l e d s u c c e s s f u l l y , a n d w e h a v e p r o p e r l y s t o r e d
* the a p p r o p r i a t e w i n d o w o n t o t h e s t a c k .
* /
/* Restore saved globals */
mov % s a v e d _ g 5 , % g 5
mov % s a v e d _ g 6 , % g 6
wr % t _ p s r , 0 x0 , % p s r
WRITE_ P A U S E
jmp % t _ p c
rett % t _ n p c
spwin_user_stack_is_bolixed :
/* LOCATION: Window to be saved */
/ * Wheee, u s e r h a s t r a s h e d h i s / h e r s t a c k . W e h a v e t o d e c i d e
* how t o p r o c e e d b a s e d u p o n w h e t h e r w e c a m e f r o m k e r n e l m o d e
* or n o t . I f w e c a m e f r o m k e r n e l m o d e , t o s s t h e w i n d o w i n t o
* a s p e c i a l b u f f e r a n d p r o c e e d , t h e k e r n e l _ n e e d s _ a w i n d o w
* and w e c o u l d b e i n a n i n t e r r u p t h a n d l e r s o t i m i n g i s c r u c i a l .
* If w e c a m e f r o m u s e r l a n d w e b u i l d a f u l l s t a c k f r a m e a n d c a l l
* c- c o d e t o g u n d o w n t h e p r o c e s s .
* /
rd % p s r , % g l o b _ t m p
andcc % g l o b _ t m p , P S R _ P S , % g 0
bne s p w i n _ b a d _ u s t a c k _ f r o m _ k e r n e l
nop
/ * Oh w e l l , t h r o w t h i s o n e w i n d o w i n t o t h e p e r - t a s k w i n d o w
* buffer, t h e f i r s t o n e .
* /
st % s p , [ % c u r p t r + T I _ R W I N _ S P T R S ]
STORE_ W I N D O W ( c u r p t r + T I _ R E G _ W I N D O W )
restore % g 0 , % g 0 , % g 0
/* LOCATION: Trap Window */
/* Back in the trap window, update winbuffer save count. */
mov 1 , % t w i n _ t m p
st % t w i n _ t m p , [ % c u r p t r + T I _ W _ S A V E D ]
/ * Compute n e w u s e r w i n d o w m a s k . W h a t w e a r e b a s i c a l l y
* doing i s t a k i n g t w o w i n d o w s , t h e i n v a l i d o n e a t t r a p
* time a n d t h e o n e w e a t t e m p t e d t o t h r o w o n t o t h e u s e r s
* stack, a n d s a y i n g t h a t e v e r y t h i n g e l s e i s a n o k u s e r
* window. u m a s k = ( ( ~ ( % t _ w i m | % w i m ) ) & v a l i d _ w i m _ b i t s )
* /
rd % w i m , % t w i n _ t m p
or % t w i n _ t m p , % t _ w i m , % t w i n _ t m p
not % t w i n _ t m p
spnwin_patch3 : and % t w i n _ t m p , 0 x f f , % t w i n _ t m p ! p a t c h e d o n 7 w i n S p a r c s
st % t w i n _ t m p , [ % c u r p t r + T I _ U W I N M A S K ]
# define S T A C K _ O F F S E T ( T H R E A D _ S I Z E - T R A C E R E G _ S Z - S T A C K F R A M E _ S Z )
sethi % h i ( S T A C K _ O F F S E T ) , % s p
or % s p , % l o ( S T A C K _ O F F S E T ) , % s p
add % c u r p t r , % s p , % s p
/* Restore the saved globals and build a pt_regs frame. */
mov % s a v e d _ g 5 , % g 5
mov % s a v e d _ g 6 , % g 6
STORE_ P T _ A L L ( s p , t _ p s r , t _ p c , t _ n p c , g 1 )
sethi % h i ( S T A C K _ O F F S E T ) , % g 6
or % g 6 , % l o ( S T A C K _ O F F S E T ) , % g 6
sub % s p , % g 6 , % g 6 ! c u r p t r
/* Turn on traps and call c-code to deal with it. */
wr % t _ p s r , P S R _ E T , % p s r
nop
call w i n d o w _ o v e r f l o w _ f a u l t
nop
/ * Return f r o m t r a p i f C - c o d e a c t u a l l y f i x e s t h i n g s , i f i t
* doesn' t t h e n w e n e v e r g e t t h i s f a r a s t h e p r o c e s s w i l l
* be g i v e n t h e l o o k o f d e a t h f r o m C o m m a n d e r P e a n u t .
* /
b r e t _ t r a p _ e n t r y
clr % l 6
spwin_bad_ustack_from_kernel :
/* LOCATION: Window to be saved */
/ * The k e r n e l p r o v o k e d a s p i l l w i n d o w t r a p , b u t t h e w i n d o w w e
* need t o s a v e i s a u s e r o n e a n d t h e p r o c e s s h a s t r a s h e d i t s
* stack p o i n t e r . W e n e e d t o b e q u i c k , s o w e t h r o w i t i n t o
* a p e r - p r o c e s s w i n d o w b u f f e r u n t i l w e c a n p r o p e r l y h a n d l e
* this l a t e r o n .
* /
SAVE_ B O L I X E D _ U S E R _ S T A C K ( c u r p t r , g l o b _ t m p )
restore % g 0 , % g 0 , % g 0
/* LOCATION: Trap window */
/ * Restore g l o b a l s , c o n d i t i o n c o d e s i n t h e % p s r a n d
* return f r o m t r a p . N o t e , r e s t o r i n g % g 6 w h e n r e t u r n i n g
* to k e r n e l m o d e i s n o t n e c e s s a r i l y t h e s e d a y s . ;-)
* /
mov % s a v e d _ g 5 , % g 5
mov % s a v e d _ g 6 , % g 6
wr % t _ p s r , 0 x0 , % p s r
WRITE_ P A U S E
jmp % t _ p c
rett % t _ n p c
/ * Undefine t h e r e g i s t e r m a c r o s w h i c h w o u l d o n l y c a u s e t r o u b l e
* if u s e d b e l o w . T h i s h e l p s f i n d ' s t u p i d ' c o d i n g e r r o r s t h a t
* produce ' o d d ' b e h a v i o r . T h e r o u t i n e s b e l o w a r e a l l o w e d t o
* make u s a g e o f g l o b _ t m p a n d t _ p s r s o w e l e a v e t h e m d e f i n e d .
* /
# undef t w i n _ t m p
# undef c u r p t r
# undef t _ p c
# undef t _ n p c
# undef t _ w i m
# undef s a v e d _ g 5
# undef s a v e d _ g 6
/ * Now c o m e t h e p e r - a r c h i t e c t u r e w i n d o w o v e r f l o w s t a c k c h e c k i n g r o u t i n e s .
* As n o t e d a b o v e % c u r p t r c a n n o t b e t o u c h e d b y t h i s r o u t i n e a t a l l .
* /
/ * This i s a g e n e r i c S R M M U r o u t i n e . A s f a r a s I k n o w t h i s
* works f o r a l l c u r r e n t v8 / s r m m u i m p l e m e n t a t i o n s , w e ' l l
* see. . .
* /
.globl spwin_srmmu_stackchk
spwin_srmmu_stackchk :
/* LOCATION: Window to be saved on the stack */
/ * Because o f S M P c o n c e r n s a n d s p e e d w e p l a y a t r i c k .
* We d i s a b l e f a u l t t r a p s i n t h e M M U c o n t r o l r e g i s t e r ,
* Execute t h e s t o r e s , t h e n c h e c k t h e f a u l t r e g i s t e r s
* to s e e w h a t h a p p e n s . I c a n h e a r L i n u s n o w
* " disgusting. . . b r o k e n h a r d w a r e . . . " .
*
* But f i r s t , c h e c k t o s e e i f t h e u s e r s s t a c k h a s e n d e d
* up i n k e r n e l v m a , t h e n w e w o u l d s u c c e e d f o r t h e ' w r o n g '
* reason. . . ;( Note that the 'sethi' below assumes the
* kernel i s p a g e a l i g n e d , w h i c h s h o u l d a l w a y s b e t h e c a s e .
* /
/* Check results of callers andcc %sp, 0x7, %g0 */
bne s p w i n _ u s e r _ s t a c k _ i s _ b o l i x e d
sethi % h i ( P A G E _ O F F S E T ) , % g l o b _ t m p
cmp % g l o b _ t m p , % s p
bleu s p w i n _ u s e r _ s t a c k _ i s _ b o l i x e d
mov A C _ M _ S F S R , % g l o b _ t m p
/* Clear the fault status and turn on the no_fault bit. */
2012-05-25 21:20:16 +00:00
LEON_ P I ( l d a [ % g l o b _ t m p ] A S I _ L E O N _ M M U R E G S , % g 0 ) ! e a t S F S R
SUN_ P I _ ( l d a [ % g l o b _ t m p ] A S I _ M _ M M U R E G S , % g 0 ) ! e a t S F S R
2005-04-16 15:20:36 -07:00
2012-05-25 21:20:16 +00:00
LEON_ P I ( l d a [ % g 0 ] A S I _ L E O N _ M M U R E G S , % g l o b _ t m p ) ! r e a d M M U c o n t r o l
SUN_ P I _ ( l d a [ % g 0 ] A S I _ M _ M M U R E G S , % g l o b _ t m p ) ! r e a d M M U c o n t r o l
2005-04-16 15:20:36 -07:00
or % g l o b _ t m p , 0 x2 , % g l o b _ t m p ! o r i n n o _ f a u l t b i t
2012-05-25 21:20:16 +00:00
LEON_ P I ( s t a % g l o b _ t m p , [ % g 0 ] A S I _ L E O N _ M M U R E G S ) ! s e t i t
SUN_ P I _ ( s t a % g l o b _ t m p , [ % g 0 ] A S I _ M _ M M U R E G S ) ! s e t i t
2005-04-16 15:20:36 -07:00
/* Dump the registers and cross fingers. */
STORE_ W I N D O W ( s p )
/* Clear the no_fault bit and check the status. */
andn % g l o b _ t m p , 0 x2 , % g l o b _ t m p
2012-05-25 21:20:16 +00:00
LEON_ P I ( s t a % g l o b _ t m p , [ % g 0 ] A S I _ L E O N _ M M U R E G S )
SUN_ P I _ ( s t a % g l o b _ t m p , [ % g 0 ] A S I _ M _ M M U R E G S )
2005-04-16 15:20:36 -07:00
mov A C _ M _ S F A R , % g l o b _ t m p
2012-05-25 21:20:16 +00:00
LEON_ P I ( l d a [ % g l o b _ t m p ] A S I _ L E O N _ M M U R E G S , % g 0 )
SUN_ P I _ ( l d a [ % g l o b _ t m p ] A S I _ M _ M M U R E G S , % g 0 )
2005-04-16 15:20:36 -07:00
mov A C _ M _ S F S R , % g l o b _ t m p
2012-05-25 21:20:16 +00:00
LEON_ P I ( l d a [ % g l o b _ t m p ] A S I _ L E O N _ M M U R E G S , % g l o b _ t m p )
SUN_ P I _ ( l d a [ % g l o b _ t m p ] A S I _ M _ M M U R E G S , % g l o b _ t m p )
2005-04-16 15:20:36 -07:00
andcc % g l o b _ t m p , 0 x2 , % g 0 ! d i d w e f a u l t ?
be,a s p w i n _ f i n i s h _ u p + 0 x4 ! c o o l b e a n s , s u c c e s s
restore % g 0 , % g 0 , % g 0
rd % p s r , % g l o b _ t m p
b s p w i n _ u s e r _ s t a c k _ i s _ b o l i x e d + 0 x4 ! w e f a u l t e d , u g h
nop