2009-03-27 16:25:13 +03:00
/ *
* Exception h a n d l i n g f o r M i c r o b l a z e
*
* Rewriten i n t e r r u p t h a n d l i n g
*
* Copyright ( C ) 2 0 0 8 - 2 0 0 9 M i c h a l S i m e k < m o n s t r @monstr.eu>
* Copyright ( C ) 2 0 0 8 - 2 0 0 9 P e t a L o g i x
*
* uClinux c u s t o m i s a t i o n ( C ) 2 0 0 5 J o h n W i l l i a m s
*
* MMU c o d e d e r i v e d f r o m a r c h / p p c / k e r n e l / h e a d _ 4 x x . S :
* Copyright ( C ) 1 9 9 5 - 1 9 9 6 G a r y T h o m a s < g d t @linuxppc.org>
* Initial P o w e r P C v e r s i o n .
* Copyright ( C ) 1 9 9 6 C o r t D o u g a n < c o r t @cs.nmt.edu>
* Rewritten f o r P R e P
* 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>
* 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 .
* Copyright ( C ) 1 9 9 7 D a n M a l e k < d m a l e k @jlc.net>
* PowerPC 8 x x m o d i f i c a t i o n s .
* Copyright ( C ) 1 9 9 8 - 1 9 9 9 T i V o , I n c .
* PowerPC 4 0 3 G C X m o d i f i c a t i o n s .
* 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>
* 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 .
* 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
* 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
*
* Original c o d e
* Copyright ( C ) 2 0 0 4 X i l i n x , I n c .
*
* 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 v e r s i o n 2 a s p u b l i s h e d
* by 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 .
* /
/ *
* Here a r e t h e h a n d l e r s w h i c h d o n ' t r e q u i r e e n a b l i n g t r a n s l a t i o n
* and c a l l i n g o t h e r k e r n e l c o d e t h u s w e c a n k e e p t h e i r d e s i g n v e r y s i m p l e
* and d o a l l p r o c e s s i n g i n r e a l m o d e . A l l w h a t t h e y n e e d i s a v a l i d c u r r e n t
* ( that i s a n i s s u e f o r t h e C O N F I G _ R E G I S T E R _ T A S K _ P T R c a s e )
* This h a n d l e r s u s e r3 ,r4 ,r5 ,r6 a n d o p t i o n a l l y r [ c u r r e n t ] t o w o r k t h e r e f o r e
* these r e g i s t e r s a r e s a v e d / r e s t o r e d
* The h a n d l e r s w h i c h r e q u i r e t r a n s l a t i o n a r e i n e n t r y . S - - K A A
*
* Microblaze H W E x c e p t i o n H a n d l e r
* - Non s e l f - m o d i f y i n g e x c e p t i o n h a n d l e r f o r t h e f o l l o w i n g e x c e p t i o n c o n d i t i o n s
* - Unalignment
* - Instruction b u s e r r o r
* - Data b u s e r r o r
* - Illegal i n s t r u c t i o n o p c o d e
* - Divide- b y - z e r o
*
2009-05-26 18:30:22 +04:00
* - Privileged i n s t r u c t i o n e x c e p t i o n ( M M U )
* - Data s t o r a g e e x c e p t i o n ( M M U )
* - Instruction s t o r a g e e x c e p t i o n ( M M U )
* - Data T L B m i s s e x c e p t i o n ( M M U )
* - Instruction T L B m i s s e x c e p t i o n ( M M U )
*
2009-03-27 16:25:13 +03:00
* Note w e d i s a b l e i n t e r r u p t s d u r i n g e x c e p t i o n h a n d l i n g , o t h e r w i s e w e w i l l
* possibly g e t m u l t i p l e r e - e n t r a n c y i f i n t e r r u p t h a n d l e s t h e m s e l v e s c a u s e
* exceptions. J W
* /
# include < a s m / e x c e p t i o n s . h >
# include < a s m / u n i s t d . h >
# include < a s m / p a g e . h >
# include < a s m / e n t r y . h >
# include < a s m / c u r r e n t . h >
# include < l i n u x / l i n k a g e . h >
# include < a s m / m m u . h >
# include < a s m / p g t a b l e . h >
2009-07-21 14:48:01 +04:00
# include < a s m / s i g n a l . h >
2009-03-27 16:25:13 +03:00
# include < a s m / a s m - o f f s e t s . h >
/* Helpful Macros */
# define N U M _ T O _ R E G ( n u m ) r ## n u m
2009-05-26 18:30:22 +04:00
# ifdef C O N F I G _ M M U
# define R E S T O R E _ S T A T E \
2009-09-17 19:37:33 +04:00
lwi r5 , r1 , 0 ; \
mts r m s r , r5 ; \
nop; \
2009-05-26 18:30:22 +04:00
lwi r3 , r1 , P T _ R 3 ; \
lwi r4 , r1 , P T _ R 4 ; \
lwi r5 , r1 , P T _ R 5 ; \
lwi r6 , r1 , P T _ R 6 ; \
lwi r11 , r1 , P T _ R 1 1 ; \
lwi r31 , r1 , P T _ R 3 1 ; \
lwi r1 , r0 , T O P H Y S ( r0 _ r a m + 0 ) ;
# endif / * C O N F I G _ M M U * /
2009-03-27 16:25:13 +03:00
# define L W R E G _ N O P \
bri e x _ h a n d l e r _ u n h a n d l e d ; \
nop;
# define S W R E G _ N O P \
bri e x _ h a n d l e r _ u n h a n d l e d ; \
nop;
/ * FIXME t h i s i s w e i r d - f o r n o M M U k e r n e l i s n o t p o s s i b l e t o u s e b r i d
* instruction w h i c h c a n s h o r t e n e x e c u t e d t i m e
* /
/* r3 is the source */
# define R 3 _ T O _ L W R E G _ V ( r e g n u m ) \
swi r3 , r1 , 4 * r e g n u m ; \
bri e x _ h a n d l e r _ d o n e ;
/* r3 is the source */
# define R 3 _ T O _ L W R E G ( r e g n u m ) \
or N U M _ T O _ R E G ( r e g n u m ) , r0 , r3 ; \
bri e x _ h a n d l e r _ d o n e ;
/* r3 is the target */
# define S W R E G _ T O _ R 3 _ V ( r e g n u m ) \
lwi r3 , r1 , 4 * r e g n u m ; \
bri e x _ s w _ t a i l ;
/* r3 is the target */
# define S W R E G _ T O _ R 3 ( r e g n u m ) \
or r3 , r0 , N U M _ T O _ R E G ( r e g n u m ) ; \
bri e x _ s w _ t a i l ;
2009-05-26 18:30:22 +04:00
# ifdef C O N F I G _ M M U
# define R 3 _ T O _ L W R E G _ V M _ V ( r e g n u m ) \
brid e x _ l w _ e n d _ v m ; \
swi r3 , r7 , 4 * r e g n u m ;
# define R 3 _ T O _ L W R E G _ V M ( r e g n u m ) \
brid e x _ l w _ e n d _ v m ; \
or N U M _ T O _ R E G ( r e g n u m ) , r0 , r3 ;
# define S W R E G _ T O _ R 3 _ V M _ V ( r e g n u m ) \
brid e x _ s w _ t a i l _ v m ; \
lwi r3 , r7 , 4 * r e g n u m ;
# define S W R E G _ T O _ R 3 _ V M ( r e g n u m ) \
brid e x _ s w _ t a i l _ v m ; \
or r3 , r0 , N U M _ T O _ R E G ( r e g n u m ) ;
/* Shift right instruction depending on available configuration */
# if C O N F I G _ X I L I N X _ M I C R O B L A Z E 0 _ U S E _ B A R R E L > 0
# define B S R L I ( r D , r A , i m m ) \
bsrli r D , r A , i m m
# elif C O N F I G _ X I L I N X _ M I C R O B L A Z E 0 _ U S E _ D I V > 0
# define B S R L I ( r D , r A , i m m ) \
ori r D , r0 , ( 1 < < i m m ) ; \
idivu r D , r D , r A
# else
# define B S R L I ( r D , r A , i m m ) B S R L I ## i m m ( r D , r A )
/* Only the used shift constants defined here - add more if needed */
# define B S R L I 2 ( r D , r A ) \
srl r D , r A ; /* << 1 */ \
srl r D , r D ; /* << 2 */
# define B S R L I 1 0 ( r D , r A ) \
srl r D , r A ; /* << 1 */ \
srl r D , r D ; /* << 2 */ \
srl r D , r D ; /* << 3 */ \
srl r D , r D ; /* << 4 */ \
srl r D , r D ; /* << 5 */ \
srl r D , r D ; /* << 6 */ \
srl r D , r D ; /* << 7 */ \
srl r D , r D ; /* << 8 */ \
srl r D , r D ; /* << 9 */ \
srl r D , r D / * < < 1 0 * /
# define B S R L I 2 0 ( r D , r A ) \
BSRLI1 0 ( r D , r A ) ; \
BSRLI1 0 ( r D , r D )
# endif
# endif / * C O N F I G _ M M U * /
2009-03-27 16:25:13 +03:00
.extern other_exception_handler /* Defined in exception.c */
/ *
* hw_ e x c e p t i o n _ h a n d l e r - H a n d l e r f o r e x c e p t i o n s
*
* Exception h a n d l e r n o t e s :
* - Handles a l l e x c e p t i o n s
* - Does n o t h a n d l e u n a l i g n e d e x c e p t i o n s d u r i n g l o a d i n t o r17 , r1 , r0 .
* - Does n o t h a n d l e u n a l i g n e d e x c e p t i o n s d u r i n g s t o r e f r o m r17 ( c a n n o t b e
* done) a n d r1 ( s l o w s d o w n c o m m o n c a s e )
*
* Relevant r e g i s t e r s t r u c t u r e s
*
* EAR - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - |
* - < # # 3 2 bit f a u l t i n g a d d r e s s ## >
*
* ESR - | - - - - | - - - - | - - - - | - - - - | - - - - | - | - | - - - - - | - - - - - |
* - W S R E G E X C
*
*
* STACK F R A M E S T R U C T U R E ( f o r N O _ M M U )
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*
* + - - - - - - - - - - - - - + + 0
* | MSR |
* + - - - - - - - - - - - - - + + 4
* | r1 |
* | . |
* | . |
* | . |
* | . |
* | r1 8 |
* + - - - - - - - - - - - - - + + 7 6
* | . |
* | . |
*
* NO_ M M U k e r n e l u s e t h e s a m e r0 _ r a m p o i n t e d s p a c e - l o o k t o v m l i n u x . l d s . S
* which i s u s e d f o r s t o r i n g r e g i s t e r v a l u e s - o l d s t y l e w a s , t h a t v a l u e w e r e
* stored i n s t a c k b u t i n c a s e o f f a i l u r e y o u l o s t i n f o r m a t i o n a b o u t r e g i s t e r .
* Currently y o u c a n s e e r e g i s t e r v a l u e i n m e m o r y i n s p e c i f i c p l a c e .
* In c o m p a r e t o w i t h p r e v i o u s s o l u t i o n t h e s p e e d s h o u l d b e t h e s a m e .
*
* MMU e x c e p t i o n h a n d l e r h a s d i f f e r e n t h a n d l i n g c o m p a r e t o n o M M U k e r n e l .
* Exception h a n d l e r u s e j u m p t a b l e f o r d i r e c t i n g o f w h a t h a p p e n . F o r M M U k e r n e l
* is t h i s a p p r o a c h b e t t e r b e c a u s e M M U r e l a t e e x c e p t i o n a r e h a n d l e d b y a s m c o d e
* in t h i s f i l e . I n c o m p a r e t o w i t h M M U e x p e c t o f u n a l i g n e d e x c e p t i o n
* is e v e r y t h i n g h a n d l e d b y C c o d e .
* /
/ *
* every o f t h e s e h a n d l e r s i s e n t e r e d h a v i n g R 3 / 4 / 5 / 6 / 1 1 / c u r r e n t s a v e d o n s t a c k
* and c l o b b e r e d s o c a r e s h o u l d b e t a k e n t o r e s t o r e t h e m i f s o m e o n e i s g o i n g t o
* return f r o m e x c e p t i o n
* /
/* wrappers to restore state before coming to entry.S */
2009-05-26 18:30:22 +04:00
# ifdef C O N F I G _ M M U
.section .rodata
.align 4
_MB_HW_ExceptionVectorTable :
/* 0 - Undefined */
.long TOPHYS( e x _ h a n d l e r _ u n h a n d l e d )
/* 1 - Unaligned data access exception */
.long TOPHYS( h a n d l e _ u n a l i g n e d _ e x )
/* 2 - Illegal op-code exception */
.long TOPHYS( f u l l _ e x c e p t i o n _ t r a p w )
/* 3 - Instruction bus error exception */
.long TOPHYS( f u l l _ e x c e p t i o n _ t r a p w )
/* 4 - Data bus error exception */
.long TOPHYS( f u l l _ e x c e p t i o n _ t r a p w )
/* 5 - Divide by zero exception */
.long TOPHYS( f u l l _ e x c e p t i o n _ t r a p w )
/* 6 - Floating point unit exception */
.long TOPHYS( f u l l _ e x c e p t i o n _ t r a p w )
/* 7 - Privileged instruction exception */
.long TOPHYS( f u l l _ e x c e p t i o n _ t r a p w )
/* 8 - 15 - Undefined */
.long TOPHYS( e x _ h a n d l e r _ u n h a n d l e d )
.long TOPHYS( e x _ h a n d l e r _ u n h a n d l e d )
.long TOPHYS( e x _ h a n d l e r _ u n h a n d l e d )
.long TOPHYS( e x _ h a n d l e r _ u n h a n d l e d )
.long TOPHYS( e x _ h a n d l e r _ u n h a n d l e d )
.long TOPHYS( e x _ h a n d l e r _ u n h a n d l e d )
.long TOPHYS( e x _ h a n d l e r _ u n h a n d l e d )
.long TOPHYS( e x _ h a n d l e r _ u n h a n d l e d )
/* 16 - Data storage exception */
.long TOPHYS( h a n d l e _ d a t a _ s t o r a g e _ e x c e p t i o n )
/* 17 - Instruction storage exception */
.long TOPHYS( h a n d l e _ i n s t r u c t i o n _ s t o r a g e _ e x c e p t i o n )
/* 18 - Data TLB miss exception */
.long TOPHYS( h a n d l e _ d a t a _ t l b _ m i s s _ e x c e p t i o n )
/* 19 - Instruction TLB miss exception */
.long TOPHYS( h a n d l e _ i n s t r u c t i o n _ t l b _ m i s s _ e x c e p t i o n )
/* 20 - 31 - Undefined */
.long TOPHYS( e x _ h a n d l e r _ u n h a n d l e d )
.long TOPHYS( e x _ h a n d l e r _ u n h a n d l e d )
.long TOPHYS( e x _ h a n d l e r _ u n h a n d l e d )
.long TOPHYS( e x _ h a n d l e r _ u n h a n d l e d )
.long TOPHYS( e x _ h a n d l e r _ u n h a n d l e d )
.long TOPHYS( e x _ h a n d l e r _ u n h a n d l e d )
.long TOPHYS( e x _ h a n d l e r _ u n h a n d l e d )
.long TOPHYS( e x _ h a n d l e r _ u n h a n d l e d )
.long TOPHYS( e x _ h a n d l e r _ u n h a n d l e d )
.long TOPHYS( e x _ h a n d l e r _ u n h a n d l e d )
.long TOPHYS( e x _ h a n d l e r _ u n h a n d l e d )
.long TOPHYS( e x _ h a n d l e r _ u n h a n d l e d )
# endif
2009-03-27 16:25:13 +03:00
.global _hw_exception_handler
.section .text
.align 4
.ent _hw_exception_handler
_hw_exception_handler :
2009-05-26 18:30:22 +04:00
# ifndef C O N F I G _ M M U
2009-03-27 16:25:13 +03:00
addik r1 , r1 , - ( E X _ H A N D L E R _ S T A C K _ S I Z ) ; /* Create stack frame */
2009-05-26 18:30:22 +04:00
# else
swi r1 , r0 , T O P H Y S ( r0 _ r a m + 0 ) ; /* GET_SP */
/ * Save d a t e t o k e r n e l m e m o r y . H e r e i s t h e p r o b l e m
* when y o u c a m e f r o m u s e r s p a c e * /
ori r1 , r0 , T O P H Y S ( r0 _ r a m + 2 8 ) ;
# endif
2009-03-27 16:25:13 +03:00
swi r3 , r1 , P T _ R 3
swi r4 , r1 , P T _ R 4
swi r5 , r1 , P T _ R 5
swi r6 , r1 , P T _ R 6
2009-05-26 18:30:22 +04:00
# ifdef C O N F I G _ M M U
swi r11 , r1 , P T _ R 1 1
swi r31 , r1 , P T _ R 3 1
lwi r31 , r0 , T O P H Y S ( P E R _ C P U ( C U R R E N T _ S A V E ) ) / * g e t s a v e d c u r r e n t * /
# endif
2009-09-17 19:37:33 +04:00
mfs r5 , r m s r ;
nop
swi r5 , r1 , 0 ;
2010-03-19 14:44:40 +03:00
mfs r4 , r e s r
2009-03-27 16:25:13 +03:00
nop
2010-03-19 14:44:40 +03:00
mfs r3 , r e a r ;
2009-05-26 18:30:22 +04:00
nop
2009-03-27 16:25:13 +03:00
2009-05-26 18:30:22 +04:00
# ifndef C O N F I G _ M M U
2010-03-19 14:44:40 +03:00
andi r5 , r4 , 0 x10 0 0 ; /* Check ESR[DS] */
2009-03-27 16:25:13 +03:00
beqi r5 , n o t _ i n _ d e l a y _ s l o t ; /* Branch if ESR[DS] not set */
mfs r17 , r b t r ; /* ESR[DS] set - return address in BTR */
nop
not_in_delay_slot :
swi r17 , r1 , P T _ R 1 7
2009-05-26 18:30:22 +04:00
# endif
2009-03-27 16:25:13 +03:00
2010-03-19 14:44:40 +03:00
andi r5 , r4 , 0 x1 F ; /* Extract ESR[EXC] */
2009-03-27 16:25:13 +03:00
2009-05-26 18:30:22 +04:00
# ifdef C O N F I G _ M M U
/* Calculate exception vector offset = r5 << 2 */
addk r6 , r5 , r5 ; /* << 1 */
addk r6 , r6 , r6 ; /* << 2 */
2010-03-18 09:23:04 +03:00
# ifdef D E B U G
2009-05-26 18:30:22 +04:00
/* counting which exception happen */
lwi r5 , r0 , 0 x20 0 + T O P H Y S ( r0 _ r a m )
addi r5 , r5 , 1
swi r5 , r0 , 0 x20 0 + T O P H Y S ( r0 _ r a m )
lwi r5 , r6 , 0 x20 0 + T O P H Y S ( r0 _ r a m )
addi r5 , r5 , 1
swi r5 , r6 , 0 x20 0 + T O P H Y S ( r0 _ r a m )
2010-03-18 09:23:04 +03:00
# endif
2009-05-26 18:30:22 +04:00
/* end */
/* Load the HW Exception vector */
lwi r6 , r6 , T O P H Y S ( _ M B _ H W _ E x c e p t i o n V e c t o r T a b l e )
bra r6
full_exception_trapw :
RESTORE_ S T A T E
bri f u l l _ e x c e p t i o n _ t r a p
# else
2009-03-27 16:25:13 +03:00
/* Exceptions enabled here. This will allow nested exceptions */
mfs r6 , r m s r ;
nop
swi r6 , r1 , 0 ; /* RMSR_OFFSET */
ori r6 , r6 , 0 x10 0 ; /* Turn ON the EE bit */
andi r6 , r6 , ~ 2 ; /* Disable interrupts */
mts r m s r , r6 ;
nop
xori r6 , r5 , 1 ; /* 00001 = Unaligned Exception */
/* Jump to unalignment exception handler */
beqi r6 , h a n d l e _ u n a l i g n e d _ e x ;
handle_other_ex : /* Handle Other exceptions here */
/* Save other volatiles before we make procedure calls below */
swi r7 , r1 , P T _ R 7
swi r8 , r1 , P T _ R 8
swi r9 , r1 , P T _ R 9
swi r10 , r1 , P T _ R 1 0
swi r11 , r1 , P T _ R 1 1
swi r12 , r1 , P T _ R 1 2
swi r14 , r1 , P T _ R 1 4
swi r15 , r1 , P T _ R 1 5
swi r18 , r1 , P T _ R 1 8
or r5 , r1 , r0
2010-03-19 14:44:40 +03:00
andi r6 , r4 , 0 x1 F ; /* Load ESR[EC] */
2009-03-27 16:25:13 +03:00
lwi r7 , r0 , P E R _ C P U ( K M ) / * M S : s a v i n g c u r r e n t k e r n e l m o d e t o r e g s * /
swi r7 , r1 , P T _ M O D E
mfs r7 , r f s r
nop
addk r8 , r17 , r0 ; /* Load exception address */
bralid r15 , f u l l _ e x c e p t i o n ; /* Branch to the handler */
nop;
2009-09-28 10:50:53 +04:00
mts r f s r , r0 ; /* Clear sticky fsr */
2009-09-15 06:29:55 +04:00
nop
2009-03-27 16:25:13 +03:00
/ *
* Trigger e x e c u t i o n o f t h e s i g n a l h a n d l e r b y e n a b l i n g
* interrupts a n d c a l l i n g a n i n v a l i d s y s c a l l .
* /
mfs r5 , r m s r ;
nop
ori r5 , r5 , 2 ;
mts r m s r , r5 ; /* enable interrupt */
nop
addi r12 , r0 , _ _ N R _ s y s c a l l s ;
brki r14 , 0 x08 ;
mfs r5 , r m s r ; /* disable interrupt */
nop
andi r5 , r5 , ~ 2 ;
mts r m s r , r5 ;
nop
lwi r7 , r1 , P T _ R 7
lwi r8 , r1 , P T _ R 8
lwi r9 , r1 , P T _ R 9
lwi r10 , r1 , P T _ R 1 0
lwi r11 , r1 , P T _ R 1 1
lwi r12 , r1 , P T _ R 1 2
lwi r14 , r1 , P T _ R 1 4
lwi r15 , r1 , P T _ R 1 5
lwi r18 , r1 , P T _ R 1 8
bri e x _ h a n d l e r _ d o n e ; /* Complete exception handling */
2009-05-26 18:30:22 +04:00
# endif
2009-03-27 16:25:13 +03:00
/ * 0 x0 1 - U n a l i g n e d d a t a a c c e s s e x c e p t i o n
* This o c c u r s w h e n a w o r d a c c e s s i s n o t a l i g n e d o n a w o r d b o u n d a r y ,
* or w h e n a 1 6 - b i t a c c e s s i s n o t a l i g n e d o n a 1 6 - b i t b o u n d a r y .
* This h a n d l e r p e r f o r m t h e a c c e s s , a n d r e t u r n s , e x c e p t f o r M M U w h e n
* the u n a l i g n e d a d d r e s s i s l a s t o n a 4 k p a g e o r t h e p h y s i c a l a d d r e s s i s
* not f o u n d i n t h e p a g e t a b l e , i n w h i c h c a s e u n a l i g n e d _ d a t a _ t r a p i s c a l l e d .
* /
handle_unaligned_ex :
/ * Working r e g i s t e r s a l r e a d y s a v e d : R 3 , R 4 , R 5 , R 6
2010-03-19 14:44:40 +03:00
* R4 = E S R
* R3 = E A R
2009-03-27 16:25:13 +03:00
* /
2009-05-26 18:30:22 +04:00
# ifdef C O N F I G _ M M U
2010-03-19 14:44:40 +03:00
andi r6 , r4 , 0 x10 0 0 / * C h e c k E S R [ D S ] * /
2009-05-26 18:30:22 +04:00
beqi r6 , _ n o _ d e l a y s l o t / * B r a n c h i f E S R [ D S ] n o t s e t * /
mfs r17 , r b t r ; /* ESR[DS] set - return address in BTR */
2009-03-27 16:25:13 +03:00
nop
2009-05-26 18:30:22 +04:00
_no_delayslot :
2009-07-21 14:48:01 +04:00
/* jump to high level unaligned handler */
RESTORE_ S T A T E ;
bri u n a l i g n e d _ d a t a _ t r a p
2009-05-26 18:30:22 +04:00
# endif
2010-03-19 14:44:40 +03:00
andi r6 , r4 , 0 x3 E 0 ; /* Mask and extract the register operand */
2009-03-27 16:25:13 +03:00
srl r6 , r6 ; /* r6 >> 5 */
srl r6 , r6 ;
srl r6 , r6 ;
srl r6 , r6 ;
srl r6 , r6 ;
/* Store the register operand in a temporary location */
sbi r6 , r0 , T O P H Y S ( e x _ r e g _ o p ) ;
2010-03-19 14:44:40 +03:00
andi r6 , r4 , 0 x40 0 ; /* Extract ESR[S] */
2009-03-27 16:25:13 +03:00
bnei r6 , e x _ s w ;
ex_lw :
2010-03-19 14:44:40 +03:00
andi r6 , r4 , 0 x80 0 ; /* Extract ESR[W] */
2009-03-27 16:25:13 +03:00
beqi r6 , e x _ l h w ;
2010-03-19 14:44:40 +03:00
lbui r5 , r3 , 0 ; /* Exception address in r3 */
2009-03-27 16:25:13 +03:00
/ * Load a w o r d , b y t e - b y - b y t e f r o m d e s t i n a t i o n a d d r e s s
and s a v e i t i n t m p s p a c e * /
sbi r5 , r0 , T O P H Y S ( e x _ t m p _ d a t a _ l o c _ 0 ) ;
2010-03-19 14:44:40 +03:00
lbui r5 , r3 , 1 ;
2009-03-27 16:25:13 +03:00
sbi r5 , r0 , T O P H Y S ( e x _ t m p _ d a t a _ l o c _ 1 ) ;
2010-03-19 14:44:40 +03:00
lbui r5 , r3 , 2 ;
2009-03-27 16:25:13 +03:00
sbi r5 , r0 , T O P H Y S ( e x _ t m p _ d a t a _ l o c _ 2 ) ;
2010-03-19 14:44:40 +03:00
lbui r5 , r3 , 3 ;
2009-03-27 16:25:13 +03:00
sbi r5 , r0 , T O P H Y S ( e x _ t m p _ d a t a _ l o c _ 3 ) ;
2010-03-19 14:44:40 +03:00
/* Get the destination register value into r4 */
lwi r4 , r0 , T O P H Y S ( e x _ t m p _ d a t a _ l o c _ 0 ) ;
2009-03-27 16:25:13 +03:00
bri e x _ l w _ t a i l ;
ex_lhw :
2010-03-19 14:44:40 +03:00
lbui r5 , r3 , 0 ; /* Exception address in r3 */
2009-03-27 16:25:13 +03:00
/ * Load a h a l f - w o r d , b y t e - b y - b y t e f r o m d e s t i n a t i o n
address a n d s a v e i t i n t m p s p a c e * /
sbi r5 , r0 , T O P H Y S ( e x _ t m p _ d a t a _ l o c _ 0 ) ;
2010-03-19 14:44:40 +03:00
lbui r5 , r3 , 1 ;
2009-03-27 16:25:13 +03:00
sbi r5 , r0 , T O P H Y S ( e x _ t m p _ d a t a _ l o c _ 1 ) ;
2010-03-19 14:44:40 +03:00
/* Get the destination register value into r4 */
lhui r4 , r0 , T O P H Y S ( e x _ t m p _ d a t a _ l o c _ 0 ) ;
2009-03-27 16:25:13 +03:00
ex_lw_tail :
/* Get the destination register number into r5 */
lbui r5 , r0 , T O P H Y S ( e x _ r e g _ o p ) ;
/* Form load_word jump table offset (lw_table + (8 * regnum)) */
la r6 , r0 , T O P H Y S ( l w _ t a b l e ) ;
addk r5 , r5 , r5 ;
addk r5 , r5 , r5 ;
addk r5 , r5 , r5 ;
addk r5 , r5 , r6 ;
bra r5 ;
ex_lw_end : /* Exception handling of load word, ends */
ex_sw :
/* Get the destination register number into r5 */
lbui r5 , r0 , T O P H Y S ( e x _ r e g _ o p ) ;
/* Form store_word jump table offset (sw_table + (8 * regnum)) */
la r6 , r0 , T O P H Y S ( s w _ t a b l e ) ;
add r5 , r5 , r5 ;
add r5 , r5 , r5 ;
add r5 , r5 , r5 ;
add r5 , r5 , r6 ;
bra r5 ;
ex_sw_tail :
mfs r6 , r e s r ;
nop
andi r6 , r6 , 0 x80 0 ; /* Extract ESR[W] */
beqi r6 , e x _ s h w ;
/* Get the word - delay slot */
2010-03-19 14:44:40 +03:00
swi r4 , r0 , T O P H Y S ( e x _ t m p _ d a t a _ l o c _ 0 ) ;
2009-03-27 16:25:13 +03:00
/* Store the word, byte-by-byte into destination address */
2010-03-19 14:44:40 +03:00
lbui r4 , r0 , T O P H Y S ( e x _ t m p _ d a t a _ l o c _ 0 ) ;
sbi r4 , r3 , 0 ;
lbui r4 , r0 , T O P H Y S ( e x _ t m p _ d a t a _ l o c _ 1 ) ;
sbi r4 , r3 , 1 ;
lbui r4 , r0 , T O P H Y S ( e x _ t m p _ d a t a _ l o c _ 2 ) ;
sbi r4 , r3 , 2 ;
lbui r4 , r0 , T O P H Y S ( e x _ t m p _ d a t a _ l o c _ 3 ) ;
sbi r4 , r3 , 3 ;
2009-03-27 16:25:13 +03:00
bri e x _ h a n d l e r _ d o n e ;
ex_shw :
/* Store the lower half-word, byte-by-byte into destination address */
2010-03-19 14:44:40 +03:00
swi r4 , r0 , T O P H Y S ( e x _ t m p _ d a t a _ l o c _ 0 ) ;
lbui r4 , r0 , T O P H Y S ( e x _ t m p _ d a t a _ l o c _ 2 ) ;
sbi r4 , r3 , 0 ;
lbui r4 , r0 , T O P H Y S ( e x _ t m p _ d a t a _ l o c _ 3 ) ;
sbi r4 , r3 , 1 ;
2009-03-27 16:25:13 +03:00
ex_sw_end : /* Exception handling of store word, ends. */
ex_handler_done :
2009-05-26 18:30:22 +04:00
# ifndef C O N F I G _ M M U
2009-03-27 16:25:13 +03:00
lwi r5 , r1 , 0 / * R M S R * /
mts r m s r , r5
nop
lwi r3 , r1 , P T _ R 3
lwi r4 , r1 , P T _ R 4
lwi r5 , r1 , P T _ R 5
lwi r6 , r1 , P T _ R 6
lwi r17 , r1 , P T _ R 1 7
rted r17 , 0
addik r1 , r1 , ( E X _ H A N D L E R _ S T A C K _ S I Z ) ; /* Restore stack frame */
2009-05-26 18:30:22 +04:00
# else
RESTORE_ S T A T E ;
rted r17 , 0
nop
# endif
# ifdef C O N F I G _ M M U
/ * Exception v e c t o r e n t r y c o d e . T h i s c o d e r u n s w i t h a d d r e s s t r a n s l a t i o n
* turned o f f ( i . e . u s i n g p h y s i c a l a d d r e s s e s ) . * /
/* Exception vectors. */
/ * 0 x1 0 - D a t a S t o r a g e E x c e p t i o n
* This h a p p e n s f o r j u s t a f e w r e a s o n s . U 0 s e t ( b u t w e d o n ' t d o t h a t ) ,
* or z o n e p r o t e c t i o n f a u l t ( u s e r v i o l a t i o n , w r i t e t o p r o t e c t e d p a g e ) .
* If t h i s i s j u s t a n u p d a t e o f m o d i f i e d s t a t u s , w e d o t h a t q u i c k l y
* and e x i t . O t h e r w i s e , w e c a l l h e a v y w e i g h t f u n c t i o n s t o d o t h e w o r k .
* /
handle_data_storage_exception :
/ * Working r e g i s t e r s a l r e a d y s a v e d : R 3 , R 4 , R 5 , R 6
* R3 = E S R
* /
mfs r11 , r p i d
nop
/ * 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 .
* /
2010-03-19 14:50:35 +03:00
ori r5 , r0 , C O N F I G _ K E R N E L _ S T A R T
cmpu r5 , r3 , r5
bgti r5 , e x3
2009-05-26 18:30:22 +04:00
/ * First, c h e c k i f i t w a s a z o n e f a u l t ( w h i c h m e a n s a u s e r
* tried t o a c c e s s a k e r n e l o r r e a d - p r o t e c t e d p a g e - a l w a y s
* a S E G V ) . A l l o t h e r f a u l t s h e r e m u s t b e s t o r e s , s o n o
* need t o c h e c k E S R _ S a s w e l l . * /
andi r4 , r4 , 0 x80 0 / * E S R _ Z - z o n e p r o t e c t i o n * /
bnei r4 , e x2
ori r4 , r0 , s w a p p e r _ p g _ d i r
mts r p i d , r0 / * T L B w i l l h a v e 0 T I D * /
nop
bri e x4
/* Get the PGD for the current thread. */
ex3 :
/ * First, c h e c k i f i t w a s a z o n e f a u l t ( w h i c h m e a n s a u s e r
* tried t o a c c e s s a k e r n e l o r r e a d - p r o t e c t e d p a g e - a l w a y s
* a S E G V ) . A l l o t h e r f a u l t s h e r e m u s t b e s t o r e s , s o n o
* need t o c h e c k E S R _ S a s w e l l . * /
andi r4 , r4 , 0 x80 0 / * E S R _ Z * /
bnei r4 , e x2
/* get current task address */
addi r4 ,C U R R E N T _ T A S K , T O P H Y S ( 0 ) ;
lwi r4 , r4 , T A S K _ T H R E A D + P G D I R
ex4 :
tophys( r4 ,r4 )
BSRLI( r5 ,r3 ,2 0 ) / * C r e a t e L 1 ( p g d i r / p m d ) a d d r e s s * /
andi r5 , r5 , 0 x f f c
/* Assume pgdir aligned on 4K boundary, no need for "andi r4,r4,0xfffff003" */
or r4 , r4 , r5
lwi r4 , r4 , 0 / * G e t L 1 e n t r y * /
andi r5 , r4 , 0 x f f f f f00 0 / * E x t r a c t L 2 ( p t e ) b a s e a d d r e s s * /
beqi r5 , e x2 / * B a i l i f n o t a b l e * /
tophys( r5 ,r5 )
BSRLI( r6 ,r3 ,1 0 ) / * C o m p u t e P T E a d d r e s s * /
andi r6 , r6 , 0 x f f c
andi r5 , r5 , 0 x f f f f f00 3
or r5 , r5 , r6
lwi r4 , r5 , 0 / * G e t L i n u x P T E * /
andi r6 , r4 , _ P A G E _ R W / * I s i t w r i t e a b l e ? * /
beqi r6 , e x2 / * B a i l i f n o t * /
/* Update 'changed' */
ori r4 , r4 , _ P A G E _ D I R T Y | _ P A G E _ A C C E S S E D | _ P A G E _ H W W R I T E
swi r4 , r5 , 0 / * U p d a t e L i n u x p a g e t a b l e * /
/ * Most o f t h e L i n u x P T E i s r e a d y t o l o a d i n t o t h e T L B L O .
* We s e t Z S E L , w h e r e o n l y t h e L S - b i t d e t e r m i n e s u s e r a c c e s s .
* 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 ) .
* If s h a r e d i s s e t , w e c a u s e a z e r o P I D - > T I D l o a d .
* 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 .
* /
andni r4 , r4 , 0 x0 c e 2 / * M a k e s u r e 2 0 , 2 1 a r e z e r o * /
ori r4 , r4 , _ P A G E _ H W E X E C / * m a k e i t e x e c u t a b l e * /
/* find the TLB index that caused the fault. It has to be here*/
mts r t l b s x , r3
nop
mfs r5 , r t l b x / * D E B U G : T B D * /
nop
mts r t l b l o , r4 / * L o a d T L B L O * /
nop
/* Will sync shadow TLBs */
/* Done...restore registers and get out of here. */
mts r p i d , r11
nop
bri 4
RESTORE_ S T A T E ;
rted r17 , 0
nop
ex2 :
/ * 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 . * /
mts r p i d , r11
nop
bri 4
RESTORE_ S T A T E ;
bri p a g e _ f a u l t _ d a t a _ t r a p
/ * 0 x1 1 - I n s t r u c t i o n S t o r a g e E x c e p t i o n
* This i s c a u s e d b y a f e t c h f r o m n o n - e x e c u t e o r g u a r d e d p a g e s . * /
handle_instruction_storage_exception :
/ * Working r e g i s t e r s a l r e a d y s a v e d : R 3 , R 4 , R 5 , R 6
* R3 = E S R
* /
RESTORE_ S T A T E ;
bri p a g e _ f a u l t _ i n s t r _ t r a p
/ * 0 x1 2 - D a t a T L B M i s s E x c e p t i o n
* As t h e n a m e i m p l i e s , t r a n s l a t i o n i s n o t i n t h e M M U , s o s e a r c h t h e
* page t a b l e s a n d f i x i t . T h e o n l y p u r p o s e o f t h i s f u n c t i o n i s t o
* load T L B e n t r i e s f r o m t h e p a g e t a b l e i f t h e y e x i s t .
* /
handle_data_tlb_miss_exception :
/ * Working r e g i s t e r s a l r e a d y s a v e d : R 3 , R 4 , R 5 , R 6
2010-03-22 22:37:23 +03:00
* R3 = E A R , R 4 = E S R
2009-05-26 18:30:22 +04:00
* /
mfs r11 , r p i d
nop
/ * 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 . * /
2010-03-22 22:37:23 +03:00
ori r6 , r0 , C O N F I G _ K E R N E L _ S T A R T
cmpu r4 , r3 , r6
2009-05-26 18:30:22 +04:00
bgti r4 , e x5
ori r4 , r0 , s w a p p e r _ p g _ d i r
mts r p i d , r0 / * T L B w i l l h a v e 0 T I D * /
nop
bri e x6
2009-03-27 16:25:13 +03:00
2009-05-26 18:30:22 +04:00
/* Get the PGD for the current thread. */
ex5 :
/* get current task address */
addi r4 ,C U R R E N T _ T A S K , T O P H Y S ( 0 ) ;
lwi r4 , r4 , T A S K _ T H R E A D + P G D I R
ex6 :
tophys( r4 ,r4 )
BSRLI( r5 ,r3 ,2 0 ) / * C r e a t e L 1 ( p g d i r / p m d ) a d d r e s s * /
andi r5 , r5 , 0 x f f c
/* Assume pgdir aligned on 4K boundary, no need for "andi r4,r4,0xfffff003" */
or r4 , r4 , r5
lwi r4 , r4 , 0 / * G e t L 1 e n t r y * /
andi r5 , r4 , 0 x f f f f f00 0 / * E x t r a c t L 2 ( p t e ) b a s e a d d r e s s * /
beqi r5 , e x7 / * B a i l i f n o t a b l e * /
tophys( r5 ,r5 )
BSRLI( r6 ,r3 ,1 0 ) / * C o m p u t e P T E a d d r e s s * /
andi r6 , r6 , 0 x f f c
andi r5 , r5 , 0 x f f f f f00 3
or r5 , r5 , r6
lwi r4 , r5 , 0 / * G e t L i n u x P T E * /
andi r6 , r4 , _ P A G E _ P R E S E N T
beqi r6 , e x7
ori r4 , r4 , _ P A G E _ A C C E S S E D
swi r4 , r5 , 0
/ * Most o f t h e L i n u x P T E i s r e a d y t o l o a d i n t o t h e T L B L O .
* We s e t Z S E L , w h e r e o n l y t h e L S - b i t d e t e r m i n e s u s e r a c c e s s .
* 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 ) .
* If s h a r e d i s s e t , w e c a u s e a z e r o P I D - > T I D l o a d .
* 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 .
* /
2010-03-22 22:43:27 +03:00
brid f i n i s h _ t l b _ l o a d
2009-05-26 18:30:22 +04:00
andni r4 , r4 , 0 x0 c e 2 / * M a k e s u r e 2 0 , 2 1 a r e z e r o * /
ex7 :
/ * 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 .
* /
mts r p i d , r11
nop
bri 4
RESTORE_ S T A T E ;
bri p a g e _ f a u l t _ d a t a _ t r a p
/ * 0 x1 3 - I n s t r u c t i o n T L B M i s s E x c e p t i o n
* 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 i n f o r m a t i o n f r o m
* different r e g i s t e r s a n d b a i l o u t t o a d i f f e r e n t p o i n t .
* /
handle_instruction_tlb_miss_exception :
/ * Working r e g i s t e r s a l r e a d y s a v e d : R 3 , R 4 , R 5 , R 6
* R3 = E S R
* /
mfs r11 , r p i d
nop
/ * 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 .
* /
ori r4 , r0 , C O N F I G _ K E R N E L _ S T A R T
cmpu r4 , r3 , r4
bgti r4 , e x8
ori r4 , r0 , s w a p p e r _ p g _ d i r
mts r p i d , r0 / * T L B w i l l h a v e 0 T I D * /
nop
bri e x9
/* Get the PGD for the current thread. */
ex8 :
/* get current task address */
addi r4 ,C U R R E N T _ T A S K , T O P H Y S ( 0 ) ;
lwi r4 , r4 , T A S K _ T H R E A D + P G D I R
ex9 :
tophys( r4 ,r4 )
BSRLI( r5 ,r3 ,2 0 ) / * C r e a t e L 1 ( p g d i r / p m d ) a d d r e s s * /
andi r5 , r5 , 0 x f f c
/* Assume pgdir aligned on 4K boundary, no need for "andi r4,r4,0xfffff003" */
or r4 , r4 , r5
lwi r4 , r4 , 0 / * G e t L 1 e n t r y * /
andi r5 , r4 , 0 x f f f f f00 0 / * E x t r a c t L 2 ( p t e ) b a s e a d d r e s s * /
beqi r5 , e x10 / * B a i l i f n o t a b l e * /
tophys( r5 ,r5 )
BSRLI( r6 ,r3 ,1 0 ) / * C o m p u t e P T E a d d r e s s * /
andi r6 , r6 , 0 x f f c
andi r5 , r5 , 0 x f f f f f00 3
or r5 , r5 , r6
lwi r4 , r5 , 0 / * G e t L i n u x P T E * /
andi r6 , r4 , _ P A G E _ P R E S E N T
2010-03-22 22:43:27 +03:00
beqi r6 , e x10
2009-05-26 18:30:22 +04:00
ori r4 , r4 , _ P A G E _ A C C E S S E D
swi r4 , r5 , 0
/ * Most o f t h e L i n u x P T E i s r e a d y t o l o a d i n t o t h e T L B L O .
* We s e t Z S E L , w h e r e o n l y t h e L S - b i t d e t e r m i n e s u s e r a c c e s s .
* 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 ) .
* If s h a r e d i s s e t , w e c a u s e a z e r o P I D - > T I D l o a d .
* 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 .
* /
2010-03-22 22:43:27 +03:00
brid f i n i s h _ t l b _ l o a d
2009-05-26 18:30:22 +04:00
andni r4 , r4 , 0 x0 c e 2 / * M a k e s u r e 2 0 , 2 1 a r e z e r o * /
ex10 :
/ * 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 .
* /
mts r p i d , r11
nop
bri 4
RESTORE_ S T A T E ;
bri p a g e _ f a u l t _ i n s t r _ t r a p
/ * 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 p o i n t t o l o a d t h e T L B .
* r3 - E A o f f a u l t
* r4 - T L B L O ( i n f o f r o m L i n u x P T E )
* r5 , r6 - a v a i l a b l e t o u s e
* PID - 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
* 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 .
* A c o m m o n p l a c e t o l o a d t h e T L B .
* /
tlb_index :
.long 1 /* MS: storing last used tlb index */
finish_tlb_load :
/* MS: load the last used TLB index. */
lwi r5 , r0 , T O P H Y S ( t l b _ i n d e x )
addik r5 , r5 , 1 / * M S : i n c t l b _ i n d e x - > u s e n e x t o n e * /
/* MS: FIXME this is potential fault, because this is mask not count */
andi r5 , r5 , ( M I C R O B L A Z E _ T L B _ S I Z E - 1 )
ori r6 , r0 , 1
cmp r31 , r5 , r6
2010-03-22 22:43:27 +03:00
blti r31 , e x12
2009-05-26 18:30:22 +04:00
addik r5 , r6 , 1
2010-03-22 22:43:27 +03:00
ex12 :
2009-05-26 18:30:22 +04:00
/* MS: save back current TLB index */
swi r5 , r0 , T O P H Y S ( t l b _ i n d e x )
ori r4 , r4 , _ P A G E _ H W E X E C / * m a k e i t e x e c u t a b l e * /
mts r t l b x , r5 / * M S : s a v e c u r r e n t T L B * /
nop
mts r t l b l o , r4 / * M S : s a v e t o T L B L O * /
nop
/ * Create E P N . T h i s i s t h e f a u l t i n g a d d r e s s p l u s a s t a t i c
* set o f b i t s . T h e s e a r e s i z e , v a l i d , E , U 0 , a n d e n s u r e
* bits 2 0 a n d 2 1 a r e z e r o .
* /
andi r3 , r3 , 0 x f f f f f00 0
ori r3 , r3 , 0 x0 c0
mts r t l b h i , r3 / * L o a d T L B H I * /
nop
/* Done...restore registers and get out of here. */
mts r p i d , r11
nop
bri 4
RESTORE_ S T A T E ;
rted r17 , 0
nop
/ * 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 )
*
* The M i c r o B l a z e p r o c e s s o r m a y h a v e a n F P U , s o t h i s s h o u l d n o t j u s t
* return : TBD.
* /
.globl giveup_ f p u ;
.align 4 ;
giveup_fpu :
bralid r15 ,0 / * T B D * /
nop
/* At present, this routine just hangs. - extern void abort(void) */
.globl abort;
.align 4 ;
abort :
br r0
.globl set_ c o n t e x t ;
.align 4 ;
set_context :
mts r p i d , r5 / * S h a d o w T L B s a r e a u t o m a t i c a l l y * /
nop
bri 4 / * f l u s h e d b y c h a n g i n g P I D * /
rtsd r15 ,8
nop
# endif
2009-03-27 16:25:13 +03:00
.end _hw_exception_handler
2009-05-26 18:30:22 +04:00
# ifdef C O N F I G _ M M U
/ * Unaligned d a t a a c c e s s e x c e p t i o n l a s t o n a 4 k p a g e f o r M M U .
* When t h i s i s c a l l e d , w e a r e i n v i r t u a l m o d e w i t h e x c e p t i o n s e n a b l e d
* and r e g i s t e r s 1 - 1 3 ,1 5 ,1 7 ,1 8 s a v e d .
*
* R3 = E S R
* R4 = E A R
* R7 = p o i n t e r t o s a v e d r e g i s t e r s ( s t r u c t p t _ r e g s * r e g s )
*
* This h a n d l e r p e r f o r m t h e a c c e s s , a n d r e t u r n s v i a r e t _ f r o m _ e x c .
* /
.global _unaligned_data_exception
.ent _unaligned_data_exception
_unaligned_data_exception :
andi r8 , r3 , 0 x3 E 0 ; /* Mask and extract the register operand */
BSRLI( r8 ,r8 ,2 ) ; /* r8 >> 2 = register operand * 8 */
andi r6 , r3 , 0 x40 0 ; /* Extract ESR[S] */
bneid r6 , e x _ s w _ v m ;
andi r6 , r3 , 0 x80 0 ; /* Extract ESR[W] - delay slot */
ex_lw_vm :
beqid r6 , e x _ l h w _ v m ;
2009-07-21 14:48:01 +04:00
load1 : lbui r5 , r4 , 0 ; /* Exception address in r4 - delay slot */
2009-05-26 18:30:22 +04:00
/* Load a word, byte-by-byte from destination address and save it in tmp space*/
la r6 , r0 , e x _ t m p _ d a t a _ l o c _ 0 ;
sbi r5 , r6 , 0 ;
2009-07-21 14:48:01 +04:00
load2 : lbui r5 , r4 , 1 ;
2009-05-26 18:30:22 +04:00
sbi r5 , r6 , 1 ;
2009-07-21 14:48:01 +04:00
load3 : lbui r5 , r4 , 2 ;
2009-05-26 18:30:22 +04:00
sbi r5 , r6 , 2 ;
2009-07-21 14:48:01 +04:00
load4 : lbui r5 , r4 , 3 ;
2009-05-26 18:30:22 +04:00
sbi r5 , r6 , 3 ;
brid e x _ l w _ t a i l _ v m ;
/* Get the destination register value into r3 - delay slot */
lwi r3 , r6 , 0 ;
ex_lhw_vm :
/ * Load a h a l f - w o r d , b y t e - b y - b y t e f r o m d e s t i n a t i o n a d d r e s s a n d
* save i t i n t m p s p a c e * /
la r6 , r0 , e x _ t m p _ d a t a _ l o c _ 0 ;
sbi r5 , r6 , 0 ;
2009-07-21 14:48:01 +04:00
load5 : lbui r5 , r4 , 1 ;
2009-05-26 18:30:22 +04:00
sbi r5 , r6 , 1 ;
lhui r3 , r6 , 0 ; /* Get the destination register value into r3 */
ex_lw_tail_vm :
/* Form load_word jump table offset (lw_table_vm + (8 * regnum)) */
addik r5 , r8 , l w _ t a b l e _ v m ;
bra r5 ;
ex_lw_end_vm : /* Exception handling of load word, ends */
brai r e t _ f r o m _ e x c ;
ex_sw_vm :
/* Form store_word jump table offset (sw_table_vm + (8 * regnum)) */
addik r5 , r8 , s w _ t a b l e _ v m ;
bra r5 ;
ex_sw_tail_vm :
la r5 , r0 , e x _ t m p _ d a t a _ l o c _ 0 ;
beqid r6 , e x _ s h w _ v m ;
swi r3 , r5 , 0 ; /* Get the word - delay slot */
/* Store the word, byte-by-byte into destination address */
lbui r3 , r5 , 0 ;
2009-07-21 14:48:01 +04:00
store1 : sbi r3 , r4 , 0 ;
2009-05-26 18:30:22 +04:00
lbui r3 , r5 , 1 ;
2009-07-21 14:48:01 +04:00
store2 : sbi r3 , r4 , 1 ;
2009-05-26 18:30:22 +04:00
lbui r3 , r5 , 2 ;
2009-07-21 14:48:01 +04:00
store3 : sbi r3 , r4 , 2 ;
2009-05-26 18:30:22 +04:00
lbui r3 , r5 , 3 ;
brid r e t _ f r o m _ e x c ;
2009-07-21 14:48:01 +04:00
store4 : sbi r3 , r4 , 3 ; /* Delay slot */
2009-05-26 18:30:22 +04:00
ex_shw_vm :
/* Store the lower half-word, byte-by-byte into destination address */
lbui r3 , r5 , 2 ;
2009-07-21 14:48:01 +04:00
store5 : sbi r3 , r4 , 0 ;
2009-05-26 18:30:22 +04:00
lbui r3 , r5 , 3 ;
brid r e t _ f r o m _ e x c ;
2009-07-21 14:48:01 +04:00
store6 : sbi r3 , r4 , 1 ; /* Delay slot */
2009-05-26 18:30:22 +04:00
ex_sw_end_vm : /* Exception handling of store word, ends. */
2009-07-21 14:48:01 +04:00
/ * We h a v e t o p r e v e n t c a s e s t h a t g e t / p u t _ u s e r m a c r o s g e t u n a l i g n e d p o i n t e r
* to b a d p a g e a r e a . W e h a v e t o f i n d o u t w h i c h o r i g i n i n s t r u c t i o n c a u s e d i t
* and c a l l e d f i x u p f o r t h a t o r i g i n i n s t r u c t i o n n o t i n s t r u c t i o n i n u n a l i g n e d
* handler * /
ex_unaligned_fixup :
ori r5 , r7 , 0 / * s e t u p p o i n t e r t o p t _ r e g s * /
lwi r6 , r7 , P T _ P C ; /* faulting address is one instruction above */
addik r6 , r6 , - 4 / * f o r f i n d i n g p r o p e r f i x u p * /
swi r6 , r7 , P T _ P C ; /* a save back it to PT_PC */
addik r7 , r0 , S I G S E G V
/ * call b a d _ p a g e _ f a u l t f o r f i n d i n g a l i g n e d f i x u p , f i x u p a d d r e s s i s s a v e d
* in P T _ P C w h i c h i s u s e d a s r e t u r n a d d r e s s f r o m e x c e p t i o n * /
la r15 , r0 , r e t _ f r o m _ e x c - 8 / * s e t u p r e t u r n a d d r e s s * /
brid b a d _ p a g e _ f a u l t
nop
/* We prevent all load/store because it could failed any attempt to access */
.section _ _ ex_ t a b l e ," a " ;
.word load1 ,e x _ u n a l i g n e d _ f i x u p ;
.word load2 ,e x _ u n a l i g n e d _ f i x u p ;
.word load3 ,e x _ u n a l i g n e d _ f i x u p ;
.word load4 ,e x _ u n a l i g n e d _ f i x u p ;
.word load5 ,e x _ u n a l i g n e d _ f i x u p ;
.word store1 ,e x _ u n a l i g n e d _ f i x u p ;
.word store2 ,e x _ u n a l i g n e d _ f i x u p ;
.word store3 ,e x _ u n a l i g n e d _ f i x u p ;
.word store4 ,e x _ u n a l i g n e d _ f i x u p ;
.word store5 ,e x _ u n a l i g n e d _ f i x u p ;
.word store6 ,e x _ u n a l i g n e d _ f i x u p ;
.previous ;
2009-05-26 18:30:22 +04:00
.end _unaligned_data_exception
# endif / * C O N F I G _ M M U * /
2010-04-27 21:37:54 +04:00
.global ex_handler_unhandled
2009-03-27 16:25:13 +03:00
ex_handler_unhandled :
/* FIXME add handle function for unhandled exception - dump register */
bri 0
2009-05-26 18:30:22 +04:00
/ *
* hw_ e x c e p t i o n _ h a n d l e r J u m p T a b l e
* - Contains c o d e s n i p p e t s f o r e a c h r e g i s t e r t h a t c a u s e d t h e u n a l i g n e x c e p t i o n
* - Hence e x c e p t i o n h a n d l e r i s N O T s e l f - m o d i f y i n g
* - Separate t a b l e f o r l o a d e x c e p t i o n s a n d s t o r e e x c e p t i o n s .
* - Each t a b l e i s o f s i z e : ( 8 * 3 2 ) = 2 5 6 b y t e s
* /
2009-03-27 16:25:13 +03:00
.section .text
.align 4
lw_table :
lw_r0 : R3 _ T O _ L W R E G ( 0 ) ;
lw_r1 : LWREG_ N O P ;
lw_r2 : R3 _ T O _ L W R E G ( 2 ) ;
lw_r3 : R3 _ T O _ L W R E G _ V ( 3 ) ;
lw_r4 : R3 _ T O _ L W R E G _ V ( 4 ) ;
lw_r5 : R3 _ T O _ L W R E G _ V ( 5 ) ;
lw_r6 : R3 _ T O _ L W R E G _ V ( 6 ) ;
lw_r7 : R3 _ T O _ L W R E G ( 7 ) ;
lw_r8 : R3 _ T O _ L W R E G ( 8 ) ;
lw_r9 : R3 _ T O _ L W R E G ( 9 ) ;
lw_r10 : R3 _ T O _ L W R E G ( 1 0 ) ;
lw_r11 : R3 _ T O _ L W R E G ( 1 1 ) ;
lw_r12 : R3 _ T O _ L W R E G ( 1 2 ) ;
lw_r13 : R3 _ T O _ L W R E G ( 1 3 ) ;
lw_r14 : R3 _ T O _ L W R E G ( 1 4 ) ;
lw_r15 : R3 _ T O _ L W R E G ( 1 5 ) ;
lw_r16 : R3 _ T O _ L W R E G ( 1 6 ) ;
lw_r17 : LWREG_ N O P ;
lw_r18 : R3 _ T O _ L W R E G ( 1 8 ) ;
lw_r19 : R3 _ T O _ L W R E G ( 1 9 ) ;
lw_r20 : R3 _ T O _ L W R E G ( 2 0 ) ;
lw_r21 : R3 _ T O _ L W R E G ( 2 1 ) ;
lw_r22 : R3 _ T O _ L W R E G ( 2 2 ) ;
lw_r23 : R3 _ T O _ L W R E G ( 2 3 ) ;
lw_r24 : R3 _ T O _ L W R E G ( 2 4 ) ;
lw_r25 : R3 _ T O _ L W R E G ( 2 5 ) ;
lw_r26 : R3 _ T O _ L W R E G ( 2 6 ) ;
lw_r27 : R3 _ T O _ L W R E G ( 2 7 ) ;
lw_r28 : R3 _ T O _ L W R E G ( 2 8 ) ;
lw_r29 : R3 _ T O _ L W R E G ( 2 9 ) ;
lw_r30 : R3 _ T O _ L W R E G ( 3 0 ) ;
2009-05-26 18:30:22 +04:00
# ifdef C O N F I G _ M M U
lw_r31 : R3 _ T O _ L W R E G _ V ( 3 1 ) ;
# else
2009-03-27 16:25:13 +03:00
lw_r31 : R3 _ T O _ L W R E G ( 3 1 ) ;
2009-05-26 18:30:22 +04:00
# endif
2009-03-27 16:25:13 +03:00
sw_table :
sw_r0 : SWREG_ T O _ R 3 ( 0 ) ;
sw_r1 : SWREG_ N O P ;
sw_r2 : SWREG_ T O _ R 3 ( 2 ) ;
sw_r3 : SWREG_ T O _ R 3 _ V ( 3 ) ;
sw_r4 : SWREG_ T O _ R 3 _ V ( 4 ) ;
sw_r5 : SWREG_ T O _ R 3 _ V ( 5 ) ;
sw_r6 : SWREG_ T O _ R 3 _ V ( 6 ) ;
sw_r7 : SWREG_ T O _ R 3 ( 7 ) ;
sw_r8 : SWREG_ T O _ R 3 ( 8 ) ;
sw_r9 : SWREG_ T O _ R 3 ( 9 ) ;
sw_r10 : SWREG_ T O _ R 3 ( 1 0 ) ;
sw_r11 : SWREG_ T O _ R 3 ( 1 1 ) ;
sw_r12 : SWREG_ T O _ R 3 ( 1 2 ) ;
sw_r13 : SWREG_ T O _ R 3 ( 1 3 ) ;
sw_r14 : SWREG_ T O _ R 3 ( 1 4 ) ;
sw_r15 : SWREG_ T O _ R 3 ( 1 5 ) ;
sw_r16 : SWREG_ T O _ R 3 ( 1 6 ) ;
sw_r17 : SWREG_ N O P ;
sw_r18 : SWREG_ T O _ R 3 ( 1 8 ) ;
sw_r19 : SWREG_ T O _ R 3 ( 1 9 ) ;
sw_r20 : SWREG_ T O _ R 3 ( 2 0 ) ;
sw_r21 : SWREG_ T O _ R 3 ( 2 1 ) ;
sw_r22 : SWREG_ T O _ R 3 ( 2 2 ) ;
sw_r23 : SWREG_ T O _ R 3 ( 2 3 ) ;
sw_r24 : SWREG_ T O _ R 3 ( 2 4 ) ;
sw_r25 : SWREG_ T O _ R 3 ( 2 5 ) ;
sw_r26 : SWREG_ T O _ R 3 ( 2 6 ) ;
sw_r27 : SWREG_ T O _ R 3 ( 2 7 ) ;
sw_r28 : SWREG_ T O _ R 3 ( 2 8 ) ;
sw_r29 : SWREG_ T O _ R 3 ( 2 9 ) ;
sw_r30 : SWREG_ T O _ R 3 ( 3 0 ) ;
2009-05-26 18:30:22 +04:00
# ifdef C O N F I G _ M M U
sw_r31 : SWREG_ T O _ R 3 _ V ( 3 1 ) ;
# else
2009-03-27 16:25:13 +03:00
sw_r31 : SWREG_ T O _ R 3 ( 3 1 ) ;
2009-05-26 18:30:22 +04:00
# endif
# ifdef C O N F I G _ M M U
lw_table_vm :
lw_r0_vm : R3 _ T O _ L W R E G _ V M ( 0 ) ;
lw_r1_vm : R3 _ T O _ L W R E G _ V M _ V ( 1 ) ;
lw_r2_vm : R3 _ T O _ L W R E G _ V M _ V ( 2 ) ;
lw_r3_vm : R3 _ T O _ L W R E G _ V M _ V ( 3 ) ;
lw_r4_vm : R3 _ T O _ L W R E G _ V M _ V ( 4 ) ;
lw_r5_vm : R3 _ T O _ L W R E G _ V M _ V ( 5 ) ;
lw_r6_vm : R3 _ T O _ L W R E G _ V M _ V ( 6 ) ;
lw_r7_vm : R3 _ T O _ L W R E G _ V M _ V ( 7 ) ;
lw_r8_vm : R3 _ T O _ L W R E G _ V M _ V ( 8 ) ;
lw_r9_vm : R3 _ T O _ L W R E G _ V M _ V ( 9 ) ;
lw_r10_vm : R3 _ T O _ L W R E G _ V M _ V ( 1 0 ) ;
lw_r11_vm : R3 _ T O _ L W R E G _ V M _ V ( 1 1 ) ;
lw_r12_vm : R3 _ T O _ L W R E G _ V M _ V ( 1 2 ) ;
lw_r13_vm : R3 _ T O _ L W R E G _ V M _ V ( 1 3 ) ;
lw_r14_vm : R3 _ T O _ L W R E G _ V M ( 1 4 ) ;
lw_r15_vm : R3 _ T O _ L W R E G _ V M _ V ( 1 5 ) ;
lw_r16_vm : R3 _ T O _ L W R E G _ V M ( 1 6 ) ;
lw_r17_vm : R3 _ T O _ L W R E G _ V M _ V ( 1 7 ) ;
lw_r18_vm : R3 _ T O _ L W R E G _ V M _ V ( 1 8 ) ;
lw_r19_vm : R3 _ T O _ L W R E G _ V M ( 1 9 ) ;
lw_r20_vm : R3 _ T O _ L W R E G _ V M ( 2 0 ) ;
lw_r21_vm : R3 _ T O _ L W R E G _ V M ( 2 1 ) ;
lw_r22_vm : R3 _ T O _ L W R E G _ V M ( 2 2 ) ;
lw_r23_vm : R3 _ T O _ L W R E G _ V M ( 2 3 ) ;
lw_r24_vm : R3 _ T O _ L W R E G _ V M ( 2 4 ) ;
lw_r25_vm : R3 _ T O _ L W R E G _ V M ( 2 5 ) ;
lw_r26_vm : R3 _ T O _ L W R E G _ V M ( 2 6 ) ;
lw_r27_vm : R3 _ T O _ L W R E G _ V M ( 2 7 ) ;
lw_r28_vm : R3 _ T O _ L W R E G _ V M ( 2 8 ) ;
lw_r29_vm : R3 _ T O _ L W R E G _ V M ( 2 9 ) ;
lw_r30_vm : R3 _ T O _ L W R E G _ V M ( 3 0 ) ;
lw_r31_vm : R3 _ T O _ L W R E G _ V M _ V ( 3 1 ) ;
sw_table_vm :
sw_r0_vm : SWREG_ T O _ R 3 _ V M ( 0 ) ;
sw_r1_vm : SWREG_ T O _ R 3 _ V M _ V ( 1 ) ;
sw_r2_vm : SWREG_ T O _ R 3 _ V M _ V ( 2 ) ;
sw_r3_vm : SWREG_ T O _ R 3 _ V M _ V ( 3 ) ;
sw_r4_vm : SWREG_ T O _ R 3 _ V M _ V ( 4 ) ;
sw_r5_vm : SWREG_ T O _ R 3 _ V M _ V ( 5 ) ;
sw_r6_vm : SWREG_ T O _ R 3 _ V M _ V ( 6 ) ;
sw_r7_vm : SWREG_ T O _ R 3 _ V M _ V ( 7 ) ;
sw_r8_vm : SWREG_ T O _ R 3 _ V M _ V ( 8 ) ;
sw_r9_vm : SWREG_ T O _ R 3 _ V M _ V ( 9 ) ;
sw_r10_vm : SWREG_ T O _ R 3 _ V M _ V ( 1 0 ) ;
sw_r11_vm : SWREG_ T O _ R 3 _ V M _ V ( 1 1 ) ;
sw_r12_vm : SWREG_ T O _ R 3 _ V M _ V ( 1 2 ) ;
sw_r13_vm : SWREG_ T O _ R 3 _ V M _ V ( 1 3 ) ;
sw_r14_vm : SWREG_ T O _ R 3 _ V M ( 1 4 ) ;
sw_r15_vm : SWREG_ T O _ R 3 _ V M _ V ( 1 5 ) ;
sw_r16_vm : SWREG_ T O _ R 3 _ V M ( 1 6 ) ;
sw_r17_vm : SWREG_ T O _ R 3 _ V M _ V ( 1 7 ) ;
sw_r18_vm : SWREG_ T O _ R 3 _ V M _ V ( 1 8 ) ;
sw_r19_vm : SWREG_ T O _ R 3 _ V M ( 1 9 ) ;
sw_r20_vm : SWREG_ T O _ R 3 _ V M ( 2 0 ) ;
sw_r21_vm : SWREG_ T O _ R 3 _ V M ( 2 1 ) ;
sw_r22_vm : SWREG_ T O _ R 3 _ V M ( 2 2 ) ;
sw_r23_vm : SWREG_ T O _ R 3 _ V M ( 2 3 ) ;
sw_r24_vm : SWREG_ T O _ R 3 _ V M ( 2 4 ) ;
sw_r25_vm : SWREG_ T O _ R 3 _ V M ( 2 5 ) ;
sw_r26_vm : SWREG_ T O _ R 3 _ V M ( 2 6 ) ;
sw_r27_vm : SWREG_ T O _ R 3 _ V M ( 2 7 ) ;
sw_r28_vm : SWREG_ T O _ R 3 _ V M ( 2 8 ) ;
sw_r29_vm : SWREG_ T O _ R 3 _ V M ( 2 9 ) ;
sw_r30_vm : SWREG_ T O _ R 3 _ V M ( 3 0 ) ;
sw_r31_vm : SWREG_ T O _ R 3 _ V M _ V ( 3 1 ) ;
# endif / * C O N F I G _ M M U * /
2009-03-27 16:25:13 +03:00
/* Temporary data structures used in the handler */
.section .data
.align 4
ex_tmp_data_loc_0 :
.byte 0
ex_tmp_data_loc_1 :
.byte 0
ex_tmp_data_loc_2 :
.byte 0
ex_tmp_data_loc_3 :
.byte 0
ex_reg_op :
.byte 0