aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/kernel/acpi/wakeup_32.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/i386/kernel/acpi/wakeup_32.S')
-rw-r--r--arch/i386/kernel/acpi/wakeup_32.S321
1 files changed, 0 insertions, 321 deletions
diff --git a/arch/i386/kernel/acpi/wakeup_32.S b/arch/i386/kernel/acpi/wakeup_32.S
deleted file mode 100644
index f22ba8534d26..000000000000
--- a/arch/i386/kernel/acpi/wakeup_32.S
+++ /dev/null
@@ -1,321 +0,0 @@
1.text
2#include <linux/linkage.h>
3#include <asm/segment.h>
4#include <asm/page.h>
5
6#
7# wakeup_code runs in real mode, and at unknown address (determined at run-time).
8# Therefore it must only use relative jumps/calls.
9#
10# Do we need to deal with A20? It is okay: ACPI specs says A20 must be enabled
11#
12# If physical address of wakeup_code is 0x12345, BIOS should call us with
13# cs = 0x1234, eip = 0x05
14#
15
16#define BEEP \
17 inb $97, %al; \
18 outb %al, $0x80; \
19 movb $3, %al; \
20 outb %al, $97; \
21 outb %al, $0x80; \
22 movb $-74, %al; \
23 outb %al, $67; \
24 outb %al, $0x80; \
25 movb $-119, %al; \
26 outb %al, $66; \
27 outb %al, $0x80; \
28 movb $15, %al; \
29 outb %al, $66;
30
31ALIGN
32 .align 4096
33ENTRY(wakeup_start)
34wakeup_code:
35 wakeup_code_start = .
36 .code16
37
38 movw $0xb800, %ax
39 movw %ax,%fs
40 movw $0x0e00 + 'L', %fs:(0x10)
41
42 cli
43 cld
44
45 # setup data segment
46 movw %cs, %ax
47 movw %ax, %ds # Make ds:0 point to wakeup_start
48 movw %ax, %ss
49
50 testl $4, realmode_flags - wakeup_code
51 jz 1f
52 BEEP
531:
54 mov $(wakeup_stack - wakeup_code), %sp # Private stack is needed for ASUS board
55 movw $0x0e00 + 'S', %fs:(0x12)
56
57 pushl $0 # Kill any dangerous flags
58 popfl
59
60 movl real_magic - wakeup_code, %eax
61 cmpl $0x12345678, %eax
62 jne bogus_real_magic
63
64 testl $1, realmode_flags - wakeup_code
65 jz 1f
66 lcall $0xc000,$3
67 movw %cs, %ax
68 movw %ax, %ds # Bios might have played with that
69 movw %ax, %ss
701:
71
72 testl $2, realmode_flags - wakeup_code
73 jz 1f
74 mov video_mode - wakeup_code, %ax
75 call mode_set
761:
77
78 # set up page table
79 movl $swsusp_pg_dir-__PAGE_OFFSET, %eax
80 movl %eax, %cr3
81
82 testl $1, real_efer_save_restore - wakeup_code
83 jz 4f
84 # restore efer setting
85 movl real_save_efer_edx - wakeup_code, %edx
86 movl real_save_efer_eax - wakeup_code, %eax
87 mov $0xc0000080, %ecx
88 wrmsr
894:
90 # make sure %cr4 is set correctly (features, etc)
91 movl real_save_cr4 - wakeup_code, %eax
92 movl %eax, %cr4
93 movw $0xb800, %ax
94 movw %ax,%fs
95 movw $0x0e00 + 'i', %fs:(0x12)
96
97 # need a gdt -- use lgdtl to force 32-bit operands, in case
98 # the GDT is located past 16 megabytes.
99 lgdtl real_save_gdt - wakeup_code
100
101 movl real_save_cr0 - wakeup_code, %eax
102 movl %eax, %cr0
103 jmp 1f
1041:
105 movw $0x0e00 + 'n', %fs:(0x14)
106
107 movl real_magic - wakeup_code, %eax
108 cmpl $0x12345678, %eax
109 jne bogus_real_magic
110
111 testl $8, realmode_flags - wakeup_code
112 jz 1f
113 BEEP
1141:
115 ljmpl $__KERNEL_CS, $wakeup_pmode_return
116
117real_save_gdt: .word 0
118 .long 0
119real_save_cr0: .long 0
120real_save_cr3: .long 0
121real_save_cr4: .long 0
122real_magic: .long 0
123video_mode: .long 0
124realmode_flags: .long 0
125beep_flags: .long 0
126real_efer_save_restore: .long 0
127real_save_efer_edx: .long 0
128real_save_efer_eax: .long 0
129
130bogus_real_magic:
131 movw $0x0e00 + 'B', %fs:(0x12)
132 jmp bogus_real_magic
133
134/* This code uses an extended set of video mode numbers. These include:
135 * Aliases for standard modes
136 * NORMAL_VGA (-1)
137 * EXTENDED_VGA (-2)
138 * ASK_VGA (-3)
139 * Video modes numbered by menu position -- NOT RECOMMENDED because of lack
140 * of compatibility when extending the table. These are between 0x00 and 0xff.
141 */
142#define VIDEO_FIRST_MENU 0x0000
143
144/* Standard BIOS video modes (BIOS number + 0x0100) */
145#define VIDEO_FIRST_BIOS 0x0100
146
147/* VESA BIOS video modes (VESA number + 0x0200) */
148#define VIDEO_FIRST_VESA 0x0200
149
150/* Video7 special modes (BIOS number + 0x0900) */
151#define VIDEO_FIRST_V7 0x0900
152
153# Setting of user mode (AX=mode ID) => CF=success
154
155# For now, we only handle VESA modes (0x0200..0x03ff). To handle other
156# modes, we should probably compile in the video code from the boot
157# directory.
158mode_set:
159 movw %ax, %bx
160 subb $VIDEO_FIRST_VESA>>8, %bh
161 cmpb $2, %bh
162 jb check_vesa
163
164setbad:
165 clc
166 ret
167
168check_vesa:
169 orw $0x4000, %bx # Use linear frame buffer
170 movw $0x4f02, %ax # VESA BIOS mode set call
171 int $0x10
172 cmpw $0x004f, %ax # AL=4f if implemented
173 jnz setbad # AH=0 if OK
174
175 stc
176 ret
177
178 .code32
179 ALIGN
180
181.org 0x800
182wakeup_stack_begin: # Stack grows down
183
184.org 0xff0 # Just below end of page
185wakeup_stack:
186ENTRY(wakeup_end)
187
188.org 0x1000
189
190wakeup_pmode_return:
191 movw $__KERNEL_DS, %ax
192 movw %ax, %ss
193 movw %ax, %ds
194 movw %ax, %es
195 movw %ax, %fs
196 movw %ax, %gs
197 movw $0x0e00 + 'u', 0xb8016
198
199 # reload the gdt, as we need the full 32 bit address
200 lgdt saved_gdt
201 lidt saved_idt
202 lldt saved_ldt
203 ljmp $(__KERNEL_CS),$1f
2041:
205 movl %cr3, %eax
206 movl %eax, %cr3
207 wbinvd
208
209 # and restore the stack ... but you need gdt for this to work
210 movl saved_context_esp, %esp
211
212 movl %cs:saved_magic, %eax
213 cmpl $0x12345678, %eax
214 jne bogus_magic
215
216 # jump to place where we left off
217 movl saved_eip,%eax
218 jmp *%eax
219
220bogus_magic:
221 movw $0x0e00 + 'B', 0xb8018
222 jmp bogus_magic
223
224
225##
226# acpi_copy_wakeup_routine
227#
228# Copy the above routine to low memory.
229#
230# Parameters:
231# %eax: place to copy wakeup routine to
232#
233# Returned address is location of code in low memory (past data and stack)
234#
235ENTRY(acpi_copy_wakeup_routine)
236
237 pushl %ebx
238 sgdt saved_gdt
239 sidt saved_idt
240 sldt saved_ldt
241 str saved_tss
242
243 movl nx_enabled, %edx
244 movl %edx, real_efer_save_restore - wakeup_start (%eax)
245 testl $1, real_efer_save_restore - wakeup_start (%eax)
246 jz 2f
247 # save efer setting
248 pushl %eax
249 movl %eax, %ebx
250 mov $0xc0000080, %ecx
251 rdmsr
252 movl %edx, real_save_efer_edx - wakeup_start (%ebx)
253 movl %eax, real_save_efer_eax - wakeup_start (%ebx)
254 popl %eax
2552:
256
257 movl %cr3, %edx
258 movl %edx, real_save_cr3 - wakeup_start (%eax)
259 movl %cr4, %edx
260 movl %edx, real_save_cr4 - wakeup_start (%eax)
261 movl %cr0, %edx
262 movl %edx, real_save_cr0 - wakeup_start (%eax)
263 sgdt real_save_gdt - wakeup_start (%eax)
264
265 movl saved_videomode, %edx
266 movl %edx, video_mode - wakeup_start (%eax)
267 movl acpi_realmode_flags, %edx
268 movl %edx, realmode_flags - wakeup_start (%eax)
269 movl $0x12345678, real_magic - wakeup_start (%eax)
270 movl $0x12345678, saved_magic
271 popl %ebx
272 ret
273
274save_registers:
275 leal 4(%esp), %eax
276 movl %eax, saved_context_esp
277 movl %ebx, saved_context_ebx
278 movl %ebp, saved_context_ebp
279 movl %esi, saved_context_esi
280 movl %edi, saved_context_edi
281 pushfl ; popl saved_context_eflags
282
283 movl $ret_point, saved_eip
284 ret
285
286
287restore_registers:
288 movl saved_context_ebp, %ebp
289 movl saved_context_ebx, %ebx
290 movl saved_context_esi, %esi
291 movl saved_context_edi, %edi
292 pushl saved_context_eflags ; popfl
293 ret
294
295ENTRY(do_suspend_lowlevel)
296 call save_processor_state
297 call save_registers
298 pushl $3
299 call acpi_enter_sleep_state
300 addl $4, %esp
301
302# In case of S3 failure, we'll emerge here. Jump
303# to ret_point to recover
304 jmp ret_point
305 .p2align 4,,7
306ret_point:
307 call restore_registers
308 call restore_processor_state
309 ret
310
311.data
312ALIGN
313ENTRY(saved_magic) .long 0
314ENTRY(saved_eip) .long 0
315
316# saved registers
317saved_gdt: .long 0,0
318saved_idt: .long 0,0
319saved_ldt: .long 0
320saved_tss: .long 0
321