2005-10-10 16:36:14 +04:00
/ *
* arch/ p o w e r p c / k e r n e l / m i s c64 . S
*
* This f i l e c o n t a i n s m i s c e l l a n e o u s l o w - l e v e l f u n c t i o n s .
* Copyright ( C ) 1 9 9 5 - 1 9 9 6 G a r y T h o m a s ( g d t @linuxppc.org)
*
* Largely r e w r i t t e n b y C o r t D o u g a n ( c o r t @cs.nmt.edu)
* and P a u l M a c k e r r a s .
* Adapted f o r i S e r i e s b y M i k e C o r r i g a n ( m i k e j c @us.ibm.com)
* PPC6 4 u p d a t e s b y D a v e E n g e b r e t s e n ( e n g e b r e t @us.ibm.com)
*
* 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 < l i n u x / s y s . h >
# include < a s m / u n i s t d . h >
# include < a s m / e r r n o . 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 a c h e . h >
# include < a s m / p p c _ a s m . h >
# include < a s m / a s m - o f f s e t s . h >
# include < a s m / c p u t a b l e . h >
[PATCH] powerpc: Merge thread_info.h
Merge ppc32 and ppc64 versions of thread_info.h. They were pretty
similar already, the chief changes are:
- Instead of inline asm to implement current_thread_info(),
which needs to be different for ppc32 and ppc64, we use C with an
asm("r1") register variable. gcc turns it into the same asm as we
used to have for both platforms.
- We replace ppc32's 'local_flags' with the ppc64
'syscall_noerror' field. The noerror flag was in fact the only thing
in the local_flags field anyway, so the ppc64 approach is simpler, and
means we only need a load-immediate/store instead of load/mask/store
when clearing the flag.
- In readiness for 64k pages, when THREAD_SIZE will be less
than a page, ppc64 used kmalloc() rather than get_free_pages() to
allocate the kernel stack. With this patch we do the same for ppc32,
since there's no strong reason not to.
- For ppc64, we no longer export THREAD_SHIFT and THREAD_SIZE
via asm-offsets, thread_info.h can now be safely included in asm, as
on ppc32.
Built and booted on G4 Powerbook (ARCH=ppc and ARCH=powerpc) and
Power5 (ARCH=ppc64 and ARCH=powerpc).
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Paul Mackerras <paulus@samba.org>
2005-10-21 09:45:50 +04:00
# include < a s m / t h r e a d _ i n f o . h >
2005-10-10 16:36:14 +04:00
.text
/ *
* Returns ( a d d r e s s w e a r e r u n n i n g a t ) - ( a d d r e s s w e w e r e l i n k e d a t )
* for u s e b e f o r e t h e t e x t a n d d a t a a r e m a p p e d t o K E R N E L B A S E .
* /
_ GLOBAL( r e l o c _ o f f s e t )
mflr r0
bl 1 f
1 : mflr r3
2006-01-13 06:56:25 +03:00
LOAD_ R E G _ I M M E D I A T E ( r4 ,1 b )
2005-10-10 16:36:14 +04:00
subf r3 ,r4 ,r3
mtlr r0
blr
/ *
* add_ r e l o c _ o f f s e t ( x ) r e t u r n s x + r e l o c _ o f f s e t ( ) .
* /
_ GLOBAL( a d d _ r e l o c _ o f f s e t )
mflr r0
bl 1 f
1 : mflr r5
2006-01-13 06:56:25 +03:00
LOAD_ R E G _ I M M E D I A T E ( r4 ,1 b )
2005-10-10 16:36:14 +04:00
subf r5 ,r4 ,r5
add r3 ,r3 ,r5
mtlr r0
blr
_ GLOBAL( g e t _ m s r )
mfmsr r3
blr
_ GLOBAL( g e t _ d a r )
mfdar r3
blr
_ GLOBAL( g e t _ s r r0 )
mfsrr0 r3
blr
_ GLOBAL( g e t _ s r r1 )
mfsrr1 r3
blr
_ GLOBAL( g e t _ s p )
mr r3 ,r1
blr
# ifdef C O N F I G _ I R Q S T A C K S
_ GLOBAL( c a l l _ d o _ s o f t i r q )
mflr r0
std r0 ,1 6 ( r1 )
stdu r1 ,T H R E A D _ S I Z E - 1 1 2 ( r3 )
mr r1 ,r3
bl . _ _ d o _ s o f t i r q
ld r1 ,0 ( r1 )
ld r0 ,1 6 ( r1 )
mtlr r0
blr
2005-11-09 08:19:53 +03:00
_ GLOBAL( c a l l _ _ _ d o _ I R Q )
2005-10-10 16:36:14 +04:00
mflr r0
std r0 ,1 6 ( r1 )
2005-11-09 05:28:33 +03:00
stdu r1 ,T H R E A D _ S I Z E - 1 1 2 ( r5 )
mr r1 ,r5
2005-11-09 08:19:53 +03:00
bl . _ _ d o _ I R Q
2005-10-10 16:36:14 +04:00
ld r1 ,0 ( r1 )
ld r0 ,1 6 ( r1 )
mtlr r0
blr
# endif / * C O N F I G _ I R Q S T A C K S * /
/ *
* To b e c a l l e d b y C c o d e w h i c h n e e d s t o d o s o m e o p e r a t i o n s w i t h M M U
* disabled. N o t e t h a t i n t e r r u p t s h a v e t o b e d i s a b l e d b y t h e c a l l e r
* prior t o c a l l i n g u s . T h e c o d e c a l l e d _ M U S T _ b e i n t h e R M O o f c o u r s e
* and p a r t o f t h e l i n e a r m a p p i n g a s w e d o n ' t a t t e m p t t o t r a n s l a t e t h e
* stack p o i n t e r a t a l l . T h e f u n c t i o n i s c a l l e d w i t h t h e s t a c k s w i t c h e d
* to t h i s C P U e m e r g e n c y s t a c k
*
* prototype i s v o i d * c a l l _ w i t h _ m m u _ o f f ( v o i d * f u n c , v o i d * d a t a ) ;
*
* the c a l l e d f u n c t i o n i s e x p e c t e d t o b e o f t h e f o r m
*
* void * c a l l e d ( v o i d * d a t a ) ;
* /
_ GLOBAL( c a l l _ w i t h _ m m u _ o f f )
mflr r0 / * g e t l i n k , s a v e i t o n s t a c k f r a m e * /
std r0 ,1 6 ( r1 )
mr r1 ,r5 / * s a v e o l d s t a c k p t r * /
ld r1 ,P A C A E M E R G S P ( r13 ) / * g e t e m e r g . s t a c k * /
subi r1 ,r1 ,S T A C K _ F R A M E _ O V E R H E A D
std r0 ,1 6 ( r1 ) / * s a v e l i n k o n e m e r g . s t a c k * /
std r5 ,0 ( r1 ) / * s a v e o l d s t a c k p t r i n b a c k c h a i n * /
ld r3 ,0 ( r3 ) / * g e t t o r e a l f u n c t i o n p t r ( a s s u m e s a m e T O C ) * /
bl 2 f / * w e n e e d L R t o r e t u r n , c o n t i n u e a t l a b e l 2 * /
ld r0 ,1 6 ( r1 ) / * w e r e t u r n h e r e f r o m t h e c a l l , g e t L R a n d * /
ld r1 ,0 ( r1 ) / * . . o l d s t a c k p t r * /
mtspr S P R N _ S R R 0 ,r0 / * a n d g e t b a c k t o v i r t u a l m o d e w i t h t h e s e * /
mfmsr r4
ori r4 ,r4 ,M S R _ I R | M S R _ D R
mtspr S P R N _ S R R 1 ,r4
rfid
2 : mtspr S P R N _ S R R 0 ,r3 / * c o m i n g f r o m a b o v e , e n t e r r e a l m o d e * /
mr r3 ,r4 / * g e t p a r a m e t e r * /
mfmsr r0
ori r0 ,r0 ,M S R _ I R | M S R _ D R
xori r0 ,r0 ,M S R _ I R | M S R _ D R
mtspr S P R N _ S R R 1 ,r0
rfid
.section " .toc " , " aw"
PPC64_CACHES :
.tc ppc6 4 _ c a c h e s [ T C ] ,p p c64 _ c a c h e s
.section " .text "
/ *
* Write a n y m o d i f i e d d a t a c a c h e b l o c k s o u t t o m e m o r y
* and i n v a l i d a t e t h e c o r r e s p o n d i n g i n s t r u c t i o n c a c h e b l o c k s .
*
* flush_ i c a c h e _ r a n g e ( u n s i g n e d l o n g s t a r t , u n s i g n e d l o n g s t o p )
*
* flush a l l b y t e s f r o m s t a r t t h r o u g h s t o p - 1 i n c l u s i v e
* /
_ KPROBE( _ _ f l u s h _ i c a c h e _ r a n g e )
/ *
* Flush t h e d a t a c a c h e t o m e m o r y
*
* Different s y s t e m s h a v e d i f f e r e n t c a c h e l i n e s i z e s
* and i n s o m e c a s e s i - c a c h e a n d d - c a c h e l i n e s i z e s d i f f e r f r o m
* each o t h e r .
* /
ld r10 ,P P C 6 4 _ C A C H E S @toc(r2)
lwz r7 ,D C A C H E L 1 L I N E S I Z E ( r10 ) / * G e t c a c h e l i n e s i z e * /
addi r5 ,r7 ,- 1
andc r6 ,r3 ,r5 / * r o u n d l o w t o l i n e b d y * /
subf r8 ,r6 ,r4 / * c o m p u t e l e n g t h * /
add r8 ,r8 ,r5 / * e n s u r e w e g e t e n o u g h * /
lwz r9 ,D C A C H E L 1 L O G L I N E S I Z E ( r10 ) / * G e t l o g - 2 o f c a c h e l i n e s i z e * /
srw. r8 ,r8 ,r9 / * c o m p u t e l i n e c o u n t * /
beqlr / * n o t h i n g t o d o ? * /
mtctr r8
1 : dcbst 0 ,r6
add r6 ,r6 ,r7
bdnz 1 b
sync
/* Now invalidate the instruction cache */
lwz r7 ,I C A C H E L 1 L I N E S I Z E ( r10 ) / * G e t I c a c h e l i n e s i z e * /
addi r5 ,r7 ,- 1
andc r6 ,r3 ,r5 / * r o u n d l o w t o l i n e b d y * /
subf r8 ,r6 ,r4 / * c o m p u t e l e n g t h * /
add r8 ,r8 ,r5
lwz r9 ,I C A C H E L 1 L O G L I N E S I Z E ( r10 ) / * G e t l o g - 2 o f I c a c h e l i n e s i z e * /
srw. r8 ,r8 ,r9 / * c o m p u t e l i n e c o u n t * /
beqlr / * n o t h i n g t o d o ? * /
mtctr r8
2 : icbi 0 ,r6
add r6 ,r6 ,r7
bdnz 2 b
isync
blr
.previous .text
/ *
* Like a b o v e , b u t o n l y d o t h e D - c a c h e .
*
* flush_ d c a c h e _ r a n g e ( u n s i g n e d l o n g s t a r t , u n s i g n e d l o n g s t o p )
*
* flush a l l b y t e s f r o m s t a r t t o s t o p - 1 i n c l u s i v e
* /
_ GLOBAL( f l u s h _ d c a c h e _ r a n g e )
/ *
* Flush t h e d a t a c a c h e t o m e m o r y
*
* Different s y s t e m s h a v e d i f f e r e n t c a c h e l i n e s i z e s
* /
ld r10 ,P P C 6 4 _ C A C H E S @toc(r2)
lwz r7 ,D C A C H E L 1 L I N E S I Z E ( r10 ) / * G e t d c a c h e l i n e s i z e * /
addi r5 ,r7 ,- 1
andc r6 ,r3 ,r5 / * r o u n d l o w t o l i n e b d y * /
subf r8 ,r6 ,r4 / * c o m p u t e l e n g t h * /
add r8 ,r8 ,r5 / * e n s u r e w e g e t e n o u g h * /
lwz r9 ,D C A C H E L 1 L O G L I N E S I Z E ( r10 ) / * G e t l o g - 2 o f d c a c h e l i n e s i z e * /
srw. r8 ,r8 ,r9 / * c o m p u t e l i n e c o u n t * /
beqlr / * n o t h i n g t o d o ? * /
mtctr r8
0 : dcbst 0 ,r6
add r6 ,r6 ,r7
bdnz 0 b
sync
blr
/ *
* Like a b o v e , b u t w o r k s o n n o n - m a p p e d p h y s i c a l a d d r e s s e s .
* Use o n l y f o r n o n - L P A R s e t u p s ! I t a l s o a s s u m e s r e a l m o d e
* is c a c h e a b l e . U s e d f o r f l u s h i n g o u t t h e D A R T b e f o r e u s i n g
* it a s u n c a c h e a b l e m e m o r y
*
* flush_ d c a c h e _ p h y s _ r a n g e ( u n s i g n e d l o n g s t a r t , u n s i g n e d l o n g s t o p )
*
* flush a l l b y t e s f r o m s t a r t t o s t o p - 1 i n c l u s i v e
* /
_ GLOBAL( f l u s h _ d c a c h e _ p h y s _ r a n g e )
ld r10 ,P P C 6 4 _ C A C H E S @toc(r2)
lwz r7 ,D C A C H E L 1 L I N E S I Z E ( r10 ) / * G e t d c a c h e l i n e s i z e * /
addi r5 ,r7 ,- 1
andc r6 ,r3 ,r5 / * r o u n d l o w t o l i n e b d y * /
subf r8 ,r6 ,r4 / * c o m p u t e l e n g t h * /
add r8 ,r8 ,r5 / * e n s u r e w e g e t e n o u g h * /
lwz r9 ,D C A C H E L 1 L O G L I N E S I Z E ( r10 ) / * G e t l o g - 2 o f d c a c h e l i n e s i z e * /
srw. r8 ,r8 ,r9 / * c o m p u t e l i n e c o u n t * /
beqlr / * n o t h i n g t o d o ? * /
mfmsr r5 / * D i s a b l e M M U D a t a R e l o c a t i o n * /
ori r0 ,r5 ,M S R _ D R
xori r0 ,r0 ,M S R _ D R
sync
mtmsr r0
sync
isync
mtctr r8
0 : dcbst 0 ,r6
add r6 ,r6 ,r7
bdnz 0 b
sync
isync
mtmsr r5 / * R e - e n a b l e M M U D a t a R e l o c a t i o n * /
sync
isync
blr
_ GLOBAL( f l u s h _ i n v a l _ d c a c h e _ r a n g e )
ld r10 ,P P C 6 4 _ C A C H E S @toc(r2)
lwz r7 ,D C A C H E L 1 L I N E S I Z E ( r10 ) / * G e t d c a c h e l i n e s i z e * /
addi r5 ,r7 ,- 1
andc r6 ,r3 ,r5 / * r o u n d l o w t o l i n e b d y * /
subf r8 ,r6 ,r4 / * c o m p u t e l e n g t h * /
add r8 ,r8 ,r5 / * e n s u r e w e g e t e n o u g h * /
lwz r9 ,D C A C H E L 1 L O G L I N E S I Z E ( r10 ) / * G e t l o g - 2 o f d c a c h e l i n e s i z e * /
srw. r8 ,r8 ,r9 / * c o m p u t e l i n e c o u n t * /
beqlr / * n o t h i n g t o d o ? * /
sync
isync
mtctr r8
0 : dcbf 0 ,r6
add r6 ,r6 ,r7
bdnz 0 b
sync
isync
blr
/ *
* Flush a p a r t i c u l a r p a g e f r o m t h e d a t a c a c h e t o R A M .
* Note : this i s n e c e s s a r y b e c a u s e t h e i n s t r u c t i o n c a c h e d o e s * n o t *
* snoop f r o m t h e d a t a c a c h e .
*
* void _ _ f l u s h _ d c a c h e _ i c a c h e ( v o i d * p a g e )
* /
_ GLOBAL( _ _ f l u s h _ d c a c h e _ i c a c h e )
/ *
* Flush t h e d a t a c a c h e t o m e m o r y
*
* Different s y s t e m s h a v e d i f f e r e n t c a c h e l i n e s i z e s
* /
/* Flush the dcache */
ld r7 ,P P C 6 4 _ C A C H E S @toc(r2)
clrrdi r3 ,r3 ,P A G E _ S H I F T / * P a g e a l i g n * /
lwz r4 ,D C A C H E L 1 L I N E S P E R P A G E ( r7 ) / * G e t # d c a c h e l i n e s p e r p a g e * /
lwz r5 ,D C A C H E L 1 L I N E S I Z E ( r7 ) / * G e t d c a c h e l i n e s i z e * /
mr r6 ,r3
mtctr r4
0 : dcbst 0 ,r6
add r6 ,r6 ,r5
bdnz 0 b
sync
/* Now invalidate the icache */
lwz r4 ,I C A C H E L 1 L I N E S P E R P A G E ( r7 ) / * G e t # i c a c h e l i n e s p e r p a g e * /
lwz r5 ,I C A C H E L 1 L I N E S I Z E ( r7 ) / * G e t i c a c h e l i n e s i z e * /
mtctr r4
1 : icbi 0 ,r3
add r3 ,r3 ,r5
bdnz 1 b
isync
blr
/ *
* I/ O s t r i n g o p e r a t i o n s
*
* insb( p o r t , b u f , l e n )
* outsb( p o r t , b u f , l e n )
* insw( p o r t , b u f , l e n )
* outsw( p o r t , b u f , l e n )
* insl( p o r t , b u f , l e n )
* outsl( p o r t , b u f , l e n )
* insw_ n s ( p o r t , b u f , l e n )
* outsw_ n s ( p o r t , b u f , l e n )
* insl_ n s ( p o r t , b u f , l e n )
* outsl_ n s ( p o r t , b u f , l e n )
*
* The * _ n s v e r s i o n s d o n ' t d o b y t e - s w a p p i n g .
* /
_ GLOBAL( _ i n s b )
cmpwi 0 ,r5 ,0
mtctr r5
subi r4 ,r4 ,1
blelr-
00 : lbz r5 ,0 ( r3 )
eieio
stbu r5 ,1 ( r4 )
bdnz 0 0 b
twi 0 ,r5 ,0
isync
blr
_ GLOBAL( _ o u t s b )
cmpwi 0 ,r5 ,0
mtctr r5
subi r4 ,r4 ,1
blelr-
00 : lbzu r5 ,1 ( r4 )
stb r5 ,0 ( r3 )
bdnz 0 0 b
sync
blr
_ GLOBAL( _ i n s w )
cmpwi 0 ,r5 ,0
mtctr r5
subi r4 ,r4 ,2
blelr-
00 : lhbrx r5 ,0 ,r3
eieio
sthu r5 ,2 ( r4 )
bdnz 0 0 b
twi 0 ,r5 ,0
isync
blr
_ GLOBAL( _ o u t s w )
cmpwi 0 ,r5 ,0
mtctr r5
subi r4 ,r4 ,2
blelr-
00 : lhzu r5 ,2 ( r4 )
sthbrx r5 ,0 ,r3
bdnz 0 0 b
sync
blr
_ GLOBAL( _ i n s l )
cmpwi 0 ,r5 ,0
mtctr r5
subi r4 ,r4 ,4
blelr-
00 : lwbrx r5 ,0 ,r3
eieio
stwu r5 ,4 ( r4 )
bdnz 0 0 b
twi 0 ,r5 ,0
isync
blr
_ GLOBAL( _ o u t s l )
cmpwi 0 ,r5 ,0
mtctr r5
subi r4 ,r4 ,4
blelr-
00 : lwzu r5 ,4 ( r4 )
stwbrx r5 ,0 ,r3
bdnz 0 0 b
sync
blr
/* _GLOBAL(ide_insw) now in drivers/ide/ide-iops.c */
_ GLOBAL( _ i n s w _ n s )
cmpwi 0 ,r5 ,0
mtctr r5
subi r4 ,r4 ,2
blelr-
00 : lhz r5 ,0 ( r3 )
eieio
sthu r5 ,2 ( r4 )
bdnz 0 0 b
twi 0 ,r5 ,0
isync
blr
/* _GLOBAL(ide_outsw) now in drivers/ide/ide-iops.c */
_ GLOBAL( _ o u t s w _ n s )
cmpwi 0 ,r5 ,0
mtctr r5
subi r4 ,r4 ,2
blelr-
00 : lhzu r5 ,2 ( r4 )
sth r5 ,0 ( r3 )
bdnz 0 0 b
sync
blr
_ GLOBAL( _ i n s l _ n s )
cmpwi 0 ,r5 ,0
mtctr r5
subi r4 ,r4 ,4
blelr-
00 : lwz r5 ,0 ( r3 )
eieio
stwu r5 ,4 ( r4 )
bdnz 0 0 b
twi 0 ,r5 ,0
isync
blr
_ GLOBAL( _ o u t s l _ n s )
cmpwi 0 ,r5 ,0
mtctr r5
subi r4 ,r4 ,4
blelr-
00 : lwzu r5 ,4 ( r4 )
stw r5 ,0 ( r3 )
bdnz 0 0 b
sync
blr
/ *
* identify_ c p u a n d c a l l s s e t u p _ c p u
* In : r3 = b a s e o f t h e c p u _ s p e c s a r r a y
* r4 = a d d r e s s o f c u r _ c p u _ s p e c
* r5 = r e l o c a t i o n o f f s e t
* /
_ GLOBAL( i d e n t i f y _ c p u )
mfpvr r7
1 :
lwz r8 ,C P U _ S P E C _ P V R _ M A S K ( r3 )
and r8 ,r8 ,r7
lwz r9 ,C P U _ S P E C _ P V R _ V A L U E ( r3 )
cmplw 0 ,r9 ,r8
beq 1 f
addi r3 ,r3 ,C P U _ S P E C _ E N T R Y _ S I Z E
b 1 b
1 :
sub r0 ,r3 ,r5
std r0 ,0 ( r4 )
ld r4 ,C P U _ S P E C _ S E T U P ( r3 )
add r4 ,r4 ,r5
ld r4 ,0 ( r4 )
add r4 ,r4 ,r5
mtctr r4
/* Calling convention for cpu setup is r3=offset, r4=cur_cpu_spec */
mr r4 ,r3
mr r3 ,r5
bctr
/ *
* do_ c p u _ f t r _ f i x u p s - g o e s t h r o u g h t h e l i s t o f C P U f e a t u r e f i x u p s
* and w r i t e s n o p ' s o v e r s e c t i o n s o f c o d e t h a t d o n ' t a p p l y f o r t h i s c p u .
* r3 = d a t a o f f s e t ( n o t c h a n g e d )
* /
_ GLOBAL( d o _ c p u _ f t r _ f i x u p s )
/* Get CPU 0 features */
2006-01-13 06:56:25 +03:00
LOAD_ R E G _ I M M E D I A T E ( r6 ,c u r _ c p u _ s p e c )
2005-10-10 16:36:14 +04:00
sub r6 ,r6 ,r3
ld r4 ,0 ( r6 )
sub r4 ,r4 ,r3
ld r4 ,C P U _ S P E C _ F E A T U R E S ( r4 )
/* Get the fixup table */
2006-01-13 06:56:25 +03:00
LOAD_ R E G _ I M M E D I A T E ( r6 ,_ _ s t a r t _ _ _ f t r _ f i x u p )
2005-10-10 16:36:14 +04:00
sub r6 ,r6 ,r3
2006-01-13 06:56:25 +03:00
LOAD_ R E G _ I M M E D I A T E ( r7 ,_ _ s t o p _ _ _ f t r _ f i x u p )
2005-10-10 16:36:14 +04:00
sub r7 ,r7 ,r3
/* Do the fixup */
1 : cmpld r6 ,r7
bgelr
addi r6 ,r6 ,3 2
ld r8 ,- 3 2 ( r6 ) / * m a s k * /
and r8 ,r8 ,r4
ld r9 ,- 2 4 ( r6 ) / * v a l u e * /
cmpld r8 ,r9
beq 1 b
ld r8 ,- 1 6 ( r6 ) / * s e c t i o n b e g i n * /
ld r9 ,- 8 ( r6 ) / * s e c t i o n e n d * /
subf. r9 ,r8 ,r9
beq 1 b
/* write nops over the section of code */
/* todo: if large section, add a branch at the start of it */
srwi r9 ,r9 ,2
mtctr r9
sub r8 ,r8 ,r3
lis r0 ,0 x60 0 0 0 0 0 0 @h /* nop */
3 : stw r0 ,0 ( r8 )
andi. r10 ,r4 ,C P U _ F T R _ S P L I T _ I D _ C A C H E @l
beq 2 f
dcbst 0 ,r8 / * s u b o p t i m a l , b u t s i m p l e r * /
sync
icbi 0 ,r8
2 : addi r8 ,r8 ,4
bdnz 3 b
sync / * a d d i t i o n a l s y n c n e e d e d o n g 4 * /
isync
b 1 b
# if d e f i n e d ( C O N F I G _ P P C _ P M A C ) | | d e f i n e d ( C O N F I G _ P P C _ M A P L E )
/ *
* Do a n I O a c c e s s i n r e a l m o d e
* /
_ GLOBAL( r e a l _ r e a d b )
mfmsr r7
ori r0 ,r7 ,M S R _ D R
xori r0 ,r0 ,M S R _ D R
sync
mtmsrd r0
sync
isync
mfspr r6 ,S P R N _ H I D 4
rldicl r5 ,r6 ,3 2 ,0
ori r5 ,r5 ,0 x10 0
rldicl r5 ,r5 ,3 2 ,0
sync
mtspr S P R N _ H I D 4 ,r5
isync
slbia
isync
lbz r3 ,0 ( r3 )
sync
mtspr S P R N _ H I D 4 ,r6
isync
slbia
isync
mtmsrd r7
sync
isync
blr
/ *
* Do a n I O a c c e s s i n r e a l m o d e
* /
_ GLOBAL( r e a l _ w r i t e b )
mfmsr r7
ori r0 ,r7 ,M S R _ D R
xori r0 ,r0 ,M S R _ D R
sync
mtmsrd r0
sync
isync
mfspr r6 ,S P R N _ H I D 4
rldicl r5 ,r6 ,3 2 ,0
ori r5 ,r5 ,0 x10 0
rldicl r5 ,r5 ,3 2 ,0
sync
mtspr S P R N _ H I D 4 ,r5
isync
slbia
isync
stb r3 ,0 ( r4 )
sync
mtspr S P R N _ H I D 4 ,r6
isync
slbia
isync
mtmsrd r7
sync
isync
blr
# endif / * d e f i n e d ( C O N F I G _ P P C _ P M A C ) | | d e f i n e d ( C O N F I G _ P P C _ M A P L E ) * /
2005-11-07 06:27:33 +03:00
/ *
* SCOM a c c e s s f u n c t i o n s f o r 9 7 0 ( F X o n l y f o r n o w )
*
* unsigned l o n g s c o m 9 7 0 _ r e a d ( u n s i g n e d i n t a d d r e s s ) ;
* void s c o m 9 7 0 _ w r i t e ( u n s i g n e d i n t a d d r e s s , u n s i g n e d l o n g v a l u e ) ;
*
* The a d d r e s s p a s s e d i n i s t h e 2 4 b i t s r e g i s t e r a d d r e s s . T h i s c o d e
* is 9 7 0 s p e c i f i c a n d w i l l n o t c h e c k t h e s t a t u s b i t s , s o y o u s h o u l d
* know w h a t y o u a r e d o i n g .
* /
_ GLOBAL( s c o m 9 7 0 _ r e a d )
/* interrupts off */
mfmsr r4
ori r0 ,r4 ,M S R _ E E
xori r0 ,r0 ,M S R _ E E
mtmsrd r0 ,1
/ * rotate 2 4 b i t s S C O M a d d r e s s 8 b i t s l e f t a n d m a s k o u t i t ' s l o w 8 b i t s
* ( including p a r i t y ) . O n c u r r e n t C P U s t h e y m u s t b e 0 ' d ,
* and f i n a l l y o r i n R W b i t
* /
rlwinm r3 ,r3 ,8 ,0 ,1 5
ori r3 ,r3 ,0 x80 0 0
/* do the actual scom read */
sync
mtspr S P R N _ S C O M C ,r3
isync
mfspr r3 ,S P R N _ S C O M D
isync
mfspr r0 ,S P R N _ S C O M C
isync
/ * XXX : fixup r e s u l t o n s o m e b u g g y 9 7 0 ' s ( o u c h ! w e l o s t a b i t , b a h
* that' s t h e b e s t w e c a n d o ) . N o t i m p l e m e n t e d y e t a s w e d o n ' t u s e
* the s c o m o n a n y o f t h e b o g u s C P U s y e t , b u t m a y h a v e t o b e d o n e
* ultimately
* /
/* restore interrupts */
mtmsrd r4 ,1
blr
_ GLOBAL( s c o m 9 7 0 _ w r i t e )
/* interrupts off */
mfmsr r5
ori r0 ,r5 ,M S R _ E E
xori r0 ,r0 ,M S R _ E E
mtmsrd r0 ,1
/ * rotate 2 4 b i t s S C O M a d d r e s s 8 b i t s l e f t a n d m a s k o u t i t ' s l o w 8 b i t s
* ( including p a r i t y ) . O n c u r r e n t C P U s t h e y m u s t b e 0 ' d .
* /
rlwinm r3 ,r3 ,8 ,0 ,1 5
sync
mtspr S P R N _ S C O M D ,r4 / * w r i t e d a t a * /
isync
mtspr S P R N _ S C O M C ,r3 / * w r i t e c o m m a n d * /
isync
mfspr 3 ,S P R N _ S C O M C
isync
/* restore interrupts */
mtmsrd r5 ,1
blr
2005-10-10 16:36:14 +04:00
/ *
* Create a k e r n e l t h r e a d
* kernel_ t h r e a d ( f n , a r g , f l a g s )
* /
_ GLOBAL( k e r n e l _ t h r e a d )
std r29 ,- 2 4 ( r1 )
std r30 ,- 1 6 ( r1 )
stdu r1 ,- S T A C K _ F R A M E _ O V E R H E A D ( r1 )
mr r29 ,r3
mr r30 ,r4
ori r3 ,r5 ,C L O N E _ V M / * f l a g s * /
oris r3 ,r3 ,( C L O N E _ U N T R A C E D > > 1 6 )
li r4 ,0 / * n e w s p ( u n u s e d ) * /
li r0 ,_ _ N R _ c l o n e
sc
cmpdi 0 ,r3 ,0 / * p a r e n t o r c h i l d ? * /
bne 1 f / * r e t u r n i f p a r e n t * /
li r0 ,0
stdu r0 ,- S T A C K _ F R A M E _ O V E R H E A D ( r1 )
ld r2 ,8 ( r29 )
ld r29 ,0 ( r29 )
mtlr r29 / * f n a d d r i n l r * /
mr r3 ,r30 / * l o a d a r g a n d c a l l f n * /
blrl
li r0 ,_ _ N R _ e x i t / * e x i t a f t e r c h i l d e x i t s * /
li r3 ,0
sc
1 : addi r1 ,r1 ,S T A C K _ F R A M E _ O V E R H E A D
ld r29 ,- 2 4 ( r1 )
ld r30 ,- 1 6 ( r1 )
blr
/ *
* disable_ k e r n e l _ f p ( )
* Disable t h e F P U .
* /
_ GLOBAL( d i s a b l e _ k e r n e l _ f p )
mfmsr r3
rldicl r0 ,r3 ,( 6 3 - M S R _ F P _ L G ) ,1
rldicl r3 ,r0 ,( M S R _ F P _ L G + 1 ) ,0
mtmsrd r3 / * d i s a b l e u s e o f f p u n o w * /
isync
blr
# ifdef C O N F I G _ A L T I V E C
# if 0 / * t h i s h a s n o c a l l e r s f o r n o w * /
/ *
* disable_ k e r n e l _ a l t i v e c ( )
* Disable t h e V M X .
* /
_ GLOBAL( d i s a b l e _ k e r n e l _ a l t i v e c )
mfmsr r3
rldicl r0 ,r3 ,( 6 3 - M S R _ V E C _ L G ) ,1
rldicl r3 ,r0 ,( M S R _ V E C _ L G + 1 ) ,0
mtmsrd r3 / * d i s a b l e u s e o f V M X n o w * /
isync
blr
# endif / * 0 * /
/ *
* giveup_ a l t i v e c ( t s k )
* Disable V M X f o r t h e t a s k g i v e n a s t h e a r g u m e n t ,
* and s a v e t h e v e c t o r r e g i s t e r s i n i t s t h r e a d _ s t r u c t .
* Enables t h e V M X f o r u s e i n t h e k e r n e l o n r e t u r n .
* /
_ GLOBAL( g i v e u p _ a l t i v e c )
mfmsr r5
oris r5 ,r5 ,M S R _ V E C @h
mtmsrd r5 / * e n a b l e u s e o f V M X n o w * /
isync
cmpdi 0 ,r3 ,0
beqlr- / * i f n o p r e v i o u s o w n e r , d o n e * /
addi r3 ,r3 ,T H R E A D / * w a n t T H R E A D o f t a s k * /
ld r5 ,P T _ R E G S ( r3 )
cmpdi 0 ,r5 ,0
SAVE_ 3 2 V R S ( 0 ,r4 ,r3 )
mfvscr v r0
li r4 ,T H R E A D _ V S C R
stvx v r0 ,r4 ,r3
beq 1 f
ld r4 ,_ M S R - S T A C K _ F R A M E _ O V E R H E A D ( r5 )
lis r3 ,M S R _ V E C @h
andc r4 ,r4 ,r3 / * d i s a b l e F P f o r p r e v i o u s t a s k * /
std r4 ,_ M S R - S T A C K _ F R A M E _ O V E R H E A D ( r5 )
1 :
# ifndef C O N F I G _ S M P
li r5 ,0
ld r4 ,l a s t _ t a s k _ u s e d _ a l t i v e c @got(r2)
std r5 ,0 ( r4 )
# endif / * C O N F I G _ S M P * /
blr
# endif / * C O N F I G _ A L T I V E C * /
_ GLOBAL( _ _ s e t u p _ c p u _ p o w e r3 )
blr
_ GLOBAL( e x e c v e )
li r0 ,_ _ N R _ e x e c v e
sc
bnslr
neg r3 ,r3
blr
/ * kexec_ w a i t ( p h y s _ c p u )
*
* wait f o r t h e f l a g t o c h a n g e , i n d i c a t i n g t h i s k e r n e l i s g o i n g a w a y b u t
* the s l a v e c o d e f o r t h e n e x t o n e i s a t a d d r e s s e s 0 t o 1 0 0 .
*
* This i s u s e d b y a l l s l a v e s .
*
* Physical ( h a r d w a r e ) c p u i d s h o u l d b e i n r3 .
* /
_ GLOBAL( k e x e c _ w a i t )
bl 1 f
1 : mflr r5
addi r5 ,r5 ,k e x e c _ f l a g - 1 b
99 : HMT_ L O W
# ifdef C O N F I G _ K E X E C / * u s e n o m e m o r y w i t h o u t k e x e c * /
lwz r4 ,0 ( r5 )
cmpwi 0 ,r4 ,0
bnea 0 x60
# endif
b 9 9 b
/ * this c a n b e i n t e x t b e c a u s e w e w o n ' t c h a n g e i t u n t i l w e a r e
* running i n r e a l a n y w a y s
* /
kexec_flag :
.long 0
# ifdef C O N F I G _ K E X E C
/ * kexec_ s m p _ w a i t ( v o i d )
*
* call w i t h i n t e r r u p t s o f f
* note : this i s a t e r m i n a l r o u t i n e , i t d o e s n o t s a v e l r
*
* get p h y s i d f r o m p a c a
* set p a c a i d t o - 1 t o s a y w e g o t h e r e
* switch t o r e a l m o d e
* join o t h e r c p u s i n k e x e c _ w a i t ( p h y s _ i d )
* /
_ GLOBAL( k e x e c _ s m p _ w a i t )
lhz r3 ,P A C A H W C P U I D ( r13 )
li r4 ,- 1
sth r4 ,P A C A H W C P U I D ( r13 ) / * l e t o t h e r s k n o w w e l e f t * /
bl r e a l _ m o d e
b . k e x e c _ w a i t
/ *
* switch t o r e a l m o d e ( t u r n m m u o f f )
* we u s e t h e e a r l y k e r n e l t r i c k t h a t t h e h a r d w a r e i g n o r e s b i t s
* 0 and 1 ( b i g e n d i a n ) o f t h e e f f e c t i v e a d d r e s s i n r e a l m o d e
*
* don' t o v e r w r i t e r3 h e r e , i t i s l i v e f o r k e x e c _ w a i t a b o v e .
* /
real_mode : /* assume normal blr return */
1 : li r9 ,M S R _ R I
li r10 ,M S R _ D R | M S R _ I R
mflr r11 / * r e t u r n a d d r e s s t o S R R 0 * /
mfmsr r12
andc r9 ,r12 ,r9
andc r10 ,r12 ,r10
mtmsrd r9 ,1
mtspr S P R N _ S R R 1 ,r10
mtspr S P R N _ S R R 0 ,r11
rfid
/ *
* kexec_ s e q u e n c e ( n e w s t a c k , s t a r t , i m a g e , c o n t r o l , c l e a r _ a l l ( ) )
*
* does t h e g r u n g y w o r k w i t h s t a c k s w i t c h i n g a n d r e a l m o d e s w i t c h e s
* also d o e s s i m p l e c a l l s t o o t h e r c o d e
* /
_ GLOBAL( k e x e c _ s e q u e n c e )
mflr r0
std r0 ,1 6 ( r1 )
/* switch stacks to newstack -- &kexec_stack.stack */
stdu r1 ,T H R E A D _ S I Z E - 1 1 2 ( r3 )
mr r1 ,r3
li r0 ,0
std r0 ,1 6 ( r1 )
/ * save r e g s f o r l o c a l v a r s o n n e w s t a c k .
* yes, w e w o n ' t g o b a c k , b u t . . .
* /
std r31 ,- 8 ( r1 )
std r30 ,- 1 6 ( r1 )
std r29 ,- 2 4 ( r1 )
std r28 ,- 3 2 ( r1 )
std r27 ,- 4 0 ( r1 )
std r26 ,- 4 8 ( r1 )
std r25 ,- 5 6 ( r1 )
stdu r1 ,- 1 1 2 - 6 4 ( r1 )
/* save args into preserved regs */
mr r31 ,r3 / * n e w s t a c k ( b o t h ) * /
mr r30 ,r4 / * s t a r t ( r e a l ) * /
mr r29 ,r5 / * i m a g e ( v i r t ) * /
mr r28 ,r6 / * c o n t r o l , u n u s e d * /
mr r27 ,r7 / * c l e a r _ a l l ( ) f n d e s c * /
mr r26 ,r8 / * s p a r e * /
lhz r25 ,P A C A H W C P U I D ( r13 ) / * g e t o u r p h y s c p u f r o m p a c a * /
/* disable interrupts, we are overwriting kernel data next */
mfmsr r3
rlwinm r3 ,r3 ,0 ,1 7 ,1 5
mtmsrd r3 ,1
/* copy dest pages, flush whole dest image */
mr r3 ,r29
bl . k e x e c _ c o p y _ f l u s h / * ( i m a g e ) * /
/* turn off mmu */
bl r e a l _ m o d e
/* clear out hardware hash page table and tlb */
ld r5 ,0 ( r27 ) / * d e r e f f u n c t i o n d e s c r i p t o r * /
mtctr r5
bctrl / * p p c _ m d . h a s h _ c l e a r _ a l l ( v o i d ) ; */
/ *
* kexec i m a g e c a l l i n g i s :
* the f i r s t 0 x10 0 b y t e s o f t h e e n t r y p o i n t a r e c o p i e d t o 0
*
* all s l a v e s b r a n c h t o s l a v e = 0 x60 ( a b s o l u t e )
* slave( p h y s _ c p u _ i d ) ;
*
* master g o e s t o s t a r t = e n t r y p o i n t
* start( p h y s _ c p u _ i d , s t a r t , 0 ) ;
*
*
* a w r a p p e r i s n e e d e d t o c a l l e x i s t i n g k e r n e l s , h e r e i s a n a p p r o x i m a t e
* description o f o n e m e t h o d :
*
* v2 : ( 2 .6 .10 )
* start w i l l b e n e a r t h e b o o t _ b l o c k ( m a y b e 0 x10 0 b y t e s b e f o r e i t ? )
* it w i l l h a v e a 0 x60 , w h i c h w i l l b t o b o o t _ b l o c k , w h e r e i t w i l l w a i t
* and 0 w i l l s t o r e p h y s i n t o s t r u c t b o o t - b l o c k a n d l o a d r3 f r o m t h e r e ,
* copy k e r n e l 0 - 0 x10 0 a n d t e l l s l a v e s t o b a c k d o w n t o 0 x60 a g a i n
*
* v1 : ( 2 .6 .9 )
* boot b l o c k w i l l h a v e a l l c p u s s c a n n i n g d e v i c e t r e e t o s e e i f t h e y
* are t h e b o o t c p u ? ? ? ? ?
* other d e v i c e t r e e d i f f e r e n c e s ( p r o p s i z e s , v a v s p a , e t c ) . . .
* /
/* copy 0x100 bytes starting at start to 0 */
li r3 ,0
mr r4 ,r30
li r5 ,0 x10 0
li r6 ,0
bl . c o p y _ a n d _ f l u s h / * ( d e s t , s r c , c o p y l i m i t , s t a r t o f f s e t ) * /
1 : /* assume normal blr return */
/* release other cpus to the new kernel secondary start at 0x60 */
mflr r5
li r6 ,1
stw r6 ,k e x e c _ f l a g - 1 b ( 5 )
mr r3 ,r25 # m y p h y s c p u
mr r4 ,r30 # s t a r t , a k a p h y s m e m o f f s e t
mtlr 4
li r5 ,0
blr / * i m a g e - > s t a r t ( p h y s i d , i m a g e - > s t a r t , 0 ) ; */
# endif / * C O N F I G _ K E X E C * /