2019-06-04 10:11:33 +02:00
/* SPDX-License-Identifier: GPL-2.0-only */
2010-05-21 18:06:41 +01:00
/ *
* linux/ a r c h / a r m / m m / p r o c - v7 m . S
*
* Copyright ( C ) 2 0 0 8 A R M L t d .
* Copyright ( C ) 2 0 0 1 D e e p B l u e S o l u t i o n s L t d .
*
* This i s t h e " s h e l l " o f t h e A R M v7 - M p r o c e s s o r s u p p o r t .
* /
# include < l i n u x / l i n k a g e . h >
# include < a s m / a s s e m b l e r . h >
ARM: 8451/1: v7-M: Set an early stack for __v7m_setup
On ARM v7-M, when PROCINFO_INITFUNC (__v7m_setup) is called,
a stack is needed before calling the supervisor call (SVC),
which is used by the supervisor call to save the context.
Currently, __v7m_setup() prepares a temporary stack in the .text.init
section, which is is broken if the kernel is executing directly from
read-only memory.
In particular, this is the case for LPC43xx, which allows
to execute the kernel in-place from a serial flash through its SPIFI
controller.
This commit fixes the issue by seting an early stack to its usual location.
Also, __v7m_setup() is currently saving and restoring the previous
stack. That was bogus, because there's no stack previously set,
so this commit removes it.
Acked-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
2015-11-04 17:08:37 +01:00
# include < a s m / m e m o r y . h >
2010-05-21 18:06:41 +01:00
# include < a s m / v7 m . h >
# include " p r o c - m a c r o s . S "
ENTRY( c p u _ v7 m _ p r o c _ i n i t )
2014-06-30 16:29:12 +01:00
ret l r
2010-05-21 18:06:41 +01:00
ENDPROC( c p u _ v7 m _ p r o c _ i n i t )
ENTRY( c p u _ v7 m _ p r o c _ f i n )
2014-06-30 16:29:12 +01:00
ret l r
2010-05-21 18:06:41 +01:00
ENDPROC( c p u _ v7 m _ p r o c _ f i n )
/ *
* cpu_ v7 m _ r e s e t ( l o c )
*
* Perform a s o f t r e s e t o f t h e s y s t e m . P u t t h e C P U i n t o t h e
* same s t a t e a s i t w o u l d b e i f i t h a d b e e n r e s e t , a n d b r a n c h
* to w h a t w o u l d b e t h e r e s e t v e c t o r .
*
* - loc - l o c a t i o n t o j u m p t o f o r s o f t r e s e t
* /
.align 5
ENTRY( c p u _ v7 m _ r e s e t )
2014-06-30 16:29:12 +01:00
ret r0
2010-05-21 18:06:41 +01:00
ENDPROC( c p u _ v7 m _ r e s e t )
/ *
* cpu_ v7 m _ d o _ i d l e ( )
*
* Idle t h e p r o c e s s o r ( e g , w a i t f o r i n t e r r u p t ) .
*
* IRQs a r e a l r e a d y d i s a b l e d .
* /
ENTRY( c p u _ v7 m _ d o _ i d l e )
wfi
2014-06-30 16:29:12 +01:00
ret l r
2010-05-21 18:06:41 +01:00
ENDPROC( c p u _ v7 m _ d o _ i d l e )
ENTRY( c p u _ v7 m _ d c a c h e _ c l e a n _ a r e a )
2014-06-30 16:29:12 +01:00
ret l r
2010-05-21 18:06:41 +01:00
ENDPROC( c p u _ v7 m _ d c a c h e _ c l e a n _ a r e a )
/ *
* There i s n o M M U , s o h e r e i s n o t h i n g t o d o .
* /
ENTRY( c p u _ v7 m _ s w i t c h _ m m )
2014-06-30 16:29:12 +01:00
ret l r
2010-05-21 18:06:41 +01:00
ENDPROC( c p u _ v7 m _ s w i t c h _ m m )
.globl cpu_v7m_suspend_size
.equ cpu_ v7 m _ s u s p e n d _ s i z e , 0
# ifdef C O N F I G _ A R M _ C P U _ S U S P E N D
ENTRY( c p u _ v7 m _ d o _ s u s p e n d )
2014-06-30 16:29:12 +01:00
ret l r
2010-05-21 18:06:41 +01:00
ENDPROC( c p u _ v7 m _ d o _ s u s p e n d )
ENTRY( c p u _ v7 m _ d o _ r e s u m e )
2014-06-30 16:29:12 +01:00
ret l r
2010-05-21 18:06:41 +01:00
ENDPROC( c p u _ v7 m _ d o _ r e s u m e )
# endif
2016-08-30 17:34:00 +01:00
ENTRY( c p u _ c m 7 _ d c a c h e _ c l e a n _ a r e a )
dcache_ l i n e _ s i z e r2 , r3
movw r3 , #: l o w e r 16 : B A S E A D D R _ V 7 M _ S C B + V 7 M _ S C B _ D C C M V A C
movt r3 , #: u p p e r 16 : B A S E A D D R _ V 7 M _ S C B + V 7 M _ S C B _ D C C M V A C
1 : str r0 , [ r3 ] @ clean D entry
add r0 , r0 , r2
subs r1 , r1 , r2
bhi 1 b
dsb
ret l r
ENDPROC( c p u _ c m 7 _ d c a c h e _ c l e a n _ a r e a )
ENTRY( c p u _ c m 7 _ p r o c _ f i n )
movw r2 , #: l o w e r 16 : ( B A S E A D D R _ V 7 M _ S C B + V 7 M _ S C B _ C C R )
movt r2 , #: u p p e r 16 : ( B A S E A D D R _ V 7 M _ S C B + V 7 M _ S C B _ C C R )
ldr r0 , [ r2 ]
bic r0 , r0 , #( V 7 M _ S C B _ C C R _ D C | V 7 M _ S C B _ C C R _ I C )
str r0 , [ r2 ]
ret l r
ENDPROC( c p u _ c m 7 _ p r o c _ f i n )
2019-11-04 19:31:45 +01:00
.section " .init .text " , " ax"
2010-05-21 18:06:41 +01:00
2016-08-30 17:34:00 +01:00
__v7m_cm7_setup :
mov r8 , #( V 7 M _ S C B _ C C R _ D C | V 7 M _ S C B _ C C R _ I C | V 7 M _ S C B _ C C R _ B P )
b _ _ v7 m _ s e t u p _ c o n t
2010-05-21 18:06:41 +01:00
/ *
* _ _ v7 m _ s e t u p
*
* This s h o u l d b e a b l e t o c o v e r a l l A R M v7 - M c o r e s .
* /
__v7m_setup :
2016-08-30 17:34:00 +01:00
mov r8 , 0
__v7m_setup_cont :
2010-05-21 18:06:41 +01:00
@ Configure the vector table base address
ldr r0 , =BASEADDR_V7M_SCB
ldr r12 , =vector_table
str r12 , [ r0 , V 7 M _ S C B _ V T O R ]
@ enable UsageFault, BusFault and MemManage fault.
ldr r5 , [ r0 , #V 7 M _ S C B _ S H C S R ]
orr r5 , #( V 7 M _ S C B _ S H C S R _ U S G F A U L T E N A | V 7 M _ S C B _ S H C S R _ B U S F A U L T E N A | V 7 M _ S C B _ S H C S R _ M E M F A U L T E N A )
str r5 , [ r0 , #V 7 M _ S C B _ S H C S R ]
@ Lower the priority of the SVC and PendSV exceptions
mov r5 , #0x80000000
str r5 , [ r0 , V 7 M _ S C B _ S H P R 2 ] @ set SVC priority
mov r5 , #0x00800000
str r5 , [ r0 , V 7 M _ S C B _ S H P R 3 ] @ set PendSV priority
ARM: 8451/1: v7-M: Set an early stack for __v7m_setup
On ARM v7-M, when PROCINFO_INITFUNC (__v7m_setup) is called,
a stack is needed before calling the supervisor call (SVC),
which is used by the supervisor call to save the context.
Currently, __v7m_setup() prepares a temporary stack in the .text.init
section, which is is broken if the kernel is executing directly from
read-only memory.
In particular, this is the case for LPC43xx, which allows
to execute the kernel in-place from a serial flash through its SPIFI
controller.
This commit fixes the issue by seting an early stack to its usual location.
Also, __v7m_setup() is currently saving and restoring the previous
stack. That was bogus, because there's no stack previously set,
so this commit removes it.
Acked-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
2015-11-04 17:08:37 +01:00
@ SVC to switch to handler mode. Notice that this requires sp to
@ point to writeable memory because the processor saves
@ some registers to the stack.
2015-04-21 14:17:25 +01:00
badr r1 , 1 f
2010-05-21 18:06:41 +01:00
ldr r5 , [ r12 , #11 * 4 ] @ read the SVC vector entry
str r1 , [ r12 , #11 * 4 ] @ write the temporary SVC vector entry
2016-08-31 09:14:14 +01:00
dsb
2010-05-21 18:06:41 +01:00
mov r6 , l r @ save LR
ARM: 8451/1: v7-M: Set an early stack for __v7m_setup
On ARM v7-M, when PROCINFO_INITFUNC (__v7m_setup) is called,
a stack is needed before calling the supervisor call (SVC),
which is used by the supervisor call to save the context.
Currently, __v7m_setup() prepares a temporary stack in the .text.init
section, which is is broken if the kernel is executing directly from
read-only memory.
In particular, this is the case for LPC43xx, which allows
to execute the kernel in-place from a serial flash through its SPIFI
controller.
This commit fixes the issue by seting an early stack to its usual location.
Also, __v7m_setup() is currently saving and restoring the previous
stack. That was bogus, because there's no stack previously set,
so this commit removes it.
Acked-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
2015-11-04 17:08:37 +01:00
ldr s p , =init_thread_union + T H R E A D _ S T A R T _ S P
2010-05-21 18:06:41 +01:00
cpsie i
svc #0
1 : cpsid i
2019-10-10 10:12:20 +01:00
/* Calculate exc_ret */
orr r10 , l r , #E X C _ R E T _ T H R E A D M O D E _ P R O C E S S S T A C K
2017-04-24 10:41:53 +01:00
ldmia s p , { r0 - r3 , r12 }
2010-05-21 18:06:41 +01:00
str r5 , [ r12 , #11 * 4 ] @ restore the original SVC vector entry
mov l r , r6 @ restore LR
@ Special-purpose control register
mov r1 , #1
msr c o n t r o l , r1 @ Thread mode has unpriviledged access
2016-08-30 17:34:00 +01:00
@ Configure caches (if implemented)
teq r8 , #0
2019-02-18 00:57:38 +01:00
stmiane s p , { r0 - r6 , l r } @ v7m_invalidate_l1 touches r0-r6
2016-08-30 17:34:00 +01:00
blne v7 m _ i n v a l i d a t e _ l 1
teq r8 , #0 @ re-evalutae condition
2019-02-18 00:57:38 +01:00
ldmiane s p , { r0 - r6 , l r }
2016-08-30 17:34:00 +01:00
2010-05-21 18:06:41 +01:00
@ Configure the System Control Register to ensure 8-byte stack alignment
@ Note the STKALIGN bit is either RW or RAO.
2016-08-30 17:31:22 +01:00
ldr r0 , [ r0 , V 7 M _ S C B _ C C R ] @ system control register
orr r0 , #V 7 M _ S C B _ C C R _ S T K A L I G N
2016-08-30 17:34:00 +01:00
orr r0 , r0 , r8
2014-06-30 16:29:12 +01:00
ret l r
2010-05-21 18:06:41 +01:00
ENDPROC( _ _ v7 m _ s e t u p )
2016-08-30 17:34:00 +01:00
/ *
* Cortex- M 7 p r o c e s s o r f u n c t i o n s
* /
globl_ e q u c p u _ c m 7 _ p r o c _ i n i t , c p u _ v7 m _ p r o c _ i n i t
globl_ e q u c p u _ c m 7 _ r e s e t , c p u _ v7 m _ r e s e t
globl_ e q u c p u _ c m 7 _ d o _ i d l e , c p u _ v7 m _ d o _ i d l e
globl_ e q u c p u _ c m 7 _ s w i t c h _ m m , c p u _ v7 m _ s w i t c h _ m m
2010-05-21 18:06:41 +01:00
define_ p r o c e s s o r _ f u n c t i o n s v7 m , d a b o r t =nommu_early_abort , p a b o r t =legacy_pabort , n o m m u =1
2016-08-30 17:34:00 +01:00
define_ p r o c e s s o r _ f u n c t i o n s c m 7 , d a b o r t =nommu_early_abort , p a b o r t =legacy_pabort , n o m m u =1
2010-05-21 18:06:41 +01:00
.section " .rodata "
string c p u _ a r c h _ n a m e , " a r m v7 m "
string c p u _ e l f _ n a m e " v7 m "
string c p u _ v7 m _ n a m e " A R M v7 - M "
2019-11-04 19:31:45 +01:00
.section " .proc .info .init " , " a"
2010-05-21 18:06:41 +01:00
2016-08-30 17:32:42 +01:00
.macro __v7m_proc name, i n i t f u n c , c a c h e _ f n s = n o p _ c a c h e _ f n s , h w c a p s = 0 , p r o c _ f n s = v7 m _ p r o c e s s o r _ f u n c t i o n s
.long 0 /* proc_info_list.__cpu_mm_mmu_flags */
.long 0 /* proc_info_list.__cpu_io_mmu_flags */
initfn \ i n i t f u n c , \ n a m e
.long cpu_arch_name
.long cpu_elf_name
.long HWCAP_HALF | HWCAP_ T H U M B | H W C A P _ F A S T _ M U L T | \ h w c a p s
.long cpu_v7m_name
.long \ proc_ f n s
.long 0 /* proc_info_list.tlb */
.long 0 /* proc_info_list.user */
.long \ cache_ f n s
.endm
2016-08-30 17:34:00 +01:00
/ *
* Match A R M C o r t e x - M 7 p r o c e s s o r .
* /
.type _ _ v7 m _ c m 7 _ p r o c _ i n f o , #o b j e c t
__v7m_cm7_proc_info :
.long 0x410fc270 /* ARM Cortex-M7 0xC27 */
.long 0xff0ffff0 /* Mask off revision, patch release */
_ _ v7 m _ p r o c _ _ v7 m _ c m 7 _ p r o c _ i n f o , _ _ v7 m _ c m 7 _ s e t u p , h w c a p s = H W C A P _ E D S P , c a c h e _ f n s = v7 m _ c a c h e _ f n s , p r o c _ f n s = c m 7 _ p r o c e s s o r _ f u n c t i o n s
.size _ _ v7 m _ c m 7 _ p r o c _ i n f o , . - _ _ v7 m _ c m 7 _ p r o c _ i n f o
2016-08-30 17:32:42 +01:00
/ *
* Match A R M C o r t e x - M 4 p r o c e s s o r .
* /
.type _ _ v7 m _ c m 4 _ p r o c _ i n f o , #o b j e c t
__v7m_cm4_proc_info :
.long 0x410fc240 /* ARM Cortex-M4 0xC24 */
.long 0xff0ffff0 /* Mask off revision, patch release */
_ _ v7 m _ p r o c _ _ v7 m _ c m 4 _ p r o c _ i n f o , _ _ v7 m _ s e t u p , h w c a p s = H W C A P _ E D S P
.size _ _ v7 m _ c m 4 _ p r o c _ i n f o , . - _ _ v7 m _ c m 4 _ p r o c _ i n f o
/ *
* Match A R M C o r t e x - M 3 p r o c e s s o r .
* /
.type _ _ v7 m _ c m 3 _ p r o c _ i n f o , #o b j e c t
__v7m_cm3_proc_info :
.long 0x410fc230 /* ARM Cortex-M3 0xC23 */
.long 0xff0ffff0 /* Mask off revision, patch release */
_ _ v7 m _ p r o c _ _ v7 m _ c m 3 _ p r o c _ i n f o , _ _ v7 m _ s e t u p
.size _ _ v7 m _ c m 3 _ p r o c _ i n f o , . - _ _ v7 m _ c m 3 _ p r o c _ i n f o
2010-05-21 18:06:41 +01:00
/ *
* Match a n y A R M v7 - M p r o c e s s o r c o r e .
* /
.type _ _ v7 m _ p r o c _ i n f o , #o b j e c t
__v7m_proc_info :
.long 0x000f0000 @ Required ID value
.long 0x000f0000 @ Mask for ID
2016-08-30 17:32:42 +01:00
_ _ v7 m _ p r o c _ _ v7 m _ p r o c _ i n f o , _ _ v7 m _ s e t u p
2010-05-21 18:06:41 +01:00
.size _ _ v7 m _ p r o c _ i n f o , . - _ _ v7 m _ p r o c _ i n f o