1
2
3
4
5
6
7
8
9.text
10#include <linux/threads.h>
11#include <linux/init.h>
12#include <linux/linkage.h>
13#include <asm/segment.h>
14#include <asm/page_types.h>
15#include <asm/pgtable_types.h>
16#include <asm/cache.h>
17#include <asm/thread_info.h>
18#include <asm/asm-offsets.h>
19#include <asm/setup.h>
20#include <asm/processor-flags.h>
21#include <asm/msr-index.h>
22#include <asm/cpufeature.h>
23#include <asm/percpu.h>
24#include <asm/nops.h>
25
26
27#define pa(X) ((X) - __PAGE_OFFSET)
28
29
30
31
32
33#define X86 new_cpu_data+CPUINFO_x86
34#define X86_VENDOR new_cpu_data+CPUINFO_x86_vendor
35#define X86_MODEL new_cpu_data+CPUINFO_x86_model
36#define X86_MASK new_cpu_data+CPUINFO_x86_mask
37#define X86_HARD_MATH new_cpu_data+CPUINFO_hard_math
38#define X86_CPUID new_cpu_data+CPUINFO_cpuid_level
39#define X86_CAPABILITY new_cpu_data+CPUINFO_x86_capability
40#define X86_VENDOR_ID new_cpu_data+CPUINFO_x86_vendor_id
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59#define PAGE_TABLE_SIZE(pages) (((pages) / PTRS_PER_PMD) + PTRS_PER_PGD)
60#else
61#define PAGE_TABLE_SIZE(pages) ((pages) / PTRS_PER_PGD)
62#endif
63
64
65LOWMEM_PAGES = (((1<<32) - __PAGE_OFFSET) >> PAGE_SHIFT)
66
67
68MAPPING_BEYOND_END = PAGE_TABLE_SIZE(LOWMEM_PAGES) << PAGE_SHIFT
69
70
71
72
73
74
75KERNEL_PAGES = LOWMEM_PAGES
76
77INIT_MAP_SIZE = PAGE_TABLE_SIZE(KERNEL_PAGES) * PAGE_SIZE
78RESERVE_BRK(pagetables, INIT_MAP_SIZE)
79
80
81
82
83
84
85
86
87__HEAD
88ENTRY(startup_32)
89 movl pa(stack_start),%ecx
90
91
92
93 testb $(1<<6), BP_loadflags(%esi)
94 jnz 2f
95
96
97
98
99 lgdt pa(boot_gdt_descr)
100 movl $(__BOOT_DS),%eax
101 movl %eax,%ds
102 movl %eax,%es
103 movl %eax,%fs
104 movl %eax,%gs
105 movl %eax,%ss
1062:
107 leal -__PAGE_OFFSET(%ecx),%esp
108
109
110
111
112 cld
113 xorl %eax,%eax
114 movl $pa(__bss_start),%edi
115 movl $pa(__bss_stop),%ecx
116 subl %edi,%ecx
117 shrl $2,%ecx
118 rep ; stosl
119
120
121
122
123
124
125
126
127 movl $pa(boot_params),%edi
128 movl $(PARAM_SIZE/4),%ecx
129 cld
130 rep
131 movsl
132 movl pa(boot_params) + NEW_CL_POINTER,%esi
133 andl %esi,%esi
134 jz 1f
135 movl $pa(boot_command_line),%edi
136 movl $(COMMAND_LINE_SIZE/4),%ecx
137 rep
138 movsl
1391:
140
141#ifdef CONFIG_OLPC
142
143 movl %cr3, %eax
144 movl %eax, pa(olpc_ofw_pgd)
145#endif
146
147#ifdef CONFIG_MICROCODE_EARLY
148
149 call load_ucode_bsp
150#endif
151
152
153
154
155
156
157
158
159#ifdef CONFIG_X86_PAE
160
161
162
163
164
165
166
167
168
169
170#define KPMDS (((-__PAGE_OFFSET) >> 30) & 3)
171
172 xorl %ebx,%ebx
173
174 movl $pa(__brk_base), %edi
175 movl $pa(initial_pg_pmd), %edx
176 movl $PTE_IDENT_ATTR, %eax
17710:
178 leal PDE_IDENT_ATTR(%edi),%ecx
179 movl %ecx,(%edx)
180
181 addl $8,%edx
182 movl $512,%ecx
18311:
184 stosl
185 xchgl %eax,%ebx
186 stosl
187 xchgl %eax,%ebx
188 addl $0x1000,%eax
189 loop 11b
190
191
192
193
194 movl $pa(_end) + MAPPING_BEYOND_END + PTE_IDENT_ATTR, %ebp
195 cmpl %ebp,%eax
196 jb 10b
1971:
198 addl $__PAGE_OFFSET, %edi
199 movl %edi, pa(_brk_end)
200 shrl $12, %eax
201 movl %eax, pa(max_pfn_mapped)
202
203
204 movl $pa(initial_pg_fixmap)+PDE_IDENT_ATTR,%eax
205 movl %eax,pa(initial_pg_pmd+0x1000*KPMDS-8)
206#else
207
208page_pde_offset = (__PAGE_OFFSET >> 20);
209
210 movl $pa(__brk_base), %edi
211 movl $pa(initial_page_table), %edx
212 movl $PTE_IDENT_ATTR, %eax
21310:
214 leal PDE_IDENT_ATTR(%edi),%ecx
215 movl %ecx,(%edx)
216 movl %ecx,page_pde_offset(%edx)
217 addl $4,%edx
218 movl $1024, %ecx
21911:
220 stosl
221 addl $0x1000,%eax
222 loop 11b
223
224
225
226 movl $pa(_end) + MAPPING_BEYOND_END + PTE_IDENT_ATTR, %ebp
227 cmpl %ebp,%eax
228 jb 10b
229 addl $__PAGE_OFFSET, %edi
230 movl %edi, pa(_brk_end)
231 shrl $12, %eax
232 movl %eax, pa(max_pfn_mapped)
233
234
235 movl $pa(initial_pg_fixmap)+PDE_IDENT_ATTR,%eax
236 movl %eax,pa(initial_page_table+0xffc)
237#endif
238
239#ifdef CONFIG_PARAVIRT
240
241 cmpw $0x207, pa(boot_params + BP_version)
242 jb default_entry
243
244
245
246 movl pa(boot_params + BP_hardware_subarch), %eax
247 cmpl $num_subarch_entries, %eax
248 jae bad_subarch
249
250 movl pa(subarch_entries)(,%eax,4), %eax
251 subl $__PAGE_OFFSET, %eax
252 jmp *%eax
253
254bad_subarch:
255WEAK(lguest_entry)
256WEAK(xen_entry)
257
258
259 ud2a
260
261 __INITDATA
262
263subarch_entries:
264 .long default_entry
265 .long lguest_entry
266 .long xen_entry
267 .long default_entry
268num_subarch_entries = (. - subarch_entries) / 4
269.previous
270#else
271 jmp default_entry
272#endif
273
274#ifdef CONFIG_HOTPLUG_CPU
275
276
277
278
279
280ENTRY(start_cpu0)
281 movl stack_start, %ecx
282 movl %ecx, %esp
283 jmp *(initial_code)
284ENDPROC(start_cpu0)
285#endif
286
287
288
289
290
291
292
293
294
295ENTRY(startup_32_smp)
296 cld
297 movl $(__BOOT_DS),%eax
298 movl %eax,%ds
299 movl %eax,%es
300 movl %eax,%fs
301 movl %eax,%gs
302 movl pa(stack_start),%ecx
303 movl %eax,%ss
304 leal -__PAGE_OFFSET(%ecx),%esp
305
306#ifdef CONFIG_MICROCODE_EARLY
307
308 call load_ucode_ap
309#endif
310
311
312default_entry:
313#define CR0_STATE (X86_CR0_PE | X86_CR0_MP | X86_CR0_ET | \
314 X86_CR0_NE | X86_CR0_WP | X86_CR0_AM | \
315 X86_CR0_PG)
316 movl $(CR0_STATE & ~X86_CR0_PG),%eax
317 movl %eax,%cr0
318
319
320
321
322
323
324
325
326 pushl $0
327 popfl
328
329
330
331
332
333
334
335 movl $-1,pa(X86_CPUID)
336 movl $X86_EFLAGS_ID,%ecx
337 pushl %ecx
338 popfl
339 pushfl
340 popl %eax
341 testl $X86_EFLAGS_ID,%eax
342 jz enable_paging
343
344
345 xorl %eax,%eax
346 cpuid
347 movl %eax,pa(X86_CPUID)
348
349 movl $1,%eax
350 cpuid
351 andl $~1,%edx
352 jz enable_paging
353
354 movl pa(mmu_cr4_features),%eax
355 movl %eax,%cr4
356
357 testb $X86_CR4_PAE, %al
358 jz enable_paging
359
360
361 movl $0x80000000, %eax
362 cpuid
363
364 subl $0x80000001, %eax
365 cmpl $(0x8000ffff-0x80000001), %eax
366 ja enable_paging
367
368
369 call verify_cpu
370
371 mov $0x80000001, %eax
372 cpuid
373
374 btl $(X86_FEATURE_NX & 31), %edx
375 jnc enable_paging
376
377
378 movl $MSR_EFER, %ecx
379 rdmsr
380
381 btsl $_EFER_NX, %eax
382
383 wrmsr
384
385enable_paging:
386
387
388
389
390 movl $pa(initial_page_table), %eax
391 movl %eax,%cr3
392 movl $CR0_STATE,%eax
393 movl %eax,%cr0
394 ljmp $__BOOT_CS,$1f
3951:
396
397 addl $__PAGE_OFFSET, %esp
398
399
400
401
402
403 movl setup_once_ref,%eax
404 andl %eax,%eax
405 jz 1f
406 call *%eax
4071:
408
409
410
411
412 movb $4,X86
413 cmpl $-1,X86_CPUID
414 je is486
415
416
417 xorl %eax,%eax
418 cpuid
419 movl %eax,X86_CPUID
420 movl %ebx,X86_VENDOR_ID
421 movl %edx,X86_VENDOR_ID+4
422 movl %ecx,X86_VENDOR_ID+8
423
424 orl %eax,%eax
425 je is486
426
427 movl $1,%eax
428 cpuid
429 movb %al,%cl
430 andb $0x0f,%ah
431 movb %ah,X86
432 andb $0xf0,%al
433 shrb $4,%al
434 movb %al,X86_MODEL
435 andb $0x0f,%cl
436 movb %cl,X86_MASK
437 movl %edx,X86_CAPABILITY
438
439is486:
440 movl $0x50022,%ecx
441 movl %cr0,%eax
442 andl $0x80000011,%eax
443 orl %ecx,%eax
444 movl %eax,%cr0
445
446 lgdt early_gdt_descr
447 lidt idt_descr
448 ljmp $(__KERNEL_CS),$1f
4491: movl $(__KERNEL_DS),%eax
450 movl %eax,%ss
451
452 movl $(__USER_DS),%eax
453 movl %eax,%ds
454 movl %eax,%es
455
456 movl $(__KERNEL_PERCPU), %eax
457 movl %eax,%fs
458
459 movl $(__KERNEL_STACK_CANARY),%eax
460 movl %eax,%gs
461
462 xorl %eax,%eax
463 lldt %ax
464
465 pushl $0
466 jmp *(initial_code)
467
468#include "verify_cpu.S"
469
470
471
472
473
474
475
476
477__INIT
478setup_once:
479
480
481
482
483
484
485
486 movl $idt_table,%edi
487 movl $early_idt_handlers,%eax
488 movl $NUM_EXCEPTION_VECTORS,%ecx
4891:
490 movl %eax,(%edi)
491 movl %eax,4(%edi)
492
493 movl $(0x8E000000 + __KERNEL_CS),2(%edi)
494 addl $9,%eax
495 addl $8,%edi
496 loop 1b
497
498 movl $256 - NUM_EXCEPTION_VECTORS,%ecx
499 movl $ignore_int,%edx
500 movl $(__KERNEL_CS << 16),%eax
501 movw %dx,%ax
502 movw $0x8E00,%dx
5032:
504 movl %eax,(%edi)
505 movl %edx,4(%edi)
506 addl $8,%edi
507 loop 2b
508
509#ifdef CONFIG_CC_STACKPROTECTOR
510
511
512
513
514
515 movl $gdt_page,%eax
516 movl $stack_canary,%ecx
517 movw %cx, 8 * GDT_ENTRY_STACK_CANARY + 2(%eax)
518 shrl $16, %ecx
519 movb %cl, 8 * GDT_ENTRY_STACK_CANARY + 4(%eax)
520 movb %ch, 8 * GDT_ENTRY_STACK_CANARY + 7(%eax)
521#endif
522
523 andl $0,setup_once_ref
524 ret
525
526ENTRY(early_idt_handlers)
527
528
529
530
531 i = 0
532 .rept NUM_EXCEPTION_VECTORS
533 .if (EXCEPTION_ERRCODE_MASK >> i) & 1
534 ASM_NOP2
535 .else
536 pushl $0
537 .endif
538 pushl $i
539 jmp early_idt_handler
540 i = i + 1
541 .endr
542ENDPROC(early_idt_handlers)
543
544
545ENTRY(early_idt_handler)
546 cld
547
548 cmpl $2,(%esp)
549 je is_nmi
550
551 cmpl $2,%ss:early_recursion_flag
552 je hlt_loop
553 incl %ss:early_recursion_flag
554
555 push %eax
556 push %ecx
557 push %edx
558 push %ds
559 push %es
560 movl $(__KERNEL_DS),%eax
561 movl %eax,%ds
562 movl %eax,%es
563
564 cmpl $(__KERNEL_CS),32(%esp)
565 jne 10f
566
567 leal 28(%esp),%eax
568 call early_fixup_exception
569 andl %eax,%eax
570 jnz ex_entry
571
57210:
573#ifdef CONFIG_PRINTK
574 xorl %eax,%eax
575 movw %ax,2(%esp)
576 movw %ax,6(%esp)
577 movw %ax,34(%esp)
578 leal 40(%esp),%eax
579 pushl %eax
580 pushl %ebx
581 pushl %ebp
582 pushl %esi
583 pushl %edi
584 movl %cr2,%eax
585 pushl %eax
586 pushl (20+6*4)(%esp)
587 pushl $fault_msg
588 call printk
589#endif
590 call dump_stack
591hlt_loop:
592 hlt
593 jmp hlt_loop
594
595ex_entry:
596 pop %es
597 pop %ds
598 pop %edx
599 pop %ecx
600 pop %eax
601 decl %ss:early_recursion_flag
602is_nmi:
603 addl $8,%esp
604 iret
605ENDPROC(early_idt_handler)
606
607
608 ALIGN
609ignore_int:
610 cld
611#ifdef CONFIG_PRINTK
612 pushl %eax
613 pushl %ecx
614 pushl %edx
615 pushl %es
616 pushl %ds
617 movl $(__KERNEL_DS),%eax
618 movl %eax,%ds
619 movl %eax,%es
620 cmpl $2,early_recursion_flag
621 je hlt_loop
622 incl early_recursion_flag
623 pushl 16(%esp)
624 pushl 24(%esp)
625 pushl 32(%esp)
626 pushl 40(%esp)
627 pushl $int_msg
628 call printk
629
630 call dump_stack
631
632 addl $(5*4),%esp
633 popl %ds
634 popl %es
635 popl %edx
636 popl %ecx
637 popl %eax
638#endif
639 iret
640ENDPROC(ignore_int)
641__INITDATA
642 .align 4
643early_recursion_flag:
644 .long 0
645
646__REFDATA
647 .align 4
648ENTRY(initial_code)
649 .long i386_start_kernel
650ENTRY(setup_once_ref)
651 .long setup_once
652
653
654
655
656__PAGE_ALIGNED_BSS
657 .align PAGE_SIZE
658#ifdef CONFIG_X86_PAE
659initial_pg_pmd:
660 .fill 1024*KPMDS,4,0
661#else
662ENTRY(initial_page_table)
663 .fill 1024,4,0
664#endif
665initial_pg_fixmap:
666 .fill 1024,4,0
667ENTRY(empty_zero_page)
668 .fill 4096,1,0
669ENTRY(swapper_pg_dir)
670 .fill 1024,4,0
671
672
673
674
675#ifdef CONFIG_X86_PAE
676__PAGE_ALIGNED_DATA
677
678 .align PAGE_SIZE
679ENTRY(initial_page_table)
680 .long pa(initial_pg_pmd+PGD_IDENT_ATTR),0
681
682 .long pa(initial_pg_pmd+PGD_IDENT_ATTR),0
683 .long pa(initial_pg_pmd+PGD_IDENT_ATTR+0x1000),0
684 .long pa(initial_pg_pmd+PGD_IDENT_ATTR+0x2000),0
685
686 .long 0,0
687 .long pa(initial_pg_pmd+PGD_IDENT_ATTR),0
688 .long pa(initial_pg_pmd+PGD_IDENT_ATTR+0x1000),0
689
690 .long 0,0
691 .long 0,0
692 .long pa(initial_pg_pmd+PGD_IDENT_ATTR),0
693# else
694
695# endif
696 .align PAGE_SIZE
697#endif
698
699.data
700.balign 4
701ENTRY(stack_start)
702 .long init_thread_union+THREAD_SIZE
703
704__INITRODATA
705int_msg:
706 .asciz "Unknown interrupt or fault at: %p %p %p\n"
707
708fault_msg:
709
710 .ascii "BUG: Int %d: CR2 %p\n"
711
712 .ascii " EDI %p ESI %p EBP %p EBX %p\n"
713 .ascii " ESP %p ES %p DS %p\n"
714 .ascii " EDX %p ECX %p EAX %p\n"
715
716 .ascii " vec %p err %p EIP %p CS %p flg %p\n"
717 .ascii "Stack: %p %p %p %p %p %p %p %p\n"
718 .ascii " %p %p %p %p %p %p %p %p\n"
719 .asciz " %p %p %p %p %p %p %p %p\n"
720
721#include "../../x86/xen/xen-head.S"
722
723
724
725
726
727
728
729
730 .data
731.globl boot_gdt_descr
732.globl idt_descr
733
734 ALIGN
735
736 .word 0
737boot_gdt_descr:
738 .word __BOOT_DS+7
739 .long boot_gdt - __PAGE_OFFSET
740
741 .word 0
742idt_descr:
743 .word IDT_ENTRIES*8-1
744 .long idt_table
745
746
747 .word 0
748ENTRY(early_gdt_descr)
749 .word GDT_ENTRIES*8-1
750 .long gdt_page
751
752
753
754
755
756 .align L1_CACHE_BYTES
757ENTRY(boot_gdt)
758 .fill GDT_ENTRY_BOOT_CS,8,0
759 .quad 0x00cf9a000000ffff
760 .quad 0x00cf92000000ffff
761