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 p r o g r a m i s f r e e s o f t w a r e ; you can redistribute it and/or modify
* it u n d e r t h e t e r m s o f t h e G N U G e n e r a l P u b l i c L i c e n s e v e r s i o n 2 a s
* published b y t h e F r e e S o f t w a r e F o u n d a t i o n .
*
* 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
.section " .text .init " , # alloc, #e x e c i n s t r
/ *
* _ _ 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 :
@ 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
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
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
@ Configure the System Control Register to ensure 8-byte stack alignment
@ Note the STKALIGN bit is either RW or RAO.
ldr r12 , [ r0 , V 7 M _ S C B _ C C R ] @ system control register
orr r12 , #V 7 M _ S C B _ C C R _ S T K A L I G N
str r12 , [ r0 , V 7 M _ S C B _ C C R ]
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 )
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
.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 "
2015-03-18 07:29:32 +01:00
.section " .proc .info .init " , # alloc
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
.long 0 @ proc_info_list.__cpu_mm_mmu_flags
.long 0 @ proc_info_list.__cpu_io_mmu_flags
2015-03-18 07:29:32 +01:00
initfn _ _ v7 m _ s e t u p , _ _ v7 m _ p r o c _ i n f o @ proc_info_list.__cpu_flush
2010-05-21 18:06:41 +01:00
.long cpu_arch_name
.long cpu_elf_name
2013-05-06 11:35:42 +02:00
.long HWCAP_ H A L F | H W C A P _ T H U M B | H W C A P _ F A S T _ M U L T
2010-05-21 18:06:41 +01:00
.long cpu_v7m_name
.long v7m_processor_functions @ proc_info_list.proc
.long 0 @ proc_info_list.tlb
.long 0 @ proc_info_list.user
.long nop_cache_fns @ proc_info_list.cache
.size _ _ v7 m _ p r o c _ i n f o , . - _ _ v7 m _ p r o c _ i n f o