blob: dbed12377e63bf6f106950d5a808d50efbb3138f [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
Julius Wernerec5e5e02014-08-20 15:29:56 -070019 .section ".text._start", "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
Kyösti Mälkkif2f7f032014-04-04 15:05:28 +030089 call gdb_hw_init
Denis 'GNUtoo' Cariklie4cece02012-06-22 15:56:37 +020090 call gdb_stub_breakpoint
91#endif
Stefan Reinauer6adef082013-05-09 16:30:06 -070092 call main
Stefan Reinauer607cdf62010-04-26 12:08:51 +000093 /* NOTREACHED */
Eric Biederman8ca8d762003-04-22 19:02:15 +000094.Lhlt:
Alexandru Gagniuc5005bb062011-04-11 20:17:22 +000095 post_code(POST_DEAD_CODE) /* post ee */
Eric Biederman8ca8d762003-04-22 19:02:15 +000096 hlt
97 jmp .Lhlt
Stefan Reinauer607cdf62010-04-26 12:08:51 +000098
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +000099vec0:
100 pushl $0 /* error code */
101 pushl $0 /* vector */
102 jmp int_hand
103vec1:
104 pushl $0 /* error code */
105 pushl $1 /* vector */
106 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000107
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000108vec2:
109 pushl $0 /* error code */
110 pushl $2 /* vector */
111 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000112
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000113vec3:
114 pushl $0 /* error code */
115 pushl $3 /* vector */
116 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000117
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000118vec4:
119 pushl $0 /* error code */
120 pushl $4 /* vector */
121 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000122
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000123vec5:
124 pushl $0 /* error code */
125 pushl $5 /* vector */
126 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000127
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000128vec6:
129 pushl $0 /* error code */
130 pushl $6 /* vector */
131 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000132
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000133vec7:
134 pushl $0 /* error code */
135 pushl $7 /* vector */
136 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000137
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000138vec8:
139 /* error code */
140 pushl $8 /* vector */
141 jmp int_hand
142 .word 0x9090
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000143
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000144vec9:
145 pushl $0 /* error code */
146 pushl $9 /* vector */
147 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000148
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000149vec10:
150 /* error code */
151 pushl $10 /* vector */
152 jmp int_hand
153 .word 0x9090
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000154
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000155vec11:
156 /* error code */
157 pushl $11 /* vector */
158 jmp int_hand
159 .word 0x9090
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000160
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000161vec12:
162 /* error code */
163 pushl $12 /* vector */
164 jmp int_hand
165 .word 0x9090
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000166
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000167vec13:
168 /* error code */
169 pushl $13 /* vector */
170 jmp int_hand
171 .word 0x9090
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000172
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000173vec14:
174 /* error code */
175 pushl $14 /* vector */
176 jmp int_hand
177 .word 0x9090
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000178
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000179vec15:
180 pushl $0 /* error code */
181 pushl $15 /* vector */
182 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000183
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000184vec16:
185 pushl $0 /* error code */
186 pushl $16 /* vector */
187 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000188
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000189vec17:
190 /* error code */
191 pushl $17 /* vector */
192 jmp int_hand
193 .word 0x9090
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000194
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000195vec18:
196 pushl $0 /* error code */
197 pushl $18 /* vector */
198 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000199
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000200vec19:
201 pushl $0 /* error code */
202 pushl $19 /* vector */
203 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000204
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000205int_hand:
206 /* At this point on the stack there is:
207 * 0(%esp) vector
208 * 4(%esp) error code
209 * 8(%esp) eip
210 * 12(%esp) cs
211 * 16(%esp) eflags
212 */
213 pushl %edi
214 pushl %esi
215 pushl %ebp
216 /* Original stack pointer */
217 leal 32(%esp), %ebp
218 pushl %ebp
219 pushl %ebx
220 pushl %edx
221 pushl %ecx
222 pushl %eax
Eric Biederman8ca8d762003-04-22 19:02:15 +0000223
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000224 pushl %esp /* Pointer to structure on the stack */
225 call x86_exception
226 pop %eax /* Drop the pointer */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000227
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000228 popl %eax
229 popl %ecx
230 popl %edx
231 popl %ebx
Li-Ta Lof84926e2004-11-04 18:36:06 +0000232 popl %ebp /* Ignore saved %esp value */
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000233 popl %ebp
234 popl %esi
235 popl %edi
236
237 addl $8, %esp /* pop of the vector and error code */
238
239 iret
240
Stefan Reinauer8ada1522012-11-16 13:34:48 -0800241#if CONFIG_GDB_WAIT
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000242
243 .globl gdb_stub_breakpoint
244gdb_stub_breakpoint:
245 popl %eax /* Return address */
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000246 pushfl
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000247 pushl %cs
248 pushl %eax /* Return address */
249 pushl $0 /* No error code */
250 pushl $32 /* vector 32 is user defined */
251 jmp int_hand
252
253#endif
254
Aaron Durbina146d582013-02-08 16:56:51 -0600255 .globl gdt, gdt_end, idtarg
Eric Biederman8ca8d762003-04-22 19:02:15 +0000256
Eric Biederman8ca8d762003-04-22 19:02:15 +0000257gdtaddr:
Aaron Durbina146d582013-02-08 16:56:51 -0600258 .word gdt_end - gdt - 1
Li-Ta Lof84926e2004-11-04 18:36:06 +0000259 .long gdt /* we know the offset */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000260
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000261 .data
Li-Ta Lof84926e2004-11-04 18:36:06 +0000262
Stefan Reinauerf8ee1802008-01-18 15:08:58 +0000263 /* This is the gdt for GCC part of coreboot.
264 * It is different from the gdt in ROMCC/ASM part of coreboot
Stefan Reinauerc0ac7e92009-11-10 22:17:15 +0000265 * which is defined in entry32.inc
266 *
267 * When the machine is initially started, we use a very simple
268 * gdt from rom (that in entry32.inc) which only contains those
269 * entries we need for protected mode.
270 *
271 * When we're executing code from RAM, we want to do more complex
272 * stuff, like initializing PCI option roms in real mode, or doing
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000273 * a resume from a suspend to ram.
Stefan Reinauerc0ac7e92009-11-10 22:17:15 +0000274 */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000275gdt:
Li-Ta Lof84926e2004-11-04 18:36:06 +0000276 /* selgdt 0, unused */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000277 .word 0x0000, 0x0000 /* dummy */
278 .byte 0x00, 0x00, 0x00, 0x00
279
Li-Ta Lof84926e2004-11-04 18:36:06 +0000280 /* selgdt 8, unused */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000281 .word 0x0000, 0x0000 /* dummy */
282 .byte 0x00, 0x00, 0x00, 0x00
283
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000284 /* selgdt 0x10, flat code segment */
285 .word 0xffff, 0x0000
286 .byte 0x00, 0x9b, 0xcf, 0x00 /* G=1 and 0x0f, So we get 4Gbytes for limit */
Li-Ta Lof84926e2004-11-04 18:36:06 +0000287
288 /* selgdt 0x18, flat data segment */
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000289 .word 0xffff, 0x0000
290 .byte 0x00, 0x93, 0xcf, 0x00
Eric Biederman8ca8d762003-04-22 19:02:15 +0000291
Li-Ta Lof84926e2004-11-04 18:36:06 +0000292 /* selgdt 0x20, unused */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000293 .word 0x0000, 0x0000 /* dummy */
294 .byte 0x00, 0x00, 0x00, 0x00
295
Stefan Reinauerc0ac7e92009-11-10 22:17:15 +0000296 /* The next two entries are used for executing VGA option ROMs */
297
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000298 /* selgdt 0x28 16 bit 64k code at 0x00000000 */
Stefan Reinauerf8a5c6e2009-05-29 13:08:27 +0000299 .word 0xffff, 0x0000
300 .byte 0, 0x9a, 0, 0
301
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000302 /* selgdt 0x30 16 bit 64k data at 0x00000000 */
Stefan Reinauerf8a5c6e2009-05-29 13:08:27 +0000303 .word 0xffff, 0x0000
304 .byte 0, 0x92, 0, 0
Stefan Reinauerc0ac7e92009-11-10 22:17:15 +0000305
306 /* The next two entries are used for ACPI S3 RESUME */
307
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000308 /* selgdt 0x38, flat data segment 16 bit */
Stefan Reinauerc0ac7e92009-11-10 22:17:15 +0000309 .word 0x0000, 0x0000 /* dummy */
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000310 .byte 0x00, 0x93, 0x8f, 0x00 /* G=1 and 0x0f, So we get 4Gbytes for limit */
Stefan Reinauerc0ac7e92009-11-10 22:17:15 +0000311
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000312 /* selgdt 0x40, flat code segment 16 bit */
313 .word 0xffff, 0x0000
314 .byte 0x00, 0x9b, 0x8f, 0x00 /* G=1 and 0x0f, So we get 4Gbytes for limit */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000315gdt_end:
316
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000317idtarg:
318 .word _idt_end - _idt - 1 /* limit */
319 .long _idt
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000320 .word 0
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000321_idt:
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000322 .fill 20, 8, 0 # idt is uninitialized
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000323_idt_end:
324
325 .previous
Eric Biederman8ca8d762003-04-22 19:02:15 +0000326.code32