2005-09-26 10:04:21 +04:00
/ *
* Kernel e x e c u t i o n e n t r y p o i n t c o d e .
*
* 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>
2007-09-27 17:43:35 +04:00
* Initial P o w e r P C v e r s i o n .
2005-09-26 10:04:21 +04:00
* Copyright ( c ) 1 9 9 6 C o r t D o u g a n < c o r t @cs.nmt.edu>
2007-09-27 17:43:35 +04:00
* Rewritten f o r P R e P
2005-09-26 10:04:21 +04:00
* Copyright ( c ) 1 9 9 6 P a u l M a c k e r r a s < p a u l u s @cs.anu.edu.au>
2007-09-27 17:43:35 +04:00
* Low- l e v e l e x c e p t i o n h a n d e r s , M M U s u p p o r t , a n d r e w r i t e .
2005-09-26 10:04:21 +04:00
* Copyright ( c ) 1 9 9 7 D a n M a l e k < d m a l e k @jlc.net>
2007-09-27 17:43:35 +04:00
* PowerPC 8 x x m o d i f i c a t i o n s .
2005-09-26 10:04:21 +04:00
* Copyright ( c ) 1 9 9 8 - 1 9 9 9 T i V o , I n c .
2007-09-27 17:43:35 +04:00
* PowerPC 4 0 3 G C X m o d i f i c a t i o n s .
2005-09-26 10:04:21 +04:00
* Copyright ( c ) 1 9 9 9 G r a n t E r i c k s o n < g r a n t @lcse.umn.edu>
2007-09-27 17:43:35 +04:00
* PowerPC 4 0 3 G C X / 4 0 5 G P m o d i f i c a t i o n s .
2005-09-26 10:04:21 +04:00
* Copyright 2 0 0 0 M o n t a V i s t a S o f t w a r e I n c .
* PPC4 0 5 m o d i f i c a t i o n s
2007-09-27 17:43:35 +04:00
* PowerPC 4 0 3 G C X / 4 0 5 G P m o d i f i c a t i o n s .
* Author : MontaVista S o f t w a r e , I n c .
* frank_ r o w a n d @mvista.com or source@mvista.com
* debbie_ c h u @mvista.com
2005-09-26 10:04:21 +04:00
* Copyright 2 0 0 2 - 2 0 0 4 M o n t a V i s t a S o f t w a r e , I n c .
2007-09-27 17:43:35 +04:00
* PowerPC 4 4 x s u p p o r t , M a t t P o r t e r < m p o r t e r @kernel.crashing.org>
2005-09-26 10:04:21 +04:00
* Copyright 2 0 0 4 F r e e s c a l e S e m i c o n d u c t o r , I n c
2007-09-27 17:43:35 +04:00
* PowerPC e 5 0 0 m o d i f i c a t i o n s , K u m a r G a l a < g a l a k @kernel.crashing.org>
2005-09-26 10:04:21 +04:00
*
* 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 it
* under 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 a s p u b l i s h e d b y t h e
* Free S o f t w a r e F o u n d a t i o n ; either version 2 of the License, or (at your
* option) a n y l a t e r v e r s i o n .
* /
# 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 / m m u . h >
# include < a s m / p g t a b l 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 >
# include < a s m / a s m - o f f s e t s . h >
2008-06-19 01:26:52 +04:00
# include < a s m / c a c h e . h >
2005-09-26 10:04:21 +04:00
# include " h e a d _ b o o k e . h "
/ * As w i t h t h e o t h e r P o w e r P C p o r t s , i t i s e x p e c t e d t h a t w h e n c o d e
* execution b e g i n s h e r e , t h e f o l l o w i n g r e g i s t e r s c o n t a i n v a l i d , y e t
* optional, i n f o r m a t i o n :
*
* r3 - B o a r d i n f o s t r u c t u r e p o i n t e r ( D R A M , f r e q u e n c y , M A C a d d r e s s , e t c . )
* r4 - S t a r t i n g a d d r e s s o f t h e i n i t R A M d i s k
* r5 - E n d i n g a d d r e s s o f t h e i n i t R A M d i s k
* r6 - S t a r t o f k e r n e l c o m m a n d l i n e s t r i n g ( e . g . " m e m =128 " )
* r7 - E n d o f k e r n e l c o m m a n d l i n e s t r i n g
*
* /
2007-09-14 00:42:35 +04:00
.section .text .head , " ax"
_ ENTRY( _ s t e x t ) ;
_ ENTRY( _ s t a r t ) ;
2005-09-26 10:04:21 +04:00
/ *
* Reserve a w o r d a t a f i x e d l o c a t i o n t o s t o r e t h e a d d r e s s
* of a b a t r o n _ p t e p t r s
* /
nop
/ *
* Save p a r a m e t e r s w e a r e p a s s e d
* /
mr r31 ,r3
mr r30 ,r4
mr r29 ,r5
mr r28 ,r6
mr r27 ,r7
2008-04-15 23:52:23 +04:00
li r25 ,0 / * p h y s k e r n e l s t a r t ( l o w ) * /
2005-09-26 10:04:21 +04:00
li r24 ,0 / * C P U n u m b e r * /
2008-04-15 23:52:23 +04:00
li r23 ,0 / * p h y s k e r n e l s t a r t ( h i g h ) * /
2005-09-26 10:04:21 +04:00
/ * We t r y t o n o t m a k e a n y a s s u m p t i o n s a b o u t h o w t h e b o o t l o a d e r
* setup o r u s e d t h e T L B s . W e i n v a l i d a t e a l l m a p p i n g s f r o m t h e
* boot l o a d e r a n d l o a d a s i n g l e e n t r y i n T L B 1 [ 0 ] t o m a p t h e
2007-11-22 18:46:20 +03:00
* first 6 4 M o f k e r n e l m e m o r y . A n y b o o t i n f o p a s s e d f r o m t h e
* bootloader n e e d s t o l i v e i n t h i s f i r s t 6 4 M .
2005-09-26 10:04:21 +04:00
*
* Requirement o n b o o t l o a d e r :
* - The p a g e w e ' r e e x e c u t i n g i n n e e d s t o r e s i d e i n T L B 1 a n d
* have I P R O T =1 . I f n o t a n i n v a l i d a t e b r o a d c a s t c o u l d
* evict t h e e n t r y w e ' r e c u r r e n t l y e x e c u t i n g i n .
*
* r3 = I n d e x o f T L B 1 w e r e e x e c u t i n g i n
* r4 = C u r r e n t M S R [ I S ]
* r5 = I n d e x o f T L B 1 t e m p m a p p i n g
*
* Later i n m a p i n _ r a m w e w i l l c o r r e c t l y m a p l o w m e m , a n d r e s i z e T L B 1 [ 0 ]
* if n e e d e d
* /
2008-11-19 18:35:56 +03:00
_ ENTRY( _ _ e a r l y _ s t a r t )
2005-09-26 10:04:21 +04:00
/* 1. Find the index of the entry we're executing in */
bl i n v s t r / * F i n d o u r a d d r e s s * /
invstr : mflr r6 / * M a k e i t a c c e s s i b l e * /
mfmsr r7
rlwinm r4 ,r7 ,2 7 ,3 1 ,3 1 / * e x t r a c t M S R [ I S ] * /
mfspr r7 , S P R N _ P I D 0
slwi r7 ,r7 ,1 6
or r7 ,r7 ,r4
mtspr S P R N _ M A S 6 ,r7
tlbsx 0 ,r6 / * s e a r c h M S R [ I S ] , S P I D =PID0 * /
# ifndef C O N F I G _ E 2 0 0
mfspr r7 ,S P R N _ M A S 1
andis. r7 ,r7 ,M A S 1 _ V A L I D @h
bne m a t c h _ T L B
mfspr r7 ,S P R N _ P I D 1
slwi r7 ,r7 ,1 6
or r7 ,r7 ,r4
mtspr S P R N _ M A S 6 ,r7
tlbsx 0 ,r6 / * s e a r c h M S R [ I S ] , S P I D =PID1 * /
mfspr r7 ,S P R N _ M A S 1
andis. r7 ,r7 ,M A S 1 _ V A L I D @h
bne m a t c h _ T L B
mfspr r7 , S P R N _ P I D 2
slwi r7 ,r7 ,1 6
or r7 ,r7 ,r4
mtspr S P R N _ M A S 6 ,r7
tlbsx 0 ,r6 / * F a l l t h r o u g h , w e h a d t o m a t c h * /
# endif
match_TLB :
mfspr r7 ,S P R N _ M A S 0
rlwinm r3 ,r7 ,1 6 ,2 0 ,3 1 / * E x t r a c t M A S 0 ( E n t r y ) * /
mfspr r7 ,S P R N _ M A S 1 / * I n s u r e I P R O T s e t * /
oris r7 ,r7 ,M A S 1 _ I P R O T @h
mtspr S P R N _ M A S 1 ,r7
tlbwe
/* 2. Invalidate all entries except the entry we're executing in */
mfspr r9 ,S P R N _ T L B 1 C F G
andi. r9 ,r9 ,0 x f f f
li r6 ,0 / * S e t E n t r y c o u n t e r t o 0 * /
1 : lis r7 ,0 x10 0 0 / * S e t M A S 0 ( T L B S E L ) = 1 * /
rlwimi r7 ,r6 ,1 6 ,4 ,1 5 / * S e t u p M A S 0 = T L B S E L | E S E L ( r6 ) * /
mtspr S P R N _ M A S 0 ,r7
tlbre
mfspr r7 ,S P R N _ M A S 1
rlwinm r7 ,r7 ,0 ,2 ,3 1 / * C l e a r M A S 1 V a l i d a n d I P R O T * /
cmpw r3 ,r6
beq s k p i n v / * D o n t u p d a t e t h e c u r r e n t e x e c u t i o n T L B * /
mtspr S P R N _ M A S 1 ,r7
tlbwe
isync
skpinv : addi r6 ,r6 ,1 / * I n c r e m e n t * /
cmpw r6 ,r9 / * A r e w e d o n e ? * /
bne 1 b / * I f n o t , r e p e a t * /
/* Invalidate TLB0 */
2007-09-27 17:43:35 +04:00
li r6 ,0 x04
2005-09-26 10:04:21 +04:00
tlbivax 0 ,r6
2008-07-11 23:31:35 +04:00
TLBSYNC
2005-09-26 10:04:21 +04:00
/* Invalidate TLB1 */
2007-09-27 17:43:35 +04:00
li r6 ,0 x0 c
2005-09-26 10:04:21 +04:00
tlbivax 0 ,r6
2008-07-11 23:31:35 +04:00
TLBSYNC
2005-09-26 10:04:21 +04:00
/* 3. Setup a temp mapping and jump to it */
andi. r5 , r3 , 0 x1 / * F i n d a n e n t r y n o t u s e d a n d i s n o n - z e r o * /
addi r5 , r5 , 0 x1
lis r7 ,0 x10 0 0 / * S e t M A S 0 ( T L B S E L ) = 1 * /
rlwimi r7 ,r3 ,1 6 ,4 ,1 5 / * S e t u p M A S 0 = T L B S E L | E S E L ( r3 ) * /
mtspr S P R N _ M A S 0 ,r7
tlbre
2008-04-15 23:52:23 +04:00
/* grab and fixup the RPN */
mfspr r6 ,S P R N _ M A S 1 / * e x t r a c t M A S 1 [ S I Z E ] * /
rlwinm r6 ,r6 ,2 5 ,2 7 ,3 0
li r8 ,- 1
addi r6 ,r6 ,1 0
slw r6 ,r8 ,r6 / * c o n v e r t t o m a s k * /
bl 1 f / * F i n d o u r a d d r e s s * /
1 : mflr r7
mfspr r8 ,S P R N _ M A S 3
# ifdef C O N F I G _ P H Y S _ 6 4 B I T
mfspr r23 ,S P R N _ M A S 7
# endif
and r8 ,r6 ,r8
subfic r9 ,r6 ,- 4 0 9 6
and r9 ,r9 ,r7
or r25 ,r8 ,r9
ori r8 ,r25 ,( M A S 3 _ S X | M A S 3 _ S W | M A S 3 _ S R )
/* Just modify the entry ID and EPN for the temp mapping */
2005-09-26 10:04:21 +04:00
lis r7 ,0 x10 0 0 / * S e t M A S 0 ( T L B S E L ) = 1 * /
rlwimi r7 ,r5 ,1 6 ,4 ,1 5 / * S e t u p M A S 0 = T L B S E L | E S E L ( r5 ) * /
mtspr S P R N _ M A S 0 ,r7
xori r6 ,r4 ,1 / * S e t u p T M P m a p p i n g i n t h e o t h e r A d d r e s s s p a c e * /
slwi r6 ,r6 ,1 2
oris r6 ,r6 ,( M A S 1 _ V A L I D | M A S 1 _ I P R O T ) @h
ori r6 ,r6 ,( M A S 1 _ T S I Z E ( B O O K E _ P A G E S Z _ 4 K ) ) @l
mtspr S P R N _ M A S 1 ,r6
mfspr r6 ,S P R N _ M A S 2
2008-04-15 23:52:23 +04:00
li r7 ,0 / * t e m p E P N = 0 * /
2005-09-26 10:04:21 +04:00
rlwimi r7 ,r6 ,0 ,2 0 ,3 1
mtspr S P R N _ M A S 2 ,r7
2008-04-15 23:52:23 +04:00
mtspr S P R N _ M A S 3 ,r8
2005-09-26 10:04:21 +04:00
tlbwe
xori r6 ,r4 ,1
slwi r6 ,r6 ,5 / * s e t u p n e w c o n t e x t w i t h o t h e r a d d r e s s s p a c e * /
bl 1 f / * F i n d o u r a d d r e s s * /
1 : mflr r9
rlwimi r7 ,r9 ,0 ,2 0 ,3 1
addi r7 ,r7 ,2 4
mtspr S P R N _ S R R 0 ,r7
mtspr S P R N _ S R R 1 ,r6
rfi
/* 4. Clear out PIDs & Search info */
li r6 ,0
mtspr S P R N _ P I D 0 ,r6
# ifndef C O N F I G _ E 2 0 0
mtspr S P R N _ P I D 1 ,r6
mtspr S P R N _ P I D 2 ,r6
# endif
mtspr S P R N _ M A S 6 ,r6
/* 5. Invalidate mapping we started in */
lis r7 ,0 x10 0 0 / * S e t M A S 0 ( T L B S E L ) = 1 * /
rlwimi r7 ,r3 ,1 6 ,4 ,1 5 / * S e t u p M A S 0 = T L B S E L | E S E L ( r3 ) * /
mtspr S P R N _ M A S 0 ,r7
tlbre
2007-02-13 02:43:46 +03:00
mfspr r6 ,S P R N _ M A S 1
rlwinm r6 ,r6 ,0 ,2 ,0 / * c l e a r I P R O T * /
2005-09-26 10:04:21 +04:00
mtspr S P R N _ M A S 1 ,r6
tlbwe
/* Invalidate TLB1 */
2007-09-27 17:43:35 +04:00
li r9 ,0 x0 c
2005-09-26 10:04:21 +04:00
tlbivax 0 ,r9
2008-07-11 23:31:35 +04:00
TLBSYNC
2005-09-26 10:04:21 +04:00
powerpc: Better setup of boot page TLB entry
The initial TLB mapping for the kernel boot didn't set the memory coherent
attribute, MAS2[M], in SMP mode.
If this code supported booting a secondary processor, which it doesn't yet,
but if it did, then when a secondary processor boots, it would probably signal
the primary processor by setting a variable called something like
__secondary_hold_acknowledge. However, due to the lack of the M bit, the
primary processor would not snoop the transaction (even if a transaction were
broadcast). If primary CPU's L1 D-cache had a copy, it would not be flushed
and the CPU would never see the ack. Which would have resulted in the primary
CPU spinning for a long time, perhaps a full second before it gives up, while
it would have waited for the ack from the secondary CPU that it wouldn't have
been able to see because of the stale cache.
The value of MAS2 for the boot page TLB1 entry is a compile time constant,
so there is no need to calculate it in powerpc assembly language.
Also, from the MPC8572 manual section 6.12.5.3, "Bits that represent
offsets within a page are ignored and should be cleared." Existing code
didn't clear them, this code does.
The same when the page of KERNELBASE is found; we don't need to use asm to
mask the lower 12 bits off.
In the code that computes the address to rfi from, don't hard code the
offset to 24 bytes, but have the assembler figure that out for us.
Signed-off-by: Trent Piepho <tpiepho@freescale.com>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
2008-11-19 14:13:14 +03:00
/* The mapping only needs to be cache-coherent on SMP */
# ifdef C O N F I G _ S M P
# define M _ I F _ S M P M A S 2 _ M
# else
# define M _ I F _ S M P 0
# endif
2005-09-26 10:04:21 +04:00
/* 6. Setup KERNELBASE mapping in TLB1[0] */
lis r6 ,0 x10 0 0 / * S e t M A S 0 ( T L B S E L ) = T L B 1 ( 1 ) , E S E L = 0 * /
mtspr S P R N _ M A S 0 ,r6
lis r6 ,( M A S 1 _ V A L I D | M A S 1 _ I P R O T ) @h
2007-11-22 18:46:20 +03:00
ori r6 ,r6 ,( M A S 1 _ T S I Z E ( B O O K E _ P A G E S Z _ 6 4 M ) ) @l
2005-09-26 10:04:21 +04:00
mtspr S P R N _ M A S 1 ,r6
powerpc: Better setup of boot page TLB entry
The initial TLB mapping for the kernel boot didn't set the memory coherent
attribute, MAS2[M], in SMP mode.
If this code supported booting a secondary processor, which it doesn't yet,
but if it did, then when a secondary processor boots, it would probably signal
the primary processor by setting a variable called something like
__secondary_hold_acknowledge. However, due to the lack of the M bit, the
primary processor would not snoop the transaction (even if a transaction were
broadcast). If primary CPU's L1 D-cache had a copy, it would not be flushed
and the CPU would never see the ack. Which would have resulted in the primary
CPU spinning for a long time, perhaps a full second before it gives up, while
it would have waited for the ack from the secondary CPU that it wouldn't have
been able to see because of the stale cache.
The value of MAS2 for the boot page TLB1 entry is a compile time constant,
so there is no need to calculate it in powerpc assembly language.
Also, from the MPC8572 manual section 6.12.5.3, "Bits that represent
offsets within a page are ignored and should be cleared." Existing code
didn't clear them, this code does.
The same when the page of KERNELBASE is found; we don't need to use asm to
mask the lower 12 bits off.
In the code that computes the address to rfi from, don't hard code the
offset to 24 bytes, but have the assembler figure that out for us.
Signed-off-by: Trent Piepho <tpiepho@freescale.com>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
2008-11-19 14:13:14 +03:00
lis r6 ,M A S 2 _ V A L ( P A G E _ O F F S E T , B O O K E _ P A G E S Z _ 6 4 M , M _ I F _ S M P ) @h
ori r6 ,r6 ,M A S 2 _ V A L ( P A G E _ O F F S E T , B O O K E _ P A G E S Z _ 6 4 M , M _ I F _ S M P ) @l
2005-09-26 10:04:21 +04:00
mtspr S P R N _ M A S 2 ,r6
2008-04-15 23:52:23 +04:00
mtspr S P R N _ M A S 3 ,r8
2005-09-26 10:04:21 +04:00
tlbwe
/* 7. Jump to KERNELBASE mapping */
powerpc: Better setup of boot page TLB entry
The initial TLB mapping for the kernel boot didn't set the memory coherent
attribute, MAS2[M], in SMP mode.
If this code supported booting a secondary processor, which it doesn't yet,
but if it did, then when a secondary processor boots, it would probably signal
the primary processor by setting a variable called something like
__secondary_hold_acknowledge. However, due to the lack of the M bit, the
primary processor would not snoop the transaction (even if a transaction were
broadcast). If primary CPU's L1 D-cache had a copy, it would not be flushed
and the CPU would never see the ack. Which would have resulted in the primary
CPU spinning for a long time, perhaps a full second before it gives up, while
it would have waited for the ack from the secondary CPU that it wouldn't have
been able to see because of the stale cache.
The value of MAS2 for the boot page TLB1 entry is a compile time constant,
so there is no need to calculate it in powerpc assembly language.
Also, from the MPC8572 manual section 6.12.5.3, "Bits that represent
offsets within a page are ignored and should be cleared." Existing code
didn't clear them, this code does.
The same when the page of KERNELBASE is found; we don't need to use asm to
mask the lower 12 bits off.
In the code that computes the address to rfi from, don't hard code the
offset to 24 bytes, but have the assembler figure that out for us.
Signed-off-by: Trent Piepho <tpiepho@freescale.com>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
2008-11-19 14:13:14 +03:00
lis r6 ,( K E R N E L B A S E & ~ 0 x f f f ) @h
ori r6 ,r6 ,( K E R N E L B A S E & ~ 0 x f f f ) @l
2005-09-26 10:04:21 +04:00
lis r7 ,M S R _ K E R N E L @h
ori r7 ,r7 ,M S R _ K E R N E L @l
bl 1 f / * F i n d o u r a d d r e s s * /
1 : mflr r9
rlwimi r6 ,r9 ,0 ,2 0 ,3 1
powerpc: Better setup of boot page TLB entry
The initial TLB mapping for the kernel boot didn't set the memory coherent
attribute, MAS2[M], in SMP mode.
If this code supported booting a secondary processor, which it doesn't yet,
but if it did, then when a secondary processor boots, it would probably signal
the primary processor by setting a variable called something like
__secondary_hold_acknowledge. However, due to the lack of the M bit, the
primary processor would not snoop the transaction (even if a transaction were
broadcast). If primary CPU's L1 D-cache had a copy, it would not be flushed
and the CPU would never see the ack. Which would have resulted in the primary
CPU spinning for a long time, perhaps a full second before it gives up, while
it would have waited for the ack from the secondary CPU that it wouldn't have
been able to see because of the stale cache.
The value of MAS2 for the boot page TLB1 entry is a compile time constant,
so there is no need to calculate it in powerpc assembly language.
Also, from the MPC8572 manual section 6.12.5.3, "Bits that represent
offsets within a page are ignored and should be cleared." Existing code
didn't clear them, this code does.
The same when the page of KERNELBASE is found; we don't need to use asm to
mask the lower 12 bits off.
In the code that computes the address to rfi from, don't hard code the
offset to 24 bytes, but have the assembler figure that out for us.
Signed-off-by: Trent Piepho <tpiepho@freescale.com>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
2008-11-19 14:13:14 +03:00
addi r6 ,r6 ,( 2 f - 1 b )
2005-09-26 10:04:21 +04:00
mtspr S P R N _ S R R 0 ,r6
mtspr S P R N _ S R R 1 ,r7
rfi / * s t a r t e x e c u t i o n o u t o f T L B 1 [ 0 ] e n t r y * /
/* 8. Clear out the temp mapping */
powerpc: Better setup of boot page TLB entry
The initial TLB mapping for the kernel boot didn't set the memory coherent
attribute, MAS2[M], in SMP mode.
If this code supported booting a secondary processor, which it doesn't yet,
but if it did, then when a secondary processor boots, it would probably signal
the primary processor by setting a variable called something like
__secondary_hold_acknowledge. However, due to the lack of the M bit, the
primary processor would not snoop the transaction (even if a transaction were
broadcast). If primary CPU's L1 D-cache had a copy, it would not be flushed
and the CPU would never see the ack. Which would have resulted in the primary
CPU spinning for a long time, perhaps a full second before it gives up, while
it would have waited for the ack from the secondary CPU that it wouldn't have
been able to see because of the stale cache.
The value of MAS2 for the boot page TLB1 entry is a compile time constant,
so there is no need to calculate it in powerpc assembly language.
Also, from the MPC8572 manual section 6.12.5.3, "Bits that represent
offsets within a page are ignored and should be cleared." Existing code
didn't clear them, this code does.
The same when the page of KERNELBASE is found; we don't need to use asm to
mask the lower 12 bits off.
In the code that computes the address to rfi from, don't hard code the
offset to 24 bytes, but have the assembler figure that out for us.
Signed-off-by: Trent Piepho <tpiepho@freescale.com>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
2008-11-19 14:13:14 +03:00
2 : lis r7 ,0 x10 0 0 / * S e t M A S 0 ( T L B S E L ) = 1 * /
2005-09-26 10:04:21 +04:00
rlwimi r7 ,r5 ,1 6 ,4 ,1 5 / * S e t u p M A S 0 = T L B S E L | E S E L ( r5 ) * /
mtspr S P R N _ M A S 0 ,r7
tlbre
2007-02-13 02:43:46 +03:00
mfspr r8 ,S P R N _ M A S 1
rlwinm r8 ,r8 ,0 ,2 ,0 / * c l e a r I P R O T * /
2005-09-26 10:04:21 +04:00
mtspr S P R N _ M A S 1 ,r8
tlbwe
/* Invalidate TLB1 */
2007-09-27 17:43:35 +04:00
li r9 ,0 x0 c
2005-09-26 10:04:21 +04:00
tlbivax 0 ,r9
2008-07-11 23:31:35 +04:00
TLBSYNC
2005-09-26 10:04:21 +04:00
/* Establish the interrupt vector offsets */
SET_ I V O R ( 0 , C r i t i c a l I n p u t ) ;
SET_ I V O R ( 1 , M a c h i n e C h e c k ) ;
SET_ I V O R ( 2 , D a t a S t o r a g e ) ;
SET_ I V O R ( 3 , I n s t r u c t i o n S t o r a g e ) ;
SET_ I V O R ( 4 , E x t e r n a l I n p u t ) ;
SET_ I V O R ( 5 , A l i g n m e n t ) ;
SET_ I V O R ( 6 , P r o g r a m ) ;
SET_ I V O R ( 7 , F l o a t i n g P o i n t U n a v a i l a b l e ) ;
SET_ I V O R ( 8 , S y s t e m C a l l ) ;
SET_ I V O R ( 9 , A u x i l l a r y P r o c e s s o r U n a v a i l a b l e ) ;
SET_ I V O R ( 1 0 , D e c r e m e n t e r ) ;
SET_ I V O R ( 1 1 , F i x e d I n t e r v a l T i m e r ) ;
SET_ I V O R ( 1 2 , W a t c h d o g T i m e r ) ;
SET_ I V O R ( 1 3 , D a t a T L B E r r o r ) ;
SET_ I V O R ( 1 4 , I n s t r u c t i o n T L B E r r o r ) ;
2008-04-09 15:06:11 +04:00
SET_ I V O R ( 1 5 , D e b u g D e b u g ) ;
2008-06-16 18:41:32 +04:00
# if d e f i n e d ( C O N F I G _ E 5 0 0 ) & & ! d e f i n e d ( C O N F I G _ P P C _ E 5 0 0 M C )
2008-04-09 15:06:11 +04:00
SET_ I V O R ( 1 5 , D e b u g C r i t ) ;
# endif
2005-09-26 10:04:21 +04:00
SET_ I V O R ( 3 2 , S P E U n a v a i l a b l e ) ;
SET_ I V O R ( 3 3 , S P E F l o a t i n g P o i n t D a t a ) ;
SET_ I V O R ( 3 4 , S P E F l o a t i n g P o i n t R o u n d ) ;
# ifndef C O N F I G _ E 2 0 0
SET_ I V O R ( 3 5 , P e r f o r m a n c e M o n i t o r ) ;
# endif
2008-06-16 18:41:32 +04:00
# ifdef C O N F I G _ P P C _ E 5 0 0 M C
SET_ I V O R ( 3 6 , D o o r b e l l ) ;
# endif
2005-09-26 10:04:21 +04:00
/* Establish the interrupt vector base */
lis r4 ,i n t e r r u p t _ b a s e @h /* IVPR only uses the high 16-bits */
mtspr S P R N _ I V P R ,r4
/* Setup the defaults for TLB entries */
li r2 ,( M A S 4 _ T S I Z E D ( B O O K E _ P A G E S Z _ 4 K ) ) @l
# ifdef C O N F I G _ E 2 0 0
oris r2 ,r2 ,M A S 4 _ T L B S E L D ( 1 ) @h
# endif
2007-09-27 17:43:35 +04:00
mtspr S P R N _ M A S 4 , r2
2005-09-26 10:04:21 +04:00
# if 0
/* Enable DOZE */
mfspr r2 ,S P R N _ H I D 0
oris r2 ,r2 ,H I D 0 _ D O Z E @h
mtspr S P R N _ H I D 0 , r2
# endif
# ifdef C O N F I G _ E 2 0 0
/* enable dedicated debug exception handling resources (Debug APU) */
mfspr r2 ,S P R N _ H I D 0
2007-09-27 17:43:35 +04:00
ori r2 ,r2 ,H I D 0 _ D A P U E N @l
2005-09-26 10:04:21 +04:00
mtspr S P R N _ H I D 0 ,r2
# endif
# if ! d e f i n e d ( C O N F I G _ B D I _ S W I T C H )
/ *
* The A b a t r o n B D I J T A G d e b u g g e r d o e s n o t t o l e r a t e o t h e r s
* mucking w i t h t h e d e b u g r e g i s t e r s .
* /
lis r2 ,D B C R 0 _ I D M @h
mtspr S P R N _ D B C R 0 ,r2
2006-02-09 01:41:26 +03:00
isync
2005-09-26 10:04:21 +04:00
/* clear any residual debug events */
li r2 ,- 1
mtspr S P R N _ D B S R ,r2
# endif
2008-11-19 18:35:56 +03:00
# ifdef C O N F I G _ S M P
/ * Check t o s e e i f w e ' r e t h e s e c o n d p r o c e s s o r , a n d j u m p
* to t h e s e c o n d a r y _ s t a r t c o d e i f s o
* /
mfspr r24 ,S P R N _ P I R
cmpwi r24 ,0
bne _ _ s e c o n d a r y _ s t a r t
# endif
2005-09-26 10:04:21 +04:00
/ *
* This i s w h e r e t h e m a i n k e r n e l c o d e s t a r t s .
* /
/* ptr to current */
lis r2 ,i n i t _ t a s k @h
ori r2 ,r2 ,i n i t _ t a s k @l
/* ptr to current thread */
addi r4 ,r2 ,T H R E A D / * i n i t t a s k ' s T H R E A D * /
mtspr S P R N _ S P R G 3 ,r4
/* stack */
lis r1 ,i n i t _ t h r e a d _ u n i o n @h
ori r1 ,r1 ,i n i t _ t h r e a d _ u n i o n @l
li r0 ,0
stwu r0 ,T H R E A D _ S I Z E - S T A C K _ F R A M E _ O V E R H E A D ( r1 )
bl e a r l y _ i n i t
2008-04-21 22:22:34 +04:00
# ifdef C O N F I G _ R E L O C A T A B L E
lis r3 ,k e r n s t a r t _ a d d r @ha
la r3 ,k e r n s t a r t _ a d d r @l(r3)
# ifdef C O N F I G _ P H Y S _ 6 4 B I T
stw r23 ,0 ( r3 )
stw r25 ,4 ( r3 )
# else
stw r25 ,0 ( r3 )
# endif
# endif
2005-09-26 10:04:21 +04:00
mfspr r3 ,S P R N _ T L B 1 C F G
andi. r3 ,r3 ,0 x f f f
lis r4 ,n u m _ t l b c a m _ e n t r i e s @ha
stw r3 ,n u m _ t l b c a m _ e n t r i e s @l(r4)
/ *
* Decide w h a t s o r t o f m a c h i n e t h i s i s a n d i n i t i a l i z e t h e M M U .
* /
mr r3 ,r31
mr r4 ,r30
mr r5 ,r29
mr r6 ,r28
mr r7 ,r27
bl m a c h i n e _ i n i t
bl M M U _ i n i t
/* Setup PTE pointers for the Abatron bdiGDB */
lis r6 , s w a p p e r _ p g _ d i r @h
ori r6 , r6 , s w a p p e r _ p g _ d i r @l
lis r5 , a b a t r o n _ p t e p t r s @h
ori r5 , r5 , a b a t r o n _ p t e p t r s @l
lis r4 , K E R N E L B A S E @h
ori r4 , r4 , K E R N E L B A S E @l
stw r5 , 0 ( r4 ) / * S a v e a b a t r o n _ p t e p t r s a t a f i x e d l o c a t i o n * /
stw r6 , 0 ( r5 )
/* Let's move on */
lis r4 ,s t a r t _ k e r n e l @h
ori r4 ,r4 ,s t a r t _ k e r n e l @l
lis r3 ,M S R _ K E R N E L @h
ori r3 ,r3 ,M S R _ K E R N E L @l
mtspr S P R N _ S R R 0 ,r4
mtspr S P R N _ S R R 1 ,r3
rfi / * c h a n g e c o n t e x t a n d j u m p t o s t a r t _ k e r n e l * /
/ * Macros t o h i d e t h e P T E s i z e d i f f e r e n c e s
*
* FIND_ P T E - - w a l k s t h e p a g e t a b l e s g i v e n E A & p g d i r p o i n t e r
* r1 0 - - E A o f f a u l t
* r1 1 - - P G D I R p o i n t e r
* r1 2 - - f r e e
* label 2 : i s t h e b a i l o u t c a s e
*
* if w e f i n d t h e p t e ( f a l l t h r o u g h ) :
* r1 1 i s l o w p t e w o r d
* r1 2 i s p o i n t e r t o t h e p t e
* /
# ifdef C O N F I G _ P T E _ 6 4 B I T
# define F I N D _ P T E \
2007-09-27 17:43:35 +04:00
rlwinm r12 , r10 , 1 3 , 1 9 , 2 9 ; /* Compute pgdir/pmd offset */ \
2005-09-26 10:04:21 +04:00
lwzx r11 , r12 , r11 ; /* Get pgd/pmd entry */ \
rlwinm. r12 , r11 , 0 , 0 , 2 0 ; /* Extract pt base address */ \
beq 2 f ; /* Bail if no table */ \
rlwimi r12 , r10 , 2 3 , 2 0 , 2 8 ; /* Compute pte address */ \
lwz r11 , 4 ( r12 ) ; /* Get pte entry */
# else
# define F I N D _ P T E \
rlwimi r11 , r10 , 1 2 , 2 0 , 2 9 ; /* Create L1 (pgdir/pmd) address */ \
lwz r11 , 0 ( r11 ) ; /* Get L1 entry */ \
rlwinm. r12 , r11 , 0 , 0 , 1 9 ; /* Extract L2 (pte) base address */ \
beq 2 f ; /* Bail if no table */ \
rlwimi r12 , r10 , 2 2 , 2 0 , 2 9 ; /* Compute PTE address */ \
lwz r11 , 0 ( r12 ) ; /* Get Linux PTE */
# endif
/ *
* Interrupt v e c t o r e n t r y c o d e
*
* The B o o k E M M U s a r e a l w a y s o n s o w e d o n ' t n e e d t o h a n d l e
* interrupts i n r e a l m o d e a s w i t h p r e v i o u s P P C p r o c e s s o r s . I n
* this c a s e w e h a n d l e i n t e r r u p t s i n t h e k e r n e l v i r t u a l a d d r e s s
* space.
*
* Interrupt v e c t o r s a r e d y n a m i c a l l y p l a c e d r e l a t i v e t o t h e
* interrupt p r e f i x a s d e t e r m i n e d b y t h e a d d r e s s o f i n t e r r u p t _ b a s e .
* The i n t e r r u p t v e c t o r s o f f s e t s a r e p r o g r a m m e d u s i n g t h e l a b e l s
* for e a c h i n t e r r u p t v e c t o r e n t r y .
*
* Interrupt v e c t o r s m u s t b e a l i g n e d o n a 1 6 b y t e b o u n d a r y .
* We a l i g n o n a 3 2 b y t e c a c h e l i n e b o u n d a r y f o r g o o d m e a s u r e .
* /
interrupt_base :
/* Critical Input Interrupt */
2005-10-01 12:43:42 +04:00
CRITICAL_ E X C E P T I O N ( 0 x01 0 0 , C r i t i c a l I n p u t , u n k n o w n _ e x c e p t i o n )
2005-09-26 10:04:21 +04:00
/* Machine Check Interrupt */
# ifdef C O N F I G _ E 2 0 0
/* no RFMCI, MCSRRs on E200 */
2005-10-01 12:43:42 +04:00
CRITICAL_ E X C E P T I O N ( 0 x02 0 0 , M a c h i n e C h e c k , m a c h i n e _ c h e c k _ e x c e p t i o n )
2005-09-26 10:04:21 +04:00
# else
2005-10-01 12:43:42 +04:00
MCHECK_ E X C E P T I O N ( 0 x02 0 0 , M a c h i n e C h e c k , m a c h i n e _ c h e c k _ e x c e p t i o n )
2005-09-26 10:04:21 +04:00
# endif
/* Data Storage Interrupt */
START_ E X C E P T I O N ( D a t a S t o r a g e )
2008-07-09 19:03:28 +04:00
NORMAL_ E X C E P T I O N _ P R O L O G
mfspr r5 ,S P R N _ E S R / * G r a b t h e E S R , s a v e i t , p a s s a r g 3 * /
stw r5 ,_ E S R ( r11 )
mfspr r4 ,S P R N _ D E A R / * G r a b t h e D E A R , s a v e i t , p a s s a r g 2 * /
andis. r10 ,r5 ,( E S R _ I L K | E S R _ D L K ) @h
bne 1 f
EXC_ X F E R _ E E _ L I T E ( 0 x03 0 0 , h a n d l e _ p a g e _ f a u l t )
1 :
addi r3 ,r1 ,S T A C K _ F R A M E _ O V E R H E A D
EXC_ X F E R _ E E _ L I T E ( 0 x03 0 0 , C a c h e L o c k i n g E x c e p t i o n )
2005-09-26 10:04:21 +04:00
/* Instruction Storage Interrupt */
INSTRUCTION_ S T O R A G E _ E X C E P T I O N
/* External Input Interrupt */
EXCEPTION( 0 x05 0 0 , E x t e r n a l I n p u t , d o _ I R Q , E X C _ X F E R _ L I T E )
/* Alignment Interrupt */
ALIGNMENT_ E X C E P T I O N
/* Program Interrupt */
PROGRAM_ E X C E P T I O N
/* Floating Point Unavailable Interrupt */
# ifdef C O N F I G _ P P C _ F P U
FP_ U N A V A I L A B L E _ E X C E P T I O N
# else
# ifdef C O N F I G _ E 2 0 0
/* E200 treats 'normal' floating point instructions as FP Unavail exception */
2005-10-01 12:43:42 +04:00
EXCEPTION( 0 x08 0 0 , F l o a t i n g P o i n t U n a v a i l a b l e , p r o g r a m _ c h e c k _ e x c e p t i o n , E X C _ X F E R _ E E )
2005-09-26 10:04:21 +04:00
# else
2005-10-01 12:43:42 +04:00
EXCEPTION( 0 x08 0 0 , F l o a t i n g P o i n t U n a v a i l a b l e , u n k n o w n _ e x c e p t i o n , E X C _ X F E R _ E E )
2005-09-26 10:04:21 +04:00
# endif
# endif
/* System Call Interrupt */
START_ E X C E P T I O N ( S y s t e m C a l l )
NORMAL_ E X C E P T I O N _ P R O L O G
EXC_ X F E R _ E E _ L I T E ( 0 x0 c00 , D o S y s c a l l )
/* Auxillary Processor Unavailable Interrupt */
2005-10-01 12:43:42 +04:00
EXCEPTION( 0 x29 0 0 , A u x i l l a r y P r o c e s s o r U n a v a i l a b l e , u n k n o w n _ e x c e p t i o n , E X C _ X F E R _ E E )
2005-09-26 10:04:21 +04:00
/* Decrementer Interrupt */
DECREMENTER_ E X C E P T I O N
/* Fixed Internal Timer Interrupt */
/* TODO: Add FIT support */
2005-10-01 12:43:42 +04:00
EXCEPTION( 0 x31 0 0 , F i x e d I n t e r v a l T i m e r , u n k n o w n _ e x c e p t i o n , E X C _ X F E R _ E E )
2005-09-26 10:04:21 +04:00
/* Watchdog Timer Interrupt */
# ifdef C O N F I G _ B O O K E _ W D T
CRITICAL_ E X C E P T I O N ( 0 x32 0 0 , W a t c h d o g T i m e r , W a t c h d o g E x c e p t i o n )
# else
2005-10-01 12:43:42 +04:00
CRITICAL_ E X C E P T I O N ( 0 x32 0 0 , W a t c h d o g T i m e r , u n k n o w n _ e x c e p t i o n )
2005-09-26 10:04:21 +04:00
# endif
/* Data TLB Error Interrupt */
START_ E X C E P T I O N ( D a t a T L B E r r o r )
mtspr S P R N _ S P R G 0 , r10 / * S a v e s o m e w o r k i n g r e g i s t e r s * /
mtspr S P R N _ S P R G 1 , r11
mtspr S P R N _ S P R G 4 W , r12
mtspr S P R N _ S P R G 5 W , r13
mfcr r11
mtspr S P R N _ S P R G 7 W , r11
mfspr r10 , S P R N _ D E A R / * G e t f a u l t i n g a d d r e s s * /
/ * If w e a r e f a u l t i n g a k e r n e l a d d r e s s , w e h a v e t o u s e t h e
* kernel p a g e t a b l e s .
* /
2007-10-11 22:36:52 +04:00
lis r11 , P A G E _ O F F S E T @h
2005-09-26 10:04:21 +04:00
cmplw 5 , r10 , r11
blt 5 , 3 f
lis r11 , s w a p p e r _ p g _ d i r @h
ori r11 , r11 , s w a p p e r _ p g _ d i r @l
mfspr r12 ,S P R N _ M A S 1 / * S e t T I D t o 0 * /
rlwinm r12 ,r12 ,0 ,1 6 ,1
mtspr S P R N _ M A S 1 ,r12
b 4 f
/* Get the PGD for the current thread */
3 :
mfspr r11 ,S P R N _ S P R G 3
lwz r11 ,P G D I R ( r11 )
4 :
2008-07-09 19:03:28 +04:00
/ * Mask o f r e q u i r e d p e r m i s s i o n b i t s . N o t e t h a t w h i l e w e
* do c o p y E S R : S T t o _ P A G E _ R W p o s i t i o n a s t r y i n g t o w r i t e
* to a n R O p a g e i s p r e t t y c o m m o n , w e d o n ' t d o i t w i t h
* _ PAGE_ D I R T Y . W e c o u l d d o i t , b u t i t ' s a f a i r l y r a r e
* event s o I ' d r a t h e r t a k e t h e o v e r h e a d w h e n i t h a p p e n s
* rather t h a n a d d i n g a n i n s t r u c t i o n h e r e . W e s h o u l d m e a s u r e
* whether t h e w h o l e t h i n g i s w o r t h i t i n t h e f i r s t p l a c e
* as w e c o u l d a v o i d l o a d i n g S P R N _ E S R c o m p l e t e l y i n t h e f i r s t
* place. . .
*
* TODO : Is i t w o r t h d o i n g t h a t m f s p r & r l w i m i i n t h e f i r s t
* place o r c a n w e s a v e a c o u p l e o f i n s t r u c t i o n s h e r e ?
* /
mfspr r12 ,S P R N _ E S R
li r13 ,_ P A G E _ P R E S E N T | _ P A G E _ A C C E S S E D
rlwimi r13 ,r12 ,1 1 ,2 9 ,2 9
2005-09-26 10:04:21 +04:00
FIND_ P T E
2008-07-09 19:03:28 +04:00
andc. r13 ,r13 ,r11 / * C h e c k p e r m i s s i o n * /
2005-09-26 10:04:21 +04:00
# ifdef C O N F I G _ P T E _ 6 4 B I T
2008-07-17 01:17:08 +04:00
# ifdef C O N F I G _ S M P
subf r10 ,r11 ,r12 / * c r e a t e f a l s e d a t a d e p * /
lwzx r13 ,r11 ,r10 / * G e t u p p e r p t e b i t s * /
# else
lwz r13 ,0 ( r12 ) / * G e t u p p e r p t e b i t s * /
# endif
2005-09-26 10:04:21 +04:00
# endif
2008-07-17 01:17:08 +04:00
bne 2 f / * B a i l i f p e r m i s s i o n / v a l i d m i s m a c h * /
/* Jump to common tlb load */
2005-09-26 10:04:21 +04:00
b f i n i s h _ t l b _ l o a d
2 :
/ * The b a i l o u t . R e s t o r e r e g i s t e r s t o p r e - e x c e p t i o n c o n d i t i o n s
* and c a l l t h e h e a v y w e i g h t s t o h e l p u s o u t .
* /
mfspr r11 , S P R N _ S P R G 7 R
mtcr r11
mfspr r13 , S P R N _ S P R G 5 R
mfspr r12 , S P R N _ S P R G 4 R
mfspr r11 , S P R N _ S P R G 1
mfspr r10 , S P R N _ S P R G 0
2008-07-09 19:03:28 +04:00
b D a t a S t o r a g e
2005-09-26 10:04:21 +04:00
/* Instruction TLB Error Interrupt */
/ *
* Nearly t h e s a m e a s a b o v e , e x c e p t w e g e t o u r
* information f r o m d i f f e r e n t r e g i s t e r s a n d b a i l o u t
* to a d i f f e r e n t p o i n t .
* /
START_ E X C E P T I O N ( I n s t r u c t i o n T L B E r r o r )
mtspr S P R N _ S P R G 0 , r10 / * S a v e s o m e w o r k i n g r e g i s t e r s * /
mtspr S P R N _ S P R G 1 , r11
mtspr S P R N _ S P R G 4 W , r12
mtspr S P R N _ S P R G 5 W , r13
mfcr r11
mtspr S P R N _ S P R G 7 W , r11
mfspr r10 , S P R N _ S R R 0 / * G e t f a u l t i n g a d d r e s s * /
/ * If w e a r e f a u l t i n g a k e r n e l a d d r e s s , w e h a v e t o u s e t h e
* kernel p a g e t a b l e s .
* /
2007-10-11 22:36:52 +04:00
lis r11 , P A G E _ O F F S E T @h
2005-09-26 10:04:21 +04:00
cmplw 5 , r10 , r11
blt 5 , 3 f
lis r11 , s w a p p e r _ p g _ d i r @h
ori r11 , r11 , s w a p p e r _ p g _ d i r @l
mfspr r12 ,S P R N _ M A S 1 / * S e t T I D t o 0 * /
rlwinm r12 ,r12 ,0 ,1 6 ,1
mtspr S P R N _ M A S 1 ,r12
b 4 f
/* Get the PGD for the current thread */
3 :
mfspr r11 ,S P R N _ S P R G 3
lwz r11 ,P G D I R ( r11 )
4 :
2008-07-09 19:03:28 +04:00
/* Make up the required permissions */
li r13 ,_ P A G E _ P R E S E N T | _ P A G E _ A C C E S S E D | _ P A G E _ H W E X E C
2005-09-26 10:04:21 +04:00
FIND_ P T E
2008-07-09 19:03:28 +04:00
andc. r13 ,r13 ,r11 / * C h e c k p e r m i s s i o n * /
2008-07-17 01:17:08 +04:00
# ifdef C O N F I G _ P T E _ 6 4 B I T
# ifdef C O N F I G _ S M P
subf r10 ,r11 ,r12 / * c r e a t e f a l s e d a t a d e p * /
lwzx r13 ,r11 ,r10 / * G e t u p p e r p t e b i t s * /
# else
lwz r13 ,0 ( r12 ) / * G e t u p p e r p t e b i t s * /
# endif
# endif
2008-07-09 19:03:28 +04:00
bne 2 f / * B a i l i f p e r m i s s i o n m i s m a c h * /
2005-09-26 10:04:21 +04:00
/* Jump to common TLB load point */
b f i n i s h _ t l b _ l o a d
2 :
/ * The b a i l o u t . R e s t o r e r e g i s t e r s t o p r e - e x c e p t i o n c o n d i t i o n s
* and c a l l t h e h e a v y w e i g h t s t o h e l p u s o u t .
* /
mfspr r11 , S P R N _ S P R G 7 R
mtcr r11
mfspr r13 , S P R N _ S P R G 5 R
mfspr r12 , S P R N _ S P R G 4 R
mfspr r11 , S P R N _ S P R G 1
mfspr r10 , S P R N _ S P R G 0
b I n s t r u c t i o n S t o r a g e
# ifdef C O N F I G _ S P E
/* SPE Unavailable */
START_ E X C E P T I O N ( S P E U n a v a i l a b l e )
NORMAL_ E X C E P T I O N _ P R O L O G
bne l o a d _ u p _ s p e
2007-09-27 17:43:35 +04:00
addi r3 ,r1 ,S T A C K _ F R A M E _ O V E R H E A D
2005-09-26 10:04:21 +04:00
EXC_ X F E R _ E E _ L I T E ( 0 x20 1 0 , K e r n e l S P E )
# else
2005-10-01 12:43:42 +04:00
EXCEPTION( 0 x20 2 0 , S P E U n a v a i l a b l e , u n k n o w n _ e x c e p t i o n , E X C _ X F E R _ E E )
2005-09-26 10:04:21 +04:00
# endif / * C O N F I G _ S P E * /
/* SPE Floating Point Data */
# ifdef C O N F I G _ S P E
EXCEPTION( 0 x20 3 0 , S P E F l o a t i n g P o i n t D a t a , S P E F l o a t i n g P o i n t E x c e p t i o n , E X C _ X F E R _ E E ) ;
/* SPE Floating Point Round */
2008-10-28 06:50:21 +03:00
EXCEPTION( 0 x20 5 0 , S P E F l o a t i n g P o i n t R o u n d , S P E F l o a t i n g P o i n t R o u n d E x c e p t i o n , E X C _ X F E R _ E E )
# else
EXCEPTION( 0 x20 4 0 , S P E F l o a t i n g P o i n t D a t a , u n k n o w n _ e x c e p t i o n , E X C _ X F E R _ E E )
2005-10-01 12:43:42 +04:00
EXCEPTION( 0 x20 5 0 , S P E F l o a t i n g P o i n t R o u n d , u n k n o w n _ e x c e p t i o n , E X C _ X F E R _ E E )
2008-10-28 06:50:21 +03:00
# endif / * C O N F I G _ S P E * /
2005-09-26 10:04:21 +04:00
/* Performance Monitor */
2005-10-01 12:43:42 +04:00
EXCEPTION( 0 x20 6 0 , P e r f o r m a n c e M o n i t o r , p e r f o r m a n c e _ m o n i t o r _ e x c e p t i o n , E X C _ X F E R _ S T D )
2005-09-26 10:04:21 +04:00
2008-06-16 18:41:32 +04:00
# ifdef C O N F I G _ P P C _ E 5 0 0 M C
EXCEPTION( 0 x20 7 0 , D o o r b e l l , u n k n o w n _ e x c e p t i o n , E X C _ X F E R _ E E )
# endif
2005-09-26 10:04:21 +04:00
/* Debug Interrupt */
2008-04-09 15:06:11 +04:00
DEBUG_ D E B U G _ E X C E P T I O N
2008-06-16 18:41:32 +04:00
# if d e f i n e d ( C O N F I G _ E 5 0 0 ) & & ! d e f i n e d ( C O N F I G _ P P C _ E 5 0 0 M C )
2008-04-09 15:06:11 +04:00
DEBUG_ C R I T _ E X C E P T I O N
# endif
2005-09-26 10:04:21 +04:00
/ *
* Local f u n c t i o n s
* /
/ *
* Both t h e i n s t r u c t i o n a n d d a t a T L B m i s s g e t t o t h i s
* point t o l o a d t h e T L B .
2008-07-17 01:17:08 +04:00
* r1 0 - a v a i l a b l e t o u s e
2007-09-27 17:43:35 +04:00
* r1 1 - T L B ( i n f o f r o m L i n u x P T E )
2008-07-09 19:03:28 +04:00
* r1 2 - a v a i l a b l e t o u s e
* r1 3 - u p p e r b i t s o f P T E ( i f P T E _ 6 4 B I T ) o r a v a i l a b l e t o u s e
2007-10-11 22:36:52 +04:00
* CR5 - r e s u l t s o f a d d r > = P A G E _ O F F S E T
2005-09-26 10:04:21 +04:00
* MAS0 , M A S 1 - l o a d e d w i t h p r o p e r v a l u e w h e n w e g e t h e r e
* MAS2 , M A S 3 - w i l l n e e d a d d i t i o n a l i n f o f r o m L i n u x P T E
* Upon e x i t , w e r e l o a d e v e r y t h i n g a n d R F I .
* /
finish_tlb_load :
/ *
* We s e t e x e c u t e , b e c a u s e w e d o n ' t h a v e t h e g r a n u l a r i t y t o
* properly s e t t h i s a t t h e p a g e l e v e l ( L i n u x p r o b l e m ) .
* Many o f t h e s e b i t s a r e s o f t w a r e o n l y . B i t s w e d o n ' t s e t
* here w e ( p r o p e r l y s h o u l d ) a s s u m e h a v e t h e a p p r o p r i a t e v a l u e .
* /
mfspr r12 , S P R N _ M A S 2
# ifdef C O N F I G _ P T E _ 6 4 B I T
rlwimi r12 , r11 , 2 6 , 2 4 , 3 1 / * e x t r a c t . . . W I M G E f r o m p t e * /
# else
rlwimi r12 , r11 , 2 6 , 2 7 , 3 1 / * e x t r a c t W I M G E f r o m p t e * /
2008-11-19 18:35:56 +03:00
# endif
# ifdef C O N F I G _ S M P
ori r12 , r12 , M A S 2 _ M
2005-09-26 10:04:21 +04:00
# endif
mtspr S P R N _ M A S 2 , r12
2008-07-09 19:03:28 +04:00
li r10 , ( _ P A G E _ H W E X E C | _ P A G E _ P R E S E N T )
rlwimi r10 , r11 , 3 1 , 2 9 , 2 9 / * e x t r a c t _ P A G E _ D I R T Y i n t o S W * /
and r12 , r11 , r10
2005-09-26 10:04:21 +04:00
andi. r10 , r11 , _ P A G E _ U S E R / * T e s t f o r _ P A G E _ U S E R * /
2008-07-09 19:03:28 +04:00
slwi r10 , r12 , 1
or r10 , r10 , r12
iseleq r12 , r12 , r10
2005-09-26 10:04:21 +04:00
# ifdef C O N F I G _ P T E _ 6 4 B I T
2008-12-01 23:38:32 +03:00
rlwimi r12 , r13 , 2 4 , 0 , 7 / * g r a b R P N [ 3 2 : 3 9 ] * /
2005-09-26 10:04:21 +04:00
rlwimi r12 , r11 , 2 4 , 8 , 1 9 / * g r a b R P N [ 4 0 : 5 1 ] * /
mtspr S P R N _ M A S 3 , r12
2008-12-18 22:13:32 +03:00
BEGIN_ M M U _ F T R _ S E C T I O N
2005-09-26 10:04:21 +04:00
srwi r10 , r13 , 8 / * g r a b R P N [ 8 : 3 1 ] * /
mtspr S P R N _ M A S 7 , r10
2008-12-18 22:13:32 +03:00
END_ M M U _ F T R _ S E C T I O N _ I F S E T ( M M U _ F T R _ B I G _ P H Y S )
2005-09-26 10:04:21 +04:00
# else
2008-12-01 23:38:32 +03:00
rlwimi r11 , r12 , 0 , 2 0 , 3 1 / * E x t r a c t R P N f r o m P T E a n d m e r g e w i t h p e r m s * /
2005-09-26 10:04:21 +04:00
mtspr S P R N _ M A S 3 , r11
# endif
# ifdef C O N F I G _ E 2 0 0
/* Round robin TLB1 entries assignment */
mfspr r12 , S P R N _ M A S 0
/* Extract TLB1CFG(NENTRY) */
mfspr r11 , S P R N _ T L B 1 C F G
andi. r11 , r11 , 0 x f f f
/* Extract MAS0(NV) */
andi. r13 , r12 , 0 x f f f
addi r13 , r13 , 1
cmpw 0 , r13 , r11
addi r12 , r12 , 1
/* check if we need to wrap */
blt 7 f
/* wrap back to first free tlbcam entry */
lis r13 , t l b c a m _ i n d e x @ha
lwz r13 , t l b c a m _ i n d e x @l(r13)
rlwimi r12 , r13 , 0 , 2 0 , 3 1
7 :
2007-09-27 17:43:35 +04:00
mtspr S P R N _ M A S 0 ,r12
2005-09-26 10:04:21 +04:00
# endif / * C O N F I G _ E 2 0 0 * /
tlbwe
/* Done...restore registers and get out of here. */
mfspr r11 , S P R N _ S P R G 7 R
mtcr r11
mfspr r13 , S P R N _ S P R G 5 R
mfspr r12 , S P R N _ S P R G 4 R
mfspr r11 , S P R N _ S P R G 1
mfspr r10 , S P R N _ S P R G 0
rfi / * F o r c e c o n t e x t c h a n g e * /
# ifdef C O N F I G _ S P E
/ * Note t h a t t h e S P E s u p p o r t i s c l o s e l y m o d e l e d a f t e r t h e A l t i V e c
* support. C h a n g e s t o o n e a r e l i k e l y t o b e a p p l i c a b l e t o t h e
* other! * /
load_up_spe :
/ *
* Disable S P E f o r t h e t a s k w h i c h h a d S P E p r e v i o u s l y ,
* and s a v e i t s S P E 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 S P E 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 .
* On S M P w e k n o w t h e S P E u n i t s a r e f r e e , s i n c e w e g i v e i t u p e v e r y
* switch. - - K u m a r
* /
mfmsr r5
oris r5 ,r5 ,M S R _ S P E @h
mtmsr r5 / * e n a b l e u s e o f S P E n o w * /
isync
/ *
* For S M P , w e d o n ' t d o l a z y S P E s w i t c h i n g b e c a u s e i t j u s t g e t s t o o
* horrendously c o m p l e x , e s p e c i a l l y w h e n a t a s k s w i t c h e s f r o m o n e C P U
* to a n o t h e r . I n s t e a d w e c a l l g i v e u p _ s p e i n s w i t c h _ t o .
* /
# ifndef C O N F I G _ S M P
lis r3 ,l a s t _ t a s k _ u s e d _ s p e @ha
lwz r4 ,l a s t _ t a s k _ u s e d _ s p e @l(r3)
cmpi 0 ,r4 ,0
beq 1 f
addi r4 ,r4 ,T H R E A D / * w a n t T H R E A D o f l a s t _ t a s k _ u s e d _ s p e * /
SAVE_ 3 2 E V R S ( 0 ,r10 ,r4 )
2007-09-27 17:43:35 +04:00
evxor e v r10 , e v r10 , e v r10 / * c l e a r o u t e v r10 * /
2005-09-26 10:04:21 +04:00
evmwumiaa e v r10 , e v r10 , e v r10 / * e v r10 < - A C C = 0 * 0 + A C C * /
li r5 ,T H R E A D _ A C C
2007-09-27 17:43:35 +04:00
evstddx e v r10 , r4 , r5 / * s a v e o f f a c c u m u l a t o r * /
2005-09-26 10:04:21 +04:00
lwz r5 ,P T _ R E G S ( r4 )
lwz r4 ,_ M S R - S T A C K _ F R A M E _ O V E R H E A D ( r5 )
lis r10 ,M S R _ S P E @h
andc r4 ,r4 ,r10 / * d i s a b l e S P E f o r p r e v i o u s t a s k * /
stw r4 ,_ M S R - S T A C K _ F R A M E _ O V E R H E A D ( r5 )
1 :
2007-09-27 17:43:35 +04:00
# endif / * ! C O N F I G _ S M P * /
2005-09-26 10:04:21 +04:00
/* enable use of SPE after return */
oris r9 ,r9 ,M S R _ S P E @h
mfspr r5 ,S P R N _ S P R G 3 / * c u r r e n t t a s k ' s T H R E A D ( p h y s ) * /
li r4 ,1
li r10 ,T H R E A D _ A C C
stw r4 ,T H R E A D _ U S E D _ S P E ( r5 )
evlddx e v r4 ,r10 ,r5
evmra e v r4 ,e v r4
REST_ 3 2 E V R S ( 0 ,r10 ,r5 )
# ifndef C O N F I G _ S M P
subi r4 ,r5 ,T H R E A D
stw r4 ,l a s t _ t a s k _ u s e d _ s p e @l(r3)
2007-09-27 17:43:35 +04:00
# endif / * ! C O N F I G _ S M P * /
2005-09-26 10:04:21 +04:00
/* restore registers and return */
2 : REST_ 4 G P R S ( 3 , r11 )
lwz r10 ,_ C C R ( r11 )
REST_ G P R ( 1 , r11 )
mtcr r10
lwz r10 ,_ L I N K ( r11 )
mtlr r10
REST_ G P R ( 1 0 , r11 )
mtspr S P R N _ S R R 1 ,r9
mtspr S P R N _ S R R 0 ,r12
REST_ G P R ( 9 , r11 )
REST_ G P R ( 1 2 , r11 )
lwz r11 ,G P R 1 1 ( r11 )
rfi
/ *
* SPE u n a v a i l a b l e t r a p f r o m k e r n e l - p r i n t a m e s s a g e , b u t l e t
* the t a s k u s e S P E i n t h e k e r n e l u n t i l i t r e t u r n s t o u s e r m o d e .
* /
KernelSPE :
lwz r3 ,_ M S R ( r1 )
oris r3 ,r3 ,M S R _ S P E @h
stw r3 ,_ M S R ( r1 ) / * e n a b l e u s e o f S P E a f t e r r e t u r n * /
lis r3 ,8 7 f @h
ori r3 ,r3 ,8 7 f @l
mr r4 ,r2 / * c u r r e n t * /
lwz r5 ,_ N I P ( r1 )
bl p r i n t k
b r e t _ f r o m _ e x c e p t
87 : .string " SPE used in kernel (task=%p, pc=%x) \n "
.align 4 , 0
# endif / * C O N F I G _ S P E * /
/ *
* Global f u n c t i o n s
* /
/ *
* extern v o i d l o a d c a m _ e n t r y ( u n s i g n e d i n t i n d e x )
*
* Load T L B C A M [ i n d e x ] e n t r y i n t o t h e L 2 C A M M M U
* /
_ GLOBAL( l o a d c a m _ e n t r y )
lis r4 ,T L B C A M @ha
addi r4 ,r4 ,T L B C A M @l
mulli r5 ,r3 ,2 0
add r3 ,r5 ,r4
lwz r4 ,0 ( r3 )
mtspr S P R N _ M A S 0 ,r4
lwz r4 ,4 ( r3 )
mtspr S P R N _ M A S 1 ,r4
lwz r4 ,8 ( r3 )
mtspr S P R N _ M A S 2 ,r4
lwz r4 ,1 2 ( r3 )
mtspr S P R N _ M A S 3 ,r4
tlbwe
isync
blr
/ *
* extern v o i d g i v e u p _ a l t i v e c ( s t r u c t t a s k _ s t r u c t * p r e v )
*
* The e 5 0 0 c o r e d o e s n o t h a v e a n A l t i V e c u n i t .
* /
_ GLOBAL( g i v e u p _ a l t i v e c )
blr
# ifdef C O N F I G _ S P E
/ *
* extern v o i d g i v e u p _ s p e ( s t r u c t t a s k _ s t r u c t * p r e v )
*
* /
_ GLOBAL( g i v e u p _ s p e )
mfmsr r5
oris r5 ,r5 ,M S R _ S P E @h
mtmsr r5 / * e n a b l e u s e o f S P E n o w * /
isync
cmpi 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 * /
lwz r5 ,P T _ R E G S ( r3 )
cmpi 0 ,r5 ,0
SAVE_ 3 2 E V R S ( 0 , r4 , r3 )
2007-09-27 17:43:35 +04:00
evxor e v r6 , e v r6 , e v r6 / * c l e a r o u t e v r6 * /
2005-09-26 10:04:21 +04:00
evmwumiaa e v r6 , e v r6 , e v r6 / * e v r6 < - A C C = 0 * 0 + A C C * /
li r4 ,T H R E A D _ A C C
2007-09-27 17:43:35 +04:00
evstddx e v r6 , r4 , r3 / * s a v e o f f a c c u m u l a t o r * /
2005-09-26 10:04:21 +04:00
mfspr r6 ,S P R N _ S P E F S C R
stw r6 ,T H R E A D _ S P E F S C R ( r3 ) / * s a v e s p e f s c r r e g i s t e r v a l u e * /
beq 1 f
lwz 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 _ S P E @h
andc r4 ,r4 ,r3 / * d i s a b l e S P E f o r p r e v i o u s t a s k * /
stw 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
lis r4 ,l a s t _ t a s k _ u s e d _ s p e @ha
stw r5 ,l a s t _ t a s k _ u s e d _ s p e @l(r4)
2007-09-27 17:43:35 +04:00
# endif / * ! C O N F I G _ S M P * /
2005-09-26 10:04:21 +04:00
blr
# endif / * C O N F I G _ S P E * /
/ *
* extern v o i d g i v e u p _ f p u ( s t r u c t t a s k _ s t r u c t * p r e v )
*
* Not a l l F S L B o o k - E c o r e s h a v e a n F P U
* /
# ifndef C O N F I G _ P P C _ F P U
_ GLOBAL( g i v e u p _ f p u )
blr
# endif
/ *
* extern v o i d a b o r t ( v o i d )
*
* At p r e s e n t , t h i s r o u t i n e j u s t a p p l i e s a s y s t e m r e s e t .
* /
_ GLOBAL( a b o r t )
li r13 ,0
2007-09-27 17:43:35 +04:00
mtspr S P R N _ D B C R 0 ,r13 / * d i s a b l e a l l d e b u g e v e n t s * /
2006-02-09 01:41:26 +03:00
isync
2005-09-26 10:04:21 +04:00
mfmsr r13
ori r13 ,r13 ,M S R _ D E @l /* Enable Debug Events */
mtmsr r13
2006-02-09 01:41:26 +03:00
isync
2007-09-27 17:43:35 +04:00
mfspr r13 ,S P R N _ D B C R 0
lis r13 ,( D B C R 0 _ I D M | D B C R 0 _ R S T _ C H I P ) @h
mtspr S P R N _ D B C R 0 ,r13
2006-02-09 01:41:26 +03:00
isync
2005-09-26 10:04:21 +04:00
_ GLOBAL( s e t _ c o n t e x t )
# ifdef C O N F I G _ B D I _ S W I T C H
/ * Context s w i t c h t h e P T E p o i n t e r f o r t h e A b a t r o n B D I 2 0 0 0 .
* The P G D I R i s t h e s e c o n d p a r a m e t e r .
* /
lis r5 , a b a t r o n _ p t e p t r s @h
ori r5 , r5 , a b a t r o n _ p t e p t r s @l
stw r4 , 0 x4 ( r5 )
# endif
mtspr S P R N _ P I D ,r3
isync / * F o r c e c o n t e x t c h a n g e * /
blr
2008-06-19 01:26:52 +04:00
_ GLOBAL( f l u s h _ d c a c h e _ L 1 )
mfspr r3 ,S P R N _ L 1 C F G 0
rlwinm r5 ,r3 ,9 ,3 / * E x t r a c t c a c h e b l o c k s i z e * /
twlgti r5 ,1 / * O n l y 3 2 a n d 6 4 b y t e c a c h e b l o c k s
* are c u r r e n t l y d e f i n e d .
* /
li r4 ,3 2
subfic r6 ,r5 ,2 / * r6 = l o g 2 ( 1 K i B / c a c h e b l o c k s i z e ) -
* log2 ( n u m b e r o f w a y s )
* /
slw r5 ,r4 ,r5 / * r5 = c a c h e b l o c k s i z e * /
rlwinm r7 ,r3 ,0 ,0 x f f / * E x t r a c t n u m b e r o f K i B i n t h e c a c h e * /
mulli r7 ,r7 ,1 3 / * A n 8 - w a y c a c h e w i l l r e q u i r e 1 3
* loads p e r s e t .
* /
slw r7 ,r7 ,r6
/* save off HID0 and set DCFA */
mfspr r8 ,S P R N _ H I D 0
ori r9 ,r8 ,H I D 0 _ D C F A @l
mtspr S P R N _ H I D 0 ,r9
isync
lis r4 ,K E R N E L B A S E @h
mtctr r7
1 : lwz r3 ,0 ( r4 ) / * L o a d . . . * /
add r4 ,r4 ,r5
bdnz 1 b
msync
lis r4 ,K E R N E L B A S E @h
mtctr r7
1 : dcbf 0 ,r4 / * . . . a n d f l u s h . * /
add r4 ,r4 ,r5
bdnz 1 b
/* restore HID0 */
mtspr S P R N _ H I D 0 ,r8
isync
blr
2008-11-19 18:35:56 +03:00
# ifdef C O N F I G _ S M P
/* When we get here, r24 needs to hold the CPU # */
.globl __secondary_start
__secondary_start :
lis r3 ,_ _ s e c o n d a r y _ h o l d _ a c k n o w l e d g e @h
ori r3 ,r3 ,_ _ s e c o n d a r y _ h o l d _ a c k n o w l e d g e @l
stw r24 ,0 ( r3 )
li r3 ,0
mr r4 ,r24 / * W h y ? * /
bl c a l l _ s e t u p _ c p u
lis r3 ,t l b c a m _ i n d e x @ha
lwz r3 ,t l b c a m _ i n d e x @l(r3)
mtctr r3
li r26 ,0 / * r26 s a f e ? * /
/* Load each CAM entry */
1 : mr r3 ,r26
bl l o a d c a m _ e n t r y
addi r26 ,r26 ,1
bdnz 1 b
/* get current_thread_info and current */
lis r1 ,s e c o n d a r y _ t i @ha
lwz r1 ,s e c o n d a r y _ t i @l(r1)
lwz r2 ,T I _ T A S K ( r1 )
/* stack */
addi r1 ,r1 ,T H R E A D _ S I Z E - S T A C K _ F R A M E _ O V E R H E A D
li r0 ,0
stw r0 ,0 ( r1 )
/* ptr to current thread */
addi r4 ,r2 ,T H R E A D / * a d d r e s s o f o u r t h r e a d _ s t r u c t * /
mtspr S P R N _ S P R G 3 ,r4
/* Setup the defaults for TLB entries */
li r4 ,( M A S 4 _ T S I Z E D ( B O O K E _ P A G E S Z _ 4 K ) ) @l
mtspr S P R N _ M A S 4 ,r4
/* Jump to start_secondary */
lis r4 ,M S R _ K E R N E L @h
ori r4 ,r4 ,M S R _ K E R N E L @l
lis r3 ,s t a r t _ s e c o n d a r y @h
ori r3 ,r3 ,s t a r t _ s e c o n d a r y @l
mtspr S P R N _ S R R 0 ,r3
mtspr S P R N _ S R R 1 ,r4
sync
rfi
sync
.globl __secondary_hold_acknowledge
__secondary_hold_acknowledge :
.long - 1
# endif
2005-09-26 10:04:21 +04:00
/ *
* We p u t a f e w t h i n g s h e r e t h a t h a v e t o b e p a g e - a l i g n e d . T h i s s t u f f
* goes a t t h e b e g i n n i n g o f t h e d a t a s e g m e n t , w h i c h i s p a g e - a l i g n e d .
* /
.data
2005-10-12 08:54:00 +04:00
.align 12
.globl sdata
sdata :
.globl empty_zero_page
empty_zero_page :
2005-09-26 10:04:21 +04:00
.space 4096
2005-10-12 08:54:00 +04:00
.globl swapper_pg_dir
swapper_pg_dir :
2007-12-06 22:11:04 +03:00
.space PGD_TABLE_SIZE
2005-09-26 10:04:21 +04:00
/ *
* Room f o r t w o P T E p o i n t e r s , u s u a l l y t h e k e r n e l a n d c u r r e n t u s e r p o i n t e r s
* to t h e i r r e s p e c t i v e r o o t p a g e t a b l e .
* /
abatron_pteptrs :
.space 8