blob: 124bfa84bf034a2d8b6a5d660b8e4285cb8e73af [file] [log] [blame]
Martin Roth9df9e9392016-01-12 15:55:28 -07001/*
2 * This file is part of the coreboot project.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
Stefan Reinauer5f5436f2010-04-25 20:42:02 +000014#include <cpu/x86/post_code.h>
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +000015
Aaron Durbin633f1122013-02-06 15:28:40 -060016/* Place the stack in the bss section. It's not necessary to define it in the
17 * the linker script. */
18 .section .bss, "aw", @nobits
19.global _stack
20.global _estack
21
22.align CONFIG_STACK_SIZE
23_stack:
24.space CONFIG_MAX_CPUS*CONFIG_STACK_SIZE
25_estack:
Aaron Durbin38c326d2013-05-06 12:22:23 -050026#if CONFIG_COOP_MULTITASKING
27.global thread_stacks
28thread_stacks:
29.space CONFIG_STACK_SIZE*CONFIG_NUM_THREADS
30#endif
Aaron Durbin633f1122013-02-06 15:28:40 -060031
Julius Wernerec5e5e02014-08-20 15:29:56 -070032 .section ".text._start", "ax", @progbits
Stefan Reinauer96938852015-06-18 01:23:48 -070033#ifdef __x86_64__
34 .code64
35#else
Eric Biederman8ca8d762003-04-22 19:02:15 +000036 .code32
Stefan Reinauer96938852015-06-18 01:23:48 -070037#endif
Eric Biederman8ca8d762003-04-22 19:02:15 +000038 .globl _start
39_start:
40 cli
41 lgdt %cs:gdtaddr
Stefan Reinauer96938852015-06-18 01:23:48 -070042#ifndef __x86_64__
Eric Biederman8ca8d762003-04-22 19:02:15 +000043 ljmp $0x10, $1f
Stefan Reinauer96938852015-06-18 01:23:48 -070044#endif
Eric Biederman8ca8d762003-04-22 19:02:15 +0000451: movl $0x18, %eax
46 movl %eax, %ds
47 movl %eax, %es
48 movl %eax, %ss
49 movl %eax, %fs
50 movl %eax, %gs
Stefan Reinauer96938852015-06-18 01:23:48 -070051#ifdef __x86_64__
52 mov $0x48, %ecx
53 call SetCodeSelector
54#endif
Eric Biederman8ca8d762003-04-22 19:02:15 +000055
Alexandru Gagniuc5005bb062011-04-11 20:17:22 +000056 post_code(POST_ENTRY_C_START) /* post 13 */
Eric Biederman8ca8d762003-04-22 19:02:15 +000057
arch import user (historical)6ca76362005-07-06 17:17:25 +000058 cld
Eric Biederman8ca8d762003-04-22 19:02:15 +000059
Aaron Durbin633f1122013-02-06 15:28:40 -060060 /** poison the stack. Code should not count on the
61 * stack being full of zeros. This stack poisoning
62 * recently uncovered a bug in the broadcast SIPI
63 * code.
64 */
65 leal _stack, %edi
66 movl $_estack, %ecx
67 subl %edi, %ecx
68 shrl $2, %ecx /* it is 32 bit aligned, right? */
69 movl $0xDEADBEEF, %eax
70 rep
71 stosl
72
Eric Biederman8ca8d762003-04-22 19:02:15 +000073 /* set new stack */
74 movl $_estack, %esp
Eric Biederman8ca8d762003-04-22 19:02:15 +000075
Aaron Durbin38c326d2013-05-06 12:22:23 -050076#if CONFIG_COOP_MULTITASKING
77 /* Push the thread pointer. */
Stefan Reinauer96938852015-06-18 01:23:48 -070078 push $0
Aaron Durbin38c326d2013-05-06 12:22:23 -050079#endif
Eric Biedermanb78c1972004-10-14 20:54:17 +000080 /* Push the cpu index and struct cpu */
Stefan Reinauer96938852015-06-18 01:23:48 -070081 push $0
82 push $0
Eric Biederman8ca8d762003-04-22 19:02:15 +000083
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +000084 /* Initialize the Interrupt Descriptor table */
85 leal _idt, %edi
86 leal vec0, %ebx
87 movl $(0x10 << 16), %eax /* cs selector */
88
891: movw %bx, %ax
90 movl %ebx, %edx
91 movw $0x8E00, %dx /* Interrupt gate - dpl=0, present */
92 movl %eax, 0(%edi)
93 movl %edx, 4(%edi)
94 addl $6, %ebx
95 addl $8, %edi
96 cmpl $_idt_end, %edi
97 jne 1b
98
99 /* Load the Interrupt descriptor table */
Stefan Reinauer96938852015-06-18 01:23:48 -0700100#ifndef __x86_64__
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000101 lidt idtarg
Stefan Reinauer96938852015-06-18 01:23:48 -0700102#else
103 // FIXME port table to x64 - lidt idtarg
104#endif
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000105
Eric Biederman8ca8d762003-04-22 19:02:15 +0000106 /*
107 * Now we are finished. Memory is up, data is copied and
108 * bss is cleared. Now we call the main routine and
109 * let it do the rest.
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000110 */
Alexandru Gagniuc5005bb062011-04-11 20:17:22 +0000111 post_code(POST_PRE_HARDWAREMAIN) /* post fe */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000112
Stefan Reinauer8ada1522012-11-16 13:34:48 -0800113#if CONFIG_GDB_WAIT
Kyösti Mälkkif2f7f032014-04-04 15:05:28 +0300114 call gdb_hw_init
Denis 'GNUtoo' Cariklie4cece02012-06-22 15:56:37 +0200115 call gdb_stub_breakpoint
116#endif
Stefan Reinauer6adef082013-05-09 16:30:06 -0700117 call main
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000118 /* NOTREACHED */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000119.Lhlt:
Alexandru Gagniuc5005bb062011-04-11 20:17:22 +0000120 post_code(POST_DEAD_CODE) /* post ee */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000121 hlt
122 jmp .Lhlt
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000123
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000124vec0:
Stefan Reinauer96938852015-06-18 01:23:48 -0700125 push $0 /* error code */
126 push $0 /* vector */
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000127 jmp int_hand
128vec1:
Stefan Reinauer96938852015-06-18 01:23:48 -0700129 push $0 /* error code */
130 push $1 /* vector */
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000131 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000132
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000133vec2:
Stefan Reinauer96938852015-06-18 01:23:48 -0700134 push $0 /* error code */
135 push $2 /* vector */
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000136 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000137
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000138vec3:
Stefan Reinauer96938852015-06-18 01:23:48 -0700139 push $0 /* error code */
140 push $3 /* vector */
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000141 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000142
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000143vec4:
Stefan Reinauer96938852015-06-18 01:23:48 -0700144 push $0 /* error code */
145 push $4 /* vector */
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000146 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000147
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000148vec5:
Stefan Reinauer96938852015-06-18 01:23:48 -0700149 push $0 /* error code */
150 push $5 /* vector */
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000151 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000152
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000153vec6:
Stefan Reinauer96938852015-06-18 01:23:48 -0700154 push $0 /* error code */
155 push $6 /* vector */
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000156 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000157
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000158vec7:
Stefan Reinauer96938852015-06-18 01:23:48 -0700159 push $0 /* error code */
160 push $7 /* vector */
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000161 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000162
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000163vec8:
164 /* error code */
Stefan Reinauer96938852015-06-18 01:23:48 -0700165 push $8 /* vector */
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000166 jmp int_hand
167 .word 0x9090
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000168
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000169vec9:
Stefan Reinauer96938852015-06-18 01:23:48 -0700170 push $0 /* error code */
171 push $9 /* vector */
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000172 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000173
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000174vec10:
175 /* error code */
Stefan Reinauer96938852015-06-18 01:23:48 -0700176 push $10 /* vector */
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000177 jmp int_hand
178 .word 0x9090
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000179
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000180vec11:
181 /* error code */
Stefan Reinauer96938852015-06-18 01:23:48 -0700182 push $11 /* vector */
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000183 jmp int_hand
184 .word 0x9090
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000185
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000186vec12:
187 /* error code */
Stefan Reinauer96938852015-06-18 01:23:48 -0700188 push $12 /* vector */
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000189 jmp int_hand
190 .word 0x9090
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000191
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000192vec13:
193 /* error code */
Stefan Reinauer96938852015-06-18 01:23:48 -0700194 push $13 /* vector */
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000195 jmp int_hand
196 .word 0x9090
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000197
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000198vec14:
199 /* error code */
Stefan Reinauer96938852015-06-18 01:23:48 -0700200 push $14 /* vector */
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000201 jmp int_hand
202 .word 0x9090
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000203
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000204vec15:
Stefan Reinauer96938852015-06-18 01:23:48 -0700205 push $0 /* error code */
206 push $15 /* vector */
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000207 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000208
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000209vec16:
Stefan Reinauer96938852015-06-18 01:23:48 -0700210 push $0 /* error code */
211 push $16 /* vector */
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000212 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000213
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000214vec17:
215 /* error code */
Stefan Reinauer96938852015-06-18 01:23:48 -0700216 push $17 /* vector */
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000217 jmp int_hand
218 .word 0x9090
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000219
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000220vec18:
Stefan Reinauer96938852015-06-18 01:23:48 -0700221 push $0 /* error code */
222 push $18 /* vector */
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000223 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000224
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000225vec19:
Stefan Reinauer96938852015-06-18 01:23:48 -0700226 push $0 /* error code */
227 push $19 /* vector */
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000228 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000229
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000230int_hand:
Stefan Reinauer96938852015-06-18 01:23:48 -0700231 /* At this point, on x86-32, on the stack there is:
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000232 * 0(%esp) vector
233 * 4(%esp) error code
234 * 8(%esp) eip
235 * 12(%esp) cs
236 * 16(%esp) eflags
237 */
Stefan Reinauer96938852015-06-18 01:23:48 -0700238#ifdef __x86_64__
239 push %rdi
240 push %rsi
241 push %rbp
242 /* Original stack pointer */
243 lea 32(%rsp), %rbp
244 push %rbp
245 push %rbx
246 push %rdx
247 push %rcx
248 push %rax
249
250 push %rsp /* Pointer to structure on the stack */
251 call x86_exception
252 pop %rax /* Drop the pointer */
253
254 pop %rax
255 pop %rcx
256 pop %rdx
257 pop %rbx
258 pop %rbp /* Ignore saved %rsp value */
259 pop %rbp
260 pop %rsi
261 pop %rdi
262
263 add $8, %rsp /* pop of the vector and error code */
264#else
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000265 pushl %edi
266 pushl %esi
267 pushl %ebp
Stefan Reinauer96938852015-06-18 01:23:48 -0700268
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000269 /* Original stack pointer */
270 leal 32(%esp), %ebp
271 pushl %ebp
272 pushl %ebx
273 pushl %edx
274 pushl %ecx
275 pushl %eax
Eric Biederman8ca8d762003-04-22 19:02:15 +0000276
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000277 pushl %esp /* Pointer to structure on the stack */
278 call x86_exception
279 pop %eax /* Drop the pointer */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000280
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000281 popl %eax
282 popl %ecx
283 popl %edx
284 popl %ebx
Li-Ta Lof84926e2004-11-04 18:36:06 +0000285 popl %ebp /* Ignore saved %esp value */
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000286 popl %ebp
287 popl %esi
288 popl %edi
289
290 addl $8, %esp /* pop of the vector and error code */
Stefan Reinauer96938852015-06-18 01:23:48 -0700291#endif
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000292
293 iret
294
Stefan Reinauer8ada1522012-11-16 13:34:48 -0800295#if CONFIG_GDB_WAIT
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000296
297 .globl gdb_stub_breakpoint
298gdb_stub_breakpoint:
Stefan Reinauer96938852015-06-18 01:23:48 -0700299#ifdef __x86_64__
300 pop %rax /* Return address */
301 pushfl
302 push %cs
303 push %rax /* Return address */
304 push $0 /* No error code */
305 push $32 /* vector 32 is user defined */
306#else
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000307 popl %eax /* Return address */
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000308 pushfl
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000309 pushl %cs
310 pushl %eax /* Return address */
311 pushl $0 /* No error code */
312 pushl $32 /* vector 32 is user defined */
Stefan Reinauer96938852015-06-18 01:23:48 -0700313#endif
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000314 jmp int_hand
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000315#endif
316
Aaron Durbina146d582013-02-08 16:56:51 -0600317 .globl gdt, gdt_end, idtarg
Eric Biederman8ca8d762003-04-22 19:02:15 +0000318
Eric Biederman8ca8d762003-04-22 19:02:15 +0000319gdtaddr:
Aaron Durbina146d582013-02-08 16:56:51 -0600320 .word gdt_end - gdt - 1
Stefan Reinauer96938852015-06-18 01:23:48 -0700321#ifdef __x86_64__
322 .quad gdt
323#else
Li-Ta Lof84926e2004-11-04 18:36:06 +0000324 .long gdt /* we know the offset */
Stefan Reinauer96938852015-06-18 01:23:48 -0700325#endif
Eric Biederman8ca8d762003-04-22 19:02:15 +0000326
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000327 .data
Li-Ta Lof84926e2004-11-04 18:36:06 +0000328
Stefan Reinauerf8ee1802008-01-18 15:08:58 +0000329 /* This is the gdt for GCC part of coreboot.
330 * It is different from the gdt in ROMCC/ASM part of coreboot
Stefan Reinauerc0ac7e92009-11-10 22:17:15 +0000331 * which is defined in entry32.inc
332 *
333 * When the machine is initially started, we use a very simple
334 * gdt from rom (that in entry32.inc) which only contains those
335 * entries we need for protected mode.
336 *
337 * When we're executing code from RAM, we want to do more complex
338 * stuff, like initializing PCI option roms in real mode, or doing
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000339 * a resume from a suspend to ram.
Stefan Reinauerc0ac7e92009-11-10 22:17:15 +0000340 */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000341gdt:
Li-Ta Lof84926e2004-11-04 18:36:06 +0000342 /* selgdt 0, unused */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000343 .word 0x0000, 0x0000 /* dummy */
344 .byte 0x00, 0x00, 0x00, 0x00
345
Li-Ta Lof84926e2004-11-04 18:36:06 +0000346 /* selgdt 8, unused */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000347 .word 0x0000, 0x0000 /* dummy */
348 .byte 0x00, 0x00, 0x00, 0x00
349
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000350 /* selgdt 0x10, flat code segment */
351 .word 0xffff, 0x0000
352 .byte 0x00, 0x9b, 0xcf, 0x00 /* G=1 and 0x0f, So we get 4Gbytes for limit */
Li-Ta Lof84926e2004-11-04 18:36:06 +0000353
354 /* selgdt 0x18, flat data segment */
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000355 .word 0xffff, 0x0000
Stefan Reinauer96938852015-06-18 01:23:48 -0700356#ifdef __x86_64__
357 .byte 0x00, 0x92, 0xcf, 0x00
358#else
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000359 .byte 0x00, 0x93, 0xcf, 0x00
Stefan Reinauer96938852015-06-18 01:23:48 -0700360#endif
Eric Biederman8ca8d762003-04-22 19:02:15 +0000361
Li-Ta Lof84926e2004-11-04 18:36:06 +0000362 /* selgdt 0x20, unused */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000363 .word 0x0000, 0x0000 /* dummy */
364 .byte 0x00, 0x00, 0x00, 0x00
365
Stefan Reinauerc0ac7e92009-11-10 22:17:15 +0000366 /* The next two entries are used for executing VGA option ROMs */
367
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000368 /* selgdt 0x28 16 bit 64k code at 0x00000000 */
Stefan Reinauerf8a5c6e2009-05-29 13:08:27 +0000369 .word 0xffff, 0x0000
370 .byte 0, 0x9a, 0, 0
371
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000372 /* selgdt 0x30 16 bit 64k data at 0x00000000 */
Stefan Reinauerf8a5c6e2009-05-29 13:08:27 +0000373 .word 0xffff, 0x0000
374 .byte 0, 0x92, 0, 0
Stefan Reinauerc0ac7e92009-11-10 22:17:15 +0000375
376 /* The next two entries are used for ACPI S3 RESUME */
377
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000378 /* selgdt 0x38, flat data segment 16 bit */
Stefan Reinauerc0ac7e92009-11-10 22:17:15 +0000379 .word 0x0000, 0x0000 /* dummy */
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000380 .byte 0x00, 0x93, 0x8f, 0x00 /* G=1 and 0x0f, So we get 4Gbytes for limit */
Stefan Reinauerc0ac7e92009-11-10 22:17:15 +0000381
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000382 /* selgdt 0x40, flat code segment 16 bit */
383 .word 0xffff, 0x0000
384 .byte 0x00, 0x9b, 0x8f, 0x00 /* G=1 and 0x0f, So we get 4Gbytes for limit */
Stefan Reinauer96938852015-06-18 01:23:48 -0700385
386#ifdef __x86_64__
387 /* selgdt 0x48, flat x64 code segment */
388 .word 0xffff, 0x0000
389 .byte 0x00, 0x9b, 0xaf, 0x00
390#endif
Eric Biederman8ca8d762003-04-22 19:02:15 +0000391gdt_end:
392
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000393idtarg:
394 .word _idt_end - _idt - 1 /* limit */
395 .long _idt
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000396 .word 0
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000397_idt:
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000398 .fill 20, 8, 0 # idt is uninitialized
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000399_idt_end:
400
Stefan Reinauer96938852015-06-18 01:23:48 -0700401#ifdef __x86_64__
402SetCodeSelector:
403.intel_syntax noprefix
404
Martin Rothe3690102016-01-06 15:21:02 -0700405 # save rsp because iret will align it to a 16 byte boundary
406 mov rdx, rsp
Stefan Reinauer96938852015-06-18 01:23:48 -0700407
Martin Rothe3690102016-01-06 15:21:02 -0700408 # use iret to jump to a 64-bit offset in a new code segment
409 # iret will pop cs:rip, flags, then ss:rsp
410 mov ax, ss # need to push ss..
411 push rax # push ss instuction not valid in x64 mode, so use ax
412 push rsp
413 pushfq
414 push rcx # cx is code segment selector from caller
415 mov rax, offset setCodeSelectorLongJump
416 push rax
Stefan Reinauer96938852015-06-18 01:23:48 -0700417
Martin Rothe3690102016-01-06 15:21:02 -0700418 # the iret will continue at next instruction, with the new cs value loaded
419 iretq
Stefan Reinauer96938852015-06-18 01:23:48 -0700420
421setCodeSelectorLongJump:
Martin Rothe3690102016-01-06 15:21:02 -0700422 # restore rsp, it might not have been 16-byte aligned on entry
423 mov rsp, rdx
424 ret
Stefan Reinauer96938852015-06-18 01:23:48 -0700425.att_syntax prefix
426
427 .previous
428.code64
429#else
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000430 .previous
Eric Biederman8ca8d762003-04-22 19:02:15 +0000431.code32
Stefan Reinauer96938852015-06-18 01:23:48 -0700432#endif