@ -244,6 +244,19 @@ svc_preempt:
b 1 b
b 1 b
# endif
# endif
__und_fault :
@ Correct the PC such that it is pointing at the instruction
@ which caused the fault. If the faulting instruction was ARM
@ the PC will be pointing at the next instruction, and have to
@ subtract 4. Otherwise, it is Thumb, and the PC will be
@ pointing at the second half of the Thumb instruction. We
@ have to subtract 2.
ldr r2 , [ r0 , #S _ P C ]
sub r2 , r2 , r1
str r2 , [ r0 , #S _ P C ]
b d o _ u n d e f i n s t r
ENDPROC( _ _ u n d _ f a u l t )
.align 5
.align 5
__und_svc :
__und_svc :
# ifdef C O N F I G _ K P R O B E S
# ifdef C O N F I G _ K P R O B E S
@ -261,25 +274,32 @@ __und_svc:
@
@
@ r0 - instruction
@ r0 - instruction
@
@
# ifndef C O N F I G _ T H U M B 2 _ K E R N E L
# ifndef C O N F I G _ T H U M B 2 _ K E R N E L
ldr r0 , [ r4 , #- 4 ]
ldr r0 , [ r4 , #- 4 ]
# else
# else
mov r1 , #2
ldrh r0 , [ r4 , #- 2 ] @ Thumb instruction at LR - 2
ldrh r0 , [ r4 , #- 2 ] @ Thumb instruction at LR - 2
cmp r0 , #0xe800 @ 32-bit instruction if xx >= 0
cmp r0 , #0xe800 @ 32-bit instruction if xx >= 0
ldrhhs r9 , [ r4 ] @ bottom 16 bits
blo _ _ u n d _ s v c _ f a u l t
orrhs r0 , r9 , r0 , l s l #16
ldrh r9 , [ r4 ] @ bottom 16 bits
add r4 , r4 , #2
str r4 , [ s p , #S _ P C ]
orr r0 , r9 , r0 , l s l #16
# endif
# endif
adr r9 , B S Y M ( 1 f )
adr r9 , B S Y M ( _ _ u n d _ s v c _ f i n i s h )
mov r2 , r4
mov r2 , r4
bl c a l l _ f p e
bl c a l l _ f p e
mov r1 , #4 @ PC correction to apply
__und_svc_fault :
mov r0 , s p @ struct pt_regs *regs
mov r0 , s p @ struct pt_regs *regs
bl d o _ u n d e f i n s t r
bl _ _ u n d _ f a u l t
@
@
@ IRQs off again before pulling preserved data off the stack
@ IRQs off again before pulling preserved data off the stack
@
@
1 : disable_ i r q _ n o t r a c e
__und_svc_finish :
disable_ i r q _ n o t r a c e
@
@
@ restore SPSR and restart the instruction
@ restore SPSR and restart the instruction
@ -423,25 +443,33 @@ __und_usr:
mov r2 , r4
mov r2 , r4
mov r3 , r5
mov r3 , r5
@ r2 = regs->ARM_pc, which is either 2 or 4 bytes ahead of the
@ faulting instruction depending on Thumb mode.
@ r3 = regs->ARM_cpsr
@
@
@ fall through to the emulation code, which returns using r9 if
@ The emulation code returns using r9 if it has emulated the
@ it has emulated the instruction, or the more conventional lr
@ instruction, or the more conventional lr if we are to treat
@ if we are to treat this as a real undefined instruction
@ this as a real undefined instruction
@
@ r0 - instruction
@
@
adr r9 , B S Y M ( r e t _ f r o m _ e x c e p t i o n )
adr r9 , B S Y M ( r e t _ f r o m _ e x c e p t i o n )
adr l r , B S Y M ( _ _ u n d _ u s r _ u n k n o w n )
tst r3 , #P S R _ T _ B I T @ T h u m b m o d e ?
tst r3 , #P S R _ T _ B I T @ T h u m b m o d e ?
itet e q @ explicit IT needed for the 1f label
bne _ _ u n d _ u s r _ t h u m b
subeq r4 , r2 , #4 @ ARM instr at LR - 4
sub r4 , r2 , #4 @ ARM instr at LR - 4
subne r4 , r2 , #2 @ Thumb instr at LR - 2
1 : ldrt r0 , [ r4 ]
1 : ldreqt r0 , [ r4 ]
# ifdef C O N F I G _ C P U _ E N D I A N _ B E 8
# ifdef C O N F I G _ C P U _ E N D I A N _ B E 8
reveq r0 , r0 @ little endian instruction
rev r0 , r0 @ little endian instruction
# endif
# endif
beq c a l l _ f p e
@ r0 = 32-bit ARM instruction which caused the exception
@ r2 = PC value for the following instruction (:= regs->ARM_pc)
@ r4 = PC value for the faulting instruction
@ lr = 32-bit undefined instruction function
adr l r , B S Y M ( _ _ u n d _ u s r _ f a u l t _ 3 2 )
b c a l l _ f p e
__und_usr_thumb :
@ Thumb instruction
@ Thumb instruction
sub r4 , r2 , #2 @ First half of thumb instr at LR - 2
# if C O N F I G _ A R M _ T H U M B & & _ _ L I N U X _ A R M _ A R C H _ _ > = 6 & & C O N F I G _ C P U _ V 7
# if C O N F I G _ A R M _ T H U M B & & _ _ L I N U X _ A R M _ A R C H _ _ > = 6 & & C O N F I G _ C P U _ V 7
/ *
/ *
* Thumb- 2 i n s t r u c t i o n h a n d l i n g . N o t e t h a t b e c a u s e p r e - v6 a n d > = v6 p l a t f o r m s
* Thumb- 2 i n s t r u c t i o n h a n d l i n g . N o t e t h a t b e c a u s e p r e - v6 a n d > = v6 p l a t f o r m s
@ -455,7 +483,7 @@ __und_usr:
ldr r5 , . L C c p u _ a r c h i t e c t u r e
ldr r5 , . L C c p u _ a r c h i t e c t u r e
ldr r5 , [ r5 ]
ldr r5 , [ r5 ]
cmp r5 , #C P U _ A R C H _ A R M v 7
cmp r5 , #C P U _ A R C H _ A R M v 7
blo _ _ u n d _ u s r _ u n k n o w n
blo _ _ u n d _ u s r _ f a u l t _ 1 6 @ 16bit undefined instruction
/ *
/ *
* The f o l l o w i n g c o d e w o n ' t g e t r u n u n l e s s t h e r u n n i n g C P U r e a l l y i s v7 , s o
* The f o l l o w i n g c o d e w o n ' t g e t r u n u n l e s s t h e r u n n i n g C P U r e a l l y i s v7 , s o
* coding r o u n d t h e l a c k o f l d r h t o n o l d e r a r c h e s i s p o i n t l e s s . T e m p o r a r i l y
* coding r o u n d t h e l a c k o f l d r h t o n o l d e r a r c h e s i s p o i n t l e s s . T e m p o r a r i l y
@ -463,15 +491,18 @@ __und_usr:
* /
* /
.arch armv6t2
.arch armv6t2
# endif
# endif
2 :
2 : ldrht r5 , [ r4 ]
ARM( l d r h t r5 , [ r4 ] , #2 )
THUMB( l d r h t r5 , [ r4 ] )
THUMB( a d d r4 , r4 , #2 )
cmp r5 , #0xe800 @ 32bit instruction if xx != 0
cmp r5 , #0xe800 @ 32bit instruction if xx != 0
blo _ _ u n d _ u s r _ u n k n o w n
blo _ _ u n d _ u s r _ f a u l t _ 1 6 @ 16bit undefined instruction
3 : ldrht r0 , [ r4 ]
3 : ldrht r0 , [ r2 ]
add r2 , r2 , #2 @ r2 is PC + 2, make it PC + 4
add r2 , r2 , #2 @ r2 is PC + 2, make it PC + 4
str r2 , [ s p , #S _ P C ] @ i t ' s a 2 x16 b i t i n s t r , u p d a t e
orr r0 , r0 , r5 , l s l #16
orr r0 , r0 , r5 , l s l #16
adr l r , B S Y M ( _ _ u n d _ u s r _ f a u l t _ 3 2 )
@ r0 = the two 16-bit Thumb instructions which caused the exception
@ r2 = PC value for the following Thumb instruction (:= regs->ARM_pc)
@ r4 = PC value for the first 16-bit Thumb instruction
@ lr = 32bit undefined instruction function
# if _ _ L I N U X _ A R M _ A R C H _ _ < 7
# if _ _ L I N U X _ A R M _ A R C H _ _ < 7
/* If the target arch was overridden, change it back: */
/* If the target arch was overridden, change it back: */
@ -482,17 +513,13 @@ __und_usr:
# endif
# endif
# endif / * _ _ L I N U X _ A R M _ A R C H _ _ < 7 * /
# endif / * _ _ L I N U X _ A R M _ A R C H _ _ < 7 * /
# else / * ! ( C O N F I G _ A R M _ T H U M B & & _ _ L I N U X _ A R M _ A R C H _ _ > = 6 & & C O N F I G _ C P U _ V 7 ) * /
# else / * ! ( C O N F I G _ A R M _ T H U M B & & _ _ L I N U X _ A R M _ A R C H _ _ > = 6 & & C O N F I G _ C P U _ V 7 ) * /
b _ _ u n d _ u s r _ u n k n o w n
b _ _ u n d _ u s r _ f a u l t _ 1 6
# endif
# endif
UNWIND( . f n e n d )
UNWIND( . f n e n d )
ENDPROC( _ _ u n d _ u s r )
ENDPROC( _ _ u n d _ u s r )
@
@ fallthrough to call_fpe
@
/ *
/ *
* The o u t o f l i n e f i x u p f o r t h e l d r t a b o v e .
* The o u t o f l i n e f i x u p f o r t h e l d r t i n s t r u c t i o n s a b o v e .
* /
* /
.pushsection .fixup , " ax"
.pushsection .fixup , " ax"
.align 2
.align 2
@ -524,11 +551,12 @@ ENDPROC(__und_usr)
* NEON h a n d l e r c o d e .
* NEON h a n d l e r c o d e .
*
*
* Emulators m a y w i s h t o m a k e u s e o f t h e f o l l o w i n g r e g i s t e r s :
* Emulators m a y w i s h t o m a k e u s e o f t h e f o l l o w i n g r e g i s t e r s :
* r0 = i n s t r u c t i o n o p c o d e .
* r0 = i n s t r u c t i o n o p c o d e ( 3 2 - b i t A R M o r t w o 1 6 - b i t T h u m b )
* r2 = P C + 4
* r2 = P C v a l u e t o r e s u m e e x e c u t i o n a f t e r s u c c e s s f u l e m u l a t i o n
* r9 = n o r m a l " s u c c e s s f u l " r e t u r n a d d r e s s
* r9 = n o r m a l " s u c c e s s f u l " r e t u r n a d d r e s s
* r1 0 = t h i s t h r e a d s t h r e a d _ i n f o s t r u c t u r e .
* r1 0 = t h i s t h r e a d s t h r e a d _ i n f o s t r u c t u r e
* lr = u n r e c o g n i s e d i n s t r u c t i o n r e t u r n a d d r e s s
* lr = u n r e c o g n i s e d i n s t r u c t i o n r e t u r n a d d r e s s
* IRQs d i s a b l e d , F I Q s e n a b l e d .
* /
* /
@
@
@ Fall-through from Thumb-2 __und_usr
@ Fall-through from Thumb-2 __und_usr
@ -659,12 +687,17 @@ ENTRY(no_fp)
mov p c , l r
mov p c , l r
ENDPROC( n o _ f p )
ENDPROC( n o _ f p )
__und_usr_unknown :
__und_usr_fault_32 :
enable_ i r q
mov r1 , #4
b 1 f
__und_usr_fault_16 :
mov r1 , #2
1 : enable_ i r q
mov r0 , s p
mov r0 , s p
adr l r , B S Y M ( r e t _ f r o m _ e x c e p t i o n )
adr l r , B S Y M ( r e t _ f r o m _ e x c e p t i o n )
b d o _ u n d e f i n s t r
b _ _ u n d _ f a u l t
ENDPROC( _ _ u n d _ u s r _ u n k n o w n )
ENDPROC( _ _ u n d _ u s r _ f a u l t _ 3 2 )
ENDPROC( _ _ u n d _ u s r _ f a u l t _ 1 6 )
.align 5
.align 5
__pabt_usr :
__pabt_usr :