2019-06-04 11:11:33 +03:00
/* SPDX-License-Identifier: GPL-2.0-only */
2006-03-27 17:58:25 +04:00
/ *
* linux/ a r c h / a r m / k e r n e l / h e a d - c o m m o n . S
*
* Copyright ( C ) 1 9 9 4 - 2 0 0 2 R u s s e l l K i n g
* Copyright ( c ) 2 0 0 3 A R M L i m i t e d
* All R i g h t s R e s e r v e d
* /
2014-06-30 19:29:12 +04:00
# include < a s m / a s s e m b l e r . h >
2006-03-27 17:58:25 +04:00
2008-03-05 08:50:07 +03:00
# define A T A G _ C O R E 0 x54 4 1 0 0 0 1
# define A T A G _ C O R E _ S I Z E ( ( 2 * 4 + 3 * 4 ) > > 2 )
2009-10-01 20:43:29 +04:00
# define A T A G _ C O R E _ S I Z E _ E M P T Y ( ( 2 * 4 ) > > 2 )
2008-03-05 08:50:07 +03:00
2011-04-29 00:27:20 +04:00
# ifdef C O N F I G _ C P U _ B I G _ E N D I A N
# define O F _ D T _ M A G I C 0 x d00 d f e e d
# else
# define O F _ D T _ M A G I C 0 x e d f e 0 d d0 / * 0 x d00 d f e e d i n b i g - e n d i a n * /
# endif
2006-03-27 17:58:25 +04:00
/ *
* Exception h a n d l i n g . S o m e t h i n g w e n t w r o n g a n d w e c a n ' t p r o c e e d . W e
* ought t o t e l l t h e u s e r , b u t s i n c e w e d o n ' t h a v e a n y g u a r a n t e e t h a t
* we' r e e v e n r u n n i n g o n t h e r i g h t a r c h i t e c t u r e , w e d o v i r t u a l l y n o t h i n g .
*
* If C O N F I G _ D E B U G _ L L i s s e t w e t r y t o p r i n t o u t s o m e t h i n g a b o u t t h e e r r o r
* and h o p e f o r t h e b e s t ( u s e f u l i f b o o t l o a d e r f a i l s t o p a s s a p r o p e r
* machine I D f o r e x a m p l e ) .
* /
2010-10-04 20:45:25 +04:00
_ _ HEAD
2007-06-01 01:02:22 +04:00
/ * Determine v a l i d i t y o f t h e r2 a t a g s p o i n t e r . T h e h e u r i s t i c r e q u i r e s
* that t h e p o i n t e r b e a l i g n e d , i n t h e f i r s t 1 6 k o f p h y s i c a l R A M a n d
2011-04-29 00:27:20 +04:00
* that t h e A T A G _ C O R E m a r k e r i s f i r s t a n d p r e s e n t . I f C O N F I G _ O F _ F L A T T R E E
* is s e l e c t e d , t h e n i t w i l l a l s o a c c e p t a d t b p o i n t e r . F u t u r e r e v i s i o n s
2007-06-01 01:02:22 +04:00
* of t h i s f u n c t i o n m a y b e m o r e l e n i e n t w i t h t h e p h y s i c a l a d d r e s s a n d
* may a l s o b e a b l e t o m o v e t h e A T A G S b l o c k i f n e c e s s a r y .
*
* Returns :
2011-04-29 00:27:20 +04:00
* r2 e i t h e r v a l i d a t a g s p o i n t e r , v a l i d d t b p o i n t e r , o r z e r o
2007-06-01 01:02:22 +04:00
* r5 , r6 c o r r u p t e d
* /
__vet_atags :
tst r2 , #0x3 @ aligned?
bne 1 f
2011-04-29 00:27:20 +04:00
ldr r5 , [ r2 , #0 ]
# ifdef C O N F I G _ O F _ F L A T T R E E
ldr r6 , =OF_DT_MAGIC @ is it a DTB?
cmp r5 , r6
beq 2 f
# endif
cmp r5 , #A T A G _ C O R E _ S I Z E @ i s f i r s t t a g A T A G _ C O R E ?
2009-10-01 20:43:29 +04:00
cmpne r5 , #A T A G _ C O R E _ S I Z E _ E M P T Y
2007-06-01 01:02:22 +04:00
bne 1 f
ldr r5 , [ r2 , #4 ]
ldr r6 , =ATAG_CORE
cmp r5 , r6
bne 1 f
2014-06-30 19:29:12 +04:00
2 : ret l r @ atag/dtb pointer is ok
2007-06-01 01:02:22 +04:00
1 : mov r2 , #0
2014-06-30 19:29:12 +04:00
ret l r
2008-08-28 14:22:32 +04:00
ENDPROC( _ _ v e t _ a t a g s )
2010-10-01 18:37:05 +04:00
2010-10-04 19:29:35 +04:00
/ *
* The f o l l o w i n g f r a g m e n t o f c o d e i s e x e c u t e d w i t h t h e M M U o n i n M M U m o d e ,
* and u s e s a b s o l u t e a d d r e s s e s ; this is not position independent.
*
2019-10-10 12:12:20 +03:00
* r0 = c p #15 c o n t r o l r e g i s t e r ( e x c _ r e t f o r M - c l a s s )
2010-10-04 19:29:35 +04:00
* r1 = m a c h i n e I D
2011-04-29 00:27:20 +04:00
* r2 = a t a g s / d t b p o i n t e r
2010-10-04 19:29:35 +04:00
* r9 = p r o c e s s o r I D
* /
_ _ INIT
__mmap_switched :
2017-08-24 22:54:47 +03:00
mov r7 , r1
mov r8 , r2
mov r10 , r0
adr r4 , _ _ m m a p _ s w i t c h e d _ d a t a
mov f p , #0
2017-08-25 07:54:18 +03:00
# if d e f i n e d ( C O N F I G _ X I P _ D E F L A T E D _ D A T A )
ARM( l d r s p , [ r4 ] , #4 )
THUMB( l d r s p , [ r4 ] )
THUMB( a d d r4 , #4 )
bl _ _ i n f l a t e _ k e r n e l _ d a t a @ decompress .data to RAM
teq r0 , #0
bne _ _ e r r o r
# elif d e f i n e d ( C O N F I G _ X I P _ K E R N E L )
2017-08-24 22:54:47 +03:00
ARM( l d m i a r4 ! , { r0 , r1 , r2 , s p } )
THUMB( l d m i a r4 ! , { r0 , r1 , r2 , r3 } )
THUMB( m o v s p , r3 )
sub r2 , r2 , r1
2020-10-26 01:52:08 +03:00
bl _ _ m e m c p y @ copy .data to RAM
2017-08-24 22:54:47 +03:00
# endif
ARM( l d m i a r4 ! , { r0 , r1 , s p } )
THUMB( l d m i a r4 ! , { r0 , r1 , r3 } )
THUMB( m o v s p , r3 )
2018-01-19 20:17:46 +03:00
sub r2 , r1 , r0
mov r1 , #0
2020-10-26 01:52:08 +03:00
bl _ _ m e m s e t @ clear .bss
2017-08-24 22:54:47 +03:00
ldmia r4 , { r0 , r1 , r2 , r3 }
str r9 , [ r0 ] @ Save processor ID
str r7 , [ r1 ] @ Save machine type
str r8 , [ r2 ] @ Save atags pointer
cmp r3 , #0
strne r10 , [ r3 ] @ Save control register values
2020-10-26 01:55:16 +03:00
# ifdef C O N F I G _ K A S A N
bl k a s a n _ e a r l y _ i n i t
# endif
2017-10-03 21:14:38 +03:00
mov l r , #0
2010-10-04 19:29:35 +04:00
b s t a r t _ k e r n e l
ENDPROC( _ _ m m a p _ s w i t c h e d )
.align 2
.type _ _ mmap_ s w i t c h e d _ d a t a , % o b j e c t
__mmap_switched_data :
2017-08-24 22:54:47 +03:00
# ifdef C O N F I G _ X I P _ K E R N E L
2017-08-25 07:54:18 +03:00
# ifndef C O N F I G _ X I P _ D E F L A T E D _ D A T A
2017-08-24 22:54:47 +03:00
.long _sdata @ r0
.long __data_loc @ r1
.long _edata_loc @ r2
2017-08-25 07:54:18 +03:00
# endif
2017-08-24 22:54:47 +03:00
.long __bss_stop @ sp (temporary stack in .bss)
# endif
.long __bss_start @ r0
.long __bss_stop @ r1
.long init_thread_union + THREAD_ S T A R T _ S P @ sp
.long processor_id @ r0
.long __machine_arch_type @ r1
.long __atags_pointer @ r2
2012-01-16 13:34:31 +04:00
# ifdef C O N F I G _ C P U _ C P 1 5
2017-08-24 22:54:47 +03:00
.long cr_alignment @ r3
2012-01-16 13:34:31 +04:00
# else
2019-10-10 12:12:20 +03:00
M_ C L A S S ( . l o n g e x c _ r e t ) @ r3
AR_ C L A S S ( . l o n g 0 ) @ r3
2012-01-16 13:34:31 +04:00
# endif
2010-10-04 19:29:35 +04:00
.size _ _ mmap_ s w i t c h e d _ d a t a , . - _ _ m m a p _ s w i t c h e d _ d a t a
2018-07-19 13:42:36 +03:00
_ _ FINIT
.text
2010-10-04 19:29:35 +04:00
/ *
* This p r o v i d e s a C - A P I v e r s i o n o f _ _ l o o k u p _ p r o c e s s o r _ t y p e
* /
ENTRY( l o o k u p _ p r o c e s s o r _ t y p e )
stmfd s p ! , { r4 - r6 , r9 , l r }
mov r9 , r0
bl _ _ l o o k u p _ p r o c e s s o r _ t y p e
mov r0 , r5
ldmfd s p ! , { r4 - r6 , r9 , p c }
ENDPROC( l o o k u p _ p r o c e s s o r _ t y p e )
2010-10-01 18:37:05 +04:00
/ *
* Read p r o c e s s o r I D r e g i s t e r ( C P #15 , C R 0 ) , a n d l o o k u p i n t h e l i n k e r - b u i l t
* supported p r o c e s s o r l i s t . N o t e t h a t w e c a n ' t u s e t h e a b s o l u t e a d d r e s s e s
* for t h e _ _ p r o c _ i n f o l i s t s s i n c e w e a r e n ' t r u n n i n g w i t h t h e M M U o n
* ( and t h e r e f o r e , w e a r e n o t i n t h e c o r r e c t a d d r e s s s p a c e ) . W e h a v e t o
* calculate t h e o f f s e t .
*
* r9 = c p u i d
* Returns :
* r3 , r4 , r6 c o r r u p t e d
* r5 = p r o c _ i n f o p o i n t e r i n p h y s i c a l a d d r e s s s p a c e
* r9 = c p u i d ( p r e s e r v e d )
* /
__lookup_processor_type :
2020-09-14 11:25:06 +03:00
/ *
* Look i n < a s m / p r o c i n f o . h > f o r i n f o r m a t i o n a b o u t t h e _ _ p r o c _ i n f o
* structure.
* /
adr_ l r5 , _ _ p r o c _ i n f o _ b e g i n
adr_ l r6 , _ _ p r o c _ i n f o _ e n d
2010-10-01 18:37:05 +04:00
1 : ldmia r5 , { r3 , r4 } @ value, mask
and r4 , r4 , r9 @ mask wanted bits
teq r3 , r4
beq 2 f
add r5 , r5 , #P R O C _ I N F O _ S Z @ s i z e o f ( p r o c _ i n f o _ l i s t )
cmp r5 , r6
blo 1 b
mov r5 , #0 @ unknown processor
2014-06-30 19:29:12 +04:00
2 : ret l r
2010-10-01 18:37:05 +04:00
ENDPROC( _ _ l o o k u p _ p r o c e s s o r _ t y p e )
ARM: 7980/1: kernel: improve error message when LPAE config doesn't match CPU
Currently, when the kernel is configured with LPAE support, but the
CPU doesn't support it, the error message is fairly cryptic:
Error: unrecognized/unsupported processor variant (0x561f5811).
This messages is normally shown when there is an issue when comparing
the processor ID (CP15 0, c0, c0) with the values/masks described in
proc-v7.S. However, the same message is displayed when LPAE support is
enabled in the kernel configuration, but not available in the CPU,
after looking at ID_MMFR0 (CP15 0, c0, c1, 4). Having the same error
message is highly misleading.
This commit improves this by showing a different error message when
this situation occurs:
Error: Kernel with LPAE support, but CPU does not support LPAE.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
2014-02-18 20:02:54 +04:00
__error_lpae :
# ifdef C O N F I G _ D E B U G _ L L
adr r0 , s t r _ l p a e
bl p r i n t a s c i i
b _ _ e r r o r
str_lpae : .asciz " \nError: Kernel with LPAE support, but CPU does not support LPAE.\n "
# else
b _ _ e r r o r
# endif
.align
ENDPROC( _ _ e r r o r _ l p a e )
2010-10-04 20:39:20 +04:00
__error_p :
# ifdef C O N F I G _ D E B U G _ L L
adr r0 , s t r _ p1
bl p r i n t a s c i i
mov r0 , r9
bl p r i n t h e x8
adr r0 , s t r _ p2
bl p r i n t a s c i i
b _ _ e r r o r
str_p1 : .asciz " \nError: unrecognized/unsupported processor variant (0x "
str_p2 : .asciz " ).\n "
.align
# endif
ENDPROC( _ _ e r r o r _ p )
__error :
# ifdef C O N F I G _ A R C H _ R P C
/ *
* Turn t h e s c r e e n r e d o n a e r r o r - R i s c P C o n l y .
* /
mov r0 , #0x02000000
mov r3 , #0x11
orr r3 , r3 , r3 , l s l #8
orr r3 , r3 , r3 , l s l #16
str r3 , [ r0 ] , #4
str r3 , [ r0 ] , #4
str r3 , [ r0 ] , #4
str r3 , [ r0 ] , #4
# endif
1 : mov r0 , r0
b 1 b
ENDPROC( _ _ e r r o r )