1/* 2 * linux/arch/i386/kernel/head.S -- the 32-bit startup code. 3 * 4 * Copyright (C) 1991, 1992 Linus Torvalds 5 * 6 * Enhanced CPU detection and feature setting code by Mike Jagdis 7 * and Martin Mares, November 1997. 8 */ 9 10.text 11#include <linux/threads.h> 12#include <linux/linkage.h> 13#include <asm/segment.h> 14#include <asm/page.h> 15#include <asm/pgtable.h> 16#include <asm/desc.h> 17#include <asm/cache.h> 18#include <asm/thread_info.h> 19#include <asm/asm-offsets.h> 20#include <asm/setup.h> 21 22/* 23 * References to members of the new_cpu_data structure. 24 */ 25 26#define X86 new_cpu_data+CPUINFO_x86 27#define X86_VENDOR new_cpu_data+CPUINFO_x86_vendor 28#define X86_MODEL new_cpu_data+CPUINFO_x86_model 29#define X86_MASK new_cpu_data+CPUINFO_x86_mask 30#define X86_HARD_MATH new_cpu_data+CPUINFO_hard_math 31#define X86_CPUID new_cpu_data+CPUINFO_cpuid_level 32#define X86_CAPABILITY new_cpu_data+CPUINFO_x86_capability 33#define X86_VENDOR_ID new_cpu_data+CPUINFO_x86_vendor_id 34 35/* 36 * This is how much memory *in addition to the memory covered up to 37 * and including _end* we need mapped initially. 38 * We need: 39 * - one bit for each possible page, but only in low memory, which means 40 * 2^32/4096/8 = 128K worst case (4G/4G split.) 41 * - enough space to map all low memory, which means 42 * (2^32/4096) / 1024 pages (worst case, non PAE) 43 * (2^32/4096) / 512 + 4 pages (worst case for PAE) 44 * - a few pages for allocator use before the kernel pagetable has 45 * been set up 46 * 47 * Modulo rounding, each megabyte assigned here requires a kilobyte of 48 * memory, which is currently unreclaimed. 49 * 50 * This should be a multiple of a page. 51 */ 52LOW_PAGES = 1<<(32-PAGE_SHIFT_asm) 53 54#if PTRS_PER_PMD > 1 55PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PMD) + PTRS_PER_PGD 56#else 57PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PGD) 58#endif 59BOOTBITMAP_SIZE = LOW_PAGES / 8 60ALLOCATOR_SLOP = 4 61 62INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE + (PAGE_TABLE_SIZE + ALLOCATOR_SLOP)*PAGE_SIZE_asm 63 64/* 65 * 32-bit kernel entrypoint; only used by the boot CPU. On entry, 66 * %esi points to the real-mode code as a 32-bit pointer. 67 * CS and DS must be 4 GB flat segments, but we don't depend on 68 * any particular GDT layout, because we load our own as soon as we 69 * can. 70 */ 71.section .text.head,"ax",@progbits 72ENTRY(startup_32) 73 74/* 75 * Set segments to known values. 76 */ 77 cld 78 lgdt boot_gdt_descr - __PAGE_OFFSET 79 movl $(__BOOT_DS),%eax 80 movl %eax,%ds 81 movl %eax,%es 82 movl %eax,%fs 83 movl %eax,%gs 84 85/* 86 * Clear BSS first so that there are no surprises... 87 * No need to cld as DF is already clear from cld above... 88 */ 89 xorl %eax,%eax 90 movl $__bss_start - __PAGE_OFFSET,%edi 91 movl $__bss_stop - __PAGE_OFFSET,%ecx 92 subl %edi,%ecx 93 shrl $2,%ecx 94 rep ; stosl 95/* 96 * Copy bootup parameters out of the way. 97 * Note: %esi still has the pointer to the real-mode data. 98 * With the kexec as boot loader, parameter segment might be loaded beyond 99 * kernel image and might not even be addressable by early boot page tables. 100 * (kexec on panic case). Hence copy out the parameters before initializing 101 * page tables. 102 */ 103 movl $(boot_params - __PAGE_OFFSET),%edi 104 movl $(PARAM_SIZE/4),%ecx 105 cld 106 rep 107 movsl 108 movl boot_params - __PAGE_OFFSET + NEW_CL_POINTER,%esi 109 andl %esi,%esi 110 jnz 2f # New command line protocol 111 cmpw $(OLD_CL_MAGIC),OLD_CL_MAGIC_ADDR 112 jne 1f 113 movzwl OLD_CL_OFFSET,%esi 114 addl $(OLD_CL_BASE_ADDR),%esi 1152: 116 movl $(boot_command_line - __PAGE_OFFSET),%edi 117 movl $(COMMAND_LINE_SIZE/4),%ecx 118 rep 119 movsl 1201: 121 122/* 123 * Initialize page tables. This creates a PDE and a set of page 124 * tables, which are located immediately beyond _end. The variable 125 * init_pg_tables_end is set up to point to the first "safe" location. 126 * Mappings are created both at virtual address 0 (identity mapping) 127 * and PAGE_OFFSET for up to _end+sizeof(page tables)+INIT_MAP_BEYOND_END. 128 * 129 * Warning: don't use %esi or the stack in this code. However, %esp 130 * can be used as a GPR if you really need it... 131 */ 132page_pde_offset = (__PAGE_OFFSET >> 20); 133 134 movl $(pg0 - __PAGE_OFFSET), %edi 135 movl $(swapper_pg_dir - __PAGE_OFFSET), %edx 136 movl $0x007, %eax /* 0x007 = PRESENT+RW+USER */ 13710: 138 leal 0x007(%edi),%ecx /* Create PDE entry */ 139 movl %ecx,(%edx) /* Store identity PDE entry */ 140 movl %ecx,page_pde_offset(%edx) /* Store kernel PDE entry */ 141 addl $4,%edx 142 movl $1024, %ecx 14311: 144 stosl 145 addl $0x1000,%eax 146 loop 11b 147 /* End condition: we must map up to and including INIT_MAP_BEYOND_END */ 148 /* bytes beyond the end of our own page tables; the +0x007 is the attribute bits */ 149 leal (INIT_MAP_BEYOND_END+0x007)(%edi),%ebp 150 cmpl %ebp,%eax 151 jb 10b 152 movl %edi,(init_pg_tables_end - __PAGE_OFFSET) 153 154 xorl %ebx,%ebx /* This is the boot CPU (BSP) */ 155 jmp 3f 156/* 157 * Non-boot CPU entry point; entered from trampoline.S 158 * We can't lgdt here, because lgdt itself uses a data segment, but 159 * we know the trampoline has already loaded the boot_gdt for us. 160 * 161 * If cpu hotplug is not supported then this code can go in init section 162 * which will be freed later 163 */ 164 165#ifndef CONFIG_HOTPLUG_CPU 166.section .init.text,"ax",@progbits 167#endif 168 169 /* Do an early initialization of the fixmap area */ 170 movl $(swapper_pg_dir - __PAGE_OFFSET), %edx 171 movl $(swapper_pg_pmd - __PAGE_OFFSET), %eax 172 addl $0x007, %eax /* 0x007 = PRESENT+RW+USER */ 173 movl %eax, 4092(%edx) 174 175#ifdef CONFIG_SMP 176ENTRY(startup_32_smp) 177 cld 178 movl $(__BOOT_DS),%eax 179 movl %eax,%ds 180 movl %eax,%es 181 movl %eax,%fs 182 movl %eax,%gs 183 184/* 185 * New page tables may be in 4Mbyte page mode and may 186 * be using the global pages. 187 * 188 * NOTE! If we are on a 486 we may have no cr4 at all! 189 * So we do not try to touch it unless we really have 190 * some bits in it to set. This won't work if the BSP 191 * implements cr4 but this AP does not -- very unlikely 192 * but be warned! The same applies to the pse feature 193 * if not equally supported. --macro 194 * 195 * NOTE! We have to correct for the fact that we're 196 * not yet offset PAGE_OFFSET.. 197 */ 198#define cr4_bits mmu_cr4_features-__PAGE_OFFSET 199 movl cr4_bits,%edx 200 andl %edx,%edx 201 jz 6f 202 movl %cr4,%eax # Turn on paging options (PSE,PAE,..) 203 orl %edx,%eax 204 movl %eax,%cr4 205 206 btl $5, %eax # check if PAE is enabled 207 jnc 6f 208 209 /* Check if extended functions are implemented */ 210 movl $0x80000000, %eax 211 cpuid 212 cmpl $0x80000000, %eax 213 jbe 6f 214 mov $0x80000001, %eax 215 cpuid 216 /* Execute Disable bit supported? */ 217 btl $20, %edx 218 jnc 6f 219 220 /* Setup EFER (Extended Feature Enable Register) */ 221 movl $0xc0000080, %ecx 222 rdmsr 223 224 btsl $11, %eax 225 /* Make changes effective */ 226 wrmsr 227 2286: 229 /* This is a secondary processor (AP) */ 230 xorl %ebx,%ebx 231 incl %ebx 232 233#endif /* CONFIG_SMP */ 2343: 235 236/* 237 * Enable paging 238 */ 239 movl $swapper_pg_dir-__PAGE_OFFSET,%eax 240 movl %eax,%cr3 /* set the page table pointer.. */ 241 movl %cr0,%eax 242 orl $0x80000000,%eax 243 movl %eax,%cr0 /* ..and set paging (PG) bit */ 244 ljmp $__BOOT_CS,$1f /* Clear prefetch and normalize %eip */ 2451: 246 /* Set up the stack pointer */ 247 lss stack_start,%esp 248 249/* 250 * Initialize eflags. Some BIOS's leave bits like NT set. This would 251 * confuse the debugger if this code is traced. 252 * XXX - best to initialize before switching to protected mode. 253 */ 254 pushl $0 255 popfl 256 257#ifdef CONFIG_SMP 258 andl %ebx,%ebx 259 jz 1f /* Initial CPU cleans BSS */ 260 jmp checkCPUtype 2611: 262#endif /* CONFIG_SMP */ 263 264/* 265 * start system 32-bit setup. We need to re-do some of the things done 266 * in 16-bit mode for the "real" operations. 267 */ 268 call setup_idt 269 270checkCPUtype: 271 272 movl $-1,X86_CPUID # -1 for no CPUID initially 273 274/* check if it is 486 or 386. */ 275/* 276 * XXX - this does a lot of unnecessary setup. Alignment checks don't 277 * apply at our cpl of 0 and the stack ought to be aligned already, and 278 * we don't need to preserve eflags. 279 */ 280 281 movb $3,X86 # at least 386 282 pushfl # push EFLAGS 283 popl %eax # get EFLAGS 284 movl %eax,%ecx # save original EFLAGS 285 xorl $0x240000,%eax # flip AC and ID bits in EFLAGS 286 pushl %eax # copy to EFLAGS 287 popfl # set EFLAGS 288 pushfl # get new EFLAGS 289 popl %eax # put it in eax 290 xorl %ecx,%eax # change in flags 291 pushl %ecx # restore original EFLAGS 292 popfl 293 testl $0x40000,%eax # check if AC bit changed 294 je is386 295 296 movb $4,X86 # at least 486 297 testl $0x200000,%eax # check if ID bit changed 298 je is486 299 300 /* get vendor info */ 301 xorl %eax,%eax # call CPUID with 0 -> return vendor ID 302 cpuid 303 movl %eax,X86_CPUID # save CPUID level 304 movl %ebx,X86_VENDOR_ID # lo 4 chars 305 movl %edx,X86_VENDOR_ID+4 # next 4 chars 306 movl %ecx,X86_VENDOR_ID+8 # last 4 chars 307 308 orl %eax,%eax # do we have processor info as well? 309 je is486 310 311 movl $1,%eax # Use the CPUID instruction to get CPU type 312 cpuid 313 movb %al,%cl # save reg for future use 314 andb $0x0f,%ah # mask processor family 315 movb %ah,X86 316 andb $0xf0,%al # mask model 317 shrb $4,%al 318 movb %al,X86_MODEL 319 andb $0x0f,%cl # mask mask revision 320 movb %cl,X86_MASK 321 movl %edx,X86_CAPABILITY 322 323is486: movl $0x50022,%ecx # set AM, WP, NE and MP 324 jmp 2f 325 326is386: movl $2,%ecx # set MP 3272: movl %cr0,%eax 328 andl $0x80000011,%eax # Save PG,PE,ET 329 orl %ecx,%eax 330 movl %eax,%cr0 331 332 call check_x87 333 lgdt early_gdt_descr 334 lidt idt_descr 335 ljmp $(__KERNEL_CS),$1f 3361: movl $(__KERNEL_DS),%eax # reload all the segment registers 337 movl %eax,%ss # after changing gdt. 338 movl %eax,%fs # gets reset once there's real percpu 339 340 movl $(__USER_DS),%eax # DS/ES contains default USER segment 341 movl %eax,%ds 342 movl %eax,%es 343 344 xorl %eax,%eax # Clear GS and LDT 345 movl %eax,%gs 346 lldt %ax 347 348 cld # gcc2 wants the direction flag cleared at all times 349 pushl $0 # fake return address for unwinder 350#ifdef CONFIG_SMP 351 movb ready, %cl 352 movb $1, ready 353 cmpb $0,%cl # the first CPU calls start_kernel 354 je 1f 355 movl $(__KERNEL_PERCPU), %eax 356 movl %eax,%fs # set this cpu's percpu 357 jmp initialize_secondary # all other CPUs call initialize_secondary 3581: 359#endif /* CONFIG_SMP */ 360 jmp start_kernel 361 362/* 363 * We depend on ET to be correct. This checks for 287/387. 364 */ 365check_x87: 366 movb $0,X86_HARD_MATH 367 clts 368 fninit 369 fstsw %ax 370 cmpb $0,%al 371 je 1f 372 movl %cr0,%eax /* no coprocessor: have to set bits */ 373 xorl $4,%eax /* set EM */ 374 movl %eax,%cr0 375 ret 376 ALIGN 3771: movb $1,X86_HARD_MATH 378 .byte 0xDB,0xE4 /* fsetpm for 287, ignored by 387 */ 379 ret 380 381/* 382 * setup_idt 383 * 384 * sets up a idt with 256 entries pointing to 385 * ignore_int, interrupt gates. It doesn't actually load 386 * idt - that can be done only after paging has been enabled 387 * and the kernel moved to PAGE_OFFSET. Interrupts 388 * are enabled elsewhere, when we can be relatively 389 * sure everything is ok. 390 * 391 * Warning: %esi is live across this function. 392 */ 393setup_idt: 394 lea ignore_int,%edx 395 movl $(__KERNEL_CS << 16),%eax 396 movw %dx,%ax /* selector = 0x0010 = cs */ 397 movw $0x8E00,%dx /* interrupt gate - dpl=0, present */ 398 399 lea idt_table,%edi 400 mov $256,%ecx 401rp_sidt: 402 movl %eax,(%edi) 403 movl %edx,4(%edi) 404 addl $8,%edi 405 dec %ecx 406 jne rp_sidt 407 408.macro set_early_handler handler,trapno 409 lea \handler,%edx 410 movl $(__KERNEL_CS << 16),%eax 411 movw %dx,%ax 412 movw $0x8E00,%dx /* interrupt gate - dpl=0, present */ 413 lea idt_table,%edi 414 movl %eax,8*\trapno(%edi) 415 movl %edx,8*\trapno+4(%edi) 416.endm 417 418 set_early_handler handler=early_divide_err,trapno=0 419 set_early_handler handler=early_illegal_opcode,trapno=6 420 set_early_handler handler=early_protection_fault,trapno=13 421 set_early_handler handler=early_page_fault,trapno=14 422 423 ret 424 425early_divide_err: 426 xor %edx,%edx 427 pushl $0 /* fake errcode */ 428 jmp early_fault 429 430early_illegal_opcode: 431 movl $6,%edx 432 pushl $0 /* fake errcode */ 433 jmp early_fault 434 435early_protection_fault: 436 movl $13,%edx 437 jmp early_fault 438 439early_page_fault: 440 movl $14,%edx 441 jmp early_fault 442 443early_fault: 444 cld 445#ifdef CONFIG_PRINTK 446 movl $(__KERNEL_DS),%eax 447 movl %eax,%ds 448 movl %eax,%es 449 cmpl $2,early_recursion_flag 450 je hlt_loop 451 incl early_recursion_flag 452 movl %cr2,%eax 453 pushl %eax 454 pushl %edx /* trapno */ 455 pushl $fault_msg 456#ifdef CONFIG_EARLY_PRINTK 457 call early_printk 458#else 459 call printk 460#endif 461#endif 462hlt_loop: 463 hlt 464 jmp hlt_loop 465 466/* This is the default interrupt "handler" :-) */ 467 ALIGN 468ignore_int: 469 cld 470#ifdef CONFIG_PRINTK 471 pushl %eax 472 pushl %ecx 473 pushl %edx 474 pushl %es 475 pushl %ds 476 movl $(__KERNEL_DS),%eax 477 movl %eax,%ds 478 movl %eax,%es 479 cmpl $2,early_recursion_flag 480 je hlt_loop 481 incl early_recursion_flag 482 pushl 16(%esp) 483 pushl 24(%esp) 484 pushl 32(%esp) 485 pushl 40(%esp) 486 pushl $int_msg 487#ifdef CONFIG_EARLY_PRINTK 488 call early_printk 489#else 490 call printk 491#endif 492 addl $(5*4),%esp 493 popl %ds 494 popl %es 495 popl %edx 496 popl %ecx 497 popl %eax 498#endif 499 iret 500 501.section .text 502/* 503 * Real beginning of normal "text" segment 504 */ 505ENTRY(stext) 506ENTRY(_stext) 507 508/* 509 * BSS section 510 */ 511.section ".bss.page_aligned","wa" 512 .align PAGE_SIZE_asm 513ENTRY(swapper_pg_dir) 514 .fill 1024,4,0 515ENTRY(swapper_pg_pmd) 516 .fill 1024,4,0 517ENTRY(empty_zero_page) 518 .fill 4096,1,0 519 520/* 521 * This starts the data section. 522 */ 523.data 524ENTRY(stack_start) 525 .long init_thread_union+THREAD_SIZE 526 .long __BOOT_DS 527 528ready: .byte 0 529 530early_recursion_flag: 531 .long 0 532 533int_msg: 534 .asciz "Unknown interrupt or fault at EIP %p %p %p\n" 535 536fault_msg: 537 .ascii "Int %d: CR2 %p err %p EIP %p CS %p flags %p\n" 538 .asciz "Stack: %p %p %p %p %p %p %p %p\n" 539 540#include "../../x86/xen/xen-head.S" 541 542/* 543 * The IDT and GDT 'descriptors' are a strange 48-bit object 544 * only used by the lidt and lgdt instructions. They are not 545 * like usual segment descriptors - they consist of a 16-bit 546 * segment size, and 32-bit linear address value: 547 */ 548 549.globl boot_gdt_descr 550.globl idt_descr 551 552 ALIGN 553# early boot GDT descriptor (must use 1:1 address mapping) 554 .word 0 # 32 bit align gdt_desc.address 555boot_gdt_descr: 556 .word __BOOT_DS+7 557 .long boot_gdt - __PAGE_OFFSET 558 559 .word 0 # 32-bit align idt_desc.address 560idt_descr: 561 .word IDT_ENTRIES*8-1 # idt contains 256 entries 562 .long idt_table 563 564# boot GDT descriptor (later on used by CPU#0): 565 .word 0 # 32 bit align gdt_desc.address 566ENTRY(early_gdt_descr) 567 .word GDT_ENTRIES*8-1 568 .long per_cpu__gdt_page /* Overwritten for secondary CPUs */ 569 570/* 571 * The boot_gdt must mirror the equivalent in setup.S and is 572 * used only for booting. 573 */ 574 .align L1_CACHE_BYTES 575ENTRY(boot_gdt) 576 .fill GDT_ENTRY_BOOT_CS,8,0 577 .quad 0x00cf9a000000ffff /* kernel 4GB code at 0x00000000 */ 578 .quad 0x00cf92000000ffff /* kernel 4GB data at 0x00000000 */ 579