author | Kuriakose Kuruvilla <kuriakose.kuruvilla@oracle.com> |
Mon, 16 Aug 2010 22:47:01 -0700 | |
changeset 13148 | 67d1861e02c1 |
parent 12838 | fca99d9e3f2f |
child 13646 | 8f5bd7d387bc |
permissions | -rw-r--r-- |
5295 | 1 |
/* |
2 |
* CDDL HEADER START |
|
3 |
* |
|
4 |
* The contents of this file are subject to the terms of the |
|
5 |
* Common Development and Distribution License (the "License"). |
|
6 |
* You may not use this file except in compliance with the License. |
|
7 |
* |
|
8 |
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE |
|
9 |
* or http://www.opensolaris.org/os/licensing. |
|
10 |
* See the License for the specific language governing permissions |
|
11 |
* and limitations under the License. |
|
12 |
* |
|
13 |
* When distributing Covered Code, include this CDDL HEADER in each |
|
14 |
* file and include the License file at usr/src/OPENSOLARIS.LICENSE. |
|
15 |
* If applicable, add the following below this CDDL HEADER, with the |
|
16 |
* fields enclosed by brackets "[]" replaced with your own identifying |
|
17 |
* information: Portions Copyright [yyyy] [name of copyright owner] |
|
18 |
* |
|
19 |
* CDDL HEADER END |
|
20 |
*/ |
|
21 |
/* |
|
12838
fca99d9e3f2f
6812663 Running out of bits in x86_feature
Kuriakose Kuruvilla <kuriakose.kuruvilla@oracle.com>
parents:
9989
diff
changeset
|
22 |
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. |
5295 | 23 |
*/ |
24 |
||
25 |
#include <sys/asm_linkage.h> |
|
26 |
#include <sys/asm_misc.h> |
|
27 |
#include <sys/regset.h> |
|
28 |
#include <sys/privregs.h> |
|
29 |
#include <sys/x86_archext.h> |
|
30 |
#include <sys/cpr_wakecode.h> |
|
31 |
||
32 |
#if !defined(__lint) |
|
33 |
#include <sys/segments.h> |
|
34 |
#include "assym.h" |
|
35 |
#endif |
|
36 |
||
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
37 |
#ifdef DEBUG |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
38 |
#define LED 1 |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
39 |
#define SERIAL 1 |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
40 |
#endif /* DEBUG */ |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
41 |
|
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
42 |
#ifdef DEBUG |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
43 |
#define COM1 0x3f8 |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
44 |
#define COM2 0x2f8 |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
45 |
#define WC_COM COM2 /* either COM1 or COM2 */ |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
46 |
#define WC_LED 0x80 /* diagnostic led port ON motherboard */ |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
47 |
|
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
48 |
/* |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
49 |
* defined as offsets from the data register |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
50 |
*/ |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
51 |
#define DLL 0 /* divisor latch (lsb) */ |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
52 |
#define DLH 1 /* divisor latch (msb) */ |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
53 |
#define LCR 3 /* line control register */ |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
54 |
#define MCR 4 /* modem control register */ |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
55 |
|
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
56 |
|
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
57 |
#define DLAB 0x80 /* divisor latch access bit */ |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
58 |
#define B9600L 0X0c /* lsb bit pattern for 9600 baud */ |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
59 |
#define B9600H 0X0 /* hsb bit pattern for 9600 baud */ |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
60 |
#define DTR 0x01 /* Data Terminal Ready */ |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
61 |
#define RTS 0x02 /* Request To Send */ |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
62 |
#define STOP1 0x00 /* 1 stop bit */ |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
63 |
#define BITS8 0x03 /* 8 bits per char */ |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
64 |
|
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
65 |
#endif /* DEBUG */ |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
66 |
|
5295 | 67 |
/* |
68 |
* This file contains the low level routines involved in getting |
|
69 |
* into and out of ACPI S3, including those needed for restarting |
|
70 |
* the non-boot cpus. |
|
71 |
* |
|
72 |
* Our assumptions: |
|
73 |
* |
|
74 |
* Our actions: |
|
75 |
* |
|
76 |
*/ |
|
77 |
||
78 |
#if defined(lint) || defined(__lint) |
|
79 |
||
80 |
/*ARGSUSED*/ |
|
81 |
int |
|
82 |
wc_save_context(wc_cpu_t *pcpu) |
|
83 |
{ return 0; } |
|
84 |
||
85 |
#else /* lint */ |
|
86 |
||
87 |
#if defined(__GNU_AS__) |
|
88 |
||
89 |
NOTHING AT ALL YET! |
|
90 |
||
91 |
#else /* !defined(__GNU_AS__) */ |
|
92 |
||
93 |
#if defined(__amd64) |
|
94 |
||
95 |
ENTRY_NP(wc_save_context) |
|
96 |
||
97 |
movq (%rsp), %rdx / return address |
|
98 |
movq %rdx, WC_RETADDR(%rdi) |
|
99 |
pushq %rbp |
|
100 |
movq %rsp,%rbp |
|
101 |
||
102 |
movq %rdi, WC_VIRTADDR(%rdi) |
|
103 |
movq %rdi, WC_RDI(%rdi) |
|
104 |
||
105 |
movq %rdx, WC_RDX(%rdi) |
|
106 |
||
107 |
/ stash everything else we need |
|
108 |
sgdt WC_GDT(%rdi) |
|
109 |
sidt WC_IDT(%rdi) |
|
110 |
sldt WC_LDT(%rdi) |
|
111 |
str WC_TR(%rdi) |
|
112 |
||
113 |
movq %cr0, %rdx |
|
114 |
movq %rdx, WC_CR0(%rdi) |
|
115 |
movq %cr3, %rdx |
|
116 |
movq %rdx, WC_CR3(%rdi) |
|
117 |
movq %cr4, %rdx |
|
118 |
movq %rdx, WC_CR4(%rdi) |
|
119 |
movq %cr8, %rdx |
|
120 |
movq %rdx, WC_CR8(%rdi) |
|
121 |
||
122 |
movq %r8, WC_R8(%rdi) |
|
123 |
movq %r9, WC_R9(%rdi) |
|
124 |
movq %r10, WC_R10(%rdi) |
|
125 |
movq %r11, WC_R11(%rdi) |
|
126 |
movq %r12, WC_R12(%rdi) |
|
127 |
movq %r13, WC_R13(%rdi) |
|
128 |
movq %r14, WC_R14(%rdi) |
|
129 |
movq %r15, WC_R15(%rdi) |
|
130 |
movq %rax, WC_RAX(%rdi) |
|
131 |
movq %rbp, WC_RBP(%rdi) |
|
132 |
movq %rbx, WC_RBX(%rdi) |
|
133 |
movq %rcx, WC_RCX(%rdi) |
|
134 |
movq %rsi, WC_RSI(%rdi) |
|
135 |
movq %rsp, WC_RSP(%rdi) |
|
136 |
||
137 |
movw %ss, WC_SS(%rdi) |
|
138 |
movw %cs, WC_CS(%rdi) |
|
139 |
movw %ds, WC_DS(%rdi) |
|
140 |
movw %es, WC_ES(%rdi) |
|
141 |
||
142 |
movq $0, %rcx / save %fs register |
|
143 |
movw %fs, %cx |
|
144 |
movq %rcx, WC_FS(%rdi) |
|
145 |
||
146 |
movl $MSR_AMD_FSBASE, %ecx |
|
147 |
rdmsr |
|
148 |
movl %eax, WC_FSBASE(%rdi) |
|
149 |
movl %edx, WC_FSBASE+4(%rdi) |
|
150 |
||
151 |
movq $0, %rcx / save %gs register |
|
152 |
movw %gs, %cx |
|
153 |
movq %rcx, WC_GS(%rdi) |
|
154 |
||
155 |
movl $MSR_AMD_GSBASE, %ecx / save gsbase msr |
|
156 |
rdmsr |
|
157 |
movl %eax, WC_GSBASE(%rdi) |
|
158 |
movl %edx, WC_GSBASE+4(%rdi) |
|
159 |
||
160 |
movl $MSR_AMD_KGSBASE, %ecx / save kgsbase msr |
|
161 |
rdmsr |
|
162 |
movl %eax, WC_KGSBASE(%rdi) |
|
163 |
movl %edx, WC_KGSBASE+4(%rdi) |
|
164 |
||
9989
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
165 |
movq %gs:CPU_ID, %rax / save current cpu id |
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
166 |
movq %rax, WC_CPU_ID(%rdi) |
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
167 |
|
5295 | 168 |
pushfq |
169 |
popq WC_EFLAGS(%rdi) |
|
170 |
||
171 |
wbinvd / flush the cache |
|
9989
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
172 |
mfence |
5295 | 173 |
|
174 |
movq $1, %rax / at suspend return 1 |
|
175 |
||
176 |
leave |
|
177 |
||
178 |
ret |
|
179 |
||
180 |
SET_SIZE(wc_save_context) |
|
181 |
||
182 |
#elif defined(__i386) |
|
183 |
||
184 |
ENTRY_NP(wc_save_context) |
|
185 |
||
186 |
movl 4(%esp), %eax / wc_cpu_t * |
|
187 |
movl %eax, WC_VIRTADDR(%eax) |
|
188 |
||
189 |
movl (%esp), %edx / return address |
|
190 |
movl %edx, WC_RETADDR(%eax) |
|
191 |
||
192 |
str WC_TR(%eax) / stash everything else we need |
|
193 |
sgdt WC_GDT(%eax) |
|
194 |
sldt WC_LDT(%eax) |
|
195 |
sidt WC_IDT(%eax) |
|
196 |
||
197 |
movl %cr0, %edx |
|
198 |
movl %edx, WC_CR0(%eax) |
|
199 |
movl %cr3, %edx |
|
200 |
movl %edx, WC_CR3(%eax) |
|
201 |
movl %cr4, %edx |
|
202 |
movl %edx, WC_CR4(%eax) |
|
203 |
||
204 |
movl %ebx, WC_EBX(%eax) |
|
205 |
movl %edi, WC_EDI(%eax) |
|
206 |
movl %esi, WC_ESI(%eax) |
|
207 |
movl %ebp, WC_EBP(%eax) |
|
208 |
movl %esp, WC_ESP(%eax) |
|
209 |
||
210 |
movw %ss, WC_SS(%eax) |
|
211 |
movw %cs, WC_CS(%eax) |
|
212 |
movw %ds, WC_DS(%eax) |
|
213 |
movw %es, WC_ES(%eax) |
|
214 |
movw %fs, WC_FS(%eax) |
|
215 |
movw %gs, WC_GS(%eax) |
|
216 |
||
217 |
pushfl |
|
218 |
popl WC_EFLAGS(%eax) |
|
219 |
||
9989
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
220 |
pushl %gs:CPU_ID / save current cpu id |
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
221 |
popl WC_CPU_ID(%eax) |
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
222 |
|
5295 | 223 |
wbinvd / flush the cache |
9989
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
224 |
mfence |
5295 | 225 |
|
226 |
movl $1, %eax / at suspend return 1 |
|
227 |
ret |
|
228 |
||
229 |
SET_SIZE(wc_save_context) |
|
230 |
||
231 |
#endif /* __amd64 */ |
|
232 |
||
233 |
#endif /* __GNU_AS__ */ |
|
234 |
||
235 |
#endif /* lint */ |
|
236 |
||
237 |
||
238 |
/* |
|
239 |
* Our assumptions: |
|
240 |
* - We are running in real mode. |
|
241 |
* - Interrupts are disabled. |
|
242 |
* |
|
243 |
* Our actions: |
|
244 |
* - We start using our GDT by loading correct values in the |
|
245 |
* selector registers (cs=KCS_SEL, ds=es=ss=KDS_SEL, fs=KFS_SEL, |
|
246 |
* gs=KGS_SEL). |
|
247 |
* - We change over to using our IDT. |
|
248 |
* - We load the default LDT into the hardware LDT register. |
|
249 |
* - We load the default TSS into the hardware task register. |
|
250 |
* - We restore registers |
|
251 |
* - We return to original caller (a la setjmp) |
|
252 |
*/ |
|
253 |
||
254 |
#if defined(lint) || defined(__lint) |
|
255 |
||
256 |
void |
|
257 |
wc_rm_start(void) |
|
258 |
{} |
|
259 |
||
260 |
void |
|
261 |
wc_rm_end(void) |
|
262 |
{} |
|
263 |
||
264 |
#else /* lint */ |
|
265 |
||
266 |
#if defined(__GNU_AS__) |
|
267 |
||
268 |
NOTHING AT ALL YET! |
|
269 |
||
270 |
#else /* __GNU_AS__ */ |
|
271 |
||
272 |
#if defined(__amd64) |
|
273 |
||
274 |
ENTRY_NP(wc_rm_start) |
|
275 |
||
276 |
/* |
|
277 |
* For vulcan as we need to do a .code32 and mentally invert the |
|
278 |
* meaning of the addr16 and data16 prefixes to get 32-bit access when |
|
279 |
* generating code to be executed in 16-bit mode (sigh...) |
|
280 |
*/ |
|
281 |
||
282 |
.code32 |
|
283 |
||
284 |
cli |
|
285 |
movw %cs, %ax |
|
286 |
movw %ax, %ds / establish ds ... |
|
287 |
movw %ax, %ss / ... and ss:esp |
|
288 |
D16 movl $WC_STKSTART, %esp |
|
289 |
/ using the following value blows up machines! - DO NOT USE |
|
290 |
/ D16 movl 0xffc, %esp |
|
291 |
||
292 |
||
293 |
#if LED |
|
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
294 |
D16 movl $WC_LED, %edx |
5295 | 295 |
D16 movb $0xd1, %al |
296 |
outb (%dx) |
|
297 |
#endif |
|
298 |
||
299 |
#if SERIAL |
|
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
300 |
D16 movl $WC_COM, %edx |
5295 | 301 |
D16 movb $0x61, %al |
302 |
outb (%dx) |
|
303 |
#endif |
|
304 |
||
305 |
D16 call cominit |
|
306 |
||
307 |
/* |
|
308 |
* Enable protected-mode, write protect, and alignment mask |
|
309 |
* %cr0 has already been initialsed to zero |
|
310 |
*/ |
|
311 |
movl %cr0, %eax |
|
312 |
D16 orl $[CR0_PE|CR0_WP|CR0_AM], %eax |
|
313 |
movl %eax, %cr0 |
|
314 |
||
315 |
/* |
|
316 |
* Do a jmp immediately after writing to cr0 when enabling protected |
|
317 |
* mode to clear the real mode prefetch queue (per Intel's docs) |
|
318 |
*/ |
|
319 |
jmp pestart |
|
320 |
pestart: |
|
321 |
||
322 |
#if LED |
|
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
323 |
D16 movl $WC_LED, %edx |
5295 | 324 |
D16 movb $0xd2, %al |
325 |
outb (%dx) |
|
326 |
#endif |
|
327 |
||
328 |
#if SERIAL |
|
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
329 |
D16 movl $WC_COM, %edx |
5295 | 330 |
D16 movb $0x62, %al |
331 |
outb (%dx) |
|
332 |
#endif |
|
333 |
||
334 |
/* |
|
335 |
* 16-bit protected mode is now active, so prepare to turn on long |
|
336 |
* mode |
|
337 |
*/ |
|
338 |
||
339 |
#if LED |
|
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
340 |
D16 movl $WC_LED, %edx |
5295 | 341 |
D16 movb $0xd3, %al |
342 |
outb (%dx) |
|
343 |
#endif |
|
344 |
||
345 |
#if SERIAL |
|
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
346 |
D16 movl $WC_COM, %edx |
5295 | 347 |
D16 movb $0x63, %al |
348 |
outb (%dx) |
|
349 |
#endif |
|
350 |
||
351 |
/* |
|
352 |
* Add any initial cr4 bits |
|
353 |
*/ |
|
354 |
movl %cr4, %eax |
|
355 |
A16 D16 orl CR4OFF, %eax |
|
356 |
||
357 |
/* |
|
358 |
* Enable PAE mode (CR4.PAE) |
|
359 |
*/ |
|
360 |
D16 orl $CR4_PAE, %eax |
|
361 |
movl %eax, %cr4 |
|
362 |
||
363 |
#if LED |
|
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
364 |
D16 movl $WC_LED, %edx |
5295 | 365 |
D16 movb $0xd4, %al |
366 |
outb (%dx) |
|
367 |
#endif |
|
368 |
||
369 |
#if SERIAL |
|
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
370 |
D16 movl $WC_COM, %edx |
5295 | 371 |
D16 movb $0x64, %al |
372 |
outb (%dx) |
|
373 |
#endif |
|
374 |
||
375 |
/* |
|
376 |
* Point cr3 to the 64-bit long mode page tables. |
|
377 |
* |
|
378 |
* Note that these MUST exist in 32-bit space, as we don't have |
|
379 |
* a way to load %cr3 with a 64-bit base address for the page tables |
|
380 |
* until the CPU is actually executing in 64-bit long mode. |
|
381 |
*/ |
|
382 |
A16 D16 movl CR3OFF, %eax |
|
383 |
movl %eax, %cr3 |
|
384 |
||
385 |
/* |
|
386 |
* Set long mode enable in EFER (EFER.LME = 1) |
|
387 |
*/ |
|
388 |
D16 movl $MSR_AMD_EFER, %ecx |
|
389 |
rdmsr |
|
390 |
||
391 |
D16 orl $AMD_EFER_LME, %eax |
|
392 |
wrmsr |
|
393 |
||
394 |
#if LED |
|
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
395 |
D16 movl $WC_LED, %edx |
5295 | 396 |
D16 movb $0xd5, %al |
397 |
outb (%dx) |
|
398 |
#endif |
|
399 |
||
400 |
#if SERIAL |
|
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
401 |
D16 movl $WC_COM, %edx |
5295 | 402 |
D16 movb $0x65, %al |
403 |
outb (%dx) |
|
404 |
#endif |
|
405 |
||
406 |
/* |
|
407 |
* Finally, turn on paging (CR0.PG = 1) to activate long mode. |
|
408 |
*/ |
|
409 |
movl %cr0, %eax |
|
410 |
D16 orl $CR0_PG, %eax |
|
411 |
movl %eax, %cr0 |
|
412 |
||
413 |
/* |
|
414 |
* The instruction after enabling paging in CR0 MUST be a branch. |
|
415 |
*/ |
|
416 |
jmp long_mode_active |
|
417 |
||
418 |
long_mode_active: |
|
419 |
||
420 |
#if LED |
|
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
421 |
D16 movl $WC_LED, %edx |
5295 | 422 |
D16 movb $0xd6, %al |
423 |
outb (%dx) |
|
424 |
#endif |
|
425 |
||
426 |
#if SERIAL |
|
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
427 |
D16 movl $WC_COM, %edx |
5295 | 428 |
D16 movb $0x66, %al |
429 |
outb (%dx) |
|
430 |
#endif |
|
431 |
||
432 |
/* |
|
433 |
* Long mode is now active but since we're still running with the |
|
434 |
* original 16-bit CS we're actually in 16-bit compatability mode. |
|
435 |
* |
|
436 |
* We have to load an intermediate GDT and IDT here that we know are |
|
437 |
* in 32-bit space before we can use the kernel's GDT and IDT, which |
|
438 |
* may be in the 64-bit address space, and since we're in compatability |
|
439 |
* mode, we only have access to 16 and 32-bit instructions at the |
|
440 |
* moment. |
|
441 |
*/ |
|
442 |
A16 D16 lgdt TEMPGDTOFF /* load temporary GDT */ |
|
443 |
A16 D16 lidt TEMPIDTOFF /* load temporary IDT */ |
|
444 |
||
445 |
||
446 |
/* |
|
447 |
* Do a far transfer to 64-bit mode. Set the CS selector to a 64-bit |
|
448 |
* long mode selector (CS.L=1) in the temporary 32-bit GDT and jump |
|
449 |
* to the real mode platter address of wc_long_mode_64 as until the |
|
450 |
* 64-bit CS is in place we don't have access to 64-bit instructions |
|
451 |
* and thus can't reference a 64-bit %rip. |
|
452 |
*/ |
|
453 |
||
454 |
#if LED |
|
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
455 |
D16 movl $WC_LED, %edx |
5295 | 456 |
D16 movb $0xd7, %al |
457 |
outb (%dx) |
|
458 |
#endif |
|
459 |
||
460 |
#if SERIAL |
|
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
461 |
D16 movl $WC_COM, %edx |
5295 | 462 |
D16 movb $0x67, %al |
463 |
outb (%dx) |
|
464 |
#endif |
|
465 |
||
466 |
D16 pushl $TEMP_CS64_SEL |
|
467 |
A16 D16 pushl LM64OFF |
|
468 |
||
469 |
D16 lret |
|
470 |
||
471 |
||
472 |
/* |
|
473 |
* Support routine to re-initialize VGA subsystem |
|
474 |
*/ |
|
475 |
vgainit: |
|
476 |
D16 ret |
|
477 |
||
478 |
/* |
|
479 |
* Support routine to re-initialize keyboard (which is USB - help!) |
|
480 |
*/ |
|
481 |
kbdinit: |
|
482 |
D16 ret |
|
483 |
||
484 |
/* |
|
485 |
* Support routine to re-initialize COM ports to something sane |
|
486 |
*/ |
|
487 |
cominit: |
|
488 |
/ init COM1 & COM2 |
|
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
489 |
|
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
490 |
#if DEBUG |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
491 |
/* |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
492 |
* on debug kernels we need to initialize COM1 & COM2 here, so that |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
493 |
* we can get debug output before the asy driver has resumed |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
494 |
*/ |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
495 |
|
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
496 |
/ select COM1 |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
497 |
D16 movl $[COM1+LCR], %edx |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
498 |
D16 movb $DLAB, %al / divisor latch |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
499 |
outb (%dx) |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
500 |
|
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
501 |
D16 movl $[COM1+DLL], %edx / divisor latch lsb |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
502 |
D16 movb $B9600L, %al / divisor latch |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
503 |
outb (%dx) |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
504 |
|
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
505 |
D16 movl $[COM1+DLH], %edx / divisor latch hsb |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
506 |
D16 movb $B9600H, %al / divisor latch |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
507 |
outb (%dx) |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
508 |
|
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
509 |
D16 movl $[COM1+LCR], %edx / select COM1 |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
510 |
D16 movb $[STOP1|BITS8], %al / 1 stop bit, 8bit word len |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
511 |
outb (%dx) |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
512 |
|
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
513 |
D16 movl $[COM1+MCR], %edx / select COM1 |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
514 |
D16 movb $[RTS|DTR], %al / data term ready & req to send |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
515 |
outb (%dx) |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
516 |
|
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
517 |
/ select COM2 |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
518 |
D16 movl $[COM2+LCR], %edx |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
519 |
D16 movb $DLAB, %al / divisor latch |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
520 |
outb (%dx) |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
521 |
|
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
522 |
D16 movl $[COM2+DLL], %edx / divisor latch lsb |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
523 |
D16 movb $B9600L, %al / divisor latch |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
524 |
outb (%dx) |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
525 |
|
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
526 |
D16 movl $[COM2+DLH], %edx / divisor latch hsb |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
527 |
D16 movb $B9600H, %al / divisor latch |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
528 |
outb (%dx) |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
529 |
|
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
530 |
D16 movl $[COM2+LCR], %edx / select COM1 |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
531 |
D16 movb $[STOP1|BITS8], %al / 1 stop bit, 8bit word len |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
532 |
outb (%dx) |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
533 |
|
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
534 |
D16 movl $[COM2+MCR], %edx / select COM1 |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
535 |
D16 movb $[RTS|DTR], %al / data term ready & req to send |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
536 |
outb (%dx) |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
537 |
#endif /* DEBUG */ |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
538 |
|
5295 | 539 |
D16 ret |
540 |
||
541 |
.code64 |
|
542 |
||
543 |
.globl wc_long_mode_64 |
|
544 |
wc_long_mode_64: |
|
545 |
||
546 |
#if LED |
|
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
547 |
movw $WC_LED, %dx |
5295 | 548 |
movb $0xd8, %al |
549 |
outb (%dx) |
|
550 |
#endif |
|
551 |
||
552 |
#if SERIAL |
|
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
553 |
movw $WC_COM, %dx |
5295 | 554 |
movb $0x68, %al |
555 |
outb (%dx) |
|
556 |
#endif |
|
557 |
||
558 |
/* |
|
559 |
* We are now running in long mode with a 64-bit CS (EFER.LMA=1, |
|
560 |
* CS.L=1) so we now have access to 64-bit instructions. |
|
561 |
* |
|
562 |
* First, set the 64-bit GDT base. |
|
563 |
*/ |
|
564 |
.globl rm_platter_pa |
|
565 |
movl rm_platter_pa, %eax |
|
566 |
||
567 |
lgdtq GDTROFF(%rax) /* load 64-bit GDT */ |
|
568 |
||
569 |
/* |
|
570 |
* Save the CPU number in %r11; get the value here since it's saved in |
|
571 |
* the real mode platter. |
|
572 |
*/ |
|
573 |
/ JAN |
|
574 |
/ the following is wrong! need to figure out MP systems |
|
575 |
/ movl CPUNOFF(%rax), %r11d |
|
576 |
||
577 |
/* |
|
578 |
* Add rm_platter_pa to %rsp to point it to the same location as seen |
|
579 |
* from 64-bit mode. |
|
580 |
*/ |
|
581 |
addq %rax, %rsp |
|
582 |
||
583 |
/* |
|
584 |
* Now do an lretq to load CS with the appropriate selector for the |
|
585 |
* kernel's 64-bit GDT and to start executing 64-bit setup code at the |
|
586 |
* virtual address where boot originally loaded this code rather than |
|
587 |
* the copy in the real mode platter's rm_code array as we've been |
|
588 |
* doing so far. |
|
589 |
*/ |
|
590 |
||
591 |
#if LED |
|
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
592 |
movw $WC_LED, %dx |
5295 | 593 |
movb $0xd9, %al |
594 |
outb (%dx) |
|
595 |
#endif |
|
596 |
||
597 |
/ JAN this should produce 'i' but we get 'g' instead ??? |
|
598 |
#if SERIAL |
|
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
599 |
movw $WC_COM, %dx |
5295 | 600 |
movb $0x69, %al |
601 |
outb (%dx) |
|
602 |
#endif |
|
603 |
||
604 |
pushq $KCS_SEL |
|
605 |
pushq $kernel_wc_code |
|
606 |
lretq |
|
607 |
||
608 |
.globl kernel_wc_code |
|
609 |
kernel_wc_code: |
|
610 |
||
611 |
#if LED |
|
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
612 |
movw $WC_LED, %dx |
5295 | 613 |
movb $0xda, %al |
614 |
outb (%dx) |
|
615 |
#endif |
|
616 |
||
617 |
/ JAN this should produce 'j' but we get 'g' instead ??? |
|
618 |
#if SERIAL |
|
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
619 |
movw $WC_COM, %dx |
5295 | 620 |
movb $0x6a, %al |
621 |
outb (%dx) |
|
622 |
#endif |
|
623 |
||
624 |
/* |
|
625 |
* Complete the balance of the setup we need to before executing |
|
626 |
* 64-bit kernel code (namely init rsp, TSS, LGDT, FS and GS). |
|
627 |
*/ |
|
628 |
.globl rm_platter_va |
|
629 |
movq rm_platter_va, %rbx |
|
630 |
addq $WC_CPU, %rbx |
|
631 |
||
632 |
#if LED |
|
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
633 |
movw $WC_LED, %dx |
5295 | 634 |
movb $0xdb, %al |
635 |
outb (%dx) |
|
636 |
#endif |
|
637 |
||
638 |
#if SERIAL |
|
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
639 |
movw $WC_COM, %dx |
5295 | 640 |
movw $0x6b, %ax |
641 |
outb (%dx) |
|
642 |
#endif |
|
643 |
||
644 |
/* |
|
645 |
* restore the rest of the registers |
|
646 |
*/ |
|
647 |
||
648 |
lidtq WC_IDT(%rbx) |
|
649 |
||
650 |
#if LED |
|
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
651 |
movw $WC_LED, %dx |
5295 | 652 |
movb $0xdc, %al |
653 |
outb (%dx) |
|
654 |
#endif |
|
655 |
||
656 |
#if SERIAL |
|
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
657 |
movw $WC_COM, %dx |
5295 | 658 |
movw $0x6c, %ax |
659 |
outb (%dx) |
|
660 |
#endif |
|
661 |
||
662 |
/* |
|
663 |
* restore the rest of the registers |
|
664 |
*/ |
|
665 |
||
666 |
movw $KDS_SEL, %ax |
|
667 |
movw %ax, %ds |
|
668 |
movw %ax, %es |
|
669 |
movw %ax, %ss |
|
670 |
||
671 |
/* |
|
672 |
* Before proceeding, enable usage of the page table NX bit if |
|
673 |
* that's how the page tables are set up. |
|
674 |
*/ |
|
13148
67d1861e02c1
6970888 panic BAD TRAP: type=d (#gp General protection) due to incorrect use of x86_featureset
Kuriakose Kuruvilla <kuriakose.kuruvilla@oracle.com>
parents:
12838
diff
changeset
|
675 |
bt $X86FSET_NX, x86_featureset(%rip) |
12838
fca99d9e3f2f
6812663 Running out of bits in x86_feature
Kuriakose Kuruvilla <kuriakose.kuruvilla@oracle.com>
parents:
9989
diff
changeset
|
676 |
jnc 1f |
5295 | 677 |
movl $MSR_AMD_EFER, %ecx |
678 |
rdmsr |
|
679 |
orl $AMD_EFER_NXE, %eax |
|
680 |
wrmsr |
|
681 |
1: |
|
682 |
||
683 |
movq WC_CR4(%rbx), %rax / restore full cr4 (with Global Enable) |
|
684 |
movq %rax, %cr4 |
|
685 |
||
686 |
lldt WC_LDT(%rbx) |
|
687 |
movzwq WC_TR(%rbx), %rax / clear TSS busy bit |
|
688 |
addq WC_GDT+2(%rbx), %rax |
|
689 |
andl $0xfffffdff, 4(%rax) |
|
690 |
movq 4(%rax), %rcx |
|
691 |
ltr WC_TR(%rbx) |
|
692 |
||
693 |
#if LED |
|
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
694 |
movw $WC_LED, %dx |
5295 | 695 |
movb $0xdd, %al |
696 |
outb (%dx) |
|
697 |
#endif |
|
698 |
||
699 |
#if SERIAL |
|
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
700 |
movw $WC_COM, %dx |
5295 | 701 |
movw $0x6d, %ax |
702 |
outb (%dx) |
|
703 |
#endif |
|
704 |
||
705 |
/ restore %fsbase %gsbase %kgbase registers using wrmsr instruction |
|
706 |
||
707 |
movq WC_FS(%rbx), %rcx / restore fs register |
|
708 |
movw %cx, %fs |
|
709 |
||
710 |
movl $MSR_AMD_FSBASE, %ecx |
|
711 |
movl WC_FSBASE(%rbx), %eax |
|
712 |
movl WC_FSBASE+4(%rbx), %edx |
|
713 |
wrmsr |
|
714 |
||
715 |
movq WC_GS(%rbx), %rcx / restore gs register |
|
716 |
movw %cx, %gs |
|
717 |
||
718 |
movl $MSR_AMD_GSBASE, %ecx / restore gsbase msr |
|
719 |
movl WC_GSBASE(%rbx), %eax |
|
720 |
movl WC_GSBASE+4(%rbx), %edx |
|
721 |
wrmsr |
|
722 |
||
723 |
movl $MSR_AMD_KGSBASE, %ecx / restore kgsbase msr |
|
724 |
movl WC_KGSBASE(%rbx), %eax |
|
725 |
movl WC_KGSBASE+4(%rbx), %edx |
|
726 |
wrmsr |
|
727 |
||
728 |
movq WC_CR0(%rbx), %rdx |
|
729 |
movq %rdx, %cr0 |
|
730 |
movq WC_CR3(%rbx), %rdx |
|
731 |
movq %rdx, %cr3 |
|
732 |
movq WC_CR8(%rbx), %rdx |
|
733 |
movq %rdx, %cr8 |
|
734 |
||
735 |
#if LED |
|
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
736 |
movw $WC_LED, %dx |
5295 | 737 |
movb $0xde, %al |
738 |
outb (%dx) |
|
739 |
#endif |
|
740 |
||
741 |
#if SERIAL |
|
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
742 |
movw $WC_COM, %dx |
5295 | 743 |
movb $0x6e, %al |
744 |
outb (%dx) |
|
745 |
#endif |
|
746 |
||
9989
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
747 |
/* |
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
748 |
* if we are not running on the boot CPU restore stack contents by |
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
749 |
* calling i_cpr_restore_stack(curthread, save_stack); |
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
750 |
*/ |
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
751 |
movq %rsp, %rbp |
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
752 |
call i_cpr_bootcpuid |
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
753 |
cmpl %eax, WC_CPU_ID(%rbx) |
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
754 |
je 2f |
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
755 |
|
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
756 |
movq %gs:CPU_THREAD, %rdi |
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
757 |
movq WC_SAVED_STACK(%rbx), %rsi |
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
758 |
call i_cpr_restore_stack |
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
759 |
2: |
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
760 |
|
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
761 |
movq WC_RSP(%rbx), %rsp / restore stack pointer |
5295 | 762 |
|
763 |
/* |
|
7362
0b07b96ed3bd
6734669 resume hangs on Toshiba M8/M9 with 64bit nondebug kernel
Guoli Shu<Kerry.Shu@Sun.COM>
parents:
6876
diff
changeset
|
764 |
* APIC initialization |
5295 | 765 |
*/ |
9989
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
766 |
movq %rsp, %rbp |
5295 | 767 |
|
5817 | 768 |
/* |
769 |
* skip iff function pointer is NULL |
|
770 |
*/ |
|
771 |
cmpq $0, ap_mlsetup |
|
9989
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
772 |
je 3f |
5817 | 773 |
call *ap_mlsetup |
9989
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
774 |
3: |
5295 | 775 |
|
776 |
call *cpr_start_cpu_func |
|
777 |
||
778 |
/ restore %rbx to the value it ahd before we called the functions above |
|
779 |
movq rm_platter_va, %rbx |
|
780 |
addq $WC_CPU, %rbx |
|
781 |
||
782 |
movq WC_R8(%rbx), %r8 |
|
783 |
movq WC_R9(%rbx), %r9 |
|
784 |
movq WC_R10(%rbx), %r10 |
|
785 |
movq WC_R11(%rbx), %r11 |
|
786 |
movq WC_R12(%rbx), %r12 |
|
787 |
movq WC_R13(%rbx), %r13 |
|
788 |
movq WC_R14(%rbx), %r14 |
|
789 |
movq WC_R15(%rbx), %r15 |
|
790 |
/ movq WC_RAX(%rbx), %rax |
|
791 |
movq WC_RBP(%rbx), %rbp |
|
792 |
movq WC_RCX(%rbx), %rcx |
|
793 |
/ movq WC_RDX(%rbx), %rdx |
|
794 |
movq WC_RDI(%rbx), %rdi |
|
795 |
movq WC_RSI(%rbx), %rsi |
|
796 |
||
797 |
||
798 |
/ assume that %cs does not need to be restored |
|
799 |
/ %ds, %es & %ss are ignored in 64bit mode |
|
800 |
movw WC_SS(%rbx), %ss |
|
801 |
movw WC_DS(%rbx), %ds |
|
802 |
movw WC_ES(%rbx), %es |
|
803 |
||
804 |
#if LED |
|
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
805 |
movw $WC_LED, %dx |
5295 | 806 |
movb $0xdf, %al |
807 |
outb (%dx) |
|
808 |
#endif |
|
809 |
||
810 |
#if SERIAL |
|
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
811 |
movw $WC_COM, %dx |
5295 | 812 |
movb $0x6f, %al |
813 |
outb (%dx) |
|
814 |
#endif |
|
815 |
||
816 |
||
817 |
movq WC_RBP(%rbx), %rbp |
|
818 |
movq WC_RSP(%rbx), %rsp |
|
819 |
||
820 |
#if LED |
|
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
821 |
movw $WC_LED, %dx |
5295 | 822 |
movb $0xe0, %al |
823 |
outb (%dx) |
|
824 |
#endif |
|
825 |
||
826 |
#if SERIAL |
|
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
827 |
movw $WC_COM, %dx |
5295 | 828 |
movb $0x70, %al |
829 |
outb (%dx) |
|
830 |
#endif |
|
831 |
||
832 |
||
833 |
movq WC_RCX(%rbx), %rcx |
|
834 |
||
835 |
pushq WC_EFLAGS(%rbx) / restore flags |
|
836 |
popfq |
|
837 |
||
838 |
#if LED |
|
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
839 |
movw $WC_LED, %dx |
5295 | 840 |
movb $0xe1, %al |
841 |
outb (%dx) |
|
842 |
#endif |
|
843 |
||
844 |
#if SERIAL |
|
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
845 |
movw $WC_COM, %dx |
5295 | 846 |
movb $0x71, %al |
847 |
outb (%dx) |
|
848 |
#endif |
|
849 |
||
850 |
/* |
|
851 |
* can not use outb after this point, because doing so would mean using |
|
852 |
* %dx which would modify %rdx which is restored here |
|
853 |
*/ |
|
854 |
||
855 |
movq %rbx, %rax |
|
856 |
movq WC_RDX(%rax), %rdx |
|
857 |
movq WC_RBX(%rax), %rbx |
|
858 |
||
859 |
leave |
|
860 |
||
861 |
movq WC_RETADDR(%rax), %rax |
|
862 |
movq %rax, (%rsp) / return to caller of wc_save_context |
|
863 |
||
864 |
xorl %eax, %eax / at wakeup return 0 |
|
865 |
ret |
|
866 |
||
867 |
||
868 |
SET_SIZE(wc_rm_start) |
|
869 |
||
870 |
ENTRY_NP(asmspin) |
|
871 |
||
872 |
movl %edi, %ecx |
|
873 |
A1: |
|
874 |
loop A1 |
|
875 |
||
876 |
SET_SIZE(asmspin) |
|
877 |
||
878 |
.globl wc_rm_end |
|
879 |
wc_rm_end: |
|
880 |
nop |
|
881 |
||
882 |
#elif defined(__i386) |
|
883 |
||
884 |
ENTRY_NP(wc_rm_start) |
|
885 |
||
886 |
/entry: jmp entry / stop here for HDT |
|
887 |
||
888 |
cli |
|
889 |
movw %cs, %ax |
|
890 |
movw %ax, %ds / establish ds ... |
|
891 |
movw %ax, %ss / ... and ss:esp |
|
892 |
D16 movl $WC_STKSTART, %esp |
|
893 |
||
894 |
#if LED |
|
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
895 |
D16 movl $WC_LED, %edx |
5295 | 896 |
D16 movb $0xd1, %al |
897 |
outb (%dx) |
|
898 |
#endif |
|
899 |
||
900 |
#if SERIAL |
|
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
901 |
D16 movl $WC_COM, %edx |
5295 | 902 |
D16 movb $0x61, %al |
903 |
outb (%dx) |
|
904 |
#endif |
|
905 |
||
906 |
||
907 |
D16 call vgainit |
|
908 |
D16 call kbdinit |
|
909 |
D16 call cominit |
|
910 |
||
911 |
#if LED |
|
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
912 |
D16 movl $WC_LED, %edx |
5295 | 913 |
D16 movb $0xd2, %al |
914 |
outb (%dx) |
|
915 |
#endif |
|
916 |
||
917 |
#if SERIAL |
|
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
918 |
D16 movl $WC_COM, %edx |
5295 | 919 |
D16 movb $0x62, %al |
920 |
outb (%dx) |
|
921 |
#endif |
|
922 |
||
923 |
D16 A16 movl $WC_CPU, %ebx / base add of wc_cpu_t |
|
924 |
||
925 |
#if LED |
|
926 |
D16 movb $0xd3, %al |
|
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
927 |
outb $WC_LED |
5295 | 928 |
#endif |
929 |
||
930 |
#if SERIAL |
|
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
931 |
D16 movl $WC_COM, %edx |
5295 | 932 |
D16 movb $0x63, %al |
933 |
outb (%dx) |
|
934 |
#endif |
|
935 |
||
936 |
D16 A16 movl %cs:WC_DS(%ebx), %edx / %ds post prot/paging transit |
|
937 |
||
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
938 |
#if LED |
5295 | 939 |
D16 movb $0xd4, %al |
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
940 |
outb $WC_LED |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
941 |
#endif |
5295 | 942 |
|
943 |
D16 A16 lgdt %cs:WC_GDT(%ebx) / restore gdt and idtr |
|
944 |
D16 A16 lidt %cs:WC_IDT(%ebx) |
|
945 |
||
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
946 |
#if LED |
5295 | 947 |
D16 movb $0xd5, %al |
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
948 |
outb $WC_LED |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
949 |
#endif |
5295 | 950 |
|
951 |
D16 A16 movl %cs:WC_CR4(%ebx), %eax / restore cr4 |
|
952 |
D16 andl $-1!CR4_PGE, %eax / don't set Global Enable yet |
|
953 |
movl %eax, %cr4 |
|
954 |
||
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
955 |
#if LED |
5295 | 956 |
D16 movb $0xd6, %al |
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
957 |
outb $WC_LED |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
958 |
#endif |
5295 | 959 |
|
960 |
D16 A16 movl %cs:WC_CR3(%ebx), %eax / set PDPT |
|
961 |
movl %eax, %cr3 |
|
962 |
||
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
963 |
#if LED |
5295 | 964 |
D16 movb $0xd7, %al |
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
965 |
outb $WC_LED |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
966 |
#endif |
5295 | 967 |
|
968 |
D16 A16 movl %cs:WC_CR0(%ebx), %eax / enable prot/paging, etc. |
|
969 |
movl %eax, %cr0 |
|
970 |
||
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
971 |
#if LED |
5295 | 972 |
D16 movb $0xd8, %al |
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
973 |
outb $WC_LED |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
974 |
#endif |
5295 | 975 |
|
976 |
D16 A16 movl %cs:WC_VIRTADDR(%ebx), %ebx / virtaddr of wc_cpu_t |
|
977 |
||
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
978 |
#if LED |
5295 | 979 |
D16 movb $0xd9, %al |
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
980 |
outb $WC_LED |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
981 |
#endif |
5295 | 982 |
|
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
983 |
#if LED |
5295 | 984 |
D16 movb $0xda, %al |
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
985 |
outb $WC_LED |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
986 |
#endif |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
987 |
|
5295 | 988 |
jmp flush / flush prefetch queue |
989 |
flush: |
|
990 |
D16 pushl $KCS_SEL |
|
991 |
D16 pushl $kernel_wc_code |
|
992 |
D16 lret / re-appear at kernel_wc_code |
|
993 |
||
994 |
||
995 |
/* |
|
996 |
* Support routine to re-initialize VGA subsystem |
|
997 |
*/ |
|
998 |
vgainit: |
|
999 |
D16 ret |
|
1000 |
||
1001 |
/* |
|
1002 |
* Support routine to re-initialize keyboard (which is USB - help!) |
|
1003 |
*/ |
|
1004 |
kbdinit: |
|
1005 |
D16 ret |
|
1006 |
||
1007 |
/* |
|
1008 |
* Support routine to re-initialize COM ports to something sane for debug output |
|
1009 |
*/ |
|
1010 |
cominit: |
|
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
1011 |
#if DEBUG |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
1012 |
/* |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
1013 |
* on debug kernels we need to initialize COM1 & COM2 here, so that |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
1014 |
* we can get debug output before the asy driver has resumed |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
1015 |
*/ |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
1016 |
|
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
1017 |
/ select COM1 |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
1018 |
D16 movl $[COM1+LCR], %edx |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
1019 |
D16 movb $DLAB, %al / divisor latch |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
1020 |
outb (%dx) |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
1021 |
|
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
1022 |
D16 movl $[COM1+DLL], %edx / divisor latch lsb |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
1023 |
D16 movb $B9600L, %al / divisor latch |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
1024 |
outb (%dx) |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
1025 |
|
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
1026 |
D16 movl $[COM1+DLH], %edx / divisor latch hsb |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
1027 |
D16 movb $B9600H, %al / divisor latch |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
1028 |
outb (%dx) |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
1029 |
|
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
1030 |
D16 movl $[COM1+LCR], %edx / select COM1 |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
1031 |
D16 movb $[STOP1|BITS8], %al / 1 stop bit, 8bit word len |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
1032 |
outb (%dx) |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
1033 |
|
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
1034 |
D16 movl $[COM1+MCR], %edx / select COM1 |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
1035 |
D16 movb $[RTS|DTR], %al / 1 stop bit, 8bit word len |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
1036 |
outb (%dx) |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
1037 |
|
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
1038 |
/ select COM2 |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
1039 |
D16 movl $[COM2+LCR], %edx |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
1040 |
D16 movb $DLAB, %al / divisor latch |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
1041 |
outb (%dx) |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
1042 |
|
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
1043 |
D16 movl $[COM2+DLL], %edx / divisor latch lsb |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
1044 |
D16 movb $B9600L, %al / divisor latch |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
1045 |
outb (%dx) |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
1046 |
|
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
1047 |
D16 movl $[COM2+DLH], %edx / divisor latch hsb |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
1048 |
D16 movb $B9600H, %al / divisor latch |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
1049 |
outb (%dx) |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
1050 |
|
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
1051 |
D16 movl $[COM2+LCR], %edx / select COM1 |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
1052 |
D16 movb $[STOP1|BITS8], %al / 1 stop bit, 8bit word len |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
1053 |
outb (%dx) |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
1054 |
|
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
1055 |
D16 movl $[COM2+MCR], %edx / select COM1 |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
1056 |
D16 movb $[RTS|DTR], %al / 1 stop bit, 8bit word len |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
1057 |
outb (%dx) |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
1058 |
#endif /* DEBUG */ |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
1059 |
|
5295 | 1060 |
D16 ret |
1061 |
||
1062 |
.globl wc_rm_end |
|
1063 |
wc_rm_end: |
|
1064 |
nop |
|
1065 |
||
1066 |
.globl kernel_wc_code |
|
1067 |
kernel_wc_code: |
|
1068 |
/ At this point we are with kernel's cs and proper eip. |
|
1069 |
/ We will be executing not from the copy in real mode platter, |
|
1070 |
/ but from the original code where boot loaded us. |
|
1071 |
/ By this time GDT and IDT are loaded as is cr0, cr3 and cr4. |
|
1072 |
/ %ebx is wc_cpu |
|
1073 |
/ %dx is our ds |
|
1074 |
||
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
1075 |
#if LED |
5295 | 1076 |
D16 movb $0xdb, %al |
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
1077 |
outb $WC_LED |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
1078 |
#endif |
5295 | 1079 |
|
1080 |
/ got here OK |
|
1081 |
||
1082 |
movw %dx, %ds / $KDS_SEL |
|
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
1083 |
|
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
1084 |
#if LED |
5295 | 1085 |
movb $0xdc, %al |
6876
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
1086 |
outb $WC_LED |
f2842fea385a
6701717 com1 and com2 incorrectly initialized during resume
jan
parents:
5817
diff
changeset
|
1087 |
#endif |
5295 | 1088 |
|
5817 | 1089 |
/* |
1090 |
* Before proceeding, enable usage of the page table NX bit if |
|
1091 |
* that's how the page tables are set up. |
|
1092 |
*/ |
|
12838
fca99d9e3f2f
6812663 Running out of bits in x86_feature
Kuriakose Kuruvilla <kuriakose.kuruvilla@oracle.com>
parents:
9989
diff
changeset
|
1093 |
bt $X86FSET_NX, x86_featureset |
fca99d9e3f2f
6812663 Running out of bits in x86_feature
Kuriakose Kuruvilla <kuriakose.kuruvilla@oracle.com>
parents:
9989
diff
changeset
|
1094 |
jnc 1f |
5817 | 1095 |
movl $MSR_AMD_EFER, %ecx |
5295 | 1096 |
rdmsr |
5817 | 1097 |
orl $AMD_EFER_NXE, %eax |
5295 | 1098 |
wrmsr |
5817 | 1099 |
1: |
5295 | 1100 |
|
1101 |
movl WC_CR4(%ebx), %eax / restore full cr4 (with Global Enable) |
|
1102 |
movl %eax, %cr4 |
|
1103 |
||
1104 |
||
1105 |
lldt WC_LDT(%ebx) / $LDT_SEL |
|
1106 |
||
1107 |
movzwl WC_TR(%ebx), %eax / clear TSS busy bit |
|
1108 |
addl WC_GDT+2(%ebx), %eax |
|
1109 |
andl $-1!0x200, 4(%eax) |
|
1110 |
ltr WC_TR(%ebx) / $UTSS_SEL |
|
1111 |
||
9989
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
1112 |
movw WC_SS(%ebx), %ss / restore segment registers |
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
1113 |
movw WC_ES(%ebx), %es |
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
1114 |
movw WC_FS(%ebx), %fs |
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
1115 |
movw WC_GS(%ebx), %gs |
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
1116 |
|
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
1117 |
/* |
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
1118 |
* set the stack pointer to point into the identity mapped page |
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
1119 |
* temporarily, so we can make function calls |
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
1120 |
*/ |
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
1121 |
.globl rm_platter_va |
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
1122 |
movl rm_platter_va, %eax |
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
1123 |
movl $WC_STKSTART, %esp |
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
1124 |
addl %eax, %esp |
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
1125 |
movl %esp, %ebp |
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
1126 |
|
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
1127 |
/* |
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
1128 |
* if we are not running on the boot CPU restore stack contents by |
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
1129 |
* calling i_cpr_restore_stack(curthread, save_stack); |
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
1130 |
*/ |
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
1131 |
call i_cpr_bootcpuid |
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
1132 |
cmpl %eax, WC_CPU_ID(%ebx) |
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
1133 |
je 2f |
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
1134 |
|
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
1135 |
pushl WC_SAVED_STACK(%ebx) |
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
1136 |
pushl %gs:CPU_THREAD |
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
1137 |
call i_cpr_restore_stack |
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
1138 |
addl $0x10, %esp |
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
1139 |
2: |
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
1140 |
|
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
1141 |
movl WC_ESP(%ebx), %esp |
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
1142 |
movl %esp, %ebp |
5295 | 1143 |
|
1144 |
movl WC_RETADDR(%ebx), %eax / return to caller of wc_save_context |
|
1145 |
movl %eax, (%esp) |
|
1146 |
||
1147 |
/* |
|
5817 | 1148 |
* APIC initialization, skip iff function pointer is NULL |
5295 | 1149 |
*/ |
5817 | 1150 |
cmpl $0, ap_mlsetup |
9989
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
1151 |
je 3f |
5817 | 1152 |
call *ap_mlsetup |
9989
33d24b36e077
6814942 auxiliary CPUs needs to have their stacks saved and restored across suspend/resume
Joseph A Townsend <Joseph.Townsend@Sun.COM>
parents:
7362
diff
changeset
|
1153 |
3: |
5295 | 1154 |
|
1155 |
call *cpr_start_cpu_func |
|
1156 |
||
1157 |
pushl WC_EFLAGS(%ebx) / restore flags |
|
1158 |
popfl |
|
1159 |
||
1160 |
movl WC_EDI(%ebx), %edi / restore general registers |
|
1161 |
movl WC_ESI(%ebx), %esi |
|
1162 |
movl WC_EBP(%ebx), %ebp |
|
1163 |
movl WC_EBX(%ebx), %ebx |
|
1164 |
||
1165 |
/exit: jmp exit / stop here for HDT |
|
1166 |
||
1167 |
xorl %eax, %eax / at wakeup return 0 |
|
1168 |
ret |
|
1169 |
||
1170 |
SET_SIZE(wc_rm_start) |
|
1171 |
||
1172 |
||
1173 |
#endif /* defined(__amd64) */ |
|
1174 |
||
1175 |
#endif /* !defined(__GNU_AS__) */ |
|
1176 |
||
1177 |
#endif /* lint */ |
|
1178 |