2019-06-04 11:11:33 +03:00
/* SPDX-License-Identifier: GPL-2.0-only */
2010-05-21 21:06:42 +04:00
/ *
* linux/ a r c h / a r m / k e r n e l / e n t r y - v7 m . S
*
* Copyright ( C ) 2 0 0 8 A R M L t d .
*
* Low- l e v e l v e c t o r i n t e r f a c e r o u t i n e s f o r t h e A R M v7 - M a r c h i t e c t u r e
* /
# include < a s m / m e m o r y . h >
# include < a s m / g l u e . h >
# include < a s m / t h r e a d _ n o t i f y . h >
# include < a s m / v7 m . h >
# include " e n t r y - h e a d e r . S "
# ifdef C O N F I G _ T R A C E _ I R Q F L A G S
# error " C O N F I G _ T R A C E _ I R Q F L A G S n o t s u p p o r t e d o n t h e c u r r e n t A R M v7 M i m p l e m e n t a t i o n "
# endif
__invalid_entry :
v7 m _ e x c e p t i o n _ e n t r y
2015-01-28 18:05:04 +03:00
# ifdef C O N F I G _ P R I N T K
2010-05-21 21:06:42 +04:00
adr r0 , s t r e r r
mrs r1 , i p s r
mov r2 , l r
bl p r i n t k
2015-01-28 18:05:04 +03:00
# endif
2010-05-21 21:06:42 +04:00
mov r0 , s p
bl s h o w _ r e g s
1 : b 1 b
ENDPROC( _ _ i n v a l i d _ e n t r y )
strerr : .asciz " \nUnhandled exception: IPSR = %08lx LR = %08lx\n "
.align 2
__irq_entry :
v7 m _ e x c e p t i o n _ e n t r y
@
@ Invoke the IRQ handler
@
mrs r0 , i p s r
ldr r1 , =V7M_xPSR_EXCEPTIONNO
and r0 , r1
sub r0 , #16
mov r1 , s p
stmdb s p ! , { l r }
@ routine called with r0 = irq number, r1 = struct pt_regs *
2013-07-30 14:33:00 +04:00
bl n v i c _ h a n d l e _ i r q
2010-05-21 21:06:42 +04:00
pop { l r }
@
@ Check for any pending work if returning to user
@
ldr r1 , =BASEADDR_V7M_SCB
ldr r0 , [ r1 , V 7 M _ S C B _ I C S R ]
tst r0 , V 7 M _ S C B _ I C S R _ R E T T O B A S E
beq 2 f
get_ t h r e a d _ i n f o t s k
ldr r2 , [ t s k , #T I _ F L A G S ]
tst r2 , #_ T I F _ W O R K _ M A S K
beq 2 f @ no work pending
mov r0 , #V 7 M _ S C B _ I C S R _ P E N D S V S E T
str r0 , [ r1 , V 7 M _ S C B _ I C S R ] @ raise PendSV
2 :
@ registers r0-r3 and r12 are automatically restored on exception
@ return. r4-r7 were not clobbered in v7m_exception_entry so for
@ correctness they don't need to be restored. So only r8-r11 must be
@ restored here. The easiest way to do so is to restore r0-r7, too.
ldmia s p ! , { r0 - r11 }
2016-05-10 18:34:27 +03:00
add s p , #P T _ R E G S _ S I Z E - S _ I P
2010-05-21 21:06:42 +04:00
cpsie i
bx l r
ENDPROC( _ _ i r q _ e n t r y )
__pendsv_entry :
v7 m _ e x c e p t i o n _ e n t r y
ldr r1 , =BASEADDR_V7M_SCB
mov r0 , #V 7 M _ S C B _ I C S R _ P E N D S V C L R
str r0 , [ r1 , V 7 M _ S C B _ I C S R ] @ clear PendSV
@ execute the pending work, including reschedule
get_ t h r e a d _ i n f o t s k
mov w h y , #0
2015-10-30 23:08:05 +03:00
b r e t _ t o _ u s e r _ f r o m _ i r q
2010-05-21 21:06:42 +04:00
ENDPROC( _ _ p e n d s v _ e n t r y )
/ *
* Register s w i t c h f o r A R M v7 - M p r o c e s s o r s .
* r0 = p r e v i o u s t a s k _ s t r u c t , r1 = p r e v i o u s t h r e a d _ i n f o , r2 = n e x t t h r e a d _ i n f o
* previous a n d n e x t a r e g u a r a n t e e d n o t t o b e t h e s a m e .
* /
ENTRY( _ _ s w i t c h _ t o )
.fnstart
.cantunwind
add i p , r1 , #T I _ C P U _ S A V E
stmia i p ! , { r4 - r11 } @ Store most regs on stack
str s p , [ i p ] , #4
str l r , [ i p ] , #4
mov r5 , r0
add r4 , r2 , #T I _ C P U _ S A V E
ldr r0 , =thread_notify_head
mov r1 , #T H R E A D _ N O T I F Y _ S W I T C H
bl a t o m i c _ n o t i f i e r _ c a l l _ c h a i n
mov i p , r4
mov r0 , r5
ldmia i p ! , { r4 - r11 } @ Load all regs saved previously
ldr s p , [ i p ]
ldr p c , [ i p , #4 ] !
.fnend
ENDPROC( _ _ s w i t c h _ t o )
.data
2015-04-10 11:46:46 +03:00
# if C O N F I G _ C P U _ V 7 M _ N U M _ I R Q < = 1 1 2
.align 9
# else
.align 10
# endif
2010-05-21 21:06:42 +04:00
/ *
2015-04-10 11:46:46 +03:00
* Vector t a b l e ( N a t u r a l a l i g n m e n t n e e d t o b e e n s u r e d )
2010-05-21 21:06:42 +04:00
* /
ENTRY( v e c t o r _ t a b l e )
.long 0 @ 0 - Reset stack pointer
.long __invalid_entry @ 1 - Reset
.long __invalid_entry @ 2 - NMI
.long __invalid_entry @ 3 - HardFault
.long __invalid_entry @ 4 - MemManage
.long __invalid_entry @ 5 - BusFault
.long __invalid_entry @ 6 - UsageFault
.long __invalid_entry @ 7 - Reserved
.long __invalid_entry @ 8 - Reserved
.long __invalid_entry @ 9 - Reserved
.long __invalid_entry @ 10 - Reserved
.long vector_swi @ 11 - SVCall
.long __invalid_entry @ 12 - Debug Monitor
.long __invalid_entry @ 13 - Reserved
.long __pendsv_entry @ 14 - PendSV
.long __invalid_entry @ 15 - SysTick
2015-04-10 11:46:46 +03:00
.rept CONFIG_CPU_V7M_NUM_IRQ
.long __irq_entry @ External Interrupts
2010-05-21 21:06:42 +04:00
.endr
2019-01-25 17:18:37 +03:00
.align 2
.globl exc_ret
exc_ret :
.space 4