2005-04-17 02:20:36 +04:00
/ *
* arch/ p p c64 / m m / s l b _ l o w . S
*
* Low- l e v e l S L B r o u t i n e s
*
* Copyright ( C ) 2 0 0 4 D a v i d G i b s o n < d w g @au.ibm.com>, IBM
*
* Based o n e a r l i e r C v e r s i o n :
* Dave E n g e b r e t s e n a n d M i k e C o r r i g a n { e n g e b r e t | m i k e j c } @us.ibm.com
* Copyright ( c ) 2 0 0 1 D a v e E n g e b r e t s e n
* Copyright ( C ) 2 0 0 2 A n t o n B l a n c h a r d < a n t o n @au.ibm.com>, IBM
*
* 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 ; either version
* 2 of t h e L i c e n s e , o r ( a t y o u r o p t i o n ) a n y l a t e r v e r s i o n .
* /
# include < l i n u x / c o n f i g . h >
# include < a s m / p r o c e s s o r . h >
# include < a s m / p p c _ a s m . h >
2005-09-09 22:57:26 +04:00
# include < a s m / a s m - o f f s e t s . h >
2005-04-17 02:20:36 +04:00
# include < a s m / c p u t a b l e . h >
2005-11-07 03:06:55 +03:00
# include < a s m / p a g e . h >
# include < a s m / m m u . h >
# include < a s m / p g t a b l e . h >
2005-04-17 02:20:36 +04:00
2005-11-07 03:06:55 +03:00
/ * void s l b _ a l l o c a t e _ r e a l m o d e ( u n s i g n e d l o n g e a ) ;
2005-04-17 02:20:36 +04:00
*
* Create a n S L B e n t r y f o r t h e g i v e n E A ( u s e r o r k e r n e l ) .
* r3 = f a u l t i n g a d d r e s s , r13 = P A C A
* r9 , r10 , r11 a r e c l o b b e r e d b y t h i s f u n c t i o n
* No o t h e r r e g i s t e r s a r e e x a m i n e d o r c h a n g e d .
* /
2005-11-07 03:06:55 +03:00
_ GLOBAL( s l b _ a l l o c a t e _ r e a l m o d e )
/* r3 = faulting address */
2005-04-17 02:20:36 +04:00
srdi r9 ,r3 ,6 0 / * g e t r e g i o n * /
2005-11-07 03:06:55 +03:00
srdi r10 ,r3 ,2 8 / * g e t e s i d * /
2005-04-17 02:20:36 +04:00
cmpldi c r7 ,r9 ,0 x c / * c m p K E R N E L B A S E f o r l a t e r u s e * /
2005-11-07 03:06:55 +03:00
/* r3 = address, r10 = esid, cr7 = <>KERNELBASE */
2005-04-17 02:20:36 +04:00
blt c r7 ,0 f / * u s e r o r k e r n e l ? * /
/* kernel address: proto-VSID = ESID */
/ * WARNING - M A G I C : w e d o n ' t u s e t h e V S I D 0 x f f f f f f f f f , b u t
* this c o d e w i l l g e n e r a t e t h e p r o t o V S I D 0 x f f f f f f f f f f o r t h e
* top s e g m e n t . T h a t ' s o k , t h e s c r a m b l e b e l o w w i l l t r a n s l a t e
* it t o V S I D 0 , w h i c h i s r e s e r v e d a s a b a d V S I D - o n e w h i c h
* will n e v e r h a v e a n y p a g e s i n i t . * /
2005-11-07 03:06:55 +03:00
/ * Check i f h i t t i n g t h e l i n e a r m a p p i n g o f t h e v m a l l o c / i o r e m a p
* kernel s p a c e
* /
bne c r7 ,1 f
/ * Linear m a p p i n g e n c o d i n g b i t s , t h e " l i " i n s t r u c t i o n b e l o w w i l l
* be p a t c h e d b y t h e k e r n e l a t b o o t
* /
_ GLOBAL( s l b _ m i s s _ k e r n e l _ l o a d _ l i n e a r )
li r11 ,0
b s l b _ f i n i s h _ l o a d
1 : / * vmalloc/ i o r e m a p m a p p i n g e n c o d i n g b i t s , t h e " l i " i n s t r u c t i o n b e l o w
* will b e p a t c h e d b y t h e k e r n e l a t b o o t
* /
_ GLOBAL( s l b _ m i s s _ k e r n e l _ l o a d _ v i r t u a l )
li r11 ,0
b s l b _ f i n i s h _ l o a d
0 : / * user a d d r e s s : p r o t o - V S I D = c o n t e x t < < 1 5 | E S I D . F i r s t c h e c k
* if t h e a d d r e s s i s w i t h i n t h e b o u n d a r i e s o f t h e u s e r r e g i o n
* /
srdi. r9 ,r10 ,U S E R _ E S I D _ B I T S
2005-04-17 02:20:36 +04:00
bne- 8 f / * i n v a l i d e a b i t s s e t * /
2005-11-07 03:06:55 +03:00
/* Figure out if the segment contains huge pages */
2005-04-17 02:20:36 +04:00
# ifdef C O N F I G _ H U G E T L B _ P A G E
BEGIN_ F T R _ S E C T I O N
2005-11-07 03:06:55 +03:00
b 1 f
END_ F T R _ S E C T I O N _ I F C L R ( C P U _ F T R _ 1 6 M _ P A G E )
2005-08-11 10:55:21 +04:00
lhz r9 ,P A C A H I G H H T L B A R E A S ( r13 )
2005-11-07 03:06:55 +03:00
srdi r11 ,r10 ,( H T L B _ A R E A _ S H I F T - S I D _ S H I F T )
2005-08-11 10:55:21 +04:00
srd r9 ,r9 ,r11
2005-08-31 08:34:05 +04:00
lhz r11 ,P A C A L O W H T L B A R E A S ( r13 )
2005-11-07 03:06:55 +03:00
srd r11 ,r11 ,r10
or. r9 ,r9 ,r11
beq 1 f
_ GLOBAL( s l b _ m i s s _ u s e r _ l o a d _ h u g e )
li r11 ,0
b 2 f
1 :
2005-08-31 08:34:05 +04:00
# endif / * C O N F I G _ H U G E T L B _ P A G E * /
2005-08-11 10:55:21 +04:00
2005-11-07 03:06:55 +03:00
_ GLOBAL( s l b _ m i s s _ u s e r _ l o a d _ n o r m a l )
li r11 ,0
2005-08-11 10:55:21 +04:00
2005-11-07 03:06:55 +03:00
2 :
ld r9 ,P A C A C O N T E X T I D ( r13 )
rldimi r10 ,r9 ,U S E R _ E S I D _ B I T S ,0
b s l b _ f i n i s h _ l o a d
8 : /* invalid EA */
li r10 ,0 / * B A D _ V S I D * /
li r11 ,S L B _ V S I D _ U S E R / * f l a g s d o n ' t m u c h m a t t e r * /
b s l b _ f i n i s h _ l o a d
# ifdef _ _ D I S A B L E D _ _
/ * void s l b _ a l l o c a t e _ u s e r ( u n s i g n e d l o n g e a ) ;
*
* Create a n S L B e n t r y f o r t h e g i v e n E A ( u s e r o r k e r n e l ) .
* r3 = f a u l t i n g a d d r e s s , r13 = P A C A
* r9 , r10 , r11 a r e c l o b b e r e d b y t h i s f u n c t i o n
* No o t h e r r e g i s t e r s a r e e x a m i n e d o r c h a n g e d .
*
* It i s c a l l e d w i t h t r a n s l a t i o n e n a b l e d i n o r d e r t o b e a b l e t o w a l k t h e
* page t a b l e s . T h i s i s n o t c u r r e n t l y u s e d .
* /
_ GLOBAL( s l b _ a l l o c a t e _ u s e r )
/* r3 = faulting address */
srdi r10 ,r3 ,2 8 / * g e t e s i d * /
crset 4 * c r7 + l t / * s e t " u s e r " f l a g f o r l a t e r * /
/* check if we fit in the range covered by the pagetables*/
srdi. r9 ,r3 ,P G T A B L E _ E A D D R _ S I Z E
crnot 4 * c r0 + e q ,4 * c r0 + e q
beqlr
2005-04-17 02:20:36 +04:00
2005-11-07 03:06:55 +03:00
/ * now w e n e e d t o g e t t o t h e p a g e t a b l e s i n o r d e r t o g e t t h e p a g e
* size e n c o d i n g f r o m t h e P M D . I n t h e f u t u r e , w e ' l l b e a b l e t o d e a l
* with 1 T s e g m e n t s t o o b y g e t t i n g t h e e n c o d i n g f r o m t h e P G D i n s t e a d
* /
ld r9 ,P A C A P G D I R ( r13 )
cmpldi c r0 ,r9 ,0
beqlr
rlwinm r11 ,r10 ,8 ,2 5 ,2 8
ldx r9 ,r9 ,r11 / * g e t p g d _ t * /
cmpldi c r0 ,r9 ,0
beqlr
rlwinm r11 ,r10 ,3 ,1 7 ,2 8
ldx r9 ,r9 ,r11 / * g e t p m d _ t * /
cmpldi c r0 ,r9 ,0
beqlr
/* build vsid flags */
andi. r11 ,r9 ,S L B _ V S I D _ L L P
ori r11 ,r11 ,S L B _ V S I D _ U S E R
/* get context to calculate proto-VSID */
2005-08-31 08:34:05 +04:00
ld r9 ,P A C A C O N T E X T I D ( r13 )
2005-11-07 03:06:55 +03:00
rldimi r10 ,r9 ,U S E R _ E S I D _ B I T S ,0
/* fall through slb_finish_load */
# endif / * _ _ D I S A B L E D _ _ * /
2005-04-17 02:20:36 +04:00
2005-11-07 03:06:55 +03:00
/ *
* Finish l o a d i n g o f a n S L B e n t r y a n d r e t u r n
*
* r3 = E A , r10 = p r o t o - V S I D , r11 = f l a g s , c l o b b e r s r9 , c r7 = < > K E R N E L B A S E
* /
slb_finish_load :
ASM_ V S I D _ S C R A M B L E ( r10 ,r9 )
rldimi r11 ,r10 ,S L B _ V S I D _ S H I F T ,1 6 / * c o m b i n e V S I D a n d f l a g s * /
/* r3 = EA, r11 = VSID data */
/ *
* Find a s l o t , r o u n d r o b i n . P r e v i o u s l y w e t r i e d t o f i n d a
* free s l o t f i r s t b u t t h a t t o o k t o o l o n g . U n f o r t u n a t e l y w e
* dont h a v e a n y L R U i n f o r m a t i o n t o h e l p u s c h o o s e a s l o t .
* /
# ifdef C O N F I G _ P P C _ I S E R I E S
/ *
* On i S e r i e s , t h e " b o l t e d " s t a c k s e g m e n t c a n b e c a s t o u t o n
* shared p r o c e s s o r s w i t c h s o w e n e e d t o c h e c k f o r a m i s s o n
* it a n d r e s t o r e i t t o t h e r i g h t s l o t .
* /
ld r9 ,P A C A K S A V E ( r13 )
clrrdi r9 ,r9 ,2 8
clrrdi r3 ,r3 ,2 8
li r10 ,S L B _ N U M _ B O L T E D - 1 / * S t a c k g o e s i n l a s t b o l t e d s l o t * /
cmpld r9 ,r3
beq 3 f
# endif / * C O N F I G _ P P C _ I S E R I E S * /
ld r10 ,P A C A S T A B R R ( r13 )
addi r10 ,r10 ,1
/* use a cpu feature mask if we ever change our slb size */
cmpldi r10 ,S L B _ N U M _ E N T R I E S
blt+ 4 f
li r10 ,S L B _ N U M _ B O L T E D
4 :
std r10 ,P A C A S T A B R R ( r13 )
3 :
rldimi r3 ,r10 ,0 ,3 6 / * r3 = E A [ 0 : 3 5 ] | e n t r y * /
oris r10 ,r3 ,S L B _ E S I D _ V @h /* r3 |= SLB_ESID_V */
/* r3 = ESID data, r11 = VSID data */
2005-04-17 02:20:36 +04:00
/ *
* No n e e d f o r a n i s y n c b e f o r e o r a f t e r t h i s s l b m t e . T h e e x c e p t i o n
* we e n t e r w i t h a n d t h e r f i d w e e x i t w i t h a r e c o n t e x t s y n c h r o n i z i n g .
* /
slbmte r11 ,r10
2005-11-07 03:06:55 +03:00
/* we're done for kernel addresses */
crclr 4 * c r0 + e q / * s e t r e s u l t t o " s u c c e s s " * /
bgelr c r7
2005-04-17 02:20:36 +04:00
/* Update the slb cache */
lhz r3 ,P A C A S L B C A C H E P T R ( r13 ) / * o f f s e t = p a c a - > s l b _ c a c h e _ p t r * /
cmpldi r3 ,S L B _ C A C H E _ E N T R I E S
bge 1 f
/* still room in the slb cache */
sldi r11 ,r3 ,1 / * r11 = o f f s e t * s i z e o f ( u 1 6 ) * /
rldicl r10 ,r10 ,3 6 ,2 8 / * g e t l o w 1 6 b i t s o f t h e E S I D * /
add r11 ,r11 ,r13 / * r11 = ( u 1 6 * ) p a c a + o f f s e t * /
sth r10 ,P A C A S L B C A C H E ( r11 ) / * p a c a - > s l b _ c a c h e [ o f f s e t ] = e s i d * /
addi r3 ,r3 ,1 / * o f f s e t + + * /
b 2 f
1 : /* offset >= SLB_CACHE_ENTRIES */
li r3 ,S L B _ C A C H E _ E N T R I E S + 1
2 :
sth r3 ,P A C A S L B C A C H E P T R ( r13 ) / * p a c a - > s l b _ c a c h e _ p t r = o f f s e t * /
2005-11-07 03:06:55 +03:00
crclr 4 * c r0 + e q / * s e t r e s u l t t o " s u c c e s s " * /
2005-04-17 02:20:36 +04:00
blr