2005-04-16 15:20:36 -07:00
/ *
* linux/ a r c h / m 3 2 r / k e r n e l / e n t r y . S
*
* Copyright ( c ) 2 0 0 1 , 2 0 0 2 H i r o k a z u T a k a t a , H i t o s h i Y a m a m o t o , H . K o n d o
* Copyright ( c ) 2 0 0 3 H i t o s h i Y a m a m o t o
* Copyright ( c ) 2 0 0 4 H i r o k a z u T a k a t a < t a k a t a a t l i n u x - m 3 2 r . o r g >
*
* Taken f r o m i 3 8 6 v e r s i o n .
* Copyright ( C ) 1 9 9 1 , 1 9 9 2 L i n u s T o r v a l d s
* /
/ *
* entry. S c o n t a i n s t h e s y s t e m - c a l l a n d f a u l t l o w - l e v e l h a n d l i n g r o u t i n e s .
* This a l s o c o n t a i n s t h e t i m e r - i n t e r r u p t h a n d l e r , a s w e l l a s a l l i n t e r r u p t s
* and f a u l t s t h a t c a n r e s u l t i n a t a s k - s w i t c h .
*
* NOTE : This c o d e h a n d l e s s i g n a l - r e c o g n i t i o n , w h i c h h a p p e n s e v e r y t i m e
* after a t i m e r - i n t e r r u p t a n d a f t e r e a c h s y s t e m c a l l .
*
* Stack l a y o u t i n ' r e t _ f r o m _ s y s t e m _ c a l l ' :
* ptrace n e e d s t o h a v e a l l r e g s o n t h e s t a c k .
* if t h e o r d e r h e r e i s c h a n g e d , i t n e e d s t o b e
[PATCH] m32r: Fix pt_regs for !COFNIG_ISA_DSP_LEVEL2 target
This modification is required to fix debugging function for m32r targets
with !CONFIG_ISA_DSP_LEVEL2, by unifying 'struct pt_regs' and 'struct
sigcontext' size for all M32R ISA.
Some m32r processor core with !CONFIG_ISA_DSP_LEVEL2 configuration has only
single accumulator a0 (ex. VDEC2 core, M32102 core, etc.), the others with
CONFIG_ISA_DSP_LEVEL2 has two accumulators, a0 and a1.
This means there are two variations of thread context. So far, we reduced
and changed stackframe size at a syscall for their context size. However,
this causes a problem that a GDB for processors with CONFIG_ISA_DSP_LEVEL2
cannot be used for processors with !CONFIG_ISA_DSP_LEVEL2.
From the viewpoint of GDB support, we should reduce such variation of
stackframe size for simplicity.
In this patch, dummy members are added to 'struct pt_regs' and 'struct
sigcontext' to adjust their size for !CONFIG_ISA_DSP_LEVEL2.
This modification is also a one step for a GDB update in future.
Currently, on the m32r, GDB can access process's context by using ptrace
functions in a simple way of register by register access. By unifying
stackframe size, we have a possibility to make use of ptrace functions of
not only a single register access but also block register access,
PTRACE_{GETREGS,PUTREGS}.
However, for this purpose, we might have to modify stackframe structure
some more; for example, PSW (processor status word) register should be
pre-processed before pushing to stack at a syscall, and so on. In this
case, we must update carefully both kernel and GDB at a time...
Signed-off-by: Hayato Fujiwara <fujiwara@linux-m32r.org>
Signed-off-by: Hirokazu Takata <takata@linux-m32r.org>
Cc: Kei Sakamoto <ksakamot@linux-m32r.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-04-18 22:21:20 -07:00
* updated i n f o r k . c : c o p y _ t h r e a d , s i g n a l . c : d o _ s i g n a l ,
2005-04-16 15:20:36 -07:00
* ptrace. c a n d p t r a c e . h
*
2006-12-08 02:35:54 -08:00
* M3 2 R / M 3 2 R x / M 3 2 R 2
* @(sp) - r4
* @(0x04,sp) - r5
* @(0x08,sp) - r6
* @(0x0c,sp) - *pt_regs
* @(0x10,sp) - r0
* @(0x14,sp) - r1
* @(0x18,sp) - r2
* @(0x1c,sp) - r3
* @(0x20,sp) - r7
* @(0x24,sp) - r8
* @(0x28,sp) - r9
* @(0x2c,sp) - r10
* @(0x30,sp) - r11
* @(0x34,sp) - r12
* @(0x38,sp) - syscall_nr
* @(0x3c,sp) - acc0h
* @(0x40,sp) - acc0l
* @(0x44,sp) - acc1h ; ISA_DSP_LEVEL2 only
* @(0x48,sp) - acc1l ; ISA_DSP_LEVEL2 only
* @(0x4c,sp) - psw
* @(0x50,sp) - bpc
* @(0x54,sp) - bbpsw
* @(0x58,sp) - bbpc
* @(0x5c,sp) - spu (cr3)
* @(0x60,sp) - fp (r13)
* @(0x64,sp) - lr (r14)
* @(0x68,sp) - spi (cr2)
* @(0x6c,sp) - orig_r0
2005-04-16 15:20:36 -07:00
* /
# include < l i n u x / l i n k a g e . h >
# include < a s m / i r q . h >
# include < a s m / u n i s t d . h >
# include < a s m / a s s e m b l e r . h >
# include < a s m / t h r e a d _ i n f o . h >
# include < a s m / e r r n o . h >
# include < a s m / s e g m e n t . h >
# include < a s m / s m p . h >
# include < a s m / p a g e . h >
# include < a s m / m 3 2 r . h >
# include < a s m / m m u _ c o n t e x t . h >
# if ! d e f i n e d ( C O N F I G _ M M U )
# define s y s _ m a d v i s e s y s _ n i _ s y s c a l l
# define s y s _ r e a d a h e a d s y s _ n i _ s y s c a l l
# define s y s _ m p r o t e c t s y s _ n i _ s y s c a l l
# define s y s _ m s y n c s y s _ n i _ s y s c a l l
# define s y s _ m l o c k s y s _ n i _ s y s c a l l
# define s y s _ m u n l o c k s y s _ n i _ s y s c a l l
# define s y s _ m l o c k a l l s y s _ n i _ s y s c a l l
# define s y s _ m u n l o c k a l l s y s _ n i _ s y s c a l l
# define s y s _ m r e m a p s y s _ n i _ s y s c a l l
# define s y s _ m i n c o r e s y s _ n i _ s y s c a l l
# define s y s _ r e m a p _ f i l e _ p a g e s s y s _ n i _ s y s c a l l
# endif / * C O N F I G _ M M U * /
# define R 4 ( r e g ) @reg
# define R 5 ( r e g ) @(0x04,reg)
# define R 6 ( r e g ) @(0x08,reg)
# define P T R E G S ( r e g ) @(0x0C,reg)
# define R 0 ( r e g ) @(0x10,reg)
# define R 1 ( r e g ) @(0x14,reg)
# define R 2 ( r e g ) @(0x18,reg)
# define R 3 ( r e g ) @(0x1C,reg)
# define R 7 ( r e g ) @(0x20,reg)
# define R 8 ( r e g ) @(0x24,reg)
# define R 9 ( r e g ) @(0x28,reg)
# define R 1 0 ( r e g ) @(0x2C,reg)
# define R 1 1 ( r e g ) @(0x30,reg)
# define R 1 2 ( r e g ) @(0x34,reg)
# define S Y S C A L L _ N R ( r e g ) @(0x38,reg)
# define A C C 0 H ( r e g ) @(0x3C,reg)
# define A C C 0 L ( r e g ) @(0x40,reg)
# define A C C 1 H ( r e g ) @(0x44,reg)
# define A C C 1 L ( r e g ) @(0x48,reg)
# define P S W ( r e g ) @(0x4C,reg)
# define B P C ( r e g ) @(0x50,reg)
# define B B P S W ( r e g ) @(0x54,reg)
# define B B P C ( r e g ) @(0x58,reg)
# define S P U ( r e g ) @(0x5C,reg)
# define F P ( r e g ) @(0x60,reg) /* FP = R13 */
# define L R ( r e g ) @(0x64,reg)
# define S P ( r e g ) @(0x68,reg)
# define O R I G _ R 0 ( r e g ) @(0x6C,reg)
2007-08-20 09:12:46 +09:00
# define n r _ s y s c a l l s ( ( s y s c a l l _ t a b l e _ s i z e ) / 4 )
2005-04-16 15:20:36 -07:00
# ifdef C O N F I G _ P R E E M P T
2007-08-20 20:53:50 +09:00
# define p r e e m p t _ s t o p ( x ) D I S A B L E _ I N T E R R U P T S ( x )
2005-04-16 15:20:36 -07:00
# else
# define p r e e m p t _ s t o p ( x )
# define r e s u m e _ k e r n e l r e s t o r e _ a l l
# endif
ENTRY( r e t _ f r o m _ f o r k )
2006-04-18 22:21:38 -07:00
pop r0
2005-04-16 15:20:36 -07:00
bl s c h e d u l e _ t a i l
GET_ T H R E A D _ I N F O ( r8 )
bra s y s c a l l _ e x i t
/ *
* Return t o u s e r m o d e i s n o t a s c o m p l e x a s a l l t h i s l o o k s ,
* but w e w a n t t h e d e f a u l t p a t h f o r a s y s t e m c a l l r e t u r n t o
* go a s q u i c k l y a s p o s s i b l e w h i c h i s w h y s o m e o f t h i s i s
* less c l e a r t h a n i t o t h e r w i s e s h o u l d b e .
* /
; userspace resumption stub bypassing syscall exit tracing
ALIGN
ret_from_exception :
preempt_ s t o p ( r4 )
ret_from_intr :
ld r4 , P S W ( s p )
# ifdef C O N F I G _ I S A _ M 3 2 R 2
and3 r4 , r4 , #0x8800 ; check BSM and BPM bits
# else
and3 r4 , r4 , #0x8000 ; check BSM bit
# endif
beqz r4 , r e s u m e _ k e r n e l
2008-09-24 15:01:47 +09:00
resume_userspace :
2007-08-20 20:53:50 +09:00
DISABLE_ I N T E R R U P T S ( r4 ) ; make sure we don't miss an interrupt
2005-04-16 15:20:36 -07:00
; setting need_resched or sigpending
; between sampling and the iret
GET_ T H R E A D _ I N F O ( r8 )
ld r9 , @(TI_FLAGS, r8)
and3 r4 , r9 , #_ T I F _ W O R K _ M A S K ; i s t h e r e a n y w o r k t o b e d o n e o n
; int/exception return?
bnez r4 , w o r k _ p e n d i n g
bra r e s t o r e _ a l l
# ifdef C O N F I G _ P R E E M P T
ENTRY( r e s u m e _ k e r n e l )
GET_ T H R E A D _ I N F O ( r8 )
ld r9 , @(TI_PRE_COUNT, r8) ; non-zero preempt_count ?
bnez r9 , r e s t o r e _ a l l
need_resched :
ld r9 , @(TI_FLAGS, r8) ; need_resched set ?
and3 r4 , r9 , #_ T I F _ N E E D _ R E S C H E D
beqz r4 , r e s t o r e _ a l l
ld r4 , P S W ( s p ) ; interrupts off (exception path) ?
and3 r4 , r4 , #0x4000
beqz r4 , r e s t o r e _ a l l
LDIMM ( r4 , P R E E M P T _ A C T I V E )
st r4 , @(TI_PRE_COUNT, r8)
2007-08-20 20:53:50 +09:00
ENABLE_ I N T E R R U P T S ( r4 )
2005-04-16 15:20:36 -07:00
bl s c h e d u l e
ldi r4 , #0
st r4 , @(TI_PRE_COUNT, r8)
2007-08-20 20:53:50 +09:00
DISABLE_ I N T E R R U P T S ( r4 )
2005-04-16 15:20:36 -07:00
bra n e e d _ r e s c h e d
# endif
; system call handler stub
ENTRY( s y s t e m _ c a l l )
SWITCH_ T O _ K E R N E L _ S T A C K
SAVE_ A L L
2007-08-20 20:53:50 +09:00
ENABLE_ I N T E R R U P T S ( r4 ) ; Enable interrupt
2005-04-16 15:20:36 -07:00
st s p , P T R E G S ( s p ) ; implicit pt_regs parameter
cmpui r7 , #N R _ s y s c a l l s
bnc s y s c a l l _ b a d s y s
st r7 , S Y S C A L L _ N R ( s p ) ; syscall_nr
; system call tracing in operation
GET_ T H R E A D _ I N F O ( r8 )
ld r9 , @(TI_FLAGS, r8)
and3 r4 , r9 , #_ T I F _ S Y S C A L L _ T R A C E
bnez r4 , s y s c a l l _ t r a c e _ e n t r y
syscall_call :
slli r7 , #2 ; table jump for the system call
LDIMM ( r4 , s y s _ c a l l _ t a b l e )
add r7 , r4
ld r7 , @r7
jl r7 ; execute system call
st r0 , R 0 ( s p ) ; save the return value
syscall_exit :
2007-08-20 20:53:50 +09:00
DISABLE_ I N T E R R U P T S ( r4 ) ; make sure we don't miss an interrupt
2005-04-16 15:20:36 -07:00
; setting need_resched or sigpending
; between sampling and the iret
ld r9 , @(TI_FLAGS, r8)
and3 r4 , r9 , #_ T I F _ A L L W O R K _ M A S K ; c u r r e n t - > w o r k
bnez r4 , s y s c a l l _ e x i t _ w o r k
restore_all :
RESTORE_ A L L
# perform w o r k t h a t n e e d s t o b e d o n e i m m e d i a t e l y b e f o r e r e s u m p t i o n
[PATCH] m32r: Fix pt_regs for !COFNIG_ISA_DSP_LEVEL2 target
This modification is required to fix debugging function for m32r targets
with !CONFIG_ISA_DSP_LEVEL2, by unifying 'struct pt_regs' and 'struct
sigcontext' size for all M32R ISA.
Some m32r processor core with !CONFIG_ISA_DSP_LEVEL2 configuration has only
single accumulator a0 (ex. VDEC2 core, M32102 core, etc.), the others with
CONFIG_ISA_DSP_LEVEL2 has two accumulators, a0 and a1.
This means there are two variations of thread context. So far, we reduced
and changed stackframe size at a syscall for their context size. However,
this causes a problem that a GDB for processors with CONFIG_ISA_DSP_LEVEL2
cannot be used for processors with !CONFIG_ISA_DSP_LEVEL2.
From the viewpoint of GDB support, we should reduce such variation of
stackframe size for simplicity.
In this patch, dummy members are added to 'struct pt_regs' and 'struct
sigcontext' to adjust their size for !CONFIG_ISA_DSP_LEVEL2.
This modification is also a one step for a GDB update in future.
Currently, on the m32r, GDB can access process's context by using ptrace
functions in a simple way of register by register access. By unifying
stackframe size, we have a possibility to make use of ptrace functions of
not only a single register access but also block register access,
PTRACE_{GETREGS,PUTREGS}.
However, for this purpose, we might have to modify stackframe structure
some more; for example, PSW (processor status word) register should be
pre-processed before pushing to stack at a syscall, and so on. In this
case, we must update carefully both kernel and GDB at a time...
Signed-off-by: Hayato Fujiwara <fujiwara@linux-m32r.org>
Signed-off-by: Hirokazu Takata <takata@linux-m32r.org>
Cc: Kei Sakamoto <ksakamot@linux-m32r.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-04-18 22:21:20 -07:00
# r9 : f l a g s
2005-04-16 15:20:36 -07:00
ALIGN
work_pending :
and3 r4 , r9 , #_ T I F _ N E E D _ R E S C H E D
beqz r4 , w o r k _ n o t i f y s i g
work_resched :
bl s c h e d u l e
2007-08-20 20:53:50 +09:00
DISABLE_ I N T E R R U P T S ( r4 ) ; make sure we don't miss an interrupt
2005-04-16 15:20:36 -07:00
; setting need_resched or sigpending
; between sampling and the iret
ld r9 , @(TI_FLAGS, r8)
and3 r4 , r9 , #_ T I F _ W O R K _ M A S K ; i s t h e r e a n y w o r k t o b e d o n e o t h e r
; than syscall tracing?
beqz r4 , r e s t o r e _ a l l
and3 r4 , r4 , #_ T I F _ N E E D _ R E S C H E D
bnez r4 , w o r k _ r e s c h e d
work_notifysig : ; deal with pending signals and
; notify-resume requests
mv r0 , s p ; arg1 : struct pt_regs *regs
ldi r1 , #0 ; arg2 : sigset_t *oldset
mv r2 , r9 ; arg3 : __u32 thread_info_flags
bl d o _ n o t i f y _ r e s u m e
bra r e s t o r e _ a l l
; perform syscall exit tracing
ALIGN
syscall_trace_entry :
ldi r4 , #- E N O S Y S
st r4 , R 0 ( s p )
bl d o _ s y s c a l l _ t r a c e
ld r0 , O R I G _ R 0 ( s p )
ld r1 , R 1 ( s p )
ld r2 , R 2 ( s p )
ld r3 , R 3 ( s p )
ld r4 , R 4 ( s p )
ld r5 , R 5 ( s p )
ld r6 , R 6 ( s p )
ld r7 , S Y S C A L L _ N R ( s p )
cmpui r7 , #N R _ s y s c a l l s
bc s y s c a l l _ c a l l
bra s y s c a l l _ e x i t
; perform syscall exit tracing
ALIGN
syscall_exit_work :
ld r9 , @(TI_FLAGS, r8)
and3 r4 , r9 , #_ T I F _ S Y S C A L L _ T R A C E
beqz r4 , w o r k _ p e n d i n g
2007-08-20 20:53:50 +09:00
ENABLE_ I N T E R R U P T S ( r4 ) ; could let do_syscall_trace() call
2005-04-16 15:20:36 -07:00
; schedule() instead
bl d o _ s y s c a l l _ t r a c e
bra r e s u m e _ u s e r s p a c e
ALIGN
syscall_fault :
SAVE_ A L L
GET_ T H R E A D _ I N F O ( r8 )
ldi r4 , #- E F A U L T
st r4 , R 0 ( s p )
bra r e s u m e _ u s e r s p a c e
ALIGN
syscall_badsys :
ldi r4 , #- E N O S Y S
st r4 , R 0 ( s p )
bra r e s u m e _ u s e r s p a c e
.global eit_vector
.equ ei_ v e c _ t a b l e , e i t _ v e c t o r + 0 x02 0 0
/ *
* EI h a n d l e r r o u t i n e
* /
ENTRY( e i _ h a n d l e r )
# if d e f i n e d ( C O N F I G _ C H I P _ M 3 2 7 0 0 )
; WORKAROUND: force to clear SM bit and use the kernel stack (SPI).
2007-08-17 18:11:37 +09:00
SWITCH_ T O _ K E R N E L _ S T A C K
2005-04-16 15:20:36 -07:00
# endif
SAVE_ A L L
mv r1 , s p ; arg1(regs)
2007-08-18 00:10:18 +09:00
; get ICU status
2005-04-16 15:20:36 -07:00
seth r0 , #s h i g h ( M 32 R _ I C U _ I S T S _ A D D R )
ld r0 , @(low(M32R_ICU_ISTS_ADDR),r0)
2006-04-18 22:21:38 -07:00
push r0
2005-04-16 15:20:36 -07:00
# if d e f i n e d ( C O N F I G _ S M P )
/ *
* If I R Q = = 0 - - > N o t h i n g t o d o , N o t w r i t e I M A S K
* If I R Q = = I P I - - > D o I P I h a n d l e r , N o t w r i t e I M A S K
* If I R Q ! = 0 , I P I - - > D o d o _ I R Q ( ) , W r i t e I M A S K
* /
slli r0 , #4
srli r0 , #24 ; r0(irq_num<<2)
;; IRQ exist check
# if d e f i n e d ( C O N F I G _ C H I P _ M 3 2 7 0 0 )
/* WORKAROUND: IMASK bug M32700-TS1, TS2 chip. */
2007-08-17 18:11:37 +09:00
bnez r0 , 0 f
ld2 4 r14 , #0x00070000
seth r0 , #s h i g h ( M 32 R _ I C U _ I M A S K _ A D D R )
st r14 , @(low(M32R_ICU_IMASK_ADDR),r0)
bra 1 f
.fillinsn
0 :
# endif / * C O N F I G _ C H I P _ M 3 2 7 0 0 * /
2005-04-16 15:20:36 -07:00
beqz r0 , 1 f ; if (!irq_num) goto exit
;; IPI check
cmpi r0 , #( M 32 R _ I R Q _ I P I 0 < < 2 ) ; ISN < IPI0 check
bc 2 f
cmpi r0 , #( ( M 32 R _ I R Q _ I P I 7 + 1 ) < < 2 ) ; ISN > IPI7 check
bnc 2 f
LDIMM ( r2 , e i _ v e c _ t a b l e )
add r2 , r0
ld r2 , @r2
beqz r2 , 1 f ; if (no IPI handler) goto exit
mv r0 , r1 ; arg0(regs)
jl r2
.fillinsn
1 :
addi s p , #4
2007-08-17 23:40:37 +09:00
bra r e s t o r e _ a l l
2005-04-16 15:20:36 -07:00
.fillinsn
2 :
srli r0 , #2
2007-08-17 18:11:37 +09:00
# else / * n o t C O N F I G _ S M P * /
2005-04-16 15:20:36 -07:00
srli r0 , #22 ; r0(irq)
2007-08-17 18:11:37 +09:00
# endif / * n o t C O N F I G _ S M P * /
# if d e f i n e d ( C O N F I G _ P L A T _ H A S _ I N T 1 I C U )
2005-04-16 15:20:36 -07:00
add3 r2 , r0 , #- ( M 32 R _ I R Q _ I N T 1 ) ; INT1# interrupt
2007-08-17 18:11:37 +09:00
bnez r2 , 3 f
seth r0 , #s h i g h ( M 32 R _ I N T 1 I C U _ I S T S )
lduh r0 , @(low(M32R_INT1ICU_ISTS),r0) ; bit10-6 : ISN
2005-04-16 15:20:36 -07:00
slli r0 , #21
srli r0 , #27 ; ISN
2007-08-17 18:11:37 +09:00
addi r0 , #( M 32 R _ I N T 1 I C U _ I R Q _ B A S E )
2005-04-16 15:20:36 -07:00
bra c h e c k _ e n d
.fillinsn
2007-08-17 18:11:37 +09:00
3 :
# endif / * C O N F I G _ P L A T _ H A S _ I N T 1 I C U * /
# if d e f i n e d ( C O N F I G _ P L A T _ H A S _ I N T 0 I C U )
add3 r2 , r0 , #- ( M 32 R _ I R Q _ I N T 0 ) ; INT0# interrupt
bnez r2 , 4 f
seth r0 , #s h i g h ( M 32 R _ I N T 0 I C U _ I S T S )
lduh r0 , @(low(M32R_INT0ICU_ISTS),r0) ; bit10-6 : ISN
2005-04-16 15:20:36 -07:00
slli r0 , #21
2007-08-17 18:11:37 +09:00
srli r0 , #27 ; ISN
2007-08-21 12:04:29 +09:00
add3 r0 , r0 , #( M 32 R _ I N T 0 I C U _ I R Q _ B A S E )
2005-04-16 15:20:36 -07:00
bra c h e c k _ e n d
.fillinsn
2007-08-17 18:11:37 +09:00
4 :
# endif / * C O N F I G _ P L A T _ H A S _ I N T 0 I C U * /
# if d e f i n e d ( C O N F I G _ P L A T _ H A S _ I N T 2 I C U )
add3 r2 , r0 , #- ( M 32 R _ I R Q _ I N T 2 ) ; INT2# interrupt
bnez r2 , 5 f
seth r0 , #s h i g h ( M 32 R _ I N T 2 I C U _ I S T S )
lduh r0 , @(low(M32R_INT2ICU_ISTS),r0) ; bit10-6 : ISN
2006-01-06 00:18:41 -08:00
slli r0 , #21
2007-08-17 18:11:37 +09:00
srli r0 , #27 ; ISN
2007-08-21 12:04:29 +09:00
add3 r0 , r0 , #( M 32 R _ I N T 2 I C U _ I R Q _ B A S E )
2007-08-17 18:11:37 +09:00
; bra check_end
2006-01-06 00:18:41 -08:00
.fillinsn
2007-08-17 18:11:37 +09:00
5 :
# endif / * C O N F I G _ P L A T _ H A S _ I N T 2 I C U * /
2007-08-18 00:10:18 +09:00
2006-01-06 00:18:41 -08:00
check_end :
2005-04-16 15:20:36 -07:00
bl d o _ I R Q
2006-04-18 22:21:38 -07:00
pop r14
2005-04-16 15:20:36 -07:00
seth r0 , #s h i g h ( M 32 R _ I C U _ I M A S K _ A D D R )
st r14 , @(low(M32R_ICU_IMASK_ADDR),r0)
bra r e t _ f r o m _ i n t r
/ *
* Default E I T h a n d l e r
* /
ALIGN
int_msg :
.asciz " Unknown i n t e r r u p t \ n "
.byte 0
ENTRY( d e f a u l t _ e i t _ h a n d l e r )
push r0
mvfc r0 , p s w
push r1
push r2
push r3
push r0
LDIMM ( r0 , _ _ K E R N E L _ D S )
mv r0 , r1
mv r0 , r2
LDIMM ( r0 , i n t _ m s g )
bl p r i n t k
pop r0
pop r3
pop r2
pop r1
mvtc r0 , p s w
pop r0
infinit :
bra i n f i n i t
# ifdef C O N F I G _ M M U
/ *
* Access E x c e p t i o n h a n d l e r
* /
ENTRY( a c e _ h a n d l e r )
SWITCH_ T O _ K E R N E L _ S T A C K
SAVE_ A L L
seth r2 , #s h i g h ( M M U _ R E G _ B A S E ) / * C h e c k s t a t u s r e g i s t e r * /
ld r4 , @(low(MESTS_offset),r2)
st r4 , @(low(MESTS_offset),r2)
srl3 r1 , r4 , #4
# ifdef C O N F I G _ C H I P _ M 3 2 7 0 0
and3 r1 , r1 , #0x0000ffff
; WORKAROUND: ignore TME bit for the M32700(TS1).
# endif / * C O N F I G _ C H I P _ M 3 2 7 0 0 * /
beqz r1 , i n s t
oprand :
ld r2 , @(low(MDEVA_offset),r2) ; set address
srli r1 , #1
bra 1 f
inst :
and3 r1 , r4 , #2
srli r1 , #1
or3 r1 , r1 , #8
mvfc r2 , b p c ; set address
.fillinsn
1 :
mvfc r3 , p s w
mv r0 , s p
and3 r3 , r3 , 0 x80 0
srli r3 , #9
or r1 , r3
/ *
* do_ p a g e _ f a u l t ( ) :
* r0 : s t r u c t p t _ r e g s * r e g s
* r1 : u n s i g n e d l o n g e r r o r - c o d e
* r2 : u n s i g n e d l o n g a d d r e s s
* error- c o d e :
* + - - - - - - + - - - - - - + - - - - - - + - - - - - - +
* | bit3 | b i t 2 | b i t 1 | b i t 0 |
* + - - - - - - + - - - - - - + - - - - - - + - - - - - - +
* bit 3 = = 0 : m e a n s d a t a , 1 : m e a n s i n s t r u c t i o n
* bit 2 = = 0 : m e a n s k e r n e l , 1 : m e a n s u s e r - m o d e
* bit 1 = = 0 : m e a n s r e a d , 1 : m e a n s w r i t e
* bit 0 = = 0 : m e a n s n o p a g e f o u n d 1 : m e a n s p r o t e c t i o n f a u l t
*
* /
bl d o _ p a g e _ f a u l t
bra r e t _ f r o m _ i n t r
# endif / * C O N F I G _ M M U * /
ENTRY( a l i g n m e n t _ c h e c k )
2007-08-18 00:10:18 +09:00
/* void alignment_check(int error_code) */
2005-04-16 15:20:36 -07:00
SWITCH_ T O _ K E R N E L _ S T A C K
SAVE_ A L L
ldi r1 , #0x30 ; error_code
mv r0 , s p ; pt_regs
bl d o _ a l i g n m e n t _ c h e c k
error_code :
bra r e t _ f r o m _ e x c e p t i o n
ENTRY( r i e _ h a n d l e r )
2007-08-18 00:10:18 +09:00
/* void rie_handler(int error_code) */
2005-04-16 15:20:36 -07:00
SWITCH_ T O _ K E R N E L _ S T A C K
SAVE_ A L L
ldi r1 , #0x20 ; error_code
mv r0 , s p ; pt_regs
bl d o _ r i e _ h a n d l e r
bra e r r o r _ c o d e
ENTRY( p i e _ h a n d l e r )
2007-08-18 00:10:18 +09:00
/* void pie_handler(int error_code) */
2005-04-16 15:20:36 -07:00
SWITCH_ T O _ K E R N E L _ S T A C K
SAVE_ A L L
ldi r1 , #0 ; error_code ; FIXME
mv r0 , s p ; pt_regs
bl d o _ p i e _ h a n d l e r
bra e r r o r _ c o d e
ENTRY( d e b u g _ t r a p )
/* void debug_trap(void) */
2007-08-18 00:10:18 +09:00
.global withdraw_debug_trap
2005-04-16 15:20:36 -07:00
SWITCH_ T O _ K E R N E L _ S T A C K
SAVE_ A L L
mv r0 , s p ; pt_regs
bl w i t h d r a w _ d e b u g _ t r a p
ldi r1 , #0 ; error_code
mv r0 , s p ; pt_regs
bl d o _ d e b u g _ t r a p
bra e r r o r _ c o d e
2005-10-11 08:29:09 -07:00
ENTRY( i l l _ t r a p )
/* void ill_trap(void) */
SWITCH_ T O _ K E R N E L _ S T A C K
SAVE_ A L L
ldi r1 , #0 ; error_code ; FIXME
mv r0 , s p ; pt_regs
bl d o _ i l l _ t r a p
bra e r r o r _ c o d e
2005-04-16 15:20:36 -07:00
ENTRY( c a c h e _ f l u s h i n g _ h a n d l e r )
/* void _flush_cache_all(void); */
2007-08-18 00:10:18 +09:00
.global _flush_cache_all
2005-04-16 15:20:36 -07:00
SWITCH_ T O _ K E R N E L _ S T A C K
push r0
push r1
push r2
push r3
push r4
push r5
push r6
push r7
push l r
bl _ f l u s h _ c a c h e _ a l l
pop l r
pop r7
pop r6
pop r5
pop r4
pop r3
pop r2
pop r1
pop r0
rte
2007-08-20 09:12:46 +09:00
.section .rodata , " a"
# include " s y s c a l l _ t a b l e . S "
2005-04-16 15:20:36 -07:00
syscall_ t a b l e _ s i z e = ( . - s y s _ c a l l _ t a b l e )