2008-05-19 16:53:02 -07:00
/ *
2005-04-16 15:20:36 -07:00
* wuf. S : W i n d o w u n d e r f l o w t r a p h a n d l e r f o r t h e S p a r c .
*
* Copyright ( C ) 1 9 9 5 D a v i d S . M i l l e r
* /
# 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 >
/ * Just l i k e t h e o v e r f l o w h a n d l e r w e d e f i n e m a c r o s f o r r e g i s t e r s
* with f i x e d m e a n i n g s i n t h i s r o u t i n e .
* /
# define t _ p s r l 0
# define t _ p c l 1
# define t _ n p c l 2
# define t _ w i m l 3
/* Don't touch the above registers or else you die horribly... */
/* Now macros for the available scratch registers in this routine. */
# define t w i n _ t m p1 l 4
# define t w i n _ t m p2 l 5
# define c u r p t r g 6
.text
.align 4
/ * The t r a p e n t r y p o i n t h a s e x e c u t e d 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 f 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 .
* /
/ * To g e t a n i d e a o f w h a t h a s j u s t h a p p e n e d t o c a u s e t h i s
* trap t a k e a l o o k a t t h i s d i a g r a m :
*
* 1 2 3 4 < - - Window n u m b e r
* - - - - - - - - - -
* T O W I < - - S y m b o l i c n a m e
*
* O = = t h e w i n d o w t h a t e x e c u t i o n w a s i n w h e n
* the r e s t o r e w a s a t t e m p t e d
*
* T = = t h e t r a p i t s e l f h a s s a v e ' d u s i n t o t h i s
* window
*
* W = = t h i s w i n d o w i s t h e o n e w h i c h i s n o w i n v a l i d
* and m u s t b e m a d e v a l i d p l u s l o a d e d f r o m t h e
* stack
*
* I = = t h i s w i n d o w w i l l b e t h e i n v a l i d o n e w h e n w e
* are d o n e a n d r e t u r n f r o m t r a p i f s u c c e s s f u l
* /
/* BEGINNING OF PATCH INSTRUCTIONS */
/ * On 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 f n w i n _ p a t c h1
* with t h e f o l l o w i n g i n s t r u c t i o n .
* /
.globl fnwin_ p a t c h1 _ 7 w i n , f n w i n _ p a t c h2 _ 7 w i n
fnwin_patch1_7win : srl % t _ w i m , 6 , % t w i n _ t m p2
fnwin_patch2_7win : and % t w i n _ t m p1 , 0 x7 f , % t w i n _ t m p1
/* END OF PATCH INSTRUCTIONS */
.globl fill_ w i n d o w _ e n t r y , f n w i n _ p a t c h1 , f n w i n _ p a t c h2
fill_window_entry :
/* LOCATION: Window 'T' */
/ * Compute w h a t t h e n e w % w i m i s g o i n g t o b e i f w e r e t r i e v e
* the p r o p e r w i n d o w o f f o f t h e s t a c k .
* /
sll % t _ w i m , 1 , % t w i n _ t m p1
fnwin_patch1 : srl % t _ w i m , 7 , % t w i n _ t m p2
or % t w i n _ t m p1 , % t w i n _ t m p2 , % t w i n _ t m p1
fnwin_patch2 : and % t w i n _ t m p1 , 0 x f f , % t w i n _ t m p1
wr % t w i n _ t m p1 , 0 x0 , % w i m / * M a k e w i n d o w ' I ' i n v a l i d * /
andcc % t _ p s r , P S R _ P S , % g 0
be f w i n _ f r o m _ u s e r
restore % g 0 , % g 0 , % g 0 / * R e s t o r e t o w i n d o w ' O ' * /
/ * Trapped f r o m k e r n e l , w e t r u s t t h a t t h e k e r n e l d o e s n o t
* ' over r e s t o r e ' s o r t a s p e a k a n d j u s t g r a b t h e w i n d o w
* from t h e s t a c k a n d r e t u r n . E a s y e n o u g h .
* /
fwin_from_kernel :
/* LOCATION: Window 'O' */
restore % g 0 , % g 0 , % g 0
/* LOCATION: Window 'W' */
LOAD_ W I N D O W ( s p ) / * L o a d i t u p * /
/* Spin the wheel... */
save % g 0 , % g 0 , % g 0
save % g 0 , % g 0 , % g 0
/* I'd like to buy a vowel please... */
/* LOCATION: Window 'T' */
/ * Now p r e s e r v e t h e c o n d i t i o n c o d e s i n % p s r , p a u s e , a n d
* return f r o m t r a p . T h i s i s t h e s i m p l e s t c a s e o f a l l .
* /
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
fwin_from_user :
/* LOCATION: Window 'O' */
restore % g 0 , % g 0 , % g 0 / * R e s t o r e t o w i n d o w ' W ' * /
/* LOCATION: Window 'W' */
2012-05-11 11:35:10 +00:00
/* Branch to the stack validation routine */
b s r m m u _ f w i n _ s t a c k c h k
andcc % s p , 0 x7 , % g 0
2005-04-16 15:20:36 -07:00
# 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 )
fwin_user_stack_is_bolixed :
/* LOCATION: Window 'W' */
/ * Place a p t _ r e g s f r a m e o n t h e k e r n e l s t a c k , s a v e b a c k
* to t h e t r a p w i n d o w a n d c a l l c - c o d e t o d e a l w i t h t h i s .
* /
LOAD_ C U R R E N T ( l 4 , l 5 )
sethi % h i ( S T A C K _ O F F S E T ) , % l 5
or % l 5 , % l o ( S T A C K _ O F F S E T ) , % l 5
add % l 4 , % l 5 , % l 5
/* Store globals into pt_regs frame. */
STORE_ P T _ G L O B A L S ( l 5 )
STORE_ P T _ Y R E G ( l 5 , g 3 )
/* Save current in a global while we change windows. */
mov % l 4 , % c u r p t r
save % g 0 , % g 0 , % g 0
/* LOCATION: Window 'O' */
rd % p s r , % g 3 / * R e a d % p s r i n l i v e u s e r w i n d o w * /
mov % f p , % g 4 / * S a v e b o g u s f r a m e p o i n t e r . * /
save % g 0 , % g 0 , % g 0
/* LOCATION: Window 'T' */
sethi % h i ( S T A C K _ O F F S E T ) , % l 5
or % l 5 , % l o ( S T A C K _ O F F S E T ) , % l 5
add % c u r p t r , % l 5 , % s p
/* Build rest of pt_regs. */
STORE_ P T _ I N S ( s p )
STORE_ P T _ P R I V ( s p , t _ p s r , t _ p c , t _ n p c )
/* re-set trap time %wim value */
wr % t _ w i m , 0 x0 , % w i m
/* Fix users window mask and buffer save count. */
mov 0 x1 , % g 5
sll % g 5 , % g 3 , % g 5
st % g 5 , [ % c u r p t r + T I _ U W I N M A S K ] ! o n e l i v e u s e r w i n d o w s t i l l
st % g 0 , [ % c u r p t r + T I _ W _ S A V E D ] ! n o w i n d o w s i n t h e b u f f e r
wr % t _ p s r , P S R _ E T , % p s r ! e n a b l e t r a p s
nop
call w i n d o w _ u n d e r f l o w _ f a u l t
mov % g 4 , % o 0
b r e t _ t r a p _ e n t r y
clr % l 6
fwin_user_stack_is_ok :
/* LOCATION: Window 'W' */
/ * The u s e r s s t a c k a r e a i s k o s h e r a n d m a p p e d , l o a d t h e
* window a n d f a l l t h r o u g h t o t h e f i n i s h u p r o u t i n e .
* /
LOAD_ W I N D O W ( s p )
/* Round and round she goes... */
save % g 0 , % g 0 , % g 0 / * S a v e t o w i n d o w ' O ' * /
save % g 0 , % g 0 , % g 0 / * S a v e t o w i n d o w ' T ' * /
/* Where she'll trap nobody knows... */
/* LOCATION: Window 'T' */
fwin_user_finish_up :
/* LOCATION: Window 'T' */
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
/ * Here c o m e t h e a r c h i t e c t u r e s p e c i f i c c h e c k s f o r s t a c k .
* mappings. N o t e t h a t u n l i k e t h e w i n d o w o v e r f l o w h a n d l e r
* we o n l y n e e d t o c h e c k w h e t h e r t h e u s e r c a n r e a d f r o m
* the a p p r o p r i a t e a d d r e s s e s . A l s o n o t e t h a t w e a r e i n
* an i n v a l i d w i n d o w w h i c h w i l l b e l o a d e d , a n d t h i s m e a n s
* that u n t i l w e a c t u a l l y l o a d t h e w i n d o w u p w e a r e f r e e
* to u s e a n y o f t h e l o c a l r e g i s t e r s c o n t a i n e d w i t h i n .
*
* On s u c c e s s t h e s e r o u t i n e b r a n c h t o f w i n _ u s e r _ s t a c k _ i s _ o k
* if t h e a r e a a t % s p i s u s e r r e a d a b l e a n d t h e w i n d o w s t i l l
* needs t o b e l o a d e d , e l s e f w i n _ u s e r _ f i n i s h _ u p i f t h e
* routine h a s d o n e t h e l o a d i n g i t s e l f . O n f a i l u r e ( b o g u s
* user s t a c k ) t h e r o u t i n e s h a l l b r a n c h t o t h e l a b e l c a l l e d
* fwin_ u s e r _ s t a c k _ i s _ b o l i x e d .
*
* Contrary t o t h e a r c h - s p e c i f i c w i n d o w o v e r f l o w s t a c k
* check r o u t i n e s i n w o f . S , t h e s e r o u t i n e s a r e f r e e t o u s e
* any o f t h e l o c a l r e g i s t e r s t h e y w a n t t o a s t h i s w i n d o w
* does n o t b e l o n g t o a n y o n e a t t h i s p o i n t , h o w e v e r t h e
* outs a n d i n s a r e s t i l l v e r b o t e n a s t h e y a r e p a r t o f
* ' someone e l s e s ' w i n d o w p o s s i b l y .
* /
.globl srmmu_fwin_stackchk
srmmu_fwin_stackchk :
/* LOCATION: Window 'W' */
/* Caller did 'andcc %sp, 0x7, %g0' */
bne f 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 ) , % l 5
/ * Check i f t h e u s e r s s t a c k i s i n k e r n e l v m a , t h e n o u r
* trial a n d e r r o r t e c h n i q u e b e l o w w o u l d s u c c e e d f o r
* the ' w r o n g ' r e a s o n .
* /
mov A C _ M _ S F S R , % l 4
cmp % l 5 , % s p
bleu f w i n _ u s e r _ s t a c k _ i s _ b o l i x e d
2012-05-25 21:20:16 +00:00
LEON_ P I ( l d a [ % l 4 ] A S I _ L E O N _ M M U R E G S , % g 0 ) ! c l e a r f a u l t s t a t u s
SUN_ P I _ ( l d a [ % l 4 ] A S I _ M _ M M U R E G S , % g 0 ) ! c l e a r f a u l t s t a t u s
2005-04-16 15:20:36 -07:00
/ * The t e c h n i q u e i s , t u r n o f f f a u l t s o n t h i s p r o c e s s o r ,
* just l e t t h e l o a d r i p , t h e n c h e c k t h e s f s r t o s e e i f
* a f a u l t d i d o c c u r . T h e n w e t u r n o n f a u l t t r a p s a g a i n
* and b r a n c h c o n d i t i o n a l l y b a s e d u p o n w h a t h a p p e n e d .
* /
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 , % l 5 ) ! r e a d m m u - c t r l r e g
SUN_ P I _ ( l d a [ % g 0 ] A S I _ M _ M M U R E G S , % l 5 ) ! r e a d m m u - c t r l r e g
2005-04-16 15:20:36 -07:00
or % l 5 , 0 x2 , % l 5 ! t u r n o 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 % l 5 , [ % g 0 ] A S I _ L E O N _ M M U R E G S ) ! s t o r e i t
SUN_ P I _ ( s t a % l 5 , [ % g 0 ] A S I _ M _ M M U R E G S ) ! s t o r e i t
2005-04-16 15:20:36 -07:00
/* Cross fingers and go for it. */
LOAD_ W I N D O W ( s p )
/* A penny 'saved'... */
save % g 0 , % g 0 , % g 0
save % g 0 , % g 0 , % g 0
/* Is a BADTRAP earned... */
/* LOCATION: Window 'T' */
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 , % t w i n _ t m p1 ) ! l o a d m m u - c t r l a g a i n
SUN_ P I _ ( l d a [ % g 0 ] A S I _ M _ M M U R E G S , % t w i n _ t m p1 ) ! l o a d m m u - c t r l a g a i n
andn % t w i n _ t m p1 , 0 x2 , % t w i n _ t m p1 ! c l e a r n o - f a u l t b i t
LEON_ P I ( s t a % t w i n _ t m p1 , [ % g 0 ] A S I _ L E O N _ M M U R E G S ) ! s t o r e i t
SUN_ P I _ ( s t a % t w i n _ t m p1 , [ % g 0 ] A S I _ M _ M M U R E G S ) ! s t o r e i t
2005-04-16 15:20:36 -07:00
mov A C _ M _ S F A R , % t w i n _ t m p2
2012-05-25 21:20:16 +00:00
LEON_ P I ( l d a [ % t w i n _ t m p2 ] A S I _ L E O N _ M M U R E G S , % g 0 ) ! r e a d f a u l t a d d r e s s
SUN_ P I _ ( l d a [ % t w i n _ t m p2 ] A S I _ M _ M M U R E G S , % g 0 ) ! r e a d f a u l t a d d r e s s
2005-04-16 15:20:36 -07:00
mov A C _ M _ S F S R , % t w i n _ t m p2
2012-05-25 21:20:16 +00:00
LEON_ P I ( l d a [ % t w i n _ t m p2 ] A S I _ L E O N _ M M U R E G S , % t w i n _ t m p2 ) ! r e a d f a u l t s t a t u s
SUN_ P I _ ( l d a [ % t w i n _ t m p2 ] A S I _ M _ M M U R E G S , % t w i n _ t m p2 ) ! r e a d f a u l t s t a t u s
andcc % t w i n _ t m p2 , 0 x2 , % g 0 ! d i d f a u l t o c c u r ?
2005-04-16 15:20:36 -07:00
2012-05-25 21:20:16 +00:00
bne 1 f ! y e p , c l e a n u p
2005-04-16 15:20:36 -07:00
nop
wr % t _ p s r , 0 x0 , % p s r
nop
b f w i n _ u s e r _ f i n i s h _ u p + 0 x4
nop
/ * Did I e v e r t e l l y o u a b o u t m y w i n d o w l o b o t o m y ?
* anyways. . . f w i n _ u s e r _ s t a c k _ i s _ b o l i x e d e x p e c t s
* to b e i n w i n d o w ' W ' s o m a k e i t h a p p y o r e l s e
* we w a t c h d o g b a d l y .
* /
1 :
restore % g 0 , % g 0 , % g 0
b f w i n _ u s e r _ s t a c k _ i s _ b o l i x e d ! o h w e l l
restore % g 0 , % g 0 , % g 0