2014-04-15 22:47:52 -04:00
/ *
* EFI e n t r y p o i n t .
*
* Copyright ( C ) 2 0 1 3 , 2 0 1 4 R e d H a t , I n c .
* Author : Mark S a l t e r < m s a l t e r @redhat.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 .
*
* /
# 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 >
# define E F I _ L O A D _ E R R O R 0 x80 0 0 0 0 0 0 0 0 0 0 0 0 0 1
_ _ INIT
/ *
* We a r r i v e h e r e f r o m t h e E F I b o o t m a n a g e r w i t h :
*
* * CPU i n l i t t l e - e n d i a n m o d e
* * MMU o n w i t h i d e n t i t y - m a p p e d R A M
* * Icache a n d D c a c h e o n
*
* We w i l l m o s t l i k e l y b e r u n n i n g f r o m s o m e p l a c e o t h e r t h a n w h e r e
* we w a n t t o b e . T h e k e r n e l i m a g e w a n t s t o b e p l a c e d a t T E X T _ O F F S E T
* from s t a r t o f R A M .
* /
2015-10-08 20:02:04 +01:00
ENTRY( e n t r y )
2014-04-15 22:47:52 -04:00
/ *
* Create a s t a c k f r a m e t o s a v e F P / L R w i t h e x t r a s p a c e
* for i m a g e _ a d d r v a r i a b l e p a s s e d t o e f i _ e n t r y ( ) .
* /
stp x29 , x30 , [ s p , #- 32 ] !
2016-03-03 17:31:32 +01:00
mov x29 , s p
2014-04-15 22:47:52 -04:00
/ *
* Call e f i _ e n t r y t o d o t h e r e a l w o r k .
* x0 a n d x1 a r e a l r e a d y s e t u p b y f i r m w a r e . C u r r e n t r u n t i m e
* address o f i m a g e i s c a l c u l a t e d a n d p a s s e d v i a * i m a g e _ a d d r .
*
* unsigned l o n g e f i _ e n t r y ( v o i d * h a n d l e ,
* efi_ s y s t e m _ t a b l e _ t * s y s _ t a b l e ,
* unsigned l o n g * i m a g e _ a d d r ) ;
* /
2017-01-17 16:10:57 +00:00
adr_ l x8 , _ t e x t
2014-04-15 22:47:52 -04:00
add x2 , s p , 1 6
str x8 , [ x2 ]
bl e f i _ e n t r y
cmn x0 , #1
b. e q e f i _ l o a d _ f a i l
/ *
2014-11-13 12:22:01 +00:00
* efi_ e n t r y ( ) w i l l h a v e c o p i e d t h e k e r n e l i m a g e i f n e c e s s a r y a n d w e
* return h e r e w i t h d e v i c e t r e e a d d r e s s i n x0 a n d t h e k e r n e l e n t r y
* point s t o r e d a t * i m a g e _ a d d r . S a v e t h o s e v a l u e s i n r e g i s t e r s w h i c h
* are c a l l e e p r e s e r v e d .
2014-04-15 22:47:52 -04:00
* /
mov x20 , x0 / / D T B a d d r e s s
ldr x0 , [ s p , #16 ] / / r e l o c a t e d _ t e x t a d d r e s s
2016-03-30 17:43:07 +02:00
ldr w21 , =stext_offset
arm64/efi: efistub: jump to 'stext' directly, not through the header
After the EFI stub has done its business, it jumps into the kernel by
branching to offset #0 of the loaded Image, which is where it expects
to find the header containing a 'branch to stext' instruction.
However, the UEFI spec 2.1.1 states the following regarding PE/COFF
image loading:
"A UEFI image is loaded into memory through the LoadImage() Boot
Service. This service loads an image with a PE32+ format into memory.
This PE32+ loader is required to load all sections of the PE32+ image
into memory."
In other words, it is /not/ required to load parts of the image that are
not covered by a PE/COFF section, so it may not have loaded the header
at the expected offset, as it is not covered by any PE/COFF section.
So instead, jump to 'stext' directly, which is at the base of the
PE/COFF .text section, by supplying a symbol 'stext_offset' to
efi-entry.o which contains the relative offset of stext into the Image.
Also replace other open coded calculations of the same value with a
reference to 'stext_offset'
Acked-by: Mark Rutland <mark.rutland@arm.com>
Acked-by: Roy Franz <roy.franz@linaro.org>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
2014-10-08 16:11:27 +02:00
add x21 , x0 , x21
2014-04-15 22:47:52 -04:00
/ *
2014-11-13 12:22:01 +00:00
* Calculate s i z e o f t h e k e r n e l I m a g e ( s a m e f o r o r i g i n a l a n d c o p y ) .
2014-04-15 22:47:52 -04:00
* /
2017-01-17 16:10:57 +00:00
adr_ l x1 , _ t e x t
adr_ l x2 , _ e d a t a
2014-04-15 22:47:52 -04:00
sub x1 , x2 , x1
2014-11-13 12:22:01 +00:00
/ *
* Flush t h e c o p i e d I m a g e t o t h e P o C , a n d e n s u r e i t i s n o t s h a d o w e d b y
* stale i c a c h e e n t r i e s f r o m b e f o r e r e l o c a t i o n .
* /
2014-04-15 22:47:52 -04:00
bl _ _ f l u s h _ d c a c h e _ a r e a
ic i a l l u i s
2014-11-13 12:22:01 +00:00
/ *
* Ensure t h a t t h e r e s t o f t h i s f u n c t i o n ( i n t h e o r i g i n a l I m a g e ) i s
* visible w h e n t h e c a c h e s a r e d i s a b l e d . T h e I - c a c h e c a n ' t h a v e s t a l e
* entries f o r t h e V A r a n g e o f t h e c u r r e n t i m a g e , s o n o m a i n t e n a n c e i s
* necessary.
* /
2015-10-08 20:02:04 +01:00
adr x0 , e n t r y
adr x1 , e n t r y _ e n d
2014-11-13 12:22:01 +00:00
sub x1 , x1 , x0
bl _ _ f l u s h _ d c a c h e _ a r e a
2014-04-15 22:47:52 -04:00
/* Turn off Dcache and MMU */
mrs x0 , C u r r e n t E L
2014-06-06 14:16:21 +01:00
cmp x0 , #C u r r e n t E L _ E L 2
2014-04-15 22:47:52 -04:00
b. n e 1 f
mrs x0 , s c t l r _ e l 2
bic x0 , x0 , #1 < < 0 / / c l e a r S C T L R . M
bic x0 , x0 , #1 < < 2 / / c l e a r S C T L R . C
msr s c t l r _ e l 2 , x0
isb
b 2 f
1 :
mrs x0 , s c t l r _ e l 1
bic x0 , x0 , #1 < < 0 / / c l e a r S C T L R . M
bic x0 , x0 , #1 < < 2 / / c l e a r S C T L R . C
msr s c t l r _ e l 1 , x0
isb
2 :
/* Jump to kernel entry point */
mov x0 , x20
mov x1 , x z r
mov x2 , x z r
mov x3 , x z r
br x21
efi_load_fail :
mov x0 , #E F I _ L O A D _ E R R O R
ldp x29 , x30 , [ s p ] , #32
ret
2015-10-08 20:02:04 +01:00
entry_end :
ENDPROC( e n t r y )