• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6.36/arch/x86/kernel/acpi/realmode/
1/*
2 * ACPI wakeup real mode startup stub
3 */
4#include <asm/segment.h>
5#include <asm/msr-index.h>
6#include <asm/page_types.h>
7#include <asm/pgtable_types.h>
8#include <asm/processor-flags.h>
9
10	.code16
11	.section ".header", "a"
12
13/* This should match the structure in wakeup.h */
14		.globl	wakeup_header
15wakeup_header:
16video_mode:	.short	0	/* Video mode number */
17pmode_return:	.byte	0x66, 0xea	/* ljmpl */
18		.long	0	/* offset goes here */
19		.short	__KERNEL_CS
20pmode_cr0:	.long	0	/* Saved %cr0 */
21pmode_cr3:	.long	0	/* Saved %cr3 */
22pmode_cr4:	.long	0	/* Saved %cr4 */
23pmode_efer:	.quad	0	/* Saved EFER */
24pmode_gdt:	.quad	0
25realmode_flags:	.long	0
26real_magic:	.long	0
27trampoline_segment:	.word 0
28_pad1:		.byte	0
29wakeup_jmp:	.byte	0xea	/* ljmpw */
30wakeup_jmp_off:	.word	3f
31wakeup_jmp_seg:	.word	0
32wakeup_gdt:	.quad	0, 0, 0
33signature:	.long	0x51ee1111
34
35	.text
36	.globl	_start
37	.code16
38wakeup_code:
39_start:
40	cli
41	cld
42
43	/* Apparently some dimwit BIOS programmers don't know how to
44	   program a PM to RM transition, and we might end up here with
45	   junk in the data segment descriptor registers.  The only way
46	   to repair that is to go into PM and fix it ourselves... */
47	movw	$16, %cx
48	lgdtl	%cs:wakeup_gdt
49	movl	%cr0, %eax
50	orb	$X86_CR0_PE, %al
51	movl	%eax, %cr0
52	jmp	1f
531:	ljmpw	$8, $2f
542:
55	movw	%cx, %ds
56	movw	%cx, %es
57	movw	%cx, %ss
58	movw	%cx, %fs
59	movw	%cx, %gs
60
61	andb	$~X86_CR0_PE, %al
62	movl	%eax, %cr0
63	jmp	wakeup_jmp
643:
65	/* Set up segments */
66	movw	%cs, %ax
67	movw	%ax, %ds
68	movw	%ax, %es
69	movw	%ax, %ss
70	lidtl	wakeup_idt
71
72	movl	$wakeup_stack_end, %esp
73
74	/* Clear the EFLAGS */
75	pushl	$0
76	popfl
77
78	/* Check header signature... */
79	movl	signature, %eax
80	cmpl	$0x51ee1111, %eax
81	jne	bogus_real_magic
82
83	/* Check we really have everything... */
84	movl	end_signature, %eax
85	cmpl	$0x65a22c82, %eax
86	jne	bogus_real_magic
87
88	/* Call the C code */
89	calll	main
90
91	/* Do any other stuff... */
92
93#ifndef CONFIG_64BIT
94	/* This could also be done in C code... */
95	movl	pmode_cr3, %eax
96	movl	%eax, %cr3
97
98	movl	pmode_cr4, %ecx
99	jecxz	1f
100	movl	%ecx, %cr4
1011:
102	movl	pmode_efer, %eax
103	movl	pmode_efer + 4, %edx
104	movl	%eax, %ecx
105	orl	%edx, %ecx
106	jz	1f
107	movl	$MSR_EFER, %ecx
108	wrmsr
1091:
110
111	lgdtl	pmode_gdt
112
113	/* This really couldn't... */
114	movl	pmode_cr0, %eax
115	movl	%eax, %cr0
116	jmp	pmode_return
117#else
118	pushw	$0
119	pushw	trampoline_segment
120	pushw	$0
121	lret
122#endif
123
124bogus_real_magic:
1251:
126	hlt
127	jmp	1b
128
129	.data
130	.balign	8
131
132	/* This is the standard real-mode IDT */
133wakeup_idt:
134	.word	0xffff		/* limit */
135	.long	0		/* address */
136	.word	0
137
138	.globl	HEAP, heap_end
139HEAP:
140	.long	wakeup_heap
141heap_end:
142	.long	wakeup_stack
143
144	.bss
145wakeup_heap:
146	.space	2048
147wakeup_stack:
148	.space	2048
149wakeup_stack_end:
150