2009-07-23 23:15:59 +00:00
/ *
* Boot c o d e a n d e x c e p t i o n v e c t o r s f o r B o o k 3 E p r o c e s s o r s
*
* Copyright ( C ) 2 0 0 7 B e n . H e r r e n s c h m i d t ( b e n h @kernel.crashing.org), IBM Corp.
*
* 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 / t h r e a d s . h >
# include < a s m / r e g . h >
# include < a s m / p a g 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 >
# include < a s m / s e t u p . h >
# include < a s m / t h r e a d _ i n f o . h >
# include < a s m / e x c e p t i o n - 6 4 e . h >
# include < a s m / b u g . h >
# include < a s m / i r q f l a g s . h >
# include < a s m / p t r a c e . h >
# include < a s m / p p c - o p c o d e . h >
# include < a s m / m m u . h >
/ * XXX T h i s w i l l u l t i m a t e l y a d d s p a c e f o r a s p e c i a l e x c e p t i o n s a v e
* structure u s e d t o s a v e t h i n g s l i k e S R R 0 / S R R 1 , S P R G s , M A S , e t c . . .
* when t a k i n g s p e c i a l i n t e r r u p t s . F o r n o w w e d o n ' t s u p p o r t t h a t ,
* special i n t e r r u p t s f r o m w i t h i n a n o n - s t a n d a r d l e v e l w i l l p r o b a b l y
* blow y o u u p
* /
# define S P E C I A L _ E X C _ F R A M E _ S I Z E I N T _ F R A M E _ S I Z E
/* Exception prolog code for all exceptions */
# define E X C E P T I O N _ P R O L O G ( n , t y p e , a d d i t i o n ) \
mtspr S P R N _ S P R G _ ## t y p e # # _ S C R A T C H , r 13 ; /* get spare registers */ \
mfspr r13 ,S P R N _ S P R G _ P A C A ; /* get PACA */ \
std r10 ,P A C A _ E X ## t y p e + E X _ R 10 ( r13 ) ; \
std r11 ,P A C A _ E X ## t y p e + E X _ R 11 ( r13 ) ; \
mfcr r10 ; /* save CR */ \
addition; /* additional code for that exc. */ \
std r1 ,P A C A _ E X ## t y p e + E X _ R 1 ( r13 ) ; /* save old r1 in the PACA */ \
stw r10 ,P A C A _ E X ## t y p e + E X _ C R ( r 13 ) ; /* save old CR in the PACA */ \
mfspr r11 ,S P R N _ ## t y p e # # _ S R R 1 ;/* what are we coming from */ \
type## _ S E T _ K S T A C K ; / * g e t s p e c i a l s t a c k i f n e c e s s a r y * / \
andi. r10 ,r11 ,M S R _ P R ; /* save stack pointer */ \
beq 1 f ; /* branch around if supervisor */ \
ld r1 ,P A C A K S A V E ( r13 ) ; /* get kernel stack coming from usr */\
1 : cmpdi c r1 ,r1 ,0 ; /* check if SP makes sense */ \
bge- c r1 ,e x c _ ## n # # _ b a d _ s t a c k ; / * b a d s t a c k ( T O D O : o u t o f l i n e ) * / \
mfspr r10 ,S P R N _ ## t y p e # # _ S R R 0 ; /* read SRR0 before touching stack */
/* Exception type-specific macros */
# define G E N _ S E T _ K S T A C K \
subi r1 ,r1 ,I N T _ F R A M E _ S I Z E ; /* alloc frame on kernel stack */
# define S P R N _ G E N _ S R R 0 S P R N _ S R R 0
# define S P R N _ G E N _ S R R 1 S P R N _ S R R 1
# define C R I T _ S E T _ K S T A C K \
ld r1 ,P A C A _ C R I T _ S T A C K ( r13 ) ; \
subi r1 ,r1 ,S P E C I A L _ E X C _ F R A M E _ S I Z E ;
# define S P R N _ C R I T _ S R R 0 S P R N _ C S R R 0
# define S P R N _ C R I T _ S R R 1 S P R N _ C S R R 1
# define D B G _ S E T _ K S T A C K \
ld r1 ,P A C A _ D B G _ S T A C K ( r13 ) ; \
subi r1 ,r1 ,S P E C I A L _ E X C _ F R A M E _ S I Z E ;
# define S P R N _ D B G _ S R R 0 S P R N _ D S R R 0
# define S P R N _ D B G _ S R R 1 S P R N _ D S R R 1
# define M C _ S E T _ K S T A C K \
ld r1 ,P A C A _ M C _ S T A C K ( r13 ) ; \
subi r1 ,r1 ,S P E C I A L _ E X C _ F R A M E _ S I Z E ;
# define S P R N _ M C _ S R R 0 S P R N _ M C S R R 0
# define S P R N _ M C _ S R R 1 S P R N _ M C S R R 1
# define N O R M A L _ E X C E P T I O N _ P R O L O G ( n , a d d i t i o n ) \
EXCEPTION_ P R O L O G ( n , G E N , a d d i t i o n ## _ G E N )
# define C R I T _ E X C E P T I O N _ P R O L O G ( n , a d d i t i o n ) \
EXCEPTION_ P R O L O G ( n , C R I T , a d d i t i o n ## _ C R I T )
# define D B G _ E X C E P T I O N _ P R O L O G ( n , a d d i t i o n ) \
EXCEPTION_ P R O L O G ( n , D B G , a d d i t i o n ## _ D B G )
# define M C _ E X C E P T I O N _ P R O L O G ( n , a d d i t i o n ) \
EXCEPTION_ P R O L O G ( n , M C , a d d i t i o n ## _ M C )
/ * Variants o f t h e " a d d i t i o n " a r g u m e n t f o r t h e p r o l o g
* /
# define P R O L O G _ A D D I T I O N _ N O N E _ G E N
# define P R O L O G _ A D D I T I O N _ N O N E _ C R I T
# define P R O L O G _ A D D I T I O N _ N O N E _ D B G
# define P R O L O G _ A D D I T I O N _ N O N E _ M C
# define P R O L O G _ A D D I T I O N _ M A S K A B L E _ G E N \
lbz r11 ,P A C A S O F T I R Q E N ( r13 ) ; /* are irqs soft-disabled ? */ \
cmpwi c r0 ,r11 ,0 ; /* yes -> go out of line */ \
beq m a s k e d _ i n t e r r u p t _ b o o k 3 e ;
# define P R O L O G _ A D D I T I O N _ 2 R E G S _ G E N \
std r14 ,P A C A _ E X G E N + E X _ R 1 4 ( r13 ) ; \
std r15 ,P A C A _ E X G E N + E X _ R 1 5 ( r13 )
# define P R O L O G _ A D D I T I O N _ 1 R E G _ G E N \
std r14 ,P A C A _ E X G E N + E X _ R 1 4 ( r13 ) ;
# define P R O L O G _ A D D I T I O N _ 2 R E G S _ C R I T \
std r14 ,P A C A _ E X C R I T + E X _ R 1 4 ( r13 ) ; \
std r15 ,P A C A _ E X C R I T + E X _ R 1 5 ( r13 )
# define P R O L O G _ A D D I T I O N _ 2 R E G S _ D B G \
std r14 ,P A C A _ E X D B G + E X _ R 1 4 ( r13 ) ; \
std r15 ,P A C A _ E X D B G + E X _ R 1 5 ( r13 )
# define P R O L O G _ A D D I T I O N _ 2 R E G S _ M C \
std r14 ,P A C A _ E X M C + E X _ R 1 4 ( r13 ) ; \
std r15 ,P A C A _ E X M C + E X _ R 1 5 ( r13 )
/ * Core e x c e p t i o n c o d e f o r a l l e x c e p t i o n s e x c e p t T L B m i s s e s .
* XXX : Needs t o m a k e S P R N _ S P R G _ G E N d e p e n d o n e x c e p t i o n t y p e
* /
# define E X C E P T I O N _ C O M M O N ( n , e x c f , i n t s ) \
std r0 ,G P R 0 ( r1 ) ; /* save r0 in stackframe */ \
std r2 ,G P R 2 ( r1 ) ; /* save r2 in stackframe */ \
SAVE_ 4 G P R S ( 3 , r1 ) ; /* save r3 - r6 in stackframe */ \
SAVE_ 2 G P R S ( 7 , r1 ) ; /* save r7, r8 in stackframe */ \
std r9 ,G P R 9 ( r1 ) ; /* save r9 in stackframe */ \
std r10 ,_ N I P ( r1 ) ; /* save SRR0 to stackframe */ \
std r11 ,_ M S R ( r1 ) ; /* save SRR1 to stackframe */ \
ACCOUNT_ C P U _ U S E R _ E N T R Y ( r10 ,r11 ) ;/* accounting (uses cr0+eq) */ \
ld r3 ,e x c f + E X _ R 1 0 ( r13 ) ; /* get back r10 */ \
ld r4 ,e x c f + E X _ R 1 1 ( r13 ) ; /* get back r11 */ \
mfspr r5 ,S P R N _ S P R G _ G E N _ S C R A T C H ;/* get back r13 */ \
std r12 ,G P R 1 2 ( r1 ) ; /* save r12 in stackframe */ \
ld r2 ,P A C A T O C ( r13 ) ; /* get kernel TOC into r2 */ \
mflr r6 ; /* save LR in stackframe */ \
mfctr r7 ; /* save CTR in stackframe */ \
mfspr r8 ,S P R N _ X E R ; /* save XER in stackframe */ \
ld r9 ,e x c f + E X _ R 1 ( r13 ) ; /* load orig r1 back from PACA */ \
lwz r10 ,e x c f + E X _ C R ( r13 ) ; /* load orig CR back from PACA */ \
lbz r11 ,P A C A S O F T I R Q E N ( r13 ) ; /* get current IRQ softe */ \
ld r12 ,e x c e p t i o n _ m a r k e r @toc(r2); \
li r0 ,0 ; \
std r3 ,G P R 1 0 ( r1 ) ; /* save r10 to stackframe */ \
std r4 ,G P R 1 1 ( r1 ) ; /* save r11 to stackframe */ \
std r5 ,G P R 1 3 ( r1 ) ; /* save it to stackframe */ \
std r6 ,_ L I N K ( r1 ) ; \
std r7 ,_ C T R ( r1 ) ; \
std r8 ,_ X E R ( r1 ) ; \
li r3 ,( n ) + 1 ; /* indicate partial regs in trap */ \
std r9 ,0 ( r1 ) ; /* store stack frame back link */ \
std r10 ,_ C C R ( r1 ) ; /* store orig CR in stackframe */ \
std r9 ,G P R 1 ( r1 ) ; /* store stack frame back link */ \
std r11 ,S O F T E ( r1 ) ; /* and save it to stackframe */ \
std r12 ,S T A C K _ F R A M E _ O V E R H E A D - 1 6 ( r1 ) ; /* mark the frame */ \
std r3 ,_ T R A P ( r1 ) ; /* set trap number */ \
std r0 ,R E S U L T ( r1 ) ; /* clear regs->result */ \
ints;
/* Variants for the "ints" argument */
# define I N T S _ K E E P
# define I N T S _ D I S A B L E _ S O F T \
stb r0 ,P A C A S O F T I R Q E N ( r13 ) ; /* mark interrupts soft-disabled */ \
TRACE_ D I S A B L E _ I N T S ;
# define I N T S _ D I S A B L E _ H A R D \
stb r0 ,P A C A H A R D I R Q E N ( r13 ) ; /* and hard disabled */
# define I N T S _ D I S A B L E _ A L L \
INTS_ D I S A B L E _ S O F T \
INTS_ D I S A B L E _ H A R D
/ * This i s c a l l e d b y e x c e p t i o n s t h a t u s e d I N T S _ K E E P ( t h a t i s d i d n o t c l e a r
* neither s o f t n o r h a r d I R Q i n d i c a t o r s i n t h e P A C A . T h i s w i l l r e s t o r e M S R : E E
* to i t ' s p r e v i o u s v a l u e
*
* XXX I n t h e l o n g r u n , w e m a y w a n t t o o p e n - c o d e i t i n o r d e r t o s e p a r a t e t h e
* load f r o m t h e w r t e e , t h u s l i m i t i n g t h e l a t e n c y c a u s e d b y t h e d e p e n d e n c y
* but a t t h i s p o i n t , I ' l l f a v o r c o d e c l a r i t y u n t i l w e h a v e a n e a r t o f i n a l
* implementation
* /
# define I N T S _ R E S T O R E _ H A R D \
ld r11 ,_ M S R ( r1 ) ; \
wrtee r11 ;
/* XXX FIXME: Restore r14/r15 when necessary */
# define B A D _ S T A C K _ T R A M P O L I N E ( n ) \
exc_ ## n # # _ b a d _ s t a c k : \
li r1 ,( n ) ; /* get exception number */ \
sth r1 ,P A C A _ T R A P _ S A V E ( r13 ) ; /* store trap */ \
b b a d _ s t a c k _ b o o k 3 e ; /* bad stack error */
2010-06-08 10:58:58 +10:00
/ * WARNING : If y o u c h a n g e t h e l a y o u t o f t h i s s t u b , m a k e s u r e y o u c h c e k
* the d e b u g e x c e p t i o n h a n d l e r w h i c h h a n d l e s s i n g l e s t e p p i n g
* into e x c e p t i o n s f r o m u s e r s p a c e , a n d t h e M M c o d e i n
* arch/ p o w e r p c / m m / t l b _ n o h a s h . c w h i c h p a t c h e s t h e b r a n c h h e r e
* and w o u l d n e e d t o b e u p d a t e d i f t h a t b r a n c h i s m o v e d
* /
2009-07-23 23:15:59 +00:00
# define E X C E P T I O N _ S T U B ( l o c , l a b e l ) \
. = interrupt_ b a s e _ b o o k 3 e + l o c ; \
nop; /* To make debug interrupts happy */ \
b e x c _ ## l a b e l # # _ b o o k 3 e ;
# define A C K _ N O N E ( r )
# define A C K _ D E C ( r ) \
lis r ,T S R _ D I S @h; \
mtspr S P R N _ T S R ,r
# define A C K _ F I T ( r ) \
lis r ,T S R _ F I S @h; \
mtspr S P R N _ T S R ,r
2010-07-14 14:12:16 +10:00
/ * Used b y a s y n c h r o n o u s i n t e r r u p t t h a t m a y h a p p e n i n t h e i d l e l o o p .
*
* This c h e c k i f t h e t h r e a d w a s i n t h e i d l e l o o p , a n d i f y e s , r e t u r n s
* to t h e c a l l e r r a t h e r t h a n t h e P C . T h i s i s t o a v o i d a r a c e i f
* interrupts h a p p e n b e f o r e t h e w a i t i n s t r u c t i o n .
* /
# define C H E C K _ N A P P I N G ( ) \
clrrdi r11 ,r1 ,T H R E A D _ S H I F T ; \
ld r10 ,T I _ L O C A L _ F L A G S ( r11 ) ; \
andi. r9 ,r10 ,_ T L F _ N A P P I N G ; \
beq+ 1 f ; \
ld r8 ,_ L I N K ( r1 ) ; \
rlwinm r7 ,r10 ,0 ,~ _ T L F _ N A P P I N G ; \
std r8 ,_ N I P ( r1 ) ; \
std r7 ,T I _ L O C A L _ F L A G S ( r11 ) ; \
1 :
2009-07-23 23:15:59 +00:00
# define M A S K A B L E _ E X C E P T I O N ( t r a p n u m , l a b e l , h d l r , a c k ) \
START_ E X C E P T I O N ( l a b e l ) ; \
NORMAL_ E X C E P T I O N _ P R O L O G ( t r a p n u m , P R O L O G _ A D D I T I O N _ M A S K A B L E ) \
EXCEPTION_ C O M M O N ( t r a p n u m , P A C A _ E X G E N , I N T S _ D I S A B L E _ A L L ) \
ack( r8 ) ; \
2010-07-14 14:12:16 +10:00
CHECK_ N A P P I N G ( ) ; \
2009-07-23 23:15:59 +00:00
addi r3 ,r1 ,S T A C K _ F R A M E _ O V E R H E A D ; \
bl h d l r ; \
b . r e t _ f r o m _ e x c e p t _ l i t e ;
/* This value is used to mark exception frames on the stack. */
.section " .toc " , " aw"
exception_marker :
.tc ID_ E X C _ M A R K E R [ T C ] ,S T A C K _ F R A M E _ R E G S _ M A R K E R
/ *
* And h e r e w e h a v e t h e e x c e p t i o n v e c t o r s !
* /
.text
.balign 0x1000
.globl interrupt_base_book3e
interrupt_base_book3e : /* fake trap */
/ * Note : If r e a l d e b u g e x c e p t i o n s a r e s u p p o r t e d b y t h e H W , t h e v e c t o r
* below w i l l h a v e t o b e p a t c h e d u p t o p o i n t t o a n a p p r o p r i a t e h a n d l e r
* /
EXCEPTION_ S T U B ( 0 x00 0 , m a c h i n e _ c h e c k ) / * 0 x02 0 0 * /
EXCEPTION_ S T U B ( 0 x02 0 , c r i t i c a l _ i n p u t ) / * 0 x05 8 0 * /
EXCEPTION_ S T U B ( 0 x04 0 , d e b u g _ c r i t ) / * 0 x0 d00 * /
EXCEPTION_ S T U B ( 0 x06 0 , d a t a _ s t o r a g e ) / * 0 x03 0 0 * /
EXCEPTION_ S T U B ( 0 x08 0 , i n s t r u c t i o n _ s t o r a g e ) / * 0 x04 0 0 * /
EXCEPTION_ S T U B ( 0 x0 a0 , e x t e r n a l _ i n p u t ) / * 0 x05 0 0 * /
EXCEPTION_ S T U B ( 0 x0 c0 , a l i g n m e n t ) / * 0 x06 0 0 * /
EXCEPTION_ S T U B ( 0 x0 e 0 , p r o g r a m ) / * 0 x07 0 0 * /
EXCEPTION_ S T U B ( 0 x10 0 , f p _ u n a v a i l a b l e ) / * 0 x08 0 0 * /
EXCEPTION_ S T U B ( 0 x12 0 , s y s t e m _ c a l l ) / * 0 x0 c00 * /
EXCEPTION_ S T U B ( 0 x14 0 , a p _ u n a v a i l a b l e ) / * 0 x0 f20 * /
EXCEPTION_ S T U B ( 0 x16 0 , d e c r e m e n t e r ) / * 0 x09 0 0 * /
EXCEPTION_ S T U B ( 0 x18 0 , f i x e d _ i n t e r v a l ) / * 0 x09 8 0 * /
EXCEPTION_ S T U B ( 0 x1 a0 , w a t c h d o g ) / * 0 x09 f0 * /
EXCEPTION_ S T U B ( 0 x1 c0 , d a t a _ t l b _ m i s s )
EXCEPTION_ S T U B ( 0 x1 e 0 , i n s t r u c t i o n _ t l b _ m i s s )
2010-07-09 15:31:28 +10:00
EXCEPTION_ S T U B ( 0 x28 0 , d o o r b e l l )
EXCEPTION_ S T U B ( 0 x2 a0 , d o o r b e l l _ c r i t )
2009-07-23 23:15:59 +00:00
.globl interrupt_end_book3e
interrupt_end_book3e :
/* Critical Input Interrupt */
START_ E X C E P T I O N ( c r i t i c a l _ i n p u t ) ;
CRIT_ E X C E P T I O N _ P R O L O G ( 0 x10 0 , P R O L O G _ A D D I T I O N _ N O N E )
/ / EXCEPTION_ C O M M O N ( 0 x10 0 , P A C A _ E X C R I T , I N T S _ D I S A B L E _ A L L )
/ / bl s p e c i a l _ r e g _ s a v e _ c r i t
2010-07-14 14:12:16 +10:00
/ / CHECK_ N A P P I N G ( ) ;
2009-07-23 23:15:59 +00:00
/ / addi r3 ,r1 ,S T A C K _ F R A M E _ O V E R H E A D
/ / bl . c r i t i c a l _ e x c e p t i o n
/ / b r e t _ f r o m _ c r i t _ e x c e p t
b .
/* Machine Check Interrupt */
START_ E X C E P T I O N ( m a c h i n e _ c h e c k ) ;
CRIT_ E X C E P T I O N _ P R O L O G ( 0 x20 0 , P R O L O G _ A D D I T I O N _ N O N E )
/ / EXCEPTION_ C O M M O N ( 0 x20 0 , P A C A _ E X M C , I N T S _ D I S A B L E _ A L L )
/ / bl s p e c i a l _ r e g _ s a v e _ m c
/ / addi r3 ,r1 ,S T A C K _ F R A M E _ O V E R H E A D
2010-07-14 14:12:16 +10:00
/ / CHECK_ N A P P I N G ( ) ;
2009-07-23 23:15:59 +00:00
/ / bl . m a c h i n e _ c h e c k _ e x c e p t i o n
/ / b r e t _ f r o m _ m c _ e x c e p t
b .
/* Data Storage Interrupt */
START_ E X C E P T I O N ( d a t a _ s t o r a g e )
NORMAL_ E X C E P T I O N _ P R O L O G ( 0 x30 0 , P R O L O G _ A D D I T I O N _ 2 R E G S )
mfspr r14 ,S P R N _ D E A R
mfspr r15 ,S P R N _ E S R
EXCEPTION_ C O M M O N ( 0 x30 0 , P A C A _ E X G E N , I N T S _ K E E P )
b s t o r a g e _ f a u l t _ c o m m o n
/* Instruction Storage Interrupt */
START_ E X C E P T I O N ( i n s t r u c t i o n _ s t o r a g e ) ;
NORMAL_ E X C E P T I O N _ P R O L O G ( 0 x40 0 , P R O L O G _ A D D I T I O N _ 2 R E G S )
li r15 ,0
mr r14 ,r10
EXCEPTION_ C O M M O N ( 0 x40 0 , P A C A _ E X G E N , I N T S _ K E E P )
b s t o r a g e _ f a u l t _ c o m m o n
/* External Input Interrupt */
MASKABLE_ E X C E P T I O N ( 0 x50 0 , e x t e r n a l _ i n p u t , . d o _ I R Q , A C K _ N O N E )
/* Alignment */
START_ E X C E P T I O N ( a l i g n m e n t ) ;
NORMAL_ E X C E P T I O N _ P R O L O G ( 0 x60 0 , P R O L O G _ A D D I T I O N _ 2 R E G S )
mfspr r14 ,S P R N _ D E A R
mfspr r15 ,S P R N _ E S R
EXCEPTION_ C O M M O N ( 0 x60 0 , P A C A _ E X G E N , I N T S _ K E E P )
b a l i g n m e n t _ m o r e / * n o r o o m , g o o u t o f l i n e * /
/* Program Interrupt */
START_ E X C E P T I O N ( p r o g r a m ) ;
NORMAL_ E X C E P T I O N _ P R O L O G ( 0 x70 0 , P R O L O G _ A D D I T I O N _ 1 R E G )
mfspr r14 ,S P R N _ E S R
EXCEPTION_ C O M M O N ( 0 x70 0 , P A C A _ E X G E N , I N T S _ D I S A B L E _ S O F T )
std r14 ,_ D S I S R ( r1 )
addi r3 ,r1 ,S T A C K _ F R A M E _ O V E R H E A D
ld r14 ,P A C A _ E X G E N + E X _ R 1 4 ( r13 )
bl . s a v e _ n v g p r s
INTS_ R E S T O R E _ H A R D
bl . p r o g r a m _ c h e c k _ e x c e p t i o n
b . r e t _ f r o m _ e x c e p t
/* Floating Point Unavailable Interrupt */
START_ E X C E P T I O N ( f p _ 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 ( 0 x80 0 , P R O L O G _ A D D I T I O N _ N O N E )
/* we can probably do a shorter exception entry for that one... */
EXCEPTION_ C O M M O N ( 0 x80 0 , P A C A _ E X G E N , I N T S _ K E E P )
bne 1 f / * i f f r o m u s e r , j u s t l o a d i t u p * /
bl . s a v e _ n v g p r s
addi r3 ,r1 ,S T A C K _ F R A M E _ O V E R H E A D
INTS_ R E S T O R E _ H A R D
bl . k e r n e l _ f p _ u n a v a i l a b l e _ e x c e p t i o n
BUG_ O P C O D E
1 : ld r12 ,_ M S R ( r1 )
bl . l o a d _ u p _ f p u
b f a s t _ e x c e p t i o n _ r e t u r n
/* Decrementer Interrupt */
MASKABLE_ E X C E P T I O N ( 0 x90 0 , d e c r e m e n t e r , . t i m e r _ i n t e r r u p t , A C K _ D E C )
/* Fixed Interval Timer Interrupt */
MASKABLE_ E X C E P T I O N ( 0 x98 0 , f i x e d _ i n t e r v a l , . u n k n o w n _ e x c e p t i o n , A C K _ F I T )
/* Watchdog Timer Interrupt */
START_ E X C E P T I O N ( w a t c h d o g ) ;
CRIT_ E X C E P T I O N _ P R O L O G ( 0 x9 f0 , P R O L O G _ A D D I T I O N _ N O N E )
/ / EXCEPTION_ C O M M O N ( 0 x9 f0 , P A C A _ E X C R I T , I N T S _ D I S A B L E _ A L L )
/ / bl s p e c i a l _ r e g _ s a v e _ c r i t
2010-07-14 14:12:16 +10:00
/ / CHECK_ N A P P I N G ( ) ;
2009-07-23 23:15:59 +00:00
/ / addi r3 ,r1 ,S T A C K _ F R A M E _ O V E R H E A D
/ / bl . u n k n o w n _ e x c e p t i o n
/ / b r e t _ f r o m _ c r i t _ e x c e p t
b .
/* System Call Interrupt */
START_ E X C E P T I O N ( s y s t e m _ c a l l )
mr r9 ,r13 / * k e e p a c o p y o f u s e r l a n d r13 * /
mfspr r11 ,S P R N _ S R R 0 / * g e t r e t u r n a d d r e s s * /
mfspr r12 ,S P R N _ S R R 1 / * g e t p r e v i o u s M S R * /
mfspr r13 ,S P R N _ S P R G _ P A C A / * g e t o u r P A C A * /
b s y s t e m _ c a l l _ c o m m o n
2011-03-30 22:57:33 -03:00
/* Auxiliary Processor Unavailable Interrupt */
2009-07-23 23:15:59 +00:00
START_ E X C E P T I O N ( a p _ 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 ( 0 x f20 , P R O L O G _ A D D I T I O N _ N O N E )
EXCEPTION_ C O M M O N ( 0 x f20 , P A C A _ E X G E N , I N T S _ K E E P )
addi r3 ,r1 ,S T A C K _ F R A M E _ O V E R H E A D
bl . s a v e _ n v g p r s
INTS_ R E S T O R E _ H A R D
bl . u n k n o w n _ e x c e p t i o n
b . r e t _ f r o m _ e x c e p t
/* Debug exception as a critical interrupt*/
START_ E X C E P T I O N ( d e b u g _ c r i t ) ;
CRIT_ E X C E P T I O N _ P R O L O G ( 0 x d00 , P R O L O G _ A D D I T I O N _ 2 R E G S )
/ *
* If t h e r e i s a s i n g l e s t e p o r b r a n c h - t a k e n e x c e p t i o n i n a n
* exception e n t r y s e q u e n c e , i t w a s p r o b a b l y m e a n t t o a p p l y t o
* the c o d e w h e r e t h e e x c e p t i o n o c c u r r e d ( s i n c e e x c e p t i o n e n t r y
* doesn' t t u r n o f f D E a u t o m a t i c a l l y ) . W e s i m u l a t e t h e e f f e c t
* of t u r n i n g o f f D E o n e n t r y t o a n e x c e p t i o n h a n d l e r b y t u r n i n g
* off D E i n t h e C S R R 1 v a l u e a n d c l e a r i n g t h e d e b u g s t a t u s .
* /
mfspr r14 ,S P R N _ D B S R / * c h e c k s i n g l e - s t e p / b r a n c h t a k e n * /
andis. r15 ,r14 ,D B S R _ I C @h
beq+ 1 f
LOAD_ R E G _ I M M E D I A T E ( r14 ,i n t e r r u p t _ b a s e _ b o o k 3 e )
LOAD_ R E G _ I M M E D I A T E ( r15 ,i n t e r r u p t _ e n d _ b o o k 3 e )
cmpld c r0 ,r10 ,r14
cmpld c r1 ,r10 ,r15
blt+ c r0 ,1 f
bge+ c r1 ,1 f
/* here it looks like we got an inappropriate debug exception. */
lis r14 ,D B S R _ I C @h /* clear the IC event */
rlwinm r11 ,r11 ,0 ,~ M S R _ D E / * c l e a r D E i n t h e C S R R 1 v a l u e * /
mtspr S P R N _ D B S R ,r14
mtspr S P R N _ C S R R 1 ,r11
lwz r10 ,P A C A _ E X C R I T + E X _ C R ( r13 ) / * r e s t o r e r e g i s t e r s * /
ld r1 ,P A C A _ E X C R I T + E X _ R 1 ( r13 )
ld r14 ,P A C A _ E X C R I T + E X _ R 1 4 ( r13 )
ld r15 ,P A C A _ E X C R I T + E X _ R 1 5 ( r13 )
mtcr r10
ld r10 ,P A C A _ E X C R I T + E X _ R 1 0 ( r13 ) / * r e s t o r e r e g i s t e r s * /
ld r11 ,P A C A _ E X C R I T + E X _ R 1 1 ( r13 )
mfspr r13 ,S P R N _ S P R G _ C R I T _ S C R A T C H
rfci
/* Normal debug exception */
/ * XXX W e o n l y h a n d l e c o m i n g f r o m u s e r s p a c e f o r n o w s i n c e w e c a n ' t
* quite s a v e p r o p e r l y a n i n t e r r u p t e d k e r n e l s t a t e y e t
* /
1 : andi. r14 ,r11 ,M S R _ P R ; /* check for userspace again */
beq k e r n e l _ d b g _ e x c ; /* if from kernel mode */
/ * Now w e m a s h u p t h i n g s t o m a k e i t l o o k l i k e w e a r e c o m i n g o n a
* normal e x c e p t i o n
* /
mfspr r15 ,S P R N _ S P R G _ C R I T _ S C R A T C H
mtspr S P R N _ S P R G _ G E N _ S C R A T C H ,r15
mfspr r14 ,S P R N _ D B S R
EXCEPTION_ C O M M O N ( 0 x d00 , P A C A _ E X C R I T , I N T S _ D I S A B L E _ A L L )
std r14 ,_ D S I S R ( r1 )
addi r3 ,r1 ,S T A C K _ F R A M E _ O V E R H E A D
mr r4 ,r14
ld r14 ,P A C A _ E X C R I T + E X _ R 1 4 ( r13 )
ld r15 ,P A C A _ E X C R I T + E X _ R 1 5 ( r13 )
bl . s a v e _ n v g p r s
bl . D e b u g E x c e p t i o n
b . r e t _ f r o m _ e x c e p t
kernel_dbg_exc :
b . / * N Y I * /
2010-07-09 15:31:28 +10:00
/* Doorbell interrupt */
MASKABLE_ E X C E P T I O N ( 0 x20 7 0 , d o o r b e l l , . d o o r b e l l _ e x c e p t i o n , A C K _ N O N E )
/* Doorbell critical Interrupt */
START_ E X C E P T I O N ( d o o r b e l l _ c r i t ) ;
CRIT_ E X C E P T I O N _ P R O L O G ( 0 x20 8 0 , P R O L O G _ A D D I T I O N _ N O N E )
/ / EXCEPTION_ C O M M O N ( 0 x20 8 0 , P A C A _ E X C R I T , I N T S _ D I S A B L E _ A L L )
/ / bl s p e c i a l _ r e g _ s a v e _ c r i t
2010-07-14 14:12:16 +10:00
/ / CHECK_ N A P P I N G ( ) ;
2010-07-09 15:31:28 +10:00
/ / addi r3 ,r1 ,S T A C K _ F R A M E _ O V E R H E A D
/ / bl . d o o r b e l l _ c r i t i c a l _ e x c e p t i o n
/ / b r e t _ f r o m _ c r i t _ e x c e p t
b .
2009-07-23 23:15:59 +00:00
/ *
* An i n t e r r u p t c a m e i n w h i l e s o f t - d i s a b l e d ; clear EE in SRR1,
* clear p a c a - > h a r d _ e n a b l e d a n d r e t u r n .
* /
masked_interrupt_book3e :
mtcr r10
stb r11 ,P A C A H A R D I R Q E N ( r13 )
mfspr r10 ,S P R N _ S R R 1
rldicl r11 ,r10 ,4 8 ,1 / * c l e a r M S R _ E E * /
rotldi r10 ,r11 ,1 6
mtspr S P R N _ S R R 1 ,r10
ld r10 ,P A C A _ E X G E N + E X _ R 1 0 ( r13 ) ; /* restore registers */
ld r11 ,P A C A _ E X G E N + E X _ R 1 1 ( r13 ) ;
mfspr r13 ,S P R N _ S P R G _ G E N _ S C R A T C H ;
rfi
b .
/ *
* This i s c a l l e d f r o m 0 x30 0 a n d 0 x40 0 h a n d l e r s a f t e r t h e p r o l o g s w i t h
* r1 4 a n d r15 c o n t a i n i n g t h e f a u l t a d d r e s s a n d e r r o r c o d e , w i t h t h e
* original v a l u e s s t a s h e d a w a y i n t h e P A C A
* /
storage_fault_common :
std r14 ,_ D A R ( r1 )
std r15 ,_ D S I S R ( r1 )
addi r3 ,r1 ,S T A C K _ F R A M E _ O V E R H E A D
mr r4 ,r14
mr r5 ,r15
ld r14 ,P A C A _ E X G E N + E X _ R 1 4 ( r13 )
ld r15 ,P A C A _ E X G E N + E X _ R 1 5 ( r13 )
INTS_ R E S T O R E _ H A R D
bl . d o _ p a g e _ f a u l t
cmpdi r3 ,0
bne- 1 f
b . r e t _ f r o m _ e x c e p t _ l i t e
1 : bl . s a v e _ n v g p r s
mr r5 ,r3
addi r3 ,r1 ,S T A C K _ F R A M E _ O V E R H E A D
ld r4 ,_ D A R ( r1 )
bl . b a d _ p a g e _ f a u l t
b . r e t _ f r o m _ e x c e p t
/ *
* Alignment e x c e p t i o n d o e s n ' t f i t e n t i r e l y i n t h e 0 x10 0 b y t e s s o i t
* continues h e r e .
* /
alignment_more :
std r14 ,_ D A R ( r1 )
std r15 ,_ D S I S R ( r1 )
addi r3 ,r1 ,S T A C K _ F R A M E _ O V E R H E A D
ld r14 ,P A C A _ E X G E N + E X _ R 1 4 ( r13 )
ld r15 ,P A C A _ E X G E N + E X _ R 1 5 ( r13 )
bl . s a v e _ n v g p r s
INTS_ R E S T O R E _ H A R D
bl . a l i g n m e n t _ e x c e p t i o n
b . r e t _ f r o m _ e x c e p t
/ *
* We b r a n c h h e r e f r o m e n t r y _ 6 4 . S f o r t h e l a s t s t a g e o f t h e e x c e p t i o n
* return c o d e p a t h . M S R : E E i s e x p e c t e d t o b e o f f a t t h a t p o i n t
* /
_ GLOBAL( e x c e p t i o n _ r e t u r n _ b o o k 3 e )
b 1 f
/ * This i s t h e r e t u r n f r o m l o a d _ u p _ f p u f a s t p a t h w h i c h c o u l d d o w i t h
* less G P R r e s t o r e s i n f a c t , b u t f o r n o w w e h a v e a s i n g l e r e t u r n p a t h
* /
.globl fast_exception_return
fast_exception_return :
wrteei 0
1 : mr r0 ,r13
ld r10 ,_ M S R ( r1 )
REST_ 4 G P R S ( 2 , r1 )
andi. r6 ,r10 ,M S R _ P R
REST_ 2 G P R S ( 6 , r1 )
beq 1 f
ACCOUNT_ C P U _ U S E R _ E X I T ( r10 , r11 )
ld r0 ,G P R 1 3 ( r1 )
1 : stdcx. r0 ,0 ,r1 / * t o c l e a r t h e r e s e r v a t i o n * /
ld r8 ,_ C C R ( r1 )
ld r9 ,_ L I N K ( r1 )
ld r10 ,_ C T R ( r1 )
ld r11 ,_ X E R ( r1 )
mtcr r8
mtlr r9
mtctr r10
mtxer r11
REST_ 2 G P R S ( 8 , r1 )
ld r10 ,G P R 1 0 ( r1 )
ld r11 ,G P R 1 1 ( r1 )
ld r12 ,G P R 1 2 ( r1 )
mtspr S P R N _ S P R G _ G E N _ S C R A T C H ,r0
std r10 ,P A C A _ E X G E N + E X _ R 1 0 ( r13 ) ;
std r11 ,P A C A _ E X G E N + E X _ R 1 1 ( r13 ) ;
ld r10 ,_ N I P ( r1 )
ld r11 ,_ M S R ( r1 )
ld r0 ,G P R 0 ( r1 )
ld r1 ,G P R 1 ( r1 )
mtspr S P R N _ S R R 0 ,r10
mtspr S P R N _ S R R 1 ,r11
ld r10 ,P A C A _ E X G E N + E X _ R 1 0 ( r13 )
ld r11 ,P A C A _ E X G E N + E X _ R 1 1 ( r13 )
mfspr r13 ,S P R N _ S P R G _ G E N _ S C R A T C H
rfi
/ *
* Trampolines u s e d w h e n s p o t t i n g a b a d k e r n e l s t a c k p o i n t e r i n
* the e x c e p t i o n e n t r y c o d e .
*
* TODO : move s o m e b i t s l i k e S R R 0 r e a d t o t r a m p o l i n e , p a s s P A C A
* index a r o u n d , e t c . . . t o h a n d l e c r i t & m c h e c k
* /
BAD_ S T A C K _ T R A M P O L I N E ( 0 x00 0 )
BAD_ S T A C K _ T R A M P O L I N E ( 0 x10 0 )
BAD_ S T A C K _ T R A M P O L I N E ( 0 x20 0 )
BAD_ S T A C K _ T R A M P O L I N E ( 0 x30 0 )
BAD_ S T A C K _ T R A M P O L I N E ( 0 x40 0 )
BAD_ S T A C K _ T R A M P O L I N E ( 0 x50 0 )
BAD_ S T A C K _ T R A M P O L I N E ( 0 x60 0 )
BAD_ S T A C K _ T R A M P O L I N E ( 0 x70 0 )
BAD_ S T A C K _ T R A M P O L I N E ( 0 x80 0 )
BAD_ S T A C K _ T R A M P O L I N E ( 0 x90 0 )
BAD_ S T A C K _ T R A M P O L I N E ( 0 x98 0 )
BAD_ S T A C K _ T R A M P O L I N E ( 0 x9 f0 )
BAD_ S T A C K _ T R A M P O L I N E ( 0 x a00 )
BAD_ S T A C K _ T R A M P O L I N E ( 0 x b00 )
BAD_ S T A C K _ T R A M P O L I N E ( 0 x c00 )
BAD_ S T A C K _ T R A M P O L I N E ( 0 x d00 )
BAD_ S T A C K _ T R A M P O L I N E ( 0 x e 0 0 )
BAD_ S T A C K _ T R A M P O L I N E ( 0 x f00 )
BAD_ S T A C K _ T R A M P O L I N E ( 0 x f20 )
2010-07-09 15:31:28 +10:00
BAD_ S T A C K _ T R A M P O L I N E ( 0 x20 7 0 )
BAD_ S T A C K _ T R A M P O L I N E ( 0 x20 8 0 )
2009-07-23 23:15:59 +00:00
.globl bad_stack_book3e
bad_stack_book3e :
/* XXX: Needs to make SPRN_SPRG_GEN depend on exception type */
mfspr r10 ,S P R N _ S R R 0 ; /* read SRR0 before touching stack */
ld r1 ,P A C A E M E R G S P ( r13 )
subi r1 ,r1 ,6 4 + I N T _ F R A M E _ S I Z E
std r10 ,_ N I P ( r1 )
std r11 ,_ M S R ( r1 )
ld r10 ,P A C A _ E X G E N + E X _ R 1 ( r13 ) / * F I X M E f o r c r i t & m c h e c k * /
lwz r11 ,P A C A _ E X G E N + E X _ C R ( r13 ) / * F I X M E f o r c r i t & m c h e c k * /
std r10 ,G P R 1 ( r1 )
std r11 ,_ C C R ( r1 )
mfspr r10 ,S P R N _ D E A R
mfspr r11 ,S P R N _ E S R
std r10 ,_ D A R ( r1 )
std r11 ,_ D S I S R ( r1 )
std r0 ,G P R 0 ( r1 ) ; /* save r0 in stackframe */ \
std r2 ,G P R 2 ( r1 ) ; /* save r2 in stackframe */ \
SAVE_ 4 G P R S ( 3 , r1 ) ; /* save r3 - r6 in stackframe */ \
SAVE_ 2 G P R S ( 7 , r1 ) ; /* save r7, r8 in stackframe */ \
std r9 ,G P R 9 ( r1 ) ; /* save r9 in stackframe */ \
ld r3 ,P A C A _ E X G E N + E X _ R 1 0 ( r13 ) ;/* get back r10 */ \
ld r4 ,P A C A _ E X G E N + E X _ R 1 1 ( r13 ) ;/* get back r11 */ \
mfspr r5 ,S P R N _ S P R G _ G E N _ S C R A T C H ;/* get back r13 XXX can be wrong */ \
std r3 ,G P R 1 0 ( r1 ) ; /* save r10 to stackframe */ \
std r4 ,G P R 1 1 ( r1 ) ; /* save r11 to stackframe */ \
std r12 ,G P R 1 2 ( r1 ) ; /* save r12 in stackframe */ \
std r5 ,G P R 1 3 ( r1 ) ; /* save it to stackframe */ \
mflr r10
mfctr r11
mfxer r12
std r10 ,_ L I N K ( r1 )
std r11 ,_ C T R ( r1 )
std r12 ,_ X E R ( r1 )
SAVE_ 1 0 G P R S ( 1 4 ,r1 )
SAVE_ 8 G P R S ( 2 4 ,r1 )
lhz r12 ,P A C A _ T R A P _ S A V E ( r13 )
std r12 ,_ T R A P ( r1 )
addi r11 ,r1 ,I N T _ F R A M E _ S I Z E
std r11 ,0 ( r1 )
li r12 ,0
std r12 ,0 ( r11 )
ld r2 ,P A C A T O C ( r13 )
1 : addi r3 ,r1 ,S T A C K _ F R A M E _ O V E R H E A D
bl . k e r n e l _ b a d _ s t a c k
b 1 b
/ *
* Setup t h e i n i t i a l T L B f o r a c o r e . T h i s c u r r e n t i m p l e m e n t a t i o n
* assume t h a t w h a t e v e r w e a r e r u n n i n g o f f w i l l n o t c o n f l i c t w i t h
* the n e w m a p p i n g a t P A G E _ O F F S E T .
* /
_ GLOBAL( i n i t i a l _ t l b _ b o o k 3 e )
2009-08-18 19:08:33 +00:00
/* Look for the first TLB with IPROT set */
mfspr r4 ,S P R N _ T L B 0 C F G
andi. r3 ,r4 ,T L B n C F G _ I P R O T
lis r3 ,M A S 0 _ T L B S E L ( 0 ) @h
bne f o u n d _ i p r o t
mfspr r4 ,S P R N _ T L B 1 C F G
andi. r3 ,r4 ,T L B n C F G _ I P R O T
lis r3 ,M A S 0 _ T L B S E L ( 1 ) @h
bne f o u n d _ i p r o t
mfspr r4 ,S P R N _ T L B 2 C F G
andi. r3 ,r4 ,T L B n C F G _ I P R O T
lis r3 ,M A S 0 _ T L B S E L ( 2 ) @h
bne f o u n d _ i p r o t
lis r3 ,M A S 0 _ T L B S E L ( 3 ) @h
mfspr r4 ,S P R N _ T L B 3 C F G
/* fall through */
found_iprot :
andi. r5 ,r4 ,T L B n C F G _ H E S
bne h a v e _ h e s
mflr r8 / * s a v e L R * /
/ * 1 . Find t h e i n d e x o f t h e e n t r y w e ' r e e x e c u t i n g i n
*
* r3 = M A S 0 _ T L B S E L ( f o r t h e i p r o t a r r a y )
* r4 = S P R N _ T L B n C F G
* /
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 r5 ,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
slwi r7 ,r7 ,1 6
or r7 ,r7 ,r5
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 =PID * /
mfspr r3 ,S P R N _ M A S 0
rlwinm r5 ,r3 ,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 a l l e n t r i e s e x c e p t t h e e n t r y w e ' r e e x e c u t i n g i n
*
* r3 = M A S 0 w / T L B S E L & E S E L f o r t h e e n t r y w e a r e r u n n i n g i n
* r4 = S P R N _ T L B n C F G
* r5 = E S E L o f e n t r y w e a r e r u n n i n g i n
* /
andi. r4 ,r4 ,T L B n C F G _ N _ E N T R Y / * E x t r a c t # e n t r i e s * /
li r6 ,0 / * S e t E n t r y c o u n t e r t o 0 * /
1 : mr r7 ,r3 / * S e t M A S 0 ( T L B S E L ) * /
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 r5 ,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 ,r4 / * A r e w e d o n e ? * /
bne 1 b / * I f n o t , r e p e a t * /
/* Invalidate all TLBs */
PPC_ T L B I L X _ A L L ( 0 ,0 )
sync
isync
/ * 3 . Setup a t e m p m a p p i n g a n d j u m p t o i t
*
* r3 = M A S 0 w / T L B S E L & E S E L f o r t h e e n t r y w e a r e r u n n i n g i n
* r5 = E S E L o f e n t r y w e a r e r u n n i n g i n
* /
andi. r7 ,r5 ,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 r7 ,r7 ,0 x1
mr r4 ,r3 / * S e t M A S 0 ( T L B S E L ) = 1 * /
mtspr S P R N _ M A S 0 ,r4
tlbre
rlwimi r4 ,r7 ,1 6 ,4 ,1 5 / * S e t u p M A S 0 = T L B S E L | E S E L ( r7 ) * /
mtspr S P R N _ M A S 0 ,r4
mfspr r7 ,S P R N _ M A S 1
xori r6 ,r7 ,M A S 1 _ T S / * 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 * /
mtspr S P R N _ M A S 1 ,r6
tlbwe
mfmsr r6
xori r6 ,r6 ,M S R _ I S
mtspr S P R N _ S R R 1 ,r6
bl 1 f / * F i n d o u r a d d r e s s * /
1 : mflr r6
addi r6 ,r6 ,( 2 f - 1 b )
mtspr S P R N _ S R R 0 ,r6
rfi
2 :
/ * 4 . Clear o u t P I D s & S e a r c h i n f o
*
* r3 = M A S 0 w / T L B S E L & E S E L f o r t h e e n t r y w e s t a r t e d i n
* r4 = M A S 0 w / T L B S E L & E S E L f o r t h e t e m p m a p p i n g
* r5 = M A S 3
* /
li r6 ,0
mtspr S P R N _ M A S 6 ,r6
mtspr S P R N _ P I D ,r6
/ * 5 . Invalidate m a p p i n g w e s t a r t e d i n
*
* r3 = M A S 0 w / T L B S E L & E S E L f o r t h e e n t r y w e s t a r t e d i n
* r4 = M A S 0 w / T L B S E L & E S E L f o r t h e t e m p m a p p i n g
* r5 = M A S 3
* /
mtspr S P R N _ M A S 0 ,r3
tlbre
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 * /
mtspr S P R N _ M A S 1 ,r6
tlbwe
/* Invalidate TLB1 */
PPC_ T L B I L X _ A L L ( 0 ,0 )
sync
isync
/* 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
/ * 6 . Setup K E R N E L B A S E m a p p i n g i n T L B [ 0 ]
*
* r3 = M A S 0 w / T L B S E L & E S E L f o r t h e e n t r y w e s t a r t e d i n
* r4 = M A S 0 w / T L B S E L & E S E L f o r t h e t e m p m a p p i n g
* r5 = M A S 3
* /
rlwinm r3 ,r3 ,0 ,1 6 ,3 / * c l e a r E S E L * /
mtspr S P R N _ M A S 0 ,r3
lis 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 3 E _ P A G E S Z _ 1 G B ) ) @l
mtspr S P R N _ M A S 1 ,r6
LOAD_ R E G _ I M M E D I A T E ( r6 , P A G E _ O F F S E T | M _ I F _ S M P )
mtspr S P R N _ M A S 2 ,r6
rlwinm r5 ,r5 ,0 ,0 ,2 5
ori r5 ,r5 ,M A S 3 _ S R | M A S 3 _ S W | M A S 3 _ S X
mtspr S P R N _ M A S 3 ,r5
li r5 ,- 1
rlwinm r5 ,r5 ,0 ,0 ,2 5
tlbwe
/ * 7 . Jump t o K E R N E L B A S E m a p p i n g
*
* r4 = M A S 0 w / T L B S E L & E S E L f o r t h e t e m p m a p p i n g
* /
/* Now we branch the new virtual address mapped by this entry */
LOAD_ R E G _ I M M E D I A T E ( r6 ,2 f )
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
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 * /
2 :
/ * 8 . Clear o u t t h e t e m p m a p p i n g
*
* r4 = M A S 0 w / T L B S E L & E S E L f o r t h e e n t r y w e a r e r u n n i n g i n
* /
mtspr S P R N _ M A S 0 ,r4
tlbre
mfspr r5 ,S P R N _ M A S 1
rlwinm r5 ,r5 ,0 ,2 ,0 / * c l e a r I P R O T * /
mtspr S P R N _ M A S 1 ,r5
tlbwe
/* Invalidate TLB1 */
PPC_ T L B I L X _ A L L ( 0 ,0 )
sync
isync
/* We translate LR and return */
tovirt( r8 ,r8 )
mtlr r8
blr
have_hes :
2009-07-23 23:15:59 +00:00
/ * Setup M A S 0 ,1 ,2 ,3 a n d 7 f o r t l b w e o f a 1 G e n t r y t h a t m a p s t h e
* kernel l i n e a r m a p p i n g . W e a l s o s e t M A S 8 o n c e f o r a l l h e r e t h o u g h
* that w i l l h a v e t o b e m a d e d e p e n d e n t o n w h e t h e r w e a r e r u n n i n g u n d e r
* a h y p e r v i s o r I s u p p o s e .
* /
2009-08-18 19:08:33 +00:00
ori r3 ,r3 ,M A S 0 _ H E S | M A S 0 _ W Q _ A L L W A Y S
2009-07-23 23:15:59 +00:00
mtspr S P R N _ M A S 0 ,r3
lis r3 ,( M A S 1 _ V A L I D | M A S 1 _ I P R O T ) @h
ori r3 ,r3 ,B O O K 3 E _ P A G E S Z _ 1 G B < < M A S 1 _ T S I Z E _ S H I F T
mtspr S P R N _ M A S 1 ,r3
LOAD_ R E G _ I M M E D I A T E ( r3 , P A G E _ O F F S E T | M A S 2 _ M )
mtspr S P R N _ M A S 2 ,r3
li r3 ,M A S 3 _ S R | M A S 3 _ S W | M A S 3 _ S X
mtspr S P R N _ M A S 7 _ M A S 3 ,r3
li r3 ,0
mtspr S P R N _ M A S 8 ,r3
/* Write the TLB entry */
tlbwe
/* Now we branch the new virtual address mapped by this entry */
LOAD_ R E G _ I M M E D I A T E ( r3 ,1 f )
mtctr r3
bctr
1 : / * We a r e n o w r u n n i n g a t P A G E _ O F F S E T , c l e a n t h e T L B o f e v e r y t h i n g
* else ( X X X w e s h o u l d s c a n f o r b o l t e d c r a p f r o m t h e f i r m w a r e t o o )
* /
PPC_ T L B I L X ( 0 ,0 ,0 )
sync
isync
/* We translate LR and return */
mflr r3
tovirt( r3 ,r3 )
mtlr r3
blr
/ *
* Main e n t r y ( b o o t C P U , t h r e a d 0 )
*
* We e n t e r h e r e f r o m h e a d _ 6 4 . S , p o s s i b l y a f t e r t h e p r o m _ i n i t t r a m p o l i n e
* with r3 a n d r4 a l r e a d y s a v e d t o r31 a n d 3 0 r e s p e c t i v e l y a n d i n 6 4 b i t s
* mode. A n y t h i n g e l s e i s a s i t w a s l e f t b y t h e b o o t l o a d e r
*
* Initial r e q u i r e m e n t s o f t h i s p o r t :
*
* - Kernel l o a d e d a t 0 p h y s i c a l
* - A g o o d l u m p o f m e m o r y m a p p e d 0 : 0 b y U T L B e n t r y 0
* - MSR : IS & M S R : D S s e t t o 0
*
* Note t h a t s o m e o f t h e a b o v e r e q u i r e m e n t s w i l l b e r e l a x e d i n t h e f u t u r e
* as t h e k e r n e l b e c o m e s s m a r t e r a t d e a l i n g w i t h d i f f e r e n t i n i t i a l c o n d i t i o n s
* but f o r n o w y o u h a v e t o b e c a r e f u l
* /
_ GLOBAL( s t a r t _ i n i t i a l i z a t i o n _ b o o k 3 e )
mflr r28
/ * First, w e n e e d t o s e t u p s o m e i n i t i a l T L B s t o m a p t h e k e r n e l
* text, d a t a a n d b s s a t P A G E _ O F F S E T . W e d o n ' t h a v e a r e a l m o d e
* and a l w a y s u s e A S 0 , s o w e j u s t s e t i t u p t o m a t c h o u r l i n k
* address a n d n e v e r u s e 0 b a s e d a d d r e s s e s .
* /
bl . i n i t i a l _ t l b _ b o o k 3 e
/* Init global core bits */
bl . i n i t _ c o r e _ b o o k 3 e
/* Init per-thread bits */
bl . i n i t _ t h r e a d _ b o o k 3 e
/* Return to common init code */
tovirt( r28 ,r28 )
mtlr r28
blr
/ *
* Secondary c o r e / p r o c e s s o r e n t r y
*
* This i s e n t e r e d f o r t h r e a d 0 o f a s e c o n d a r y c o r e , a l l o t h e r t h r e a d s
* are e x p e c t e d t o b e s t o p p e d . I t ' s s i m i l a r t o s t a r t _ i n i t i a l i z a t i o n _ b o o k 3 e
* except t h a t i t ' s g e n e r a l l y e n t e r e d f r o m t h e h o l d i n g l o o p i n h e a d _ 6 4 . S
* after C P U s h a v e b e e n g a t h e r e d b y O p e n F i r m w a r e .
*
* We a s s u m e w e a r e i n 3 2 b i t s m o d e r u n n i n g w i t h w h a t e v e r T L B e n t r y w a s
* set f o r u s b y t h e f i r m w a r e o r P O R e n g i n e .
* /
_ GLOBAL( b o o k 3 e _ s e c o n d a r y _ c o r e _ i n i t _ t l b _ s e t )
li r4 ,1
b . g e n e r i c _ s e c o n d a r y _ s m p _ i n i t
_ GLOBAL( b o o k 3 e _ s e c o n d a r y _ c o r e _ i n i t )
mflr r28
/* Do we need to setup initial TLB entry ? */
cmplwi r4 ,0
bne 2 f
/* Setup TLB for this core */
bl . i n i t i a l _ t l b _ b o o k 3 e
/ * We c a n r e t u r n f r o m t h e a b o v e r u n n i n g a t a d i f f e r e n t
* address, s o r e c a l c u l a t e r2 ( T O C )
* /
bl . r e l a t i v e _ t o c
/* Init global core bits */
2 : bl . i n i t _ c o r e _ b o o k 3 e
/* Init per-thread bits */
3 : bl . i n i t _ t h r e a d _ b o o k 3 e
/ * Return t o c o m m o n i n i t c o d e a t p r o p e r v i r t u a l a d d r e s s .
*
* Due t o v a r i o u s p r e v i o u s a s s u m p t i o n s , w e k n o w w e e n t e r e d t h i s
* function a t e i t h e r t h e f i n a l P A G E _ O F F S E T m a p p i n g o r u s i n g a
* 1 : 1 mapping a t 0 , s o w e d o n ' t b o t h e r d o i n g a c o m p l i c a t e d c h e c k
* here, w e j u s t e n s u r e t h e r e t u r n a d d r e s s h a s t h e r i g h t t o p b i t s .
*
* Note t h a t i f w e e v e r w a n t t o b e s m a r t e r a b o u t w h e r e w e c a n b e
* started f r o m , w e h a v e t o b e c a r e f u l t h a t b y t h e t i m e w e r e a c h
* the c o d e b e l o w w e m a y a l r e a d y b e r u n n i n g a t a d i f f e r e n t l o c a t i o n
* than t h e o n e w e w e r e c a l l e d f r o m s i n c e i n i t i a l _ t l b _ b o o k 3 e c a n
* have m o v e d u s a l r e a d y .
* /
cmpdi c r0 ,r28 ,0
blt 1 f
lis r3 ,P A G E _ O F F S E T @highest
sldi r3 ,r3 ,3 2
or r28 ,r28 ,r3
1 : mtlr r28
blr
_ GLOBAL( b o o k 3 e _ s e c o n d a r y _ t h r e a d _ i n i t )
mflr r28
b 3 b
_ STATIC( i n i t _ c o r e _ b o o k 3 e )
/* Establish the interrupt vector base */
LOAD_ R E G _ I M M E D I A T E ( r3 , i n t e r r u p t _ b a s e _ b o o k 3 e )
mtspr S P R N _ I V P R ,r3
sync
blr
_ STATIC( i n i t _ t h r e a d _ b o o k 3 e )
lis r3 ,( S P R N _ E P C R _ I C M | S P R N _ E P C R _ G I C M ) @h
mtspr S P R N _ E P C R ,r3
/* Make sure interrupts are off */
wrteei 0
2009-08-18 19:08:31 +00:00
/* disable all timers and clear out status */
li r3 ,0
2009-07-23 23:15:59 +00:00
mtspr S P R N _ T C R ,r3
2009-08-18 19:08:31 +00:00
mfspr r3 ,S P R N _ T S R
mtspr S P R N _ T S R ,r3
2009-07-23 23:15:59 +00:00
blr
2009-08-18 19:08:32 +00:00
_ GLOBAL( _ _ s e t u p _ b a s e _ i v o r s )
SET_ I V O R ( 0 , 0 x02 0 ) / * C r i t i c a l I n p u t * /
SET_ I V O R ( 1 , 0 x00 0 ) / * M a c h i n e C h e c k * /
SET_ I V O R ( 2 , 0 x06 0 ) / * D a t a S t o r a g e * /
SET_ I V O R ( 3 , 0 x08 0 ) / * I n s t r u c t i o n S t o r a g e * /
SET_ I V O R ( 4 , 0 x0 a0 ) / * E x t e r n a l I n p u t * /
SET_ I V O R ( 5 , 0 x0 c0 ) / * A l i g n m e n t * /
SET_ I V O R ( 6 , 0 x0 e 0 ) / * P r o g r a m * /
SET_ I V O R ( 7 , 0 x10 0 ) / * F P U n a v a i l a b l e * /
SET_ I V O R ( 8 , 0 x12 0 ) / * S y s t e m C a l l * /
SET_ I V O R ( 9 , 0 x14 0 ) / * A u x i l i 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 , 0 x16 0 ) / * D e c r e m e n t e r * /
SET_ I V O R ( 1 1 , 0 x18 0 ) / * 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 , 0 x1 a0 ) / * W a t c h d o g T i m e r * /
SET_ I V O R ( 1 3 , 0 x1 c0 ) / * D a t a T L B E r r o r * /
SET_ I V O R ( 1 4 , 0 x1 e 0 ) / * I n s t r u c t i o n T L B E r r o r * /
SET_ I V O R ( 1 5 , 0 x04 0 ) / * D e b u g * /
2009-07-23 23:15:59 +00:00
2009-08-18 19:08:32 +00:00
sync
2009-07-23 23:15:59 +00:00
2009-08-18 19:08:32 +00:00
blr