2 #include <linux/linkage.h>
3 #include <asm/segment.h>
7 # wakeup_code runs in real mode, and at unknown address (determined at run-time).
8 # Therefore it must only use relative jumps/calls.
10 # Do we need to deal with A20? It is okay: ACPI specs says A20 must be enabled
12 # If physical address of wakeup_code is 0x12345, BIOS should call us with
13 # cs = 0x1234, eip = 0x05
25 movw $0x0e00 + 'L', %fs:(0x10)
32 movw %ax, %ds # Make ds:0 point to wakeup_start
34 mov $(wakeup_stack - wakeup_code), %sp # Private stack is needed for ASUS board
35 movw $0x0e00 + 'S', %fs:(0x12)
37 pushl $0 # Kill any dangerous flags
40 movl real_magic - wakeup_code, %eax
41 cmpl $0x12345678, %eax
44 testl $1, video_flags - wakeup_code
48 movw %ax, %ds # Bios might have played with that
52 testl $2, video_flags - wakeup_code
54 mov video_mode - wakeup_code, %ax
59 movl $swapper_pg_dir-__PAGE_OFFSET, %eax
62 # make sure %cr4 is set correctly (features, etc)
63 movl real_save_cr4 - wakeup_code, %eax
67 movw $0x0e00 + 'i', %fs:(0x12)
70 #use the gdt copied in this low mem
71 lea temp_gdt_table - wakeup_code, %eax
76 movl %eax, real_save_gdt + 2 - wakeup_code
77 lgdt real_save_gdt - wakeup_code
79 movl real_save_cr0 - wakeup_code, %eax
83 movw $0x0e00 + 'n', %fs:(0x14)
85 movl real_magic - wakeup_code, %eax
86 cmpl $0x12345678, %eax
89 ljmpl $__KERNEL_CS,$wakeup_pmode_return
91 real_save_gdt: .word 0
93 real_save_cr0: .long 0
94 real_save_cr3: .long 0
95 real_save_cr4: .long 0
99 temp_gdt_table: .fill GDT_ENTRIES, 8, 0
102 movw $0x0e00 + 'B', %fs:(0x12)
105 /* This code uses an extended set of video mode numbers. These include:
106 * Aliases for standard modes
110 * Video modes numbered by menu position -- NOT RECOMMENDED because of lack
111 * of compatibility when extending the table. These are between 0x00 and 0xff.
113 #define VIDEO_FIRST_MENU 0x0000
115 /* Standard BIOS video modes (BIOS number + 0x0100) */
116 #define VIDEO_FIRST_BIOS 0x0100
118 /* VESA BIOS video modes (VESA number + 0x0200) */
119 #define VIDEO_FIRST_VESA 0x0200
121 /* Video7 special modes (BIOS number + 0x0900) */
122 #define VIDEO_FIRST_V7 0x0900
124 # Setting of user mode (AX=mode ID) => CF=success
131 testb $VIDEO_RECALC>>8, %ah
134 cmpb $VIDEO_FIRST_RESOLUTION>>8, %ah
137 cmpb $VIDEO_FIRST_SPECIAL>>8, %ah
140 cmpb $VIDEO_FIRST_V7>>8, %ah
144 cmpb $VIDEO_FIRST_VESA>>8, %ah
152 # jz setbios Add bios modes later
158 subb $VIDEO_FIRST_VESA>>8, %bh
159 orw $0x4000, %bx # Use linear frame buffer
160 movw $0x4f02, %ax # VESA BIOS mode set call
162 cmpw $0x004f, %ax # AL=4f if implemented
163 jnz _setbad # AH=0 if OK
174 wakeup_stack_begin: # Stack grows down
176 .org 0xff0 # Just below end of page
183 movw $__KERNEL_DS, %ax
189 movw $0x0e00 + 'u', 0xb8016
191 # reload the gdt, as we need the full 32 bit address
195 ljmp $(__KERNEL_CS),$1f
201 # and restore the stack ... but you need gdt for this to work
202 movl saved_context_esp, %esp
204 movl %cs:saved_magic, %eax
205 cmpl $0x12345678, %eax
208 # jump to place where we left off
213 movw $0x0e00 + 'B', 0xb8018
218 # acpi_copy_wakeup_routine
220 # Copy the above routine to low memory.
223 # %eax: place to copy wakeup routine to
225 # Returned address is location of code in low memory (past data and stack)
227 ENTRY(acpi_copy_wakeup_routine)
235 movl %edx, real_save_cr3 - wakeup_start (%eax)
237 movl %edx, real_save_cr4 - wakeup_start (%eax)
239 movl %edx, real_save_cr0 - wakeup_start (%eax)
240 sgdt real_save_gdt - wakeup_start (%eax)
242 # gdt wont be addressable from real mode in 4g4g split
243 # copying it to the lower mem
246 movl saved_gdt + 2, %esi
247 lea temp_gdt_table - wakeup_start (%eax), %edi
249 movl saved_videomode, %edx
250 movl %edx, video_mode - wakeup_start (%eax)
251 movl acpi_video_flags, %edx
252 movl %edx, video_flags - wakeup_start (%eax)
253 movl $0x12345678, real_magic - wakeup_start (%eax)
254 movl $0x12345678, saved_magic
259 ENTRY(saved_magic) .long 0
260 ENTRY(saved_eip) .long 0
264 movl %eax, saved_context_esp
265 movl %ebx, saved_context_ebx
266 movl %ebp, saved_context_ebp
267 movl %esi, saved_context_esi
268 movl %edi, saved_context_edi
269 pushfl ; popl saved_context_eflags
271 movl $ret_point,saved_eip
276 movl saved_context_ebp, %ebp
277 movl saved_context_ebx, %ebx
278 movl saved_context_esi, %esi
279 movl saved_context_edi, %edi
280 pushl saved_context_eflags ; popfl
283 ENTRY(do_suspend_lowlevel)
284 call save_processor_state
287 call acpi_enter_sleep_state
292 call restore_registers
293 call restore_processor_state
296 ENTRY(do_suspend_lowlevel_s4bios)
297 call save_processor_state
299 call acpi_enter_sleep_state_s4bios