2005-06-24 09:01:16 +04:00
/ *
* arch/ x t e n s a / k e r n e l / e n t r y . S
*
* Low- l e v e l e x c e p t i o n h a n d l i n g
*
* 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 .
*
2013-01-05 04:57:17 +04:00
* Copyright ( C ) 2 0 0 4 - 2 0 0 8 b y T e n s i l i c a I n c .
2005-06-24 09:01:16 +04:00
*
* Chris Z a n k e l < c h r i s @zankel.net>
*
* /
# include < l i n u x / l i n k a g e . h >
2005-09-09 22:57:26 +04:00
# include < a s m / a s m - o f f s e t s . h >
2005-06-24 09:01:16 +04:00
# include < a s m / p r o c e s s o r . h >
2010-05-02 12:05:13 +04:00
# include < a s m / c o p r o c e s s o r . h >
2005-06-24 09:01:16 +04:00
# include < a s m / t h r e a d _ i n f o . h >
# include < a s m / u a c c e s s . h >
# include < a s m / u n i s t d . h >
# include < a s m / p t r a c e . h >
# include < a s m / c u r r e n t . h >
# include < a s m / p g t a b l e . h >
# include < a s m / p a g e . h >
# include < a s m / s i g n a l . h >
2006-12-10 13:18:48 +03:00
# include < a s m / t l b f l u s h . h >
2008-11-06 17:40:46 +03:00
# include < v a r i a n t / t i e - a s m . h >
2005-06-24 09:01:16 +04:00
/* Unimplemented features. */
# undef K E R N E L _ S T A C K _ O V E R F L O W _ C H E C K
/ * Not w e l l t e s t e d .
*
* - fast_ c o p r o c e s s o r
* /
/ *
* Macro t o f i n d f i r s t b i t s e t i n W I N D O W B A S E f r o m t h e l e f t + 1
*
* 1 0 0 . . . .0 - > 1
* 0 1 0 . . . .0 - > 2
* 0 0 0 . . . .1 - > WSBITS
* /
.macro ffs_ws bit m a s k
# if X C H A L _ H A V E _ N S A
nsau \ b i t , \ m a s k # 32 - W S B I T S . . . 3 1 ( 3 2 i f f 0 )
addi \ b i t , \ b i t , W S B I T S - 3 2 + 1 # u p p e s t b i t s e t - > r e t u r n 1
# else
movi \ b i t , W S B I T S
# if W S B I T S > 1 6
_ bltui \ m a s k , 0 x10 0 0 0 , 9 9 f
addi \ b i t , \ b i t , - 1 6
extui \ m a s k , \ m a s k , 1 6 , 1 6
# endif
# if W S B I T S > 8
99 : _ bltui \ m a s k , 0 x10 0 , 9 9 f
addi \ b i t , \ b i t , - 8
srli \ m a s k , \ m a s k , 8
# endif
99 : _ bltui \ m a s k , 0 x10 , 9 9 f
addi \ b i t , \ b i t , - 4
srli \ m a s k , \ m a s k , 4
99 : _ bltui \ m a s k , 0 x4 , 9 9 f
addi \ b i t , \ b i t , - 2
srli \ m a s k , \ m a s k , 2
99 : _ bltui \ m a s k , 0 x2 , 9 9 f
addi \ b i t , \ b i t , - 1
99 :
# endif
.endm
/* ----------------- DEFAULT FIRST LEVEL EXCEPTION HANDLERS ----------------- */
/ *
* First- l e v e l e x c e p t i o n h a n d l e r f o r u s e r e x c e p t i o n s .
* Save s o m e s p e c i a l r e g i s t e r s , e x t r a s t a t e s a n d a l l r e g i s t e r s i n t h e A R
* register f i l e t h a t w e r e i n u s e i n t h e u s e r t a s k , a n d j u m p t o t h e c o m m o n
* exception c o d e .
* We s a v e S A R ( u s e d t o c a l c u l a t e W M A S K ) , a n d W B a n d W S ( w e d o n ' t h a v e t o
* save t h e m f o r k e r n e l e x c e p t i o n s ) .
*
* Entry c o n d i t i o n f o r u s e r _ e x c e p t i o n :
*
* a0 : trashed, o r i g i n a l v a l u e s a v e d o n s t a c k ( P T _ A R E G 0 )
* a1 : a1
* a2 : new s t a c k p o i n t e r , o r i g i n a l v a l u e i n d e p c
2013-07-03 20:23:28 +04:00
* a3 : a3
2005-06-24 09:01:16 +04:00
* depc : a2 , o r i g i n a l v a l u e s a v e d o n s t a c k ( P T _ D E P C )
2013-07-03 20:23:28 +04:00
* excsave1 : dispatch t a b l e
2005-06-24 09:01:16 +04:00
*
* PT_ D E P C > = V A L I D _ D O U B L E _ E X C E P T I O N _ A D D R E S S : d o u b l e e x c e p t i o n , D E P C
* < VALID_DOUBLE_EXCEPTION_ADDRESS : regular e x c e p t i o n
*
* Entry c o n d i t i o n f o r _ u s e r _ e x c e p t i o n :
*
* a0 - a3 a n d d e p c h a v e b e e n s a v e d t o P T _ A R E G 0 . . . P T _ A R E G 3 a n d P T _ D E P C
* excsave h a s b e e n r e s t o r e d , a n d
* stack p o i n t e r ( a1 ) h a s b e e n s e t .
*
tree-wide: Assorted spelling fixes
In particular, several occurances of funny versions of 'success',
'unknown', 'therefore', 'acknowledge', 'argument', 'achieve', 'address',
'beginning', 'desirable', 'separate' and 'necessary' are fixed.
Signed-off-by: Daniel Mack <daniel@caiaq.de>
Cc: Joe Perches <joe@perches.com>
Cc: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2010-02-03 03:01:28 +03:00
* Note : _ user_ e x c e p t i o n m i g h t b e a t a n o d d a d d r e s s . D o n ' t u s e c a l l 0 . . c a l l 1 2
2005-06-24 09:01:16 +04:00
* /
ENTRY( u s e r _ e x c e p t i o n )
2013-07-03 20:23:28 +04:00
/* Save a1, a2, a3, and set SP. */
2005-06-24 09:01:16 +04:00
2012-10-15 03:55:38 +04:00
rsr a0 , d e p c
2005-06-24 09:01:16 +04:00
s3 2 i a1 , a2 , P T _ A R E G 1
s3 2 i a0 , a2 , P T _ A R E G 2
s3 2 i a3 , a2 , P T _ A R E G 3
mov a1 , a2
.globl _user_exception
_user_exception :
/* Save SAR and turn off single stepping */
movi a2 , 0
2015-06-25 23:03:29 +03:00
wsr a2 , d e p c # t e r m i n a t e u s e r s t a c k t r a c e w i t h 0
2012-10-15 03:55:38 +04:00
rsr a3 , s a r
xsr a2 , i c o u n t l e v e l
2005-06-24 09:01:16 +04:00
s3 2 i a3 , a1 , P T _ S A R
2007-06-01 04:49:32 +04:00
s3 2 i a2 , a1 , P T _ I C O U N T L E V E L
2005-06-24 09:01:16 +04:00
2013-02-24 07:35:57 +04:00
# if X C H A L _ H A V E _ T H R E A D P T R
rur a2 , t h r e a d p t r
s3 2 i a2 , a1 , P T _ T H R E A D P T R
# endif
2005-06-24 09:01:16 +04:00
/* Rotate ws so that the current windowbase is at bit0. */
/* Assume ws = xxwww1yyyy. Rotate ws right, so that a2 = yyyyxxwww1 */
2012-10-15 03:55:38 +04:00
rsr a2 , w i n d o w b a s e
rsr a3 , w i n d o w s t a r t
2005-06-24 09:01:16 +04:00
ssr a2
s3 2 i a2 , a1 , P T _ W I N D O W B A S E
s3 2 i a3 , a1 , P T _ W I N D O W S T A R T
slli a2 , a3 , 3 2 - W S B I T S
src a2 , a3 , a2
srli a2 , a2 , 3 2 - W S B I T S
s3 2 i a2 , a1 , P T _ W M A S K # n e e d e d f o r r e s t o r i n g r e g i s t e r s
/* Save only live registers. */
_ bbsi. l a2 , 1 , 1 f
s3 2 i a4 , a1 , P T _ A R E G 4
s3 2 i a5 , a1 , P T _ A R E G 5
s3 2 i a6 , a1 , P T _ A R E G 6
s3 2 i a7 , a1 , P T _ A R E G 7
_ bbsi. l a2 , 2 , 1 f
s3 2 i a8 , a1 , P T _ A R E G 8
s3 2 i a9 , a1 , P T _ A R E G 9
s3 2 i a10 , a1 , P T _ A R E G 1 0
s3 2 i a11 , a1 , P T _ A R E G 1 1
_ bbsi. l a2 , 3 , 1 f
s3 2 i a12 , a1 , P T _ A R E G 1 2
s3 2 i a13 , a1 , P T _ A R E G 1 3
s3 2 i a14 , a1 , P T _ A R E G 1 4
s3 2 i a15 , a1 , P T _ A R E G 1 5
_ bnei a2 , 1 , 1 f # o n l y o n e v a l i d f r a m e ?
/* Only one valid frame, skip saving regs. */
j 2 f
/ * Save t h e r e m a i n i n g r e g i s t e r s .
* We h a v e t o s a v e a l l r e g i s t e r s u p t o t h e f i r s t ' 1 ' f r o m
* the r i g h t , e x c e p t t h e c u r r e n t f r a m e ( b i t 0 ) .
* Assume a2 i s : 0 0 1 0 0 1 0 0 0 1 1 0 0 0 1
2007-08-22 21:14:51 +04:00
* All r e g i s t e r f r a m e s s t a r t i n g f r o m t h e t o p f i e l d t o t h e m a r k e d ' 1 '
2005-06-24 09:01:16 +04:00
* must b e s a v e d .
* /
1 : addi a3 , a2 , - 1 # e l i m i n a t e ' 1 ' i n b i t 0 : y y y y x x w w0
neg a3 , a3 # y y y y x x w w 0 - > Y Y Y Y X X W W 1 + 1
and a3 , a3 , a2 # m a x . o n l y o n e b i t i s s e t
/* Find number of frames to save */
ffs_ w s a0 , a3 # n u m b e r o f f r a m e s t o t h e ' 1 ' f r o m l e f t
/ * Store i n f o r m a t i o n i n t o W M A S K :
* bits 0 . . 3 : x x x1 m a s k e d l o w e r 4 b i t s o f t h e r o t a t e d w i n d o w s t a r t ,
* bits 4 . . . : n u m b e r o f v a l i d 4 - r e g i s t e r f r a m e s
* /
slli a3 , a0 , 4 # n u m b e r o f f r a m e s t o s a v e i n b i t s 8 . . 4
extui a2 , a2 , 0 , 4 # m a s k f o r t h e f i r s t 16 r e g i s t e r s
or a2 , a3 , a2
s3 2 i a2 , a1 , P T _ W M A S K # n e e d e d w h e n w e r e s t o r e t h e r e g - f i l e
/* Save 4 registers at a time */
1 : rotw - 1
s3 2 i a0 , a5 , P T _ A R E G _ E N D - 1 6
s3 2 i a1 , a5 , P T _ A R E G _ E N D - 1 2
s3 2 i a2 , a5 , P T _ A R E G _ E N D - 8
s3 2 i a3 , a5 , P T _ A R E G _ E N D - 4
addi a0 , a4 , - 1
addi a1 , a5 , - 1 6
_ bnez a0 , 1 b
/* WINDOWBASE still in SAR! */
2012-10-15 03:55:38 +04:00
rsr a2 , s a r # o r i g i n a l W I N D O W B A S E
2005-06-24 09:01:16 +04:00
movi a3 , 1
ssl a2
sll a3 , a3
2012-10-15 03:55:38 +04:00
wsr a3 , w i n d o w s t a r t # s e t c o r r e s p o n d i n g W I N D O W S T A R T b i t
wsr a2 , w i n d o w b a s e # a n d W I N D O W S T A R T
2005-06-24 09:01:16 +04:00
rsync
/* We are back to the original stack pointer (a1) */
2008-02-13 00:17:07 +03:00
2 : /* Now, jump to the common exception handler. */
2005-06-24 09:01:16 +04:00
j c o m m o n _ e x c e p t i o n
2012-11-17 04:16:20 +04:00
ENDPROC( u s e r _ e x c e p t i o n )
2005-06-24 09:01:16 +04:00
/ *
* First- l e v e l e x i t h a n d l e r f o r k e r n e l e x c e p t i o n s
* Save s p e c i a l r e g i s t e r s a n d t h e l i v e w i n d o w f r a m e .
* Note : Even t h o u g h w e c h a n g e s t h e s t a c k p o i n t e r , w e d o n ' t h a v e t o d o a
* MOVSP h e r e , a s w e d o t h a t w h e n w e r e t u r n f r o m t h e e x c e p t i o n .
* ( See c o m m e n t i n t h e k e r n e l e x c e p t i o n e x i t c o d e )
*
* Entry c o n d i t i o n f o r k e r n e l _ e x c e p t i o n :
*
* a0 : trashed, o r i g i n a l v a l u e s a v e d o n s t a c k ( P T _ A R E G 0 )
* a1 : a1
* a2 : new s t a c k p o i n t e r , o r i g i n a l i n D E P C
2013-07-03 20:23:28 +04:00
* a3 : a3
2005-06-24 09:01:16 +04:00
* depc : a2 , o r i g i n a l v a l u e s a v e d o n s t a c k ( P T _ D E P C )
2013-07-03 20:23:28 +04:00
* excsave_1 : dispatch t a b l e
2005-06-24 09:01:16 +04:00
*
* PT_ D E P C > = V A L I D _ D O U B L E _ E X C E P T I O N _ A D D R E S S : d o u b l e e x c e p t i o n , D E P C
* < VALID_DOUBLE_EXCEPTION_ADDRESS : regular e x c e p t i o n
*
* Entry c o n d i t i o n f o r _ k e r n e l _ e x c e p t i o n :
*
* a0 - a3 a n d d e p c h a v e b e e n s a v e d t o P T _ A R E G 0 . . . P T _ A R E G 3 a n d P T _ D E P C
* excsave h a s b e e n r e s t o r e d , a n d
* stack p o i n t e r ( a1 ) h a s b e e n s e t .
*
tree-wide: Assorted spelling fixes
In particular, several occurances of funny versions of 'success',
'unknown', 'therefore', 'acknowledge', 'argument', 'achieve', 'address',
'beginning', 'desirable', 'separate' and 'necessary' are fixed.
Signed-off-by: Daniel Mack <daniel@caiaq.de>
Cc: Joe Perches <joe@perches.com>
Cc: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2010-02-03 03:01:28 +03:00
* Note : _ kernel_ e x c e p t i o n m i g h t b e a t a n o d d a d d r e s s . D o n ' t u s e c a l l 0 . . c a l l 1 2
2005-06-24 09:01:16 +04:00
* /
ENTRY( k e r n e l _ e x c e p t i o n )
2013-07-03 20:23:28 +04:00
/* Save a1, a2, a3, and set SP. */
2005-06-24 09:01:16 +04:00
2012-10-15 03:55:38 +04:00
rsr a0 , d e p c # g e t a 2
2005-06-24 09:01:16 +04:00
s3 2 i a1 , a2 , P T _ A R E G 1
s3 2 i a0 , a2 , P T _ A R E G 2
s3 2 i a3 , a2 , P T _ A R E G 3
mov a1 , a2
.globl _kernel_exception
_kernel_exception :
/* Save SAR and turn off single stepping */
movi a2 , 0
2012-10-15 03:55:38 +04:00
rsr a3 , s a r
xsr a2 , i c o u n t l e v e l
2005-06-24 09:01:16 +04:00
s3 2 i a3 , a1 , P T _ S A R
2007-06-01 04:49:32 +04:00
s3 2 i a2 , a1 , P T _ I C O U N T L E V E L
2005-06-24 09:01:16 +04:00
/* Rotate ws so that the current windowbase is at bit0. */
/* Assume ws = xxwww1yyyy. Rotate ws right, so that a2 = yyyyxxwww1 */
2012-10-15 03:55:38 +04:00
rsr a2 , w i n d o w b a s e # d o n ' t n e e d t o s a v e t h e s e , w e o n l y
rsr a3 , w i n d o w s t a r t # n e e d s h i f t e d w i n d o w s t a r t : w i n d o w m a s k
2005-06-24 09:01:16 +04:00
ssr a2
slli a2 , a3 , 3 2 - W S B I T S
src a2 , a3 , a2
srli a2 , a2 , 3 2 - W S B I T S
s3 2 i a2 , a1 , P T _ W M A S K # n e e d e d f o r k e r n e l _ e x c e p t i o n _ e x i t
/* Save only the live window-frame */
_ bbsi. l a2 , 1 , 1 f
s3 2 i a4 , a1 , P T _ A R E G 4
s3 2 i a5 , a1 , P T _ A R E G 5
s3 2 i a6 , a1 , P T _ A R E G 6
s3 2 i a7 , a1 , P T _ A R E G 7
_ bbsi. l a2 , 2 , 1 f
s3 2 i a8 , a1 , P T _ A R E G 8
s3 2 i a9 , a1 , P T _ A R E G 9
s3 2 i a10 , a1 , P T _ A R E G 1 0
s3 2 i a11 , a1 , P T _ A R E G 1 1
_ bbsi. l a2 , 3 , 1 f
s3 2 i a12 , a1 , P T _ A R E G 1 2
s3 2 i a13 , a1 , P T _ A R E G 1 3
s3 2 i a14 , a1 , P T _ A R E G 1 4
s3 2 i a15 , a1 , P T _ A R E G 1 5
2015-06-25 23:03:29 +03:00
_ bnei a2 , 1 , 1 f
/ * Copy s p i l l s l o t s o f a0 a n d a1 t o i m i t a t e m o v s p
* in o r d e r t o k e e p e x c e p t i o n s t a c k c o n t i n u o u s
* /
l3 2 i a3 , a1 , P T _ S I Z E
l3 2 i a0 , a1 , P T _ S I Z E + 4
s3 2 e a3 , a1 , - 1 6
s3 2 e a0 , a1 , - 1 2
2005-06-24 09:01:16 +04:00
1 :
2015-06-25 23:03:29 +03:00
l3 2 i a0 , a1 , P T _ A R E G 0 # r e s t o r e s a v e d a 0
wsr a0 , d e p c
2005-06-24 09:01:16 +04:00
# ifdef K E R N E L _ S T A C K _ O V E R F L O W _ C H E C K
/* Stack overflow check, for debugging */
extui a2 , a1 , T A S K _ S I Z E _ B I T S ,X X
movi a3 , S I Z E ? ?
_ bge a2 , a3 , o u t _ o f _ s t a c k _ p a n i c
# endif
/ *
* This i s t h e c o m m o n e x c e p t i o n h a n d l e r .
* We g e t h e r e f r o m t h e u s e r e x c e p t i o n h a n d l e r o r s i m p l y b y f a l l i n g t h r o u g h
* from t h e k e r n e l e x c e p t i o n h a n d l e r .
* Save t h e r e m a i n i n g s p e c i a l r e g i s t e r s , s w i t c h t o k e r n e l m o d e , a n d j u m p
* to t h e s e c o n d - l e v e l e x c e p t i o n h a n d l e r .
*
* /
common_exception :
2007-06-01 04:49:32 +04:00
/* Save some registers, disable loops and clear the syscall flag. */
2005-06-24 09:01:16 +04:00
2012-10-15 03:55:38 +04:00
rsr a2 , d e b u g c a u s e
rsr a3 , e p c1
2005-06-24 09:01:16 +04:00
s3 2 i a2 , a1 , P T _ D E B U G C A U S E
s3 2 i a3 , a1 , P T _ P C
2007-06-01 04:49:32 +04:00
movi a2 , - 1
2012-10-15 03:55:38 +04:00
rsr a3 , e x c v a d d r
2007-06-01 04:49:32 +04:00
s3 2 i a2 , a1 , P T _ S Y S C A L L
2005-06-24 09:01:16 +04:00
movi a2 , 0
s3 2 i a3 , a1 , P T _ E X C V A D D R
2012-10-15 03:55:38 +04:00
xsr a2 , l c o u n t
2005-06-24 09:01:16 +04:00
s3 2 i a2 , a1 , P T _ L C O U N T
/* It is now save to restore the EXC_TABLE_FIXUP variable. */
2012-10-15 03:55:38 +04:00
rsr a0 , e x c c a u s e
2005-06-24 09:01:16 +04:00
movi a3 , 0
2012-10-15 03:55:38 +04:00
rsr a2 , e x c s a v e 1
2005-06-24 09:01:16 +04:00
s3 2 i a0 , a1 , P T _ E X C C A U S E
s3 2 i a3 , a2 , E X C _ T A B L E _ F I X U P
2015-06-25 23:03:29 +03:00
/ * All u n r e c o v e r a b l e s t a t e s a r e s a v e d o n s t a c k , n o w , a n d a1 i s v a l i d .
* Now w e c a n a l l o w e x c e p t i o n s a g a i n . I n c a s e w e ' v e g o t a n i n t e r r u p t
* PS. I N T L E V E L i s s e t t o L O C K L E V E L d i s a b l i n g f u r h t e r i n t e r r u p t s ,
* otherwise i t ' s l e f t u n c h a n g e d .
2005-06-24 09:01:16 +04:00
*
2015-06-25 23:03:29 +03:00
* Set P S ( E X C M = 0 , U M = 0 , R I N G = 0 , O W B = 0 , W O E = 1 , I N T L E V E L = X )
2005-06-24 09:01:16 +04:00
* /
2012-10-15 03:55:38 +04:00
rsr a3 , p s
2013-03-26 02:51:43 +04:00
addi a0 , a0 , - E X C C A U S E _ L E V E L 1 _ I N T E R R U P T
movi a2 , L O C K L E V E L
2013-01-05 04:57:17 +04:00
extui a3 , a3 , P S _ I N T L E V E L _ S H I F T , P S _ I N T L E V E L _ W I D T H
# a3 = P S . I N T L E V E L
2013-03-26 02:51:43 +04:00
moveqz a3 , a2 , a0 # a 3 = L O C K L E V E L i f f i n t e r r u p t
2006-12-10 13:18:48 +03:00
movi a2 , 1 < < P S _ W O E _ B I T
2005-06-24 09:01:16 +04:00
or a3 , a3 , a2
2015-06-25 23:03:29 +03:00
rsr a2 , e x c c a u s e
/* restore return address (or 0 if return to userspace) */
rsr a0 , d e p c
2012-10-15 03:55:38 +04:00
xsr a3 , p s
2005-06-24 09:01:16 +04:00
s3 2 i a3 , a1 , P T _ P S # s a v e p s
2012-10-15 03:55:38 +04:00
/* Save lbeg, lend */
2005-06-24 09:01:16 +04:00
2015-06-25 23:03:29 +03:00
rsr a4 , l b e g
2012-10-15 03:55:38 +04:00
rsr a3 , l e n d
2015-06-25 23:03:29 +03:00
s3 2 i a4 , a1 , P T _ L B E G
2005-06-24 09:01:16 +04:00
s3 2 i a3 , a1 , P T _ L E N D
2012-11-15 06:25:48 +04:00
/* Save SCOMPARE1 */
# if X C H A L _ H A V E _ S 3 2 C 1 I
2015-06-25 23:03:29 +03:00
rsr a3 , s c o m p a r e 1
s3 2 i a3 , a1 , P T _ S C O M P A R E 1
2012-11-15 06:25:48 +04:00
# endif
2008-02-13 00:17:07 +03:00
/* Save optional registers. */
2015-06-25 23:03:29 +03:00
save_ x t r e g s _ o p t a1 a3 a4 a5 a6 a7 P T _ X T R E G S _ O P T
2008-02-13 00:17:07 +03:00
2005-06-24 09:01:16 +04:00
/ * Go t o s e c o n d - l e v e l d i s p a t c h e r . S e t u p p a r a m e t e r s t o p a s s t o t h e
* exception h a n d l e r a n d c a l l t h e e x c e p t i o n h a n d l e r .
* /
2013-07-03 20:23:28 +04:00
rsr a4 , e x c s a v e 1
2005-06-24 09:01:16 +04:00
mov a6 , a1 # p a s s s t a c k f r a m e
2015-06-25 23:03:29 +03:00
mov a7 , a2 # p a s s E X C C A U S E
addx4 a4 , a2 , a4
2005-06-24 09:01:16 +04:00
l3 2 i a4 , a4 , E X C _ T A B L E _ D E F A U L T # l o a d h a n d l e r
/* Call the second-level handler */
callx4 a4
/* Jump here for exception exit */
2008-05-22 04:43:50 +04:00
.global common_exception_return
2005-06-24 09:01:16 +04:00
common_exception_return :
2013-03-31 06:32:42 +04:00
1 :
2013-08-26 15:12:58 +04:00
rsil a2 , L O C K L E V E L
2015-07-16 06:18:46 +03:00
# ifdef C O N F I G _ T R A C E _ I R Q F L A G S
movi a4 , t r a c e _ h a r d i r q s _ o f f
callx4 a4
# endif
2013-03-31 06:32:42 +04:00
2005-06-24 09:01:16 +04:00
/* Jump if we are returning from kernel exceptions. */
2013-08-26 15:12:58 +04:00
l3 2 i a3 , a1 , P T _ P S
2013-08-26 15:16:23 +04:00
GET_ T H R E A D _ I N F O ( a2 , a1 )
l3 2 i a4 , a2 , T I _ F L A G S
_ bbci. l a3 , P S _ U M _ B I T , 6 f
2005-06-24 09:01:16 +04:00
/ * Specific t o a u s e r e x c e p t i o n e x i t :
* We n e e d t o c h e c k s o m e f l a g s f o r s i g n a l h a n d l i n g a n d r e s c h e d u l i n g ,
* and h a v e t o r e s t o r e W B a n d W S , e x t r a s t a t e s , a n d a l l r e g i s t e r s
* in t h e r e g i s t e r f i l e t h a t w e r e i n u s e i n t h e u s e r t a s k .
2008-01-22 11:45:25 +03:00
* Note t h a t w e d o n ' t d i s a b l e i n t e r r u p t s h e r e .
2005-06-24 09:01:16 +04:00
* /
_ bbsi. l a4 , T I F _ N E E D _ R E S C H E D , 3 f
2012-04-24 10:30:16 +04:00
_ bbsi. l a4 , T I F _ N O T I F Y _ R E S U M E , 2 f
2013-05-15 19:34:05 +04:00
_ bbci. l a4 , T I F _ S I G P E N D I N G , 5 f
2005-06-24 09:01:16 +04:00
2012-04-24 10:30:16 +04:00
2 : l3 2 i a4 , a1 , P T _ D E P C
2005-06-24 09:01:16 +04:00
bgeui a4 , V A L I D _ D O U B L E _ E X C E P T I O N _ A D D R E S S , 4 f
2008-01-22 11:45:25 +03:00
/* Call do_signal() */
2015-07-16 06:18:46 +03:00
# ifdef C O N F I G _ T R A C E _ I R Q F L A G S
movi a4 , t r a c e _ h a r d i r q s _ o n
callx4 a4
# endif
2013-08-26 15:12:58 +04:00
rsil a2 , 0
2012-04-24 10:30:16 +04:00
movi a4 , d o _ n o t i f y _ r e s u m e # i n t d o _ n o t i f y _ r e s u m e ( s t r u c t p t _ r e g s * )
2005-06-24 09:01:16 +04:00
mov a6 , a1
callx4 a4
j 1 b
2008-01-22 11:45:25 +03:00
3 : /* Reschedule */
2005-06-24 09:01:16 +04:00
2015-07-16 06:18:46 +03:00
# ifdef C O N F I G _ T R A C E _ I R Q F L A G S
movi a4 , t r a c e _ h a r d i r q s _ o n
callx4 a4
# endif
2013-08-26 15:12:58 +04:00
rsil a2 , 0
2005-06-24 09:01:16 +04:00
movi a4 , s c h e d u l e # v o i d s c h e d u l e ( v o i d )
callx4 a4
j 1 b
2013-08-26 15:16:23 +04:00
# ifdef C O N F I G _ P R E E M P T
6 :
_ bbci. l a4 , T I F _ N E E D _ R E S C H E D , 4 f
/* Check current_thread_info->preempt_count */
l3 2 i a4 , a2 , T I _ P R E _ C O U N T
bnez a4 , 4 f
movi a4 , p r e e m p t _ s c h e d u l e _ i r q
callx4 a4
j 1 b
# endif
2013-05-15 19:34:05 +04:00
5 :
# ifdef C O N F I G _ D E B U G _ T L B _ S A N I T Y
l3 2 i a4 , a1 , P T _ D E P C
bgeui a4 , V A L I D _ D O U B L E _ E X C E P T I O N _ A D D R E S S , 4 f
movi a4 , c h e c k _ t l b _ s a n i t y
callx4 a4
# endif
2013-08-26 15:16:23 +04:00
6 :
2013-08-26 15:12:58 +04:00
4 :
# ifdef C O N F I G _ T R A C E _ I R Q F L A G S
2015-07-16 06:18:46 +03:00
extui a4 , a3 , P S _ I N T L E V E L _ S H I F T , P S _ I N T L E V E L _ W I D T H
bgei a4 , L O C K L E V E L , 1 f
2013-08-26 15:12:58 +04:00
movi a4 , t r a c e _ h a r d i r q s _ o n
callx4 a4
1 :
# endif
/* Restore optional registers. */
2008-01-22 11:45:25 +03:00
load_ x t r e g s _ o p t a1 a2 a4 a5 a6 a7 P T _ X T R E G S _ O P T
2005-06-24 09:01:16 +04:00
2012-11-15 06:25:48 +04:00
/* Restore SCOMPARE1 */
# if X C H A L _ H A V E _ S 3 2 C 1 I
l3 2 i a2 , a1 , P T _ S C O M P A R E 1
wsr a2 , s c o m p a r e 1
# endif
2012-10-15 03:55:38 +04:00
wsr a3 , p s / * d i s a b l e i n t e r r u p t s * /
2008-01-22 11:45:25 +03:00
_ bbci. l a3 , P S _ U M _ B I T , k e r n e l _ e x c e p t i o n _ e x i t
user_exception_exit :
/* Restore the state of the task and return from the exception. */
2005-06-24 09:01:16 +04:00
/* Switch to the user thread WINDOWBASE. Save SP temporarily in DEPC */
l3 2 i a2 , a1 , P T _ W I N D O W B A S E
l3 2 i a3 , a1 , P T _ W I N D O W S T A R T
2012-10-15 03:55:38 +04:00
wsr a1 , d e p c # u s e D E P C a s t e m p s t o r a g e
wsr a3 , w i n d o w s t a r t # r e s t o r e W I N D O W S T A R T
2005-06-24 09:01:16 +04:00
ssr a2 # p r e s e r v e u s e r ' s W B i n t h e S A R
2012-10-15 03:55:38 +04:00
wsr a2 , w i n d o w b a s e # s w i t c h t o u s e r ' s s a v e d W B
2005-06-24 09:01:16 +04:00
rsync
2012-10-15 03:55:38 +04:00
rsr a1 , d e p c # r e s t o r e s t a c k p o i n t e r
2005-06-24 09:01:16 +04:00
l3 2 i a2 , a1 , P T _ W M A S K # r e g i s t e r f r a m e s s a v e d ( i n b i t s 4 . . . 9 )
rotw - 1 # w e r e s t o r e a 4 . . a7
_ bltui a6 , 1 6 , 1 f # o n l y h a v e t o r e s t o r e c u r r e n t w i n d o w ?
/ * The w o r k i n g r e g i s t e r s a r e a0 a n d a3 . W e a r e r e s t o r i n g t o
* a4 . . a7 . B e c a r e f u l n o t t o d e s t r o y w h a t w e h a v e j u s t r e s t o r e d .
* Note : wmask h a s t h e f o r m a t Y Y Y Y M :
* Y : number o f r e g i s t e r s s a v e d i n g r o u p s o f 4
* M : 4 bit m a s k o f f i r s t 1 6 r e g i s t e r s
* /
mov a2 , a6
mov a3 , a5
2 : rotw - 1 # a 0 . . a3 b e c o m e a4 . . a7
addi a3 , a7 , - 4 * 4 # n e x t i t e r a t i o n
addi a2 , a6 , - 1 6 # d e c r e m e n t i n g Y i n W M A S K
l3 2 i a4 , a3 , P T _ A R E G _ E N D + 0
l3 2 i a5 , a3 , P T _ A R E G _ E N D + 4
l3 2 i a6 , a3 , P T _ A R E G _ E N D + 8
l3 2 i a7 , a3 , P T _ A R E G _ E N D + 1 2
_ bgeui a2 , 1 6 , 2 b
/* Clear unrestored registers (don't leak anything to user-land */
2012-10-15 03:55:38 +04:00
1 : rsr a0 , w i n d o w b a s e
rsr a3 , s a r
2005-06-24 09:01:16 +04:00
sub a3 , a0 , a3
beqz a3 , 2 f
extui a3 , a3 , 0 , W B B I T S
1 : rotw - 1
addi a3 , a7 , - 1
movi a4 , 0
movi a5 , 0
movi a6 , 0
movi a7 , 0
bgei a3 , 1 , 1 b
/ * We a r e b a c k w e r e w e w e r e w h e n w e s t a r t e d .
* Note : a2 s t i l l c o n t a i n s W M A S K ( i f w e ' v e r e t u r n e d t o t h e o r i g i n a l
* frame w h e r e w e h a d l o a d e d a2 ) , o r a t l e a s t t h e l o w e r 4 b i t s
* ( if w e h a v e r e s t o r e d W S B I T S - 1 f r a m e s ) .
* /
2015-07-04 15:27:39 +03:00
2 :
2013-02-24 07:35:57 +04:00
# if X C H A L _ H A V E _ T H R E A D P T R
l3 2 i a3 , a1 , P T _ T H R E A D P T R
wur a3 , t h r e a d p t r
# endif
2015-07-04 15:27:39 +03:00
j c o m m o n _ e x c e p t i o n _ e x i t
2005-06-24 09:01:16 +04:00
/ * This i s t h e k e r n e l e x c e p t i o n e x i t .
* We a v o i d e d t o d o a M O V S P w h e n w e e n t e r e d t h e e x c e p t i o n , b u t w e
* have t o d o i t h e r e .
* /
kernel_exception_exit :
/ * Check i f w e h a v e t o d o a m o v s p .
*
* We o n l y h a v e t o d o a m o v s p i f t h e p r e v i o u s w i n d o w - f r a m e h a s
* been s p i l l e d t o t h e * t e m p o r a r y * e x c e p t i o n s t a c k i n s t e a d o f t h e
* task' s s t a c k . T h i s i s t h e c a s e i f t h e c o r r e s p o n d i n g b i t i n
* WINDOWSTART f o r t h e p r e v i o u s w i n d o w - f r a m e w a s s e t b e f o r e
* ( not s p i l l e d ) b u t i s z e r o n o w ( s p i l l e d ) .
* If t h i s b i t i s z e r o , a l l o t h e r b i t s e x c e p t t h e o n e f o r t h e
* current w i n d o w f r a m e a r e a l s o z e r o . S o , w e c a n u s e a s i m p l e t e s t :
* ' and' W I N D O W S T A R T a n d W I N D O W S T A R T - 1 :
*
* ( XXXXXX1 [ 0 ] * - 1 ) A N D X X X X X X 1 [ 0 ] * = X X X X X X 0 [ 0 ] *
*
* The r e s u l t i s z e r o o n l y i f o n e b i t w a s s e t .
*
* ( Note : We m i g h t h a v e g o n e t h r o u g h s e v e r a l t a s k s w i t c h e s b e f o r e
* we c o m e b a c k t o t h e c u r r e n t t a s k , s o W I N D O W B A S E m i g h t b e
* different f r o m t h e t i m e t h e e x c e p t i o n o c c u r r e d . )
* /
/ * Test W I N D O W S T A R T b e f o r e a n d a f t e r t h e e x c e p t i o n .
* We a c t u a l l y h a v e W M A S K , s o w e o n l y h a v e t o t e s t i f i t i s 1 o r n o t .
* /
l3 2 i a2 , a1 , P T _ W M A S K
_ beqi a2 , 1 , c o m m o n _ e x c e p t i o n _ e x i t # S p i l l e d b e f o r e e x c e p t i o n , j u m p
/* Test WINDOWSTART now. If spilled, do the movsp */
2012-10-15 03:55:38 +04:00
rsr a3 , w i n d o w s t a r t
2005-06-24 09:01:16 +04:00
addi a0 , a3 , - 1
and a3 , a3 , a0
_ bnez a3 , c o m m o n _ e x c e p t i o n _ e x i t
/* Do a movsp (we returned from a call4, so we have at least a0..a7) */
addi a0 , a1 , - 1 6
l3 2 i a3 , a0 , 0
l3 2 i a4 , a0 , 4
s3 2 i a3 , a1 , P T _ S I Z E + 0
s3 2 i a4 , a1 , P T _ S I Z E + 4
l3 2 i a3 , a0 , 8
l3 2 i a4 , a0 , 1 2
s3 2 i a3 , a1 , P T _ S I Z E + 8
s3 2 i a4 , a1 , P T _ S I Z E + 1 2
/ * Common e x c e p t i o n e x i t .
* We r e s t o r e t h e s p e c i a l r e g i s t e r a n d t h e c u r r e n t w i n d o w f r a m e , a n d
* return f r o m t h e e x c e p t i o n .
*
* Note : We e x p e c t a2 t o h o l d P T _ W M A S K
* /
common_exception_exit :
2008-02-13 00:17:07 +03:00
/* Restore address registers. */
2005-06-24 09:01:16 +04:00
_ bbsi. l a2 , 1 , 1 f
l3 2 i a4 , a1 , P T _ A R E G 4
l3 2 i a5 , a1 , P T _ A R E G 5
l3 2 i a6 , a1 , P T _ A R E G 6
l3 2 i a7 , a1 , P T _ A R E G 7
_ bbsi. l a2 , 2 , 1 f
l3 2 i a8 , a1 , P T _ A R E G 8
l3 2 i a9 , a1 , P T _ A R E G 9
l3 2 i a10 , a1 , P T _ A R E G 1 0
l3 2 i a11 , a1 , P T _ A R E G 1 1
_ bbsi. l a2 , 3 , 1 f
l3 2 i a12 , a1 , P T _ A R E G 1 2
l3 2 i a13 , a1 , P T _ A R E G 1 3
l3 2 i a14 , a1 , P T _ A R E G 1 4
l3 2 i a15 , a1 , P T _ A R E G 1 5
/* Restore PC, SAR */
1 : l3 2 i a2 , a1 , P T _ P C
l3 2 i a3 , a1 , P T _ S A R
2012-10-15 03:55:38 +04:00
wsr a2 , e p c1
wsr a3 , s a r
2005-06-24 09:01:16 +04:00
/* Restore LBEG, LEND, LCOUNT */
l3 2 i a2 , a1 , P T _ L B E G
l3 2 i a3 , a1 , P T _ L E N D
2012-10-15 03:55:38 +04:00
wsr a2 , l b e g
2005-06-24 09:01:16 +04:00
l3 2 i a2 , a1 , P T _ L C O U N T
2012-10-15 03:55:38 +04:00
wsr a3 , l e n d
wsr a2 , l c o u n t
2005-06-24 09:01:16 +04:00
2007-06-01 04:49:32 +04:00
/* We control single stepping through the ICOUNTLEVEL register. */
l3 2 i a2 , a1 , P T _ I C O U N T L E V E L
movi a3 , - 2
2012-10-15 03:55:38 +04:00
wsr a2 , i c o u n t l e v e l
wsr a3 , i c o u n t
2007-06-01 04:49:32 +04:00
2005-06-24 09:01:16 +04:00
/* Check if it was double exception. */
l3 2 i a0 , a1 , P T _ D E P C
l3 2 i a3 , a1 , P T _ A R E G 3
l3 2 i a2 , a1 , P T _ A R E G 2
2013-03-26 02:51:43 +04:00
_ bgeui a0 , V A L I D _ D O U B L E _ E X C E P T I O N _ A D D R E S S , 1 f
2005-06-24 09:01:16 +04:00
/* Restore a0...a3 and return */
l3 2 i a0 , a1 , P T _ A R E G 0
l3 2 i a1 , a1 , P T _ A R E G 1
2013-03-26 02:51:43 +04:00
rfe
2005-06-24 09:01:16 +04:00
2013-03-26 02:51:43 +04:00
1 : wsr a0 , d e p c
2005-06-24 09:01:16 +04:00
l3 2 i a0 , a1 , P T _ A R E G 0
l3 2 i a1 , a1 , P T _ A R E G 1
2013-03-26 02:51:43 +04:00
rfde
2005-06-24 09:01:16 +04:00
2012-11-17 04:16:20 +04:00
ENDPROC( k e r n e l _ e x c e p t i o n )
2005-06-24 09:01:16 +04:00
/ *
* Debug e x c e p t i o n h a n d l e r .
*
* Currently, w e d o n ' t s u p p o r t K G D B , s o o n l y u s e r a p p l i c a t i o n c a n b e d e b u g g e d .
*
* When w e g e t h e r e , a0 i s t r a s h e d a n d s a v e d t o e x c s a v e [ d e b u g l e v e l ]
* /
ENTRY( d e b u g _ e x c e p t i o n )
2012-10-15 03:55:38 +04:00
rsr a0 , S R E G _ E P S + X C H A L _ D E B U G L E V E L
2006-12-10 13:18:48 +03:00
bbsi. l a0 , P S _ E X C M _ B I T , 1 f # e x c e p t i o n m o d e
2005-06-24 09:01:16 +04:00
2012-10-15 03:55:38 +04:00
/* Set EPC1 and EXCCAUSE */
2005-06-24 09:01:16 +04:00
2012-10-15 03:55:38 +04:00
wsr a2 , d e p c # s a v e a 2 t e m p o r a r i l y
rsr a2 , S R E G _ E P C + X C H A L _ D E B U G L E V E L
wsr a2 , e p c1
2005-06-24 09:01:16 +04:00
movi a2 , E X C C A U S E _ M A P P E D _ D E B U G
2012-10-15 03:55:38 +04:00
wsr a2 , e x c c a u s e
2005-06-24 09:01:16 +04:00
/* Restore PS to the value before the debug exc but with PS.EXCM set.*/
2006-12-10 13:18:48 +03:00
movi a2 , 1 < < P S _ E X C M _ B I T
2005-06-24 09:01:16 +04:00
or a2 , a0 , a2
movi a0 , d e b u g _ e x c e p t i o n # r e s t o r e a 3 , d e b u g j u m p v e c t o r
2012-10-15 03:55:38 +04:00
wsr a2 , p s
xsr a0 , S R E G _ E X C S A V E + X C H A L _ D E B U G L E V E L
2005-06-24 09:01:16 +04:00
/* Switch to kernel/user stack, restore jump vector, and save a0 */
2006-12-10 13:18:48 +03:00
bbsi. l a2 , P S _ U M _ B I T , 2 f # j u m p i f u s e r m o d e
2005-06-24 09:01:16 +04:00
addi a2 , a1 , - 1 6 - P T _ S I Z E # a s s u m e k e r n e l s t a c k
s3 2 i a0 , a2 , P T _ A R E G 0
movi a0 , 0
s3 2 i a1 , a2 , P T _ A R E G 1
s3 2 i a0 , a2 , P T _ D E P C # m a r k i t a s a r e g u l a r e x c e p t i o n
2012-10-15 03:55:38 +04:00
xsr a0 , d e p c
2005-06-24 09:01:16 +04:00
s3 2 i a3 , a2 , P T _ A R E G 3
s3 2 i a0 , a2 , P T _ A R E G 2
mov a1 , a2
j _ k e r n e l _ e x c e p t i o n
2012-10-15 03:55:38 +04:00
2 : rsr a2 , e x c s a v e 1
2005-06-24 09:01:16 +04:00
l3 2 i a2 , a2 , E X C _ T A B L E _ K S T K # l o a d k e r n e l s t a c k p o i n t e r
s3 2 i a0 , a2 , P T _ A R E G 0
movi a0 , 0
s3 2 i a1 , a2 , P T _ A R E G 1
s3 2 i a0 , a2 , P T _ D E P C
2012-10-15 03:55:38 +04:00
xsr a0 , d e p c
2005-06-24 09:01:16 +04:00
s3 2 i a3 , a2 , P T _ A R E G 3
s3 2 i a0 , a2 , P T _ A R E G 2
mov a1 , a2
j _ u s e r _ e x c e p t i o n
/* Debug exception while in exception mode. */
1 : j 1 b / / F I X M E ! !
2012-11-17 04:16:20 +04:00
ENDPROC( d e b u g _ e x c e p t i o n )
2005-06-24 09:01:16 +04:00
/ *
* We g e t h e r e i n c a s e o f a n u n r e c o v e r a b l e e x c e p t i o n .
* The o n l y t h i n g w e c a n d o i s t o b e n i c e a n d p r i n t a p a n i c m e s s a g e .
* We o n l y p r o d u c e a s i n g l e s t a c k f r a m e f o r p a n i c , s o ? ? ?
*
*
* Entry c o n d i t i o n s :
*
* - a0 c o n t a i n s t h e c a l l e r a d d r e s s ; original value saved in excsave1.
* - the o r i g i n a l a0 c o n t a i n s a v a l i d r e t u r n a d d r e s s ( b a c k t r a c e ) o r 0 .
* - a2 c o n t a i n s a v a l i d s t a c k p o i n t e r
*
* Notes :
*
* - If t h e s t a c k p o i n t e r c o u l d b e i n v a l i d , t h e c a l l e r h a s t o s e t u p a
* dummy s t a c k p o i n t e r ( e . g . t h e s t a c k o f t h e i n i t _ t a s k )
*
* - If t h e r e t u r n a d d r e s s c o u l d b e i n v a l i d , t h e c a l l e r h a s t o s e t i t
* to 0 , s o t h e b a c k t r a c e w o u l d s t o p .
*
* /
.align 4
unrecoverable_text :
.ascii " Unrecoverable e r r o r i n e x c e p t i o n h a n d l e r \ 0 "
ENTRY( u n r e c o v e r a b l e _ e x c e p t i o n )
movi a0 , 1
movi a1 , 0
2012-10-15 03:55:38 +04:00
wsr a0 , w i n d o w s t a r t
wsr a1 , w i n d o w b a s e
2005-06-24 09:01:16 +04:00
rsync
2013-01-05 04:57:17 +04:00
movi a1 , ( 1 < < P S _ W O E _ B I T ) | L O C K L E V E L
2012-10-15 03:55:38 +04:00
wsr a1 , p s
2005-06-24 09:01:16 +04:00
rsync
movi a1 , i n i t _ t a s k
movi a0 , 0
addi a1 , a1 , P T _ R E G S _ O F F S E T
movi a4 , p a n i c
movi a6 , u n r e c o v e r a b l e _ t e x t
callx4 a4
1 : j 1 b
2012-11-17 04:16:20 +04:00
ENDPROC( u n r e c o v e r a b l e _ e x c e p t i o n )
2005-06-24 09:01:16 +04:00
/* -------------------------- FAST EXCEPTION HANDLERS ----------------------- */
/ *
* Fast- h a n d l e r f o r a l l o c a e x c e p t i o n s
*
* The A L L O C A h a n d l e r i s e n t e r e d w h e n u s e r c o d e e x e c u t e s t h e M O V S P
* instruction a n d t h e c a l l e r ' s f r a m e i s n o t i n t h e r e g i s t e r f i l e .
*
2013-07-15 02:02:24 +04:00
* This a l g o r i t h m w a s t a k e n f r o m t h e R o s s M o r l e y ' s R T O S P o r t i n g L a y e r :
*
* / home/ r o s s / r t o s / p o r t i n g / X t e n s a R T O S - P o r t i n g L a y e r - 2 0 0 9 0 5 0 7 / x t e n s a _ v e c t o r s . S
*
* It l e v e r a g e s t h e e x i s t i n g w i n d o w s p i l l / f i l l r o u t i n e s a n d t h e i r s u p p o r t f o r
* double e x c e p t i o n s . T h e ' m o v s p ' i n s t r u c t i o n w i l l o n l y c a u s e a n e x c e p t i o n i f
* the n e x t w i n d o w n e e d s t o b e l o a d e d . I n f a c t t h i s A L L O C A e x c e p t i o n m a y b e
* replaced a t s o m e p o i n t b y c h a n g i n g t h e h a r d w a r e t o d o a u n d e r f l o w e x c e p t i o n
* of t h e p r o p e r s i z e i n s t e a d .
*
* This a l g o r i t h m s i m p l y b a c k s o u t t h e r e g i s t e r c h a n g e s s t a r t e d b y t h e u s e r
* excpetion h a n d l e r , m a k e s i t a p p e a r t h a t w e h a v e s t a r t e d a w i n d o w u n d e r f l o w
* by r o t a t i n g t h e w i n d o w b a c k a n d t h e n s e t t i n g t h e o l d w i n d o w b a s e ( O W B ) i n
* the ' p s ' r e g i s t e r w i t h t h e r o l l e d b a c k w i n d o w b a s e . T h e ' m o v s p ' i n s t r u c t i o n
* will b e r e - e x e c u t e d a n d t h i s t i m e s i n c e t h e n e x t w i n d o w f r a m e s i s i n t h e
* active A R r e g i s t e r s i t w o n ' t c a u s e a n e x c e p t i o n .
*
* If t h e W i n d o w U n d e r f l o w c o d e g e t s a T L B m i s s t h e p a g e w i l l g e t m a p p e d
* the t h e p a r t i a l w i n d e o w U n d e r f l o w w i l l b e h a n d e l e d i n t h e d o u b l e e x c e p t i o n
* handler.
2005-06-24 09:01:16 +04:00
*
* Entry c o n d i t i o n :
*
* a0 : trashed, o r i g i n a l v a l u e s a v e d o n s t a c k ( P T _ A R E G 0 )
* a1 : a1
* a2 : new s t a c k p o i n t e r , o r i g i n a l i n D E P C
2013-07-03 20:23:28 +04:00
* a3 : a3
2005-06-24 09:01:16 +04:00
* depc : a2 , o r i g i n a l v a l u e s a v e d o n s t a c k ( P T _ D E P C )
2013-07-03 20:23:28 +04:00
* excsave_1 : dispatch t a b l e
2005-06-24 09:01:16 +04:00
*
* PT_ D E P C > = V A L I D _ D O U B L E _ E X C E P T I O N _ A D D R E S S : d o u b l e e x c e p t i o n , D E P C
* < VALID_DOUBLE_EXCEPTION_ADDRESS : regular e x c e p t i o n
* /
ENTRY( f a s t _ a l l o c a )
2013-07-15 02:02:24 +04:00
rsr a0 , w i n d o w b a s e
rotw - 1
rsr a2 , p s
extui a3 , a2 , P S _ O W B _ S H I F T , P S _ O W B _ W I D T H
xor a3 , a3 , a4
l3 2 i a4 , a6 , P T _ A R E G 0
l3 2 i a1 , a6 , P T _ D E P C
rsr a6 , d e p c
wsr a1 , d e p c
slli a3 , a3 , P S _ O W B _ S H I F T
xor a2 , a2 , a3
wsr a2 , p s
rsync
2005-06-24 09:01:16 +04:00
2013-07-15 02:02:24 +04:00
_ bbci. l a4 , 3 1 , 4 f
rotw - 1
_ bbci. l a8 , 3 0 , 8 f
rotw - 1
j _ W i n d o w U n d e r f l o w12
8 : j _ W i n d o w U n d e r f l o w8
4 : j _ W i n d o w U n d e r f l o w4
2012-11-17 04:16:20 +04:00
ENDPROC( f a s t _ a l l o c a )
2005-06-24 09:01:16 +04:00
/ *
* fast s y s t e m c a l l s .
*
* WARNING : The k e r n e l d o e s n ' t s a v e t h e e n t i r e u s e r c o n t e x t b e f o r e
* handling a f a s t s y s t e m c a l l . T h e s e f u n c t i o n s a r e s m a l l a n d s h o r t ,
* usually o f f e r i n g s o m e f u n c t i o n a l i t y n o t a v a i l a b l e t o u s e r t a s k s .
*
* BE C A R E F U L T O P R E S E R V E T H E U S E R ' S C O N T E X T .
*
* Entry c o n d i t i o n :
*
* a0 : trashed, o r i g i n a l v a l u e s a v e d o n s t a c k ( P T _ A R E G 0 )
* a1 : a1
* a2 : new s t a c k p o i n t e r , o r i g i n a l i n D E P C
2013-07-03 20:23:28 +04:00
* a3 : a3
2005-06-24 09:01:16 +04:00
* depc : a2 , o r i g i n a l v a l u e s a v e d o n s t a c k ( P T _ D E P C )
2013-07-03 20:23:28 +04:00
* excsave_1 : dispatch t a b l e
2005-06-24 09:01:16 +04:00
* /
ENTRY( f a s t _ s y s c a l l _ k e r n e l )
/* Skip syscall. */
2012-10-15 03:55:38 +04:00
rsr a0 , e p c1
2005-06-24 09:01:16 +04:00
addi a0 , a0 , 3
2012-10-15 03:55:38 +04:00
wsr a0 , e p c1
2005-06-24 09:01:16 +04:00
l3 2 i a0 , a2 , P T _ D E P C
bgeui a0 , V A L I D _ D O U B L E _ E X C E P T I O N _ A D D R E S S , f a s t _ s y s c a l l _ u n r e c o v e r a b l e
2012-10-15 03:55:38 +04:00
rsr a0 , d e p c # g e t s y s c a l l - n r
2005-06-24 09:01:16 +04:00
_ beqz a0 , f a s t _ s y s c a l l _ s p i l l _ r e g i s t e r s
2006-12-10 13:18:52 +03:00
_ beqi a0 , _ _ N R _ x t e n s a , f a s t _ s y s c a l l _ x t e n s a
2005-06-24 09:01:16 +04:00
j k e r n e l _ e x c e p t i o n
2012-11-17 04:16:20 +04:00
ENDPROC( f a s t _ s y s c a l l _ k e r n e l )
2005-06-24 09:01:16 +04:00
ENTRY( f a s t _ s y s c a l l _ u s e r )
/* Skip syscall. */
2012-10-15 03:55:38 +04:00
rsr a0 , e p c1
2005-06-24 09:01:16 +04:00
addi a0 , a0 , 3
2012-10-15 03:55:38 +04:00
wsr a0 , e p c1
2005-06-24 09:01:16 +04:00
l3 2 i a0 , a2 , P T _ D E P C
bgeui a0 , V A L I D _ D O U B L E _ E X C E P T I O N _ A D D R E S S , f a s t _ s y s c a l l _ u n r e c o v e r a b l e
2012-10-15 03:55:38 +04:00
rsr a0 , d e p c # g e t s y s c a l l - n r
2005-06-24 09:01:16 +04:00
_ beqz a0 , f a s t _ s y s c a l l _ s p i l l _ r e g i s t e r s
2006-12-10 13:18:52 +03:00
_ beqi a0 , _ _ N R _ x t e n s a , f a s t _ s y s c a l l _ x t e n s a
2005-06-24 09:01:16 +04:00
j u s e r _ e x c e p t i o n
2012-11-17 04:16:20 +04:00
ENDPROC( f a s t _ s y s c a l l _ u s e r )
2005-06-24 09:01:16 +04:00
ENTRY( f a s t _ s y s c a l l _ u n r e c o v e r a b l e )
2012-11-29 04:53:51 +04:00
/* Restore all states. */
2005-06-24 09:01:16 +04:00
2012-11-29 04:53:51 +04:00
l3 2 i a0 , a2 , P T _ A R E G 0 # r e s t o r e a 0
xsr a2 , d e p c # r e s t o r e a 2 , d e p c
2005-06-24 09:01:16 +04:00
2012-11-29 04:53:51 +04:00
wsr a0 , e x c s a v e 1
movi a0 , u n r e c o v e r a b l e _ e x c e p t i o n
callx0 a0
2005-06-24 09:01:16 +04:00
2012-11-17 04:16:20 +04:00
ENDPROC( f a s t _ s y s c a l l _ u n r e c o v e r a b l e )
2005-06-24 09:01:16 +04:00
/ *
* sysxtensa s y s c a l l h a n d l e r
*
2006-12-10 13:18:52 +03:00
* int s y s x t e n s a ( S Y S _ X T E N S A _ A T O M I C _ S E T , p t r , v a l , u n u s e d ) ;
* int s y s x t e n s a ( S Y S _ X T E N S A _ A T O M I C _ A D D , p t r , v a l , u n u s e d ) ;
* int s y s x t e n s a ( S Y S _ X T E N S A _ A T O M I C _ E X G _ A D D , p t r , v a l , u n u s e d ) ;
* int s y s x t e n s a ( S Y S _ X T E N S A _ A T O M I C _ C M P _ S W P , p t r , o l d v a l , n e w v a l ) ;
* a2 a6 a3 a4 a5
2005-06-24 09:01:16 +04:00
*
* Entry c o n d i t i o n :
*
2006-12-10 13:18:52 +03:00
* a0 : a2 ( s y s c a l l - n r ) , o r i g i n a l v a l u e s a v e d o n s t a c k ( P T _ A R E G 0 )
2005-06-24 09:01:16 +04:00
* a1 : a1
2006-12-10 13:18:52 +03:00
* a2 : new s t a c k p o i n t e r , o r i g i n a l i n a0 a n d D E P C
2013-07-03 20:23:28 +04:00
* a3 : a3
2006-12-10 13:18:52 +03:00
* a4 . . a15 : u n c h a n g e d
2005-06-24 09:01:16 +04:00
* depc : a2 , o r i g i n a l v a l u e s a v e d o n s t a c k ( P T _ D E P C )
2013-07-03 20:23:28 +04:00
* excsave_1 : dispatch t a b l e
2005-06-24 09:01:16 +04:00
*
* PT_ D E P C > = V A L I D _ D O U B L E _ E X C E P T I O N _ A D D R E S S : d o u b l e e x c e p t i o n , D E P C
* < VALID_DOUBLE_EXCEPTION_ADDRESS : regular e x c e p t i o n
*
* Note : we d o n ' t h a v e t o s a v e a2 ; a2 holds the return value
*
* We u s e t h e t w o m a c r o s T R Y a n d C A T C H :
*
* TRY a d d s a n e n t r y t o t h e _ _ e x _ t a b l e f i x u p t a b l e f o r t h e i m m e d i a t e l y
* following i n s t r u c t i o n .
*
2011-03-31 05:57:33 +04:00
* CATCH c a t c h e s a n y e x c e p t i o n t h a t o c c u r r e d a t o n e o f t h e p r e c e d i n g T R Y
2005-06-24 09:01:16 +04:00
* statements a n d c o n t i n u e s f r o m t h e r e
*
* Usage T R Y l 3 2 i a0 , a1 , 0
* < other c o d e >
* done : rfe
* CATCH < s e t r e t u r n c o d e >
* j d o n e
* /
2014-08-07 03:32:30 +04:00
# ifdef C O N F I G _ F A S T _ S Y S C A L L _ X T E N S A
2005-06-24 09:01:16 +04:00
# define T R Y \
.section _ _ ex_ t a b l e , " a " ; \
.word 6 6 f, 6 7 f ; \
.text ; \
66 :
# define C A T C H \
67 :
2006-12-10 13:18:52 +03:00
ENTRY( f a s t _ s y s c a l l _ x t e n s a )
2005-06-24 09:01:16 +04:00
2006-12-10 13:18:52 +03:00
s3 2 i a7 , a2 , P T _ A R E G 7 # w e n e e d a n a d d i t i o n a l r e g i s t e r
2005-06-24 09:01:16 +04:00
movi a7 , 4 # s i z e o f ( u n s i g n e d i n t )
2006-12-10 13:18:52 +03:00
access_ o k a3 , a7 , a0 , a2 , . L e a c # a 0 : s c r a t c h r e g , a2 : s p
2005-06-24 09:01:16 +04:00
2014-07-31 22:40:57 +04:00
_ bgeui a6 , S Y S _ X T E N S A _ C O U N T , . L i l l
_ bnei a6 , S Y S _ X T E N S A _ A T O M I C _ C M P _ S W P , . L n s w p
2005-06-24 09:01:16 +04:00
2006-12-10 13:18:52 +03:00
/* Fall through for ATOMIC_CMP_SWP. */
2005-06-24 09:01:16 +04:00
.Lswp : /* Atomic compare and swap */
2006-12-10 13:18:52 +03:00
TRY l 3 2 i a0 , a3 , 0 # r e a d o l d v a l u e
bne a0 , a4 , 1 f # s a m e a s o l d v a l u e ? j u m p
TRY s32 i a5 , a3 , 0 # d i f f e r e n t , m o d i f y v a l u e
l3 2 i a7 , a2 , P T _ A R E G 7 # r e s t o r e a 7
l3 2 i a0 , a2 , P T _ A R E G 0 # r e s t o r e a 0
movi a2 , 1 # a n d r e t u r n 1
rfe
2005-06-24 09:01:16 +04:00
2006-12-10 13:18:52 +03:00
1 : l3 2 i a7 , a2 , P T _ A R E G 7 # r e s t o r e a 7
l3 2 i a0 , a2 , P T _ A R E G 0 # r e s t o r e a 0
movi a2 , 0 # r e t u r n 0 ( n o t e t h a t w e c a n n o t s e t
rfe
2005-06-24 09:01:16 +04:00
2006-12-10 13:18:52 +03:00
.Lnswp : /* Atomic set, add, and exg_add. */
2005-06-24 09:01:16 +04:00
2006-12-10 13:18:52 +03:00
TRY l 3 2 i a7 , a3 , 0 # o r i g
2014-07-31 22:40:57 +04:00
addi a6 , a6 , - S Y S _ X T E N S A _ A T O M I C _ S E T
2006-12-10 13:18:52 +03:00
add a0 , a4 , a7 # + a r g
moveqz a0 , a4 , a6 # s e t
2014-07-31 22:40:57 +04:00
addi a6 , a6 , S Y S _ X T E N S A _ A T O M I C _ S E T
2006-12-10 13:18:52 +03:00
TRY s32 i a0 , a3 , 0 # w r i t e n e w v a l u e
2005-06-24 09:01:16 +04:00
2006-12-10 13:18:52 +03:00
mov a0 , a2
2005-06-24 09:01:16 +04:00
mov a2 , a7
2006-12-10 13:18:52 +03:00
l3 2 i a7 , a0 , P T _ A R E G 7 # r e s t o r e a 7
l3 2 i a0 , a0 , P T _ A R E G 0 # r e s t o r e a 0
2005-06-24 09:01:16 +04:00
rfe
CATCH
2006-12-10 13:18:52 +03:00
.Leac : l3 2 i a7 , a2 , P T _ A R E G 7 # r e s t o r e a 7
l3 2 i a0 , a2 , P T _ A R E G 0 # r e s t o r e a 0
movi a2 , - E F A U L T
rfe
2014-07-31 22:40:57 +04:00
.Lill : l3 2 i a7 , a2 , P T _ A R E G 7 # r e s t o r e a 7
2006-12-10 13:18:52 +03:00
l3 2 i a0 , a2 , P T _ A R E G 0 # r e s t o r e a 0
movi a2 , - E I N V A L
rfe
2012-11-17 04:16:20 +04:00
ENDPROC( f a s t _ s y s c a l l _ x t e n s a )
2005-06-24 09:01:16 +04:00
2014-08-07 03:32:30 +04:00
# else / * C O N F I G _ F A S T _ S Y S C A L L _ X T E N S A * /
ENTRY( f a s t _ s y s c a l l _ x t e n s a )
l3 2 i a0 , a2 , P T _ A R E G 0 # r e s t o r e a 0
movi a2 , - E N O S Y S
rfe
ENDPROC( f a s t _ s y s c a l l _ x t e n s a )
# endif / * C O N F I G _ F A S T _ S Y S C A L L _ X T E N S A * /
2005-06-24 09:01:16 +04:00
/ * fast_ s y s c a l l _ s p i l l _ r e g i s t e r s .
*
* Entry c o n d i t i o n :
*
* a0 : trashed, o r i g i n a l v a l u e s a v e d o n s t a c k ( P T _ A R E G 0 )
* a1 : a1
* a2 : new s t a c k p o i n t e r , o r i g i n a l i n D E P C
2013-07-03 20:23:28 +04:00
* a3 : a3
2005-06-24 09:01:16 +04:00
* depc : a2 , o r i g i n a l v a l u e s a v e d o n s t a c k ( P T _ D E P C )
2013-07-03 20:23:28 +04:00
* excsave_1 : dispatch t a b l e
2005-06-24 09:01:16 +04:00
*
* Note : We a s s u m e t h e s t a c k p o i n t e r i s E X C _ T A B L E _ K S T K i n t h e f i x u p h a n d l e r .
* /
2014-08-07 03:32:30 +04:00
# ifdef C O N F I G _ F A S T _ S Y S C A L L _ S P I L L _ R E G I S T E R S
2005-06-24 09:01:16 +04:00
ENTRY( f a s t _ s y s c a l l _ s p i l l _ r e g i s t e r s )
/* Register a FIXUP handler (pass current wb as a parameter) */
2013-07-03 20:23:28 +04:00
xsr a3 , e x c s a v e 1
2005-06-24 09:01:16 +04:00
movi a0 , f a s t _ s y s c a l l _ s p i l l _ r e g i s t e r s _ f i x u p
s3 2 i a0 , a3 , E X C _ T A B L E _ F I X U P
2012-10-15 03:55:38 +04:00
rsr a0 , w i n d o w b a s e
2005-06-24 09:01:16 +04:00
s3 2 i a0 , a3 , E X C _ T A B L E _ P A R A M
2013-07-03 20:23:28 +04:00
xsr a3 , e x c s a v e 1 # r e s t o r e a 3 a n d e x c s a v e _ 1
2005-06-24 09:01:16 +04:00
2013-07-03 20:23:28 +04:00
/* Save a3, a4 and SAR on stack. */
2005-06-24 09:01:16 +04:00
2012-10-15 03:55:38 +04:00
rsr a0 , s a r
2005-06-24 09:01:16 +04:00
s3 2 i a3 , a2 , P T _ A R E G 3
2014-01-29 10:09:51 +04:00
s3 2 i a0 , a2 , P T _ S A R
2005-06-24 09:01:16 +04:00
2014-01-29 10:09:51 +04:00
/* The spill routine might clobber a4, a7, a8, a11, a12, and a15. */
2005-06-24 09:01:16 +04:00
2014-01-29 10:09:51 +04:00
s3 2 i a4 , a2 , P T _ A R E G 4
2008-02-13 00:17:07 +03:00
s3 2 i a7 , a2 , P T _ A R E G 7
2014-01-29 10:09:51 +04:00
s3 2 i a8 , a2 , P T _ A R E G 8
2008-02-13 00:17:07 +03:00
s3 2 i a11 , a2 , P T _ A R E G 1 1
2014-01-29 10:09:51 +04:00
s3 2 i a12 , a2 , P T _ A R E G 1 2
2008-02-13 00:17:07 +03:00
s3 2 i a15 , a2 , P T _ A R E G 1 5
2005-06-24 09:01:16 +04:00
2014-01-29 10:09:51 +04:00
/ *
* Rotate w s s o t h a t t h e c u r r e n t w i n d o w b a s e i s a t b i t 0 .
* Assume w s = x x x w w w1 y y ( w w w1 c u r r e n t w i n d o w f r a m e ) .
* Rotate w s r i g h t s o t h a t a4 = y y x x x w w w1 .
* /
rsr a0 , w i n d o w b a s e
rsr a3 , w i n d o w s t a r t # a 3 = x x x w w w1 y y
ssr a0 # h o l d s W B
slli a0 , a3 , W S B I T S
or a3 , a3 , a0 # a 3 = x x x w w w1 y y x x x w w w1 y y
srl a3 , a3 # a 3 = 0 0 x x x w w w1 y y x x x w w w1
/* We are done if there are no more than the current register frame. */
extui a3 , a3 , 1 , W S B I T S - 1 # a 3 = 0 y y x x x w w w
movi a0 , ( 1 < < ( W S B I T S - 1 ) )
_ beqz a3 , . L n o s p i l l # o n l y o n e a c t i v e f r a m e ? j u m p
/* We want 1 at the top, so that we return to the current windowbase */
or a3 , a3 , a0 # 1 y y x x x w w w
/* Skip empty frames - get 'oldest' WINDOWSTART-bit. */
wsr a3 , w i n d o w s t a r t # s a v e s h i f t e d w i n d o w s t a r t
neg a0 , a3
and a3 , a0 , a3 # f i r s t b i t s e t f r o m r i g h t : 000010000
ffs_ w s a0 , a3 # a 0 : s h i f t s t o s k i p e m p t y f r a m e s
movi a3 , W S B I T S
sub a0 , a3 , a0 # W S B I T S - a 0 : n u m b e r o f 0 - b i t s f r o m r i g h t
ssr a0 # s a v e i n S A R f o r l a t e r .
rsr a3 , w i n d o w b a s e
add a3 , a3 , a0
wsr a3 , w i n d o w b a s e
rsync
rsr a3 , w i n d o w s t a r t
srl a3 , a3 # s h i f t w i n d o w s t a r t
/ * WB i s n o w j u s t o n e f r a m e b e l o w t h e o l d e s t f r a m e i n t h e r e g i s t e r
window. W S i s s h i f t e d s o t h e o l d e s t f r a m e i s i n b i t 0 , t h u s , W B
and W S d i f f e r b y o n e 4 - r e g i s t e r f r a m e . * /
/ * Save f r a m e s . D e p e n d i n g w h a t c a l l w a s u s e d ( c a l l 4 , c a l l 8 , c a l l 1 2 ) ,
* we h a v e t o s a v e 4 ,8 . o r 1 2 r e g i s t e r s .
* /
.Lloop : _ bbsi. l a3 , 1 , . L c4
_ bbci. l a3 , 2 , . L c12
.Lc8 : s3 2 e a4 , a13 , - 1 6
l3 2 e a4 , a5 , - 1 2
s3 2 e a8 , a4 , - 3 2
s3 2 e a5 , a13 , - 1 2
s3 2 e a6 , a13 , - 8
s3 2 e a7 , a13 , - 4
s3 2 e a9 , a4 , - 2 8
s3 2 e a10 , a4 , - 2 4
s3 2 e a11 , a4 , - 2 0
srli a11 , a3 , 2 # s h i f t w i n d o w b a s e b y 2
rotw 2
_ bnei a3 , 1 , . L l o o p
j . L e x i t
.Lc4 : s3 2 e a4 , a9 , - 1 6
s3 2 e a5 , a9 , - 1 2
s3 2 e a6 , a9 , - 8
s3 2 e a7 , a9 , - 4
srli a7 , a3 , 1
rotw 1
_ bnei a3 , 1 , . L l o o p
j . L e x i t
.Lc12 : _ bbci. l a3 , 3 , . L i n v a l i d _ m a s k # b i t 2 s h o u l d n ' t b e z e r o !
/* 12-register frame (call12) */
l3 2 e a0 , a5 , - 1 2
s3 2 e a8 , a0 , - 4 8
mov a8 , a0
s3 2 e a9 , a8 , - 4 4
s3 2 e a10 , a8 , - 4 0
s3 2 e a11 , a8 , - 3 6
s3 2 e a12 , a8 , - 3 2
s3 2 e a13 , a8 , - 2 8
s3 2 e a14 , a8 , - 2 4
s3 2 e a15 , a8 , - 2 0
srli a15 , a3 , 3
/ * The s t a c k p o i n t e r f o r a4 . . a7 i s o u t o f r e a c h , s o w e r o t a t e t h e
* window, g r a b t h e s t a c k p o i n t e r , a n d r o t a t e b a c k .
* Alternatively, w e c o u l d a l s o u s e t h e f o l l o w i n g a p p r o a c h , b u t t h a t
* makes t h e f i x u p r o u t i n e m u c h m o r e c o m p l i c a t e d :
* rotw 1
* s3 2 e a0 , a13 , - 1 6
* . . .
* rotw 2
* /
rotw 1
mov a4 , a13
rotw - 1
s3 2 e a4 , a8 , - 1 6
s3 2 e a5 , a8 , - 1 2
s3 2 e a6 , a8 , - 8
s3 2 e a7 , a8 , - 4
rotw 3
_ beqi a3 , 1 , . L e x i t
j . L l o o p
.Lexit :
/* Done. Do the final rotation and set WS */
rotw 1
rsr a3 , w i n d o w b a s e
ssl a3
movi a3 , 1
sll a3 , a3
wsr a3 , w i n d o w s t a r t
.Lnospill :
2005-06-24 09:01:16 +04:00
/* Advance PC, restore registers and SAR, and return from exception. */
2014-01-29 10:09:51 +04:00
l3 2 i a3 , a2 , P T _ S A R
2005-06-24 09:01:16 +04:00
l3 2 i a0 , a2 , P T _ A R E G 0
2012-10-15 03:55:38 +04:00
wsr a3 , s a r
2005-06-24 09:01:16 +04:00
l3 2 i a3 , a2 , P T _ A R E G 3
/* Restore clobbered registers. */
2014-01-29 10:09:51 +04:00
l3 2 i a4 , a2 , P T _ A R E G 4
2008-02-13 00:17:07 +03:00
l3 2 i a7 , a2 , P T _ A R E G 7
2014-01-29 10:09:51 +04:00
l3 2 i a8 , a2 , P T _ A R E G 8
2008-02-13 00:17:07 +03:00
l3 2 i a11 , a2 , P T _ A R E G 1 1
2014-01-29 10:09:51 +04:00
l3 2 i a12 , a2 , P T _ A R E G 1 2
2008-02-13 00:17:07 +03:00
l3 2 i a15 , a2 , P T _ A R E G 1 5
2005-06-24 09:01:16 +04:00
movi a2 , 0
rfe
2014-01-29 10:09:51 +04:00
.Linvalid_mask :
/ * We g e t h e r e b e c a u s e o f a n u n r e c o v e r a b l e e r r o r i n t h e w i n d o w
* registers, s o s e t u p a d u m m y f r a m e a n d k i l l t h e u s e r a p p l i c a t i o n .
* Note : We a s s u m e E X C _ T A B L E _ K S T K c o n t a i n s a v a l i d s t a c k p o i n t e r .
* /
movi a0 , 1
movi a1 , 0
wsr a0 , w i n d o w s t a r t
wsr a1 , w i n d o w b a s e
rsync
movi a0 , 0
rsr a3 , e x c s a v e 1
l3 2 i a1 , a3 , E X C _ T A B L E _ K S T K
movi a4 , ( 1 < < P S _ W O E _ B I T ) | L O C K L E V E L
wsr a4 , p s
rsync
movi a6 , S I G S E G V
movi a4 , d o _ e x i t
callx4 a4
/* shouldn't return, so panic */
wsr a0 , e x c s a v e 1
movi a0 , u n r e c o v e r a b l e _ e x c e p t i o n
callx0 a0 # s h o u l d n o t r e t u r n
1 : j 1 b
2012-11-17 04:16:20 +04:00
ENDPROC( f a s t _ s y s c a l l _ s p i l l _ r e g i s t e r s )
2005-06-24 09:01:16 +04:00
/ * Fixup h a n d l e r .
*
* We g e t h e r e i f t h e s p i l l r o u t i n e c a u s e s a n e x c e p t i o n , e . g . t l b m i s s .
* We b a s i c a l l y r e s t o r e W I N D O W B A S E a n d W I N D O W S T A R T t o t h e c o n d i t i o n w h e n
* we e n t e r e d t h e s p i l l r o u t i n e a n d j u m p t o t h e u s e r e x c e p t i o n h a n d l e r .
*
2013-10-30 16:18:25 +04:00
* Note t h a t w e o n l y n e e d t o r e s t o r e t h e b i t s i n w i n d o w s t a r t t h a t h a v e n o t
* been s p i l l e d y e t b y t h e _ s p i l l _ r e g i s t e r r o u t i n e . L u c k i l y , a3 c o n t a i n s a
* rotated w i n d o w s t a r t w i t h o n l y t h o s e b i t s s e t f o r f r a m e s t h a t h a v e n ' t b e e n
* spilled y e t . B e c a u s e a3 i s r o t a t e d s u c h t h a t b i t 0 r e p r e s e n t s t h e r e g i s t e r
* frame f o r t h e c u r r e n t w i n d o w b a s e - 1 , w e n e e d t o r o t a t e a3 l e f t b y t h e
* value o f t h e c u r r e n t w i n d o w b a s e + 1 a n d m o v e i t t o w i n d o w s t a r t .
*
2005-06-24 09:01:16 +04:00
* a0 : value o f d e p c , o r i g i n a l v a l u e i n d e p c
* a2 : trashed, o r i g i n a l v a l u e i n E X C _ T A B L E _ D O U B L E _ S A V E
* a3 : exctable, o r i g i n a l v a l u e i n e x c s a v e 1
* /
2013-10-15 02:22:42 +04:00
ENTRY( f a s t _ s y s c a l l _ s p i l l _ r e g i s t e r s _ f i x u p )
2005-06-24 09:01:16 +04:00
2012-10-15 03:55:38 +04:00
rsr a2 , w i n d o w b a s e # g e t c u r r e n t w i n d o w b a s e ( a 2 i s s a v e d )
xsr a0 , d e p c # r e s t o r e d e p c a n d a 0
2005-06-24 09:01:16 +04:00
ssl a2 # s e t s h i f t ( 32 - W B )
/ * We n e e d t o m a k e s u r e t h e c u r r e n t r e g i s t e r s ( a0 - a3 ) a r e p r e s e r v e d .
* To d o t h i s , w e s i m p l y s e t t h e b i t f o r t h e c u r r e n t w i n d o w f r a m e
* in W S , s o t h a t t h e e x c e p t i o n h a n d l e r s s a v e t h e m t o t h e t a s k s t a c k .
2013-10-30 16:18:25 +04:00
*
* Note : we u s e a3 t o s e t t h e w i n d o w b a s e , s o w e t a k e a s p e c i a l c a r e
* of i t , s a v i n g i t i n t h e o r i g i n a l _ s p i l l _ r e g i s t e r s f r a m e a c r o s s
* the e x c e p t i o n h a n d l e r c a l l .
2005-06-24 09:01:16 +04:00
* /
2013-07-03 20:23:28 +04:00
xsr a3 , e x c s a v e 1 # g e t s p i l l - m a s k
2013-10-15 02:22:42 +04:00
slli a3 , a3 , 1 # s h i f t l e f t b y o n e
2013-10-30 16:18:25 +04:00
addi a3 , a3 , 1 # s e t t h e b i t f o r t h e c u r r e n t w i n d o w f r a m e
2005-06-24 09:01:16 +04:00
2013-10-15 02:22:42 +04:00
slli a2 , a3 , 3 2 - W S B I T S
src a2 , a3 , a2 # a 2 = x x w w w1 y y x x x w w w1 y y . . . . . .
2012-10-15 03:55:38 +04:00
wsr a2 , w i n d o w s t a r t # s e t c o r r e c t e d w i n d o w s t a r t
2005-06-24 09:01:16 +04:00
2013-10-15 02:22:42 +04:00
srli a3 , a3 , 1
rsr a2 , e x c s a v e 1
l3 2 i a2 , a2 , E X C _ T A B L E _ D O U B L E _ S A V E # r e s t o r e a 2
xsr a2 , e x c s a v e 1
s3 2 i a3 , a2 , E X C _ T A B L E _ D O U B L E _ S A V E # s a v e a 3
l3 2 i a3 , a2 , E X C _ T A B L E _ P A R A M # o r i g i n a l W B ( i n u s e r t a s k )
xsr a2 , e x c s a v e 1
2005-06-24 09:01:16 +04:00
/ * Return t o t h e o r i g i n a l ( u s e r t a s k ) W I N D O W B A S E .
* We l e a v e t h e f o l l o w i n g f r a m e b e h i n d :
* a0 , a1 , a2 s a m e
2013-10-15 02:22:42 +04:00
* a3 : trashed ( s a v e d i n E X C _ T A B L E _ D O U B L E _ S A V E )
2005-06-24 09:01:16 +04:00
* depc : depc ( w e h a v e t o r e t u r n t o t h a t a d d r e s s )
2013-10-15 02:22:42 +04:00
* excsave_1 : exctable
2005-06-24 09:01:16 +04:00
* /
2012-10-15 03:55:38 +04:00
wsr a3 , w i n d o w b a s e
2005-06-24 09:01:16 +04:00
rsync
/ * We a r e n o w i n t h e o r i g i n a l f r a m e w h e n w e e n t e r e d _ s p i l l _ r e g i s t e r s :
* a0 : return a d d r e s s
* a1 : used, s t a c k p o i n t e r
* a2 : kernel s t a c k p o i n t e r
2013-10-15 02:22:42 +04:00
* a3 : available
2005-06-24 09:01:16 +04:00
* depc : exception a d d r e s s
2013-10-15 02:22:42 +04:00
* excsave : exctable
2005-06-24 09:01:16 +04:00
* Note : This f r a m e m i g h t b e t h e s a m e a s a b o v e .
* /
/* Setup stack pointer. */
addi a2 , a2 , - P T _ U S E R _ S I Z E
s3 2 i a0 , a2 , P T _ A R E G 0
/* Make sure we return to this fixup handler. */
movi a3 , f a s t _ s y s c a l l _ s p i l l _ r e g i s t e r s _ f i x u p _ r e t u r n
s3 2 i a3 , a2 , P T _ D E P C # s e t u p d e p c
/* Jump to the exception handler. */
2013-07-03 20:23:28 +04:00
rsr a3 , e x c s a v e 1
2012-10-15 03:55:38 +04:00
rsr a0 , e x c c a u s e
2012-11-29 04:53:51 +04:00
addx4 a0 , a0 , a3 # f i n d e n t r y i n t a b l e
l3 2 i a0 , a0 , E X C _ T A B L E _ F A S T _ U S E R # l o a d h a n d l e r
2013-10-15 02:22:42 +04:00
l3 2 i a3 , a3 , E X C _ T A B L E _ D O U B L E _ S A V E
2012-11-29 04:53:51 +04:00
jx a0
2005-06-24 09:01:16 +04:00
2013-10-15 02:22:42 +04:00
ENDPROC( f a s t _ s y s c a l l _ s p i l l _ r e g i s t e r s _ f i x u p )
ENTRY( f a s t _ s y s c a l l _ s p i l l _ r e g i s t e r s _ f i x u p _ r e t u r n )
2005-06-24 09:01:16 +04:00
/* When we return here, all registers have been restored (a2: DEPC) */
2012-10-15 03:55:38 +04:00
wsr a2 , d e p c # e x c e p t i o n a d d r e s s
2005-06-24 09:01:16 +04:00
/* Restore fixup handler. */
2013-10-15 02:22:42 +04:00
rsr a2 , e x c s a v e 1
s3 2 i a3 , a2 , E X C _ T A B L E _ D O U B L E _ S A V E
movi a3 , f a s t _ s y s c a l l _ s p i l l _ r e g i s t e r s _ f i x u p
s3 2 i a3 , a2 , E X C _ T A B L E _ F I X U P
rsr a3 , w i n d o w b a s e
s3 2 i a3 , a2 , E X C _ T A B L E _ P A R A M
l3 2 i a2 , a2 , E X C _ T A B L E _ K S T K
2005-06-24 09:01:16 +04:00
/* Load WB at the time the exception occurred. */
2012-10-15 03:55:38 +04:00
rsr a3 , s a r # W B i s s t i l l i n S A R
2005-06-24 09:01:16 +04:00
neg a3 , a3
2012-10-15 03:55:38 +04:00
wsr a3 , w i n d o w b a s e
2005-06-24 09:01:16 +04:00
rsync
2013-10-15 02:22:42 +04:00
rsr a3 , e x c s a v e 1
l3 2 i a3 , a3 , E X C _ T A B L E _ D O U B L E _ S A V E
2005-06-24 09:01:16 +04:00
rfde
2013-10-15 02:22:42 +04:00
ENDPROC( f a s t _ s y s c a l l _ s p i l l _ r e g i s t e r s _ f i x u p _ r e t u r n )
2005-06-24 09:01:16 +04:00
2014-08-07 03:32:30 +04:00
# else / * C O N F I G _ F A S T _ S Y S C A L L _ S P I L L _ R E G I S T E R S * /
ENTRY( f a s t _ s y s c a l l _ s p i l l _ r e g i s t e r s )
l3 2 i a0 , a2 , P T _ A R E G 0 # r e s t o r e a 0
movi a2 , - E N O S Y S
rfe
ENDPROC( f a s t _ s y s c a l l _ s p i l l _ r e g i s t e r s )
# endif / * C O N F I G _ F A S T _ S Y S C A L L _ S P I L L _ R E G I S T E R S * /
2009-03-04 18:21:31 +03:00
# ifdef C O N F I G _ M M U
2005-06-24 09:01:16 +04:00
/ *
* We s h o u l d n e v e r g e t h e r e . B a i l o u t !
* /
ENTRY( f a s t _ s e c o n d _ l e v e l _ m i s s _ d o u b l e _ k e r n e l )
1 : movi a0 , u n r e c o v e r a b l e _ e x c e p t i o n
callx0 a0 # s h o u l d n o t r e t u r n
1 : j 1 b
2012-11-17 04:16:20 +04:00
ENDPROC( f a s t _ s e c o n d _ l e v e l _ m i s s _ d o u b l e _ k e r n e l )
2005-06-24 09:01:16 +04:00
/ * First- l e v e l e n t r y h a n d l e r f o r u s e r , k e r n e l , a n d d o u b l e 2 n d - l e v e l
* TLB m i s s e x c e p t i o n s . N o t e t h a t f o r n o w , u s e r a n d k e r n e l m i s s
* exceptions s h a r e t h e s a m e e n t r y p o i n t a n d a r e h a n d l e d i d e n t i c a l l y .
*
* An o l d , l e s s - e f f i c i e n t C v e r s i o n o f t h i s f u n c t i o n u s e d t o e x i s t .
* We i n c l u d e i t b e l o w , i n t e r l e a v e d a s c o m m e n t s , f o r r e f e r e n c e .
*
* Entry c o n d i t i o n :
*
* a0 : trashed, o r i g i n a l v a l u e s a v e d o n s t a c k ( P T _ A R E G 0 )
* a1 : a1
* a2 : new s t a c k p o i n t e r , o r i g i n a l i n D E P C
2013-07-03 20:23:28 +04:00
* a3 : a3
2005-06-24 09:01:16 +04:00
* depc : a2 , o r i g i n a l v a l u e s a v e d o n s t a c k ( P T _ D E P C )
2013-07-03 20:23:28 +04:00
* excsave_1 : dispatch t a b l e
2005-06-24 09:01:16 +04:00
*
* PT_ D E P C > = V A L I D _ D O U B L E _ E X C E P T I O N _ A D D R E S S : d o u b l e e x c e p t i o n , D E P C
* < VALID_DOUBLE_EXCEPTION_ADDRESS : regular e x c e p t i o n
* /
ENTRY( f a s t _ s e c o n d _ l e v e l _ m i s s )
2013-07-03 20:23:28 +04:00
/* Save a1 and a3. Note: we don't expect a double exception. */
2005-06-24 09:01:16 +04:00
s3 2 i a1 , a2 , P T _ A R E G 1
2013-07-03 20:23:28 +04:00
s3 2 i a3 , a2 , P T _ A R E G 3
2005-06-24 09:01:16 +04:00
/ * We n e e d t o m a p t h e p a g e o f P T E s f o r t h e u s e r t a s k . F i n d
* the p o i n t e r t o t h a t p a g e . A l s o , i t ' s p o s s i b l e f o r t s k - > m m
* to b e N U L L w h i l e t s k - > a c t i v e _ m m i s n o n z e r o i f w e f a u l t e d o n
* a v m a l l o c a d d r e s s . I n t h a t r a r e c a s e , w e m u s t u s e
* active_ m m i n s t e a d t o a v o i d a f a u l t i n t h i s h a n d l e r . S e e
*
* http : / / mail. n l . l i n u x . o r g / l i n u x - m m / 2 0 0 2 - 0 8 / m s g 0 0 2 5 8 . h t m l
* ( or s e a r c h I n t e r n e t o n " m m v s . a c t i v e _ m m " )
*
* if ( ! m m )
* mm = t s k - > a c t i v e _ m m ;
* pgd = p g d _ o f f s e t ( m m , r e g s - > e x c v a d d r ) ;
* pmd = p m d _ o f f s e t ( p g d , r e g s - > e x c v a d d r ) ;
* pmdval = * p m d ;
* /
GET_ C U R R E N T ( a1 ,a2 )
l3 2 i a0 , a1 , T A S K _ M M # t s k - > m m
beqz a0 , 9 f
2012-10-15 03:55:38 +04:00
8 : rsr a3 , e x c v a d d r # f a u l t a d d r e s s
2007-08-07 10:57:57 +04:00
_ PGD_ O F F S E T ( a0 , a3 , a1 )
2005-06-24 09:01:16 +04:00
l3 2 i a0 , a0 , 0 # r e a d p m d v a l
beqz a0 , 2 f
/ * Read p t e v a d d r a n d c o n v e r t t o t o p o f p a g e - t a b l e p a g e .
*
* vpnval = r e a d _ p t e v a d d r _ r e g i s t e r ( ) & P A G E _ M A S K ;
* vpnval + = D T L B _ W A Y _ P G T A B L E ;
* pteval = m k _ p t e ( v i r t _ t o _ p a g e ( p m d _ v a l ( p m d v a l ) ) , P A G E _ K E R N E L ) ;
* write_ d t l b _ e n t r y ( p t e v a l , v p n v a l ) ;
*
* The m e s s y c o m p u t a t i o n f o r ' p t e v a l ' a b o v e r e a l l y s i m p l i f i e s
* into t h e f o l l o w i n g :
*
2007-08-22 21:14:51 +04:00
* pteval = ( ( p m d v a l - P A G E _ O F F S E T ) & P A G E _ M A S K ) | P A G E _ D I R E C T O R Y
2005-06-24 09:01:16 +04:00
* /
2012-10-18 10:08:20 +04:00
movi a1 , ( - P A G E _ O F F S E T ) & 0 x f f f f f f f f
2005-06-24 09:01:16 +04:00
add a0 , a0 , a1 # p m d v a l - P A G E _ O F F S E T
extui a1 , a0 , 0 , P A G E _ S H I F T # . . . & P A G E _ M A S K
xor a0 , a0 , a1
2007-08-07 10:57:57 +04:00
movi a1 , _ P A G E _ D I R E C T O R Y
2005-06-24 09:01:16 +04:00
or a0 , a0 , a1 # . . . | P A G E _ D I R E C T O R Y
2007-08-07 10:57:57 +04:00
/ *
2007-08-22 21:14:51 +04:00
* We u t i l i z e a l l t h r e e w i r e d - w a y s ( 7 - 9 ) t o h o l d p m d t r a n s l a t i o n s .
2007-08-07 10:57:57 +04:00
* Memory r e g i o n s a r e m a p p e d t o t h e D T L B s a c c o r d i n g t o b i t s 2 8 a n d 2 9 .
* This a l l o w s t o m a p t h e t h r e e m o s t c o m m o n r e g i o n s t o t h r e e d i f f e r e n t
* DTLBs :
* 0 , 1 - > way 7 p r o g r a m ( 0 0 4 0 . 0 0 0 0 ) a n d v i r t u a l ( c00 0 . 0 0 0 0 )
* 2 - > way 8 s h a r e d l i b a r i e s ( 2 0 0 0 . 0 0 0 0 )
* 3 - > way 0 s t a c k ( 3 0 0 0 . 0 0 0 0 )
* /
extui a3 , a3 , 2 8 , 2 # a d d r . b i t 28 a n d 2 9 0 ,1 ,2 ,3
2012-10-15 03:55:38 +04:00
rsr a1 , p t e v a d d r
2007-08-07 10:57:57 +04:00
addx2 a3 , a3 , a3 # - > 0 ,3 ,6 ,9
2005-06-24 09:01:16 +04:00
srli a1 , a1 , P A G E _ S H I F T
2007-08-07 10:57:57 +04:00
extui a3 , a3 , 2 , 2 # - > 0 ,0 ,1 ,2
2005-06-24 09:01:16 +04:00
slli a1 , a1 , P A G E _ S H I F T # p t e v a d d r & P A G E _ M A S K
2007-08-07 10:57:57 +04:00
addi a3 , a3 , D T L B _ W A Y _ P G D
add a1 , a1 , a3 # . . . + w a y _ n u m b e r
2005-06-24 09:01:16 +04:00
2007-08-07 10:57:57 +04:00
3 : wdtlb a0 , a1
2005-06-24 09:01:16 +04:00
dsync
/* Exit critical section. */
2013-07-03 20:23:28 +04:00
4 : rsr a3 , e x c s a v e 1
2005-06-24 09:01:16 +04:00
movi a0 , 0
s3 2 i a0 , a3 , E X C _ T A B L E _ F I X U P
/* Restore the working registers, and return. */
l3 2 i a0 , a2 , P T _ A R E G 0
l3 2 i a1 , a2 , P T _ A R E G 1
2013-07-03 20:23:28 +04:00
l3 2 i a3 , a2 , P T _ A R E G 3
2005-06-24 09:01:16 +04:00
l3 2 i a2 , a2 , P T _ D E P C
bgeui a2 , V A L I D _ D O U B L E _ E X C E P T I O N _ A D D R E S S , 1 f
/* Restore excsave1 and return. */
2012-10-15 03:55:38 +04:00
rsr a2 , d e p c
2005-06-24 09:01:16 +04:00
rfe
/* Return from double exception. */
2012-10-15 03:55:38 +04:00
1 : xsr a2 , d e p c
2005-06-24 09:01:16 +04:00
esync
rfde
9 : l3 2 i a0 , a1 , T A S K _ A C T I V E _ M M # u n l i k e l y c a s e m m = = 0
j 8 b
2007-08-22 21:14:51 +04:00
# if ( D C A C H E _ W A Y _ S I Z E > P A G E _ S I Z E )
2 : / * Special c a s e f o r c a c h e a l i a s i n g .
* We ( s h o u l d ) o n l y g e t h e r e i f a c l e a r _ u s e r _ p a g e , c o p y _ u s e r _ p a g e
* or t h e a l i a s e d c a c h e f l u s h f u n c t i o n s g o t p r e e m p t i v e l y i n t e r r u p t e d
* by a n o t h e r t a s k . R e - e s t a b l i s h t e m p o r a r y m a p p i n g t o t h e
* TLBTEMP_ B A S E a r e a s .
* /
/* We shouldn't be in a double exception */
l3 2 i a0 , a2 , P T _ D E P C
bgeui a0 , V A L I D _ D O U B L E _ E X C E P T I O N _ A D D R E S S , 2 f
/* Make sure the exception originated in the special functions */
movi a0 , _ _ t l b t e m p _ m a p p i n g _ s t a r t
2012-10-15 03:55:38 +04:00
rsr a3 , e p c1
2007-08-22 21:14:51 +04:00
bltu a3 , a0 , 2 f
movi a0 , _ _ t l b t e m p _ m a p p i n g _ e n d
bgeu a3 , a0 , 2 f
/* Check if excvaddr was in one of the TLBTEMP_BASE areas. */
movi a3 , T L B T E M P _ B A S E _ 1
2012-10-15 03:55:38 +04:00
rsr a0 , e x c v a d d r
2007-08-22 21:14:51 +04:00
bltu a0 , a3 , 2 f
2014-07-21 22:01:51 +04:00
addi a1 , a0 , - T L B T E M P _ S I Z E
2007-08-22 21:14:51 +04:00
bgeu a1 , a3 , 2 f
/* Check if we have to restore an ITLB mapping. */
movi a1 , _ _ t l b t e m p _ m a p p i n g _ i t l b
2012-10-15 03:55:38 +04:00
rsr a3 , e p c1
2007-08-22 21:14:51 +04:00
sub a3 , a3 , a1
/* Calculate VPN */
movi a1 , P A G E _ M A S K
and a1 , a1 , a0
/* Jump for ITLB entry */
bgez a3 , 1 f
/* We can use up to two TLBTEMP areas, one for src and one for dst. */
extui a3 , a0 , P A G E _ S H I F T + D C A C H E _ A L I A S _ O R D E R , 1
add a1 , a3 , a1
/* PPN is in a6 for the first TLBTEMP area and in a7 for the second. */
mov a0 , a6
movnez a0 , a7 , a3
j 3 b
/* ITLB entry. We only use dst in a6. */
1 : witlb a6 , a1
isync
j 4 b
# endif / / D C A C H E _ W A Y _ S I Z E > P A G E _ S I Z E
2005-06-24 09:01:16 +04:00
2 : /* Invalid PGD, default exception handling */
2012-10-15 03:55:38 +04:00
rsr a1 , d e p c
2005-06-24 09:01:16 +04:00
s3 2 i a1 , a2 , P T _ A R E G 2
mov a1 , a2
2012-10-15 03:55:38 +04:00
rsr a2 , p s
2006-12-10 13:18:48 +03:00
bbsi. l a2 , P S _ U M _ B I T , 1 f
2005-06-24 09:01:16 +04:00
j _ k e r n e l _ e x c e p t i o n
1 : j _ u s e r _ e x c e p t i o n
2012-11-17 04:16:20 +04:00
ENDPROC( f a s t _ s e c o n d _ l e v e l _ m i s s )
2005-06-24 09:01:16 +04:00
/ *
* StoreProhibitedException
*
* Update t h e p t e a n d i n v a l i d a t e t h e i t l b m a p p i n g f o r t h i s p t e .
*
* Entry c o n d i t i o n :
*
* a0 : trashed, o r i g i n a l v a l u e s a v e d o n s t a c k ( P T _ A R E G 0 )
* a1 : a1
* a2 : new s t a c k p o i n t e r , o r i g i n a l i n D E P C
2013-07-03 20:23:28 +04:00
* a3 : a3
2005-06-24 09:01:16 +04:00
* depc : a2 , o r i g i n a l v a l u e s a v e d o n s t a c k ( P T _ D E P C )
2013-07-03 20:23:28 +04:00
* excsave_1 : dispatch t a b l e
2005-06-24 09:01:16 +04:00
*
* PT_ D E P C > = V A L I D _ D O U B L E _ E X C E P T I O N _ A D D R E S S : d o u b l e e x c e p t i o n , D E P C
* < VALID_DOUBLE_EXCEPTION_ADDRESS : regular e x c e p t i o n
* /
ENTRY( f a s t _ s t o r e _ p r o h i b i t e d )
2013-07-03 20:23:28 +04:00
/* Save a1 and a3. */
2005-06-24 09:01:16 +04:00
s3 2 i a1 , a2 , P T _ A R E G 1
2013-07-03 20:23:28 +04:00
s3 2 i a3 , a2 , P T _ A R E G 3
2005-06-24 09:01:16 +04:00
GET_ C U R R E N T ( a1 ,a2 )
l3 2 i a0 , a1 , T A S K _ M M # t s k - > m m
beqz a0 , 9 f
2012-10-15 03:55:38 +04:00
8 : rsr a1 , e x c v a d d r # f a u l t a d d r e s s
2013-07-03 20:23:28 +04:00
_ PGD_ O F F S E T ( a0 , a1 , a3 )
2005-06-24 09:01:16 +04:00
l3 2 i a0 , a0 , 0
beqz a0 , 2 f
2013-05-18 23:34:30 +04:00
/ *
* Note t h a t w e t e s t _ P A G E _ W R I T A B L E _ B I T o n l y i f P T E i s p r e s e n t
* and i s n o t P A G E _ N O N E . S e e p g t a b l e . h f o r p o s s i b l e P T E l a y o u t s .
* /
2007-08-07 10:57:57 +04:00
2013-07-03 20:23:28 +04:00
_ PTE_ O F F S E T ( a0 , a1 , a3 )
l3 2 i a3 , a0 , 0 # r e a d p t e v a l
2013-05-18 23:34:30 +04:00
movi a1 , _ P A G E _ C A _ I N V A L I D
2013-07-03 20:23:28 +04:00
ball a3 , a1 , 2 f
bbci. l a3 , _ P A G E _ W R I T A B L E _ B I T , 2 f
2005-06-24 09:01:16 +04:00
2007-08-07 10:57:57 +04:00
movi a1 , _ P A G E _ A C C E S S E D | _ P A G E _ D I R T Y | _ P A G E _ H W _ W R I T E
2013-07-03 20:23:28 +04:00
or a3 , a3 , a1
2012-10-15 03:55:38 +04:00
rsr a1 , e x c v a d d r
2013-07-03 20:23:28 +04:00
s3 2 i a3 , a0 , 0
2005-06-24 09:01:16 +04:00
/* We need to flush the cache if we have page coloring. */
# if ( D C A C H E _ W A Y _ S I Z E > P A G E _ S I Z E ) & & X C H A L _ D C A C H E _ I S _ W R I T E B A C K
dhwb a0 , 0
# endif
pdtlb a0 , a1
2013-07-03 20:23:28 +04:00
wdtlb a3 , a0
2005-06-24 09:01:16 +04:00
/* Exit critical section. */
movi a0 , 0
2013-07-03 20:23:28 +04:00
rsr a3 , e x c s a v e 1
2005-06-24 09:01:16 +04:00
s3 2 i a0 , a3 , E X C _ T A B L E _ F I X U P
/* Restore the working registers, and return. */
2013-07-03 20:23:28 +04:00
l3 2 i a3 , a2 , P T _ A R E G 3
2005-06-24 09:01:16 +04:00
l3 2 i a1 , a2 , P T _ A R E G 1
l3 2 i a0 , a2 , P T _ A R E G 0
l3 2 i a2 , a2 , P T _ D E P C
bgeui a2 , V A L I D _ D O U B L E _ E X C E P T I O N _ A D D R E S S , 1 f
2012-10-15 03:55:38 +04:00
rsr a2 , d e p c
2005-06-24 09:01:16 +04:00
rfe
/* Double exception. Restore FIXUP handler and return. */
2012-10-15 03:55:38 +04:00
1 : xsr a2 , d e p c
2005-06-24 09:01:16 +04:00
esync
rfde
9 : l3 2 i a0 , a1 , T A S K _ A C T I V E _ M M # u n l i k e l y c a s e m m = = 0
j 8 b
2 : /* If there was a problem, handle fault in C */
2013-07-03 20:23:28 +04:00
rsr a3 , d e p c # s t i l l h o l d s a 2
s3 2 i a3 , a2 , P T _ A R E G 2
2005-06-24 09:01:16 +04:00
mov a1 , a2
2012-10-15 03:55:38 +04:00
rsr a2 , p s
2006-12-10 13:18:48 +03:00
bbsi. l a2 , P S _ U M _ B I T , 1 f
2005-06-24 09:01:16 +04:00
j _ k e r n e l _ e x c e p t i o n
1 : j _ u s e r _ e x c e p t i o n
2012-11-17 04:16:20 +04:00
ENDPROC( f a s t _ s t o r e _ p r o h i b i t e d )
2009-03-04 18:21:31 +03:00
# endif / * C O N F I G _ M M U * /
2005-06-24 09:01:16 +04:00
2006-12-10 13:18:52 +03:00
/ *
* System C a l l s .
*
* void s y s t e m _ c a l l ( s t r u c t p t _ r e g s * r e g s , i n t e x c c a u s e )
* a2 a3
* /
ENTRY( s y s t e m _ c a l l )
2012-11-17 04:16:20 +04:00
2006-12-10 13:18:52 +03:00
entry a1 , 3 2
/* regs->syscall = regs->areg[2] */
l3 2 i a3 , a2 , P T _ A R E G 2
mov a6 , a2
movi a4 , d o _ s y s c a l l _ t r a c e _ e n t e r
s3 2 i a3 , a2 , P T _ S Y S C A L L
callx4 a4
/* syscall = sys_call_table[syscall_nr] */
movi a4 , s y s _ c a l l _ t a b l e ;
movi a5 , _ _ N R _ s y s c a l l _ c o u n t
movi a6 , - E N O S Y S
bgeu a3 , a5 , 1 f
addx4 a4 , a3 , a4
l3 2 i a4 , a4 , 0
movi a5 , s y s _ n i _ s y s c a l l ;
beq a4 , a5 , 1 f
/* Load args: arg0 - arg5 are passed via regs. */
l3 2 i a6 , a2 , P T _ A R E G 6
l3 2 i a7 , a2 , P T _ A R E G 3
l3 2 i a8 , a2 , P T _ A R E G 4
l3 2 i a9 , a2 , P T _ A R E G 5
l3 2 i a10 , a2 , P T _ A R E G 8
l3 2 i a11 , a2 , P T _ A R E G 9
/* Pass one additional argument to the syscall: pt_regs (on stack) */
s3 2 i a2 , a1 , 0
callx4 a4
1 : /* regs->areg[2] = return_value */
s3 2 i a6 , a2 , P T _ A R E G 2
movi a4 , d o _ s y s c a l l _ t r a c e _ l e a v e
mov a6 , a2
callx4 a4
retw
2012-11-17 04:16:20 +04:00
ENDPROC( s y s t e m _ c a l l )
2014-01-22 08:04:43 +04:00
/ *
* Spill l i v e r e g i s t e r s o n t h e k e r n e l s t a c k m a c r o .
*
* Entry c o n d i t i o n : p s . w o e i s s e t , p s . e x c m i s c l e a r e d
* Exit c o n d i t i o n : w i n d o w s t a r t h a s s i n g l e b i t s e t
* May c l o b b e r : a12 , a13
* /
.macro spill_registers_kernel
# if X C H A L _ N U M _ A R E G S > 1 6
call1 2 1 f
_ j 2 f
retw
.align 4
1 :
_ entry a1 , 4 8
addi a12 , a0 , 3
# if X C H A L _ N U M _ A R E G S > 3 2
.rept ( XCHAL_ N U M _ A R E G S - 3 2 ) / 1 2
_ entry a1 , 4 8
mov a12 , a0
.endr
# endif
_ entry a1 , 4 8
# if X C H A L _ N U M _ A R E G S % 1 2 = = 0
mov a8 , a8
# elif X C H A L _ N U M _ A R E G S % 1 2 = = 4
mov a12 , a12
# elif X C H A L _ N U M _ A R E G S % 1 2 = = 8
mov a4 , a4
# endif
retw
2 :
# else
mov a12 , a12
# endif
.endm
2006-12-10 13:18:52 +03:00
2005-06-24 09:01:16 +04:00
/ *
* Task s w i t c h .
*
* struct t a s k * _ s w i t c h _ t o ( s t r u c t t a s k * p r e v , s t r u c t t a s k * n e x t )
* a2 a2 a3
* /
ENTRY( _ s w i t c h _ t o )
entry a1 , 1 6
2014-01-22 08:04:43 +04:00
mov a11 , a3 # a n d ' n e x t ' ( a 3 )
2005-06-24 09:01:16 +04:00
2008-02-13 00:17:07 +03:00
l3 2 i a4 , a2 , T A S K _ T H R E A D _ I N F O
l3 2 i a5 , a3 , T A S K _ T H R E A D _ I N F O
2005-06-24 09:01:16 +04:00
2014-01-22 08:04:43 +04:00
save_ x t r e g s _ u s e r a4 a6 a8 a9 a12 a13 T H R E A D _ X T R E G S _ U S E R
2005-06-24 09:01:16 +04:00
2014-07-27 07:23:41 +04:00
# if T H R E A D _ R A > 1 0 2 0 | | T H R E A D _ S P > 1 0 2 0
addi a10 , a2 , T A S K _ T H R E A D
s3 2 i a0 , a10 , T H R E A D _ R A - T A S K _ T H R E A D # s a v e r e t u r n a d d r e s s
s3 2 i a1 , a10 , T H R E A D _ S P - T A S K _ T H R E A D # s a v e s t a c k p o i n t e r
# else
s3 2 i a0 , a2 , T H R E A D _ R A # s a v e r e t u r n a d d r e s s
s3 2 i a1 , a2 , T H R E A D _ S P # s a v e s t a c k p o i n t e r
# endif
2008-02-13 00:17:07 +03:00
/* Disable ints while we manipulate the stack pointer. */
2014-01-22 08:04:43 +04:00
rsil a14 , L O C K L E V E L
2012-10-15 03:55:38 +04:00
rsr a3 , e x c s a v e 1
2005-06-24 09:01:16 +04:00
rsync
s3 2 i a3 , a3 , E X C _ T A B L E _ F I X U P / * e n t e r c r i t i c a l s e c t i o n * /
2008-02-13 00:17:07 +03:00
/* Switch CPENABLE */
# if ( X T E N S A _ H A V E _ C O P R O C E S S O R S | | X T E N S A _ H A V E _ I O _ P O R T S )
l3 2 i a3 , a5 , T H R E A D _ C P E N A B L E
2012-10-15 03:55:38 +04:00
xsr a3 , c p e n a b l e
2008-02-13 00:17:07 +03:00
s3 2 i a3 , a4 , T H R E A D _ C P E N A B L E
# endif
/* Flush register file. */
2014-01-22 08:04:43 +04:00
spill_ r e g i s t e r s _ k e r n e l
2005-06-24 09:01:16 +04:00
/ * Set k e r n e l s t a c k ( a n d l e a v e c r i t i c a l s e c t i o n )
* Note : It' s s a v e t o s e t i t h e r e . T h e s t a c k w i l l n o t b e o v e r w r i t t e n
* because t h e k e r n e l s t a c k w i l l o n l y b e l o a d e d a g a i n a f t e r
* we r e t u r n f r o m k e r n e l s p a c e .
* /
2012-10-15 03:55:38 +04:00
rsr a3 , e x c s a v e 1 # e x c _ t a b l e
2008-02-13 00:17:07 +03:00
movi a6 , 0
addi a7 , a5 , P T _ R E G S _ O F F S E T
s3 2 i a6 , a3 , E X C _ T A B L E _ F I X U P
s3 2 i a7 , a3 , E X C _ T A B L E _ K S T K
2005-06-24 09:01:16 +04:00
2013-02-24 07:35:57 +04:00
/* restore context of the task 'next' */
2005-06-24 09:01:16 +04:00
2014-01-22 08:04:43 +04:00
l3 2 i a0 , a11 , T H R E A D _ R A # r e s t o r e r e t u r n a d d r e s s
l3 2 i a1 , a11 , T H R E A D _ S P # r e s t o r e s t a c k p o i n t e r
2008-02-13 00:17:07 +03:00
2014-01-22 08:04:43 +04:00
load_ x t r e g s _ u s e r a5 a6 a8 a9 a12 a13 T H R E A D _ X T R E G S _ U S E R
2005-06-24 09:01:16 +04:00
2012-10-15 03:55:38 +04:00
wsr a14 , p s
2005-06-24 09:01:16 +04:00
rsync
retw
2012-11-17 04:16:20 +04:00
ENDPROC( _ s w i t c h _ t o )
2005-06-24 09:01:16 +04:00
ENTRY( r e t _ f r o m _ f o r k )
/ * void s c h e d u l e _ t a i l ( s t r u c t t a s k _ s t r u c t * p r e v )
* Note : prev i s s t i l l i n a6 ( r e t u r n v a l u e f r o m f a k e c a l l 4 f r a m e )
* /
movi a4 , s c h e d u l e _ t a i l
callx4 a4
2006-12-10 13:18:52 +03:00
movi a4 , d o _ s y s c a l l _ t r a c e _ l e a v e
mov a6 , a1
2005-06-24 09:01:16 +04:00
callx4 a4
j c o m m o n _ e x c e p t i o n _ r e t u r n
2012-11-17 04:16:20 +04:00
ENDPROC( r e t _ f r o m _ f o r k )
2012-10-25 11:10:50 +04:00
/ *
* Kernel t h r e a d c r e a t i o n h e l p e r
* On e n t r y , s e t u p b y c o p y _ t h r e a d : a2 = t h r e a d _ f n , a3 = t h r e a d _ f n a r g
* left f r o m _ s w i t c h _ t o : a6 = p r e v
* /
ENTRY( r e t _ f r o m _ k e r n e l _ t h r e a d )
call4 s c h e d u l e _ t a i l
mov a6 , a3
callx4 a2
2012-10-25 11:10:51 +04:00
j c o m m o n _ e x c e p t i o n _ r e t u r n
2012-10-25 11:10:50 +04:00
ENDPROC( r e t _ f r o m _ k e r n e l _ t h r e a d )