2007-08-02 11:19:14 +04:00
/ * arch/ s p a r c / k e r n e l / e n t r y . S : S p a r c t r a p l o w - l e v e l e n t r y p o i n t s .
2005-04-17 02:20:36 +04:00
*
2007-08-02 11:19:14 +04:00
* Copyright ( C ) 1 9 9 5 , 2 0 0 7 D a v i d S . M i l l e r ( d a v e m @davemloft.net)
2005-04-17 02:20:36 +04:00
* Copyright ( C ) 1 9 9 6 E d d i e C . D o s t ( e c d @skynet.be)
* Copyright ( C ) 1 9 9 6 M i g u e l d e I c a z a ( m i g u e l @nuclecu.unam.mx)
* Copyright ( C ) 1 9 9 6 - 1 9 9 9 J a k u b J e l i n e k ( j j @sunsite.mff.cuni.cz)
* Copyright ( C ) 1 9 9 7 A n t o n B l a n c h a r d ( a n t o n @progsoc.uts.edu.au)
* /
# include < l i n u x / e r r n o . h >
# include < a s m / h e a d . h >
# include < a s m / a s i . h >
# include < a s m / s m p . h >
# include < a s m / k g d b . h >
# include < a s m / c o n t r e g s . h >
# include < a s m / p t r a c e . h >
2005-09-09 22:35:55 +04:00
# include < a s m / a s m - o f f s e t s . h >
2005-04-17 02:20:36 +04:00
# include < a s m / p s r . h >
# include < a s m / v a d d r s . h >
# include < a s m / m e m r e g . h >
# include < a s m / p a g e . h >
# ifdef C O N F I G _ S U N 4
# include < a s m / p g t s u n 4 . h >
# else
# include < a s m / p g t s u n 4 c . h >
# endif
# include < a s m / w i n m a c r o . h >
# include < a s m / s i g n a l . h >
# include < a s m / o b i o . h >
# include < a s m / m x c c . h >
# include < a s m / t h r e a d _ i n f o . h >
# include < a s m / p a r a m . h >
2006-11-06 03:51:03 +03:00
# include < a s m / u n i s t d . h >
2005-04-17 02:20:36 +04:00
# include < a s m / a s m m a c r o . h >
# define c u r p t r g 6
/* These are just handy. */
# define _ S V s a v e % s p , - S T A C K F R A M E _ S Z , % s p
# define _ R S r e s t o r e
# define F L U S H _ A L L _ K E R N E L _ W I N D O W S \
_ SV; _SV; _SV; _SV; _SV; _SV; _SV; \
_ RS; _RS; _RS; _RS; _RS; _RS; _RS;
/ * First, K G D B l o w l e v e l t h i n g s . T h i s i s a r e w r i t e
* of t h e r o u t i n e s f o u n d i n t h e s p a r c - s t u b . c a s m ( ) s t a t e m e n t
* from t h e g d b d i s t r i b u t i o n . T h i s i s a l s o d u a l - p u r p o s e
* as a s o f t w a r e t r a p f o r u s e r l e v e l p r o g r a m s .
* /
.data
.align 4
in_trap_handler :
.word 0
.text
.align 4
# if 0 / * k g d b i s d r o p p e d f r o m 2 . 5 . 3 3 * /
! This f u n c t i o n i s c a l l e d w h e n a n y S P A R C t r a p ( e x c e p t w i n d o w o v e r f l o w o r
! underflow) o c c u r s . I t m a k e s s u r e t h a t t h e i n v a l i d r e g i s t e r w i n d o w i s s t i l l
! available b e f o r e j u m p i n g i n t o C c o d e . I t w i l l a l s o r e s t o r e t h e w o r l d i f y o u
! return f r o m h a n d l e _ e x c e p t i o n .
.globl trap_low
trap_low :
rd % w i m , % l 3
SAVE_ A L L
sethi % h i ( i n _ t r a p _ h a n d l e r ) , % l 4
ld [ % l o ( i n _ t r a p _ h a n d l e r ) + % l 4 ] , % l 5
inc % l 5
st % l 5 , [ % l o ( i n _ t r a p _ h a n d l e r ) + % l 4 ]
/* Make sure kgdb sees the same state we just saved. */
LOAD_ P T _ G L O B A L S ( s p )
LOAD_ P T _ I N S ( s p )
ld [ % s p + S T A C K F R A M E _ S Z + P T _ Y ] , % l 4
ld [ % s p + S T A C K F R A M E _ S Z + P T _ W I M ] , % l 3
ld [ % s p + S T A C K F R A M E _ S Z + P T _ P S R ] , % l 0
ld [ % s p + S T A C K F R A M E _ S Z + P T _ P C ] , % l 1
ld [ % s p + S T A C K F R A M E _ S Z + P T _ N P C ] , % l 2
rd % t b r , % l 5 / * N e v e r c h a n g e s . . . * /
/* Make kgdb exception frame. */
sub % s p ,( 1 6 + 1 + 6 + 1 + 7 2 ) * 4 ,% s p ! M a k e r o o m f o r i n p u t & l o c a l s
! + hidden a r g + a r g s p i l l
! + doubleword a l i g n m e n t
! + registers[ 7 2 ] l o c a l v a r
SAVE_ K G D B _ G L O B A L S ( s p )
SAVE_ K G D B _ I N S ( s p )
SAVE_ K G D B _ S R E G S ( s p , l 4 , l 0 , l 3 , l 5 , l 1 , l 2 )
/* We are increasing PIL, so two writes. */
or % l 0 , P S R _ P I L , % l 0
wr % l 0 , 0 , % p s r
WRITE_ P A U S E
wr % l 0 , P S R _ E T , % p s r
WRITE_ P A U S E
call h a n d l e _ e x c e p t i o n
add % s p , S T A C K F R A M E _ S Z , % o 0 ! P a s s a d d r e s s o f r e g i s t e r s
/* Load new kgdb register set. */
LOAD_ K G D B _ G L O B A L S ( s p )
LOAD_ K G D B _ I N S ( s p )
LOAD_ K G D B _ S R E G S ( s p , l 4 , l 0 , l 3 , l 5 , l 1 , l 2 )
wr % l 4 , 0 x0 , % y
sethi % h i ( i n _ t r a p _ h a n d l e r ) , % l 4
ld [ % l o ( i n _ t r a p _ h a n d l e r ) + % l 4 ] , % l 5
dec % l 5
st % l 5 , [ % l o ( i n _ t r a p _ h a n d l e r ) + % l 4 ]
add % s p ,( 1 6 + 1 + 6 + 1 + 7 2 ) * 4 ,% s p ! U n d o t h e k g d b t r a p f r a m e .
/ * Now t a k e w h a t k g d b d i d a n d p l a c e i t i n t o t h e p t _ r e g s
* frame w h i c h S p a r c L i n u x R E S T O R E _ A L L u n d e r s t a n d s . ,
* /
STORE_ P T _ I N S ( s p )
STORE_ P T _ G L O B A L S ( s p )
STORE_ P T _ Y R E G ( s p , g 2 )
STORE_ P T _ P R I V ( s p , l 0 , l 1 , l 2 )
RESTORE_ A L L
# endif
2007-08-02 11:19:14 +04:00
# if d e f i n e d ( C O N F I G _ B L K _ D E V _ F D ) | | d e f i n e d ( C O N F I G _ B L K _ D E V _ F D _ M O D U L E )
2005-04-17 02:20:36 +04:00
.text
.align 4
.globl floppy_hardint
floppy_hardint :
/ *
* This c o d e c a n n o t t o u c h r e g i s t e r s % l 0 % l 1 a n d % l 2
* because S A V E _ A L L d e p e n d s o n t h e i r v a l u e s . I t d e p e n d s
* on % l 3 a l s o , b u t w e r e g e n e r a t e i t b e f o r e a c a l l .
* Other r e g i s t e r s a r e :
* % l3 - - b a s e a d d r e s s o f f d c r e g i s t e r s
* % l4 - - p d m a _ v a d d r
* % l5 - - s c r a t c h f o r l d / s t a d d r e s s
* % l6 - - p d m a _ s i z e
* % l7 - - s c r a t c h [ f l o p p y b y t e , l d / s t a d d r e s s , a u x . d a t a ]
* /
/* Do we have work to do? */
sethi % h i ( d o i n g _ p d m a ) , % l 7
ld [ % l 7 + % l o ( d o i n g _ p d m a ) ] , % l 7
cmp % l 7 , 0
be f l o p p y _ d o s o f t i n t
nop
/* Load fdc register base */
sethi % h i ( f d c _ s t a t u s ) , % l 3
ld [ % l 3 + % l o ( f d c _ s t a t u s ) ] , % l 3
/* Setup register addresses */
sethi % h i ( p d m a _ v a d d r ) , % l 5 ! t r a n s f e r b u f f e r
ld [ % l 5 + % l o ( p d m a _ v a d d r ) ] , % l 4
sethi % h i ( p d m a _ s i z e ) , % l 5 ! b y t e s t o g o
ld [ % l 5 + % l o ( p d m a _ s i z e ) ] , % l 6
next_byte :
ldub [ % l 3 ] , % l 7
andcc % l 7 , 0 x80 , % g 0 ! D o e s f i f o s t i l l h a v e d a t a
bz f l o p p y _ f i f o _ e m p t i e d ! f i f o h a s b e e n e m p t i e d . . .
andcc % l 7 , 0 x20 , % g 0 ! i n n o n - d m a m o d e s t i l l ?
bz f l o p p y _ o v e r r u n ! n o p e , o v e r r u n
andcc % l 7 , 0 x40 , % g 0 ! 0 =write 1 =read
bz f l o p p y _ w r i t e
sub % l 6 , 0 x1 , % l 6
/* Ok, actually read this byte */
ldub [ % l 3 + 1 ] , % l 7
orcc % g 0 , % l 6 , % g 0
stb % l 7 , [ % l 4 ]
bne n e x t _ b y t e
add % l 4 , 0 x1 , % l 4
b f l o p p y _ t d o n e
nop
floppy_write :
/* Ok, actually write this byte */
ldub [ % l 4 ] , % l 7
orcc % g 0 , % l 6 , % g 0
stb % l 7 , [ % l 3 + 1 ]
bne n e x t _ b y t e
add % l 4 , 0 x1 , % l 4
/* fall through... */
floppy_tdone :
sethi % h i ( p d m a _ v a d d r ) , % l 5
st % l 4 , [ % l 5 + % l o ( p d m a _ v a d d r ) ]
sethi % h i ( p d m a _ s i z e ) , % l 5
st % l 6 , [ % l 5 + % l o ( p d m a _ s i z e ) ]
/* Flip terminal count pin */
set a u x i o _ r e g i s t e r , % l 7
ld [ % l 7 ] , % l 7
set s p a r c _ c p u _ m o d e l , % l 5
ld [ % l 5 ] , % l 5
subcc % l 5 , 1 , % g 0 / * e n u m { s u n 4 c = 1 } ; */
be 1 f
ldub [ % l 7 ] , % l 5
or % l 5 , 0 x c2 , % l 5
stb % l 5 , [ % l 7 ]
andn % l 5 , 0 x02 , % l 5
b 2 f
nop
1 :
or % l 5 , 0 x f4 , % l 5
stb % l 5 , [ % l 7 ]
andn % l 5 , 0 x04 , % l 5
2 :
/* Kill some time so the bits set */
WRITE_ P A U S E
WRITE_ P A U S E
stb % l 5 , [ % l 7 ]
/* Prevent recursion */
sethi % h i ( d o i n g _ p d m a ) , % l 7
b f l o p p y _ d o s o f t i n t
st % g 0 , [ % l 7 + % l o ( d o i n g _ p d m a ) ]
/ * We e m p t i e d t h e F I F O , b u t w e h a v e n ' t r e a d e v e r y t h i n g
* as o f y e t . S t o r e t h e c u r r e n t t r a n s f e r a d d r e s s a n d
* bytes l e f t t o r e a d s o w e c a n c o n t i n u e w h e n t h e n e x t
* fast I R Q c o m e s i n .
* /
floppy_fifo_emptied :
sethi % h i ( p d m a _ v a d d r ) , % l 5
st % l 4 , [ % l 5 + % l o ( p d m a _ v a d d r ) ]
sethi % h i ( p d m a _ s i z e ) , % l 7
st % l 6 , [ % l 7 + % l o ( p d m a _ s i z e ) ]
/* Restore condition codes */
wr % l 0 , 0 x0 , % p s r
WRITE_ P A U S E
jmp % l 1
rett % l 2
floppy_overrun :
sethi % h i ( p d m a _ v a d d r ) , % l 5
st % l 4 , [ % l 5 + % l o ( p d m a _ v a d d r ) ]
sethi % h i ( p d m a _ s i z e ) , % l 5
st % l 6 , [ % l 5 + % l o ( p d m a _ s i z e ) ]
/* Prevent recursion */
sethi % h i ( d o i n g _ p d m a ) , % l 7
st % g 0 , [ % l 7 + % l o ( d o i n g _ p d m a ) ]
/* fall through... */
floppy_dosoftint :
rd % w i m , % l 3
SAVE_ A L L
/* Set all IRQs off. */
or % l 0 , P S R _ P I L , % l 4
wr % l 4 , 0 x0 , % p s r
WRITE_ P A U S E
wr % l 4 , P S R _ E T , % p s r
WRITE_ P A U S E
mov 1 1 , % o 0 ! f l o p p y i r q l e v e l ( u n u s e d a n y w a y )
mov % g 0 , % o 1 ! d e v i d i s n o t u s e d i n f a s t i n t e r r u p t s
call s p a r c _ f l o p p y _ i r q
add % s p , S T A C K F R A M E _ S Z , % o 2 ! s t r u c t p t _ r e g s * r e g s
RESTORE_ A L L
# endif / * ( C O N F I G _ B L K _ D E V _ F D ) * /
/* Bad trap handler */
.globl bad_trap_handler
bad_trap_handler :
SAVE_ A L L
wr % l 0 , P S R _ E T , % p s r
WRITE_ P A U S E
add % s p , S T A C K F R A M E _ S Z , % o 0 ! p t _ r e g s
call d o _ h w _ i n t e r r u p t
mov % l 7 , % o 1 ! t r a p n u m b e r
RESTORE_ A L L
/ * For n o w a l l I R Q ' s n o t r e g i s t e r e d g e t s e n t h e r e . h a n d l e r _ i r q ( ) w i l l
* see i f a r o u t i n e i s r e g i s t e r e d t o h a n d l e t h i s i n t e r r u p t a n d i f n o t
* it w i l l s a y s o o n t h e c o n s o l e .
* /
.align 4
.globl real_ i r q _ e n t r y , p a t c h _ h a n d l e r _ i r q
real_irq_entry :
SAVE_ A L L
# ifdef C O N F I G _ S M P
.globl patchme_maybe_smp_msg
cmp % l 7 , 1 2
patchme_maybe_smp_msg :
bgu m a y b e _ s m p4 m _ m s g
nop
# endif
real_irq_continue :
or % l 0 , P S R _ P I L , % g 2
wr % g 2 , 0 x0 , % p s r
WRITE_ P A U S E
wr % g 2 , P S R _ E T , % p s r
WRITE_ P A U S E
mov % l 7 , % o 0 ! i r q l e v e l
patch_handler_irq :
call h a n d l e r _ i r q
add % s p , S T A C K F R A M E _ S Z , % o 1 ! p t _ r e g s p t r
or % l 0 , P S R _ P I L , % g 2 ! r e s t o r e P I L a f t e r h a n d l e r _ i r q
wr % g 2 , P S R _ E T , % p s r ! k e e p E T u p
WRITE_ P A U S E
RESTORE_ A L L
# ifdef C O N F I G _ S M P
/* SMP per-cpu ticker interrupts are handled specially. */
smp4m_ticker :
bne r e a l _ i r q _ c o n t i n u e + 4
or % l 0 , P S R _ P I L , % g 2
wr % g 2 , 0 x0 , % p s r
WRITE_ P A U S E
wr % g 2 , P S R _ E T , % p s r
WRITE_ P A U S E
call s m p4 m _ p e r c p u _ t i m e r _ i n t e r r u p t
add % s p , S T A C K F R A M E _ S Z , % o 0
wr % l 0 , P S R _ E T , % p s r
WRITE_ P A U S E
RESTORE_ A L L
/ * Here i s w h e r e w e c h e c k f o r p o s s i b l e S M P I P I p a s s e d t o u s
* on s o m e l e v e l o t h e r t h a n 1 5 w h i c h i s t h e N M I a n d o n l y u s e d
* for c r o s s c a l l s . T h a t h a s a s e p a r a t e e n t r y p o i n t b e l o w .
* /
maybe_smp4m_msg :
GET_ P R O C E S S O R 4 M _ I D ( o 3 )
set s u n 4 m _ i n t e r r u p t s , % l 5
ld [ % l 5 ] , % o 5
sethi % h i ( 0 x40 0 0 0 0 0 0 ) , % o 2
sll % o 3 , 1 2 , % o 3
ld [ % o 5 + % o 3 ] , % o 1
andcc % o 1 , % o 2 , % g 0
be,a s m p4 m _ t i c k e r
cmp % l 7 , 1 4
st % o 2 , [ % o 5 + 0 x4 ]
WRITE_ P A U S E
ld [ % o 5 ] , % g 0
WRITE_ P A U S E
or % l 0 , P S R _ P I L , % l 4
wr % l 4 , 0 x0 , % p s r
WRITE_ P A U S E
wr % l 4 , P S R _ E T , % p s r
WRITE_ P A U S E
call s m p _ r e s c h e d u l e _ i r q
nop
RESTORE_ A L L
.align 4
.globl linux_trap_ipi15_sun4m
linux_trap_ipi15_sun4m :
SAVE_ A L L
sethi % h i ( 0 x80 0 0 0 0 0 0 ) , % o 2
GET_ P R O C E S S O R 4 M _ I D ( o 0 )
set s u n 4 m _ i n t e r r u p t s , % l 5
ld [ % l 5 ] , % o 5
sll % o 0 , 1 2 , % o 0
add % o 5 , % o 0 , % o 5
ld [ % o 5 ] , % o 3
andcc % o 3 , % o 2 , % g 0
be 1 f ! M u s t b e a n N M I a s y n c m e m o r y e r r o r
st % o 2 , [ % o 5 + 4 ]
WRITE_ P A U S E
ld [ % o 5 ] , % g 0
WRITE_ P A U S E
or % l 0 , P S R _ P I L , % l 4
wr % l 4 , 0 x0 , % p s r
WRITE_ P A U S E
wr % l 4 , P S R _ E T , % p s r
WRITE_ P A U S E
call s m p4 m _ c r o s s _ c a l l _ i r q
nop
b r e t _ t r a p _ l o c k l e s s _ i p i
clr % l 6
1 :
/* NMI async memory error handling. */
sethi % h i ( 0 x80 0 0 0 0 0 0 ) , % l 4
sethi % h i ( 0 x40 0 0 ) , % o 3
sub % o 5 , % o 0 , % o 5
add % o 5 , % o 3 , % l 5
st % l 4 , [ % l 5 + 0 x c ]
WRITE_ P A U S E
ld [ % l 5 ] , % g 0
WRITE_ P A U S E
or % l 0 , P S R _ P I L , % l 4
wr % l 4 , 0 x0 , % p s r
WRITE_ P A U S E
wr % l 4 , P S R _ E T , % p s r
WRITE_ P A U S E
call s u n 4 m _ n m i
nop
st % l 4 , [ % l 5 + 0 x8 ]
WRITE_ P A U S E
ld [ % l 5 ] , % g 0
WRITE_ P A U S E
RESTORE_ A L L
.globl smp4d_ticker
/* SMP per-cpu ticker interrupts are handled specially. */
smp4d_ticker :
SAVE_ A L L
or % l 0 , P S R _ P I L , % g 2
sethi % h i ( C C _ I C L R ) , % o 0
sethi % h i ( 1 < < 1 4 ) , % o 1
or % o 0 , % l o ( C C _ I C L R ) , % o 0
stha % o 1 , [ % o 0 ] A S I _ M _ M X C C / * C l e a r P I L 1 4 i n M X C C ' s I C L R * /
wr % g 2 , 0 x0 , % p s r
WRITE_ P A U S E
wr % g 2 , P S R _ E T , % p s r
WRITE_ P A U S E
call s m p4 d _ p e r c p u _ t i m e r _ i n t e r r u p t
add % s p , S T A C K F R A M E _ S Z , % o 0
wr % l 0 , P S R _ E T , % p s r
WRITE_ P A U S E
RESTORE_ A L L
.align 4
.globl linux_trap_ipi15_sun4d
linux_trap_ipi15_sun4d :
SAVE_ A L L
sethi % h i ( C C _ B A S E ) , % o 4
sethi % h i ( M X C C _ E R R _ M E | M X C C _ E R R _ P E W | M X C C _ E R R _ A S E | M X C C _ E R R _ P E E ) , % o 2
or % o 4 , ( C C _ E R E G - C C _ B A S E ) , % o 0
ldda [ % o 0 ] A S I _ M _ M X C C , % o 0
andcc % o 0 , % o 2 , % g 0
bne 1 f
sethi % h i ( B B _ S T A T 2 ) , % o 2
lduba [ % o 2 ] A S I _ M _ C T L , % o 2
andcc % o 2 , B B _ S T A T 2 _ M A S K , % g 0
bne 2 f
or % o 4 , ( C C _ I C L R - C C _ B A S E ) , % o 0
sethi % h i ( 1 < < 1 5 ) , % o 1
stha % o 1 , [ % o 0 ] A S I _ M _ M X C C / * C l e a r P I L 1 5 i n M X C C ' s I C L R * /
or % l 0 , P S R _ P I L , % l 4
wr % l 4 , 0 x0 , % p s r
WRITE_ P A U S E
wr % l 4 , P S R _ E T , % p s r
WRITE_ P A U S E
call s m p4 d _ c r o s s _ c a l l _ i r q
nop
b r e t _ t r a p _ l o c k l e s s _ i p i
clr % l 6
1 : /* MXCC error */
2 : /* BB error */
/* Disable PIL 15 */
set C C _ I M S K , % l 4
lduha [ % l 4 ] A S I _ M _ M X C C , % l 5
sethi % h i ( 1 < < 1 5 ) , % l 7
or % l 5 , % l 7 , % l 5
stha % l 5 , [ % l 4 ] A S I _ M _ M X C C
/* FIXME */
1 : b,a 1 b
# endif / * C O N F I G _ S M P * /
/ * This r o u t i n e h a n d l e s i l l e g a l i n s t r u c t i o n s a n d p r i v i l e g e d
* instruction a t t e m p t s f r o m u s e r c o d e .
* /
.align 4
.globl bad_instruction
bad_instruction :
sethi % h i ( 0 x c1 f80 0 0 0 ) , % l 4
ld [ % l 1 ] , % l 5
sethi % h i ( 0 x81 d80 0 0 0 ) , % l 7
and % l 5 , % l 4 , % l 5
cmp % l 5 , % l 7
be 1 f
SAVE_ A L L
wr % l 0 , P S R _ E T , % p s r ! r e - e n a b l e t r a p s
WRITE_ P A U S E
add % s p , S T A C K F R A M E _ S Z , % o 0
mov % l 1 , % o 1
mov % l 2 , % o 2
call d o _ i l l e g a l _ i n s t r u c t i o n
mov % l 0 , % o 3
RESTORE_ A L L
1 : /* unimplemented flush - just skip */
jmpl % l 2 , % g 0
rett % l 2 + 4
.align 4
.globl priv_instruction
priv_instruction :
SAVE_ A L L
wr % l 0 , P S R _ E T , % p s r
WRITE_ P A U S E
add % s p , S T A C K F R A M E _ S Z , % o 0
mov % l 1 , % o 1
mov % l 2 , % o 2
call d o _ p r i v _ i n s t r u c t i o n
mov % l 0 , % o 3
RESTORE_ A L L
/* This routine handles unaligned data accesses. */
.align 4
.globl mna_handler
mna_handler :
andcc % l 0 , P S R _ P S , % g 0
be m n a _ f r o m u s e r
nop
SAVE_ A L L
wr % l 0 , P S R _ E T , % p s r
WRITE_ P A U S E
ld [ % l 1 ] , % o 1
call k e r n e l _ u n a l i g n e d _ t r a p
add % s p , S T A C K F R A M E _ S Z , % o 0
RESTORE_ A L L
mna_fromuser :
SAVE_ A L L
wr % l 0 , P S R _ E T , % p s r ! r e - e n a b l e t r a p s
WRITE_ P A U S E
ld [ % l 1 ] , % o 1
call u s e r _ u n a l i g n e d _ t r a p
add % s p , S T A C K F R A M E _ S Z , % o 0
RESTORE_ A L L
/* This routine handles floating point disabled traps. */
.align 4
.globl fpd_trap_handler
fpd_trap_handler :
SAVE_ A L L
wr % l 0 , P S R _ E T , % p s r ! r e - e n a b l e t r a p s
WRITE_ P A U S E
add % s p , S T A C K F R A M E _ S Z , % o 0
mov % l 1 , % o 1
mov % l 2 , % o 2
call d o _ f p d _ t r a p
mov % l 0 , % o 3
RESTORE_ A L L
/* This routine handles Floating Point Exceptions. */
.align 4
.globl fpe_trap_handler
fpe_trap_handler :
set f p s a v e _ m a g i c , % l 5
cmp % l 1 , % l 5
be 1 f
sethi % h i ( f p s a v e ) , % l 5
or % l 5 , % l o ( f p s a v e ) , % l 5
cmp % l 1 , % l 5
bne 2 f
sethi % h i ( f p s a v e _ c a t c h2 ) , % l 5
or % l 5 , % l o ( f p s a v e _ c a t c h2 ) , % l 5
wr % l 0 , 0 x0 , % p s r
WRITE_ P A U S E
jmp % l 5
rett % l 5 + 4
1 :
sethi % h i ( f p s a v e _ c a t c h ) , % l 5
or % l 5 , % l o ( f p s a v e _ c a t c h ) , % l 5
wr % l 0 , 0 x0 , % p s r
WRITE_ P A U S E
jmp % l 5
rett % l 5 + 4
2 :
SAVE_ A L L
wr % l 0 , P S R _ E T , % p s r ! r e - e n a b l e t r a p s
WRITE_ P A U S E
add % s p , S T A C K F R A M E _ S Z , % o 0
mov % l 1 , % o 1
mov % l 2 , % o 2
call d o _ f p e _ t r a p
mov % l 0 , % o 3
RESTORE_ A L L
/* This routine handles Tag Overflow Exceptions. */
.align 4
.globl do_tag_overflow
do_tag_overflow :
SAVE_ A L L
wr % l 0 , P S R _ E T , % p s r ! r e - e n a b l e t r a p s
WRITE_ P A U S E
add % s p , S T A C K F R A M E _ S Z , % o 0
mov % l 1 , % o 1
mov % l 2 , % o 2
call h a n d l e _ t a g _ o v e r f l o w
mov % l 0 , % o 3
RESTORE_ A L L
/* This routine handles Watchpoint Exceptions. */
.align 4
.globl do_watchpoint
do_watchpoint :
SAVE_ A L L
wr % l 0 , P S R _ E T , % p s r ! r e - e n a b l e t r a p s
WRITE_ P A U S E
add % s p , S T A C K F R A M E _ S Z , % o 0
mov % l 1 , % o 1
mov % l 2 , % o 2
call h a n d l e _ w a t c h p o i n t
mov % l 0 , % o 3
RESTORE_ A L L
/* This routine handles Register Access Exceptions. */
.align 4
.globl do_reg_access
do_reg_access :
SAVE_ A L L
wr % l 0 , P S R _ E T , % p s r ! r e - e n a b l e t r a p s
WRITE_ P A U S E
add % s p , S T A C K F R A M E _ S Z , % o 0
mov % l 1 , % o 1
mov % l 2 , % o 2
call h a n d l e _ r e g _ a c c e s s
mov % l 0 , % o 3
RESTORE_ A L L
/* This routine handles Co-Processor Disabled Exceptions. */
.align 4
.globl do_cp_disabled
do_cp_disabled :
SAVE_ A L L
wr % l 0 , P S R _ E T , % p s r ! r e - e n a b l e t r a p s
WRITE_ P A U S E
add % s p , S T A C K F R A M E _ S Z , % o 0
mov % l 1 , % o 1
mov % l 2 , % o 2
call h a n d l e _ c p _ d i s a b l e d
mov % l 0 , % o 3
RESTORE_ A L L
/* This routine handles Co-Processor Exceptions. */
.align 4
.globl do_cp_exception
do_cp_exception :
SAVE_ A L L
wr % l 0 , P S R _ E T , % p s r ! r e - e n a b l e t r a p s
WRITE_ P A U S E
add % s p , S T A C K F R A M E _ S Z , % o 0
mov % l 1 , % o 1
mov % l 2 , % o 2
call h a n d l e _ c p _ e x c e p t i o n
mov % l 0 , % o 3
RESTORE_ A L L
/* This routine handles Hardware Divide By Zero Exceptions. */
.align 4
.globl do_hw_divzero
do_hw_divzero :
SAVE_ A L L
wr % l 0 , P S R _ E T , % p s r ! r e - e n a b l e t r a p s
WRITE_ P A U S E
add % s p , S T A C K F R A M E _ S Z , % o 0
mov % l 1 , % o 1
mov % l 2 , % o 2
call h a n d l e _ h w _ d i v z e r o
mov % l 0 , % o 3
RESTORE_ A L L
.align 4
.globl do_flush_windows
do_flush_windows :
SAVE_ A L L
wr % l 0 , P S R _ E T , % p s r
WRITE_ P A U S E
andcc % l 0 , P S R _ P S , % g 0
bne d f w _ k e r n e l
nop
call f l u s h _ u s e r _ w i n d o w s
nop
/* Advance over the trap instruction. */
ld [ % s p + S T A C K F R A M E _ S Z + P T _ N P C ] , % l 1
add % l 1 , 0 x4 , % l 2
st % l 1 , [ % s p + S T A C K F R A M E _ S Z + P T _ P C ]
st % l 2 , [ % s p + S T A C K F R A M E _ S Z + P T _ N P C ]
RESTORE_ A L L
.globl flush_patch_one
/* We get these for debugging routines using __builtin_return_address() */
dfw_kernel :
flush_patch_one :
FLUSH_ A L L _ K E R N E L _ W I N D O W S
/* Advance over the trap instruction. */
ld [ % s p + S T A C K F R A M E _ S Z + P T _ N P C ] , % l 1
add % l 1 , 0 x4 , % l 2
st % l 1 , [ % s p + S T A C K F R A M E _ S Z + P T _ P C ]
st % l 2 , [ % s p + S T A C K F R A M E _ S Z + P T _ N P C ]
RESTORE_ A L L
/ * The g e t c c s o f t w a r e t r a p . T h e u s e r w a n t s t h e c o n d i t i o n c o d e s f r o m
* the % p s r i n r e g i s t e r % g 1 .
* /
.align 4
.globl getcc_trap_handler
getcc_trap_handler :
srl % l 0 , 2 0 , % g 1 ! g i v e u s e r
and % g 1 , 0 x f , % g 1 ! o n l y I C C b i t s i n % p s r
jmp % l 2 ! a d v a n c e o v e r t r a p i n s t r u c t i o n
rett % l 2 + 0 x4 ! l i k e t h i s . . .
/ * The s e t c c s o f t w a r e t r a p . T h e u s e r h a s c o n d i t i o n c o d e s i n % g 1
* that i t w o u l d l i k e p l a c e d i n t h e % p s r . B e c a r e f u l n o t t o f l i p
* any u n i n t e n t i o n a l b i t s !
* /
.align 4
.globl setcc_trap_handler
setcc_trap_handler :
sll % g 1 , 0 x14 , % l 4
set P S R _ I C C , % l 5
andn % l 0 , % l 5 , % l 0 ! c l e a r I C C b i t s i n % p s r
and % l 4 , % l 5 , % l 4 ! c l e a r n o n - I C C b i t s i n u s e r v a l u e
or % l 4 , % l 0 , % l 4 ! o r t h e m i n . . . m i x m i x m i x
wr % l 4 , 0 x0 , % p s r ! s e t n e w % p s r
WRITE_ P A U S E ! T I s c u m b a g s . . .
jmp % l 2 ! a d v a n c e o v e r t r a p i n s t r u c t i o n
rett % l 2 + 0 x4 ! l i k e t h i s . . .
.align 4
.globl linux_trap_nmi_sun4c
linux_trap_nmi_sun4c :
SAVE_ A L L
/ * Ugh, w e n e e d t o c l e a r t h e I R Q l i n e . T h i s i s n o w
* a v e r y s u n 4 c s p e c i f i c t r a p h a n d l e r . . .
* /
sethi % h i ( i n t e r r u p t _ e n a b l e ) , % l 5
ld [ % l 5 + % l o ( i n t e r r u p t _ e n a b l e ) ] , % l 5
ldub [ % l 5 ] , % l 6
andn % l 6 , I N T S _ E N A B , % l 6
stb % l 6 , [ % l 5 ]
/* Now it is safe to re-enable traps without recursion. */
or % l 0 , P S R _ P I L , % l 0
wr % l 0 , P S R _ E T , % p s r
WRITE_ P A U S E
/ * Now c a l l t h e c - c o d e w i t h t h e p t _ r e g s f r a m e p t r a n d t h e
* memory e r r o r r e g i s t e r s a s a r g u m e n t s . T h e o r d e r i n g c h o s e n
* here i s d u e t o u n l a t c h i n g s e m a n t i c s .
* /
sethi % h i ( A C _ S Y N C _ E R R ) , % o 0
add % o 0 , 0 x4 , % o 0
lda [ % o 0 ] A S I _ C O N T R O L , % o 2 ! s y n c v a d d r
sub % o 0 , 0 x4 , % o 0
lda [ % o 0 ] A S I _ C O N T R O L , % o 1 ! s y n c e r r o r
add % o 0 , 0 x c , % o 0
lda [ % o 0 ] A S I _ C O N T R O L , % o 4 ! a s y n c v a d d r
sub % o 0 , 0 x4 , % o 0
lda [ % o 0 ] A S I _ C O N T R O L , % o 3 ! a s y n c e r r o r
call s p a r c _ l v l 1 5 _ n m i
add % s p , S T A C K F R A M E _ S Z , % o 0
RESTORE_ A L L
.align 4
.globl invalid_segment_patch1_ff
.globl invalid_segment_patch2_ff
invalid_segment_patch1_ff : cmp % l 4 , 0 x f f
invalid_segment_patch2_ff : mov 0 x f f , % l 3
.align 4
.globl invalid_segment_patch1_1ff
.globl invalid_segment_patch2_1ff
invalid_segment_patch1_1ff : cmp % l 4 , 0 x1 f f
invalid_segment_patch2_1ff : mov 0 x1 f f , % l 3
.align 4
.globl num_ c o n t e x t _ p a t c h1 _ 1 6 , n u m _ c o n t e x t _ p a t c h2 _ 1 6
num_context_patch1_16 : mov 0 x10 , % l 7
num_context_patch2_16 : mov 0 x10 , % l 7
.align 4
.globl vac_linesize_patch_32
vac_linesize_patch_32 : subcc % l 7 , 3 2 , % l 7
.align 4
.globl vac_ h w f l u s h _ p a t c h1 _ o n , v a c _ h w f l u s h _ p a t c h2 _ o n
/ *
* Ugly, b u t w e c a n t u s e h a r d w a r e f l u s h i n g o n t h e s u n 4 a n d w e ' d r e q u i r e
* two i n s t r u c t i o n s ( A n t o n )
* /
# ifdef C O N F I G _ S U N 4
vac_hwflush_patch1_on : nop
# else
vac_hwflush_patch1_on : addcc % l 7 , - P A G E _ S I Z E , % l 7
# endif
vac_hwflush_patch2_on : sta % g 0 , [ % l 3 + % l 7 ] A S I _ H W F L U S H S E G
.globl invalid_ s e g m e n t _ p a t c h1 , i n v a l i d _ s e g m e n t _ p a t c h2
.globl num_context_patch1
.globl vac_ l i n e s i z e _ p a t c h , v a c _ h w f l u s h _ p a t c h1
.globl vac_hwflush_patch2
.align 4
.globl sun4c_fault
! % l0 = % p s r
! % l1 = % p c
! % l2 = % n p c
! % l3 = % w i m
! % l7 = 1 f o r t e x t f a u l t
! We w a n t e r r o r i n % l 5 , v a d d r i n % l 6
sun4c_fault :
# ifdef C O N F I G _ S U N 4
sethi % h i ( s u n 4 c _ m e m e r r _ r e g ) , % l 4
ld [ % l 4 + % l o ( s u n 4 c _ m e m e r r _ r e g ) ] , % l 4 ! m e m e r r c t r l r e g a d d r
ld [ % l 4 ] , % l 6 ! m e m e r r c t r l r e g
ld [ % l 4 + 4 ] , % l 5 ! m e m e r r v a d d r r e g
andcc % l 6 , 0 x80 , % g 0 ! c h e c k f o r e r r o r t y p e
st % g 0 , [ % l 4 + 4 ] ! c l e a r t h e e r r o r
be 0 f ! n o r m a l e r r o r
sethi % h i ( A C _ B U S _ E R R O R ) , % l 4 ! b u s e r r r e g a d d r
call p r o m _ h a l t ! s o m e t h i n g w e i r d h a p p e n e d
! what e x a c t l y d i d h a p p e n ?
! what s h o u l d w e d o h e r e ?
0 : or % l 4 , % l o ( A C _ B U S _ E R R O R ) , % l 4 ! b u s e r r r e g a d d r
lduba [ % l 4 ] A S I _ C O N T R O L , % l 6 ! b u s e r r r e g
cmp % l 7 , 1 ! t e x t f a u l t ?
be 1 f ! y e s
nop
ld [ % l 1 ] , % l 4 ! l o a d i n s t r u c t i o n t h a t c a u s e d f a u l t
srl % l 4 , 2 1 , % l 4
andcc % l 4 , 1 , % g 0 ! s t o r e i n s t r u c t i o n ?
be 1 f ! n o
sethi % h i ( S U N 4 C _ S Y N C _ B A D W R I T E ) , % l 4 ! y e p
! % lo( S U N 4 C _ S Y N C _ B A D W R I T E ) = 0
or % l 4 , % l 6 , % l 6 ! s e t w r i t e b i t t o e m u l a t e s u n 4 c
1 :
# else
sethi % h i ( A C _ S Y N C _ E R R ) , % l 4
add % l 4 , 0 x4 , % l 6 ! A C _ S Y N C _ V A i n % l 6
lda [ % l 6 ] A S I _ C O N T R O L , % l 5 ! A d d r e s s
lda [ % l 4 ] A S I _ C O N T R O L , % l 6 ! E r r o r , r e t a i n e d f o r a b i t
# endif
andn % l 5 , 0 x f f f , % l 5 ! E n c o d e a l l i n f o i n t o l 7
srl % l 6 , 1 4 , % l 4
and % l 4 , 2 , % l 4
or % l 5 , % l 4 , % l 4
or % l 4 , % l 7 , % l 7 ! l 7 = [ a d d r ,w r i t e ,t x t f a u l t ]
andcc % l 0 , P S R _ P S , % g 0
be s u n 4 c _ f a u l t _ f r o m u s e r
andcc % l 7 , 1 , % g 0 ! T e x t f a u l t ?
be 1 f
sethi % h i ( K E R N B A S E ) , % l 4
mov % l 1 , % l 5 ! P C
1 :
cmp % l 5 , % l 4
blu s u n 4 c _ f a u l t _ f r o m u s e r
sethi % h i ( ~ ( ( 1 < < S U N 4 C _ R E A L _ P G D I R _ S H I F T ) - 1 ) ) , % l 4
/ * If t h e k e r n e l r e f e r e n c e s a b u m k e r n e l p o i n t e r , o r a p t e w h i c h
* points t o a n o n e x i s t a n t p a g e i n r a m , w e w i l l r u n t h i s c o d e
* _ forever_ a n d l o c k u p t h e m a c h i n e ! ! ! ! ! S o w e m u s t c h e c k f o r
* this c o n d i t i o n , t h e A C _ S Y N C _ E R R b i t s a r e w h a t w e m u s t e x a m i n e .
* Also a p a r i t y e r r o r w o u l d m a k e t h i s h a p p e n a s w e l l . S o w e j u s t
* check t h a t w e a r e i n f a c t s e r v i c i n g a t l b m i s s a n d n o t s o m e
* other t y p e o f f a u l t f o r t h e k e r n e l .
* /
andcc % l 6 , 0 x80 , % g 0
be s u n 4 c _ f a u l t _ f r o m u s e r
and % l 5 , % l 4 , % l 5
/* Test for NULL pte_t * in vmalloc area. */
sethi % h i ( V M A L L O C _ S T A R T ) , % l 4
cmp % l 5 , % l 4
blu,a i n v a l i d _ s e g m e n t _ p a t c h1
lduXa [ % l 5 ] A S I _ S E G M A P , % l 4
sethi % h i ( s w a p p e r _ p g _ d i r ) , % l 4
srl % l 5 , S U N 4 C _ P G D I R _ S H I F T , % l 6
or % l 4 , % l o ( s w a p p e r _ p g _ d i r ) , % l 4
sll % l 6 , 2 , % l 6
ld [ % l 4 + % l 6 ] , % l 4
# ifdef C O N F I G _ S U N 4
sethi % h i ( P A G E _ M A S K ) , % l 6
andcc % l 4 , % l 6 , % g 0
# else
andcc % l 4 , P A G E _ M A S K , % g 0
# endif
be s u n 4 c _ f a u l t _ f r o m u s e r
lduXa [ % l 5 ] A S I _ S E G M A P , % l 4
invalid_segment_patch1 :
cmp % l 4 , 0 x7 f
bne 1 f
sethi % h i ( s u n 4 c _ k f r e e _ r i n g ) , % l 4
or % l 4 , % l o ( s u n 4 c _ k f r e e _ r i n g ) , % l 4
ld [ % l 4 + 0 x18 ] , % l 3
deccc % l 3 ! d o w e h a v e a f r e e e n t r y ?
bcs,a 2 f ! n o , u n m a p o n e .
sethi % h i ( s u n 4 c _ k e r n e l _ r i n g ) , % l 4
st % l 3 , [ % l 4 + 0 x18 ] ! s u n 4 c _ k f r e e _ r i n g . n u m _ e n t r i e s - -
ld [ % l 4 + 0 x00 ] , % l 6 ! e n t r y = s u n 4 c _ k f r e e _ r i n g . r i n g h d . n e x t
st % l 5 , [ % l 6 + 0 x08 ] ! e n t r y - > v a d d r = a d d r e s s
ld [ % l 6 + 0 x00 ] , % l 3 ! n e x t = e n t r y - > n e x t
ld [ % l 6 + 0 x04 ] , % l 7 ! e n t r y - > p r e v
st % l 7 , [ % l 3 + 0 x04 ] ! n e x t - > p r e v = e n t r y - > p r e v
st % l 3 , [ % l 7 + 0 x00 ] ! e n t r y - > p r e v - > n e x t = n e x t
sethi % h i ( s u n 4 c _ k e r n e l _ r i n g ) , % l 4
or % l 4 , % l o ( s u n 4 c _ k e r n e l _ r i n g ) , % l 4
! head = & s u n 4 c _ k e r n e l _ r i n g . r i n g h d
ld [ % l 4 + 0 x00 ] , % l 7 ! h e a d - > n e x t
st % l 4 , [ % l 6 + 0 x04 ] ! e n t r y - > p r e v = h e a d
st % l 7 , [ % l 6 + 0 x00 ] ! e n t r y - > n e x t = h e a d - > n e x t
st % l 6 , [ % l 7 + 0 x04 ] ! h e a d - > n e x t - > p r e v = e n t r y
st % l 6 , [ % l 4 + 0 x00 ] ! h e a d - > n e x t = e n t r y
ld [ % l 4 + 0 x18 ] , % l 3
inc % l 3 ! s u n 4 c _ k e r n e l _ r i n g . n u m _ e n t r i e s + +
st % l 3 , [ % l 4 + 0 x18 ]
b 4 f
ld [ % l 6 + 0 x08 ] , % l 5
2 :
or % l 4 , % l o ( s u n 4 c _ k e r n e l _ r i n g ) , % l 4
! head = & s u n 4 c _ k e r n e l _ r i n g . r i n g h d
ld [ % l 4 + 0 x04 ] , % l 6 ! e n t r y = h e a d - > p r e v
ld [ % l 6 + 0 x08 ] , % l 3 ! t m p = e n t r y - > v a d d r
! Flush s e g m e n t f r o m t h e c a c h e .
# ifdef C O N F I G _ S U N 4
sethi % h i ( ( 1 2 8 * 1 0 2 4 ) ) , % l 7
# else
sethi % h i ( ( 6 4 * 1 0 2 4 ) ) , % l 7
# endif
9 :
vac_hwflush_patch1 :
vac_linesize_patch :
subcc % l 7 , 1 6 , % l 7
bne 9 b
vac_hwflush_patch2 :
sta % g 0 , [ % l 3 + % l 7 ] A S I _ F L U S H S E G
st % l 5 , [ % l 6 + 0 x08 ] ! e n t r y - > v a d d r = a d d r e s s
ld [ % l 6 + 0 x00 ] , % l 5 ! n e x t = e n t r y - > n e x t
ld [ % l 6 + 0 x04 ] , % l 7 ! e n t r y - > p r e v
st % l 7 , [ % l 5 + 0 x04 ] ! n e x t - > p r e v = e n t r y - > p r e v
st % l 5 , [ % l 7 + 0 x00 ] ! e n t r y - > p r e v - > n e x t = n e x t
st % l 4 , [ % l 6 + 0 x04 ] ! e n t r y - > p r e v = h e a d
ld [ % l 4 + 0 x00 ] , % l 7 ! h e a d - > n e x t
st % l 7 , [ % l 6 + 0 x00 ] ! e n t r y - > n e x t = h e a d - > n e x t
st % l 6 , [ % l 7 + 0 x04 ] ! h e a d - > n e x t - > p r e v = e n t r y
st % l 6 , [ % l 4 + 0 x00 ] ! h e a d - > n e x t = e n t r y
mov % l 3 , % l 5 ! a d d r e s s = t m p
4 :
num_context_patch1 :
mov 0 x08 , % l 7
ld [ % l 6 + 0 x08 ] , % l 4
ldub [ % l 6 + 0 x0 c ] , % l 3
or % l 4 , % l 3 , % l 4 ! e n c o d e n e w v a d d r / p s e g i n t o l 4
sethi % h i ( A C _ C O N T E X T ) , % l 3
lduba [ % l 3 ] A S I _ C O N T R O L , % l 6
/ * Invalidate o l d m a p p i n g , i n s t a n t i a t e n e w m a p p i n g ,
* for e a c h c o n t e x t . R e g i s t e r s l 6 / l 7 a r e l i v e a c r o s s
* this l o o p .
* /
3 : deccc % l 7
sethi % h i ( A C _ C O N T E X T ) , % l 3
stba % l 7 , [ % l 3 ] A S I _ C O N T R O L
invalid_segment_patch2 :
mov 0 x7 f , % l 3
stXa % l 3 , [ % l 5 ] A S I _ S E G M A P
andn % l 4 , 0 x1 f f , % l 3
bne 3 b
stXa % l 4 , [ % l 3 ] A S I _ S E G M A P
sethi % h i ( A C _ C O N T E X T ) , % l 3
stba % l 6 , [ % l 3 ] A S I _ C O N T R O L
andn % l 4 , 0 x1 f f , % l 5
1 :
sethi % h i ( V M A L L O C _ S T A R T ) , % l 4
cmp % l 5 , % l 4
bgeu 1 f
mov 1 < < ( S U N 4 C _ R E A L _ P G D I R _ S H I F T - P A G E _ S H I F T ) , % l 7
sethi % h i ( K E R N B A S E ) , % l 6
sub % l 5 , % l 6 , % l 4
srl % l 4 , P A G E _ S H I F T , % l 4
sethi % h i ( ( S U N 4 C _ P A G E _ K E R N E L & 0 x f40 0 0 0 0 0 ) ) , % l 3
or % l 3 , % l 4 , % l 3
sethi % h i ( P A G E _ S I Z E ) , % l 4
2 :
sta % l 3 , [ % l 5 ] A S I _ P T E
deccc % l 7
inc % l 3
bne 2 b
add % l 5 , % l 4 , % l 5
b 7 f
sethi % h i ( s u n 4 c _ k e r n e l _ f a u l t s ) , % l 4
1 :
srl % l 5 , S U N 4 C _ P G D I R _ S H I F T , % l 3
sethi % h i ( s w a p p e r _ p g _ d i r ) , % l 4
or % l 4 , % l o ( s w a p p e r _ p g _ d i r ) , % l 4
sll % l 3 , 2 , % l 3
ld [ % l 4 + % l 3 ] , % l 4
# ifndef C O N F I G _ S U N 4
and % l 4 , P A G E _ M A S K , % l 4
# else
sethi % h i ( P A G E _ M A S K ) , % l 6
and % l 4 , % l 6 , % l 4
# endif
srl % l 5 , ( P A G E _ S H I F T - 2 ) , % l 6
and % l 6 , ( ( S U N 4 C _ P T R S _ P E R _ P T E - 1 ) < < 2 ) , % l 6
add % l 6 , % l 4 , % l 6
sethi % h i ( P A G E _ S I Z E ) , % l 4
2 :
ld [ % l 6 ] , % l 3
deccc % l 7
sta % l 3 , [ % l 5 ] A S I _ P T E
add % l 6 , 0 x4 , % l 6
bne 2 b
add % l 5 , % l 4 , % l 5
sethi % h i ( s u n 4 c _ k e r n e l _ f a u l t s ) , % l 4
7 :
ld [ % l 4 + % l o ( s u n 4 c _ k e r n e l _ f a u l t s ) ] , % l 3
inc % l 3
st % l 3 , [ % l 4 + % l o ( s u n 4 c _ k e r n e l _ f a u l t s ) ]
/* Restore condition codes */
wr % l 0 , 0 x0 , % p s r
WRITE_ P A U S E
jmp % l 1
rett % l 2
sun4c_fault_fromuser :
SAVE_ A L L
nop
mov % l 7 , % o 1 ! D e c o d e t h e i n f o f r o m % l 7
mov % l 7 , % o 2
and % o 1 , 1 , % o 1 ! a r g 2 = t e x t _ f a u l t p
mov % l 7 , % o 3
and % o 2 , 2 , % o 2 ! a r g 3 = w r i t e p
andn % o 3 , 0 x f f f , % o 3 ! a r g 4 = f a u l t i n g a d d r e s s
wr % l 0 , P S R _ E T , % p s r
WRITE_ P A U S E
call d o _ s u n 4 c _ f a u l t
add % s p , S T A C K F R A M E _ S Z , % o 0 ! a r g 1 = p t _ r e g s p t r
RESTORE_ A L L
.align 4
.globl srmmu_fault
srmmu_fault :
mov 0 x40 0 , % l 5
mov 0 x30 0 , % l 4
lda [ % l 5 ] A S I _ M _ M M U R E G S , % l 6 ! r e a d s f a r f i r s t
lda [ % l 4 ] A S I _ M _ M M U R E G S , % l 5 ! r e a d s f s r l a s t
andn % l 6 , 0 x f f f , % l 6
srl % l 5 , 6 , % l 5 ! a n d e n c o d e a l l i n f o i n t o l 7
and % l 5 , 2 , % l 5
or % l 5 , % l 6 , % l 6
or % l 6 , % l 7 , % l 7 ! l 7 = [ a d d r ,w r i t e ,t x t f a u l t ]
SAVE_ A L L
mov % l 7 , % o 1
mov % l 7 , % o 2
and % o 1 , 1 , % o 1 ! a r g 2 = t e x t _ f a u l t p
mov % l 7 , % o 3
and % o 2 , 2 , % o 2 ! a r g 3 = w r i t e p
andn % o 3 , 0 x f f f , % o 3 ! a r g 4 = f a u l t i n g a d d r e s s
wr % l 0 , P S R _ E T , % p s r
WRITE_ P A U S E
call d o _ s p a r c _ f a u l t
add % s p , S T A C K F R A M E _ S Z , % o 0 ! a r g 1 = p t _ r e g s p t r
RESTORE_ A L L
.align 4
.globl sys_nis_syscall
sys_nis_syscall :
mov % o 7 , % l 5
add % s p , S T A C K F R A M E _ S Z , % o 0 ! p t _ r e g s * r e g s a r g
call c _ s y s _ n i s _ s y s c a l l
mov % l 5 , % o 7
.align 4
.globl sys_execve
sys_execve :
mov % o 7 , % l 5
add % s p , S T A C K F R A M E _ S Z , % o 0 ! p t _ r e g s * r e g s a r g
call s p a r c _ e x e c v e
mov % l 5 , % o 7
2008-04-20 13:14:23 +04:00
.globl sunos_execv
sunos_execv :
st % g 0 , [ % s p + S T A C K F R A M E _ S Z + P T _ I 2 ]
call s p a r c _ e x e c v e
add % s p , S T A C K F R A M E _ S Z , % o 0
b r e t _ s y s _ c a l l
ld [ % s p + S T A C K F R A M E _ S Z + P T _ I 0 ] , % o 0
2005-04-17 02:20:36 +04:00
.align 4
.globl sys_pipe
sys_pipe :
mov % o 7 , % l 5
add % s p , S T A C K F R A M E _ S Z , % o 0 ! p t _ r e g s * r e g s a r g
call s p a r c _ p i p e
mov % l 5 , % o 7
.align 4
.globl sys_sigaltstack
sys_sigaltstack :
mov % o 7 , % l 5
mov % f p , % o 2
call d o _ s i g a l t s t a c k
mov % l 5 , % o 7
.align 4
.globl sys_sigstack
sys_sigstack :
mov % o 7 , % l 5
mov % f p , % o 2
call d o _ s y s _ s i g s t a c k
mov % l 5 , % o 7
.align 4
.globl sys_sigreturn
sys_sigreturn :
call d o _ s i g r e t u r n
add % s p , S T A C K F R A M E _ S Z , % o 0
ld [ % c u r p t r + T I _ F L A G S ] , % l 5
andcc % l 5 , _ T I F _ S Y S C A L L _ T R A C E , % g 0
be 1 f
nop
call s y s c a l l _ t r a c e
nop
1 :
/ * We d o n ' t w a n t t o m u c k w i t h u s e r r e g i s t e r s l i k e a
* normal s y s c a l l , j u s t r e t u r n .
* /
RESTORE_ A L L
.align 4
.globl sys_rt_sigreturn
sys_rt_sigreturn :
call d o _ r t _ s i g r e t u r n
add % s p , S T A C K F R A M E _ S Z , % o 0
ld [ % c u r p t r + T I _ F L A G S ] , % l 5
andcc % l 5 , _ T I F _ S Y S C A L L _ T R A C E , % g 0
be 1 f
nop
call s y s c a l l _ t r a c e
nop
1 :
/* We are returning to a signal handler. */
RESTORE_ A L L
/ * Now t h a t w e h a v e a r e a l s y s _ c l o n e , s y s _ f o r k ( ) i s
* implemented i n t e r m s o f i t . O u r _ r e a l _ i m p l e m e n t a t i o n
* of S u n O S v f o r k ( ) w i l l u s e s y s _ v f o r k ( ) .
*
* XXX T h e s e t h r e e s h o u l d b e c o n s o l i d a t e d i n t o m o s t l y s h a r e d
* XXX c o d e j u s t l i k e o n s p a r c64 . . . - D a v e M
* /
.align 4
.globl sys_ f o r k , f l u s h _ p a t c h _ t w o
sys_fork :
mov % o 7 , % l 5
flush_patch_two :
FLUSH_ A L L _ K E R N E L _ W I N D O W S ;
ld [ % c u r p t r + T I _ T A S K ] , % o 4
rd % p s r , % g 4
WRITE_ P A U S E
mov S I G C H L D , % o 0 ! a r g 0 : c l o n e f l a g s
rd % w i m , % g 5
WRITE_ P A U S E
mov % f p , % o 1 ! a r g 1 : u s p
std % g 4 , [ % o 4 + A O F F _ t a s k _ t h r e a d + A O F F _ t h r e a d _ f o r k _ k p s r ]
add % s p , S T A C K F R A M E _ S Z , % o 2 ! a r g 2 : p t _ r e g s p t r
mov 0 , % o 3
call s p a r c _ d o _ f o r k
mov % l 5 , % o 7
/* Whee, kernel threads! */
.globl sys_ c l o n e , f l u s h _ p a t c h _ t h r e e
sys_clone :
mov % o 7 , % l 5
flush_patch_three :
FLUSH_ A L L _ K E R N E L _ W I N D O W S ;
ld [ % c u r p t r + T I _ T A S K ] , % o 4
rd % p s r , % g 4
WRITE_ P A U S E
/* arg0,1: flags,usp -- loaded already */
cmp % o 1 , 0 x0 ! I s n e w _ u s p N U L L ?
rd % w i m , % g 5
WRITE_ P A U S E
be,a 1 f
mov % f p , % o 1 ! y e s , u s e c a l l e r s u s p
andn % o 1 , 7 , % o 1 ! n o , a l i g n t o 8 b y t e s
1 :
std % g 4 , [ % o 4 + A O F F _ t a s k _ t h r e a d + A O F F _ t h r e a d _ f o r k _ k p s r ]
add % s p , S T A C K F R A M E _ S Z , % o 2 ! a r g 2 : p t _ r e g s p t r
mov 0 , % o 3
call s p a r c _ d o _ f o r k
mov % l 5 , % o 7
/* Whee, real vfork! */
.globl sys_ v f o r k , f l u s h _ p a t c h _ f o u r
sys_vfork :
flush_patch_four :
FLUSH_ A L L _ K E R N E L _ W I N D O W S ;
ld [ % c u r p t r + T I _ T A S K ] , % o 4
rd % p s r , % g 4
WRITE_ P A U S E
rd % w i m , % g 5
WRITE_ P A U S E
std % g 4 , [ % o 4 + A O F F _ t a s k _ t h r e a d + A O F F _ t h r e a d _ f o r k _ k p s r ]
sethi % h i ( 0 x40 0 0 | 0 x01 0 0 | S I G C H L D ) , % o 0
mov % f p , % o 1
or % o 0 , % l o ( 0 x40 0 0 | 0 x01 0 0 | S I G C H L D ) , % o 0
sethi % h i ( s p a r c _ d o _ f o r k ) , % l 1
mov 0 , % o 3
jmpl % l 1 + % l o ( s p a r c _ d o _ f o r k ) , % g 0
add % s p , S T A C K F R A M E _ S Z , % o 2
.align 4
linux_sparc_ni_syscall :
sethi % h i ( s y s _ n i _ s y s c a l l ) , % l 7
b s y s c a l l _ i s _ t o o _ h a r d
or % l 7 , % l o ( s y s _ n i _ s y s c a l l ) , % l 7
linux_fast_syscall :
andn % l 7 , 3 , % l 7
mov % i 0 , % o 0
mov % i 1 , % o 1
mov % i 2 , % o 2
jmpl % l 7 + % g 0 , % g 0
mov % i 3 , % o 3
linux_syscall_trace :
call s y s c a l l _ t r a c e
nop
mov % i 0 , % o 0
mov % i 1 , % o 1
mov % i 2 , % o 2
mov % i 3 , % o 3
b 2 f
mov % i 4 , % o 4
.globl ret_from_fork
ret_from_fork :
call s c h e d u l e _ t a i l
mov % g 3 , % o 0
b r e t _ s y s _ c a l l
ld [ % s p + S T A C K F R A M E _ S Z + P T _ I 0 ] , % o 0
2008-04-20 13:14:23 +04:00
/* Linux native system calls enter here... */
2005-04-17 02:20:36 +04:00
.align 4
.globl linux_sparc_syscall
linux_sparc_syscall :
/* Direct access to user regs, must faster. */
cmp % g 1 , N R _ S Y S C A L L S
bgeu l i n u x _ s p a r c _ n i _ s y s c a l l
sll % g 1 , 2 , % l 4
ld [ % l 7 + % l 4 ] , % l 7
andcc % l 7 , 1 , % g 0
bne l i n u x _ f a s t _ s y s c a l l
/* Just do first insn from SAVE_ALL in the delay slot */
.globl syscall_is_too_hard
syscall_is_too_hard :
SAVE_ A L L _ H E A D
rd % w i m , % l 3
wr % l 0 , P S R _ E T , % p s r
mov % i 0 , % o 0
mov % i 1 , % o 1
mov % i 2 , % o 2
ld [ % c u r p t r + T I _ F L A G S ] , % l 5
mov % i 3 , % o 3
andcc % l 5 , _ T I F _ S Y S C A L L _ T R A C E , % g 0
mov % i 4 , % o 4
bne l i n u x _ s y s c a l l _ t r a c e
mov % i 0 , % l 5
2 :
call % l 7
mov % i 5 , % o 5
st % o 0 , [ % s p + S T A C K F R A M E _ S Z + P T _ I 0 ]
ret_sys_call :
ld [ % c u r p t r + T I _ F L A G S ] , % l 6
cmp % o 0 , - E R E S T A R T _ R E S T A R T B L O C K
ld [ % s p + S T A C K F R A M E _ S Z + P T _ P S R ] , % g 3
set P S R _ C , % g 2
bgeu 1 f
andcc % l 6 , _ T I F _ S Y S C A L L _ T R A C E , % g 0
/* System call success, clear Carry condition code. */
andn % g 3 , % g 2 , % g 3
clr % l 6
st % g 3 , [ % s p + S T A C K F R A M E _ S Z + P T _ P S R ]
bne l i n u x _ s y s c a l l _ t r a c e 2
ld [ % s p + S T A C K F R A M E _ S Z + P T _ N P C ] , % l 1 / * p c = n p c * /
add % l 1 , 0 x4 , % l 2 / * n p c = n p c + 4 * /
st % l 1 , [ % s p + S T A C K F R A M E _ S Z + P T _ P C ]
b r e t _ t r a p _ e n t r y
st % l 2 , [ % s p + S T A C K F R A M E _ S Z + P T _ N P C ]
1 :
/ * System c a l l f a i l u r e , s e t C a r r y c o n d i t i o n c o d e .
* Also, g e t a b s ( e r r n o ) t o r e t u r n t o t h e p r o c e s s .
* /
sub % g 0 , % o 0 , % o 0
or % g 3 , % g 2 , % g 3
st % o 0 , [ % s p + S T A C K F R A M E _ S Z + P T _ I 0 ]
mov 1 , % l 6
st % g 3 , [ % s p + S T A C K F R A M E _ S Z + P T _ P S R ]
bne l i n u x _ s y s c a l l _ t r a c e 2
ld [ % s p + S T A C K F R A M E _ S Z + P T _ N P C ] , % l 1 / * p c = n p c * /
add % l 1 , 0 x4 , % l 2 / * n p c = n p c + 4 * /
st % l 1 , [ % s p + S T A C K F R A M E _ S Z + P T _ P C ]
b r e t _ t r a p _ e n t r y
st % l 2 , [ % s p + S T A C K F R A M E _ S Z + P T _ N P C ]
linux_syscall_trace2 :
call s y s c a l l _ t r a c e
add % l 1 , 0 x4 , % l 2 / * n p c = n p c + 4 * /
st % l 1 , [ % s p + S T A C K F R A M E _ S Z + P T _ P C ]
b r e t _ t r a p _ e n t r y
st % l 2 , [ % s p + S T A C K F R A M E _ S Z + P T _ N P C ]
/ * Saving a n d r e s t o r i n g t h e F P U s t a t e i s b e s t d o n e f r o m l o w l e v e l c o d e .
*
* void f p s a v e ( u n s i g n e d l o n g * f p r e g s , u n s i g n e d l o n g * f s r ,
* void * f p q u e u e , u n s i g n e d l o n g * f p q d e p t h )
* /
.globl fpsave
fpsave :
st % f s r , [ % o 1 ] ! t h i s c a n t r a p o n u s i f f p u i s i n b o g o n s t a t e
ld [ % o 1 ] , % g 1
set 0 x20 0 0 , % g 4
andcc % g 1 , % g 4 , % g 0
be 2 f
mov 0 , % g 2
/* We have an fpqueue to save. */
1 :
std % f q , [ % o 2 ]
fpsave_magic :
st % f s r , [ % o 1 ]
ld [ % o 1 ] , % g 3
andcc % g 3 , % g 4 , % g 0
add % g 2 , 1 , % g 2
bne 1 b
add % o 2 , 8 , % o 2
2 :
st % g 2 , [ % o 3 ]
std % f0 , [ % o 0 + 0 x00 ]
std % f2 , [ % o 0 + 0 x08 ]
std % f4 , [ % o 0 + 0 x10 ]
std % f6 , [ % o 0 + 0 x18 ]
std % f8 , [ % o 0 + 0 x20 ]
std % f10 , [ % o 0 + 0 x28 ]
std % f12 , [ % o 0 + 0 x30 ]
std % f14 , [ % o 0 + 0 x38 ]
std % f16 , [ % o 0 + 0 x40 ]
std % f18 , [ % o 0 + 0 x48 ]
std % f20 , [ % o 0 + 0 x50 ]
std % f22 , [ % o 0 + 0 x58 ]
std % f24 , [ % o 0 + 0 x60 ]
std % f26 , [ % o 0 + 0 x68 ]
std % f28 , [ % o 0 + 0 x70 ]
retl
std % f30 , [ % o 0 + 0 x78 ]
/ * Thanks f o r T h e o D e r a a d t a n d t h e a u t h o r s o f t h e S p r i t e / n e t b s d / o p e n b s d
* code f o r p o i n t i n g o u t t h i s p o s s i b l e d e a d l o c k , w h i l e w e s a v e s t a t e
* above w e c o u l d t r a p o n t h e f s r s t o r e s o o u r l o w l e v e l f p u t r a p
* code h a s t o k n o w h o w t o d e a l w i t h t h i s .
* /
fpsave_catch :
b f p s a v e _ m a g i c + 4
st % f s r , [ % o 1 ]
fpsave_catch2 :
b f p s a v e + 4
st % f s r , [ % o 1 ]
/* void fpload(unsigned long *fpregs, unsigned long *fsr); */
.globl fpload
fpload :
ldd [ % o 0 + 0 x00 ] , % f0
ldd [ % o 0 + 0 x08 ] , % f2
ldd [ % o 0 + 0 x10 ] , % f4
ldd [ % o 0 + 0 x18 ] , % f6
ldd [ % o 0 + 0 x20 ] , % f8
ldd [ % o 0 + 0 x28 ] , % f10
ldd [ % o 0 + 0 x30 ] , % f12
ldd [ % o 0 + 0 x38 ] , % f14
ldd [ % o 0 + 0 x40 ] , % f16
ldd [ % o 0 + 0 x48 ] , % f18
ldd [ % o 0 + 0 x50 ] , % f20
ldd [ % o 0 + 0 x58 ] , % f22
ldd [ % o 0 + 0 x60 ] , % f24
ldd [ % o 0 + 0 x68 ] , % f26
ldd [ % o 0 + 0 x70 ] , % f28
ldd [ % o 0 + 0 x78 ] , % f30
ld [ % o 1 ] , % f s r
retl
nop
/ * _ _ ndelay a n d _ _ u d e l a y t a k e t w o a r g u m e n t s :
* 0 - nsecs o r u s e c s t o d e l a y
* 1 - per_ c p u u d e l a y _ v a l ( l o o p s p e r j i f f y )
*
* Note t h a t n d e l a y g i v e s H Z t i m e s h i g h e r r e s o l u t i o n b u t h a s a 1 0 m s
* limit. u d e l a y c a n h a n d l e u p t o 1 s .
* /
.globl __ndelay
__ndelay :
save % s p , - S T A C K F R A M E _ S Z , % s p
mov % i 0 , % o 0
2007-07-22 06:17:41 +04:00
call . u m u l ! r o u n d m u l t i p l i e r u p s o l a r g e n s o k
mov 0 x1 a e , % o 1 ! 2 * * 3 2 / ( 1 0 0 0 0 0 0 0 0 0 / H Z )
2005-04-17 02:20:36 +04:00
call . u m u l
mov % i 1 , % o 1 ! u d e l a y _ v a l
ba d e l a y _ c o n t i n u e
mov % o 1 , % o 0 ! > > 3 2 l a t e r f o r b e t t e r r e s o l u t i o n
.globl __udelay
__udelay :
save % s p , - S T A C K F R A M E _ S Z , % s p
mov % i 0 , % o 0
2007-07-22 06:17:41 +04:00
sethi % h i ( 0 x10 c7 ) , % o 1 ! r o u n d m u l t i p l i e r u p s o l a r g e u s o k
2005-04-17 02:20:36 +04:00
call . u m u l
2007-07-22 06:17:41 +04:00
or % o 1 , % l o ( 0 x10 c7 ) , % o 1 ! 2 * * 3 2 / 1 0 0 0 0 0 0
2005-04-17 02:20:36 +04:00
call . u m u l
mov % i 1 , % o 1 ! u d e l a y _ v a l
2007-07-22 06:17:41 +04:00
sethi % h i ( 0 x02 8 f4 b62 ) , % l 0 ! A d d i n r o u n d i n g c o n s t a n t * 2 * * 3 2 ,
or % g 0 , % l o ( 0 x02 8 f4 b62 ) , % l 0
addcc % o 0 , % l 0 , % o 0 ! 2 * * 3 2 * 0 . 0 0 9 9 9 9
bcs,a 3 f
add % o 1 , 0 x01 , % o 1
3 :
2005-04-17 02:20:36 +04:00
call . u m u l
mov H Z , % o 0 ! > > 3 2 e a r l i e r f o r w i d e r r a n g e
delay_continue :
cmp % o 0 , 0 x0
1 :
bne 1 b
subcc % o 0 , 1 , % o 0
ret
restore
/* Handle a software breakpoint */
/* We have to inform parent that child has stopped */
.align 4
.globl breakpoint_trap
breakpoint_trap :
rd % w i m ,% l 3
SAVE_ A L L
wr % l 0 , P S R _ E T , % p s r
WRITE_ P A U S E
st % i 0 , [ % s p + S T A C K F R A M E _ S Z + P T _ G 0 ] ! f o r r e s t a r t i n g s y s c a l l s
call s p a r c _ b r e a k p o i n t
add % s p , S T A C K F R A M E _ S Z , % o 0
RESTORE_ A L L
.align 4
.globl _ _ handle_ e x c e p t i o n , f l u s h _ p a t c h _ e x c e p t i o n
__handle_exception :
flush_patch_exception :
FLUSH_ A L L _ K E R N E L _ W I N D O W S ;
ldd [ % o 0 ] , % o 6
jmpl % o 7 + 0 x c , % g 0 ! s e e a s m - s p a r c / p r o c e s s o r . h
mov 1 , % g 1 ! s i g n a l E F A U L T c o n d i t i o n
.align 4
.globl kill_ u s e r _ w i n d o w s , k u w _ p a t c h1 _ 7 w i n
.globl kuw_patch1
kuw_patch1_7win : sll % o 3 , 6 , % o 3
/ * No m a t t e r h o w m u c h o v e r h e a d t h i s r o u t i n e h a s i n t h e w o r s t
* case s c e n e r i o , i t i s s e v e r a l t i m e s b e t t e r t h a n t a k i n g t h e
* traps w i t h t h e o l d m e t h o d o f j u s t d o i n g f l u s h _ u s e r _ w i n d o w s ( ) .
* /
kill_user_windows :
ld [ % g 6 + T I _ U W I N M A S K ] , % o 0 ! g e t c u r r e n t u m a s k
orcc % g 0 , % o 0 , % g 0 ! i f n o b i t s s e t , w e a r e d o n e
be 3 f ! n o t h i n g t o d o
rd % p s r , % o 5 ! m u s t c l e a r i n t e r r u p t s
or % o 5 , P S R _ P I L , % o 4 ! o r e l s e t h a t c o u l d c h a n g e
wr % o 4 , 0 x0 , % p s r ! t h e u w i n m a s k s t a t e
WRITE_ P A U S E ! b u r n t h e m c y c l e s
1 :
ld [ % g 6 + T I _ U W I N M A S K ] , % o 0 ! g e t c o n s i s t e n t s t a t e
orcc % g 0 , % o 0 , % g 0 ! d i d a n i n t e r r u p t c o m e i n ?
be 4 f ! y e p , w e a r e d o n e
rd % w i m , % o 3 ! g e t c u r r e n t w i m
srl % o 3 , 1 , % o 4 ! s i m u l a t e a s a v e
kuw_patch1 :
sll % o 3 , 7 , % o 3 ! c o m p u t e n e x t w i m
or % o 4 , % o 3 , % o 3 ! r e s u l t
andncc % o 0 , % o 3 , % o 0 ! c l e a n t h i s b i t i n u m a s k
bne k u w _ p a t c h1 ! n o t d o n e y e t
srl % o 3 , 1 , % o 4 ! b e g i n a n o t h e r s a v e s i m u l a t i o n
wr % o 3 , 0 x0 , % w i m ! s e t t h e n e w w i m
st % g 0 , [ % g 6 + T I _ U W I N M A S K ] ! c l e a r u w i n m a s k
4 :
wr % o 5 , 0 x0 , % p s r ! r e - e n a b l e i n t e r r u p t s
WRITE_ P A U S E ! b u r n b a b y b u r n
3 :
retl ! r e t u r n
st % g 0 , [ % g 6 + T I _ W _ S A V E D ] ! n o w i n d o w s s a v e d
.align 4
.globl restore_current
restore_current :
LOAD_ C U R R E N T ( g 6 , o 0 )
retl
nop
# ifdef C O N F I G _ P C I
# include < a s m / p c i c . h >
.align 4
.globl linux_trap_ipi15_pcic
linux_trap_ipi15_pcic :
rd % w i m , % l 3
SAVE_ A L L
/ *
* First d e a c t i v a t e N M I
* or w e c a n n o t d r o p E T , c a n n o t g e t w i n d o w s p i l l t r a p s .
* The b u s y l o o p i s n e c e s s a r y b e c a u s e t h e P I O e r r o r
* sometimes d o e s n o t g o a w a y q u i c k l y a n d w e t r a p a g a i n .
* /
sethi % h i ( p c i c _ r e g s ) , % o 1
ld [ % o 1 + % l o ( p c i c _ r e g s ) ] , % o 2
! Get p e n d i n g s t a t u s f o r p r i n t o u t s l a t e r .
ld [ % o 2 + P C I _ S Y S _ I N T _ P E N D I N G ] , % o 0
mov P C I _ S Y S _ I N T _ P E N D I N G _ C L E A R _ A L L , % o 1
stb % o 1 , [ % o 2 + P C I _ S Y S _ I N T _ P E N D I N G _ C L E A R ]
1 :
ld [ % o 2 + P C I _ S Y S _ I N T _ P E N D I N G ] , % o 1
andcc % o 1 , ( ( P C I _ S Y S _ I N T _ P E N D I N G _ P I O | P C I _ S Y S _ I N T _ P E N D I N G _ P C I ) > > 2 4 ) , % g 0
bne 1 b
nop
or % l 0 , P S R _ P I L , % l 4
wr % l 4 , 0 x0 , % p s r
WRITE_ P A U S E
wr % l 4 , P S R _ E T , % p s r
WRITE_ P A U S E
call p c i c _ n m i
add % s p , S T A C K F R A M E _ S Z , % o 1 ! s t r u c t p t _ r e g s * r e g s
RESTORE_ A L L
.globl pcic_nmi_trap_patch
pcic_nmi_trap_patch :
sethi % h i ( l i n u x _ t r a p _ i p i 1 5 _ p c i c ) , % l 3
jmpl % l 3 + % l o ( l i n u x _ t r a p _ i p i 1 5 _ p c i c ) , % g 0
rd % p s r , % l 0
.word 0
# endif / * C O N F I G _ P C I * /
/* End of entry.S */