x86: make arch/x86/kernel/acpi/wakeup_32.S use a separate
While examining vmlinux namelist on i386 (nm -v vmlinux) I noticed :
c01021d0 t es7000_rename_gsi
c010221a T es7000_start_cpu
<Big Hole>
c0103000 T thread_saved_pc
and
c0113218 T acpi_restore_state_mem
c0113219 T acpi_save_state_mem
<Big Hole>
c0114000 t wakeup_code
This is because arch/x86/kernel/acpi/wakeup_32.S forces a .text alignment
of 4096 bytes. (I have no idea if it is really needed, since
arch/x86/kernel/acpi/wakeup_64.S uses a 16 bytes alignment *only*)
So arch/x86/kernel/built-in.o also has this alignment
arch/x86/kernel/built-in.o: file format elf32-i386
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00018c94 00000000 00000000 00001000 2**12
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
But as arch/x86/kernel/acpi/wakeup_32.o is not the first object linked
into arch/x86/kernel/built-in.o, linker had to build several holes to meet
alignement requirements, because of .o nestings in the kbuild process.
This can be solved by using a special section, .text.page_aligned, so that
no holes are needed.
# size vmlinux.before vmlinux.after
text data bss dec hex filename
4619942 422838 458752 5501532 53f25c vmlinux.before
4610534 422838 458752 5492124 53cd9c vmlinux.after
This saves 9408 bytes
Signed-off-by: Eric Dumazet <dada1@cosmosbay.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
2008-01-30 15:32:50 +03:00
.section .text .page_aligned
2005-04-17 02:20:36 +04:00
# 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 >
#
# wakeup_ c o d e r u n s i n r e a l m o d e , a n d a t u n k n o w n a d d r e s s ( d e t e r m i n e d a t r u n - t i m e ) .
# Therefore i t m u s t o n l y u s e r e l a t i v e j u m p s / c a l l s .
#
# Do w e n e e d t o d e a l w i t h A 2 0 ? I t i s o k a y : A C P I s p e c s s a y s A 2 0 m u s t b e e n a b l e d
#
# If p h y s i c a l a d d r e s s o f w a k e u p _ c o d e i s 0 x12 3 4 5 , B I O S s h o u l d c a l l u s w i t h
# cs = 0 x12 3 4 , e i p = 0 x05
2007-10-18 14:04:51 +04:00
#
2005-04-17 02:20:36 +04:00
2007-07-19 12:47:41 +04:00
# define B E E P \
inb $ 9 7 , % a l ; \
outb % a l , $ 0 x80 ; \
movb $ 3 , % a l ; \
outb % a l , $ 9 7 ; \
outb % a l , $ 0 x80 ; \
movb $ - 7 4 , % a l ; \
outb % a l , $ 6 7 ; \
outb % a l , $ 0 x80 ; \
movb $ - 1 1 9 , % a l ; \
outb % a l , $ 6 6 ; \
outb % a l , $ 0 x80 ; \
movb $ 1 5 , % a l ; \
outb % a l , $ 6 6 ;
2005-04-17 02:20:36 +04:00
ALIGN
.align 4096
ENTRY( w a k e u p _ s t a r t )
wakeup_code :
wakeup_ c o d e _ s t a r t = .
.code16
cli
cld
# setup d a t a s e g m e n t
movw % c s , % a x
movw % a x , % d s # M a k e d s : 0 p o i n t t o w a k e u p _ s t a r t
movw % a x , % s s
2007-07-19 12:47:41 +04:00
2007-07-19 12:47:41 +04:00
testl $ 4 , r e a l m o d e _ f l a g s - w a k e u p _ c o d e
2007-07-19 12:47:41 +04:00
jz 1 f
BEEP
1 :
2005-04-17 02:20:36 +04:00
mov $ ( w a k e u p _ s t a c k - w a k e u p _ c o d e ) , % s p # P r i v a t e s t a c k i s n e e d e d f o r A S U S b o a r d
pushl $ 0 # K i l l a n y d a n g e r o u s f l a g s
popfl
movl r e a l _ m a g i c - w a k e u p _ c o d e , % e a x
cmpl $ 0 x12 3 4 5 6 7 8 , % e a x
jne b o g u s _ r e a l _ m a g i c
2007-07-19 12:47:41 +04:00
testl $ 1 , r e a l m o d e _ f l a g s - w a k e u p _ c o d e
2005-04-17 02:20:36 +04:00
jz 1 f
lcall $ 0 x c00 0 ,$ 3
movw % c s , % a x
movw % a x , % d s # B i o s m i g h t h a v e p l a y e d w i t h t h a t
movw % a x , % s s
1 :
2007-07-19 12:47:41 +04:00
testl $ 2 , r e a l m o d e _ f l a g s - w a k e u p _ c o d e
2005-04-17 02:20:36 +04:00
jz 1 f
mov v i d e o _ m o d e - w a k e u p _ c o d e , % a x
call m o d e _ s e t
1 :
# set u p p a g e t a b l e
2006-06-23 13:04:49 +04:00
movl $ s w s u s p _ p g _ d i r - _ _ P A G E _ O F F S E T , % e a x
2005-04-17 02:20:36 +04:00
movl % e a x , % c r3
testl $ 1 , r e a l _ e f e r _ s a v e _ r e s t o r e - w a k e u p _ c o d e
jz 4 f
# restore e f e r s e t t i n g
movl r e a l _ s a v e _ e f e r _ e d x - w a k e u p _ c o d e , % e d x
movl r e a l _ s a v e _ e f e r _ e a x - w a k e u p _ c o d e , % e a x
mov $ 0 x c00 0 0 0 8 0 , % e c x
wrmsr
4 :
# make s u r e % c r4 i s s e t c o r r e c t l y ( f e a t u r e s , e t c )
movl r e a l _ s a v e _ c r4 - w a k e u p _ c o d e , % e a x
movl % e a x , % c r4
2005-04-09 07:37:34 +04:00
# need a g d t - - u s e l g d t l t o f o r c e 3 2 - b i t o p e r a n d s , i n c a s e
# the G D T i s l o c a t e d p a s t 1 6 m e g a b y t e s .
lgdtl r e a l _ s a v e _ g d t - w a k e u p _ c o d e
2005-04-17 02:20:36 +04:00
movl r e a l _ s a v e _ c r0 - w a k e u p _ c o d e , % e a x
movl % e a x , % c r0
jmp 1 f
1 :
movl r e a l _ m a g i c - w a k e u p _ c o d e , % e a x
cmpl $ 0 x12 3 4 5 6 7 8 , % e a x
jne b o g u s _ r e a l _ m a g i c
2007-07-19 12:47:41 +04:00
testl $ 8 , r e a l m o d e _ f l a g s - w a k e u p _ c o d e
2007-07-19 12:47:41 +04:00
jz 1 f
BEEP
1 :
2007-07-19 12:47:41 +04:00
ljmpl $ _ _ K E R N E L _ C S , $ w a k e u p _ p m o d e _ r e t u r n
2005-04-17 02:20:36 +04:00
real_save_gdt : .word 0
.long 0
real_save_cr0 : .long 0
real_save_cr3 : .long 0
real_save_cr4 : .long 0
real_magic : .long 0
video_mode : .long 0
2007-07-19 12:47:41 +04:00
realmode_flags : .long 0
2005-04-17 02:20:36 +04:00
real_efer_save_restore : .long 0
real_save_efer_edx : .long 0
real_save_efer_eax : .long 0
bogus_real_magic :
jmp b o g u s _ r e a l _ m a g i c
/ * This c o d e u s e s a n e x t e n d e d s e t o f v i d e o m o d e n u m b e r s . T h e s e i n c l u d e :
* Aliases f o r s t a n d a r d m o d e s
* NORMAL_ V G A ( - 1 )
* EXTENDED_ V G A ( - 2 )
* ASK_ V G A ( - 3 )
* Video m o d e s n u m b e r e d b y m e n u p o s i t i o n - - N O T R E C O M M E N D E D b e c a u s e o f l a c k
* of c o m p a t i b i l i t y w h e n e x t e n d i n g t h e t a b l e . T h e s e a r e b e t w e e n 0 x00 a n d 0 x f f .
* /
# define V I D E O _ F I R S T _ M E N U 0 x00 0 0
/* Standard BIOS video modes (BIOS number + 0x0100) */
# define V I D E O _ F I R S T _ B I O S 0 x01 0 0
/* VESA BIOS video modes (VESA number + 0x0200) */
# define V I D E O _ F I R S T _ V E S A 0 x02 0 0
/* Video7 special modes (BIOS number + 0x0900) */
# define V I D E O _ F I R S T _ V 7 0 x09 0 0
# Setting o f u s e r m o d e ( A X =mode I D ) = > C F =success
2007-09-14 01:16:37 +04:00
# For n o w , w e o n l y h a n d l e V E S A m o d e s ( 0 x02 0 0 . . 0 x03 f f ) . T o h a n d l e o t h e r
# modes, w e s h o u l d p r o b a b l y c o m p i l e i n t h e v i d e o c o d e f r o m t h e b o o t
# directory.
2005-04-17 02:20:36 +04:00
mode_set :
movw % a x , % b x
2007-09-14 01:16:37 +04:00
subb $ V I D E O _ F I R S T _ V E S A > > 8 , % b h
cmpb $ 2 , % b h
jb c h e c k _ v e s a
2005-04-17 02:20:36 +04:00
2007-09-14 01:16:37 +04:00
setbad :
clc
2005-04-17 02:20:36 +04:00
ret
check_vesa :
orw $ 0 x40 0 0 , % b x # U s e l i n e a r f r a m e b u f f e r
movw $ 0 x4 f02 , % a x # V E S A B I O S m o d e s e t c a l l
int $ 0 x10
cmpw $ 0 x00 4 f , % a x # A L = 4 f i f i m p l e m e n t e d
2007-09-14 01:16:37 +04:00
jnz s e t b a d # A H = 0 i f O K
2005-04-17 02:20:36 +04:00
stc
ret
.code32
ALIGN
.org 0x800
wakeup_stack_begin : # Stack g r o w s d o w n
.org 0xff0 # Just b e l o w e n d o f p a g e
wakeup_stack :
ENTRY( w a k e u p _ e n d )
.org 0x1000
wakeup_pmode_return :
movw $ _ _ K E R N E L _ D S , % a x
movw % a x , % s s
movw % a x , % d s
movw % a x , % e s
movw % a x , % f s
movw % a x , % g s
# reload t h e g d t , a s w e n e e d t h e f u l l 3 2 b i t a d d r e s s
lgdt s a v e d _ g d t
lidt s a v e d _ i d t
lldt s a v e d _ l d t
ljmp $ ( _ _ K E R N E L _ C S ) ,$ 1 f
1 :
movl % c r3 , % e a x
movl % e a x , % c r3
wbinvd
# and r e s t o r e t h e s t a c k . . . b u t y o u n e e d g d t f o r t h i s t o w o r k
movl s a v e d _ c o n t e x t _ e s p , % e s p
movl % c s : s a v e d _ m a g i c , % e a x
cmpl $ 0 x12 3 4 5 6 7 8 , % e a x
jne b o g u s _ m a g i c
# jump t o p l a c e w h e r e w e l e f t o f f
movl s a v e d _ e i p ,% e a x
jmp * % e a x
bogus_magic :
jmp b o g u s _ m a g i c
# #
# acpi_ c o p y _ w a k e u p _ r o u t i n e
#
# Copy t h e a b o v e r o u t i n e t o l o w m e m o r y .
#
# Parameters :
# % eax : place t o c o p y w a k e u p r o u t i n e t o
#
# Returned a d d r e s s i s l o c a t i o n o f c o d e i n l o w m e m o r y ( p a s t d a t a a n d s t a c k )
#
ENTRY( a c p i _ c o p y _ w a k e u p _ r o u t i n e )
2007-06-24 04:16:52 +04:00
pushl % e b x
2005-04-17 02:20:36 +04:00
sgdt s a v e d _ g d t
sidt s a v e d _ i d t
sldt s a v e d _ l d t
str s a v e d _ t s s
movl n x _ e n a b l e d , % e d x
movl % e d x , r e a l _ e f e r _ s a v e _ r e s t o r e - w a k e u p _ s t a r t ( % e a x )
testl $ 1 , r e a l _ e f e r _ s a v e _ r e s t o r e - w a k e u p _ s t a r t ( % e a x )
jz 2 f
# save e f e r s e t t i n g
pushl % e a x
movl % e a x , % e b x
mov $ 0 x c00 0 0 0 8 0 , % e c x
rdmsr
movl % e d x , r e a l _ s a v e _ e f e r _ e d x - w a k e u p _ s t a r t ( % e b x )
movl % e a x , r e a l _ s a v e _ e f e r _ e a x - w a k e u p _ s t a r t ( % e b x )
popl % e a x
2 :
movl % c r3 , % e d x
movl % e d x , r e a l _ s a v e _ c r3 - w a k e u p _ s t a r t ( % e a x )
movl % c r4 , % e d x
movl % e d x , r e a l _ s a v e _ c r4 - w a k e u p _ s t a r t ( % e a x )
movl % c r0 , % e d x
movl % e d x , r e a l _ s a v e _ c r0 - w a k e u p _ s t a r t ( % e a x )
sgdt r e a l _ s a v e _ g d t - w a k e u p _ s t a r t ( % e a x )
movl s a v e d _ v i d e o m o d e , % e d x
movl % e d x , v i d e o _ m o d e - w a k e u p _ s t a r t ( % e a x )
2007-07-19 12:47:41 +04:00
movl a c p i _ r e a l m o d e _ f l a g s , % e d x
movl % e d x , r e a l m o d e _ f l a g s - w a k e u p _ s t a r t ( % e a x )
2005-04-17 02:20:36 +04:00
movl $ 0 x12 3 4 5 6 7 8 , r e a l _ m a g i c - w a k e u p _ s t a r t ( % e a x )
movl $ 0 x12 3 4 5 6 7 8 , s a v e d _ m a g i c
2007-06-24 04:16:52 +04:00
popl % e b x
2005-04-17 02:20:36 +04:00
ret
save_registers :
leal 4 ( % e s p ) , % e a x
movl % e a x , s a v e d _ c o n t e x t _ e s p
movl % e b x , s a v e d _ c o n t e x t _ e b x
movl % e b p , s a v e d _ c o n t e x t _ e b p
movl % e s i , s a v e d _ c o n t e x t _ e s i
movl % e d i , s a v e d _ c o n t e x t _ e d i
pushfl ; popl saved_context_eflags
movl $ r e t _ p o i n t , s a v e d _ e i p
ret
restore_registers :
movl s a v e d _ c o n t e x t _ e b p , % e b p
movl s a v e d _ c o n t e x t _ e b x , % e b x
movl s a v e d _ c o n t e x t _ e s i , % e s i
movl s a v e d _ c o n t e x t _ e d i , % e d i
pushl s a v e d _ c o n t e x t _ e f l a g s ; popfl
ret
ENTRY( d o _ s u s p e n d _ l o w l e v e l )
call s a v e _ p r o c e s s o r _ s t a t e
call s a v e _ r e g i s t e r s
pushl $ 3
call a c p i _ e n t e r _ s l e e p _ s t a t e
addl $ 4 , % e s p
2006-08-15 09:37:31 +04:00
# In c a s e o f S 3 f a i l u r e , w e ' l l e m e r g e h e r e . J u m p
# to r e t _ p o i n t t o r e c o v e r
jmp r e t _ p o i n t
2005-04-17 02:20:36 +04:00
.p2align 4 , , 7
ret_point :
call r e s t o r e _ r e g i s t e r s
call r e s t o r e _ p r o c e s s o r _ s t a t e
ret
2006-06-23 13:04:50 +04:00
.data
2005-04-17 02:20:36 +04:00
ALIGN
2006-06-23 13:04:50 +04:00
ENTRY( s a v e d _ m a g i c ) . l o n g 0
ENTRY( s a v e d _ e i p ) . l o n g 0
2005-04-17 02:20:36 +04:00
# saved r e g i s t e r s
saved_gdt : .long 0 , 0
saved_idt : .long 0 , 0
saved_ldt : .long 0
saved_tss : .long 0