2005-04-16 15:20:36 -07:00
/ *
* This f i l e i s s u b j e c t t o t h e t e r m s a n d c o n d i t i o n s o f t h e G N U G e n e r a l P u b l i c
* License. S e e t h e f i l e " C O P Y I N G " i n t h e m a i n d i r e c t o r y o f t h i s a r c h i v e
* for m o r e d e t a i l s .
*
* arch/ s h64 / k e r n e l / e n t r y . S
*
* Copyright ( C ) 2 0 0 0 , 2 0 0 1 P a o l o A l b e r e l l i
* Copyright ( C ) 2 0 0 4 , 2 0 0 5 P a u l M u n d t
* Copyright ( C ) 2 0 0 3 , 2 0 0 4 R i c h a r d C u r n o w
*
* /
# include < l i n u x / e r r n o . h >
# include < l i n u x / s y s . h >
# include < a s m / p r o c e s s o r . h >
# include < a s m / r e g i s t e r s . h >
# include < a s m / u n i s t d . h >
# include < a s m / t h r e a d _ i n f o . h >
# include < a s m / a s m - o f f s e t s . h >
/ *
* SR f i e l d s .
* /
# define S R _ A S I D _ M A S K 0 x00 f f00 0 0
# define S R _ F D _ M A S K 0 x00 0 0 8 0 0 0
# define S R _ S S 0 x08 0 0 0 0 0 0
# define S R _ B L 0 x10 0 0 0 0 0 0
# define S R _ M D 0 x40 0 0 0 0 0 0
/ *
* Event c o d e .
* /
# define E V E N T _ I N T E R R U P T 0
# define E V E N T _ F A U L T _ T L B 1
# define E V E N T _ F A U L T _ N O T _ T L B 2
# define E V E N T _ D E B U G 3
/* EXPEVT values */
# define R E S E T _ C A U S E 0 x20
# define D E B U G S S _ C A U S E 0 x98 0
/ *
* Frame l a y o u t . Q u a d i n d e x .
* /
# define F R A M E _ T ( x ) F R A M E _ T B A S E + ( x * 8 )
# define F R A M E _ R ( x ) F R A M E _ R B A S E + ( x * 8 )
# define F R A M E _ S ( x ) F R A M E _ S B A S E + ( x * 8 )
# define F S P C 0
# define F S S R 1
# define F S Y S C A L L _ I D 2
/* Arrange the save frame to be a multiple of 32 bytes long */
# define F R A M E _ S B A S E 0
# define F R A M E _ R B A S E ( F R A M E _ S B A S E + ( 3 * 8 ) ) / * S Y S C A L L _ I D - S S R - S P C * /
# define F R A M E _ T B A S E ( F R A M E _ R B A S E + ( 6 3 * 8 ) ) / * r0 - r62 * /
# define F R A M E _ P B A S E ( F R A M E _ T B A S E + ( 8 * 8 ) ) / * t r0 - t r7 * /
# define F R A M E _ S I Z E ( F R A M E _ P B A S E + ( 2 * 8 ) ) / * p a d0 - p a d1 * /
# define F P _ F R A M E _ S I Z E F P _ F R A M E _ B A S E + ( 3 3 * 8 ) / * d r0 - d r31 + f p s c r * /
# define F P _ F R A M E _ B A S E 0
# define S A V E D _ R 2 0 * 8
# define S A V E D _ R 3 1 * 8
# define S A V E D _ R 4 2 * 8
# define S A V E D _ R 5 3 * 8
# define S A V E D _ R 1 8 4 * 8
# define S A V E D _ R 6 5 * 8
# define S A V E D _ T R 0 6 * 8
/ * These a r e t h e r e g i s t e r s s a v e d i n t h e T L B p a t h t h a t a r e n ' t s a v e d i n t h e f i r s t
level o f t h e n o r m a l o n e . * /
# define T L B _ S A V E D _ R 2 5 7 * 8
# define T L B _ S A V E D _ T R 1 8 * 8
# define T L B _ S A V E D _ T R 2 9 * 8
# define T L B _ S A V E D _ T R 3 1 0 * 8
# define T L B _ S A V E D _ T R 4 1 1 * 8
/ * Save R 0 / R 1 : P T - m i g r a t i n g c o m p i l e r c u r r e n t l y d i s h o u n o u r s - f f i x e d - r0 a n d - f f i x e d - r1 c a u s i n g
breakage o t h e r w i s e . * /
# define T L B _ S A V E D _ R 0 1 2 * 8
# define T L B _ S A V E D _ R 1 1 3 * 8
# define C L I ( ) \
getcon S R , r6 ; \
ori r6 , 0 x f0 , r6 ; \
putcon r6 , S R ;
# define S T I ( ) \
getcon S R , r6 ; \
andi r6 , ~ 0 x f0 , r6 ; \
putcon r6 , S R ;
# ifdef C O N F I G _ P R E E M P T
# define p r e e m p t _ s t o p ( ) C L I ( )
# else
# define p r e e m p t _ s t o p ( )
# define r e s u m e _ k e r n e l r e s t o r e _ a l l
# endif
.section .data , " aw"
# define F A S T _ T L B M I S S _ S T A C K _ C A C H E L I N E S 4
# define F A S T _ T L B M I S S _ S T A C K _ Q U A D W O R D S ( 4 * F A S T _ T L B M I S S _ S T A C K _ C A C H E L I N E S )
/* Register back-up area for all exceptions */
.balign 32
/ * Allow f o r 1 6 q u a d w o r d s t o b e p u s h e d b y f a s t t l b m i s s h a n d l i n g
* register s a v e s e t c . * /
.fill FAST_ T L B M I S S _ S T A C K _ Q U A D W O R D S , 8 , 0 x0
/* This is 32 byte aligned by construction */
/* Register back-up area for all exceptions */
reg_save_area :
.quad 0
.quad 0
.quad 0
.quad 0
.quad 0
.quad 0
.quad 0
.quad 0
.quad 0
.quad 0
.quad 0
.quad 0
.quad 0
.quad 0
/ * Save a r e a f o r R E S V E C e x c e p t i o n s . W e c a n n o t u s e r e g _ s a v e _ a r e a b e c a u s e o f
* reentrancy. N o t e t h i s a r e a m a y b e a c c e s s e d v i a p h y s i c a l a d d r e s s .
* Align s o t h i s f i t s a w h o l e s i n g l e c a c h e l i n e , f o r e a s e o f p u r g i n g .
* /
.balign 3 2 , 0 , 3 2
resvec_save_area :
.quad 0
.quad 0
.quad 0
.quad 0
.quad 0
.balign 3 2 , 0 , 3 2
/* Jump table of 3rd level handlers */
trap_jtable :
.long do_exception_error /* 0x000 */
.long do_exception_error /* 0x020 */
.long tlb_miss_load /* 0x040 */
.long tlb_miss_store /* 0x060 */
! ARTIFICIAL p s e u d o - E X P E V T s e t t i n g
.long do_debug_interrupt /* 0x080 */
.long tlb_miss_load /* 0x0A0 */
.long tlb_miss_store /* 0x0C0 */
.long do_address_error_load /* 0x0E0 */
.long do_address_error_store /* 0x100 */
# ifdef C O N F I G _ S H _ F P U
.long do_fpu_error /* 0x120 */
# else
.long do_exception_error /* 0x120 */
# endif
.long do_exception_error /* 0x140 */
.long system_call /* 0x160 */
.long do_reserved_inst /* 0x180 */
.long do_illegal_slot_inst /* 0x1A0 */
.long do_NMI /* 0x1C0 */
.long do_exception_error /* 0x1E0 */
.rept 15
.long do_IRQ /* 0x200 - 0x3C0 */
.endr
.long do_exception_error /* 0x3E0 */
.rept 32
.long do_IRQ /* 0x400 - 0x7E0 */
.endr
.long fpu_error_or_IRQA /* 0x800 */
.long fpu_error_or_IRQB /* 0x820 */
.long do_IRQ /* 0x840 */
.long do_IRQ /* 0x860 */
.rept 6
.long do_exception_error /* 0x880 - 0x920 */
.endr
.long do_software_break_point /* 0x940 */
.long do_exception_error /* 0x960 */
.long do_single_step /* 0x980 */
.rept 3
.long do_exception_error /* 0x9A0 - 0x9E0 */
.endr
.long do_IRQ /* 0xA00 */
.long do_IRQ /* 0xA20 */
.long itlb_miss_or_IRQ /* 0xA40 */
.long do_IRQ /* 0xA60 */
.long do_IRQ /* 0xA80 */
.long itlb_miss_or_IRQ /* 0xAA0 */
.long do_exception_error /* 0xAC0 */
.long do_address_error_exec /* 0xAE0 */
.rept 8
.long do_exception_error /* 0xB00 - 0xBE0 */
.endr
.rept 18
.long do_IRQ /* 0xC00 - 0xE20 */
.endr
.section .text64 , " ax"
/ *
* - - - Exception/ I n t e r r u p t / E v e n t H a n d l i n g S e c t i o n
* /
/ *
* VBR a n d R E S V E C b l o c k s .
*
* First l e v e l h a n d l e r f o r V B R - b a s e d e x c e p t i o n s .
*
* To a v o i d w a s t e o f s p a c e , a l i g n t o t h e m a x i m u m t e x t b l o c k s i z e .
* This i s a s s u m e d t o b e a t m o s t 1 2 8 b y t e s o r 3 2 i n s t r u c t i o n s .
* DO N O T E X C E E D 3 2 i n s t r u c t i o n s o n t h e f i r s t l e v e l h a n d l e r s !
*
* Also n o t e t h a t R E S V E C i s c o n t a i n e d w i t h i n t h e V B R b l o c k
* where t h e r o o m l e f t ( 1 K B - T E X T _ S I Z E ) a l l o w s p l a c i n g
* the R E S V E C b l o c k ( a t m o s t 5 1 2 B + T E X T _ S I Z E ) .
*
* So f i r s t ( a n d o n l y ) l e v e l h a n d l e r f o r R E S V E C - b a s e d e x c e p t i o n s .
*
* Where t h e f a u l t / i n t e r r u p t i s h a n d l e d ( n o t _ a _ t l b _ m i s s , t l b _ m i s s
* and i n t e r r u p t ) w e a r e a l o t t i g h t w i t h r e g i s t e r s p a c e u n t i l
* saving o n t o t h e s t a c k f r a m e , w h i c h i s d o n e i n h a n d l e _ e x c e p t i o n ( ) .
*
* /
# define T E X T _ S I Z E 1 2 8
# define B L O C K _ S I Z E 1 6 6 4 / * D y n a m i c c h e c k , 1 3 * 1 2 8 * /
.balign TEXT_SIZE
LVBR_block :
.space 2 5 6 , 0 /* Power-on class handler, */
/* not required here */
not_a_tlb_miss :
synco / * T A K u m 0 3 0 2 0 ( b u t p r o b a b l y a g o o d i d e a a n y w a y . ) * /
/* Save original stack pointer into KCR1 */
putcon S P , K C R 1
/* Save other original registers into reg_save_area */
movi r e g _ s a v e _ a r e a , S P
st. q S P , S A V E D _ R 2 , r2
st. q S P , S A V E D _ R 3 , r3
st. q S P , S A V E D _ R 4 , r4
st. q S P , S A V E D _ R 5 , r5
st. q S P , S A V E D _ R 6 , r6
st. q S P , S A V E D _ R 1 8 , r18
gettr t r0 , r3
st. q S P , S A V E D _ T R 0 , r3
/* Set args for Non-debug, Not a TLB miss class handler */
getcon E X P E V T , r2
movi r e t _ f r o m _ e x c e p t i o n , r3
ori r3 , 1 , r3
movi E V E N T _ F A U L T _ N O T _ T L B , r4
or S P , Z E R O , r5
getcon K C R 1 , S P
pta h a n d l e _ e x c e p t i o n , t r0
blink t r0 , Z E R O
.balign 256
! VBR+ 0 x20 0
nop
.balign 256
! VBR+ 0 x30 0
nop
.balign 256
/ *
* Instead o f t h e n a t u r a l . b a l i g n 1 0 2 4 p l a c e R E S V E C h e r e
* respecting t h e f i n a l 1 K B a l i g n m e n t .
* /
.balign TEXT_SIZE
/ *
* Instead o f ' . s p a c e 1 0 2 4 - T E X T _ S I Z E ' p l a c e t h e R E S V E C
* block m a k i n g s u r e t h e f i n a l a l i g n m e n t i s c o r r e c t .
* /
tlb_miss :
synco / * T A K u m 0 3 0 2 0 ( b u t p r o b a b l y a g o o d i d e a a n y w a y . ) * /
putcon S P , K C R 1
movi r e g _ s a v e _ a r e a , S P
/* SP is guaranteed 32-byte aligned. */
st. q S P , T L B _ S A V E D _ R 0 , r0
st. q S P , T L B _ S A V E D _ R 1 , r1
st. q S P , S A V E D _ R 2 , r2
st. q S P , S A V E D _ R 3 , r3
st. q S P , S A V E D _ R 4 , r4
st. q S P , S A V E D _ R 5 , r5
st. q S P , S A V E D _ R 6 , r6
st. q S P , S A V E D _ R 1 8 , r18
/ * Save R 2 5 f o r s a f e t y ; as/ld may want to use it to achieve the call to
* the c o d e i n m m / t l b m i s s . c * /
st. q S P , T L B _ S A V E D _ R 2 5 , r25
gettr t r0 , r2
gettr t r1 , r3
gettr t r2 , r4
gettr t r3 , r5
gettr t r4 , r18
st. q S P , S A V E D _ T R 0 , r2
st. q S P , T L B _ S A V E D _ T R 1 , r3
st. q S P , T L B _ S A V E D _ T R 2 , r4
st. q S P , T L B _ S A V E D _ T R 3 , r5
st. q S P , T L B _ S A V E D _ T R 4 , r18
pt d o _ f a s t _ p a g e _ f a u l t , t r0
getcon S S R , r2
getcon E X P E V T , r3
getcon T E A , r4
shlri r2 , 3 0 , r2
andi r2 , 1 , r2 / * r2 = S S R . M D * /
blink t r0 , L I N K
pt f i x u p _ t o _ i n v o k e _ g e n e r a l _ h a n d l e r , t r1
/ * If t h e f a s t p a t h h a n d l e r f i x e d t h e f a u l t , j u s t d r o p t h r o u g h q u i c k l y
to t h e r e s t o r e c o d e r i g h t a w a y t o r e t u r n t o t h e e x c e p t i n g c o n t e x t .
* /
beqi/ u r2 , 0 , t r1
fast_tlb_miss_restore :
ld. q S P , S A V E D _ T R 0 , r2
ld. q S P , T L B _ S A V E D _ T R 1 , r3
ld. q S P , T L B _ S A V E D _ T R 2 , r4
ld. q S P , T L B _ S A V E D _ T R 3 , r5
ld. q S P , T L B _ S A V E D _ T R 4 , r18
ptabs r2 , t r0
ptabs r3 , t r1
ptabs r4 , t r2
ptabs r5 , t r3
ptabs r18 , t r4
ld. q S P , T L B _ S A V E D _ R 0 , r0
ld. q S P , T L B _ S A V E D _ R 1 , r1
ld. q S P , S A V E D _ R 2 , r2
ld. q S P , S A V E D _ R 3 , r3
ld. q S P , S A V E D _ R 4 , r4
ld. q S P , S A V E D _ R 5 , r5
ld. q S P , S A V E D _ R 6 , r6
ld. q S P , S A V E D _ R 1 8 , r18
ld. q S P , T L B _ S A V E D _ R 2 5 , r25
getcon K C R 1 , S P
rte
nop / * f o r s a f e t y , i n c a s e t h e c o d e i s r u n o n s h5 - 1 0 1 c u t 1 . x * /
fixup_to_invoke_general_handler :
/ * OK, n e w m e t h o d . R e s t o r e s t u f f t h a t ' s n o t e x p e c t e d t o g e t s a v e d i n t o
the ' f i r s t - l e v e l ' r e g s a v e a r e a , t h e n j u s t f a l l t h r o u g h t o s e t t i n g
up t h e r e g i s t e r s a n d c a l l i n g t h e s e c o n d - l e v e l h a n d l e r . * /
/ * 2 nd l e v e l e x p e c t s r2 ,3 ,4 ,5 ,6 ,1 8 ,t r0 t o b e s a v e d . S o w e m u s t r e s t o r e
r2 5 ,t r1 - 4 a n d s a v e r6 t o g e t i n t o t h e r i g h t s t a t e . * /
ld. q S P , T L B _ S A V E D _ T R 1 , r3
ld. q S P , T L B _ S A V E D _ T R 2 , r4
ld. q S P , T L B _ S A V E D _ T R 3 , r5
ld. q S P , T L B _ S A V E D _ T R 4 , r18
ld. q S P , T L B _ S A V E D _ R 2 5 , r25
ld. q S P , T L B _ S A V E D _ R 0 , r0
ld. q S P , T L B _ S A V E D _ R 1 , r1
ptabs/ u r3 , t r1
ptabs/ u r4 , t r2
ptabs/ u r5 , t r3
ptabs/ u r18 , t r4
/* Set args for Non-debug, TLB miss class handler */
getcon E X P E V T , r2
movi r e t _ f r o m _ e x c e p t i o n , r3
ori r3 , 1 , r3
movi E V E N T _ F A U L T _ T L B , r4
or S P , Z E R O , r5
getcon K C R 1 , S P
pta h a n d l e _ e x c e p t i o n , t r0
blink t r0 , Z E R O
/ * NB T A K E G R E A T C A R E H E R E T O E N S U R E T H A T T H E I N T E R R U P T C O D E
DOES E N D U P A T V B R + 0 x60 0 * /
nop
nop
nop
nop
nop
nop
.balign 256
/* VBR + 0x600 */
interrupt :
synco / * T A K u m 0 3 0 2 0 ( b u t p r o b a b l y a g o o d i d e a a n y w a y . ) * /
/* Save original stack pointer into KCR1 */
putcon S P , K C R 1
/* Save other original registers into reg_save_area */
movi r e g _ s a v e _ a r e a , S P
st. q S P , S A V E D _ R 2 , r2
st. q S P , S A V E D _ R 3 , r3
st. q S P , S A V E D _ R 4 , r4
st. q S P , S A V E D _ R 5 , r5
st. q S P , S A V E D _ R 6 , r6
st. q S P , S A V E D _ R 1 8 , r18
gettr t r0 , r3
st. q S P , S A V E D _ T R 0 , r3
/* Set args for interrupt class handler */
getcon I N T E V T , r2
movi r e t _ f r o m _ i r q , r3
ori r3 , 1 , r3
movi E V E N T _ I N T E R R U P T , r4
or S P , Z E R O , r5
getcon K C R 1 , S P
pta h a n d l e _ e x c e p t i o n , t r0
blink t r0 , Z E R O
.balign TEXT_SIZE /* let's waste the bare minimum */
LVBR_block_end : /* Marker. Used for total checking */
.balign 256
LRESVEC_block :
/ * Panic h a n d l e r . C a l l e d w i t h M M U o f f . P o s s i b l e c a u s e s / a c t i o n s :
* - Reset : Jump t o p r o g r a m s t a r t .
* - Single S t e p : T u r n o f f S i n g l e S t e p & r e t u r n .
* - Others : Call p a n i c h a n d l e r , p a s s i n g P C a s a r g .
* ( this m a y n e e d t o b e e x t e n d e d . . . )
* /
reset_or_panic :
synco / * T A K u m 0 3 0 2 0 ( b u t p r o b a b l y a g o o d i d e a a n y w a y . ) * /
putcon S P , D C R
/* First save r0-1 and tr0, as we need to use these */
movi r e s v e c _ s a v e _ a r e a - C O N F I G _ C A C H E D _ M E M O R Y _ O F F S E T , S P
st. q S P , 0 , r0
st. q S P , 8 , r1
gettr t r0 , r0
st. q S P , 3 2 , r0
/* Check cause */
getcon E X P E V T , r0
movi R E S E T _ C A U S E , r1
sub r1 , r0 , r1 / * r1 =0 i f r e s e t * /
movi _ s t e x t - C O N F I G _ C A C H E D _ M E M O R Y _ O F F S E T , r0
ori r0 , 1 , r0
ptabs r0 , t r0
beqi r1 , 0 , t r0 / * J u m p t o s t a r t a d d r e s s i f r e s e t * /
getcon E X P E V T , r0
movi D E B U G S S _ C A U S E , r1
sub r1 , r0 , r1 / * r1 =0 i f s i n g l e s t e p * /
pta s i n g l e _ s t e p _ p a n i c , t r0
beqi r1 , 0 , t r0 / * j u m p i f s i n g l e s t e p * /
/* Now jump to where we save the registers. */
movi p a n i c _ s t a s h _ r e g s - C O N F I G _ C A C H E D _ M E M O R Y _ O F F S E T , r1
ptabs r1 , t r0
blink t r0 , r63
single_step_panic :
/ * We a r e i n a h a n d l e r w i t h S i n g l e S t e p s e t . W e n e e d t o r e s u m e t h e
* handler, b y t u r n i n g o n M M U & t u r n i n g o f f S i n g l e S t e p . * /
getcon S S R , r0
movi S R _ M M U , r1
or r0 , r1 , r0
movi ~ S R _ S S , r1
and r0 , r1 , r0
putcon r0 , S S R
/* Restore EXPEVT, as the rte won't do this */
getcon P E X P E V T , r0
putcon r0 , E X P E V T
/* Restore regs */
ld. q S P , 3 2 , r0
ptabs r0 , t r0
ld. q S P , 0 , r0
ld. q S P , 8 , r1
getcon D C R , S P
synco
rte
.balign 256
debug_exception :
synco / * T A K u m 0 3 0 2 0 ( b u t p r o b a b l y a g o o d i d e a a n y w a y . ) * /
/ *
* Single s t e p / s o f t w a r e _ b r e a k _ p o i n t f i r s t l e v e l h a n d l e r .
* Called w i t h M M U o f f , s o t h e f i r s t t h i n g w e d o i s e n a b l e i t
* by d o i n g a n r t e w i t h a p p r o p r i a t e S S R .
* /
putcon S P , D C R
/* Save SSR & SPC, together with R0 & R1, as we need to use 2 regs. */
movi r e s v e c _ s a v e _ a r e a - C O N F I G _ C A C H E D _ M E M O R Y _ O F F S E T , S P
/ * With t h e M M U o f f , w e a r e b y p a s s i n g t h e c a c h e , s o p u r g e a n y
* data t h a t w i l l b e m a d e s t a l e b y t h e f o l l o w i n g s t o r e s .
* /
ocbp S P , 0
synco
st. q S P , 0 , r0
st. q S P , 8 , r1
getcon S P C , r0
st. q S P , 1 6 , r0
getcon S S R , r0
st. q S P , 2 4 , r0
/* Enable MMU, block exceptions, set priv mode, disable single step */
movi S R _ M M U | S R _ B L | S R _ M D , r1
or r0 , r1 , r0
movi ~ S R _ S S , r1
and r0 , r1 , r0
putcon r0 , S S R
/* Force control to debug_exception_2 when rte is executed */
movi d e b u g _ e x e c e p t i o n _ 2 , r0
ori r0 , 1 , r0 / * f o r c e S H m e d i a , j u s t i n c a s e * /
putcon r0 , S P C
getcon D C R , S P
synco
rte
debug_exeception_2 :
/* Restore saved regs */
putcon S P , K C R 1
movi r e s v e c _ s a v e _ a r e a , S P
ld. q S P , 2 4 , r0
putcon r0 , S S R
ld. q S P , 1 6 , r0
putcon r0 , S P C
ld. q S P , 0 , r0
ld. q S P , 8 , r1
/* Save other original registers into reg_save_area */
movi r e g _ s a v e _ a r e a , S P
st. q S P , S A V E D _ R 2 , r2
st. q S P , S A V E D _ R 3 , r3
st. q S P , S A V E D _ R 4 , r4
st. q S P , S A V E D _ R 5 , r5
st. q S P , S A V E D _ R 6 , r6
st. q S P , S A V E D _ R 1 8 , r18
gettr t r0 , r3
st. q S P , S A V E D _ T R 0 , r3
/* Set args for debug class handler */
getcon E X P E V T , r2
movi r e t _ f r o m _ e x c e p t i o n , r3
ori r3 , 1 , r3
movi E V E N T _ D E B U G , r4
or S P , Z E R O , r5
getcon K C R 1 , S P
pta h a n d l e _ e x c e p t i o n , t r0
blink t r0 , Z E R O
.balign 256
debug_interrupt :
/* !!! WE COME HERE IN REAL MODE !!! */
/ * Hook- u p d e b u g i n t e r r u p t t o a l l o w v a r i o u s d e b u g g i n g o p t i o n s t o b e
* hooked i n t o i t s h a n d l e r . * /
/* Save original stack pointer into KCR1 */
synco
putcon S P , K C R 1
movi r e s v e c _ s a v e _ a r e a - C O N F I G _ C A C H E D _ M E M O R Y _ O F F S E T , S P
ocbp S P , 0
ocbp S P , 3 2
synco
/* Save other original registers into reg_save_area thru real addresses */
st. q S P , S A V E D _ R 2 , r2
st. q S P , S A V E D _ R 3 , r3
st. q S P , S A V E D _ R 4 , r4
st. q S P , S A V E D _ R 5 , r5
st. q S P , S A V E D _ R 6 , r6
st. q S P , S A V E D _ R 1 8 , r18
gettr t r0 , r3
st. q S P , S A V E D _ T R 0 , r3
/ * move ( s p c ,s s r ) - > ( p s p c ,p s s r ) . T h e r t e w i l l s h i f t
them b a c k a g a i n , s o t h a t t h e y l o o k l i k e t h e o r i g i n a l s
as f a r a s t h e r e a l h a n d l e r c o d e i s c o n c e r n e d . * /
getcon s p c , r6
putcon r6 , p s p c
getcon s s r , r6
putcon r6 , p s s r
! construct u s e f u l S R f o r h a n d l e _ e x c e p t i o n
movi 3 , r6
shlli r6 , 3 0 , r6
getcon s r , r18
or r18 , r6 , r6
putcon r6 , s s r
! SSR i s n o w t h e c u r r e n t S R w i t h t h e M D a n d M M U b i t s s e t
! i. e . t h e r t e w i l l s w i t c h b a c k t o p r i v m o d e a n d p u t
! the m m u b a c k o n
! construct s p c
movi h a n d l e _ e x c e p t i o n , r18
ori r18 , 1 , r18 ! f o r s a f e t y ( d o w e n e e d t h i s ? )
putcon r18 , s p c
/* Set args for Non-debug, Not a TLB miss class handler */
! EXPEVT= =0x80 i s u n u s e d , s o ' s t e a l ' t h i s v a l u e t o p u t t h e
! debug i n t e r r u p t h a n d l e r i n t h e v e c t o r i n g t a b l e
movi 0 x80 , r2
movi r e t _ f r o m _ e x c e p t i o n , r3
ori r3 , 1 , r3
movi E V E N T _ F A U L T _ N O T _ T L B , r4
or S P , Z E R O , r5
movi C O N F I G _ C A C H E D _ M E M O R Y _ O F F S E T , r6
add r6 , r5 , r5
getcon K C R 1 , S P
synco ! f o r s a f e t y
rte ! - > h a n d l e _ e x c e p t i o n , s w i t c h b a c k t o p r i v m o d e a g a i n
LRESVEC_block_end : /* Marker. Unused. */
.balign TEXT_SIZE
/ *
* Second l e v e l h a n d l e r f o r V B R - b a s e d e x c e p t i o n s . P r e - h a n d l e r .
* In c o m m o n t o a l l s t a c k - f r a m e s e n s i t i v e h a n d l e r s .
*
* Inputs :
* ( KCR0 ) C u r r e n t [ c u r r e n t t a s k u n i o n ]
* ( KCR1 ) O r i g i n a l S P
* ( r2 ) I N T E V T / E X P E V T
* ( r3 ) a p p r o p r i a t e r e t u r n a d d r e s s
* ( r4 ) E v e n t ( 0 = i n t e r r u p t , 1 = T L B m i s s f a u l t , 2 = N o t T L B m i s s f a u l t , 3 =debug )
* ( r5 ) P o i n t e r t o r e g _ s a v e _ a r e a
* ( SP) O r i g i n a l S P
*
* Available r e g i s t e r s :
* ( r6 )
* ( r1 8 )
* ( tr0 )
*
* /
handle_exception :
/* Common 2nd level handler. */
/* First thing we need an appropriate stack pointer */
getcon S S R , r6
shlri r6 , 3 0 , r6
andi r6 , 1 , r6
pta s t a c k _ o k , t r0
bne r6 , Z E R O , t r0 / * O r i g i n a l s t a c k p o i n t e r i s f i n e * /
/* Set stack pointer for user fault */
getcon K C R 0 , S P
movi T H R E A D _ S I Z E , r6 / * P o i n t t o t h e e n d * /
add S P , r6 , S P
stack_ok :
/* DEBUG : check for underflow/overflow of the kernel stack */
pta n o _ u n d e r f l o w , t r0
getcon K C R 0 , r6
movi 1 0 2 4 , r18
add r6 , r18 , r6
bge S P , r6 , t r0 ! ? b e l o w 1 k f r o m b o t t o m o f s t a c k : d a n g e r z o n e
/* Just panic to cause a crash. */
bad_sp :
ld. b r63 , 0 , r6
nop
no_underflow :
pta b a d _ s p , t r0
getcon k c r0 , r6
movi T H R E A D _ S I Z E , r18
add r18 , r6 , r6
bgt S P , r6 , t r0 ! s p a b o v e t h e s t a c k
/* Make some room for the BASIC frame. */
movi - ( F R A M E _ S I Z E ) , r6
add S P , r6 , S P
/ * Could d o t h i s w i t h n o s t a l l i n g i f w e h a d a n o t h e r s p a r e r e g i s t e r , b u t t h e
code b e l o w w i l l b e O K . * /
ld. q r5 , S A V E D _ R 2 , r6
ld. q r5 , S A V E D _ R 3 , r18
st. q S P , F R A M E _ R ( 2 ) , r6
ld. q r5 , S A V E D _ R 4 , r6
st. q S P , F R A M E _ R ( 3 ) , r18
ld. q r5 , S A V E D _ R 5 , r18
st. q S P , F R A M E _ R ( 4 ) , r6
ld. q r5 , S A V E D _ R 6 , r6
st. q S P , F R A M E _ R ( 5 ) , r18
ld. q r5 , S A V E D _ R 1 8 , r18
st. q S P , F R A M E _ R ( 6 ) , r6
ld. q r5 , S A V E D _ T R 0 , r6
st. q S P , F R A M E _ R ( 1 8 ) , r18
st. q S P , F R A M E _ T ( 0 ) , r6
/* Keep old SP around */
getcon K C R 1 , r6
/* Save the rest of the general purpose registers */
st. q S P , F R A M E _ R ( 0 ) , r0
st. q S P , F R A M E _ R ( 1 ) , r1
st. q S P , F R A M E _ R ( 7 ) , r7
st. q S P , F R A M E _ R ( 8 ) , r8
st. q S P , F R A M E _ R ( 9 ) , r9
st. q S P , F R A M E _ R ( 1 0 ) , r10
st. q S P , F R A M E _ R ( 1 1 ) , r11
st. q S P , F R A M E _ R ( 1 2 ) , r12
st. q S P , F R A M E _ R ( 1 3 ) , r13
st. q S P , F R A M E _ R ( 1 4 ) , r14
/* SP is somewhere else */
st. q S P , F R A M E _ R ( 1 5 ) , r6
st. q S P , F R A M E _ R ( 1 6 ) , r16
st. q S P , F R A M E _ R ( 1 7 ) , r17
/* r18 is saved earlier. */
st. q S P , F R A M E _ R ( 1 9 ) , r19
st. q S P , F R A M E _ R ( 2 0 ) , r20
st. q S P , F R A M E _ R ( 2 1 ) , r21
st. q S P , F R A M E _ R ( 2 2 ) , r22
st. q S P , F R A M E _ R ( 2 3 ) , r23
st. q S P , F R A M E _ R ( 2 4 ) , r24
st. q S P , F R A M E _ R ( 2 5 ) , r25
st. q S P , F R A M E _ R ( 2 6 ) , r26
st. q S P , F R A M E _ R ( 2 7 ) , r27
st. q S P , F R A M E _ R ( 2 8 ) , r28
st. q S P , F R A M E _ R ( 2 9 ) , r29
st. q S P , F R A M E _ R ( 3 0 ) , r30
st. q S P , F R A M E _ R ( 3 1 ) , r31
st. q S P , F R A M E _ R ( 3 2 ) , r32
st. q S P , F R A M E _ R ( 3 3 ) , r33
st. q S P , F R A M E _ R ( 3 4 ) , r34
st. q S P , F R A M E _ R ( 3 5 ) , r35
st. q S P , F R A M E _ R ( 3 6 ) , r36
st. q S P , F R A M E _ R ( 3 7 ) , r37
st. q S P , F R A M E _ R ( 3 8 ) , r38
st. q S P , F R A M E _ R ( 3 9 ) , r39
st. q S P , F R A M E _ R ( 4 0 ) , r40
st. q S P , F R A M E _ R ( 4 1 ) , r41
st. q S P , F R A M E _ R ( 4 2 ) , r42
st. q S P , F R A M E _ R ( 4 3 ) , r43
st. q S P , F R A M E _ R ( 4 4 ) , r44
st. q S P , F R A M E _ R ( 4 5 ) , r45
st. q S P , F R A M E _ R ( 4 6 ) , r46
st. q S P , F R A M E _ R ( 4 7 ) , r47
st. q S P , F R A M E _ R ( 4 8 ) , r48
st. q S P , F R A M E _ R ( 4 9 ) , r49
st. q S P , F R A M E _ R ( 5 0 ) , r50
st. q S P , F R A M E _ R ( 5 1 ) , r51
st. q S P , F R A M E _ R ( 5 2 ) , r52
st. q S P , F R A M E _ R ( 5 3 ) , r53
st. q S P , F R A M E _ R ( 5 4 ) , r54
st. q S P , F R A M E _ R ( 5 5 ) , r55
st. q S P , F R A M E _ R ( 5 6 ) , r56
st. q S P , F R A M E _ R ( 5 7 ) , r57
st. q S P , F R A M E _ R ( 5 8 ) , r58
st. q S P , F R A M E _ R ( 5 9 ) , r59
st. q S P , F R A M E _ R ( 6 0 ) , r60
st. q S P , F R A M E _ R ( 6 1 ) , r61
st. q S P , F R A M E _ R ( 6 2 ) , r62
/ *
* Save t h e S * r e g i s t e r s .
* /
getcon S S R , r61
st. q S P , F R A M E _ S ( F S S R ) , r61
getcon S P C , r62
st. q S P , F R A M E _ S ( F S P C ) , r62
movi - 1 , r62 / * R e s e t s y s c a l l _ n r * /
st. q S P , F R A M E _ S ( F S Y S C A L L _ I D ) , r62
/* Save the rest of the target registers */
gettr t r1 , r6
st. q S P , F R A M E _ T ( 1 ) , r6
gettr t r2 , r6
st. q S P , F R A M E _ T ( 2 ) , r6
gettr t r3 , r6
st. q S P , F R A M E _ T ( 3 ) , r6
gettr t r4 , r6
st. q S P , F R A M E _ T ( 4 ) , r6
gettr t r5 , r6
st. q S P , F R A M E _ T ( 5 ) , r6
gettr t r6 , r6
st. q S P , F R A M E _ T ( 6 ) , r6
gettr t r7 , r6
st. q S P , F R A M E _ T ( 7 ) , r6
! setup F P s o t h a t u n w i n d e r c a n w i n d b a c k t h r o u g h n e s t e d k e r n e l m o d e
! exceptions
add S P , Z E R O , r14
# ifdef C O N F I G _ P O O R _ M A N S _ S T R A C E
/ * We' v e p u s h e d a l l t h e r e g i s t e r s n o w , s o o n l y r2 - r4 h o l d a n y t h i n g
* useful. M o v e t h e m i n t o c a l l e e s a v e r e g i s t e r s * /
or r2 , Z E R O , r28
or r3 , Z E R O , r29
or r4 , Z E R O , r30
/* Preserve r2 as the event code */
movi e v t _ d e b u g , r3
ori r3 , 1 , r3
ptabs r3 , t r0
or S P , Z E R O , r6
getcon T R A , r5
blink t r0 , L I N K
or r28 , Z E R O , r2
or r29 , Z E R O , r3
or r30 , Z E R O , r4
# endif
/* For syscall and debug race condition, get TRA now */
getcon T R A , r5
/ * We a r e i n a s a f e p o s i t i o n t o t u r n S R . B L o f f , b u t s e t I M A S K =0xf
* Also s e t F D , t o c a t c h F P U u s a g e i n t h e k e r n e l .
*
* benedict. g a s t e r @superh.com 29/07/2002
*
* On a l l S H 5 - 1 0 1 r e v i s i o n s i t i s u n s a f e t o r a i s e t h e I M A S K a n d a t t h e
* same t i m e c h a n g e B L f r o m 1 - > 0 , a s a n y p e n d i n g i n t e r r u p t o f a l e v e l
* higher t h a n h e p r e v i o u s v a l u e o f I M A S K w i l l l e a k t h r o u g h a n d b e
* taken u n e x p e c t e d l y .
*
* To a v o i d t h i s w e r a i s e t h e I M A S K a n d t h e n i s s u e a n o t h e r P U T C O N t o
* enable i n t e r r u p t s .
* /
getcon S R , r6
movi S R _ I M A S K | S R _ F D , r7
or r6 , r7 , r6
putcon r6 , S R
movi S R _ U N B L O C K _ E X C , r7
and r6 , r7 , r6
putcon r6 , S R
/* Now call the appropriate 3rd level handler */
or r3 , Z E R O , L I N K
movi t r a p _ j t a b l e , r3
shlri r2 , 3 , r2
ldx. l r2 , r3 , r3
shlri r2 , 2 , r2
ptabs r3 , t r0
or S P , Z E R O , r3
blink t r0 , Z E R O
/ *
* Second l e v e l h a n d l e r f o r V B R - b a s e d e x c e p t i o n s . P o s t - h a n d l e r s .
*
* Post- h a n d l e r s f o r i n t e r r u p t s ( r e t _ f r o m _ i r q ) , e x c e p t i o n s
* ( ret_ f r o m _ e x c e p t i o n ) a n d c o m m o n r e e n t r a n c e d o o r s ( r e s t o r e _ a l l
* to g e t b a c k t o t h e o r i g i n a l c o n t e x t , r e t _ f r o m _ s y s c a l l l o o p t o
* check k e r n e l e x i t i n g ) .
*
* ret_ w i t h _ r e s c h e d u l e a n d w o r k _ n o t i f y s i g a r e a n i n n e r l a b l e s o f
* the r e t _ f r o m _ s y s c a l l l o o p .
*
* In c o m m o n t o a l l s t a c k - f r a m e s e n s i t i v e h a n d l e r s .
*
* Inputs :
* ( SP) s t r u c t p t _ r e g s * , o r i g i n a l r e g i s t e r ' s f r a m e p o i n t e r ( b a s i c )
*
* /
.global ret_from_irq
ret_from_irq :
# ifdef C O N F I G _ P O O R _ M A N S _ S T R A C E
pta e v t _ d e b u g _ r e t _ f r o m _ i r q , t r0
ori S P , 0 , r2
blink t r0 , L I N K
# endif
ld. q S P , F R A M E _ S ( F S S R ) , r6
shlri r6 , 3 0 , r6
andi r6 , 1 , r6
pta r e s u m e _ k e r n e l , t r0
bne r6 , Z E R O , t r0 / * n o f u r t h e r c h e c k s * /
STI( )
pta r e t _ w i t h _ r e s c h e d u l e , t r0
blink t r0 , Z E R O / * D o n o t c h e c k s o f t i r q s * /
.global ret_from_exception
ret_from_exception :
preempt_ s t o p ( )
# ifdef C O N F I G _ P O O R _ M A N S _ S T R A C E
pta e v t _ d e b u g _ r e t _ f r o m _ e x c , t r0
ori S P , 0 , r2
blink t r0 , L I N K
# endif
ld. q S P , F R A M E _ S ( F S S R ) , r6
shlri r6 , 3 0 , r6
andi r6 , 1 , r6
pta r e s u m e _ k e r n e l , t r0
bne r6 , Z E R O , t r0 / * n o f u r t h e r c h e c k s * /
/* Check softirqs */
# ifdef C O N F I G _ P R E E M P T
pta r e t _ f r o m _ s y s c a l l , t r0
blink t r0 , Z E R O
resume_kernel :
pta r e s t o r e _ a l l , t r0
getcon K C R 0 , r6
ld. l r6 , T I _ P R E _ C O U N T , r7
beq/ u r7 , Z E R O , t r0
need_resched :
ld. l r6 , T I _ F L A G S , r7
movi ( 1 < < T I F _ N E E D _ R E S C H E D ) , r8
and r8 , r7 , r8
bne r8 , Z E R O , t r0
getcon S R , r7
andi r7 , 0 x f0 , r7
bne r7 , Z E R O , t r0
movi ( ( P R E E M P T _ A C T I V E > > 1 6 ) & 6 5 5 3 5 ) , r8
shori ( P R E E M P T _ A C T I V E & 6 5 5 3 5 ) , r8
st. l r6 , T I _ P R E _ C O U N T , r8
STI( )
movi s c h e d u l e , r7
ori r7 , 1 , r7
ptabs r7 , t r1
blink t r1 , L I N K
st. l r6 , T I _ P R E _ C O U N T , Z E R O
CLI( )
pta n e e d _ r e s c h e d , t r1
blink t r1 , Z E R O
# endif
.global ret_from_syscall
ret_from_syscall :
ret_with_reschedule :
getcon K C R 0 , r6 ! r6 c o n t a i n s c u r r e n t _ t h r e a d _ i n f o
ld. l r6 , T I _ F L A G S , r7 ! r7 c o n t a i n s c u r r e n t _ t h r e a d _ i n f o - > f l a g s
! FIXME : ! ! !
! no h a n d l i n g o f T I F _ S Y S C A L L _ T R A C E y e t ! !
2007-05-14 09:12:39 +09:00
movi _ T I F _ N E E D _ R E S C H E D , r8
2005-04-16 15:20:36 -07:00
and r8 , r7 , r8
pta w o r k _ r e s c h e d , t r0
bne r8 , Z E R O , t r0
pta r e s t o r e _ a l l , t r1
2007-05-14 09:12:39 +09:00
movi ( _ T I F _ S I G P E N D I N G | _ T I F _ R E S T O R E _ S I G M A S K ) , r8
2005-04-16 15:20:36 -07:00
and r8 , r7 , r8
pta w o r k _ n o t i f y s i g , t r0
bne r8 , Z E R O , t r0
blink t r1 , Z E R O
work_resched :
pta r e t _ f r o m _ s y s c a l l , t r0
gettr t r0 , L I N K
movi s c h e d u l e , r6
ptabs r6 , t r0
blink t r0 , Z E R O / * C a l l s c h e d u l e ( ) , r e t u r n o n t o p * /
work_notifysig :
gettr t r1 , L I N K
movi d o _ s i g n a l , r6
ptabs r6 , t r0
or S P , Z E R O , r2
or Z E R O , Z E R O , r3
blink t r0 , L I N K / * C a l l d o _ s i g n a l ( r e g s , 0 ) , r e t u r n h e r e * /
restore_all :
/* Do prefetches */
ld. q S P , F R A M E _ T ( 0 ) , r6
ld. q S P , F R A M E _ T ( 1 ) , r7
ld. q S P , F R A M E _ T ( 2 ) , r8
ld. q S P , F R A M E _ T ( 3 ) , r9
ptabs r6 , t r0
ptabs r7 , t r1
ptabs r8 , t r2
ptabs r9 , t r3
ld. q S P , F R A M E _ T ( 4 ) , r6
ld. q S P , F R A M E _ T ( 5 ) , r7
ld. q S P , F R A M E _ T ( 6 ) , r8
ld. q S P , F R A M E _ T ( 7 ) , r9
ptabs r6 , t r4
ptabs r7 , t r5
ptabs r8 , t r6
ptabs r9 , t r7
ld. q S P , F R A M E _ R ( 0 ) , r0
ld. q S P , F R A M E _ R ( 1 ) , r1
ld. q S P , F R A M E _ R ( 2 ) , r2
ld. q S P , F R A M E _ R ( 3 ) , r3
ld. q S P , F R A M E _ R ( 4 ) , r4
ld. q S P , F R A M E _ R ( 5 ) , r5
ld. q S P , F R A M E _ R ( 6 ) , r6
ld. q S P , F R A M E _ R ( 7 ) , r7
ld. q S P , F R A M E _ R ( 8 ) , r8
ld. q S P , F R A M E _ R ( 9 ) , r9
ld. q S P , F R A M E _ R ( 1 0 ) , r10
ld. q S P , F R A M E _ R ( 1 1 ) , r11
ld. q S P , F R A M E _ R ( 1 2 ) , r12
ld. q S P , F R A M E _ R ( 1 3 ) , r13
ld. q S P , F R A M E _ R ( 1 4 ) , r14
ld. q S P , F R A M E _ R ( 1 6 ) , r16
ld. q S P , F R A M E _ R ( 1 7 ) , r17
ld. q S P , F R A M E _ R ( 1 8 ) , r18
ld. q S P , F R A M E _ R ( 1 9 ) , r19
ld. q S P , F R A M E _ R ( 2 0 ) , r20
ld. q S P , F R A M E _ R ( 2 1 ) , r21
ld. q S P , F R A M E _ R ( 2 2 ) , r22
ld. q S P , F R A M E _ R ( 2 3 ) , r23
ld. q S P , F R A M E _ R ( 2 4 ) , r24
ld. q S P , F R A M E _ R ( 2 5 ) , r25
ld. q S P , F R A M E _ R ( 2 6 ) , r26
ld. q S P , F R A M E _ R ( 2 7 ) , r27
ld. q S P , F R A M E _ R ( 2 8 ) , r28
ld. q S P , F R A M E _ R ( 2 9 ) , r29
ld. q S P , F R A M E _ R ( 3 0 ) , r30
ld. q S P , F R A M E _ R ( 3 1 ) , r31
ld. q S P , F R A M E _ R ( 3 2 ) , r32
ld. q S P , F R A M E _ R ( 3 3 ) , r33
ld. q S P , F R A M E _ R ( 3 4 ) , r34
ld. q S P , F R A M E _ R ( 3 5 ) , r35
ld. q S P , F R A M E _ R ( 3 6 ) , r36
ld. q S P , F R A M E _ R ( 3 7 ) , r37
ld. q S P , F R A M E _ R ( 3 8 ) , r38
ld. q S P , F R A M E _ R ( 3 9 ) , r39
ld. q S P , F R A M E _ R ( 4 0 ) , r40
ld. q S P , F R A M E _ R ( 4 1 ) , r41
ld. q S P , F R A M E _ R ( 4 2 ) , r42
ld. q S P , F R A M E _ R ( 4 3 ) , r43
ld. q S P , F R A M E _ R ( 4 4 ) , r44
ld. q S P , F R A M E _ R ( 4 5 ) , r45
ld. q S P , F R A M E _ R ( 4 6 ) , r46
ld. q S P , F R A M E _ R ( 4 7 ) , r47
ld. q S P , F R A M E _ R ( 4 8 ) , r48
ld. q S P , F R A M E _ R ( 4 9 ) , r49
ld. q S P , F R A M E _ R ( 5 0 ) , r50
ld. q S P , F R A M E _ R ( 5 1 ) , r51
ld. q S P , F R A M E _ R ( 5 2 ) , r52
ld. q S P , F R A M E _ R ( 5 3 ) , r53
ld. q S P , F R A M E _ R ( 5 4 ) , r54
ld. q S P , F R A M E _ R ( 5 5 ) , r55
ld. q S P , F R A M E _ R ( 5 6 ) , r56
ld. q S P , F R A M E _ R ( 5 7 ) , r57
ld. q S P , F R A M E _ R ( 5 8 ) , r58
getcon S R , r59
movi S R _ B L O C K _ E X C , r60
or r59 , r60 , r59
putcon r59 , S R / * S R . B L = 1 , k e e p n e s t i n g o u t * /
ld. q S P , F R A M E _ S ( F S S R ) , r61
ld. q S P , F R A M E _ S ( F S P C ) , r62
movi S R _ A S I D _ M A S K , r60
and r59 , r60 , r59
andc r61 , r60 , r61 / * C l e a r o u t o l d e r A S I D * /
or r59 , r61 , r61 / * R e t a i n c u r r e n t A S I D * /
putcon r61 , S S R
putcon r62 , S P C
/* Ignore FSYSCALL_ID */
ld. q S P , F R A M E _ R ( 5 9 ) , r59
ld. q S P , F R A M E _ R ( 6 0 ) , r60
ld. q S P , F R A M E _ R ( 6 1 ) , r61
ld. q S P , F R A M E _ R ( 6 2 ) , r62
/* Last touch */
ld. q S P , F R A M E _ R ( 1 5 ) , S P
rte
nop
/ *
* Third l e v e l h a n d l e r s f o r V B R - b a s e d e x c e p t i o n s . A d a p t i n g a r g s t o
* and/ o r d e f l e c t i n g t o f o u r t h l e v e l h a n d l e r s .
*
* Fourth l e v e l h a n d l e r s i n t e r f a c e .
* Most a r e C - c o d e d h a n d l e r s d i r e c t l y p o i n t e d b y t h e t r a p _ j t a b l e .
* ( Third = F o u r t h l e v e l )
* Inputs :
* ( r2 ) f a u l t / i n t e r r u p t c o d e , e n t r y n u m b e r ( e . g . N M I = 1 4 ,
* IRL0 - 3 ( 0 0 0 0 ) = 1 6 , R T L B M I S S = 2 , S Y S C A L L = 1 1 , e t c . . . )
* ( r3 ) s t r u c t p t _ r e g s * , o r i g i n a l r e g i s t e r ' s f r a m e p o i n t e r
* ( r4 ) E v e n t ( 0 = i n t e r r u p t , 1 = T L B m i s s f a u l t , 2 = N o t T L B m i s s f a u l t )
* ( r5 ) T R A c o n t r o l r e g i s t e r ( f o r s y s c a l l / d e b u g b e n e f i t o n l y )
* ( LINK) r e t u r n a d d r e s s
* ( SP) = r3
*
* Kernel T L B f a u l t h a n d l e r s w i l l g e t a s l i g h t l y d i f f e r e n t i n t e r f a c e .
* ( r2 ) s t r u c t p t _ r e g s * , o r i g i n a l r e g i s t e r ' s f r a m e p o i n t e r
* ( r3 ) w r i t e a c c e s s , w h e t h e r i t ' s a s t o r e f a u l t a s o p p o s e d t o l o a d f a u l t
* ( r4 ) e x e c a c c e s s , w h e t h e r i t ' s a I T L B f a u l t a s o p p o s e d t o D T L B f a u l t
* ( r5 ) E f f e c t i v e A d d r e s s o f f a u l t
* ( LINK) r e t u r n a d d r e s s
* ( SP) = r2
*
* fpu_ e r r o r _ o r _ I R Q ? i s a h e l p e r t o d e f l e c t t o t h e r i g h t c a u s e .
*
* /
tlb_miss_load :
or S P , Z E R O , r2
or Z E R O , Z E R O , r3 / * R e a d * /
or Z E R O , Z E R O , r4 / * D a t a * /
getcon T E A , r5
pta c a l l _ d o _ p a g e _ f a u l t , t r0
beq Z E R O , Z E R O , t r0
tlb_miss_store :
or S P , Z E R O , r2
movi 1 , r3 / * W r i t e * /
or Z E R O , Z E R O , r4 / * D a t a * /
getcon T E A , r5
pta c a l l _ d o _ p a g e _ f a u l t , t r0
beq Z E R O , Z E R O , t r0
itlb_miss_or_IRQ :
pta i t s _ I R Q , t r0
beqi/ u r4 , E V E N T _ I N T E R R U P T , t r0
or S P , Z E R O , r2
or Z E R O , Z E R O , r3 / * R e a d * /
movi 1 , r4 / * T e x t * /
getcon T E A , r5
/* Fall through */
call_do_page_fault :
movi d o _ p a g e _ f a u l t , r6
ptabs r6 , t r0
blink t r0 , Z E R O
fpu_error_or_IRQA :
pta i t s _ I R Q , t r0
beqi/ l r4 , E V E N T _ I N T E R R U P T , t r0
# ifdef C O N F I G _ S H _ F P U
movi d o _ f p u _ s t a t e _ r e s t o r e , r6
# else
movi d o _ e x c e p t i o n _ e r r o r , r6
# endif
ptabs r6 , t r0
blink t r0 , Z E R O
fpu_error_or_IRQB :
pta i t s _ I R Q , t r0
beqi/ l r4 , E V E N T _ I N T E R R U P T , t r0
# ifdef C O N F I G _ S H _ F P U
movi d o _ f p u _ s t a t e _ r e s t o r e , r6
# else
movi d o _ e x c e p t i o n _ e r r o r , r6
# endif
ptabs r6 , t r0
blink t r0 , Z E R O
its_IRQ :
movi d o _ I R Q , r6
ptabs r6 , t r0
blink t r0 , Z E R O
/ *
* system_ c a l l / u n k n o w n _ t r a p t h i r d l e v e l h a n d l e r :
*
* Inputs :
* ( r2 ) f a u l t / i n t e r r u p t c o d e , e n t r y n u m b e r ( T R A P = 1 1 )
* ( r3 ) s t r u c t p t _ r e g s * , o r i g i n a l r e g i s t e r ' s f r a m e p o i n t e r
* ( r4 ) N o t u s e d . E v e n t ( 0 =interrupt , 1 =TLB m i s s f a u l t , 2 =Not T L B m i s s f a u l t )
* ( r5 ) T R A C o n t r o l R e g ( 0 x00 x y z z z z : x =1 S Y S C A L L , y = #a r g s , z = n r )
* ( SP) = r3
* ( LINK) r e t u r n a d d r e s s : r e t _ f r o m _ e x c e p t i o n
* ( * r3 ) S y s c a l l p a r m s : S C #, a r g 0 , a r g 1 , . . . , a r g 5 i n o r d e r ( S a v e d r2 / r7 )
*
* Outputs :
* ( * r3 ) S y s c a l l r e p l y ( S a v e d r2 )
* ( LINK) I n c a s e o f s y s c a l l o n l y i t c a n b e s c r a p p e d .
* Common s e c o n d l e v e l p o s t h a n d l e r w i l l b e r e t _ f r o m _ s y s c a l l .
* Common ( n o n - t r a c e ) e x i t p o i n t t o t h a t i s s y s c a l l _ r e t ( s a v i n g
* result t o r2 ) . C o m m o n b a d e x i t p o i n t i s s y s c a l l _ b a d ( r e t u r n i n g
* ENOSYS t h e n s a v e d t o r2 ) .
*
* /
unknown_trap :
/* Unknown Trap or User Trace */
movi d o _ u n k n o w n _ t r a p a , r6
ptabs r6 , t r0
ld. q r3 , F R A M E _ R ( 9 ) , r2 / * r2 = #a r g < < 16 | s y s c a l l # * /
andi r2 , 0 x1 f f , r2 / * r2 = s y s c a l l # * /
blink t r0 , L I N K
pta s y s c a l l _ r e t , t r0
blink t r0 , Z E R O
/* New syscall implementation*/
system_call :
pta u n k n o w n _ t r a p , t r0
or r5 , Z E R O , r4 / * T R A ( =r5 ) - > r4 * /
shlri r4 , 2 0 , r4
bnei r4 , 1 , t r0 / * u n k n o w n _ t r a p i f n o t 0 x1 y z z z z * /
/* It's a system call */
st. q r3 , F R A M E _ S ( F S Y S C A L L _ I D ) , r5 / * I D ( 0 x1 y z z z z ) - > s t a c k * /
andi r5 , 0 x1 f f , r5 / * s y s c a l l # - > r 5 * /
STI( )
pta s y s c a l l _ a l l o w e d , t r0
movi N R _ s y s c a l l s - 1 , r4 / * L a s t v a l i d * /
bgeu/ l r4 , r5 , t r0
syscall_bad :
/* Return ENOSYS ! */
movi - ( E N O S Y S ) , r2 / * F a l l - t h r o u g h * /
.global syscall_ret
syscall_ret :
st. q S P , F R A M E _ R ( 9 ) , r2 / * E x p e c t i n g S P b a c k t o B A S I C f r a m e * /
# ifdef C O N F I G _ P O O R _ M A N S _ S T R A C E
/* nothing useful in registers at this point */
movi e v t _ d e b u g 2 , r5
ori r5 , 1 , r5
ptabs r5 , t r0
ld. q S P , F R A M E _ R ( 9 ) , r2
or S P , Z E R O , r3
blink t r0 , L I N K
# endif
ld. q S P , F R A M E _ S ( F S P C ) , r2
addi r2 , 4 , r2 / * M o v e P C , b e i n g p r e - e x e c u t i o n e v e n t * /
st. q S P , F R A M E _ S ( F S P C ) , r2
pta r e t _ f r o m _ s y s c a l l , t r0
blink t r0 , Z E R O
/ * A d i f f e r e n t r e t u r n p a t h f o r r e t _ f r o m _ f o r k , b e c a u s e w e n o w n e e d
* to c a l l s c h e d u l e _ t a i l w i t h t h e l a t e r k e r n e l s . B e c a u s e p r e v i s
* loaded i n t o r2 b y s w i t c h _ t o ( ) m e a n s w e c a n j u s t c a l l i t s t r a i g h t a w a y
* /
.global ret_from_fork
ret_from_fork :
movi s c h e d u l e _ t a i l ,r5
ori r5 , 1 , r5
ptabs r5 , t r0
blink t r0 , L I N K
# ifdef C O N F I G _ P O O R _ M A N S _ S T R A C E
/* nothing useful in registers at this point */
movi e v t _ d e b u g 2 , r5
ori r5 , 1 , r5
ptabs r5 , t r0
ld. q S P , F R A M E _ R ( 9 ) , r2
or S P , Z E R O , r3
blink t r0 , L I N K
# endif
ld. q S P , F R A M E _ S ( F S P C ) , r2
addi r2 , 4 , r2 / * M o v e P C , b e i n g p r e - e x e c u t i o n e v e n t * /
st. q S P , F R A M E _ S ( F S P C ) , r2
pta r e t _ f r o m _ s y s c a l l , t r0
blink t r0 , Z E R O
syscall_allowed :
/* Use LINK to deflect the exit point, default is syscall_ret */
pta s y s c a l l _ r e t , t r0
gettr t r0 , L I N K
pta s y s c a l l _ n o t r a c e , t r0
getcon K C R 0 , r2
ld. l r2 , T I _ F L A G S , r4
movi ( 1 < < T I F _ S Y S C A L L _ T R A C E ) , r6
and r6 , r4 , r6
beq/ l r6 , Z E R O , t r0
/* Trace it by calling syscall_trace before and after */
movi s y s c a l l _ t r a c e , r4
ptabs r4 , t r0
blink t r0 , L I N K
/* Reload syscall number as r5 is trashed by syscall_trace */
ld. q S P , F R A M E _ S ( F S Y S C A L L _ I D ) , r5
andi r5 , 0 x1 f f , r5
pta s y s c a l l _ r e t _ t r a c e , t r0
gettr t r0 , L I N K
syscall_notrace :
/* Now point to the appropriate 4th level syscall handler */
movi s y s _ c a l l _ t a b l e , r4
shlli r5 , 2 , r5
ldx. l r4 , r5 , r5
ptabs r5 , t r0
/* Prepare original args */
ld. q S P , F R A M E _ R ( 2 ) , r2
ld. q S P , F R A M E _ R ( 3 ) , r3
ld. q S P , F R A M E _ R ( 4 ) , r4
ld. q S P , F R A M E _ R ( 5 ) , r5
ld. q S P , F R A M E _ R ( 6 ) , r6
ld. q S P , F R A M E _ R ( 7 ) , r7
/* And now the trick for those syscalls requiring regs * ! */
or S P , Z E R O , r8
/* Call it */
blink t r0 , Z E R O / * L I N K i s a l r e a d y p r o p e r l y s e t * /
syscall_ret_trace :
/* We get back here only if under trace */
st. q S P , F R A M E _ R ( 9 ) , r2 / * S a v e r e t u r n v a l u e * /
movi s y s c a l l _ t r a c e , L I N K
ptabs L I N K , t r0
blink t r0 , L I N K
/* This needs to be done after any syscall tracing */
ld. q S P , F R A M E _ S ( F S P C ) , r2
addi r2 , 4 , r2 / * M o v e P C , b e i n g p r e - e x e c u t i o n e v e n t * /
st. q S P , F R A M E _ S ( F S P C ) , r2
pta r e t _ f r o m _ s y s c a l l , t r0
blink t r0 , Z E R O / * R e s u m e n o r m a l r e t u r n s e q u e n c e * /
/ *
* - - - Switch t o r u n n i n g u n d e r a p a r t i c u l a r A S I D a n d r e t u r n t h e p r e v i o u s A S I D v a l u e
* - - - The c a l l e r i s a s s u m e d t o h a v e d o n e a c l i b e f o r e c a l l i n g t h i s .
*
* Input r2 : n e w A S I D
* Output r2 : o l d A S I D
* /
.global switch_and_save_asid
switch_and_save_asid :
getcon s r , r0
movi 2 5 5 , r4
shlli r4 , 1 6 , r4 / * r4 = m a s k t o s e l e c t A S I D * /
and r0 , r4 , r3 / * r3 = s h i f t e d o l d A S I D * /
andi r2 , 2 5 5 , r2 / * m a s k d o w n n e w A S I D * /
shlli r2 , 1 6 , r2 / * a l i g n n e w A S I D a g a i n s t S R . A S I D * /
andc r0 , r4 , r0 / * e f f a c e o l d A S I D f r o m S R * /
or r0 , r2 , r0 / * i n s e r t t h e n e w A S I D * /
putcon r0 , s s r
movi 1 f , r0
putcon r0 , s p c
rte
nop
1 :
ptabs L I N K , t r0
shlri r3 , 1 6 , r2 / * r2 = o l d A S I D * /
blink t r0 , r63
.global route_to_panic_handler
route_to_panic_handler :
/ * Switch t o r e a l m o d e , g o t o p a n i c _ h a n d l e r , d o n ' t r e t u r n . U s e f u l f o r
last- c h a n c e d e b u g g i n g , e . g . i f n o o u t p u t w a n t s t o g o t o t h e c o n s o l e .
* /
movi p a n i c _ h a n d l e r - C O N F I G _ C A C H E D _ M E M O R Y _ O F F S E T , r1
ptabs r1 , t r0
pta 1 f , t r1
gettr t r1 , r0
putcon r0 , s p c
getcon s r , r0
movi 1 , r1
shlli r1 , 3 1 , r1
andc r0 , r1 , r0
putcon r0 , s s r
rte
nop
1 : /* Now in real mode */
blink t r0 , r63
nop
.global peek_real_address_q
peek_real_address_q :
/ * Two a r g s :
r2 : r e a l m o d e a d d r e s s t o p e e k
r2 ( o u t ) : r e s u l t q u a d w o r d
This i s p r o v i d e d a s a c h e a p s k a t e w a y o f m a n i p u l a t i n g d e v i c e
registers f o r d e b u g g i n g ( t o a v o i d t h e n e e d t o o n c h i p _ r e m a p t h e d e b u g
module, a n d t o a v o i d t h e n e e d t o o n c h i p _ r e m a p t h e w a t c h p o i n t
controller i n a w a y t h a t i d e n t i t y m a p s s u f f i c i e n t b i t s t o a v o i d t h e
SH5 - 1 0 1 c u t 2 s i l i c o n d e f e c t ) .
This c o d e i s n o t p e r f o r m a n c e c r i t i c a l
* /
add. l r2 , r63 , r2 / * s i g n e x t e n d a d d r e s s * /
getcon s r , r0 / * r0 = s a v e d o r i g i n a l S R * /
movi 1 , r1
shlli r1 , 2 8 , r1
or r0 , r1 , r1 / * r0 w i t h b l o c k b i t s e t * /
putcon r1 , s r / * n o w i n c r i t i c a l s e c t i o n * /
movi 1 , r36
shlli r36 , 3 1 , r36
andc r1 , r36 , r1 / * t u r n s r . m m u o f f i n r e a l m o d e s e c t i o n * /
putcon r1 , s s r
movi . p e e k 0 - C O N F I G _ C A C H E D _ M E M O R Y _ O F F S E T , r36 / * r e a l m o d e t a r g e t a d d r e s s * /
movi 1 f , r37 / * v i r t u a l m o d e r e t u r n a d d r * /
putcon r36 , s p c
synco
rte
nop
.peek0 : / * come h e r e i n r e a l m o d e , d o n ' t t o u c h c a c h e s ! !
still i n c r i t i c a l s e c t i o n ( s r . b l = =1 ) * /
putcon r0 , s s r
putcon r37 , s p c
/ * Here' s t h e a c t u a l p e e k . I f t h e a d d r e s s i s b a d , a l l b e t s a r e n o w o f f
* what w i l l h a p p e n ( h a n d l e r s i n v o k e d i n r e a l - m o d e = b a d n e w s ) * /
ld. q r2 , 0 , r2
synco
rte / * B a c k t o v i r t u a l m o d e * /
nop
1 :
ptabs L I N K , t r0
blink t r0 , r63
.global poke_real_address_q
poke_real_address_q :
/ * Two a r g s :
r2 : r e a l m o d e a d d r e s s t o p o k e
r3 : q u a d w o r d v a l u e t o w r i t e .
This i s p r o v i d e d a s a c h e a p s k a t e w a y o f m a n i p u l a t i n g d e v i c e
registers f o r d e b u g g i n g ( t o a v o i d t h e n e e d t o o n c h i p _ r e m a p t h e d e b u g
module, a n d t o a v o i d t h e n e e d t o o n c h i p _ r e m a p t h e w a t c h p o i n t
controller i n a w a y t h a t i d e n t i t y m a p s s u f f i c i e n t b i t s t o a v o i d t h e
SH5 - 1 0 1 c u t 2 s i l i c o n d e f e c t ) .
This c o d e i s n o t p e r f o r m a n c e c r i t i c a l
* /
add. l r2 , r63 , r2 / * s i g n e x t e n d a d d r e s s * /
getcon s r , r0 / * r0 = s a v e d o r i g i n a l S R * /
movi 1 , r1
shlli r1 , 2 8 , r1
or r0 , r1 , r1 / * r0 w i t h b l o c k b i t s e t * /
putcon r1 , s r / * n o w i n c r i t i c a l s e c t i o n * /
movi 1 , r36
shlli r36 , 3 1 , r36
andc r1 , r36 , r1 / * t u r n s r . m m u o f f i n r e a l m o d e s e c t i o n * /
putcon r1 , s s r
movi . p o k e 0 - C O N F I G _ C A C H E D _ M E M O R Y _ O F F S E T , r36 / * r e a l m o d e t a r g e t a d d r e s s * /
movi 1 f , r37 / * v i r t u a l m o d e r e t u r n a d d r * /
putcon r36 , s p c
synco
rte
nop
.poke0 : / * come h e r e i n r e a l m o d e , d o n ' t t o u c h c a c h e s ! !
still i n c r i t i c a l s e c t i o n ( s r . b l = =1 ) * /
putcon r0 , s s r
putcon r37 , s p c
/ * Here' s t h e a c t u a l p o k e . I f t h e a d d r e s s i s b a d , a l l b e t s a r e n o w o f f
* what w i l l h a p p e n ( h a n d l e r s i n v o k e d i n r e a l - m o d e = b a d n e w s ) * /
st. q r2 , 0 , r3
synco
rte / * B a c k t o v i r t u a l m o d e * /
nop
1 :
ptabs L I N K , t r0
blink t r0 , r63
/ *
* - - - User A c c e s s H a n d l i n g S e c t i o n
* /
/ *
* User A c c e s s s u p p o r t . I t a l l m o v e d t o n o n i n l i n e d A s s e m b l e r
* functions i n h e r e .
*
* _ _ kernel_ s i z e _ t _ _ c o p y _ u s e r ( v o i d * _ _ t o , c o n s t v o i d * _ _ f r o m ,
* _ _ kernel_ s i z e _ t _ _ n )
*
* Inputs :
* ( r2 ) t a r g e t a d d r e s s
* ( r3 ) s o u r c e a d d r e s s
* ( r4 ) s i z e i n b y t e s
*
* Ouputs :
* ( * r2 ) t a r g e t d a t a
* ( r2 ) n o n - c o p i e d b y t e s
*
* If a f a u l t o c c u r s o n t h e u s e r p o i n t e r , b a i l o u t e a r l y a n d r e t u r n t h e
* number o f b y t e s n o t c o p i e d i n r2 .
* Strategy : f o r l a r g e b l o c k s , c a l l a r e a l m e m c p y f u n c t i o n w h i c h c a n
* move > 1 b y t e a t a t i m e u s i n g u n a l i g n e d l d / s t i n s t r u c t i o n s , a n d c a n
* manipulate t h e c a c h e u s i n g p r e f e t c h + a l l o c o t o i m p r o v e t h e s p e e d
* further. I f a f a u l t o c c u r s i n t h a t f u n c t i o n , j u s t r e v e r t t o t h e
* byte- b y - b y t e a p p r o a c h u s e d f o r s m a l l b l o c k s ; this is rare so the
* performance h i t f o r t h a t c a s e d o e s n o t m a t t e r .
*
* For s m a l l b l o c k s i t ' s n o t w o r t h t h e o v e r h e a d o f s e t t i n g u p a n d c a l l i n g
* the m e m c p y r o u t i n e ; do the copy a byte at a time.
*
* /
.global __copy_user
__copy_user :
pta _ _ c o p y _ u s e r _ b y t e _ b y _ b y t e , t r1
movi 1 6 , r0 ! t h i s v a l u e i s a b e s t g u e s s , s h o u l d t u n e i t b y b e n c h m a r k i n g
bge/ u r0 , r4 , t r1
pta c o p y _ u s e r _ m e m c p y , t r0
addi S P , - 3 2 , S P
/* Save arguments in case we have to fix-up unhandled page fault */
st. q S P , 0 , r2
st. q S P , 8 , r3
st. q S P , 1 6 , r4
st. q S P , 2 4 , r35 ! r35 i s c a l l e e - s a v e
/ * Save L I N K i n a r e g i s t e r t o r e d u c e R T S t i m e l a t e r ( o t h e r w i s e
ld S P ,* ,L I N K ;ptabs LINK;trn;blink trn,r63 becomes a critical path) */
ori L I N K , 0 , r35
blink t r0 , L I N K
/* Copy completed normally if we get back here */
ptabs r35 , t r0
ld. q S P , 2 4 , r35
/* don't restore r2-r4, pointless */
/* set result=r2 to zero as the copy must have succeeded. */
or r63 , r63 , r2
addi S P , 3 2 , S P
blink t r0 , r63 ! R T S
.global __copy_user_fixup
__copy_user_fixup :
/* Restore stack frame */
ori r35 , 0 , L I N K
ld. q S P , 2 4 , r35
ld. q S P , 1 6 , r4
ld. q S P , 8 , r3
ld. q S P , 0 , r2
addi S P , 3 2 , S P
/* Fall through to original code, in the 'same' state we entered with */
/ * The s l o w b y t e - b y - b y t e m e t h o d i s u s e d i f t h e f a s t c o p y t r a p s d u e t o a b a d
user a d d r e s s . I n t h a t r a r e c a s e , t h e s p e e d d r o p c a n b e t o l e r a t e d . * /
__copy_user_byte_by_byte :
pta _ _ _ c o p y _ u s e r _ e x i t , t r1
pta _ _ _ c o p y _ u s e r1 , t r0
beq/ u r4 , r63 , t r1 / * e a r l y e x i t f o r z e r o l e n g t h c o p y * /
sub r2 , r3 , r0
addi r0 , - 1 , r0
___copy_user1 :
ld. b r3 , 0 , r5 / * F a u l t a d d r e s s 1 * /
/ * Could r e w r i t e t h i s t o u s e j u s t 1 a d d , b u t t h e s e c o n d c o m e s ' f r e e '
due t o l o a d l a t e n c y * /
addi r3 , 1 , r3
addi r4 , - 1 , r4 / * N o r e a l f i x u p r e q u i r e d * /
___copy_user2 :
stx. b r3 , r0 , r5 / * F a u l t a d d r e s s 2 * /
bne r4 , Z E R O , t r0
___copy_user_exit :
or r4 , Z E R O , r2
ptabs L I N K , t r0
blink t r0 , Z E R O
/ *
* _ _ kernel_ s i z e _ t _ _ c l e a r _ u s e r ( v o i d * a d d r , _ _ k e r n e l _ s i z e _ t s i z e )
*
* Inputs :
* ( r2 ) t a r g e t a d d r e s s
* ( r3 ) s i z e i n b y t e s
*
* Ouputs :
* ( * r2 ) z e r o - e d t a r g e t d a t a
* ( r2 ) n o n - z e r o - e d b y t e s
* /
.global __clear_user
__clear_user :
pta _ _ _ c l e a r _ u s e r _ e x i t , t r1
pta _ _ _ c l e a r _ u s e r1 , t r0
beq/ u r3 , r63 , t r1
___clear_user1 :
st. b r2 , 0 , Z E R O / * F a u l t a d d r e s s * /
addi r2 , 1 , r2
addi r3 , - 1 , r3 / * N o r e a l f i x u p r e q u i r e d * /
bne r3 , Z E R O , t r0
___clear_user_exit :
or r3 , Z E R O , r2
ptabs L I N K , t r0
blink t r0 , Z E R O
/ *
* int _ _ s t r n c p y _ f r o m _ u s e r ( u n s i g n e d l o n g _ _ d e s t , u n s i g n e d l o n g _ _ s r c ,
* int _ _ c o u n t )
*
* Inputs :
* ( r2 ) t a r g e t a d d r e s s
* ( r3 ) s o u r c e a d d r e s s
* ( r4 ) m a x i m u m s i z e i n b y t e s
*
* Ouputs :
* ( * r2 ) c o p i e d d a t a
* ( r2 ) - E F A U L T ( i n c a s e o f f a u l t i n g )
* copied d a t a ( o t h e r w i s e )
* /
.global __strncpy_from_user
__strncpy_from_user :
pta _ _ _ s t r n c p y _ f r o m _ u s e r1 , t r0
pta _ _ _ s t r n c p y _ f r o m _ u s e r _ d o n e , t r1
or r4 , Z E R O , r5 / * r5 = o r i g i n a l c o u n t * /
beq/ u r4 , r63 , t r1 / * e a r l y e x i t i f r4 = =0 * /
movi - ( E F A U L T ) , r6 / * r6 = r e p l y , n o r e a l f i x u p * /
or Z E R O , Z E R O , r7 / * r7 = d a t a , c l e a r t o p b y t e o f d a t a * /
___strncpy_from_user1 :
ld. b r3 , 0 , r7 / * F a u l t a d d r e s s : o n l y i n r e a d i n g * /
st. b r2 , 0 , r7
addi r2 , 1 , r2
addi r3 , 1 , r3
beq/ u Z E R O , r7 , t r1
addi r4 , - 1 , r4 / * r e t u r n r e a l n u m b e r o f c o p i e d b y t e s * /
bne/ l Z E R O , r4 , t r0
___strncpy_from_user_done :
sub r5 , r4 , r6 / * I f d o n e , r e t u r n c o p i e d * /
___strncpy_from_user_exit :
or r6 , Z E R O , r2
ptabs L I N K , t r0
blink t r0 , Z E R O
/ *
* extern l o n g _ _ s t r n l e n _ u s e r ( c o n s t c h a r * _ _ s , l o n g _ _ n )
*
* Inputs :
* ( r2 ) s o u r c e a d d r e s s
* ( r3 ) s o u r c e s i z e i n b y t e s
*
* Ouputs :
* ( r2 ) - E F A U L T ( i n c a s e o f f a u l t i n g )
* string l e n g t h ( o t h e r w i s e )
* /
.global __strnlen_user
__strnlen_user :
pta _ _ _ s t r n l e n _ u s e r _ s e t _ r e p l y , t r0
pta _ _ _ s t r n l e n _ u s e r1 , t r1
or Z E R O , Z E R O , r5 / * r5 = c o u n t e r * /
movi - ( E F A U L T ) , r6 / * r6 = r e p l y , n o r e a l f i x u p * /
or Z E R O , Z E R O , r7 / * r7 = d a t a , c l e a r t o p b y t e o f d a t a * /
beq r3 , Z E R O , t r0
___strnlen_user1 :
ldx. b r2 , r5 , r7 / * F a u l t a d d r e s s : o n l y i n r e a d i n g * /
addi r3 , - 1 , r3 / * N o r e a l f i x u p * /
addi r5 , 1 , r5
beq r3 , Z E R O , t r0
bne r7 , Z E R O , t r1
! The l i n e b e l o w u s e d t o b e a c t i v e . T h i s m e a n t l e d t o a j u n k b y t e l y i n g b e t w e e n e a c h p a i r
! of e n t r i e s i n t h e a r g v & e n v p s t r u c t u r e s i n m e m o r y . W h i l s t t h e p r o g r a m s a w t h e r i g h t d a t a
! via t h e a r g v a n d e n v p a r g u m e n t s t o m a i n , i t m e a n t t h e ' f l a t ' r e p r e s e n t a t i o n v i s i b l e t h r o u g h
! / proc/ $ p i d / c m d l i n e w a s c o r r u p t , c a u s i n g t r o u b l e w i t h p s , f o r e x a m p l e .
! addi r5 , 1 , r5 / * I n c l u d e ' \ 0 ' * /
___strnlen_user_set_reply :
or r5 , Z E R O , r6 / * I f d o n e , r e t u r n c o u n t e r * /
___strnlen_user_exit :
or r6 , Z E R O , r2
ptabs L I N K , t r0
blink t r0 , Z E R O
/ *
* extern l o n g _ _ g e t _ u s e r _ a s m _ ? ( v o i d * v a l , l o n g a d d r )
*
* Inputs :
* ( r2 ) d e s t a d d r e s s
* ( r3 ) s o u r c e a d d r e s s ( i n U s e r S p a c e )
*
* Ouputs :
* ( r2 ) - E F A U L T ( f a u l t i n g )
* 0 ( not f a u l t i n g )
* /
.global __get_user_asm_b
__get_user_asm_b :
or r2 , Z E R O , r4
movi - ( E F A U L T ) , r2 / * r2 = r e p l y , n o r e a l f i x u p * /
___get_user_asm_b1 :
ld. b r3 , 0 , r5 / * r5 = d a t a * /
st. b r4 , 0 , r5
or Z E R O , Z E R O , r2
___get_user_asm_b_exit :
ptabs L I N K , t r0
blink t r0 , Z E R O
.global __get_user_asm_w
__get_user_asm_w :
or r2 , Z E R O , r4
movi - ( E F A U L T ) , r2 / * r2 = r e p l y , n o r e a l f i x u p * /
___get_user_asm_w1 :
ld. w r3 , 0 , r5 / * r5 = d a t a * /
st. w r4 , 0 , r5
or Z E R O , Z E R O , r2
___get_user_asm_w_exit :
ptabs L I N K , t r0
blink t r0 , Z E R O
.global __get_user_asm_l
__get_user_asm_l :
or r2 , Z E R O , r4
movi - ( E F A U L T ) , r2 / * r2 = r e p l y , n o r e a l f i x u p * /
___get_user_asm_l1 :
ld. l r3 , 0 , r5 / * r5 = d a t a * /
st. l r4 , 0 , r5
or Z E R O , Z E R O , r2
___get_user_asm_l_exit :
ptabs L I N K , t r0
blink t r0 , Z E R O
.global __get_user_asm_q
__get_user_asm_q :
or r2 , Z E R O , r4
movi - ( E F A U L T ) , r2 / * r2 = r e p l y , n o r e a l f i x u p * /
___get_user_asm_q1 :
ld. q r3 , 0 , r5 / * r5 = d a t a * /
st. q r4 , 0 , r5
or Z E R O , Z E R O , r2
___get_user_asm_q_exit :
ptabs L I N K , t r0
blink t r0 , Z E R O
/ *
* extern l o n g _ _ p u t _ u s e r _ a s m _ ? ( v o i d * p v a l , l o n g a d d r )
*
* Inputs :
* ( r2 ) k e r n e l p o i n t e r t o v a l u e
* ( r3 ) d e s t a d d r e s s ( i n U s e r S p a c e )
*
* Ouputs :
* ( r2 ) - E F A U L T ( f a u l t i n g )
* 0 ( not f a u l t i n g )
* /
.global __put_user_asm_b
__put_user_asm_b :
ld. b r2 , 0 , r4 / * r4 = d a t a * /
movi - ( E F A U L T ) , r2 / * r2 = r e p l y , n o r e a l f i x u p * /
___put_user_asm_b1 :
st. b r3 , 0 , r4
or Z E R O , Z E R O , r2
___put_user_asm_b_exit :
ptabs L I N K , t r0
blink t r0 , Z E R O
.global __put_user_asm_w
__put_user_asm_w :
ld. w r2 , 0 , r4 / * r4 = d a t a * /
movi - ( E F A U L T ) , r2 / * r2 = r e p l y , n o r e a l f i x u p * /
___put_user_asm_w1 :
st. w r3 , 0 , r4
or Z E R O , Z E R O , r2
___put_user_asm_w_exit :
ptabs L I N K , t r0
blink t r0 , Z E R O
.global __put_user_asm_l
__put_user_asm_l :
ld. l r2 , 0 , r4 / * r4 = d a t a * /
movi - ( E F A U L T ) , r2 / * r2 = r e p l y , n o r e a l f i x u p * /
___put_user_asm_l1 :
st. l r3 , 0 , r4
or Z E R O , Z E R O , r2
___put_user_asm_l_exit :
ptabs L I N K , t r0
blink t r0 , Z E R O
.global __put_user_asm_q
__put_user_asm_q :
ld. q r2 , 0 , r4 / * r4 = d a t a * /
movi - ( E F A U L T ) , r2 / * r2 = r e p l y , n o r e a l f i x u p * /
___put_user_asm_q1 :
st. q r3 , 0 , r4
or Z E R O , Z E R O , r2
___put_user_asm_q_exit :
ptabs L I N K , t r0
blink t r0 , Z E R O
panic_stash_regs :
/ * The i d e a i s : w h e n w e g e t a n u n h a n d l e d p a n i c , w e d u m p t h e r e g i s t e r s
to a k n o w n m e m o r y l o c a t i o n , t h e j u s t s i t i n a t i g h t l o o p .
This a l l o w s t h e h u m a n t o l o o k a t t h e m e m o r y r e g i o n t h r o u g h t h e G D B
session ( a s s u m i n g t h e d e b u g m o d u l e ' s S H w y i n i t i a t o r i s n ' t l o c k e d u p
or a n y t h i n g ) , t o h o p e f u l l y a n a l y z e t h e c a u s e o f t h e p a n i c . * /
/ * On e n t r y , f o r m e r r15 ( S P ) i s i n D C R
former r0 i s a t r e s v e c _ s a v e d _ a r e a + 0
former r1 i s a t r e s v e c _ s a v e d _ a r e a + 8
former t r0 i s a t r e s v e c _ s a v e d _ a r e a + 3 2
DCR i s t h e o n l y r e g i s t e r w h o s e v a l u e i s l o s t a l t o g e t h e r .
* /
movi 0 x f f f f f f f f80 0 0 0 0 0 0 , r0 ! p h y o f d u m p a r e a
ld. q S P , 0 x00 0 , r1 ! f o r m e r r0
st. q r0 , 0 x00 0 , r1
ld. q S P , 0 x00 8 , r1 ! f o r m e r r1
st. q r0 , 0 x00 8 , r1
st. q r0 , 0 x01 0 , r2
st. q r0 , 0 x01 8 , r3
st. q r0 , 0 x02 0 , r4
st. q r0 , 0 x02 8 , r5
st. q r0 , 0 x03 0 , r6
st. q r0 , 0 x03 8 , r7
st. q r0 , 0 x04 0 , r8
st. q r0 , 0 x04 8 , r9
st. q r0 , 0 x05 0 , r10
st. q r0 , 0 x05 8 , r11
st. q r0 , 0 x06 0 , r12
st. q r0 , 0 x06 8 , r13
st. q r0 , 0 x07 0 , r14
getcon d c r , r14
st. q r0 , 0 x07 8 , r14
st. q r0 , 0 x08 0 , r16
st. q r0 , 0 x08 8 , r17
st. q r0 , 0 x09 0 , r18
st. q r0 , 0 x09 8 , r19
st. q r0 , 0 x0 a0 , r20
st. q r0 , 0 x0 a8 , r21
st. q r0 , 0 x0 b0 , r22
st. q r0 , 0 x0 b8 , r23
st. q r0 , 0 x0 c0 , r24
st. q r0 , 0 x0 c8 , r25
st. q r0 , 0 x0 d0 , r26
st. q r0 , 0 x0 d8 , r27
st. q r0 , 0 x0 e 0 , r28
st. q r0 , 0 x0 e 8 , r29
st. q r0 , 0 x0 f0 , r30
st. q r0 , 0 x0 f8 , r31
st. q r0 , 0 x10 0 , r32
st. q r0 , 0 x10 8 , r33
st. q r0 , 0 x11 0 , r34
st. q r0 , 0 x11 8 , r35
st. q r0 , 0 x12 0 , r36
st. q r0 , 0 x12 8 , r37
st. q r0 , 0 x13 0 , r38
st. q r0 , 0 x13 8 , r39
st. q r0 , 0 x14 0 , r40
st. q r0 , 0 x14 8 , r41
st. q r0 , 0 x15 0 , r42
st. q r0 , 0 x15 8 , r43
st. q r0 , 0 x16 0 , r44
st. q r0 , 0 x16 8 , r45
st. q r0 , 0 x17 0 , r46
st. q r0 , 0 x17 8 , r47
st. q r0 , 0 x18 0 , r48
st. q r0 , 0 x18 8 , r49
st. q r0 , 0 x19 0 , r50
st. q r0 , 0 x19 8 , r51
st. q r0 , 0 x1 a0 , r52
st. q r0 , 0 x1 a8 , r53
st. q r0 , 0 x1 b0 , r54
st. q r0 , 0 x1 b8 , r55
st. q r0 , 0 x1 c0 , r56
st. q r0 , 0 x1 c8 , r57
st. q r0 , 0 x1 d0 , r58
st. q r0 , 0 x1 d8 , r59
st. q r0 , 0 x1 e 0 , r60
st. q r0 , 0 x1 e 8 , r61
st. q r0 , 0 x1 f0 , r62
st. q r0 , 0 x1 f8 , r63 ! b o g u s , b u t f o r c o n s i s t e n c y ' s s a k e . . .
ld. q S P , 0 x02 0 , r1 ! f o r m e r t r0
st. q r0 , 0 x20 0 , r1
gettr t r1 , r1
st. q r0 , 0 x20 8 , r1
gettr t r2 , r1
st. q r0 , 0 x21 0 , r1
gettr t r3 , r1
st. q r0 , 0 x21 8 , r1
gettr t r4 , r1
st. q r0 , 0 x22 0 , r1
gettr t r5 , r1
st. q r0 , 0 x22 8 , r1
gettr t r6 , r1
st. q r0 , 0 x23 0 , r1
gettr t r7 , r1
st. q r0 , 0 x23 8 , r1
getcon s r , r1
getcon s s r , r2
getcon p s s r , r3
getcon s p c , r4
getcon p s p c , r5
getcon i n t e v t , r6
getcon e x p e v t , r7
getcon p e x p e v t , r8
getcon t r a , r9
getcon t e a , r10
getcon k c r0 , r11
getcon k c r1 , r12
getcon v b r , r13
getcon r e s v e c , r14
st. q r0 , 0 x24 0 , r1
st. q r0 , 0 x24 8 , r2
st. q r0 , 0 x25 0 , r3
st. q r0 , 0 x25 8 , r4
st. q r0 , 0 x26 0 , r5
st. q r0 , 0 x26 8 , r6
st. q r0 , 0 x27 0 , r7
st. q r0 , 0 x27 8 , r8
st. q r0 , 0 x28 0 , r9
st. q r0 , 0 x28 8 , r10
st. q r0 , 0 x29 0 , r11
st. q r0 , 0 x29 8 , r12
st. q r0 , 0 x2 a0 , r13
st. q r0 , 0 x2 a8 , r14
getcon S P C ,r2
getcon S S R ,r3
getcon E X P E V T ,r4
/* Prepare to jump to C - physical address */
movi p a n i c _ h a n d l e r - C O N F I G _ C A C H E D _ M E M O R Y _ O F F S E T , r1
ori r1 , 1 , r1
ptabs r1 , t r0
getcon D C R , S P
blink t r0 , Z E R O
nop
nop
nop
nop
/ *
* - - - Signal H a n d l i n g S e c t i o n
* /
/ *
* extern l o n g l o n g _ s a _ d e f a u l t _ r t _ r e s t o r e r
* extern l o n g l o n g _ s a _ d e f a u l t _ r e s t o r e r
*
* or, b e t t e r ,
*
* extern v o i d _ s a _ d e f a u l t _ r t _ r e s t o r e r ( v o i d )
* extern v o i d _ s a _ d e f a u l t _ r e s t o r e r ( v o i d )
*
* Code p r o t o t y p e s t o d o a s y s _ r t _ s i g r e t u r n ( ) o r s y s _ s y s r e t u r n ( )
* from u s e r s p a c e . C o p i e d i n t o u s e r s p a c e b y s i g n a l m a n a g e m e n t .
* Both m u s t b e q u a d a l i g n e d a n d 2 q u a d l o n g ( 4 i n s t r u c t i o n s ) .
*
* /
.balign 8
.global sa_default_rt_restorer
sa_default_rt_restorer :
movi 0 x10 , r9
shori _ _ N R _ r t _ s i g r e t u r n , r9
trapa r9
nop
.balign 8
.global sa_default_restorer
sa_default_restorer :
movi 0 x10 , r9
shori _ _ N R _ s i g r e t u r n , r9
trapa r9
nop
/ *
* - - - _ _ ex_ t a b l e S e c t i o n
* /
/ *
* User A c c e s s E x c e p t i o n T a b l e .
* /
.section _ _ ex_ t a b l e , " a "
.global asm_uaccess_start /* Just a marker */
asm_uaccess_start :
.long _ _ _ copy_ u s e r1 , _ _ _ c o p y _ u s e r _ e x i t
.long _ _ _ copy_ u s e r2 , _ _ _ c o p y _ u s e r _ e x i t
.long _ _ _ clear_ u s e r1 , _ _ _ c l e a r _ u s e r _ e x i t
.long _ _ _ strncpy_ f r o m _ u s e r1 , _ _ _ s t r n c p y _ f r o m _ u s e r _ e x i t
.long _ _ _ strnlen_ u s e r1 , _ _ _ s t r n l e n _ u s e r _ e x i t
.long _ _ _ get_ u s e r _ a s m _ b1 , _ _ _ g e t _ u s e r _ a s m _ b _ e x i t
.long _ _ _ get_ u s e r _ a s m _ w1 , _ _ _ g e t _ u s e r _ a s m _ w _ e x i t
.long _ _ _ get_ u s e r _ a s m _ l 1 , _ _ _ g e t _ u s e r _ a s m _ l _ e x i t
.long _ _ _ get_ u s e r _ a s m _ q1 , _ _ _ g e t _ u s e r _ a s m _ q _ e x i t
.long _ _ _ put_ u s e r _ a s m _ b1 , _ _ _ p u t _ u s e r _ a s m _ b _ e x i t
.long _ _ _ put_ u s e r _ a s m _ w1 , _ _ _ p u t _ u s e r _ a s m _ w _ e x i t
.long _ _ _ put_ u s e r _ a s m _ l 1 , _ _ _ p u t _ u s e r _ a s m _ l _ e x i t
.long _ _ _ put_ u s e r _ a s m _ q1 , _ _ _ p u t _ u s e r _ a s m _ q _ e x i t
.global asm_uaccess_end /* Just a marker */
asm_uaccess_end :
/ *
* - - - .text .init Section
* /
.section .text .init , " ax"
/ *
* void t r a p _ i n i t ( v o i d )
*
* /
.global trap_init
trap_init :
addi S P , - 2 4 , S P / * R o o m t o s a v e r28 / r29 / r30 * /
st. q S P , 0 , r28
st. q S P , 8 , r29
st. q S P , 1 6 , r30
/* Set VBR and RESVEC */
movi L V B R _ b l o c k , r19
andi r19 , - 4 , r19 / * r e s e t M M U O F F + r e s e r v e d * /
/ * For R E S V E C e x c e p t i o n s w e f o r c e t h e M M U o f f , w h i c h m e a n s w e n e e d t h e
physical a d d r e s s . * /
movi L R E S V E C _ b l o c k - C O N F I G _ C A C H E D _ M E M O R Y _ O F F S E T , r20
andi r20 , - 4 , r20 / * r e s e t r e s e r v e d * /
ori r20 , 1 , r20 / * s e t M M U O F F * /
putcon r19 , V B R
putcon r20 , R E S V E C
/* Sanity check */
movi L V B R _ b l o c k _ e n d , r21
andi r21 , - 4 , r21
movi B L O C K _ S I Z E , r29 / * r29 = e x p e c t e d s i z e * /
or r19 , Z E R O , r30
add r19 , r29 , r19
/ *
* Ugly, b u t b e t t e r l o o p f o r e v e r n o w t h a n c r a s h a f t e r w a r d s .
* We s h o u l d p r i n t a m e s s a g e , b u t i f w e t o u c h L V B R o r
* LRESVEC b l o c k s w e s h o u l d n o t b e s u r p r i s e d i f w e g e t s t u c k
* in t r a p _ i n i t ( ) .
* /
pta t r a p _ i n i t _ l o o p , t r1
gettr t r1 , r28 / * r28 = t r a p _ i n i t _ l o o p * /
sub r21 , r30 , r30 / * r30 = a c t u a l s i z e * /
/ *
* VBR/ R E S V E C h a n d l e r s o v e r l a p b y b e i n g b i g g e r t h a n
* allowed. V e r y b a d . J u s t l o o p f o r e v e r .
* ( r2 8 ) p a n i c / l o o p a d d r e s s
* ( r2 9 ) e x p e c t e d s i z e
* ( r3 0 ) a c t u a l s i z e
* /
trap_init_loop :
bne r19 , r21 , t r1
/* Now that exception vectors are set up reset SR.BL */
getcon S R , r22
movi S R _ U N B L O C K _ E X C , r23
and r22 , r23 , r22
putcon r22 , S R
addi S P , 2 4 , S P
ptabs L I N K , t r0
blink t r0 , Z E R O