blob: 005ac33ee99579cbe8ed870ba89806b5d8b07ca7 [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
Eric Biederman8ca8d762003-04-22 19:02:15 +00003 .section ".text"
4 .code32
5 .globl _start
6_start:
7 cli
8 lgdt %cs:gdtaddr
9 ljmp $0x10, $1f
101: movl $0x18, %eax
11 movl %eax, %ds
12 movl %eax, %es
13 movl %eax, %ss
14 movl %eax, %fs
15 movl %eax, %gs
16
Alexandru Gagniuc5005bb062011-04-11 20:17:22 +000017 post_code(POST_ENTRY_C_START) /* post 13 */
Eric Biederman8ca8d762003-04-22 19:02:15 +000018
19 /** clear stack */
arch import user (historical)6ca76362005-07-06 17:17:25 +000020 cld
Eric Biedermanae948f72003-07-14 20:40:38 +000021 leal _stack, %edi
22 movl $_estack, %ecx
Eric Biederman8ca8d762003-04-22 19:02:15 +000023 subl %edi, %ecx
Stefan Reinauer607cdf62010-04-26 12:08:51 +000024 shrl $2, %ecx /* it is 32 bit aligned, right? */
Eric Biederman8ca8d762003-04-22 19:02:15 +000025 xorl %eax, %eax
26 rep
Stefan Reinauer7ce8c542005-12-02 21:52:30 +000027 stosl
Eric Biederman8ca8d762003-04-22 19:02:15 +000028
29 /** clear bss */
Eric Biedermanae948f72003-07-14 20:40:38 +000030 leal _bss, %edi
31 movl $_ebss, %ecx
Eric Biederman8ca8d762003-04-22 19:02:15 +000032 subl %edi, %ecx
33 jz .Lnobss
Stefan Reinauer607cdf62010-04-26 12:08:51 +000034 shrl $2, %ecx /* it is 32 bit aligned, right? */
Eric Biederman8ca8d762003-04-22 19:02:15 +000035 xorl %eax, %eax
36 rep
Stefan Reinauer7ce8c542005-12-02 21:52:30 +000037 stosl
Eric Biederman8ca8d762003-04-22 19:02:15 +000038.Lnobss:
39
40 /* set new stack */
41 movl $_estack, %esp
Eric Biederman8ca8d762003-04-22 19:02:15 +000042
Eric Biedermanb78c1972004-10-14 20:54:17 +000043 /* Push the cpu index and struct cpu */
44 pushl $0
45 pushl $0
Eric Biederman8ca8d762003-04-22 19:02:15 +000046
47 /* push the boot_complete flag */
48 pushl %ebp
49
50 /* Save the stack location */
51 movl %esp, %ebp
52
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +000053 /* Initialize the Interrupt Descriptor table */
54 leal _idt, %edi
55 leal vec0, %ebx
56 movl $(0x10 << 16), %eax /* cs selector */
57
581: movw %bx, %ax
59 movl %ebx, %edx
60 movw $0x8E00, %dx /* Interrupt gate - dpl=0, present */
61 movl %eax, 0(%edi)
62 movl %edx, 4(%edi)
63 addl $6, %ebx
64 addl $8, %edi
65 cmpl $_idt_end, %edi
66 jne 1b
67
68 /* Load the Interrupt descriptor table */
69 lidt idtarg
70
Eric Biederman8ca8d762003-04-22 19:02:15 +000071 /*
72 * Now we are finished. Memory is up, data is copied and
73 * bss is cleared. Now we call the main routine and
74 * let it do the rest.
Stefan Reinauer607cdf62010-04-26 12:08:51 +000075 */
Alexandru Gagniuc5005bb062011-04-11 20:17:22 +000076 post_code(POST_PRE_HARDWAREMAIN) /* post fe */
Eric Biederman8ca8d762003-04-22 19:02:15 +000077
Eric Biedermanb78c1972004-10-14 20:54:17 +000078 /* Restore the stack location */
Eric Biederman8ca8d762003-04-22 19:02:15 +000079 movl %ebp, %esp
Stefan Reinauer607cdf62010-04-26 12:08:51 +000080
Eric Biederman8ca8d762003-04-22 19:02:15 +000081 /* The boot_complete flag has already been pushed */
Eric Biedermanae948f72003-07-14 20:40:38 +000082 call hardwaremain
Stefan Reinauer607cdf62010-04-26 12:08:51 +000083 /* NOTREACHED */
Eric Biederman8ca8d762003-04-22 19:02:15 +000084.Lhlt:
Alexandru Gagniuc5005bb062011-04-11 20:17:22 +000085 post_code(POST_DEAD_CODE) /* post ee */
Eric Biederman8ca8d762003-04-22 19:02:15 +000086 hlt
87 jmp .Lhlt
Stefan Reinauer607cdf62010-04-26 12:08:51 +000088
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +000089vec0:
90 pushl $0 /* error code */
91 pushl $0 /* vector */
92 jmp int_hand
93vec1:
94 pushl $0 /* error code */
95 pushl $1 /* vector */
96 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +000097
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +000098vec2:
99 pushl $0 /* error code */
100 pushl $2 /* vector */
101 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000102
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000103vec3:
104 pushl $0 /* error code */
105 pushl $3 /* vector */
106 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000107
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000108vec4:
109 pushl $0 /* error code */
110 pushl $4 /* vector */
111 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000112
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000113vec5:
114 pushl $0 /* error code */
115 pushl $5 /* vector */
116 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000117
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000118vec6:
119 pushl $0 /* error code */
120 pushl $6 /* vector */
121 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000122
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000123vec7:
124 pushl $0 /* error code */
125 pushl $7 /* vector */
126 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000127
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000128vec8:
129 /* error code */
130 pushl $8 /* vector */
131 jmp int_hand
132 .word 0x9090
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000133
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000134vec9:
135 pushl $0 /* error code */
136 pushl $9 /* vector */
137 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000138
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000139vec10:
140 /* error code */
141 pushl $10 /* vector */
142 jmp int_hand
143 .word 0x9090
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000144
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000145vec11:
146 /* error code */
147 pushl $11 /* vector */
148 jmp int_hand
149 .word 0x9090
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000150
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000151vec12:
152 /* error code */
153 pushl $12 /* vector */
154 jmp int_hand
155 .word 0x9090
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000156
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000157vec13:
158 /* error code */
159 pushl $13 /* vector */
160 jmp int_hand
161 .word 0x9090
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000162
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000163vec14:
164 /* error code */
165 pushl $14 /* vector */
166 jmp int_hand
167 .word 0x9090
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000168
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000169vec15:
170 pushl $0 /* error code */
171 pushl $15 /* vector */
172 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000173
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000174vec16:
175 pushl $0 /* error code */
176 pushl $16 /* vector */
177 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000178
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000179vec17:
180 /* error code */
181 pushl $17 /* vector */
182 jmp int_hand
183 .word 0x9090
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000184
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000185vec18:
186 pushl $0 /* error code */
187 pushl $18 /* vector */
188 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000189
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000190vec19:
191 pushl $0 /* error code */
192 pushl $19 /* vector */
193 jmp int_hand
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000194
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000195int_hand:
196 /* At this point on the stack there is:
197 * 0(%esp) vector
198 * 4(%esp) error code
199 * 8(%esp) eip
200 * 12(%esp) cs
201 * 16(%esp) eflags
202 */
203 pushl %edi
204 pushl %esi
205 pushl %ebp
206 /* Original stack pointer */
207 leal 32(%esp), %ebp
208 pushl %ebp
209 pushl %ebx
210 pushl %edx
211 pushl %ecx
212 pushl %eax
Eric Biederman8ca8d762003-04-22 19:02:15 +0000213
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000214 pushl %esp /* Pointer to structure on the stack */
215 call x86_exception
216 pop %eax /* Drop the pointer */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000217
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000218 popl %eax
219 popl %ecx
220 popl %edx
221 popl %ebx
Li-Ta Lof84926e2004-11-04 18:36:06 +0000222 popl %ebp /* Ignore saved %esp value */
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000223 popl %ebp
224 popl %esi
225 popl %edi
226
227 addl $8, %esp /* pop of the vector and error code */
228
229 iret
230
231#if CONFIG_GDB_STUB == 1
232
233 .globl gdb_stub_breakpoint
234gdb_stub_breakpoint:
235 popl %eax /* Return address */
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000236 pushfl
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000237 pushl %cs
238 pushl %eax /* Return address */
239 pushl $0 /* No error code */
240 pushl $32 /* vector 32 is user defined */
241 jmp int_hand
242
243#endif
244
245 .globl gdt, gdt_end, gdt_limit, idtarg
Eric Biederman8ca8d762003-04-22 19:02:15 +0000246
Li-Ta Lof84926e2004-11-04 18:36:06 +0000247gdt_limit = gdt_end - gdt - 1 /* compute the table limit */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000248gdtaddr:
249 .word gdt_limit
Li-Ta Lof84926e2004-11-04 18:36:06 +0000250 .long gdt /* we know the offset */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000251
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000252 .data
Li-Ta Lof84926e2004-11-04 18:36:06 +0000253
Stefan Reinauerf8ee1802008-01-18 15:08:58 +0000254 /* This is the gdt for GCC part of coreboot.
255 * It is different from the gdt in ROMCC/ASM part of coreboot
Stefan Reinauerc0ac7e92009-11-10 22:17:15 +0000256 * which is defined in entry32.inc
257 *
258 * When the machine is initially started, we use a very simple
259 * gdt from rom (that in entry32.inc) which only contains those
260 * entries we need for protected mode.
261 *
262 * When we're executing code from RAM, we want to do more complex
263 * stuff, like initializing PCI option roms in real mode, or doing
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000264 * a resume from a suspend to ram.
Stefan Reinauerc0ac7e92009-11-10 22:17:15 +0000265 */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000266gdt:
Li-Ta Lof84926e2004-11-04 18:36:06 +0000267 /* selgdt 0, unused */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000268 .word 0x0000, 0x0000 /* dummy */
269 .byte 0x00, 0x00, 0x00, 0x00
270
Li-Ta Lof84926e2004-11-04 18:36:06 +0000271 /* selgdt 8, unused */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000272 .word 0x0000, 0x0000 /* dummy */
273 .byte 0x00, 0x00, 0x00, 0x00
274
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000275 /* selgdt 0x10, flat code segment */
276 .word 0xffff, 0x0000
277 .byte 0x00, 0x9b, 0xcf, 0x00 /* G=1 and 0x0f, So we get 4Gbytes for limit */
Li-Ta Lof84926e2004-11-04 18:36:06 +0000278
279 /* selgdt 0x18, flat data segment */
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000280 .word 0xffff, 0x0000
281 .byte 0x00, 0x93, 0xcf, 0x00
Eric Biederman8ca8d762003-04-22 19:02:15 +0000282
Li-Ta Lof84926e2004-11-04 18:36:06 +0000283 /* selgdt 0x20, unused */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000284 .word 0x0000, 0x0000 /* dummy */
285 .byte 0x00, 0x00, 0x00, 0x00
286
Stefan Reinauerc0ac7e92009-11-10 22:17:15 +0000287 /* The next two entries are used for executing VGA option ROMs */
288
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000289 /* selgdt 0x28 16 bit 64k code at 0x00000000 */
Stefan Reinauerf8a5c6e2009-05-29 13:08:27 +0000290 .word 0xffff, 0x0000
291 .byte 0, 0x9a, 0, 0
292
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000293 /* selgdt 0x30 16 bit 64k data at 0x00000000 */
Stefan Reinauerf8a5c6e2009-05-29 13:08:27 +0000294 .word 0xffff, 0x0000
295 .byte 0, 0x92, 0, 0
Stefan Reinauerc0ac7e92009-11-10 22:17:15 +0000296
297 /* The next two entries are used for ACPI S3 RESUME */
298
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000299 /* selgdt 0x38, flat data segment 16 bit */
Stefan Reinauerc0ac7e92009-11-10 22:17:15 +0000300 .word 0x0000, 0x0000 /* dummy */
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000301 .byte 0x00, 0x93, 0x8f, 0x00 /* G=1 and 0x0f, So we get 4Gbytes for limit */
Stefan Reinauerc0ac7e92009-11-10 22:17:15 +0000302
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000303 /* selgdt 0x40, flat code segment 16 bit */
304 .word 0xffff, 0x0000
305 .byte 0x00, 0x9b, 0x8f, 0x00 /* G=1 and 0x0f, So we get 4Gbytes for limit */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000306gdt_end:
307
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000308idtarg:
309 .word _idt_end - _idt - 1 /* limit */
310 .long _idt
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000311 .word 0
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000312_idt:
Stefan Reinauer607cdf62010-04-26 12:08:51 +0000313 .fill 20, 8, 0 # idt is uninitialized
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000314_idt_end:
315
316 .previous
Eric Biederman8ca8d762003-04-22 19:02:15 +0000317.code32