blob: 35bc26b7893544a4a31277a4d76e2afd0462967b [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
Patrick Georgi69992172012-11-25 17:31:25 +010014 .section ".textfirst"
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
52 /* push the boot_complete flag */
53 pushl %ebp
54
55 /* Save the stack location */
56 movl %esp, %ebp
57
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +000058 /* Initialize the Interrupt Descriptor table */
59 leal _idt, %edi
60 leal vec0, %ebx
61 movl $(0x10 << 16), %eax /* cs selector */
62
631: movw %bx, %ax
64 movl %ebx, %edx
65 movw $0x8E00, %dx /* Interrupt gate - dpl=0, present */
66 movl %eax, 0(%edi)
67 movl %edx, 4(%edi)
68 addl $6, %ebx
69 addl $8, %edi
70 cmpl $_idt_end, %edi
71 jne 1b
72
73 /* Load the Interrupt descriptor table */
74 lidt idtarg
75
Eric Biederman8ca8d762003-04-22 19:02:15 +000076 /*
77 * Now we are finished. Memory is up, data is copied and
78 * bss is cleared. Now we call the main routine and
79 * let it do the rest.
Stefan Reinauer607cdf62010-04-26 12:08:51 +000080 */
Alexandru Gagniuc5005bb062011-04-11 20:17:22 +000081 post_code(POST_PRE_HARDWAREMAIN) /* post fe */
Eric Biederman8ca8d762003-04-22 19:02:15 +000082
Eric Biedermanb78c1972004-10-14 20:54:17 +000083 /* Restore the stack location */
Eric Biederman8ca8d762003-04-22 19:02:15 +000084 movl %ebp, %esp
Stefan Reinauer607cdf62010-04-26 12:08:51 +000085
Stefan Reinauer8ada1522012-11-16 13:34:48 -080086#if CONFIG_GDB_WAIT
Denis 'GNUtoo' Cariklie4cece02012-06-22 15:56:37 +020087 call gdb_stub_breakpoint
88#endif
Eric Biederman8ca8d762003-04-22 19:02:15 +000089 /* The boot_complete flag has already been pushed */
Eric Biedermanae948f72003-07-14 20:40:38 +000090 call hardwaremain
Stefan Reinauer607cdf62010-04-26 12:08:51 +000091 /* NOTREACHED */
Eric Biederman8ca8d762003-04-22 19:02:15 +000092.Lhlt:
Alexandru Gagniuc5005bb062011-04-11 20:17:22 +000093 post_code(POST_DEAD_CODE) /* post ee */
Eric Biederman8ca8d762003-04-22 19:02:15 +000094 hlt
95 jmp .Lhlt
Stefan Reinauer607cdf62010-04-26 12:08:51 +000096
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +000097vec0:
98 pushl $0 /* error code */
99 pushl $0 /* vector */
100 jmp int_hand
101vec1:
102 pushl $0 /* error code */
103 pushl $1 /* vector */
104 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000105
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000106vec2:
107 pushl $0 /* error code */
108 pushl $2 /* vector */
109 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000110
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000111vec3:
112 pushl $0 /* error code */
113 pushl $3 /* vector */
114 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000115
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000116vec4:
117 pushl $0 /* error code */
118 pushl $4 /* vector */
119 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000120
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000121vec5:
122 pushl $0 /* error code */
123 pushl $5 /* vector */
124 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000125
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000126vec6:
127 pushl $0 /* error code */
128 pushl $6 /* vector */
129 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000130
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000131vec7:
132 pushl $0 /* error code */
133 pushl $7 /* vector */
134 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000135
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000136vec8:
137 /* error code */
138 pushl $8 /* vector */
139 jmp int_hand
140 .word 0x9090
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000141
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000142vec9:
143 pushl $0 /* error code */
144 pushl $9 /* vector */
145 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000146
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000147vec10:
148 /* error code */
149 pushl $10 /* vector */
150 jmp int_hand
151 .word 0x9090
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000152
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000153vec11:
154 /* error code */
155 pushl $11 /* vector */
156 jmp int_hand
157 .word 0x9090
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000158
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000159vec12:
160 /* error code */
161 pushl $12 /* vector */
162 jmp int_hand
163 .word 0x9090
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000164
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000165vec13:
166 /* error code */
167 pushl $13 /* vector */
168 jmp int_hand
169 .word 0x9090
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000170
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000171vec14:
172 /* error code */
173 pushl $14 /* vector */
174 jmp int_hand
175 .word 0x9090
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000176
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000177vec15:
178 pushl $0 /* error code */
179 pushl $15 /* vector */
180 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000181
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000182vec16:
183 pushl $0 /* error code */
184 pushl $16 /* vector */
185 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000186
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000187vec17:
188 /* error code */
189 pushl $17 /* vector */
190 jmp int_hand
191 .word 0x9090
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000192
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000193vec18:
194 pushl $0 /* error code */
195 pushl $18 /* vector */
196 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000197
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000198vec19:
199 pushl $0 /* error code */
200 pushl $19 /* vector */
201 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000202
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000203int_hand:
204 /* At this point on the stack there is:
205 * 0(%esp) vector
206 * 4(%esp) error code
207 * 8(%esp) eip
208 * 12(%esp) cs
209 * 16(%esp) eflags
210 */
211 pushl %edi
212 pushl %esi
213 pushl %ebp
214 /* Original stack pointer */
215 leal 32(%esp), %ebp
216 pushl %ebp
217 pushl %ebx
218 pushl %edx
219 pushl %ecx
220 pushl %eax
Eric Biederman8ca8d762003-04-22 19:02:15 +0000221
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000222 pushl %esp /* Pointer to structure on the stack */
223 call x86_exception
224 pop %eax /* Drop the pointer */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000225
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000226 popl %eax
227 popl %ecx
228 popl %edx
229 popl %ebx
Li-Ta Lof84926e2004-11-04 18:36:06 +0000230 popl %ebp /* Ignore saved %esp value */
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000231 popl %ebp
232 popl %esi
233 popl %edi
234
235 addl $8, %esp /* pop of the vector and error code */
236
237 iret
238
Stefan Reinauer8ada1522012-11-16 13:34:48 -0800239#if CONFIG_GDB_WAIT
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000240
241 .globl gdb_stub_breakpoint
242gdb_stub_breakpoint:
243 popl %eax /* Return address */
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000244 pushfl
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000245 pushl %cs
246 pushl %eax /* Return address */
247 pushl $0 /* No error code */
248 pushl $32 /* vector 32 is user defined */
249 jmp int_hand
250
251#endif
252
253 .globl gdt, gdt_end, gdt_limit, idtarg
Eric Biederman8ca8d762003-04-22 19:02:15 +0000254
Li-Ta Lof84926e2004-11-04 18:36:06 +0000255gdt_limit = gdt_end - gdt - 1 /* compute the table limit */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000256gdtaddr:
257 .word gdt_limit
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