blob: 1e38acaf021c1818b2319c39870988a6784cb166 [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:
13
Aaron Durbin01357022013-03-22 20:23:17 -050014 .section ".textfirst", "ax", @progbits
Eric Biederman8ca8d762003-04-22 19:02:15 +000015 .code32
16 .globl _start
17_start:
18 cli
19 lgdt %cs:gdtaddr
20 ljmp $0x10, $1f
211: movl $0x18, %eax
22 movl %eax, %ds
23 movl %eax, %es
24 movl %eax, %ss
25 movl %eax, %fs
26 movl %eax, %gs
27
Alexandru Gagniuc5005bb062011-04-11 20:17:22 +000028 post_code(POST_ENTRY_C_START) /* post 13 */
Eric Biederman8ca8d762003-04-22 19:02:15 +000029
arch import user (historical)6ca76362005-07-06 17:17:25 +000030 cld
Eric Biederman8ca8d762003-04-22 19:02:15 +000031
Aaron Durbin633f1122013-02-06 15:28:40 -060032 /** poison the stack. Code should not count on the
33 * stack being full of zeros. This stack poisoning
34 * recently uncovered a bug in the broadcast SIPI
35 * code.
36 */
37 leal _stack, %edi
38 movl $_estack, %ecx
39 subl %edi, %ecx
40 shrl $2, %ecx /* it is 32 bit aligned, right? */
41 movl $0xDEADBEEF, %eax
42 rep
43 stosl
44
Eric Biederman8ca8d762003-04-22 19:02:15 +000045 /* set new stack */
46 movl $_estack, %esp
Eric Biederman8ca8d762003-04-22 19:02:15 +000047
Eric Biedermanb78c1972004-10-14 20:54:17 +000048 /* Push the cpu index and struct cpu */
49 pushl $0
50 pushl $0
Eric Biederman8ca8d762003-04-22 19:02:15 +000051
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +000052 /* Initialize the Interrupt Descriptor table */
53 leal _idt, %edi
54 leal vec0, %ebx
55 movl $(0x10 << 16), %eax /* cs selector */
56
571: movw %bx, %ax
58 movl %ebx, %edx
59 movw $0x8E00, %dx /* Interrupt gate - dpl=0, present */
60 movl %eax, 0(%edi)
61 movl %edx, 4(%edi)
62 addl $6, %ebx
63 addl $8, %edi
64 cmpl $_idt_end, %edi
65 jne 1b
66
67 /* Load the Interrupt descriptor table */
68 lidt idtarg
69
Eric Biederman8ca8d762003-04-22 19:02:15 +000070 /*
71 * Now we are finished. Memory is up, data is copied and
72 * bss is cleared. Now we call the main routine and
73 * let it do the rest.
Stefan Reinauer607cdf62010-04-26 12:08:51 +000074 */
Alexandru Gagniuc5005bb062011-04-11 20:17:22 +000075 post_code(POST_PRE_HARDWAREMAIN) /* post fe */
Eric Biederman8ca8d762003-04-22 19:02:15 +000076
Stefan Reinauer8ada1522012-11-16 13:34:48 -080077#if CONFIG_GDB_WAIT
Denis 'GNUtoo' Cariklie4cece02012-06-22 15:56:37 +020078 call gdb_stub_breakpoint
79#endif
Eric Biedermanae948f72003-07-14 20:40:38 +000080 call hardwaremain
Stefan Reinauer607cdf62010-04-26 12:08:51 +000081 /* NOTREACHED */
Eric Biederman8ca8d762003-04-22 19:02:15 +000082.Lhlt:
Alexandru Gagniuc5005bb062011-04-11 20:17:22 +000083 post_code(POST_DEAD_CODE) /* post ee */
Eric Biederman8ca8d762003-04-22 19:02:15 +000084 hlt
85 jmp .Lhlt
Stefan Reinauer607cdf62010-04-26 12:08:51 +000086
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +000087vec0:
88 pushl $0 /* error code */
89 pushl $0 /* vector */
90 jmp int_hand
91vec1:
92 pushl $0 /* error code */
93 pushl $1 /* vector */
94 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +000095
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +000096vec2:
97 pushl $0 /* error code */
98 pushl $2 /* vector */
99 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000100
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000101vec3:
102 pushl $0 /* error code */
103 pushl $3 /* vector */
104 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000105
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000106vec4:
107 pushl $0 /* error code */
108 pushl $4 /* vector */
109 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000110
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000111vec5:
112 pushl $0 /* error code */
113 pushl $5 /* vector */
114 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000115
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000116vec6:
117 pushl $0 /* error code */
118 pushl $6 /* vector */
119 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000120
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000121vec7:
122 pushl $0 /* error code */
123 pushl $7 /* vector */
124 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000125
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000126vec8:
127 /* error code */
128 pushl $8 /* vector */
129 jmp int_hand
130 .word 0x9090
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000131
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000132vec9:
133 pushl $0 /* error code */
134 pushl $9 /* vector */
135 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000136
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000137vec10:
138 /* error code */
139 pushl $10 /* vector */
140 jmp int_hand
141 .word 0x9090
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000142
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000143vec11:
144 /* error code */
145 pushl $11 /* vector */
146 jmp int_hand
147 .word 0x9090
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000148
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000149vec12:
150 /* error code */
151 pushl $12 /* vector */
152 jmp int_hand
153 .word 0x9090
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000154
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000155vec13:
156 /* error code */
157 pushl $13 /* vector */
158 jmp int_hand
159 .word 0x9090
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000160
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000161vec14:
162 /* error code */
163 pushl $14 /* vector */
164 jmp int_hand
165 .word 0x9090
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000166
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000167vec15:
168 pushl $0 /* error code */
169 pushl $15 /* vector */
170 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000171
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000172vec16:
173 pushl $0 /* error code */
174 pushl $16 /* vector */
175 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000176
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000177vec17:
178 /* error code */
179 pushl $17 /* vector */
180 jmp int_hand
181 .word 0x9090
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000182
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000183vec18:
184 pushl $0 /* error code */
185 pushl $18 /* vector */
186 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000187
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000188vec19:
189 pushl $0 /* error code */
190 pushl $19 /* vector */
191 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000192
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000193int_hand:
194 /* At this point on the stack there is:
195 * 0(%esp) vector
196 * 4(%esp) error code
197 * 8(%esp) eip
198 * 12(%esp) cs
199 * 16(%esp) eflags
200 */
201 pushl %edi
202 pushl %esi
203 pushl %ebp
204 /* Original stack pointer */
205 leal 32(%esp), %ebp
206 pushl %ebp
207 pushl %ebx
208 pushl %edx
209 pushl %ecx
210 pushl %eax
Eric Biederman8ca8d762003-04-22 19:02:15 +0000211
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000212 pushl %esp /* Pointer to structure on the stack */
213 call x86_exception
214 pop %eax /* Drop the pointer */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000215
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000216 popl %eax
217 popl %ecx
218 popl %edx
219 popl %ebx
Li-Ta Lof84926e2004-11-04 18:36:06 +0000220 popl %ebp /* Ignore saved %esp value */
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000221 popl %ebp
222 popl %esi
223 popl %edi
224
225 addl $8, %esp /* pop of the vector and error code */
226
227 iret
228
Stefan Reinauer8ada1522012-11-16 13:34:48 -0800229#if CONFIG_GDB_WAIT
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000230
231 .globl gdb_stub_breakpoint
232gdb_stub_breakpoint:
233 popl %eax /* Return address */
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000234 pushfl
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000235 pushl %cs
236 pushl %eax /* Return address */
237 pushl $0 /* No error code */
238 pushl $32 /* vector 32 is user defined */
239 jmp int_hand
240
241#endif
242
Aaron Durbina146d582013-02-08 16:56:51 -0600243 .globl gdt, gdt_end, idtarg
Eric Biederman8ca8d762003-04-22 19:02:15 +0000244
Eric Biederman8ca8d762003-04-22 19:02:15 +0000245gdtaddr:
Aaron Durbina146d582013-02-08 16:56:51 -0600246 .word gdt_end - gdt - 1
Li-Ta Lof84926e2004-11-04 18:36:06 +0000247 .long gdt /* we know the offset */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000248
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000249 .data
Li-Ta Lof84926e2004-11-04 18:36:06 +0000250
Stefan Reinauerf8ee1802008-01-18 15:08:58 +0000251 /* This is the gdt for GCC part of coreboot.
252 * It is different from the gdt in ROMCC/ASM part of coreboot
Stefan Reinauerc0ac7e92009-11-10 22:17:15 +0000253 * which is defined in entry32.inc
254 *
255 * When the machine is initially started, we use a very simple
256 * gdt from rom (that in entry32.inc) which only contains those
257 * entries we need for protected mode.
258 *
259 * When we're executing code from RAM, we want to do more complex
260 * stuff, like initializing PCI option roms in real mode, or doing
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000261 * a resume from a suspend to ram.
Stefan Reinauerc0ac7e92009-11-10 22:17:15 +0000262 */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000263gdt:
Li-Ta Lof84926e2004-11-04 18:36:06 +0000264 /* selgdt 0, unused */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000265 .word 0x0000, 0x0000 /* dummy */
266 .byte 0x00, 0x00, 0x00, 0x00
267
Li-Ta Lof84926e2004-11-04 18:36:06 +0000268 /* selgdt 8, unused */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000269 .word 0x0000, 0x0000 /* dummy */
270 .byte 0x00, 0x00, 0x00, 0x00
271
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000272 /* selgdt 0x10, flat code segment */
273 .word 0xffff, 0x0000
274 .byte 0x00, 0x9b, 0xcf, 0x00 /* G=1 and 0x0f, So we get 4Gbytes for limit */
Li-Ta Lof84926e2004-11-04 18:36:06 +0000275
276 /* selgdt 0x18, flat data segment */
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000277 .word 0xffff, 0x0000
278 .byte 0x00, 0x93, 0xcf, 0x00
Eric Biederman8ca8d762003-04-22 19:02:15 +0000279
Li-Ta Lof84926e2004-11-04 18:36:06 +0000280 /* selgdt 0x20, unused */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000281 .word 0x0000, 0x0000 /* dummy */
282 .byte 0x00, 0x00, 0x00, 0x00
283
Stefan Reinauerc0ac7e92009-11-10 22:17:15 +0000284 /* The next two entries are used for executing VGA option ROMs */
285
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000286 /* selgdt 0x28 16 bit 64k code at 0x00000000 */
Stefan Reinauerf8a5c6e2009-05-29 13:08:27 +0000287 .word 0xffff, 0x0000
288 .byte 0, 0x9a, 0, 0
289
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000290 /* selgdt 0x30 16 bit 64k data at 0x00000000 */
Stefan Reinauerf8a5c6e2009-05-29 13:08:27 +0000291 .word 0xffff, 0x0000
292 .byte 0, 0x92, 0, 0
Stefan Reinauerc0ac7e92009-11-10 22:17:15 +0000293
294 /* The next two entries are used for ACPI S3 RESUME */
295
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000296 /* selgdt 0x38, flat data segment 16 bit */
Stefan Reinauerc0ac7e92009-11-10 22:17:15 +0000297 .word 0x0000, 0x0000 /* dummy */
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000298 .byte 0x00, 0x93, 0x8f, 0x00 /* G=1 and 0x0f, So we get 4Gbytes for limit */
Stefan Reinauerc0ac7e92009-11-10 22:17:15 +0000299
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000300 /* selgdt 0x40, flat code segment 16 bit */
301 .word 0xffff, 0x0000
302 .byte 0x00, 0x9b, 0x8f, 0x00 /* G=1 and 0x0f, So we get 4Gbytes for limit */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000303gdt_end:
304
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000305idtarg:
306 .word _idt_end - _idt - 1 /* limit */
307 .long _idt
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000308 .word 0
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000309_idt:
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000310 .fill 20, 8, 0 # idt is uninitialized
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000311_idt_end:
312
313 .previous
Eric Biederman8ca8d762003-04-22 19:02:15 +0000314.code32