Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/i386/acpica/acpi_wakecode.S
39478 views
1
/*-
2
* Copyright (c) 2001 Takanori Watanabe <[email protected]>
3
* Copyright (c) 2001-2012 Mitsuru IWASAKI <[email protected]>
4
* Copyright (c) 2003 Peter Wemm
5
* Copyright (c) 2008-2012 Jung-uk Kim <[email protected]>
6
* All rights reserved.
7
*
8
* Redistribution and use in source and binary forms, with or without
9
* modification, are permitted provided that the following conditions
10
* are met:
11
* 1. Redistributions of source code must retain the above copyright
12
* notice, this list of conditions and the following disclaimer.
13
* 2. Redistributions in binary form must reproduce the above copyright
14
* notice, this list of conditions and the following disclaimer in the
15
* documentation and/or other materials provided with the distribution.
16
*
17
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27
* SUCH DAMAGE.
28
*/
29
30
#include <machine/asmacros.h>
31
#include <machine/specialreg.h>
32
#include <x86/ppireg.h>
33
#include <x86/timerreg.h>
34
35
#include "assym.inc"
36
37
/*
38
* Resume entry point. The BIOS enters here in real mode after POST with
39
* CS set to the page where we stored this code. It should configure the
40
* segment registers with a flat 4 GB address space and EFLAGS.IF = 0.
41
* Depending on the previous sleep state, we may need to initialize more
42
* of the system (i.e., S3 suspend-to-RAM vs. S4 suspend-to-disk).
43
*/
44
45
.data /* So we can modify it */
46
47
ALIGN_TEXT
48
.code16
49
wakeup_start:
50
/*
51
* Set up segment registers for real mode and a small stack for
52
* any calls we make. Set up full 32-bit bootstrap kernel flags
53
* since resumectx() doesn't restore flags. PSL_KERNEL gives
54
* bootstrap kernel flags (with interrupts disabled), not normal
55
* kernel flags.
56
*/
57
cli /* make sure no interrupts */
58
mov %cs, %ax /* copy %cs to %ds. Remember these */
59
mov %ax, %ds /* are offsets rather than selectors */
60
mov %ax, %ss
61
movw $PAGE_SIZE, %sp
62
pushl $PSL_KERNEL
63
popfl
64
65
/* To debug resume hangs, beep the speaker if the user requested. */
66
testb $~0, resume_beep - wakeup_start
67
jz 1f
68
movb $0, resume_beep - wakeup_start
69
70
/* Set PIC timer2 to beep. */
71
movb $(TIMER_SEL2 | TIMER_SQWAVE | TIMER_16BIT), %al
72
outb %al, $TIMER_MODE
73
74
/* Turn on speaker. */
75
inb $IO_PPI, %al
76
orb $PIT_SPKR, %al
77
outb %al, $IO_PPI
78
79
/* Set frequency. */
80
movw $0x4c0, %ax
81
outb %al, $TIMER_CNTR2
82
shrw $8, %ax
83
outb %al, $TIMER_CNTR2
84
1:
85
86
/* Re-initialize video BIOS if the reset_video tunable is set. */
87
testb $~0, reset_video - wakeup_start
88
jz 1f
89
movb $0, reset_video - wakeup_start
90
lcall $0xc000, $3
91
92
/* When we reach here, int 0x10 should be ready. Hide cursor. */
93
movb $0x01, %ah
94
movb $0x20, %ch
95
int $0x10
96
97
/* Re-start in case the previous BIOS call clobbers them. */
98
jmp wakeup_start
99
1:
100
101
/*
102
* Find relocation base and patch the gdt descript and ljmp targets
103
*/
104
xorl %ebx, %ebx
105
mov %cs, %bx
106
sall $4, %ebx /* %ebx is now our relocation base */
107
108
/*
109
* Load the descriptor table pointer. We'll need it when running
110
* in 16-bit protected mode.
111
*/
112
lgdtl bootgdtdesc - wakeup_start
113
114
/* Enable protected mode */
115
movl $CR0_PE, %eax
116
mov %eax, %cr0
117
118
/*
119
* Now execute a far jump to turn on protected mode. This
120
* causes the segment registers to turn into selectors and causes
121
* %cs to be loaded from the gdt.
122
*
123
* The following instruction is:
124
* ljmpl $bootcode32 - bootgdt, $wakeup_32 - wakeup_start
125
* but gas cannot assemble that. And besides, we patch the targets
126
* in early startup and its a little clearer what we are patching.
127
*/
128
wakeup_sw32:
129
.byte 0x66 /* size override to 32 bits */
130
.byte 0xea /* opcode for far jump */
131
.long wakeup_32 - wakeup_start /* offset in segment */
132
.word bootcode32 - bootgdt /* index in gdt for 32 bit code */
133
134
/*
135
* At this point, we are running in 32 bit legacy protected mode.
136
*/
137
ALIGN_TEXT
138
.code32
139
wakeup_32:
140
141
mov $bootdata32 - bootgdt, %eax
142
mov %ax, %ds
143
144
/* Restore EFER, CR4 and CR3. */
145
movl wakeup_efer - wakeup_start(%ebx), %eax
146
movl wakeup_efer - wakeup_start + 4(%ebx), %edx
147
cmpl $0, %eax
148
jne 1f
149
cmpl $0, %edx
150
je 2f
151
1: movl $MSR_EFER, %ecx
152
wrmsr
153
2: movl wakeup_cr4 - wakeup_start(%ebx), %eax
154
cmpl $0, %eax
155
je 3f
156
mov %eax, %cr4
157
3: movl wakeup_cr3 - wakeup_start(%ebx), %eax
158
mov %eax, %cr3
159
160
/* Get PCB and return address. */
161
movl wakeup_ret - wakeup_start(%ebx), %edx
162
movl wakeup_pcb - wakeup_start(%ebx), %ecx
163
164
/* Enable paging. */
165
mov %cr0, %eax
166
orl $CR0_PG, %eax
167
mov %eax, %cr0
168
169
/* Jump to return address. */
170
jmp *%edx
171
172
.data
173
174
resume_beep:
175
.byte 0
176
reset_video:
177
.byte 0
178
179
ALIGN_DATA
180
bootgdt:
181
.long 0x00000000
182
.long 0x00000000
183
184
bootcode32:
185
.long 0x0000ffff
186
.long 0x00cf9b00
187
188
bootdata32:
189
.long 0x0000ffff
190
.long 0x00cf9300
191
bootgdtend:
192
193
bootgdtdesc:
194
.word bootgdtend - bootgdt /* Length */
195
.long bootgdt - wakeup_start /* Offset plus %ds << 4 */
196
197
ALIGN_DATA
198
wakeup_efer:
199
.long 0
200
.long 0
201
wakeup_cr4:
202
.long 0
203
wakeup_cr3:
204
.long 0
205
wakeup_pcb:
206
.long 0
207
wakeup_ret:
208
.long 0
209
wakeup_gdt: /* not used */
210
.word 0
211
.long 0
212
dummy:
213
214