2005-04-17 02:20:36 +04:00
/ *
*
* Trampoline. S D e r i v e d f r o m S e t u p . S b y L i n u s T o r v a l d s
*
* 4 Jan 1 9 9 7 M i c h a e l C h a s t a i n : c h a n g e d t o g n u a s .
2007-05-02 21:27:07 +04:00
* 1 5 Sept 2 0 0 5 E r i c B i e d e r m a n : 6 4 b i t P I C s u p p o r t
2005-04-17 02:20:36 +04:00
*
* Entry : CS : IP p o i n t t o t h e s t a r t o f o u r c o d e , w e a r e
* in r e a l m o d e w i t h n o s t a c k , b u t t h e r e s t o f t h e
* trampoline p a g e t o m a k e o u r s t a c k a n d e v e r y t h i n g e l s e
* is a m y s t e r y .
*
* On e n t r y t o t r a m p o l i n e _ d a t a , t h e p r o c e s s o r i s i n r e a l m o d e
* with 1 6 - b i t a d d r e s s i n g a n d 1 6 - b i t d a t a . C S h a s s o m e v a l u e
* and I P i s z e r o . T h u s , d a t a a d d r e s s e s n e e d t o b e a b s o l u t e
* ( no r e l o c a t i o n ) a n d a r e t a k e n w i t h r e g a r d t o r _ b a s e .
*
2007-05-02 21:27:07 +04:00
* With t h e a d d i t i o n o f t r a m p o l i n e _ l e v e l 4 _ p g t t h i s c o d e c a n
* now e n t e r a 6 4 b i t k e r n e l t h a t l i v e s a t a r b i t r a r y 6 4 b i t
* physical a d d r e s s e s .
*
2005-04-17 02:20:36 +04:00
* If y o u w o r k o n t h i s f i l e , c h e c k t h e o b j e c t m o d u l e w i t h o b j d u m p
* - - full- c o n t e n t s - - r e l o c t o m a k e s u r e t h e r e a r e n o r e l o c a t i o n
2007-05-02 21:27:07 +04:00
* entries.
2005-04-17 02:20:36 +04:00
* /
# include < l i n u x / l i n k a g e . h >
2007-05-02 21:27:07 +04:00
# include < a s m / p g t a b l e . h >
2005-04-17 02:20:36 +04:00
# include < a s m / p a g e . h >
2007-05-02 21:27:07 +04:00
# include < a s m / m s r . h >
# include < a s m / s e g m e n t . h >
2005-04-17 02:20:36 +04:00
2007-10-17 20:04:37 +04:00
/* We can free up trampoline after bootup if cpu hotplug is not supported. */
# ifndef C O N F I G _ H O T P L U G _ C P U
.section .init .data , " aw" , @progbits
# else
.section .rodata , " a" , @progbits
# endif
2005-04-17 02:20:36 +04:00
.code16
ENTRY( t r a m p o l i n e _ d a t a )
r_ b a s e = .
2007-05-02 21:27:07 +04:00
cli # W e s h o u l d b e s a f e a n y w a y
2005-04-17 02:20:36 +04:00
wbinvd
mov % c s , % a x # C o d e a n d d a t a i n t h e s a m e p l a c e
mov % a x , % d s
2007-05-02 21:27:07 +04:00
mov % a x , % e s
mov % a x , % s s
2005-04-17 02:20:36 +04:00
movl $ 0 x A 5 A 5 A 5 A 5 , t r a m p o l i n e _ d a t a - r _ b a s e
# write m a r k e r f o r m a s t e r k n o w s w e ' r e r u n n i n g
2007-05-02 21:27:07 +04:00
# Setup s t a c k
movw $ ( t r a m p o l i n e _ s t a c k _ e n d - r _ b a s e ) , % s p
call v e r i f y _ c p u # V e r i f y t h e c p u s u p p o r t s l o n g m o d e
2007-05-02 21:27:08 +04:00
testl % e a x , % e a x # C h e c k f o r r e t u r n c o d e
jnz n o _ l o n g m o d e
2007-05-02 21:27:07 +04:00
mov % c s , % a x
movzx % a x , % e s i # F i n d t h e 32 b i t t r a m p o l i n e l o c a t i o n
shll $ 4 , % e s i
# Fixup t h e v e c t o r s
addl % e s i , s t a r t u p _ 3 2 _ v e c t o r - r _ b a s e
addl % e s i , s t a r t u p _ 6 4 _ v e c t o r - r _ b a s e
addl % e s i , t g d t + 2 - r _ b a s e # F i x u p t h e g d t p o i n t e r
2006-01-12 05:35:20 +03:00
/ *
* GDT t a b l e s i n n o n d e f a u l t l o c a t i o n k e r n e l c a n b e b e y o n d 1 6 M B a n d
* lgdt w i l l n o t b e a b l e t o l o a d t h e a d d r e s s a s i n r e a l m o d e d e f a u l t
* operand s i z e i s 1 6 b i t . U s e l g d t l i n s t e a d t o f o r c e o p e r a n d s i z e
* to 3 2 b i t .
* /
2007-05-02 21:27:07 +04:00
lidtl t i d t - r _ b a s e # l o a d i d t w i t h 0 , 0
lgdtl t g d t - r _ b a s e # l o a d g d t w i t h w h a t e v e r i s a p p r o p r i a t e
2005-04-17 02:20:36 +04:00
xor % a x , % a x
inc % a x # p r o t e c t e d m o d e ( P E ) b i t
lmsw % a x # i n t o p r o t e c t e d m o d e
2007-05-02 21:27:07 +04:00
# flush p r e f e t c h a n d j u m p t o s t a r t u p _ 3 2
ljmpl * ( s t a r t u p _ 3 2 _ v e c t o r - r _ b a s e )
.code32
.balign 4
startup_32 :
movl $ _ _ K E R N E L _ D S , % e a x # I n i t i a l i z e t h e % d s s e g m e n t r e g i s t e r
movl % e a x , % d s
xorl % e a x , % e a x
btsl $ 5 , % e a x # E n a b l e P A E m o d e
movl % e a x , % c r4
# Setup t r a m p o l i n e 4 l e v e l p a g e t a b l e s
leal ( t r a m p o l i n e _ l e v e l 4 _ p g t - r _ b a s e ) ( % e s i ) , % e a x
movl % e a x , % c r3
movl $ M S R _ E F E R , % e c x
movl $ ( 1 < < _ E F E R _ L M E ) , % e a x # E n a b l e L o n g M o d e
xorl % e d x , % e d x
wrmsr
xorl % e a x , % e a x
btsl $ 3 1 , % e a x # E n a b l e p a g i n g a n d i n t u r n a c t i v a t e L o n g M o d e
btsl $ 0 , % e a x # E n a b l e p r o t e c t e d m o d e
movl % e a x , % c r0
/ *
* At t h i s p o i n t w e ' r e i n l o n g m o d e b u t i n 3 2 b i t c o m p a t i b i l i t y m o d e
* with E F E R . L M E = 1 , C S . L = 0 , C S . D = 1 ( a n d i n t u r n
* EFER. L M A = 1 ) . N o w w e w a n t t o j u m p i n 6 4 b i t m o d e , t o d o t h a t w e u s e
* the n e w g d t / i d t t h a t h a s _ _ K E R N E L _ C S w i t h C S . L = 1 .
* /
ljmp * ( s t a r t u p _ 6 4 _ v e c t o r - r _ b a s e ) ( % e s i )
.code64
.balign 4
startup_64 :
# Now j u m p i n t o t h e k e r n e l u s i n g v i r t u a l a d d r e s s e s
movq $ s e c o n d a r y _ s t a r t u p _ 6 4 , % r a x
jmp * % r a x
.code16
no_longmode :
hlt
jmp n o _ l o n g m o d e
2007-10-11 13:15:19 +04:00
# include " v e r i f y _ c p u _ 6 4 . S "
2005-04-17 02:20:36 +04:00
# Careful t h e s e n e e d t o b e i n t h e s a m e 6 4 K s e g m e n t a s t h e a b o v e ;
2007-05-02 21:27:07 +04:00
tidt :
2005-04-17 02:20:36 +04:00
.word 0 # idt l i m i t = 0
.word 0 , 0 # idt b a s e = 0 L
2007-05-02 21:27:07 +04:00
# Duplicate t h e g l o b a l d e s c r i p t o r t a b l e
# so t h e k e r n e l c a n l i v e a n y w h e r e
.balign 4
tgdt :
.short tgdt_end - tgdt # g d t l i m i t
.long tgdt - r_ b a s e
.short 0
.quad 0x00cf9b000000ffff # _ _ KERNEL3 2 _ C S
.quad 0x00af9b000000ffff # _ _ KERNEL_ C S
.quad 0x00cf93000000ffff # _ _ KERNEL_ D S
tgdt_end :
.balign 4
startup_32_vector :
.long startup_32 - r_ b a s e
.word _ _ KERNEL3 2 _ C S , 0
.balign 4
startup_64_vector :
.long startup_64 - r_ b a s e
.word _ _ KERNEL_ C S , 0
trampoline_stack :
.org 0x1000
trampoline_stack_end :
ENTRY( t r a m p o l i n e _ l e v e l 4 _ p g t )
.quad level3_ident_pgt - _ _ START_ K E R N E L _ m a p + _ K E R N P G _ T A B L E
.fill 5 1 0 , 8 , 0
.quad level3_kernel_pgt - _ _ START_ K E R N E L _ m a p + _ K E R N P G _ T A B L E
2005-04-17 02:20:36 +04:00
2007-05-02 21:27:07 +04:00
ENTRY( t r a m p o l i n e _ e n d )