2005-04-17 02:20:36 +04:00
/ *
* linux/ a r c h / i 3 8 6 / k e r n e l / h e a d . S - - t h e 3 2 - b i t s t a r t u p c o d e .
*
* Copyright ( C ) 1 9 9 1 , 1 9 9 2 L i n u s T o r v a l d s
*
* Enhanced C P U d e t e c t i o n a n d f e a t u r e s e t t i n g c o d e b y M i k e J a g d i s
* and M a r t i n M a r e s , N o v e m b e r 1 9 9 7 .
* /
.text
# include < l i n u x / t h r e a d s . h >
# include < l i n u x / l i n k a g e . h >
# include < a s m / s e g m e n t . h >
# include < a s m / p a g e . h >
# include < a s m / p g t a b l e . h >
# include < a s m / d e s c . h >
# include < a s m / c a c h e . h >
# include < a s m / t h r e a d _ i n f o . h >
2005-09-09 21:28:28 +04:00
# include < a s m / a s m - o f f s e t s . h >
2005-04-17 02:20:36 +04:00
# include < a s m / s e t u p . h >
/ *
* References t o m e m b e r s o f t h e n e w _ c p u _ d a t a s t r u c t u r e .
* /
# define X 8 6 n e w _ c p u _ d a t a + C P U I N F O _ x86
# define X 8 6 _ V E N D O R n e w _ c p u _ d a t a + C P U I N F O _ x86 _ v e n d o r
# define X 8 6 _ M O D E L n e w _ c p u _ d a t a + C P U I N F O _ x86 _ m o d e l
# define X 8 6 _ M A S K n e w _ c p u _ d a t a + C P U I N F O _ x86 _ m a s k
# define X 8 6 _ H A R D _ M A T H n e w _ c p u _ d a t a + C P U I N F O _ h a r d _ m a t h
# define X 8 6 _ C P U I D n e w _ c p u _ d a t a + C P U I N F O _ c p u i d _ l e v e l
# define X 8 6 _ C A P A B I L I T Y n e w _ c p u _ d a t a + C P U I N F O _ x86 _ c a p a b i l i t y
# define X 8 6 _ V E N D O R _ I D n e w _ c p u _ d a t a + C P U I N F O _ x86 _ v e n d o r _ i d
/ *
* This i s h o w m u c h m e m o r y * i n a d d i t i o n t o t h e m e m o r y c o v e r e d u p t o
* and i n c l u d i n g _ e n d * w e n e e d m a p p e d i n i t i a l l y . W e n e e d o n e b i t f o r
* each p o s s i b l e p a g e , b u t o n l y i n l o w m e m o r y , w h i c h m e a n s
* 2 ^ 3 2 / 4 0 9 6 / 8 = 1 2 8 K w o r s t c a s e ( 4 G / 4 G s p l i t . )
*
* Modulo r o u n d i n g , e a c h m e g a b y t e a s s i g n e d h e r e r e q u i r e s a k i l o b y t e o f
* memory, w h i c h i s c u r r e n t l y u n r e c l a i m e d .
*
* This s h o u l d b e a m u l t i p l e o f a p a g e .
* /
# define I N I T _ M A P _ B E Y O N D _ E N D ( 1 2 8 * 1 0 2 4 )
/ *
* 3 2 - bit k e r n e l e n t r y p o i n t ; only used by the boot CPU. On entry,
* % esi p o i n t s t o t h e r e a l - m o d e c o d e a s a 3 2 - b i t p o i n t e r .
* CS a n d D S m u s t b e 4 G B f l a t s e g m e n t s , b u t w e d o n ' t d e p e n d o n
* any p a r t i c u l a r G D T l a y o u t , b e c a u s e w e l o a d o u r o w n a s s o o n a s w e
* can.
* /
2007-02-13 15:26:22 +03:00
.section .text .head , " ax" ,@progbits
2005-04-17 02:20:36 +04:00
ENTRY( s t a r t u p _ 3 2 )
2006-12-07 04:14:08 +03:00
# ifdef C O N F I G _ P A R A V I R T
movl % c s , % e a x
testl $ 0 x3 , % e a x
jnz s t a r t u p _ p a r a v i r t
# endif
2005-04-17 02:20:36 +04:00
/ *
* Set s e g m e n t s t o k n o w n v a l u e s .
* /
cld
lgdt b o o t _ g d t _ d e s c r - _ _ P A G E _ O F F S E T
movl $ ( _ _ B O O T _ D S ) ,% e a x
movl % e a x ,% d s
movl % e a x ,% e s
movl % e a x ,% f s
movl % e a x ,% g s
/ *
* Clear B S S f i r s t s o t h a t t h e r e a r e n o s u r p r i s e s . . .
* No n e e d t o c l d a s D F i s a l r e a d y c l e a r f r o m c l d a b o v e . . .
* /
xorl % e a x ,% e a x
movl $ _ _ b s s _ s t a r t - _ _ P A G E _ O F F S E T ,% e d i
movl $ _ _ b s s _ s t o p - _ _ P A G E _ O F F S E T ,% e c x
subl % e d i ,% e c x
shrl $ 2 ,% e c x
rep ; stosl
2005-09-04 02:56:31 +04:00
/ *
* Copy b o o t u p p a r a m e t e r s o u t o f t h e w a y .
* Note : % esi s t i l l h a s t h e p o i n t e r t o t h e r e a l - m o d e d a t a .
* With t h e k e x e c a s b o o t l o a d e r , p a r a m e t e r s e g m e n t m i g h t b e l o a d e d b e y o n d
* kernel i m a g e a n d m i g h t n o t e v e n b e a d d r e s s a b l e b y e a r l y b o o t p a g e t a b l e s .
* ( kexec o n p a n i c c a s e ) . H e n c e c o p y o u t t h e p a r a m e t e r s b e f o r e i n i t i a l i z i n g
* page t a b l e s .
* /
movl $ ( b o o t _ p a r a m s - _ _ P A G E _ O F F S E T ) ,% e d i
movl $ ( P A R A M _ S I Z E / 4 ) ,% e c x
cld
rep
movsl
movl b o o t _ p a r a m s - _ _ P A G E _ O F F S E T + N E W _ C L _ P O I N T E R ,% e s i
andl % e s i ,% e s i
jnz 2 f # N e w c o m m a n d l i n e p r o t o c o l
cmpw $ ( O L D _ C L _ M A G I C ) ,O L D _ C L _ M A G I C _ A D D R
jne 1 f
movzwl O L D _ C L _ O F F S E T ,% e s i
addl $ ( O L D _ C L _ B A S E _ A D D R ) ,% e s i
2 :
2007-02-12 11:54:11 +03:00
movl $ ( b o o t _ c o m m a n d _ l i n e - _ _ P A G E _ O F F S E T ) ,% e d i
2005-09-04 02:56:31 +04:00
movl $ ( C O M M A N D _ L I N E _ S I Z E / 4 ) ,% e c x
rep
movsl
1 :
2005-04-17 02:20:36 +04:00
/ *
* Initialize p a g e t a b l e s . T h i s c r e a t e s a P D E a n d a s e t o f p a g e
* tables, w h i c h a r e l o c a t e d i m m e d i a t e l y b e y o n d _ e n d . T h e v a r i a b l e
* init_ p g _ t a b l e s _ e n d i s s e t u p t o p o i n t t o t h e f i r s t " s a f e " l o c a t i o n .
* Mappings a r e c r e a t e d b o t h a t v i r t u a l a d d r e s s 0 ( i d e n t i t y m a p p i n g )
* and P A G E _ O F F S E T f o r u p t o _ e n d + s i z e o f ( p a g e t a b l e s ) + I N I T _ M A P _ B E Y O N D _ E N D .
*
* Warning : don' t u s e % e s i o r t h e s t a c k i n t h i s c o d e . H o w e v e r , % e s p
* can b e u s e d a s a G P R i f y o u r e a l l y n e e d i t . . .
* /
page_ p d e _ o f f s e t = ( _ _ P A G E _ O F F S E T > > 2 0 ) ;
movl $ ( p g 0 - _ _ P A G E _ O F F S E T ) , % e d i
movl $ ( s w a p p e r _ p g _ d i r - _ _ P A G E _ O F F S E T ) , % e d x
movl $ 0 x00 7 , % e a x / * 0 x00 7 = P R E S E N T + R W + U S E R * /
10 :
leal 0 x00 7 ( % e d i ) ,% e c x / * C r e a t e P D E e n t r y * /
movl % e c x ,( % e d x ) / * S t o r e i d e n t i t y P D E e n t r y * /
movl % e c x ,p a g e _ p d e _ o f f s e t ( % e d x ) / * S t o r e k e r n e l P D E e n t r y * /
addl $ 4 ,% e d x
movl $ 1 0 2 4 , % e c x
11 :
stosl
addl $ 0 x10 0 0 ,% e a x
loop 1 1 b
/* End condition: we must map up to and including INIT_MAP_BEYOND_END */
/* bytes beyond the end of our own page tables; the +0x007 is the attribute bits */
leal ( I N I T _ M A P _ B E Y O N D _ E N D + 0 x00 7 ) ( % e d i ) ,% e b p
cmpl % e b p ,% e a x
jb 1 0 b
movl % e d i ,( i n i t _ p g _ t a b l e s _ e n d - _ _ P A G E _ O F F S E T )
xorl % e b x ,% e b x / * T h i s i s t h e b o o t C P U ( B S P ) * /
jmp 3 f
/ *
* Non- b o o t C P U e n t r y p o i n t ; entered from trampoline.S
* We c a n ' t l g d t h e r e , b e c a u s e l g d t i t s e l f u s e s a d a t a s e g m e n t , b u t
2007-05-02 21:27:10 +04:00
* we k n o w t h e t r a m p o l i n e h a s a l r e a d y l o a d e d t h e b o o t _ g d t f o r u s .
2007-02-13 15:26:22 +03:00
*
* If c p u h o t p l u g i s n o t s u p p o r t e d t h e n t h i s c o d e c a n g o i n i n i t s e c t i o n
* which w i l l b e f r e e d l a t e r
2005-04-17 02:20:36 +04:00
* /
2007-02-13 15:26:22 +03:00
# ifdef C O N F I G _ H O T P L U G _ C P U
.section .text , " ax" ,@progbits
# else
.section .init .text , " ax" ,@progbits
# endif
# ifdef C O N F I G _ S M P
2005-04-17 02:20:36 +04:00
ENTRY( s t a r t u p _ 3 2 _ s m p )
cld
movl $ ( _ _ B O O T _ D S ) ,% e a x
movl % e a x ,% d s
movl % e a x ,% e s
movl % e a x ,% f s
movl % e a x ,% g s
/ *
* New p a g e t a b l e s m a y b e i n 4 M b y t e p a g e m o d e a n d m a y
* be u s i n g t h e g l o b a l p a g e s .
*
* NOTE! I f w e a r e o n a 4 8 6 w e m a y h a v e n o c r4 a t a l l !
* So w e d o n o t t r y t o t o u c h i t u n l e s s w e r e a l l y h a v e
* some b i t s i n i t t o s e t . T h i s w o n ' t w o r k i f t h e B S P
* implements c r4 b u t t h i s A P d o e s n o t - - v e r y u n l i k e l y
* but b e w a r n e d ! T h e s a m e a p p l i e s t o t h e p s e f e a t u r e
* if n o t e q u a l l y s u p p o r t e d . - - m a c r o
*
* NOTE! W e h a v e t o c o r r e c t f o r t h e f a c t t h a t w e ' r e
* not y e t o f f s e t P A G E _ O F F S E T . .
* /
# define c r4 _ b i t s m m u _ c r4 _ f e a t u r e s - _ _ P A G E _ O F F S E T
movl c r4 _ b i t s ,% e d x
andl % e d x ,% e d x
jz 6 f
movl % c r4 ,% e a x # T u r n o n p a g i n g o p t i o n s ( P S E , P A E , . . )
orl % e d x ,% e a x
movl % e a x ,% c r4
btl $ 5 , % e a x # c h e c k i f P A E i s e n a b l e d
jnc 6 f
/* Check if extended functions are implemented */
movl $ 0 x80 0 0 0 0 0 0 , % e a x
cpuid
cmpl $ 0 x80 0 0 0 0 0 0 , % e a x
jbe 6 f
mov $ 0 x80 0 0 0 0 0 1 , % e a x
cpuid
/* Execute Disable bit supported? */
btl $ 2 0 , % e d x
jnc 6 f
/* Setup EFER (Extended Feature Enable Register) */
movl $ 0 x c00 0 0 0 8 0 , % e c x
rdmsr
btsl $ 1 1 , % e a x
/* Make changes effective */
wrmsr
6 :
/* This is a secondary processor (AP) */
xorl % e b x ,% e b x
incl % e b x
# endif / * C O N F I G _ S M P * /
2007-02-13 15:26:22 +03:00
3 :
2005-04-17 02:20:36 +04:00
/ *
* Enable p a g i n g
* /
movl $ s w a p p e r _ p g _ d i r - _ _ P A G E _ O F F S E T ,% e a x
movl % e a x ,% c r3 / * s e t t h e p a g e t a b l e p o i n t e r . . * /
movl % c r0 ,% e a x
orl $ 0 x80 0 0 0 0 0 0 ,% e a x
movl % e a x ,% c r0 / * . . a n d s e t p a g i n g ( P G ) b i t * /
ljmp $ _ _ B O O T _ C S ,$ 1 f / * C l e a r p r e f e t c h a n d n o r m a l i z e % e i p * /
1 :
/* Set up the stack pointer */
lss s t a c k _ s t a r t ,% e s p
/ *
* Initialize e f l a g s . S o m e B I O S ' s l e a v e b i t s l i k e N T s e t . T h i s w o u l d
* confuse t h e d e b u g g e r i f t h i s c o d e i s t r a c e d .
* XXX - b e s t t o i n i t i a l i z e b e f o r e s w i t c h i n g t o p r o t e c t e d m o d e .
* /
pushl $ 0
popfl
# ifdef C O N F I G _ S M P
andl % e b x ,% e b x
jz 1 f / * I n i t i a l C P U c l e a n s B S S * /
jmp c h e c k C P U t y p e
1 :
# endif / * C O N F I G _ S M P * /
/ *
* start s y s t e m 3 2 - b i t s e t u p . W e n e e d t o r e - d o s o m e o f t h e t h i n g s d o n e
* in 1 6 - b i t m o d e f o r t h e " r e a l " o p e r a t i o n s .
* /
call s e t u p _ i d t
checkCPUtype :
movl $ - 1 ,X 8 6 _ C P U I D # - 1 f o r n o C P U I D i n i t i a l l y
/* check if it is 486 or 386. */
/ *
* XXX - t h i s d o e s a l o t o f u n n e c e s s a r y s e t u p . A l i g n m e n t c h e c k s d o n ' t
* apply a t o u r c p l o f 0 a n d t h e s t a c k o u g h t t o b e a l i g n e d a l r e a d y , a n d
* we d o n ' t n e e d t o p r e s e r v e e f l a g s .
* /
movb $ 3 ,X 8 6 # a t l e a s t 386
pushfl # p u s h E F L A G S
popl % e a x # g e t E F L A G S
movl % e a x ,% e c x # s a v e o r i g i n a l E F L A G S
xorl $ 0 x24 0 0 0 0 ,% e a x # f l i p A C a n d I D b i t s i n E F L A G S
pushl % e a x # c o p y t o E F L A G S
popfl # s e t E F L A G S
pushfl # g e t n e w E F L A G S
popl % e a x # p u t i t i n e a x
xorl % e c x ,% e a x # c h a n g e i n f l a g s
pushl % e c x # r e s t o r e o r i g i n a l E F L A G S
popfl
testl $ 0 x40 0 0 0 ,% e a x # c h e c k i f A C b i t c h a n g e d
je i s38 6
movb $ 4 ,X 8 6 # a t l e a s t 486
testl $ 0 x20 0 0 0 0 ,% e a x # c h e c k i f I D b i t c h a n g e d
je i s48 6
/* get vendor info */
xorl % e a x ,% e a x # c a l l C P U I D w i t h 0 - > r e t u r n v e n d o r I D
cpuid
movl % e a x ,X 8 6 _ C P U I D # s a v e C P U I D l e v e l
movl % e b x ,X 8 6 _ V E N D O R _ I D # l o 4 c h a r s
movl % e d x ,X 8 6 _ V E N D O R _ I D + 4 # n e x t 4 c h a r s
movl % e c x ,X 8 6 _ V E N D O R _ I D + 8 # l a s t 4 c h a r s
orl % e a x ,% e a x # d o w e h a v e p r o c e s s o r i n f o a s w e l l ?
je i s48 6
movl $ 1 ,% e a x # U s e t h e C P U I D i n s t r u c t i o n t o g e t C P U t y p e
cpuid
movb % a l ,% c l # s a v e r e g f o r f u t u r e u s e
andb $ 0 x0 f ,% a h # m a s k p r o c e s s o r f a m i l y
movb % a h ,X 8 6
andb $ 0 x f0 ,% a l # m a s k m o d e l
shrb $ 4 ,% a l
movb % a l ,X 8 6 _ M O D E L
andb $ 0 x0 f ,% c l # m a s k m a s k r e v i s i o n
movb % c l ,X 8 6 _ M A S K
movl % e d x ,X 8 6 _ C A P A B I L I T Y
is486 : movl $ 0 x50 0 2 2 ,% e c x # s e t A M , W P , N E a n d M P
jmp 2 f
is386 : movl $ 2 ,% e c x # s e t M P
2 : movl % c r0 ,% e a x
andl $ 0 x80 0 0 0 0 1 1 ,% e a x # S a v e P G , P E , E T
orl % e c x ,% e a x
movl % e a x ,% c r0
call c h e c k _ x87
2007-02-13 15:26:26 +03:00
lgdt e a r l y _ g d t _ d e s c r
2005-04-17 02:20:36 +04:00
lidt i d t _ d e s c r
ljmp $ ( _ _ K E R N E L _ C S ) ,$ 1 f
1 : movl $ ( _ _ K E R N E L _ D S ) ,% e a x # r e l o a d a l l t h e s e g m e n t r e g i s t e r s
movl % e a x ,% s s # a f t e r c h a n g i n g g d t .
2007-05-02 21:27:16 +04:00
movl % e a x ,% f s # g e t s r e s e t o n c e t h e r e ' s r e a l p e r c p u
2005-04-17 02:20:36 +04:00
movl $ ( _ _ U S E R _ D S ) ,% e a x # D S / E S c o n t a i n s d e f a u l t U S E R s e g m e n t
movl % e a x ,% d s
movl % e a x ,% e s
2007-02-13 15:26:20 +03:00
xorl % e a x ,% e a x # C l e a r G S a n d L D T
movl % e a x ,% g s
2005-04-17 02:20:36 +04:00
lldt % a x
[PATCH] i386: Use %gs as the PDA base-segment in the kernel
This patch is the meat of the PDA change. This patch makes several related
changes:
1: Most significantly, %gs is now used in the kernel. This means that on
entry, the old value of %gs is saved away, and it is reloaded with
__KERNEL_PDA.
2: entry.S constructs the stack in the shape of struct pt_regs, and this
is passed around the kernel so that the process's saved register
state can be accessed.
Unfortunately struct pt_regs doesn't currently have space for %gs
(or %fs). This patch extends pt_regs to add space for gs (no space
is allocated for %fs, since it won't be used, and it would just
complicate the code in entry.S to work around the space).
3: Because %gs is now saved on the stack like %ds, %es and the integer
registers, there are a number of places where it no longer needs to
be handled specially; namely context switch, and saving/restoring the
register state in a signal context.
4: And since kernel threads run in kernel space and call normal kernel
code, they need to be created with their %gs == __KERNEL_PDA.
Signed-off-by: Jeremy Fitzhardinge <jeremy@xensource.com>
Signed-off-by: Andi Kleen <ak@suse.de>
Cc: Chuck Ebbert <76306.1226@compuserve.com>
Cc: Zachary Amsden <zach@vmware.com>
Cc: Jan Beulich <jbeulich@novell.com>
Cc: Andi Kleen <ak@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
2006-12-07 04:14:02 +03:00
2005-04-17 02:20:36 +04:00
cld # g c c 2 w a n t s t h e d i r e c t i o n f l a g c l e a r e d a t a l l t i m e s
2006-10-21 20:37:02 +04:00
pushl $ 0 # f a k e r e t u r n a d d r e s s f o r u n w i n d e r
2005-04-17 02:20:36 +04:00
# ifdef C O N F I G _ S M P
2005-06-26 01:54:49 +04:00
movb r e a d y , % c l
movb $ 1 , r e a d y
2006-08-30 21:37:09 +04:00
cmpb $ 0 ,% c l # t h e f i r s t C P U c a l l s s t a r t _ k e r n e l
2007-05-02 21:27:16 +04:00
je 1 f
movl $ ( _ _ K E R N E L _ P E R C P U ) , % e a x
movl % e a x ,% f s # s e t t h i s c p u ' s p e r c p u
jmp i n i t i a l i z e _ s e c o n d a r y # a l l o t h e r C P U s c a l l i n i t i a l i z e _ s e c o n d a r y
1 :
2005-04-17 02:20:36 +04:00
# endif / * C O N F I G _ S M P * /
2006-08-30 21:37:09 +04:00
jmp s t a r t _ k e r n e l
2005-04-17 02:20:36 +04:00
/ *
* We d e p e n d o n E T t o b e c o r r e c t . T h i s c h e c k s f o r 2 8 7 / 3 8 7 .
* /
check_x87 :
movb $ 0 ,X 8 6 _ H A R D _ M A T H
clts
fninit
fstsw % a x
cmpb $ 0 ,% a l
je 1 f
movl % c r0 ,% e a x / * n o c o p r o c e s s o r : h a v e t o s e t b i t s * /
xorl $ 4 ,% e a x / * s e t E M * /
movl % e a x ,% c r0
ret
ALIGN
1 : movb $ 1 ,X 8 6 _ H A R D _ M A T H
.byte 0 xDB,0 x E 4 / * f s e t p m f o r 2 8 7 , i g n o r e d b y 3 8 7 * /
ret
/ *
* setup_ i d t
*
* sets u p a i d t w i t h 2 5 6 e n t r i e s p o i n t i n g t o
* ignore_ i n t , i n t e r r u p t g a t e s . I t d o e s n ' t a c t u a l l y l o a d
* idt - t h a t c a n b e d o n e o n l y a f t e r p a g i n g h a s b e e n e n a b l e d
* and t h e k e r n e l m o v e d t o P A G E _ O F F S E T . I n t e r r u p t s
* are e n a b l e d e l s e w h e r e , w h e n w e c a n b e r e l a t i v e l y
* sure e v e r y t h i n g i s o k .
*
* Warning : % esi i s l i v e a c r o s s t h i s f u n c t i o n .
* /
setup_idt :
lea i g n o r e _ i n t ,% e d x
movl $ ( _ _ K E R N E L _ C S < < 1 6 ) ,% e a x
movw % d x ,% a x / * s e l e c t o r = 0 x00 1 0 = c s * /
movw $ 0 x8 E 0 0 ,% d x / * i n t e r r u p t g a t e - d p l =0 , p r e s e n t * /
lea i d t _ t a b l e ,% e d i
mov $ 2 5 6 ,% e c x
rp_sidt :
movl % e a x ,( % e d i )
movl % e d x ,4 ( % e d i )
addl $ 8 ,% e d i
dec % e c x
jne r p _ s i d t
2006-09-26 12:52:39 +04:00
.macro set_early_handler handler,t r a p n o
lea \ h a n d l e r ,% e d x
movl $ ( _ _ K E R N E L _ C S < < 1 6 ) ,% e a x
movw % d x ,% a x
movw $ 0 x8 E 0 0 ,% d x / * i n t e r r u p t g a t e - d p l =0 , p r e s e n t * /
lea i d t _ t a b l e ,% e d i
movl % e a x ,8 * \ t r a p n o ( % e d i )
movl % e d x ,8 * \ t r a p n o + 4 ( % e d i )
.endm
set_ e a r l y _ h a n d l e r h a n d l e r =early_divide_err ,t r a p n o =0
set_ e a r l y _ h a n d l e r h a n d l e r =early_illegal_opcode ,t r a p n o =6
set_ e a r l y _ h a n d l e r h a n d l e r =early_protection_fault ,t r a p n o =13
set_ e a r l y _ h a n d l e r h a n d l e r =early_page_fault ,t r a p n o =14
2005-04-17 02:20:36 +04:00
ret
2006-09-26 12:52:39 +04:00
early_divide_err :
xor % e d x ,% e d x
pushl $ 0 / * f a k e e r r c o d e * /
jmp e a r l y _ f a u l t
early_illegal_opcode :
movl $ 6 ,% e d x
pushl $ 0 / * f a k e e r r c o d e * /
jmp e a r l y _ f a u l t
early_protection_fault :
movl $ 1 3 ,% e d x
jmp e a r l y _ f a u l t
early_page_fault :
movl $ 1 4 ,% e d x
jmp e a r l y _ f a u l t
early_fault :
cld
# ifdef C O N F I G _ P R I N T K
movl $ ( _ _ K E R N E L _ D S ) ,% e a x
movl % e a x ,% d s
movl % e a x ,% e s
cmpl $ 2 ,e a r l y _ r e c u r s i o n _ f l a g
je h l t _ l o o p
incl e a r l y _ r e c u r s i o n _ f l a g
movl % c r2 ,% e a x
pushl % e a x
pushl % e d x / * t r a p n o * /
pushl $ f a u l t _ m s g
# ifdef C O N F I G _ E A R L Y _ P R I N T K
call e a r l y _ p r i n t k
# else
call p r i n t k
# endif
# endif
hlt_loop :
hlt
jmp h l t _ l o o p
2005-04-17 02:20:36 +04:00
/* This is the default interrupt "handler" :-) */
ALIGN
ignore_int :
cld
2005-05-01 19:59:02 +04:00
# ifdef C O N F I G _ P R I N T K
2005-04-17 02:20:36 +04:00
pushl % e a x
pushl % e c x
pushl % e d x
pushl % e s
pushl % d s
movl $ ( _ _ K E R N E L _ D S ) ,% e a x
movl % e a x ,% d s
movl % e a x ,% e s
2006-09-26 12:52:39 +04:00
cmpl $ 2 ,e a r l y _ r e c u r s i o n _ f l a g
je h l t _ l o o p
incl e a r l y _ r e c u r s i o n _ f l a g
2005-04-17 02:20:36 +04:00
pushl 1 6 ( % e s p )
pushl 2 4 ( % e s p )
pushl 3 2 ( % e s p )
pushl 4 0 ( % e s p )
pushl $ i n t _ m s g
2006-02-12 04:55:56 +03:00
# ifdef C O N F I G _ E A R L Y _ P R I N T K
call e a r l y _ p r i n t k
# else
2005-04-17 02:20:36 +04:00
call p r i n t k
2006-02-12 04:55:56 +03:00
# endif
2005-04-17 02:20:36 +04:00
addl $ ( 5 * 4 ) ,% e s p
popl % d s
popl % e s
popl % e d x
popl % e c x
popl % e a x
2005-05-01 19:59:02 +04:00
# endif
2005-04-17 02:20:36 +04:00
iret
2007-02-13 15:26:22 +03:00
.section .text
2006-12-07 04:14:08 +03:00
# ifdef C O N F I G _ P A R A V I R T
startup_paravirt :
cld
movl $ ( i n i t _ t h r e a d _ u n i o n + T H R E A D _ S I Z E ) ,% e s p
/* We take pains to preserve all the regs. */
pushl % e d x
pushl % e c x
pushl % e a x
pushl $ _ _ s t a r t _ p a r a v i r t p r o b e
1 :
movl 0 ( % e s p ) , % e a x
2007-02-13 15:26:26 +03:00
cmpl $ _ _ s t o p _ p a r a v i r t p r o b e , % e a x
je u n h a n d l e d _ p a r a v i r t
2006-12-07 04:14:08 +03:00
pushl ( % e a x )
movl 8 ( % e s p ) , % e a x
call * ( % e s p )
popl % e a x
movl 4 ( % e s p ) , % e a x
movl 8 ( % e s p ) , % e c x
movl 1 2 ( % e s p ) , % e d x
addl $ 4 , ( % e s p )
jmp 1 b
2007-02-13 15:26:26 +03:00
unhandled_paravirt :
/* Nothing wanted us: we're screwed. */
ud2
2006-12-07 04:14:08 +03:00
# endif
2005-04-17 02:20:36 +04:00
/ *
* Real b e g i n n i n g o f n o r m a l " t e x t " s e g m e n t
* /
ENTRY( s t e x t )
ENTRY( _ s t e x t )
/ *
* BSS s e c t i o n
* /
.section " .bss .page_aligned " , " w"
ENTRY( s w a p p e r _ p g _ d i r )
.fill 1 0 2 4 , 4 , 0
ENTRY( e m p t y _ z e r o _ p a g e )
.fill 4 0 9 6 , 1 , 0
/ *
* This s t a r t s t h e d a t a s e c t i o n .
* /
.data
ENTRY( s t a c k _ s t a r t )
.long init_ t h r e a d _ u n i o n + T H R E A D _ S I Z E
.long __BOOT_DS
ready : .byte 0
2006-09-26 12:52:39 +04:00
early_recursion_flag :
.long 0
2005-04-17 02:20:36 +04:00
int_msg :
.asciz " Unknown i n t e r r u p t o r f a u l t a t E I P % p % p % p \ n "
2006-09-26 12:52:39 +04:00
fault_msg :
.ascii " Int % d : C R 2 % p e r r % p E I P % p C S % p f l a g s % p \ n "
.asciz " Stack : % p % p % p % p % p % p % p % p \ n "
2005-04-17 02:20:36 +04:00
/ *
* The I D T a n d G D T ' d e s c r i p t o r s ' a r e a s t r a n g e 4 8 - b i t o b j e c t
* only u s e d b y t h e l i d t a n d l g d t i n s t r u c t i o n s . T h e y a r e n o t
* like u s u a l s e g m e n t d e s c r i p t o r s - t h e y c o n s i s t o f a 1 6 - b i t
* segment s i z e , a n d 3 2 - b i t l i n e a r a d d r e s s v a l u e :
* /
.globl boot_gdt_descr
.globl idt_descr
ALIGN
# early b o o t G D T d e s c r i p t o r ( m u s t u s e 1 : 1 a d d r e s s m a p p i n g )
.word 0 # 3 2 bit a l i g n g d t _ d e s c . a d d r e s s
boot_gdt_descr :
.word _ _ BOOT_ D S + 7
2007-05-02 21:27:10 +04:00
.long boot_gdt - _ _ PAGE_ O F F S E T
2005-04-17 02:20:36 +04:00
.word 0 # 3 2 - bit a l i g n i d t _ d e s c . a d d r e s s
idt_descr :
.word IDT_ E N T R I E S * 8 - 1 # i d t c o n t a i n s 256 e n t r i e s
.long idt_table
# boot G D T d e s c r i p t o r ( l a t e r o n u s e d b y C P U #0 ) :
.word 0 # 3 2 bit a l i g n g d t _ d e s c . a d d r e s s
2007-02-13 15:26:26 +03:00
ENTRY( e a r l y _ g d t _ d e s c r )
2005-04-17 02:20:36 +04:00
.word GDT_ E N T R I E S * 8 - 1
2007-05-02 21:27:15 +04:00
.long per_cpu__gdt_page /* Overwritten for secondary CPUs */
2005-04-17 02:20:36 +04:00
/ *
2007-05-02 21:27:10 +04:00
* The b o o t _ g d t m u s t m i r r o r t h e e q u i v a l e n t i n s e t u p . S a n d i s
2005-04-17 02:20:36 +04:00
* used o n l y f o r b o o t i n g .
* /
.align L1_CACHE_BYTES
2007-05-02 21:27:10 +04:00
ENTRY( b o o t _ g d t )
2005-04-17 02:20:36 +04:00
.fill GDT_ E N T R Y _ B O O T _ C S ,8 ,0
.quad 0x00cf9a000000ffff /* kernel 4GB code at 0x00000000 */
.quad 0x00cf92000000ffff /* kernel 4GB data at 0x00000000 */