2 * linux/arch/x86_64/kernel/head.S -- start in 32bit and switch to 64bit
4 * Copyright (C) 2000 Andrea Arcangeli <andrea@suse.de> SuSE
5 * Copyright (C) 2000 Pavel Machek <pavel@suse.cz>
6 * Copyright (C) 2000 Karsten Keil <kkeil@suse.de>
7 * Copyright (C) 2001,2002 Andi Kleen <ak@suse.de>
9 * $Id: head.S,v 1.49 2002/03/19 17:39:25 ak Exp $
11 * Jun Nakajima <jun.nakajima@intel.com>
16 #include <linux/linkage.h>
17 #include <linux/threads.h>
18 #include <linux/init.h>
20 #include <asm/segment.h>
23 #include <asm/cache.h>
26 .section .bootstrap.text
28 #define VIRT_ENTRY_OFFSET 0x0
29 .org VIRT_ENTRY_OFFSET
33 movq $(init_thread_union+THREAD_SIZE-8),%rsp
34 /* zero EFLAGS after setting rsp */
38 /* rsi is pointer to startup info structure.
41 jmp x86_64_start_kernel
47 #define NEXT_PAGE(name) \
49 .org $page * 0x1000; \
50 phys_/**/name = $page * 0x1000 + __PHYSICAL_START; \
53 NEXT_PAGE(init_level4_pgt)
54 /* This gets initialized in x86_64_start_kernel */
58 * We update two pgd entries to make kernel and user pgd consistent
59 * at pgd_populate(). It can be used for kernel modules. So we place
60 * this page here for those cases to avoid memory corruption.
61 * We also use this page to establish the initiali mapping for
64 NEXT_PAGE(init_level4_user_pgt)
67 NEXT_PAGE(level3_kernel_pgt)
71 * This is used for vsyscall area mapping as we have a different
72 * level4 page table for user.
74 NEXT_PAGE(level3_user_pgt)
77 NEXT_PAGE(level2_kernel_pgt)
80 NEXT_PAGE(hypercall_page)
90 .word gdt_end-cpu_gdt_table-1
100 /* We need valid kernel segments for data and code in long mode too
101 * IRET will check the segment types kkeil 2000/10/28
102 * Also sysret mandates a special GDT layout
105 .section .data.page_aligned, "aw"
108 /* The TLS descriptors are currently at a different place compared to i386.
109 Hopefully nobody expects them at a fixed place (Wine?) */
112 .quad 0x0000000000000000 /* NULL descriptor */
113 .quad 0x0 /* unused */
114 .quad 0x00af9a000000ffff /* __KERNEL_CS */
115 .quad 0x00cf92000000ffff /* __KERNEL_DS */
116 .quad 0x00cffa000000ffff /* __USER32_CS */
117 .quad 0x00cff2000000ffff /* __USER_DS, __USER32_DS */
118 .quad 0x00affa000000ffff /* __USER_CS */
119 .quad 0x00cf9a000000ffff /* __KERNEL32_CS */
122 .quad 0,0,0 /* three TLS descriptors */
125 /* asm/segment.h:GDT_ENTRIES must match this */
126 /* This should be a multiple of the cache line size */
127 /* GDTs of other CPUs are now dynamically allocated */
129 /* zero the remaining page */
130 .fill PAGE_SIZE / 8 - GDT_ENTRIES,8,0
132 .section .bss, "aw", @nobits
133 .align L1_CACHE_BYTES
137 .section .bss.page_aligned, "aw", @nobits
139 ENTRY(empty_zero_page)
143 * __xen_guest information
146 .if (\value) < 0 || (\value) >= 0x10
147 utoh (((\value)>>4)&0x0fffffffffffffff)
149 .if ((\value) & 0xf) < 10
150 .byte '0' + ((\value) & 0xf)
152 .byte 'A' + ((\value) & 0xf) - 10
157 .ascii "GUEST_OS=linux,GUEST_VER=2.6"
158 .ascii ",XEN_VER=xen-3.0"
159 .ascii ",VIRT_BASE=0x"
160 utoh __START_KERNEL_map
161 #ifdef CONFIG_XEN_COMPAT_030002
162 .ascii ",ELF_PADDR_OFFSET=0x"
163 utoh __START_KERNEL_map
165 .ascii ",ELF_PADDR_OFFSET=0x0"
166 #endif /* !CONFIG_XEN_COMPAT_030002 */
167 .ascii ",VIRT_ENTRY=0x"
168 utoh (__START_KERNEL_map + __PHYSICAL_START + VIRT_ENTRY_OFFSET)
169 .ascii ",HYPERCALL_PAGE=0x"
170 utoh (phys_hypercall_page >> PAGE_SHIFT)
171 .ascii ",FEATURES=writable_page_tables"
172 .ascii "|writable_descriptor_tables"
173 .ascii "|auto_translated_physmap"
174 .ascii "|supervisor_mode_kernel"
175 .ascii ",LOADER=generic"