blob: faea22d6a6fdb80eadf7c381974fa616197f4460 [file] [log] [blame]
Stefan Reinauer5f5436f2010-04-25 20:42:02 +00001#include <cpu/x86/post_code.h>
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +00002
Aaron Durbin633f1122013-02-06 15:28:40 -06003/* Place the stack in the bss section. It's not necessary to define it in the
4 * the linker script. */
5 .section .bss, "aw", @nobits
6.global _stack
7.global _estack
8
9.align CONFIG_STACK_SIZE
10_stack:
11.space CONFIG_MAX_CPUS*CONFIG_STACK_SIZE
12_estack:
Aaron Durbin38c326d2013-05-06 12:22:23 -050013#if CONFIG_COOP_MULTITASKING
14.global thread_stacks
15thread_stacks:
16.space CONFIG_STACK_SIZE*CONFIG_NUM_THREADS
17#endif
Aaron Durbin633f1122013-02-06 15:28:40 -060018
Aaron Durbin01357022013-03-22 20:23:17 -050019 .section ".textfirst", "ax", @progbits
Eric Biederman8ca8d762003-04-22 19:02:15 +000020 .code32
21 .globl _start
Aaron Durbin3eb8eb72014-03-10 16:13:58 -050022 .globl __rmodule_entry
23__rmodule_entry:
Eric Biederman8ca8d762003-04-22 19:02:15 +000024_start:
25 cli
26 lgdt %cs:gdtaddr
27 ljmp $0x10, $1f
281: movl $0x18, %eax
29 movl %eax, %ds
30 movl %eax, %es
31 movl %eax, %ss
32 movl %eax, %fs
33 movl %eax, %gs
34
Alexandru Gagniuc5005bb062011-04-11 20:17:22 +000035 post_code(POST_ENTRY_C_START) /* post 13 */
Eric Biederman8ca8d762003-04-22 19:02:15 +000036
arch import user (historical)6ca76362005-07-06 17:17:25 +000037 cld
Eric Biederman8ca8d762003-04-22 19:02:15 +000038
Aaron Durbin633f1122013-02-06 15:28:40 -060039 /** poison the stack. Code should not count on the
40 * stack being full of zeros. This stack poisoning
41 * recently uncovered a bug in the broadcast SIPI
42 * code.
43 */
44 leal _stack, %edi
45 movl $_estack, %ecx
46 subl %edi, %ecx
47 shrl $2, %ecx /* it is 32 bit aligned, right? */
48 movl $0xDEADBEEF, %eax
49 rep
50 stosl
51
Eric Biederman8ca8d762003-04-22 19:02:15 +000052 /* set new stack */
53 movl $_estack, %esp
Eric Biederman8ca8d762003-04-22 19:02:15 +000054
Aaron Durbin38c326d2013-05-06 12:22:23 -050055#if CONFIG_COOP_MULTITASKING
56 /* Push the thread pointer. */
57 pushl $0
58#endif
Eric Biedermanb78c1972004-10-14 20:54:17 +000059 /* Push the cpu index and struct cpu */
60 pushl $0
61 pushl $0
Eric Biederman8ca8d762003-04-22 19:02:15 +000062
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +000063 /* Initialize the Interrupt Descriptor table */
64 leal _idt, %edi
65 leal vec0, %ebx
66 movl $(0x10 << 16), %eax /* cs selector */
67
681: movw %bx, %ax
69 movl %ebx, %edx
70 movw $0x8E00, %dx /* Interrupt gate - dpl=0, present */
71 movl %eax, 0(%edi)
72 movl %edx, 4(%edi)
73 addl $6, %ebx
74 addl $8, %edi
75 cmpl $_idt_end, %edi
76 jne 1b
77
78 /* Load the Interrupt descriptor table */
79 lidt idtarg
80
Eric Biederman8ca8d762003-04-22 19:02:15 +000081 /*
82 * Now we are finished. Memory is up, data is copied and
83 * bss is cleared. Now we call the main routine and
84 * let it do the rest.
Stefan Reinauer607cdf62010-04-26 12:08:51 +000085 */
Alexandru Gagniuc5005bb062011-04-11 20:17:22 +000086 post_code(POST_PRE_HARDWAREMAIN) /* post fe */
Eric Biederman8ca8d762003-04-22 19:02:15 +000087
Stefan Reinauer8ada1522012-11-16 13:34:48 -080088#if CONFIG_GDB_WAIT
Denis 'GNUtoo' Cariklie4cece02012-06-22 15:56:37 +020089 call gdb_stub_breakpoint
90#endif
Stefan Reinauer6adef082013-05-09 16:30:06 -070091 call main
Stefan Reinauer607cdf62010-04-26 12:08:51 +000092 /* NOTREACHED */
Eric Biederman8ca8d762003-04-22 19:02:15 +000093.Lhlt:
Alexandru Gagniuc5005bb062011-04-11 20:17:22 +000094 post_code(POST_DEAD_CODE) /* post ee */
Eric Biederman8ca8d762003-04-22 19:02:15 +000095 hlt
96 jmp .Lhlt
Stefan Reinauer607cdf62010-04-26 12:08:51 +000097
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +000098vec0:
99 pushl $0 /* error code */
100 pushl $0 /* vector */
101 jmp int_hand
102vec1:
103 pushl $0 /* error code */
104 pushl $1 /* vector */
105 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000106
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000107vec2:
108 pushl $0 /* error code */
109 pushl $2 /* vector */
110 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000111
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000112vec3:
113 pushl $0 /* error code */
114 pushl $3 /* vector */
115 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000116
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000117vec4:
118 pushl $0 /* error code */
119 pushl $4 /* vector */
120 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000121
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000122vec5:
123 pushl $0 /* error code */
124 pushl $5 /* vector */
125 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000126
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000127vec6:
128 pushl $0 /* error code */
129 pushl $6 /* vector */
130 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000131
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000132vec7:
133 pushl $0 /* error code */
134 pushl $7 /* vector */
135 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000136
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000137vec8:
138 /* error code */
139 pushl $8 /* vector */
140 jmp int_hand
141 .word 0x9090
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000142
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000143vec9:
144 pushl $0 /* error code */
145 pushl $9 /* vector */
146 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000147
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000148vec10:
149 /* error code */
150 pushl $10 /* vector */
151 jmp int_hand
152 .word 0x9090
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000153
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000154vec11:
155 /* error code */
156 pushl $11 /* vector */
157 jmp int_hand
158 .word 0x9090
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000159
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000160vec12:
161 /* error code */
162 pushl $12 /* vector */
163 jmp int_hand
164 .word 0x9090
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000165
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000166vec13:
167 /* error code */
168 pushl $13 /* vector */
169 jmp int_hand
170 .word 0x9090
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000171
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000172vec14:
173 /* error code */
174 pushl $14 /* vector */
175 jmp int_hand
176 .word 0x9090
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000177
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000178vec15:
179 pushl $0 /* error code */
180 pushl $15 /* vector */
181 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000182
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000183vec16:
184 pushl $0 /* error code */
185 pushl $16 /* vector */
186 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000187
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000188vec17:
189 /* error code */
190 pushl $17 /* vector */
191 jmp int_hand
192 .word 0x9090
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000193
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000194vec18:
195 pushl $0 /* error code */
196 pushl $18 /* vector */
197 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000198
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000199vec19:
200 pushl $0 /* error code */
201 pushl $19 /* vector */
202 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000203
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000204int_hand:
205 /* At this point on the stack there is:
206 * 0(%esp) vector
207 * 4(%esp) error code
208 * 8(%esp) eip
209 * 12(%esp) cs
210 * 16(%esp) eflags
211 */
212 pushl %edi
213 pushl %esi
214 pushl %ebp
215 /* Original stack pointer */
216 leal 32(%esp), %ebp
217 pushl %ebp
218 pushl %ebx
219 pushl %edx
220 pushl %ecx
221 pushl %eax
Eric Biederman8ca8d762003-04-22 19:02:15 +0000222
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000223 pushl %esp /* Pointer to structure on the stack */
224 call x86_exception
225 pop %eax /* Drop the pointer */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000226
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000227 popl %eax
228 popl %ecx
229 popl %edx
230 popl %ebx
Li-Ta Lof84926e2004-11-04 18:36:06 +0000231 popl %ebp /* Ignore saved %esp value */
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000232 popl %ebp
233 popl %esi
234 popl %edi
235
236 addl $8, %esp /* pop of the vector and error code */
237
238 iret
239
Stefan Reinauer8ada1522012-11-16 13:34:48 -0800240#if CONFIG_GDB_WAIT
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000241
242 .globl gdb_stub_breakpoint
243gdb_stub_breakpoint:
244 popl %eax /* Return address */
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000245 pushfl
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000246 pushl %cs
247 pushl %eax /* Return address */
248 pushl $0 /* No error code */
249 pushl $32 /* vector 32 is user defined */
250 jmp int_hand
251
252#endif
253
Aaron Durbina146d582013-02-08 16:56:51 -0600254 .globl gdt, gdt_end, idtarg
Eric Biederman8ca8d762003-04-22 19:02:15 +0000255
Eric Biederman8ca8d762003-04-22 19:02:15 +0000256gdtaddr:
Aaron Durbina146d582013-02-08 16:56:51 -0600257 .word gdt_end - gdt - 1
Li-Ta Lof84926e2004-11-04 18:36:06 +0000258 .long gdt /* we know the offset */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000259
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000260 .data
Li-Ta Lof84926e2004-11-04 18:36:06 +0000261
Stefan Reinauerf8ee1802008-01-18 15:08:58 +0000262 /* This is the gdt for GCC part of coreboot.
263 * It is different from the gdt in ROMCC/ASM part of coreboot
Stefan Reinauerc0ac7e92009-11-10 22:17:15 +0000264 * which is defined in entry32.inc
265 *
266 * When the machine is initially started, we use a very simple
267 * gdt from rom (that in entry32.inc) which only contains those
268 * entries we need for protected mode.
269 *
270 * When we're executing code from RAM, we want to do more complex
271 * stuff, like initializing PCI option roms in real mode, or doing
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000272 * a resume from a suspend to ram.
Stefan Reinauerc0ac7e92009-11-10 22:17:15 +0000273 */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000274gdt:
Li-Ta Lof84926e2004-11-04 18:36:06 +0000275 /* selgdt 0, unused */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000276 .word 0x0000, 0x0000 /* dummy */
277 .byte 0x00, 0x00, 0x00, 0x00
278
Li-Ta Lof84926e2004-11-04 18:36:06 +0000279 /* selgdt 8, unused */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000280 .word 0x0000, 0x0000 /* dummy */
281 .byte 0x00, 0x00, 0x00, 0x00
282
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000283 /* selgdt 0x10, flat code segment */
284 .word 0xffff, 0x0000
285 .byte 0x00, 0x9b, 0xcf, 0x00 /* G=1 and 0x0f, So we get 4Gbytes for limit */
Li-Ta Lof84926e2004-11-04 18:36:06 +0000286
287 /* selgdt 0x18, flat data segment */
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000288 .word 0xffff, 0x0000
289 .byte 0x00, 0x93, 0xcf, 0x00
Eric Biederman8ca8d762003-04-22 19:02:15 +0000290
Li-Ta Lof84926e2004-11-04 18:36:06 +0000291 /* selgdt 0x20, unused */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000292 .word 0x0000, 0x0000 /* dummy */
293 .byte 0x00, 0x00, 0x00, 0x00
294
Stefan Reinauerc0ac7e92009-11-10 22:17:15 +0000295 /* The next two entries are used for executing VGA option ROMs */
296
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000297 /* selgdt 0x28 16 bit 64k code at 0x00000000 */
Stefan Reinauerf8a5c6e2009-05-29 13:08:27 +0000298 .word 0xffff, 0x0000
299 .byte 0, 0x9a, 0, 0
300
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000301 /* selgdt 0x30 16 bit 64k data at 0x00000000 */
Stefan Reinauerf8a5c6e2009-05-29 13:08:27 +0000302 .word 0xffff, 0x0000
303 .byte 0, 0x92, 0, 0
Stefan Reinauerc0ac7e92009-11-10 22:17:15 +0000304
305 /* The next two entries are used for ACPI S3 RESUME */
306
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000307 /* selgdt 0x38, flat data segment 16 bit */
Stefan Reinauerc0ac7e92009-11-10 22:17:15 +0000308 .word 0x0000, 0x0000 /* dummy */
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000309 .byte 0x00, 0x93, 0x8f, 0x00 /* G=1 and 0x0f, So we get 4Gbytes for limit */
Stefan Reinauerc0ac7e92009-11-10 22:17:15 +0000310
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000311 /* selgdt 0x40, flat code segment 16 bit */
312 .word 0xffff, 0x0000
313 .byte 0x00, 0x9b, 0x8f, 0x00 /* G=1 and 0x0f, So we get 4Gbytes for limit */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000314gdt_end:
315
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000316idtarg:
317 .word _idt_end - _idt - 1 /* limit */
318 .long _idt
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000319 .word 0
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000320_idt:
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000321 .fill 20, 8, 0 # idt is uninitialized
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000322_idt_end:
323
324 .previous
Eric Biederman8ca8d762003-04-22 19:02:15 +0000325.code32