2e397f884733e538b075296b1441b555c23f9cce
[coreboot.git] / src / arch / i386 / lib / c_start.S
1 #include <arch/asm.h>
2 #include <arch/intel.h>
3
4         .section ".text"
5         .code32
6         .globl _start
7 _start:
8         cli
9         lgdt    %cs:gdtaddr
10         ljmp    $0x10, $1f
11 1:      movl    $0x18, %eax
12         movl    %eax, %ds
13         movl    %eax, %es
14         movl    %eax, %ss
15         movl    %eax, %fs
16         movl    %eax, %gs
17
18         intel_chip_post_macro(0x13)             /* post 12 */
19
20         /** clear stack */
21         leal    _stack, %edi
22         movl    $_estack, %ecx
23         subl    %edi, %ecx
24         xorl    %eax, %eax
25         rep
26         stosb
27
28         /** clear bss */
29         leal    _bss, %edi
30         movl    $_ebss, %ecx
31         subl    %edi, %ecx
32         jz      .Lnobss
33         xorl    %eax, %eax
34         rep
35         stosb
36 .Lnobss:
37
38         /* set new stack */
39         movl    $_estack, %esp
40
41         /* Push the cpu index and struct cpu */
42         pushl   $0
43         pushl   $0
44
45         /* push the boot_complete flag */
46         pushl   %ebp
47
48         /* Save the stack location */
49         movl    %esp, %ebp
50
51         /* Initialize the Interrupt Descriptor table */
52         leal    _idt, %edi
53         leal    vec0, %ebx
54         movl    $(0x10 << 16), %eax     /* cs selector */
55
56 1:      movw    %bx, %ax
57         movl    %ebx, %edx
58         movw    $0x8E00, %dx            /* Interrupt gate - dpl=0, present */
59         movl    %eax, 0(%edi)
60         movl    %edx, 4(%edi)
61         addl    $6, %ebx
62         addl    $8, %edi
63         cmpl    $_idt_end, %edi
64         jne     1b
65
66         /* Load the Interrupt descriptor table */
67         lidt    idtarg
68
69         /*
70          *      Now we are finished. Memory is up, data is copied and
71          *      bss is cleared.   Now we call the main routine and
72          *      let it do the rest.
73          */ 
74         intel_chip_post_macro(0xfe)     /* post fe */
75
76         /* Restore the stack location */
77         movl    %ebp, %esp
78         
79         /* The boot_complete flag has already been pushed */
80         call    hardwaremain
81         /*NOTREACHED*/
82 .Lhlt:
83         intel_chip_post_macro(0xee)     /* post fe */
84         hlt
85         jmp     .Lhlt
86         
87 vec0:
88         pushl   $0 /* error code */
89         pushl   $0 /* vector */
90         jmp int_hand
91 vec1:
92         pushl   $0 /* error code */
93         pushl   $1 /* vector */
94         jmp int_hand
95         
96 vec2:
97         pushl   $0 /* error code */
98         pushl   $2 /* vector */
99         jmp int_hand
100         
101 vec3:
102         pushl   $0 /* error code */
103         pushl   $3 /* vector */
104         jmp     int_hand
105         
106 vec4:
107         pushl   $0 /* error code */
108         pushl   $4 /* vector */
109         jmp     int_hand
110         
111 vec5:
112         pushl   $0 /* error code */
113         pushl   $5 /* vector */
114         jmp     int_hand
115         
116 vec6:
117         pushl   $0 /* error code */
118         pushl   $6 /* vector */
119         jmp     int_hand
120         
121 vec7:
122         pushl   $0 /* error code */
123         pushl   $7 /* vector */
124         jmp     int_hand
125         
126 vec8:
127         /* error code */
128         pushl   $8 /* vector */
129         jmp     int_hand
130         .word   0x9090
131         
132 vec9:
133         pushl   $0 /* error code */
134         pushl   $9 /* vector */
135         jmp int_hand
136         
137 vec10:
138         /* error code */
139         pushl   $10 /* vector */
140         jmp     int_hand
141         .word   0x9090
142         
143 vec11:
144         /* error code */
145         pushl   $11 /* vector */
146         jmp     int_hand
147         .word   0x9090
148                 
149 vec12:
150         /* error code */
151         pushl   $12 /* vector */
152         jmp     int_hand
153         .word   0x9090
154         
155 vec13:
156         /* error code */
157         pushl   $13 /* vector */
158         jmp     int_hand
159         .word   0x9090
160         
161 vec14:
162         /* error code */
163         pushl   $14 /* vector */
164         jmp     int_hand
165         .word   0x9090
166         
167 vec15:
168         pushl   $0 /* error code */
169         pushl   $15 /* vector */
170         jmp     int_hand
171         
172 vec16:
173         pushl   $0 /* error code */
174         pushl   $16 /* vector */
175         jmp     int_hand
176         
177 vec17:
178         /* error code */
179         pushl   $17 /* vector */
180         jmp     int_hand
181         .word   0x9090
182         
183 vec18:
184         pushl   $0 /* error code */
185         pushl   $18 /* vector */
186         jmp     int_hand
187         
188 vec19:
189         pushl   $0 /* error code */
190         pushl   $19 /* vector */
191         jmp     int_hand
192 int_hand:
193         /* At this point on the stack there is:
194          *  0(%esp) vector
195          *  4(%esp) error code
196          *  8(%esp) eip
197          * 12(%esp) cs
198          * 16(%esp) eflags
199          */
200         pushl   %edi
201         pushl   %esi
202         pushl   %ebp
203         /* Original stack pointer */
204         leal    32(%esp), %ebp
205         pushl   %ebp
206         pushl   %ebx
207         pushl   %edx
208         pushl   %ecx
209         pushl   %eax
210
211         pushl   %esp    /* Pointer to structure on the stack */
212         call    x86_exception
213         pop     %eax    /* Drop the pointer */
214
215         popl    %eax
216         popl    %ecx
217         popl    %edx
218         popl    %ebx
219         popl    %ebp /* Ignore saved %esp value */
220         popl    %ebp
221         popl    %esi
222         popl    %edi
223
224         addl    $8, %esp /* pop of the vector and error code */
225
226         iret
227
228 #if CONFIG_GDB_STUB == 1
229
230         .globl gdb_stub_breakpoint
231 gdb_stub_breakpoint:
232         popl    %eax    /* Return address */
233         pushfl  
234         pushl   %cs
235         pushl   %eax    /* Return address */
236         pushl   $0      /* No error code */
237         pushl   $32     /* vector 32 is user defined */
238         jmp     int_hand
239
240 #endif
241
242         .globl gdt, gdt_end, gdt_limit, idtarg
243
244 gdt_limit = gdt_end - gdt - 1 /* compute the table limit */
245 gdtaddr:
246         .word   gdt_limit
247         .long   gdt                /* we know the offset */
248
249          .data
250 gdt:
251 // selgdt 0
252         .word   0x0000, 0x0000          /* dummy */
253         .byte   0x00, 0x00, 0x00, 0x00
254
255 // selgdt 8
256         .word   0x0000, 0x0000          /* dummy */
257         .byte   0x00, 0x00, 0x00, 0x00
258
259 // selgdt 0x10 
260 /* flat code segment */
261         .word   0xffff, 0x0000          
262         .byte   0x00, 0x9b, 0xcf, 0x00  
263         
264 //selgdt 0x18
265 /* flat data segment */
266         .word   0xffff, 0x0000          
267         .byte   0x00, 0x93, 0xcf, 0x00  
268
269 //selgdt 0x20
270         .word   0x0000, 0x0000          /* dummy */
271         .byte   0x00, 0x00, 0x00, 0x00
272
273 #if defined(CONFIG_LEGACY_VGABIOS) && (CONFIG_LEGACY_VGABIOS == 1)
274         // from monty:
275         /* 0x00009a00,0000ffffULL,   20h: 16-bit 64k code at 0x00000000 */
276         /* 0x00009200,0000ffffULL    28h: 16-bit 64k data at 0x00000000 */
277 // selgdt 0x28
278 /*16-bit 64k code at 0x00000000 */
279         .word 0xffff, 0x0000
280         .byte 0, 0x9a, 0, 0
281
282 // selgdt 0x30
283 /*16-bit 64k data at 0x00000000 */
284         .word 0xffff, 0x0000
285         .byte 0, 0x92, 0, 0
286 #endif // defined(CONFIG_VGABIOS) && (CONFIG_VGABIOS == 1)
287 gdt_end:
288
289 idtarg:
290         .word   _idt_end - _idt - 1     /* limit */
291         .long   _idt
292         .word   0       
293 _idt:
294         .fill   20, 8, 0        # idt is unitiailzed
295 _idt_end:
296
297         .previous
298 .code32