2005-04-17 02:20:36 +04:00
# include < l i n u x / t h r e a d s . h >
# include < a s m / p r o c e s s o r . h >
# include < a s m / p a g e . h >
# include < a s m / c p u t a b l e . h >
# include < a s m / t h r e a d _ i n f o . 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
/ *
* Structure f o r s t o r i n g C P U r e g i s t e r s o n t h e s a v e a r e a .
* /
# define S L _ S P 0
# define S L _ P C 4
# define S L _ M S R 8
# define S L _ S D R 1 0 x c
# define S L _ S P R G 0 0 x10 / * 4 s p r g ' s * /
# define S L _ D B A T 0 0 x20
# define S L _ I B A T 0 0 x28
# define S L _ D B A T 1 0 x30
# define S L _ I B A T 1 0 x38
# define S L _ D B A T 2 0 x40
# define S L _ I B A T 2 0 x48
# define S L _ D B A T 3 0 x50
# define S L _ I B A T 3 0 x58
# define S L _ T B 0 x60
# define S L _ R 2 0 x68
# define S L _ C R 0 x6 c
# define S L _ L R 0 x70
# define S L _ R 1 2 0 x74 / * r12 t o r31 * /
# define S L _ S I Z E ( S L _ R 1 2 + 8 0 )
.section .data
.align 5
_ GLOBAL( s w s u s p _ s a v e _ a r e a )
.space SL_SIZE
.section .text
.align 5
_ GLOBAL( s w s u s p _ a r c h _ s u s p e n d )
lis r11 ,s w s u s p _ s a v e _ a r e a @h
ori r11 ,r11 ,s w s u s p _ s a v e _ a r e a @l
mflr r0
stw r0 ,S L _ L R ( r11 )
mfcr r0
stw r0 ,S L _ C R ( r11 )
stw r1 ,S L _ S P ( r11 )
stw r2 ,S L _ R 2 ( r11 )
stmw r12 ,S L _ R 1 2 ( r11 )
/* Save MSR & SDR1 */
mfmsr r4
stw r4 ,S L _ M S R ( r11 )
mfsdr1 r4
stw r4 ,S L _ S D R 1 ( r11 )
/* Get a stable timebase and save it */
1 : mftbu r4
stw r4 ,S L _ T B ( r11 )
mftb r5
stw r5 ,S L _ T B + 4 ( r11 )
mftbu r3
cmpw r3 ,r4
bne 1 b
/* Save SPRGs */
mfsprg r4 ,0
stw r4 ,S L _ S P R G 0 ( r11 )
mfsprg r4 ,1
stw r4 ,S L _ S P R G 0 + 4 ( r11 )
mfsprg r4 ,2
stw r4 ,S L _ S P R G 0 + 8 ( r11 )
mfsprg r4 ,3
stw r4 ,S L _ S P R G 0 + 1 2 ( r11 )
/* Save BATs */
mfdbatu r4 ,0
stw r4 ,S L _ D B A T 0 ( r11 )
mfdbatl r4 ,0
stw r4 ,S L _ D B A T 0 + 4 ( r11 )
mfdbatu r4 ,1
stw r4 ,S L _ D B A T 1 ( r11 )
mfdbatl r4 ,1
stw r4 ,S L _ D B A T 1 + 4 ( r11 )
mfdbatu r4 ,2
stw r4 ,S L _ D B A T 2 ( r11 )
mfdbatl r4 ,2
stw r4 ,S L _ D B A T 2 + 4 ( r11 )
mfdbatu r4 ,3
stw r4 ,S L _ D B A T 3 ( r11 )
mfdbatl r4 ,3
stw r4 ,S L _ D B A T 3 + 4 ( r11 )
mfibatu r4 ,0
stw r4 ,S L _ I B A T 0 ( r11 )
mfibatl r4 ,0
stw r4 ,S L _ I B A T 0 + 4 ( r11 )
mfibatu r4 ,1
stw r4 ,S L _ I B A T 1 ( r11 )
mfibatl r4 ,1
stw r4 ,S L _ I B A T 1 + 4 ( r11 )
mfibatu r4 ,2
stw r4 ,S L _ I B A T 2 ( r11 )
mfibatl r4 ,2
stw r4 ,S L _ I B A T 2 + 4 ( r11 )
mfibatu r4 ,3
stw r4 ,S L _ I B A T 3 ( r11 )
mfibatl r4 ,3
stw r4 ,S L _ I B A T 3 + 4 ( r11 )
# if 0
/* Backup various CPU config stuffs */
bl _ _ s a v e _ c p u _ s e t u p
# endif
/ * Call t h e l o w l e v e l s u s p e n d s t u f f ( w e s h o u l d p r o b a b l y h a v e m a d e
* a s t a c k f r a m e . . .
* /
bl s w s u s p _ s a v e
/* Restore LR from the save area */
lis r11 ,s w s u s p _ s a v e _ a r e a @h
ori r11 ,r11 ,s w s u s p _ s a v e _ a r e a @l
lwz r0 ,S L _ L R ( r11 )
mtlr r0
blr
/* Resume code */
_ GLOBAL( s w s u s p _ a r c h _ r e s u m e )
2007-11-07 15:59:44 +03:00
# ifdef C O N F I G _ A L T I V E C
2005-04-17 02:20:36 +04:00
/* Stop pending alitvec streams and memory accesses */
BEGIN_ F T R _ S E C T I O N
DSSALL
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 )
2007-11-07 15:59:44 +03:00
# endif
2005-04-17 02:20:36 +04:00
sync
/ * Disable M S R : D R t o m a k e s u r e w e d o n ' t t a k e a T L B o r
* hash m i s s d u r i n g t h e c o p y , a s o u r h a s h t a b l e w i l l
* for a w h i l e b e u n u s e a b l e . F o r . t e x t , w e a s s u m e w e a r e
* covered b y a B A T . T h i s w o r k s o n l y f o r n o n - G 5 a t t h i s
* point. G 5 w i l l n e e d a b e t t e r a p p r o a c h , p o s s i b l y u s i n g
* a s m a l l t e m p o r a r y h a s h t a b l e f i l l e d w i t h l a r g e m a p p i n g s ,
* disabling t h e M M U c o m p l e t e l y i s n ' t a g o o d o p t i o n f o r
* performance r e a s o n s .
* ( Note t h a t 7 5 0 ' s m a y h a v e t h e s a m e p e r f o r m a n c e i s s u e a s
* the G 5 i n t h i s c a s e , w e s h o u l d i n v e s t i g a t e u s i n g m o v i n g
* BATs f o r t h e s e C P U s )
* /
mfmsr r0
sync
rlwinm r0 ,r0 ,0 ,2 8 ,2 6 / * c l e a r M S R _ D R * /
mtmsr r0
sync
isync
/* Load ptr the list of pages to copy in r3 */
2006-09-26 10:32:52 +04:00
lis r11 ,( r e s t o r e _ p b l i s t - K E R N E L B A S E ) @h
ori r11 ,r11 ,r e s t o r e _ p b l i s t @l
2005-04-17 02:20:36 +04:00
lwz r10 ,0 ( r11 )
/ * Copy t h e p a g e s . T h i s i s a v e r y b a s i c i m p l e m e n t a t i o n , t o
* be r e p l a c e d b y s o m e t h i n g m o r e c a c h e e f f i c i e n t * /
1 :
tophys( r3 ,r10 )
li r0 ,2 5 6
mtctr r0
lwz r11 ,p b e _ a d d r e s s ( r3 ) / * s o u r c e * /
tophys( r5 ,r11 )
lwz r10 ,p b e _ o r i g _ a d d r e s s ( r3 ) / * d e s t i n a t i o n * /
tophys( r6 ,r10 )
2 :
lwz r8 ,0 ( r5 )
lwz r9 ,4 ( r5 )
lwz r10 ,8 ( r5 )
lwz r11 ,1 2 ( r5 )
addi r5 ,r5 ,1 6
stw r8 ,0 ( r6 )
stw r9 ,4 ( r6 )
stw r10 ,8 ( r6 )
stw r11 ,1 2 ( r6 )
addi r6 ,r6 ,1 6
bdnz 2 b
lwz r10 ,p b e _ n e x t ( r3 )
cmpwi 0 ,r10 ,0
bne 1 b
/ * Do a v e r y s i m p l e c a c h e f l u s h / i n v a l o f t h e L 1 t o e n s u r e
* coherency o f t h e i c a c h e
* /
lis r3 ,0 x00 0 2
mtctr r3
li r3 , 0
1 :
lwz r0 ,0 ( r3 )
addi r3 ,r3 ,0 x00 2 0
bdnz 1 b
isync
sync
/* Now flush those cache lines */
lis r3 ,0 x00 0 2
mtctr r3
li r3 , 0
1 :
dcbf 0 ,r3
addi r3 ,r3 ,0 x00 2 0
bdnz 1 b
sync
/ * Ok, w e a r e n o w r u n n i n g w i t h t h e k e r n e l d a t a o f t h e o l d
* kernel f u l l y r e s t o r e d . W e c a n g e t t o t h e s a v e a r e a
* easily n o w . A s f o r t h e r e s t o f t h e c o d e , i t a s s u m e s t h e
* loader k e r n e l a n d t h e b o o t e d o n e a r e e x a c t l y i d e n t i c a l
* /
lis r11 ,s w s u s p _ s a v e _ a r e a @h
ori r11 ,r11 ,s w s u s p _ s a v e _ a r e a @l
tophys( r11 ,r11 )
# if 0
/* Restore various CPU config stuffs */
bl _ _ r e s t o r e _ c p u _ s e t u p
# endif
/ * Restore t h e B A T s , a n d S D R 1 . T h e n w e c a n t u r n o n t h e M M U .
* This i s a b i t h a i r y a s w e a r e r u n n i n g o u t o f t h o s e B A T s ,
* but f i r s t , o u r c o d e i s p r o b a b l y i n t h e i c a c h e , a n d w e a r e
* writing t h e s a m e v a l u e t o t h e B A T , s o t h a t s h o u l d b e f i n e ,
* though a b e t t e r s o l u t i o n w i l l h a v e t o b e f o u n d l o n g - t e r m
* /
lwz r4 ,S L _ S D R 1 ( r11 )
mtsdr1 r4
lwz r4 ,S L _ S P R G 0 ( r11 )
mtsprg 0 ,r4
lwz r4 ,S L _ S P R G 0 + 4 ( r11 )
mtsprg 1 ,r4
lwz r4 ,S L _ S P R G 0 + 8 ( r11 )
mtsprg 2 ,r4
lwz r4 ,S L _ S P R G 0 + 1 2 ( r11 )
mtsprg 3 ,r4
# if 0
lwz r4 ,S L _ D B A T 0 ( r11 )
mtdbatu 0 ,r4
lwz r4 ,S L _ D B A T 0 + 4 ( r11 )
mtdbatl 0 ,r4
lwz r4 ,S L _ D B A T 1 ( r11 )
mtdbatu 1 ,r4
lwz r4 ,S L _ D B A T 1 + 4 ( r11 )
mtdbatl 1 ,r4
lwz r4 ,S L _ D B A T 2 ( r11 )
mtdbatu 2 ,r4
lwz r4 ,S L _ D B A T 2 + 4 ( r11 )
mtdbatl 2 ,r4
lwz r4 ,S L _ D B A T 3 ( r11 )
mtdbatu 3 ,r4
lwz r4 ,S L _ D B A T 3 + 4 ( r11 )
mtdbatl 3 ,r4
lwz r4 ,S L _ I B A T 0 ( r11 )
mtibatu 0 ,r4
lwz r4 ,S L _ I B A T 0 + 4 ( r11 )
mtibatl 0 ,r4
lwz r4 ,S L _ I B A T 1 ( r11 )
mtibatu 1 ,r4
lwz r4 ,S L _ I B A T 1 + 4 ( r11 )
mtibatl 1 ,r4
lwz r4 ,S L _ I B A T 2 ( r11 )
mtibatu 2 ,r4
lwz r4 ,S L _ I B A T 2 + 4 ( r11 )
mtibatl 2 ,r4
lwz r4 ,S L _ I B A T 3 ( r11 )
mtibatu 3 ,r4
lwz r4 ,S L _ I B A T 3 + 4 ( r11 )
mtibatl 3 ,r4
# endif
BEGIN_ F T R _ S E C T I O N
li r4 ,0
mtspr S P R N _ D B A T 4 U ,r4
mtspr S P R N _ D B A T 4 L ,r4
mtspr S P R N _ D B A T 5 U ,r4
mtspr S P R N _ D B A T 5 L ,r4
mtspr S P R N _ D B A T 6 U ,r4
mtspr S P R N _ D B A T 6 L ,r4
mtspr S P R N _ D B A T 7 U ,r4
mtspr S P R N _ D B A T 7 L ,r4
mtspr S P R N _ I B A T 4 U ,r4
mtspr S P R N _ I B A T 4 L ,r4
mtspr S P R N _ I B A T 5 U ,r4
mtspr S P R N _ I B A T 5 L ,r4
mtspr S P R N _ I B A T 6 U ,r4
mtspr S P R N _ I B A T 6 L ,r4
mtspr S P R N _ I B A T 7 U ,r4
mtspr S P R N _ I B A T 7 L ,r4
END_ F T R _ S E C T I O N _ I F S E T ( C P U _ F T R _ H A S _ H I G H _ B A T S )
/* Flush all TLBs */
lis r4 ,0 x10 0 0
1 : addic. r4 ,r4 ,- 0 x10 0 0
tlbie r4
blt 1 b
sync
/* restore the MSR and turn on the MMU */
lwz r3 ,S L _ M S R ( r11 )
bl t u r n _ o n _ m m u
tovirt( r11 ,r11 )
/* Restore TB */
li r3 ,0
mttbl r3
lwz r3 ,S L _ T B ( r11 )
lwz r4 ,S L _ T B + 4 ( r11 )
mttbu r3
mttbl r4
/* Kick decrementer */
li r0 ,1
mtdec r0
/* Restore the callee-saved registers and return */
lwz r0 ,S L _ C R ( r11 )
mtcr r0
lwz r2 ,S L _ R 2 ( r11 )
lmw r12 ,S L _ R 1 2 ( r11 )
lwz r1 ,S L _ S P ( r11 )
lwz r0 ,S L _ L R ( r11 )
mtlr r0
/ / XXX N o t e : w e d o n ' t r e a l l y n e e d t o c a l l s w s u s p _ r e s u m e
li r3 ,0
blr
/ * FIXME : This c o n s t r u c t i s a c t u a l l y n o t u s e f u l s i n c e w e d o n ' t s h u t
* down t h e i n s t r u c t i o n M M U , w e c o u l d j u s t f l i p b a c k M S R - D R o n .
* /
turn_on_mmu :
mflr r4
mtsrr0 r4
mtsrr1 r3
sync
isync
rfi