2005-09-26 16:04:21 +10:00
/ *
* This f i l e c o n t a i n s l o w - l e v e l c a c h e m a n a g e m e n t f u n c t i o n s
* used f o r s l e e p a n d C P U s p e e d c h a n g e s o n A p p l e m a c h i n e s .
* ( In f a c t t h e o n l y t h i n g t h a t i s A p p l e - s p e c i f i c i s t h a t w e a s s u m e
* that w e c a n r e a d f r o m R O M a t p h y s i c a l a d d r e s s 0 x f f f00 0 0 0 . )
*
* Copyright ( C ) 2 0 0 4 P a u l M a c k e r r a s ( p a u l u s @samba.org) and
* Benjamin H e r r e n s c h m i d t ( b e n h @kernel.crashing.org)
*
* 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 < a s m / p r o c e s s o r . h >
# include < a s m / p p c _ a s m . h >
# include < a s m / c p u t a b l e . h >
/ *
* Flush a n d d i s a b l e a l l d a t a c a c h e s ( d L 1 , L 2 , L 3 ) . T h i s i s u s e d
* when g o i n g t o s l e e p , w h e n d o i n g a P M U b a s e d c p u f r e q t r a n s i t i o n ,
* or w h e n " o f f l i n i n g " a C P U o n S M P m a c h i n e s . T h i s c o d e i s o v e r
* paranoid, b u t I ' v e h a d e n o u g h i s s u e s w i t h v a r i o u s C P U r e v s a n d
2016-02-24 10:51:11 -08:00
* bugs t h a t I d e c i d e d i t w a s w o r t h b e i n g o v e r c a u t i o u s
2005-09-26 16:04:21 +10:00
* /
_ GLOBAL( f l u s h _ d i s a b l e _ c a c h e s )
# ifndef C O N F I G _ 6 x x
blr
# else
BEGIN_ F T R _ S E C T I O N
b f l u s h _ d i s a b l e _ 7 4 5 x
END_ F T R _ S E C T I O N _ I F S E T ( C P U _ F T R _ S P E C 7 4 5 0 )
BEGIN_ F T R _ S E C T I O N
b f l u s h _ d i s a b l e _ 7 5 x
END_ F T R _ S E C T I O N _ I F S E T ( C P U _ F T R _ L 2 C R )
b _ _ f l u s h _ d i s a b l e _ L 1
/* This is the code for G3 and 74[01]0 */
flush_disable_75x :
mflr r10
/* Turn off EE and DR in MSR */
mfmsr r11
rlwinm r0 ,r11 ,0 ,~ M S R _ E E
rlwinm r0 ,r0 ,0 ,~ M S R _ D R
sync
mtmsr r0
isync
/* Stop DST streams */
BEGIN_ F T R _ S E C T I O N
DSSALL
sync
END_ F T R _ S E C T I O N _ I F S E T ( C P U _ F T R _ A L T I V E C )
/* Stop DPM */
mfspr r8 ,S P R N _ H I D 0 / * S a v e S P R N _ H I D 0 i n r8 * /
rlwinm r4 ,r8 ,0 ,1 2 ,1 0 / * T u r n o f f H I D 0 [ D P M ] * /
sync
mtspr S P R N _ H I D 0 ,r4 / * D i s a b l e D P M * /
sync
/ * Disp- f l u s h L 1 . W e h a v e a w e i r d p r o b l e m h e r e t h a t I n e v e r
* totally f i g u r e d o u t . O n 7 5 0 F X , u s i n g t h e R O M f o r t h e f l u s h
* results i n a n o n - w o r k i n g f l u s h . W e u s e t h a t w o r k a r o u n d f o r
* now u n t i l I f i n a l l y u n d e r s t a n d w h a t ' s g o i n g o n . - - B e n H
* /
/* ROM base by default */
lis r4 ,0 x f f f0
mfpvr r3
srwi r3 ,r3 ,1 6
cmplwi c r0 ,r3 ,0 x70 0 0
bne+ 1 f
/* RAM base on 750FX */
li r4 ,0
1 : li r4 ,0 x40 0 0
mtctr r4
1 : lwz r0 ,0 ( r4 )
addi r4 ,r4 ,3 2
bdnz 1 b
sync
isync
/* Disable / invalidate / enable L1 data */
mfspr r3 ,S P R N _ H I D 0
rlwinm r3 ,r3 ,0 ,~ ( H I D 0 _ D C E | H I D 0 _ I C E )
mtspr S P R N _ H I D 0 ,r3
sync
isync
ori r3 ,r3 ,( H I D 0 _ D C E | H I D 0 _ D C I | H I D 0 _ I C E | H I D 0 _ I C F I )
sync
isync
mtspr S P R N _ H I D 0 ,r3
xori r3 ,r3 ,( H I D 0 _ D C I | H I D 0 _ I C F I )
mtspr S P R N _ H I D 0 ,r3
sync
/* Get the current enable bit of the L2CR into r4 */
mfspr r5 ,S P R N _ L 2 C R
/* Set to data-only (pre-745x bit) */
oris r3 ,r5 ,L 2 C R _ L 2 D O @h
b 2 f
/* When disabling L2, code must be in L1 */
.balign 32
1 : mtspr S P R N _ L 2 C R ,r3
3 : sync
isync
b 1 f
2 : b 3 f
3 : sync
isync
b 1 b
1 : / * disp- f l u s h L 2 . T h e i n t e r e s t i n g t h i n g h e r e i s t h a t t h e L 2 c a n b e
* up t o 2 M b . . . s o u s i n g t h e R O M , w e ' l l e n d u p w r a p p i n g b a c k t o m e m o r y
* but t h a t i s p r o b b a l y f i n e . W e d i s p - f l u s h o v e r 4 M b t o b e s a f e
* /
lis r4 ,2
mtctr r4
lis r4 ,0 x f f f0
1 : lwz r0 ,0 ( r4 )
addi r4 ,r4 ,3 2
bdnz 1 b
sync
isync
lis r4 ,2
mtctr r4
lis r4 ,0 x f f f0
1 : dcbf 0 ,r4
addi r4 ,r4 ,3 2
bdnz 1 b
sync
isync
/* now disable L2 */
rlwinm r5 ,r5 ,0 ,~ L 2 C R _ L 2 E
b 2 f
/* When disabling L2, code must be in L1 */
.balign 32
1 : mtspr S P R N _ L 2 C R ,r5
3 : sync
isync
b 1 f
2 : b 3 f
3 : sync
isync
b 1 b
1 : sync
isync
/* Invalidate L2. This is pre-745x, we clear the L2I bit ourselves */
oris r4 ,r5 ,L 2 C R _ L 2 I @h
mtspr S P R N _ L 2 C R ,r4
sync
isync
/* Wait for the invalidation to complete */
1 : mfspr r3 ,S P R N _ L 2 C R
rlwinm. r0 ,r3 ,0 ,3 1 ,3 1
bne 1 b
/* Clear L2I */
xoris r4 ,r4 ,L 2 C R _ L 2 I @h
sync
mtspr S P R N _ L 2 C R ,r4
sync
/* now disable the L1 data cache */
mfspr r0 ,S P R N _ H I D 0
rlwinm r0 ,r0 ,0 ,~ ( H I D 0 _ D C E | H I D 0 _ I C E )
mtspr S P R N _ H I D 0 ,r0
sync
isync
/* Restore HID0[DPM] to whatever it was before */
sync
mfspr r0 ,S P R N _ H I D 0
rlwimi r0 ,r8 ,0 ,1 1 ,1 1 / * T u r n b a c k H I D 0 [ D P M ] * /
mtspr S P R N _ H I D 0 ,r0
sync
/* restore DR and EE */
sync
mtmsr r11
isync
mtlr r10
blr
/* This code is for 745x processors */
flush_disable_745x :
/* Turn off EE and DR in MSR */
mfmsr r11
rlwinm r0 ,r11 ,0 ,~ M S R _ E E
rlwinm r0 ,r0 ,0 ,~ M S R _ D R
sync
mtmsr r0
isync
/* Stop prefetch streams */
DSSALL
sync
/* Disable L2 prefetching */
mfspr r0 ,S P R N _ M S S C R 0
rlwinm r0 ,r0 ,0 ,0 ,2 9
mtspr S P R N _ M S S C R 0 ,r0
sync
isync
lis r4 ,0
dcbf 0 ,r4
dcbf 0 ,r4
dcbf 0 ,r4
dcbf 0 ,r4
dcbf 0 ,r4
dcbf 0 ,r4
dcbf 0 ,r4
dcbf 0 ,r4
/ * Due t o a b u g w i t h t h e H W f l u s h o n s o m e C P U r e v s , w e o c c a s i o n a l l y
* experience d a t a c o r r u p t i o n . I ' m a d d i n g a d i s p l a c e m e n t f l u s h a l o n g
* with a d c b f l o o p o v e r a f e w M b t o " h e l p " . T h e p r o b l e m i s n ' t t o t a l l y
* fixed b y t h i s i n t h e o r y , b u t a t l e a s t , i n p r a c t i c e , I c o u l d n ' t r e p r o d u c e
* it e v e n w i t h a b i g h a m m e r . . .
* /
lis r4 ,0 x00 0 2
mtctr r4
li r4 ,0
1 :
lwz r0 ,0 ( r4 )
addi r4 ,r4 ,3 2 / * G o t o s t a r t o f n e x t c a c h e l i n e * /
bdnz 1 b
isync
/* Now, flush the first 4MB of memory */
lis r4 ,0 x00 0 2
mtctr r4
li r4 ,0
sync
1 :
dcbf 0 ,r4
addi r4 ,r4 ,3 2 / * G o t o s t a r t o f n e x t c a c h e l i n e * /
bdnz 1 b
/* Flush and disable the L1 data cache */
mfspr r6 ,S P R N _ L D S T C R
lis r3 ,0 x f f f0 / * r e a d f r o m R O M f o r d i s p l a c e m e n t f l u s h * /
li r4 ,0 x f e / * s t a r t w i t h o n l y w a y 0 u n l o c k e d * /
li r5 ,1 2 8 / * 1 2 8 l i n e s i n e a c h w a y * /
1 : mtctr r5
rlwimi r6 ,r4 ,0 ,2 4 ,3 1
mtspr S P R N _ L D S T C R ,r6
sync
isync
2 : lwz r0 ,0 ( r3 ) / * t o u c h e a c h c a c h e l i n e * /
addi r3 ,r3 ,3 2
bdnz 2 b
rlwinm r4 ,r4 ,1 ,2 4 ,3 0 / * m o v e o n t o t h e n e x t w a y * /
ori r4 ,r4 ,1
cmpwi r4 ,0 x f f / * a l l d o n e ? * /
bne 1 b
/* now unlock the L1 data cache */
li r4 ,0
rlwimi r6 ,r4 ,0 ,2 4 ,3 1
sync
mtspr S P R N _ L D S T C R ,r6
sync
isync
/* Flush the L2 cache using the hardware assist */
mfspr r3 ,S P R N _ L 2 C R
cmpwi r3 ,0 / * c h e c k i f i t i s e n a b l e d f i r s t * /
bge 4 f
oris r0 ,r3 ,( L 2 C R _ L 2 I O _ 7 4 5 x | L 2 C R _ L 2 D O _ 7 4 5 x ) @h
b 2 f
/* When disabling/locking L2, code must be in L1 */
.balign 32
1 : mtspr S P R N _ L 2 C R ,r0 / * l o c k t h e L 2 c a c h e * /
3 : sync
isync
b 1 f
2 : b 3 f
3 : sync
isync
b 1 b
1 : sync
isync
ori r0 ,r3 ,L 2 C R _ L 2 H W F _ 7 4 5 x
sync
mtspr S P R N _ L 2 C R ,r0 / * s e t t h e h a r d w a r e f l u s h b i t * /
3 : mfspr r0 ,S P R N _ L 2 C R / * w a i t f o r i t t o g o t o 0 * /
andi. r0 ,r0 ,L 2 C R _ L 2 H W F _ 7 4 5 x
bne 3 b
sync
rlwinm r3 ,r3 ,0 ,~ L 2 C R _ L 2 E
b 2 f
/* When disabling L2, code must be in L1 */
.balign 32
1 : mtspr S P R N _ L 2 C R ,r3 / * d i s a b l e t h e L 2 c a c h e * /
3 : sync
isync
b 1 f
2 : b 3 f
3 : sync
isync
b 1 b
1 : sync
isync
oris r4 ,r3 ,L 2 C R _ L 2 I @h
mtspr S P R N _ L 2 C R ,r4
sync
isync
1 : mfspr r4 ,S P R N _ L 2 C R
andis. r0 ,r4 ,L 2 C R _ L 2 I @h
bne 1 b
sync
BEGIN_ F T R _ S E C T I O N
/* Flush the L3 cache using the hardware assist */
4 : mfspr r3 ,S P R N _ L 3 C R
cmpwi r3 ,0 / * c h e c k i f i t i s e n a b l e d * /
bge 6 f
oris r0 ,r3 ,L 3 C R _ L 3 I O @h
ori r0 ,r0 ,L 3 C R _ L 3 D O
sync
mtspr S P R N _ L 3 C R ,r0 / * l o c k t h e L 3 c a c h e * /
sync
isync
ori r0 ,r0 ,L 3 C R _ L 3 H W F
sync
mtspr S P R N _ L 3 C R ,r0 / * s e t t h e h a r d w a r e f l u s h b i t * /
5 : mfspr r0 ,S P R N _ L 3 C R / * w a i t f o r i t t o g o t o z e r o * /
andi. r0 ,r0 ,L 3 C R _ L 3 H W F
bne 5 b
rlwinm r3 ,r3 ,0 ,~ L 3 C R _ L 3 E
sync
mtspr S P R N _ L 3 C R ,r3 / * d i s a b l e t h e L 3 c a c h e * /
sync
ori r4 ,r3 ,L 3 C R _ L 3 I
mtspr S P R N _ L 3 C R ,r4
1 : mfspr r4 ,S P R N _ L 3 C R
andi. r0 ,r4 ,L 3 C R _ L 3 I
bne 1 b
sync
END_ F T R _ S E C T I O N _ I F S E T ( C P U _ F T R _ L 3 C R )
6 : mfspr r0 ,S P R N _ H I D 0 / * n o w d i s a b l e t h e L 1 d a t a c a c h e * /
rlwinm r0 ,r0 ,0 ,~ H I D 0 _ D C E
mtspr S P R N _ H I D 0 ,r0
sync
isync
mtmsr r11 / * r e s t o r e D R a n d E E * /
isync
blr
# endif / * C O N F I G _ 6 x x * /