2012-03-05 11:49:27 +00:00
/ *
* Low- l e v e l C P U i n i t i a l i s a t i o n
* Based o n a r c h / a r m / k e r n e l / h e a d . 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 - 2 0 1 2 A R M L t d .
* Authors : Catalin M a r i n a s < c a t a l i n . m a r i n a s @arm.com>
* Will D e a c o n < w i l l . d e a c o n @arm.com>
*
* 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 p r o g r a m i s d i s t r i b u t e d i n t h e h o p e t h a t i t w i l l b e u s e f u l ,
* but W I T H O U T A N Y W A R R A N T Y ; without even the implied warranty of
* MERCHANTABILITY o r F I T N E S S F O R A P A R T I C U L A R P U R P O S E . S e e t h e
* GNU G e n e r a l P u b l i c L i c e n s e f o r m o r e d e t a i l s .
*
* You s h o u l d h a v e r e c e i v e d a c o p y 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
* along w i t h t h i s p r o g r a m . I f n o t , s e e < h t t p : / / w w w . g n u . o r g / l i c e n s e s / > .
* /
# include < l i n u x / l i n k a g e . h >
# include < l i n u x / i n i t . h >
# include < a s m / a s s e m b l e r . h >
# include < a s m / p t r a c e . h >
# include < a s m / a s m - o f f s e t s . h >
2012-08-29 18:32:18 +01:00
# include < a s m / c p u t y p e . h >
2012-03-05 11:49:27 +00:00
# include < a s m / m e m o r y . h >
# include < a s m / t h r e a d _ i n f o . h >
# include < a s m / p g t a b l e - h w d e f . h >
# include < a s m / p g t a b l e . h >
# include < a s m / p a g e . h >
2012-10-26 15:40:05 +01:00
# include < a s m / v i r t . h >
2012-03-05 11:49:27 +00:00
/ *
* swapper_ p g _ d i r i s t h e v i r t u a l a d d r e s s o f t h e i n i t i a l p a g e t a b l e . W e p l a c e
* the p a g e t a b l e s 3 * P A G E _ S I Z E b e l o w K E R N E L _ R A M _ V A D D R . T h e i d m a p _ p g _ d i r h a s
* 2 pages a n d i s p l a c e d b e l o w s w a p p e r _ p g _ d i r .
* /
# define K E R N E L _ R A M _ V A D D R ( P A G E _ O F F S E T + T E X T _ O F F S E T )
# if ( K E R N E L _ R A M _ V A D D R & 0 x f f f f f ) ! = 0 x80 0 0 0
# error K E R N E L _ R A M _ V A D D R m u s t s t a r t a t 0 x X X X 8 0 0 0 0
# endif
# define S W A P P E R _ D I R _ S I Z E ( 3 * P A G E _ S I Z E )
# define I D M A P _ D I R _ S I Z E ( 2 * P A G E _ S I Z E )
.globl swapper_pg_dir
.equ swapper_ p g _ d i r , K E R N E L _ R A M _ V A D D R - S W A P P E R _ D I R _ S I Z E
.globl idmap_pg_dir
.equ idmap_ p g _ d i r , s w a p p e r _ p g _ d i r - I D M A P _ D I R _ S I Z E
.macro pgtbl, t t b0 , t t b1 , p h y s
add \ t t b1 , \ p h y s , #T E X T _ O F F S E T - S W A P P E R _ D I R _ S I Z E
sub \ t t b0 , \ t t b1 , #I D M A P _ D I R _ S I Z E
.endm
# ifdef C O N F I G _ A R M 6 4 _ 6 4 K _ P A G E S
# define B L O C K _ S H I F T P A G E _ S H I F T
# define B L O C K _ S I Z E P A G E _ S I Z E
# else
# define B L O C K _ S H I F T S E C T I O N _ S H I F T
# define B L O C K _ S I Z E S E C T I O N _ S I Z E
# endif
# define K E R N E L _ S T A R T K E R N E L _ R A M _ V A D D R
# define K E R N E L _ E N D _ e n d
/ *
* Initial m e m o r y m a p a t t r i b u t e s .
* /
# ifndef C O N F I G _ S M P
# define P T E _ F L A G S P T E _ T Y P E _ P A G E | P T E _ A F
# define P M D _ F L A G S P M D _ T Y P E _ S E C T | P M D _ S E C T _ A F
# else
# define P T E _ F L A G S P T E _ T Y P E _ P A G E | P T E _ A F | P T E _ S H A R E D
# define P M D _ F L A G S P M D _ T Y P E _ S E C T | P M D _ S E C T _ A F | P M D _ S E C T _ S
# endif
# ifdef C O N F I G _ A R M 6 4 _ 6 4 K _ P A G E S
# define M M _ M M U F L A G S P T E _ A T T R I N D X ( M T _ N O R M A L ) | P T E _ F L A G S
# else
# define M M _ M M U F L A G S P M D _ A T T R I N D X ( M T _ N O R M A L ) | P M D _ F L A G S
# endif
/ *
* Kernel s t a r t u p e n t r y p o i n t .
* - - - - - - - - - - - - - - - - - - - - - - - - - - -
*
* The r e q u i r e m e n t s a r e :
* MMU = o f f , D - c a c h e = o f f , I - c a c h e = o n o r o f f ,
* x0 = p h y s i c a l a d d r e s s t o t h e F D T b l o b .
*
* This c o d e i s m o s t l y p o s i t i o n i n d e p e n d e n t s o y o u c a l l t h i s a t
* _ _ pa( P A G E _ O F F S E T + T E X T _ O F F S E T ) .
*
* Note t h a t t h e c a l l e e - s a v e d r e g i s t e r s a r e u s e d f o r s t o r i n g v a r i a b l e s
* that a r e u s e f u l b e f o r e t h e M M U i s e n a b l e d . T h e a l l o c a t i o n s a r e d e s c r i b e d
* in t h e e n t r y r o u t i n e s .
* /
_ _ HEAD
/ *
* DO N O T M O D I F Y . I m a g e h e a d e r e x p e c t e d b y L i n u x b o o t - l o a d e r s .
* /
b s t e x t / / b r a n c h t o k e r n e l s t a r t , m a g i c
.long 0 / / reserved
.quad TEXT_OFFSET / / Image l o a d o f f s e t f r o m s t a r t o f R A M
.quad 0 / / reserved
.quad 0 / / reserved
2013-08-15 00:10:00 +01:00
.quad 0 / / reserved
.quad 0 / / reserved
.quad 0 / / reserved
.byte 0x41 / / Magic n u m b e r , " A R M \ x64 "
.byte 0x52
.byte 0x4d
.byte 0x64
.word 0 / / reserved
2012-03-05 11:49:27 +00:00
ENTRY( s t e x t )
mov x21 , x0 / / x21 =FDT
2013-10-11 14:52:16 +01:00
bl e l 2 _ s e t u p / / D r o p t o E L 1 , w20 =cpu_boot_mode
2012-10-26 15:40:05 +01:00
bl _ _ c a l c _ p h y s _ o f f s e t / / x24 =PHYS_OFFSET , x28 =PHYS_OFFSET - P A G E _ O F F S E T
2013-10-11 14:52:16 +01:00
bl s e t _ c p u _ b o o t _ m o d e _ f l a g
2012-03-05 11:49:27 +00:00
mrs x22 , m i d r _ e l 1 / / x22 =cpuid
mov x0 , x22
bl l o o k u p _ p r o c e s s o r _ t y p e
mov x23 , x0 / / x23 =current c p u _ t a b l e
cbz x23 , _ _ e r r o r _ p / / i n v a l i d p r o c e s s o r ( x23 =0 ) ?
bl _ _ v e t _ f d t
bl _ _ c r e a t e _ p a g e _ t a b l e s / / x25 =TTBR0 , x26 =TTBR1
/ *
* The f o l l o w i n g c a l l s C P U s p e c i f i c c o d e i n a p o s i t i o n i n d e p e n d e n t
* manner. S e e a r c h / a r m 6 4 / m m / p r o c . S f o r d e t a i l s . x23 = b a s e o f
* cpu_ i n f o s t r u c t u r e s e l e c t e d b y l o o k u p _ p r o c e s s o r _ t y p e a b o v e .
* On r e t u r n , t h e C P U w i l l b e r e a d y f o r t h e M M U t o b e t u r n e d o n a n d
* the T C R w i l l h a v e b e e n s e t .
* /
ldr x27 , _ _ s w i t c h _ d a t a / / a d d r e s s t o j u m p t o a f t e r
/ / MMU h a s b e e n e n a b l e d
adr l r , _ _ e n a b l e _ m m u / / r e t u r n ( P I C ) a d d r e s s
ldr x12 , [ x23 , #C P U _ I N F O _ S E T U P ]
add x12 , x12 , x28 / / _ _ v i r t _ t o _ p h y s
br x12 / / i n i t i a l i s e p r o c e s s o r
ENDPROC( s t e x t )
/ *
* If w e ' r e f o r t u n a t e e n o u g h t o b o o t a t E L 2 , e n s u r e t h a t t h e w o r l d i s
* sane b e f o r e d r o p p i n g t o E L 1 .
2013-10-11 14:52:16 +01:00
*
* Returns e i t h e r B O O T _ C P U _ M O D E _ E L 1 o r B O O T _ C P U _ M O D E _ E L 2 i n x20 i f
* booted i n E L 1 o r E L 2 r e s p e c t i v e l y .
2012-03-05 11:49:27 +00:00
* /
ENTRY( e l 2 _ s e t u p )
mrs x0 , C u r r e n t E L
cmp x0 , #P S R _ M O D E _ E L 2 t
ccmp x0 , #P S R _ M O D E _ E L 2 h , #0x4 , n e
2013-10-11 14:52:17 +01:00
b. n e 1 f
mrs x0 , s c t l r _ e l 2
CPU_ B E ( o r r x0 , x0 , #( 1 < < 2 5 ) ) / / S e t t h e E E b i t f o r E L 2
CPU_ L E ( b i c x0 , x0 , #( 1 < < 2 5 ) ) / / C l e a r t h e E E b i t f o r E L 2
msr s c t l r _ e l 2 , x0
b 2 f
1 : mrs x0 , s c t l r _ e l 1
CPU_ B E ( o r r x0 , x0 , #( 3 < < 2 4 ) ) / / S e t t h e E E a n d E 0 E b i t s f o r E L 1
CPU_ L E ( b i c x0 , x0 , #( 3 < < 2 4 ) ) / / C l e a r t h e E E a n d E 0 E b i t s f o r E L 1
msr s c t l r _ e l 1 , x0
2013-10-11 14:52:16 +01:00
mov w20 , #B O O T _ C P U _ M O D E _ E L 1 / / T h i s c p u b o o t e d i n E L 1
2013-10-11 14:52:17 +01:00
isb
2012-03-05 11:49:27 +00:00
ret
/* Hyp configuration. */
2013-10-11 14:52:17 +01:00
2 : mov x0 , #( 1 < < 3 1 ) / / 6 4 - b i t E L 1
2012-03-05 11:49:27 +00:00
msr h c r _ e l 2 , x0
/* Generic timers. */
mrs x0 , c n t h c t l _ e l 2
orr x0 , x0 , #3 / / E n a b l e E L 1 p h y s i c a l t i m e r s
msr c n t h c t l _ e l 2 , x0
2012-11-29 22:48:31 +00:00
msr c n t v o f f _ e l 2 , x z r / / C l e a r v i r t u a l o f f s e t
2012-03-05 11:49:27 +00:00
/* Populate ID registers. */
mrs x0 , m i d r _ e l 1
mrs x1 , m p i d r _ e l 1
msr v p i d r _ e l 2 , x0
msr v m p i d r _ e l 2 , x1
/* sctlr_el1 */
mov x0 , #0x0800 / / S e t / c l e a r R E S { 1 ,0 } b i t s
2013-10-11 14:52:17 +01:00
CPU_ B E ( m o v k x0 , #0x33d0 , l s l #16 ) / / S e t E E a n d E 0 E o n B E s y s t e m s
CPU_ L E ( m o v k x0 , #0x30d0 , l s l #16 ) / / C l e a r E E a n d E 0 E o n L E s y s t e m s
2012-03-05 11:49:27 +00:00
msr s c t l r _ e l 1 , x0
/* Coprocessor traps. */
mov x0 , #0x33ff
msr c p t r _ e l 2 , x0 / / D i s a b l e c o p r o . t r a p s t o E L 2
# ifdef C O N F I G _ C O M P A T
msr h s t r _ e l 2 , x z r / / D i s a b l e C P 1 5 t r a p s t o E L 2
# endif
2012-11-06 19:27:59 +00:00
/* Stage-2 translation */
msr v t t b r _ e l 2 , x z r
2012-10-19 17:46:27 +01:00
/* Hypervisor stub */
adr x0 , _ _ h y p _ s t u b _ v e c t o r s
msr v b a r _ e l 2 , x0
2012-03-05 11:49:27 +00:00
/* spsr */
mov x0 , #( P S R _ F _ B I T | P S R _ I _ B I T | P S R _ A _ B I T | P S R _ D _ B I T | \
PSR_ M O D E _ E L 1 h )
msr s p s r _ e l 2 , x0
msr e l r _ e l 2 , l r
2013-10-11 14:52:16 +01:00
mov w20 , #B O O T _ C P U _ M O D E _ E L 2 / / T h i s C P U b o o t e d i n E L 2
2012-03-05 11:49:27 +00:00
eret
ENDPROC( e l 2 _ s e t u p )
2013-10-11 14:52:16 +01:00
/ *
* Sets t h e _ _ b o o t _ c p u _ m o d e f l a g d e p e n d i n g o n t h e C P U b o o t m o d e p a s s e d
* in x20 . S e e a r c h / a r m 6 4 / i n c l u d e / a s m / v i r t . h f o r m o r e i n f o .
* /
ENTRY( s e t _ c p u _ b o o t _ m o d e _ f l a g )
ldr x1 , =__boot_cpu_mode / / C o m p u t e _ _ b o o t _ c p u _ m o d e
add x1 , x1 , x28
cmp w20 , #B O O T _ C P U _ M O D E _ E L 2
b. n e 1 f
add x1 , x1 , #4
1 : str w20 , [ x1 ] / / T h i s C P U h a s b o o t e d i n E L 1
ret
ENDPROC( s e t _ c p u _ b o o t _ m o d e _ f l a g )
2012-10-26 15:40:05 +01:00
/ *
* We n e e d t o f i n d o u t t h e C P U b o o t m o d e l o n g a f t e r b o o t , s o w e n e e d t o
* store i t i n a w r i t a b l e v a r i a b l e .
*
* This i s n o t i n . b s s , b e c a u s e w e s e t i t s u f f i c i e n t l y e a r l y t h a t t h e b o o t - t i m e
* zeroing o f . b s s w o u l d c l o b b e r i t .
* /
.pushsection .data
ENTRY( _ _ b o o t _ c p u _ m o d e )
.long BOOT_CPU_MODE_EL2
.long 0
.popsection
2012-03-05 11:49:27 +00:00
.align 3
2 : .quad .
.quad PAGE_OFFSET
# ifdef C O N F I G _ S M P
.align 3
1 : .quad .
.quad secondary_holding_pen_release
/ *
* This p r o v i d e s a " h o l d i n g p e n " f o r p l a t f o r m s t o h o l d a l l s e c o n d a r y
* cores a r e h e l d u n t i l w e ' r e r e a d y f o r t h e m t o i n i t i a l i s e .
* /
ENTRY( s e c o n d a r y _ h o l d i n g _ p e n )
2013-10-11 14:52:16 +01:00
bl e l 2 _ s e t u p / / D r o p t o E L 1 , w20 =cpu_boot_mode
bl _ _ c a l c _ p h y s _ o f f s e t / / x24 =PHYS_OFFSET , x28 =PHYS_OFFSET - P A G E _ O F F S E T
bl s e t _ c p u _ b o o t _ m o d e _ f l a g
2012-03-05 11:49:27 +00:00
mrs x0 , m p i d r _ e l 1
2012-08-29 18:32:18 +01:00
ldr x1 , =MPIDR_HWID_BITMASK
and x0 , x0 , x1
2012-03-05 11:49:27 +00:00
adr x1 , 1 b
ldp x2 , x3 , [ x1 ]
sub x1 , x1 , x2
add x3 , x3 , x1
pen : ldr x4 , [ x3 ]
cmp x4 , x0
b. e q s e c o n d a r y _ s t a r t u p
wfe
b p e n
ENDPROC( s e c o n d a r y _ h o l d i n g _ p e n )
arm64: factor out spin-table boot method
The arm64 kernel has an internal holding pen, which is necessary for
some systems where we can't bring CPUs online individually and must hold
multiple CPUs in a safe area until the kernel is able to handle them.
The current SMP infrastructure for arm64 is closely coupled to this
holding pen, and alternative boot methods must launch CPUs into the pen,
where they sit before they are launched into the kernel proper.
With PSCI (and possibly other future boot methods), we can bring CPUs
online individually, and need not perform the secondary_holding_pen
dance. Instead, this patch factors the holding pen management code out
to the spin-table boot method code, as it is the only boot method
requiring the pen.
A new entry point for secondaries, secondary_entry is added for other
boot methods to use, which bypasses the holding pen and its associated
overhead when bringing CPUs online. The smp.pen.text section is also
removed, as the pen can live in head.text without problem.
The cpu_operations structure is extended with two new functions,
cpu_boot and cpu_postboot, for bringing a cpu into the kernel and
performing any post-boot cleanup required by a bootmethod (e.g.
resetting the secondary_holding_pen_release to INVALID_HWID).
Documentation is added for cpu_operations.
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
2013-10-24 20:30:16 +01:00
/ *
* Secondary e n t r y p o i n t t h a t j u m p s s t r a i g h t i n t o t h e k e r n e l . O n l y t o
* be u s e d w h e r e C P U s a r e b r o u g h t o n l i n e d y n a m i c a l l y b y t h e k e r n e l .
* /
ENTRY( s e c o n d a r y _ e n t r y )
bl e l 2 _ s e t u p / / D r o p t o E L 1
2013-11-18 18:56:42 +00:00
bl _ _ c a l c _ p h y s _ o f f s e t / / x24 =PHYS_OFFSET , x28 =PHYS_OFFSET - P A G E _ O F F S E T
bl s e t _ c p u _ b o o t _ m o d e _ f l a g
arm64: factor out spin-table boot method
The arm64 kernel has an internal holding pen, which is necessary for
some systems where we can't bring CPUs online individually and must hold
multiple CPUs in a safe area until the kernel is able to handle them.
The current SMP infrastructure for arm64 is closely coupled to this
holding pen, and alternative boot methods must launch CPUs into the pen,
where they sit before they are launched into the kernel proper.
With PSCI (and possibly other future boot methods), we can bring CPUs
online individually, and need not perform the secondary_holding_pen
dance. Instead, this patch factors the holding pen management code out
to the spin-table boot method code, as it is the only boot method
requiring the pen.
A new entry point for secondaries, secondary_entry is added for other
boot methods to use, which bypasses the holding pen and its associated
overhead when bringing CPUs online. The smp.pen.text section is also
removed, as the pen can live in head.text without problem.
The cpu_operations structure is extended with two new functions,
cpu_boot and cpu_postboot, for bringing a cpu into the kernel and
performing any post-boot cleanup required by a bootmethod (e.g.
resetting the secondary_holding_pen_release to INVALID_HWID).
Documentation is added for cpu_operations.
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
2013-10-24 20:30:16 +01:00
b s e c o n d a r y _ s t a r t u p
ENDPROC( s e c o n d a r y _ e n t r y )
2012-03-05 11:49:27 +00:00
ENTRY( s e c o n d a r y _ s t a r t u p )
/ *
* Common e n t r y p o i n t f o r s e c o n d a r y C P U s .
* /
mrs x22 , m i d r _ e l 1 / / x22 =cpuid
mov x0 , x22
bl l o o k u p _ p r o c e s s o r _ t y p e
mov x23 , x0 / / x23 =current c p u _ t a b l e
cbz x23 , _ _ e r r o r _ p / / i n v a l i d p r o c e s s o r ( x23 =0 ) ?
pgtbl x25 , x26 , x24 / / x25 =TTBR0 , x26 =TTBR1
ldr x12 , [ x23 , #C P U _ I N F O _ S E T U P ]
add x12 , x12 , x28 / / _ _ v i r t _ t o _ p h y s
blr x12 / / i n i t i a l i s e p r o c e s s o r
ldr x21 , =secondary_data
ldr x27 , =__secondary_switched / / a d d r e s s t o j u m p t o a f t e r e n a b l i n g t h e M M U
b _ _ e n a b l e _ m m u
ENDPROC( s e c o n d a r y _ s t a r t u p )
ENTRY( _ _ s e c o n d a r y _ s w i t c h e d )
ldr x0 , [ x21 ] / / g e t s e c o n d a r y _ d a t a . s t a c k
mov s p , x0
mov x29 , #0
b s e c o n d a r y _ s t a r t _ k e r n e l
ENDPROC( _ _ s e c o n d a r y _ s w i t c h e d )
# endif / * C O N F I G _ S M P * /
/ *
* Setup c o m m o n b i t s b e f o r e f i n a l l y e n a b l i n g t h e M M U . E s s e n t i a l l y t h i s i s j u s t
* loading t h e p a g e t a b l e p o i n t e r a n d v e c t o r b a s e r e g i s t e r s .
*
* On e n t r y t o t h i s c o d e , x0 m u s t c o n t a i n t h e S C T L R _ E L 1 v a l u e f o r t u r n i n g o n
* the M M U .
* /
__enable_mmu :
ldr x5 , =vectors
msr v b a r _ e l 1 , x5
msr t t b r0 _ e l 1 , x25 / / l o a d T T B R 0
msr t t b r1 _ e l 1 , x26 / / l o a d T T B R 1
isb
b _ _ t u r n _ m m u _ o n
ENDPROC( _ _ e n a b l e _ m m u )
/ *
* Enable t h e M M U . T h i s c o m p l e t e l y c h a n g e s t h e s t r u c t u r e o f t h e v i s i b l e m e m o r y
* space. Y o u w i l l n o t b e a b l e t o t r a c e e x e c u t i o n t h r o u g h t h i s .
*
* x0 = s y s t e m c o n t r o l r e g i s t e r
* x2 7 = * v i r t u a l * a d d r e s s t o j u m p t o u p o n c o m p l e t i o n
*
* other r e g i s t e r s d e p e n d o n t h e f u n c t i o n c a l l e d u p o n c o m p l e t i o n
* /
.align 6
__turn_mmu_on :
msr s c t l r _ e l 1 , x0
isb
br x27
ENDPROC( _ _ t u r n _ m m u _ o n )
/ *
* Calculate t h e s t a r t o f p h y s i c a l m e m o r y .
* /
__calc_phys_offset :
adr x0 , 1 f
ldp x1 , x2 , [ x0 ]
sub x28 , x0 , x1 / / x28 = P H Y S _ O F F S E T - P A G E _ O F F S E T
add x24 , x2 , x28 / / x24 = P H Y S _ O F F S E T
ret
ENDPROC( _ _ c a l c _ p h y s _ o f f s e t )
.align 3
1 : .quad .
.quad PAGE_OFFSET
/ *
* Macro t o p o p u l a t e t h e P G D f o r t h e c o r r e s p o n d i n g b l o c k e n t r y i n t h e n e x t
* level ( t b l ) f o r t h e g i v e n v i r t u a l a d d r e s s .
*
* Preserves : pgd, t b l , v i r t
* Corrupts : tmp1 , t m p2
* /
.macro create_ p g d _ e n t r y , p g d , t b l , v i r t , t m p1 , t m p2
lsr \ t m p1 , \ v i r t , #P G D I R _ S H I F T
and \ t m p1 , \ t m p1 , #P T R S _ P E R _ P G D - 1 / / P G D i n d e x
orr \ t m p2 , \ t b l , #3 / / P G D e n t r y t a b l e t y p e
str \ t m p2 , [ \ p g d , \ t m p1 , l s l #3 ]
.endm
/ *
* Macro t o p o p u l a t e b l o c k e n t r i e s i n t h e p a g e t a b l e f o r t h e s t a r t . . e n d
* virtual r a n g e ( i n c l u s i v e ) .
*
* Preserves : tbl, f l a g s
* Corrupts : phys, s t a r t , e n d , p s t a t e
* /
.macro create_ b l o c k _ m a p , t b l , f l a g s , p h y s , s t a r t , e n d , i d m a p =0
lsr \ p h y s , \ p h y s , #B L O C K _ S H I F T
.if \ idmap
and \ s t a r t , \ p h y s , #P T R S _ P E R _ P T E - 1 / / t a b l e i n d e x
.else
lsr \ s t a r t , \ s t a r t , #B L O C K _ S H I F T
and \ s t a r t , \ s t a r t , #P T R S _ P E R _ P T E - 1 / / t a b l e i n d e x
.endif
orr \ p h y s , \ f l a g s , \ p h y s , l s l #B L O C K _ S H I F T / / t a b l e e n t r y
.ifnc \ start,\ e n d
lsr \ e n d , \ e n d , #B L O C K _ S H I F T
and \ e n d , \ e n d , #P T R S _ P E R _ P T E - 1 / / t a b l e e n d i n d e x
.endif
9999 : str \ p h y s , [ \ t b l , \ s t a r t , l s l #3 ] / / s t o r e t h e e n t r y
.ifnc \ start,\ e n d
add \ s t a r t , \ s t a r t , #1 / / n e x t e n t r y
add \ p h y s , \ p h y s , #B L O C K _ S I Z E / / n e x t b l o c k
cmp \ s t a r t , \ e n d
b. l s 9 9 9 9 b
.endif
.endm
/ *
* Setup t h e i n i t i a l p a g e t a b l e s . W e o n l y s e t u p t h e b a r e s t a m o u n t w h i c h i s
* required t o g e t t h e k e r n e l r u n n i n g . T h e f o l l o w i n g s e c t i o n s a r e r e q u i r e d :
* - identity m a p p i n g t o e n a b l e t h e M M U ( l o w a d d r e s s , T T B R 0 )
* - first f e w M B o f t h e k e r n e l l i n e a r m a p p i n g t o j u m p t o o n c e t h e M M U h a s
* been e n a b l e d , i n c l u d i n g t h e F D T b l o b ( T T B R 1 )
2012-10-23 14:55:08 +01:00
* - UART m a p p i n g i f C O N F I G _ E A R L Y _ P R I N T K i s e n a b l e d ( T T B R 1 )
2012-03-05 11:49:27 +00:00
* /
__create_page_tables :
pgtbl x25 , x26 , x24 / / i d m a p _ p g _ d i r a n d s w a p p e r _ p g _ d i r a d d r e s s e s
/ *
* Clear t h e i d m a p a n d s w a p p e r p a g e t a b l e s .
* /
mov x0 , x25
add x6 , x26 , #S W A P P E R _ D I R _ S I Z E
1 : stp x z r , x z r , [ x0 ] , #16
stp x z r , x z r , [ x0 ] , #16
stp x z r , x z r , [ x0 ] , #16
stp x z r , x z r , [ x0 ] , #16
cmp x0 , x6
b. l o 1 b
ldr x7 , =MM_MMUFLAGS
/ *
* Create t h e i d e n t i t y m a p p i n g .
* /
add x0 , x25 , #P A G E _ S I Z E / / s e c t i o n t a b l e a d d r e s s
adr x3 , _ _ t u r n _ m m u _ o n / / v i r t u a l / p h y s i c a l a d d r e s s
create_ p g d _ e n t r y x25 , x0 , x3 , x5 , x6
create_ b l o c k _ m a p x0 , x7 , x3 , x5 , x5 , i d m a p =1
/ *
* Map t h e k e r n e l i m a g e ( s t a r t i n g w i t h P H Y S _ O F F S E T ) .
* /
add x0 , x26 , #P A G E _ S I Z E / / s e c t i o n t a b l e a d d r e s s
mov x5 , #P A G E _ O F F S E T
create_ p g d _ e n t r y x26 , x0 , x5 , x3 , x6
ldr x6 , =KERNEL_END - 1
mov x3 , x24 / / p h y s o f f s e t
create_ b l o c k _ m a p x0 , x7 , x3 , x5 , x6
/ *
* Map t h e F D T b l o b ( m a x i m u m 2 M B ; must be within 512MB of
* PHYS_ O F F S E T ) .
* /
mov x3 , x21 / / F D T p h y s a d d r e s s
and x3 , x3 , #~ ( ( 1 < < 2 1 ) - 1 ) / / 2 M B a l i g n e d
mov x6 , #P A G E _ O F F S E T
sub x5 , x3 , x24 / / s u b t r a c t P H Y S _ O F F S E T
tst x5 , #~ ( ( 1 < < 2 9 ) - 1 ) / / w i t h i n 5 1 2 M B ?
csel x21 , x z r , x21 , n e / / z e r o t h e F D T p o i n t e r
b. n e 1 f
add x5 , x5 , x6 / / _ _ v a ( F D T b l o b )
add x6 , x5 , #1 < < 2 1 / / 2 M B f o r t h e F D T b l o b
sub x6 , x6 , #1 / / i n c l u s i v e r a n g e
create_ b l o c k _ m a p x0 , x7 , x3 , x5 , x6
1 :
2012-10-23 14:55:08 +01:00
# ifdef C O N F I G _ E A R L Y _ P R I N T K
/ *
* Create t h e p g d e n t r y f o r t h e U A R T m a p p i n g . T h e f u l l m a p p i n g i s d o n e
* later b a s e d e a r l y p r i n t k k e r n e l p a r a m e t e r .
* /
ldr x5 , =EARLYCON_IOBASE / / U A R T v i r t u a l a d d r e s s
add x0 , x26 , #2 * P A G E _ S I Z E / / s e c t i o n t a b l e a d d r e s s
create_ p g d _ e n t r y x26 , x0 , x5 , x6 , x7
# endif
2012-03-05 11:49:27 +00:00
ret
ENDPROC( _ _ c r e a t e _ p a g e _ t a b l e s )
.ltorg
.align 3
.type _ _ switch_ d a t a , % o b j e c t
__switch_data :
.quad __mmap_switched
.quad __data_loc / / x4
.quad _data / / x5
.quad __bss_start / / x6
.quad _end / / x7
.quad processor_id / / x4
.quad __fdt_pointer / / x5
.quad memstart_addr / / x6
.quad init_thread_union + THREAD_ S T A R T _ S P / / s p
/ *
* 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 , a n d
* uses a b s o l u t e a d d r e s s e s ; this is not position independent.
* /
__mmap_switched :
adr x3 , _ _ s w i t c h _ d a t a + 8
ldp x4 , x5 , [ x3 ] , #16
ldp x6 , x7 , [ x3 ] , #16
cmp x4 , x5 / / C o p y d a t a s e g m e n t i f n e e d e d
1 : ccmp x5 , x6 , #4 , n e
b. e q 2 f
ldr x16 , [ x4 ] , #8
str x16 , [ x5 ] , #8
b 1 b
2 :
1 : cmp x6 , x7
b. h s 2 f
str x z r , [ x6 ] , #8 / / C l e a r B S S
b 1 b
2 :
ldp x4 , x5 , [ x3 ] , #16
ldr x6 , [ x3 ] , #8
ldr x16 , [ x3 ]
mov s p , x16
str x22 , [ x4 ] / / S a v e p r o c e s s o r I D
str x21 , [ x5 ] / / S a v e F D T p o i n t e r
str x24 , [ x6 ] / / S a v e P H Y S _ O F F S E T
mov x29 , #0
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 )
/ *
* 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 o u g h t t o
* tell 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 w e ' r e e v e n
* running 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 .
* /
__error_p :
ENDPROC( _ _ e r r o r _ p )
__error :
1 : nop
b 1 b
ENDPROC( _ _ e r r o r )
/ *
* This f u n c t i o n g e t s t h e p r o c e s s o r I D i n w0 a n d s e a r c h e s t h e c p u _ t a b l e [ ] f o r
* a m a t c h . I t r e t u r n s a p o i n t e r t o t h e s t r u c t c p u _ i n f o i t f o u n d . T h e
* cpu_ t a b l e [ ] m u s t e n d w i t h a n e m p t y ( a l l z e r o s ) s t r u c t u r e .
*
* This r o u t i n e c a n b e c a l l e d v i a C c o d e a n d i t n e e d s t o w o r k w i t h t h e M M U
* both d i s a b l e d a n d e n a b l e d ( t h e o f f s e t i s c a l c u l a t e d a u t o m a t i c a l l y ) .
* /
ENTRY( l o o k u p _ p r o c e s s o r _ t y p e )
adr x1 , _ _ l o o k u p _ p r o c e s s o r _ t y p e _ d a t a
ldp x2 , x3 , [ x1 ]
sub x1 , x1 , x2 / / g e t o f f s e t b e t w e e n V A a n d P A
add x3 , x3 , x1 / / c o n v e r t V A t o P A
1 :
ldp w5 , w6 , [ x3 ] / / l o a d c p u _ i d _ v a l a n d c p u _ i d _ m a s k
cbz w5 , 2 f / / e n d o f l i s t ?
and w6 , w6 , w0
cmp w5 , w6
b. e q 3 f
add x3 , x3 , #C P U _ I N F O _ S Z
b 1 b
2 :
mov x3 , #0 / / u n k n o w n p r o c e s s o r
3 :
mov x0 , x3
ret
ENDPROC( l o o k u p _ p r o c e s s o r _ t y p e )
.align 3
.type _ _ lookup_ p r o c e s s o r _ t y p e _ d a t a , % o b j e c t
__lookup_processor_type_data :
.quad .
.quad cpu_table
.size _ _ lookup_ p r o c e s s o r _ t y p e _ d a t a , . - _ _ l o o k u p _ p r o c e s s o r _ t y p e _ d a t a
/ *
* Determine v a l i d i t y o f t h e x21 F D T p o i n t e r .
* The d t b m u s t b e 8 - b y t e a l i g n e d a n d l i v e i n t h e f i r s t 5 1 2 M o f m e m o r y .
* /
__vet_fdt :
tst x21 , #0x7
b. n e 1 f
cmp x21 , x24
b. l t 1 f
mov x0 , #( 1 < < 2 9 )
add x0 , x0 , x24
cmp x21 , x0
b. g e 1 f
ret
1 :
mov x21 , #0
ret
ENDPROC( _ _ v e t _ f d t )