2 * linux/arch/i386/head.S -- the 32-bit startup code.
4 * Copyright (C) 1991, 1992 Linus Torvalds
6 * Enhanced CPU detection and feature setting code by Mike Jagdis
7 * and Martin Mares, November 1997.
11 #include <linux/config.h>
12 #include <linux/threads.h>
13 #include <linux/linkage.h>
14 #include <asm/segment.h>
16 #include <asm/pgtable.h>
19 #define OLD_CL_MAGIC_ADDR 0x90020
20 #define OLD_CL_MAGIC 0xA33F
21 #define OLD_CL_BASE_ADDR 0x90000
22 #define OLD_CL_OFFSET 0x90022
23 #define NEW_CL_POINTER 0x228 /* Relative to real mode data */
26 * References to members of the boot_cpu_data structure.
29 #define CPU_PARAMS SYMBOL_NAME(boot_cpu_data)
30 #define X86 CPU_PARAMS+0
31 #define X86_VENDOR CPU_PARAMS+1
32 #define X86_MODEL CPU_PARAMS+2
33 #define X86_MASK CPU_PARAMS+3
34 #define X86_HARD_MATH CPU_PARAMS+6
35 #define X86_CPUID CPU_PARAMS+8
36 #define X86_CAPABILITY CPU_PARAMS+12
37 #define X86_VENDOR_ID CPU_PARAMS+16
40 * swapper_pg_dir is the main page directory, address 0x00101000
42 * On entry, %esi points to the real-mode code as a 32-bit pointer.
48 * Set segments to known values
51 movl $(__KERNEL_DS),%eax
61 * New page tables may be in 4Mbyte page mode and may
62 * be using the global pages.
64 * NOTE! If we are on a 486 we may have no cr4 at all!
65 * So we do not try to touch it unless we really have
66 * some bits in it to set. This won't work if the BSP
67 * implements cr4 but this AP does not -- very unlikely
68 * but be warned! The same applies to the pse feature
69 * if not equally supported. --macro
71 * NOTE! We have to correct for the fact that we're
72 * not yet offset PAGE_OFFSET..
74 #define cr4_bits mmu_cr4_features-__PAGE_OFFSET
77 movl %cr4,%eax # Turn on paging options (PSE,PAE,..)
84 * Initialize page tables
86 movl $pg0-__PAGE_OFFSET,%edi /* initialize page tables */
87 movl $007,%eax /* "007" doesn't mean with right to kill, but
91 cmp $empty_zero_page-__PAGE_OFFSET,%edi
98 movl $swapper_pg_dir-__PAGE_OFFSET,%eax
99 movl %eax,%cr3 /* set the page table pointer.. */
102 movl %eax,%cr0 /* ..and set paging (PG) bit */
103 jmp 1f /* flush the prefetch-queue */
106 jmp *%eax /* make sure eip is relocated */
108 /* Set up the stack pointer */
113 jz 1f /* Initial CPU cleans BSS */
121 * Clear BSS first so that there are no surprises...
124 movl $ SYMBOL_NAME(__bss_start),%edi
125 movl $ SYMBOL_NAME(_end),%ecx
132 * start system 32-bit setup. We need to re-do some of the things done
133 * in 16-bit mode for the "real" operations.
137 * Initialize eflags. Some BIOS's leave bits like NT set. This would
138 * confuse the debugger if this code is traced.
139 * XXX - best to initialize before switching to protected mode.
144 * Copy bootup parameters out of the way. First 2kB of
145 * _empty_zero_page is for boot parameters, second 2kB
146 * is for the command line.
148 * Note: %esi still has the pointer to the real-mode data.
150 movl $ SYMBOL_NAME(empty_zero_page),%edi
159 movl SYMBOL_NAME(empty_zero_page)+NEW_CL_POINTER,%esi
161 jnz 2f # New command line protocol
162 cmpw $(OLD_CL_MAGIC),OLD_CL_MAGIC_ADDR
164 movzwl OLD_CL_OFFSET,%esi
165 addl $(OLD_CL_BASE_ADDR),%esi
167 movl $ SYMBOL_NAME(empty_zero_page)+2048,%edi
176 movl $-1,X86_CPUID # -1 for no CPUID initially
178 /* check if it is 486 or 386. */
180 * XXX - this does a lot of unnecessary setup. Alignment checks don't
181 * apply at our cpl of 0 and the stack ought to be aligned already, and
182 * we don't need to preserve eflags.
185 movl $3,X86 # at least 386
187 popl %eax # get EFLAGS
188 movl %eax,%ecx # save original EFLAGS
189 xorl $0x40000,%eax # flip AC bit in EFLAGS
190 pushl %eax # copy to EFLAGS
192 pushfl # get new EFLAGS
193 popl %eax # put it in eax
194 xorl %ecx,%eax # change in flags
195 andl $0x40000,%eax # check if AC bit changed
198 movl $4,X86 # at least 486
200 xorl $0x200000,%eax # check ID flag
202 popfl # if we are on a straight 486DX, SX, or
203 pushfl # 487SX we can't change it
206 pushl %ecx # restore original EFLAGS
211 /* get vendor info */
212 xorl %eax,%eax # call CPUID with 0 -> return vendor ID
214 movl %eax,X86_CPUID # save CPUID level
215 movl %ebx,X86_VENDOR_ID # lo 4 chars
216 movl %edx,X86_VENDOR_ID+4 # next 4 chars
217 movl %ecx,X86_VENDOR_ID+8 # last 4 chars
219 orl %eax,%eax # do we have processor info as well?
222 movl $1,%eax # Use the CPUID instruction to get CPU type
224 movb %al,%cl # save reg for future use
225 andb $0x0f,%ah # mask processor family
227 andb $0xf0,%al # mask model
230 andb $0x0f,%cl # mask mask revision
232 movl %edx,X86_CAPABILITY
235 movl %cr0,%eax # 486 or better
236 andl $0x80000011,%eax # Save PG,PE,ET
237 orl $0x50022,%eax # set AM, WP, NE and MP
240 is386: pushl %ecx # restore original EFLAGS
243 andl $0x80000011,%eax # Save PG,PE,ET
252 ljmp $(__KERNEL_CS),$1f
253 1: movl $(__KERNEL_DS),%eax # reload all the segment registers
254 movl %eax,%ds # after changing gdt.
259 movl $(__KERNEL_DS), %eax
260 movl %eax,%ss # Reload the stack pointer (segment only)
262 lss stack_start,%esp # Load processor stack
266 cld # gcc2 wants the direction flag cleared at all times
270 je 1f # the first CPU calls start_kernel
271 # all other CPUs call initialize_secondary
272 call SYMBOL_NAME(initialize_secondary)
276 call SYMBOL_NAME(start_kernel)
278 jmp L6 # main should never return here, but
279 # just in case, we know what happens.
286 * We depend on ET to be correct. This checks for 287/387.
289 movb $0,X86_HARD_MATH
295 movl %cr0,%eax /* no coprocessor: have to set bits */
296 xorl $4,%eax /* set EM */
300 1: movb $1,X86_HARD_MATH
301 .byte 0xDB,0xE4 /* fsetpm for 287, ignored by 387 */
307 * sets up a idt with 256 entries pointing to
308 * ignore_int, interrupt gates. It doesn't actually load
309 * idt - that can be done only after paging has been enabled
310 * and the kernel moved to PAGE_OFFSET. Interrupts
311 * are enabled elsewhere, when we can be relatively
312 * sure everything is ok.
316 movl $(__KERNEL_CS << 16),%eax
317 movw %dx,%ax /* selector = 0x0010 = cs */
318 movw $0x8E00,%dx /* interrupt gate - dpl=0, present */
320 lea SYMBOL_NAME(idt_table),%edi
331 .long SYMBOL_NAME(init_task_union)+8192
334 /* This is the default interrupt "handler" :-) */
336 .asciz "Unknown interrupt\n"
345 movl $(__KERNEL_DS),%eax
349 call SYMBOL_NAME(printk)
359 * The interrupt descriptor table has room for 256 idt's,
360 * the global descriptor table is dependent on the number
361 * of tasks we can have..
363 #define IDT_ENTRIES 256
364 #define GDT_ENTRIES (__TSS(NR_CPUS))
367 .globl SYMBOL_NAME(idt)
368 .globl SYMBOL_NAME(gdt)
373 .word IDT_ENTRIES*8-1 # idt contains 256 entries
375 .long SYMBOL_NAME(idt_table)
379 .word GDT_ENTRIES*8-1
381 .long SYMBOL_NAME(gdt_table)
384 * This is initialized to create an identity-mapping at 0-8M (for bootup
385 * purposes) and another mapping of the 0-8M area at virtual address
389 ENTRY(swapper_pg_dir)
392 .fill BOOT_USER_PGD_PTRS-2,4,0
393 /* default: 766 entries */
396 /* default: 254 entries */
397 .fill BOOT_KERNEL_PGD_PTRS-2,4,0
400 * The page tables are initialized to only 8MB here - the final page
401 * tables are set up later depending on memory size.
410 * empty_zero_page must immediately follow the page tables ! (The
411 * initialization loop counts until empty_zero_page)
415 ENTRY(empty_zero_page)
418 ENTRY(empty_bad_page)
421 ENTRY(empty_bad_pte_table)
426 ENTRY(empty_bad_pmd_table)
437 * This starts the data section. Note that the above is all
438 * in the text section because it has alignment requirements
439 * that we cannot fulfill any other way.
445 * This contains typically 140 quadwords, depending on NR_CPUS.
447 * NOTE! Make sure the gdt descriptor in head.S matches this if you
451 .quad 0x0000000000000000 /* NULL descriptor */
452 .quad 0x0000000000000000 /* not used */
453 .quad 0x00cf9a000000ffff /* 0x10 kernel 4GB code at 0x00000000 */
454 .quad 0x00cf92000000ffff /* 0x18 kernel 4GB data at 0x00000000 */
455 .quad 0x00cffa000000ffff /* 0x23 user 4GB code at 0x00000000 */
456 .quad 0x00cff2000000ffff /* 0x2b user 4GB data at 0x00000000 */
457 .quad 0x0000000000000000 /* not used */
458 .quad 0x0000000000000000 /* not used */
460 * The APM segments have byte granularity and their bases
461 * and limits are set at run time.
463 .quad 0x0040920000000000 /* 0x40 APM set up for bad BIOS's */
464 .quad 0x00409a0000000000 /* 0x48 APM CS code */
465 .quad 0x00009a0000000000 /* 0x50 APM CS 16 code (16 bit) */
466 .quad 0x0040920000000000 /* 0x58 APM DS data */
467 .fill NR_CPUS*4,8,0 /* space for TSS's and LDT's */
470 * This is to aid debugging, the various locking macros will be putting
471 * code fragments here. When an oops occurs we'd rather know that it's
472 * inside the .text.lock section rather than as some offset from whatever
473 * function happens to be last in the .text segment.