2008-05-20 03:53:02 +04:00
/ *
2005-04-17 02:20:36 +04:00
* etrap. S : S p a r c t r a p w i n d o w p r e p a r a t i o n f o r e n t r y i n t o t h e
* Linux k e r n e l .
*
* 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 / h e a d . h >
# include < a s m / a s i . h >
# 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 s r . h >
# include < a s m / p t r a c e . 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 >
/* Registers to not touch at all. */
# define t _ p s r l 0 / * S e t b y c a l l e r * /
# define t _ p c l 1 / * S e t b y c a l l e r * /
# define t _ n p c l 2 / * S e t b y c a l l e r * /
# define t _ w i m l 3 / * S e t b y c a l l e r * /
# define t _ t w i n m a s k l 4 / * S e t a t b e g i n n i n g o f t h i s e n t r y r o u t i n e . * /
# define t _ k s t a c k l 5 / * S e t r i g h t b e f o r e p t _ r e g s f r a m e i s b u i l t * /
# define t _ r e t p c l 6 / * I f y o u c h a n g e t h i s , c h a n g e w i n m a c r o . h h e a d e r f i l e * /
# define t _ s y s t a b l e l 7 / * N e v e r t o u c h t h i s , c o u l d b e t h e s y s c a l l t a b l e p t r . * /
# define c u r p t r g 6 / * S e t a f t e r p t _ r e g s f r a m e i s b u i l t * /
.text
.align 4
/* SEVEN WINDOW PATCH INSTRUCTIONS */
.globl tsetup_ 7 w i n _ p a t c h1 , t s e t u p _ 7 w i n _ p a t c h2
.globl tsetup_ 7 w i n _ p a t c h3 , t s e t u p _ 7 w i n _ p a t c h4
.globl tsetup_ 7 w i n _ p a t c h5 , t s e t u p _ 7 w i n _ p a t c h6
tsetup_7win_patch1 : sll % t _ w i m , 0 x6 , % t _ w i m
tsetup_7win_patch2 : and % g 2 , 0 x7 f , % g 2
tsetup_7win_patch3 : and % g 2 , 0 x7 f , % g 2
tsetup_7win_patch4 : and % g 1 , 0 x7 f , % g 1
tsetup_7win_patch5 : sll % t _ w i m , 0 x6 , % t _ w i m
tsetup_7win_patch6 : and % g 2 , 0 x7 f , % g 2
/* END OF PATCH INSTRUCTIONS */
/ * At t r a p t i m e , i n t e r r u p t s a n d a l l g e n e r i c t r a p s d o t h e
* following :
*
* rd % p s r , % l 0
* b s o m e _ h a n d l e r
* rd % w i m , % l 3
* nop
*
* Then ' s o m e _ h a n d l e r ' i f i t n e e d s a t r a p f r a m e ( i e . i t h a s
* to c a l l c - c o d e a n d t h e t r a p c a n n o t b e h a n d l e d i n - w i n d o w )
* then i t d o e s t h e S A V E _ A L L m a c r o i n e n t r y . S w h i c h d o e s
*
* sethi % h i ( t r a p _ s e t u p ) , % l 4
* jmpl % l 4 + % l o ( t r a p _ s e t u p ) , % l 6
* nop
* /
/ * 2 3 4 window n u m b e r
* - - - - -
* O T S m n e m o n i c
*
* O = = C u r r e n t w i n d o w b e f o r e t r a p
* T = = W i n d o w e n t e r e d w h e n t r a p o c c u r r e d
* S = = W i n d o w w e w i l l n e e d t o s a v e i f ( 1 < < T ) = = % w i m
*
* Before e x e c u t i o n g e t s h e r e , i t m u s t b e g u a r a n t e e d t h a t
* % l0 c o n t a i n s t r a p t i m e % p s r , % l 1 a n d % l 2 c o n t a i n t h e
* trap p c a n d n p c , a n d % l 3 c o n t a i n s t h e t r a p t i m e % w i m .
* /
.globl trap_ s e t u p , t s e t u p _ p a t c h1 , t s e t u p _ p a t c h2
.globl tsetup_ p a t c h3 , t s e t u p _ p a t c h4
.globl tsetup_ p a t c h5 , t s e t u p _ p a t c h6
trap_setup :
/ * Calculate m a s k o f t r a p w i n d o w . S e e i f f r o m u s e r
* or k e r n e l a n d b r a n c h c o n d i t i o n a l l y .
* /
mov 1 , % t _ t w i n m a s k
andcc % t _ p s r , P S R _ P S , % g 0 ! f r o m s u p v _ p = ( p s r & P S R _ P S )
be t r a p _ s e t u p _ f r o m _ u s e r ! n o p e , f r o m u s e r m o d e
sll % t _ t w i n m a s k , % t _ p s r , % t _ t w i n m a s k ! t _ t w i n m a s k = ( 1 < < p s r )
/ * From k e r n e l , a l l o c a t e m o r e k e r n e l s t a c k a n d
* build a p t _ r e g s t r a p f r a m e .
* /
sub % f p , ( S T A C K F R A M E _ S Z + T R A C E R E G _ S Z ) , % t _ k s t a c k
STORE_ P T _ A L L ( t _ k s t a c k , t _ p s r , t _ p c , t _ n p c , g 2 )
/* See if we are in the trap window. */
andcc % t _ t w i n m a s k , % t _ w i m , % g 0
bne t r a p _ s e t u p _ k e r n e l _ s p i l l ! i n t r a p w i n d o w , c l e a n u p
nop
/ * Trap f r o m k e r n e l w i t h a w i n d o w a v a i l a b l e .
* Just d o i t . . .
* /
jmpl % t _ r e t p c + 0 x8 , % g 0 ! r e t u r n t o c a l l e r
mov % t _ k s t a c k , % s p ! j u m p o n t o n e w s t a c k
trap_setup_kernel_spill :
ld [ % c u r p t r + T I _ U W I N M A S K ] , % g 1
orcc % g 0 , % g 1 , % g 0
bne t r a p _ s e t u p _ u s e r _ s p i l l ! t h e r e a r e s o m e u s e r w i n d o w s , y u c k
/ * Spill f r o m k e r n e l , b u t o n l y k e r n e l w i n d o w s , a d j u s t
* % wim a n d g o .
* /
srl % t _ w i m , 0 x1 , % g 2 ! b e g i n c o m p u t a t i o n o f n e w % w i m
tsetup_patch1 :
sll % t _ w i m , 0 x7 , % t _ w i m ! p a t c h e d o n 7 w i n d o w S p a r c s
or % t _ w i m , % g 2 , % g 2
tsetup_patch2 :
and % g 2 , 0 x f f , % g 2 ! p a t c h e d o n 7 w i n d o w S p a r c s
save % g 0 , % g 0 , % g 0
/* Set new %wim value */
wr % g 2 , 0 x0 , % w i m
/* Save the kernel window onto the corresponding stack. */
STORE_ W I N D O W ( s p )
restore % g 0 , % g 0 , % g 0
jmpl % t _ r e t p c + 0 x8 , % g 0 ! r e t u r n t o c a l l e r
mov % t _ k s t a c k , % s p ! a n d o n t o n e w k e r n e l s t a c 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 )
trap_setup_from_user :
/* We can't use %curptr yet. */
LOAD_ C U R R E N T ( t _ k s t a c k , t _ t w i n m a s k )
sethi % h i ( S T A C K _ O F F S E T ) , % t _ t w i n m a s k
or % t _ t w i n m a s k , % l o ( S T A C K _ O F F S E T ) , % t _ t w i n m a s k
add % t _ k s t a c k , % t _ t w i n m a s k , % t _ k s t a c k
mov 1 , % t _ t w i n m a s k
sll % t _ t w i n m a s k , % t _ p s r , % t _ t w i n m a s k ! t _ t w i n m a s k = ( 1 < < p s r )
/* Build pt_regs frame. */
STORE_ P T _ A L L ( t _ k s t a c k , t _ p s r , t _ p c , t _ n p c , g 2 )
# if 0
/ * If w e ' r e s u r e e v e r y t a s k _ s t r u c t i s T H R E A D _ S I Z E a l i g n e d ,
we c a n s p e e d t h i s u p . * /
sethi % h i ( S T A C K _ O F F S E T ) , % c u r p t r
or % c u r p t r , % l o ( S T A C K _ O F F S E T ) , % c u r p t r
sub % t _ k s t a c k , % c u r p t r , % c u r p t r
# else
sethi % h i ( ~ ( T H R E A D _ S I Z E - 1 ) ) , % c u r p t r
and % t _ k s t a c k , % c u r p t r , % c u r p t r
# endif
/* Clear current_thread_info->w_saved */
st % g 0 , [ % c u r p t r + T I _ W _ S A V E D ]
/* See if we are in the trap window. */
andcc % t _ t w i n m a s k , % t _ w i m , % g 0
bne t r a p _ s e t u p _ u s e r _ s p i l l ! y e p w e a r e
orn % g 0 , % t _ t w i n m a s k , % g 1 ! n e g a t e t r a p w i n m a s k i n t o % g 1
/ * Trap f r o m u s e r , b u t n o t i n t o t h e i n v a l i d w i n d o w .
* Calculate n e w u m a s k . T h e w a y t h i s w o r k s i s ,
* any w i n d o w f r o m t h e % w i m a t t r a p t i m e u n t i l
* the w i n d o w r i g h t b e f o r e t h e o n e w e a r e i n n o w ,
* is a u s e r w i n d o w . A d i a g r a m :
*
* 7 6 5 4 3 2 1 0 window n u m b e r
* - - - - - - - - - - - - - - -
* I L T m n e m o n i c
*
* Window ' I ' i s t h e i n v a l i d w i n d o w i n o u r e x a m p l e ,
* window ' L ' i s t h e w i n d o w t h e u s e r w a s i n w h e n
* the t r a p o c c u r r e d , w i n d o w T i s t h e t r a p w i n d o w
* we a r e i n n o w . S o t h e r e f o r e , w i n d o w s 5 , 4 a n d
* 3 are u s e r w i n d o w s . T h e f o l l o w i n g s e q u e n c e
* computes t h e u s e r w i n m a s k t o r e p r e s e n t t h i s .
* /
subcc % t _ w i m , % t _ t w i n m a s k , % g 2
bneg,a 1 f
sub % g 2 , 0 x1 , % g 2
1 :
andn % g 2 , % t _ t w i n m a s k , % g 2
tsetup_patch3 :
and % g 2 , 0 x f f , % g 2 ! p a t c h e d o n 7 w i n S p a r c s
st % g 2 , [ % c u r p t r + T I _ U W I N M A S K ] ! s t o r e n e w u m a s k
jmpl % t _ r e t p c + 0 x8 , % g 0 ! r e t u r n t o c a l l e r
mov % t _ k s t a c k , % s p ! a n d o n t o k e r n e l s t a c k
trap_setup_user_spill :
/ * A s p i l l o c c u r r e d f r o m e i t h e r k e r n e l o r u s e r m o d e
* and t h e r e e x i s t s o m e u s e r w i n d o w s t o d e a l w i t h .
* A m a s k o f t h e c u r r e n t l y v a l i d u s e r w i n d o w s
* is i n % g 1 u p o n e n t r y t o h e r e .
* /
tsetup_patch4 :
and % g 1 , 0 x f f , % g 1 ! p a t c h e d o n 7 w i n S p a r c s , m a s k
srl % t _ w i m , 0 x1 , % g 2 ! c o m p u t e n e w % w i m
tsetup_patch5 :
sll % t _ w i m , 0 x7 , % t _ w i m ! p a t c h e d o n 7 w i n S p a r c s
or % t _ w i m , % g 2 , % g 2 ! % g 2 i s n e w % w i m
tsetup_patch6 :
and % g 2 , 0 x f f , % g 2 ! p a t c h e d o n 7 w i n S p a r c s
andn % g 1 , % g 2 , % g 1 ! c l e a r t h i s b i t i n % g 1
st % g 1 , [ % c u r p t r + T I _ U W I N M A S K ]
save % g 0 , % g 0 , % g 0
wr % g 2 , 0 x0 , % w i m
/ * Call M M U - a r c h i t e c t u r e d e p e n d e n t s t a c k c h e c k i n g
* routine.
* /
.globl tsetup_mmu_patchme
tsetup_mmu_patchme :
b t s e t u p _ s u n 4 c _ s t a c k c h k
andcc % s p , 0 x7 , % g 0
/ * Architecture s p e c i f i c s t a c k c h e c k i n g r o u t i n e s . W h e n e i t h e r
* of t h e s e r o u t i n e s a r e c a l l e d , t h e g l o b a l s a r e f r e e t o u s e
* as t h e y h a v e b e e n s a f e l y s t a s h e d o n t h e n e w k e r n e l s t a c k
* pointer. T h u s t h e d e f i n i t i o n b e l o w f o r s i m p l i c i t y .
* /
# define g l o b _ t m p g 1
tsetup_sun4c_stackchk :
/* Done by caller: andcc %sp, 0x7, %g0 */
bne t r a p _ s e t u p _ u s e r _ s t a c k _ i s _ b o l i x e d
sra % s p , 2 9 , % g l o b _ t m p
add % g l o b _ t m p , 0 x1 , % g l o b _ t m p
andncc % g l o b _ t m p , 0 x1 , % g 0
bne t r a p _ s e t u p _ u s e r _ s t a c k _ i s _ b o l i x e d
and % s p , 0 x f f f , % g l o b _ t m p ! d e l a y s l o t
/ * See i f o u r d u m p a r e a w i l l b e o n m o r e t h a n o n e
* page.
* /
add % g l o b _ t m p , 0 x38 , % g l o b _ t m p
andncc % g l o b _ t m p , 0 x f f8 , % g 0
be t s e t u p _ s u n 4 c _ o n e p a g e ! o n l y o n e p a g e t o c h e c k
lda [ % s p ] A S I _ P T E , % g l o b _ t m p ! h a v e t o c h e c k f i r s t p a g e a n y w a y s
tsetup_sun4c_twopages :
/* Is first page ok permission wise? */
srl % g l o b _ t m p , 2 9 , % g l o b _ t m p
cmp % g l o b _ t m p , 0 x6
bne t r a p _ s e t u p _ u s e r _ s t a c k _ i s _ b o l i x e d
add % s p , 0 x38 , % g l o b _ t m p / * I s s e c o n d p a g e i n v m a h o l e ? * /
sra % g l o b _ t m p , 2 9 , % g l o b _ t m p
add % g l o b _ t m p , 0 x1 , % g l o b _ t m p
andncc % g l o b _ t m p , 0 x1 , % g 0
bne t r a p _ s e t u p _ u s e r _ s t a c k _ i s _ b o l i x e d
add % s p , 0 x38 , % g l o b _ t m p
lda [ % g l o b _ t m p ] A S I _ P T E , % g l o b _ t m p
tsetup_sun4c_onepage :
srl % g l o b _ t m p , 2 9 , % g l o b _ t m p
cmp % g l o b _ t m p , 0 x6 ! c a n u s e r w r i t e t o i t ?
bne t r a p _ s e t u p _ u s e r _ s t a c k _ i s _ b o l i x e d ! f a i l u r e
nop
STORE_ W I N D O W ( s p )
restore % g 0 , % g 0 , % g 0
jmpl % t _ r e t p c + 0 x8 , % g 0
mov % t _ k s t a c k , % s p
.globl tsetup_srmmu_stackchk
tsetup_srmmu_stackchk :
/* Check results of callers andcc %sp, 0x7, %g0 */
bne t r a p _ s e t u p _ 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,a 1 f
lda [ % 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
trap_setup_user_stack_is_bolixed :
/ * From u s e r / k e r n e l i n t o i n v a l i d w i n d o w w / b a d u s e r
* stack. S a v e b a d u s e r s t a c k , a n d r e t u r n t o c a l l e r .
* /
SAVE_ B O L I X E D _ U S E R _ S T A C K ( c u r p t r , g 3 )
restore % g 0 , % g 0 , % g 0
jmpl % t _ r e t p c + 0 x8 , % g 0
mov % t _ k s t a c k , % s p
1 :
/* Clear the fault status and turn on the no_fault bit. */
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
sta % 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
/* 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
sta % g l o b _ t m p , [ % g 0 ] A S I _ M _ M M U R E G S
mov A C _ M _ S F A R , % g l o b _ t m p
lda [ % g l o b _ t m p ] A S I _ M _ M M U R E G S , % g 0
mov A C _ M _ S F S R , % g l o b _ t m p
lda [ % 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 ! s a v e a w a y s t a t u s o f w i n s t o r e
andcc % g l o b _ t m p , 0 x2 , % g 0 ! d i d w e f a u l t ?
bne t r a p _ s e t u p _ u s e r _ s t a c k _ i s _ b o l i x e d ! f a i l u r e
nop
restore % g 0 , % g 0 , % g 0
jmpl % t _ r e t p c + 0 x8 , % g 0
mov % t _ k s t a c k , % s p