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>
8 * Copyright (C) 2005 Eric Biederman <ebiederm@xmission.com>
9 * Jun Nakajima <jun.nakajima@intel.com>
14 #include <linux/linkage.h>
15 #include <linux/threads.h>
16 #include <linux/init.h>
17 #include <linux/elfnote.h>
18 #include <asm/segment.h>
20 #include <asm/pgtable.h>
22 #include <asm/cache.h>
23 #include <asm/dwarf2.h>
24 #include <asm/percpu.h>
25 #include <xen/interface/elfnote.h>
26 #include <xen/interface/features.h>
32 movq $(init_thread_union+THREAD_SIZE-8),%rsp
34 /* rsi is pointer to startup info structure.
40 * The base of %gs always points to the bottom of the irqstack
41 * union. If the stack protector canary is enabled, it is
42 * located at %gs:40. Note that, on SMP, the boot cpu uses
43 * init data section till per cpu areas are set up.
45 movl $MSR_GS_BASE,%ecx
46 movq $INIT_PER_CPU_VAR(irq_stack_union),%rax
51 pushq $0 # fake return address
52 jmp x86_64_start_kernel
54 #define NEXT_PAGE(name) \
59 NEXT_PAGE(init_level4_pgt)
62 NEXT_PAGE(level3_kernel_pgt)
66 * This is used for vsyscall area mapping as we have a different
67 * level4 page table for user.
69 NEXT_PAGE(level3_user_pgt)
72 NEXT_PAGE(level2_fixmap_pgt)
75 NEXT_PAGE(level1_fixmap_pgt)
79 NEXT_PAGE(hypercall_page)
80 phys_hypercall_page = . - .head.text
83 .skip 1 /* push %rcx */
84 CFI_ADJUST_CFA_OFFSET 8
86 .skip 2 /* push %r11 */
87 CFI_ADJUST_CFA_OFFSET 8
89 .skip 5 /* mov $#,%eax */
91 .skip 2 /* pop %r11 */
92 CFI_ADJUST_CFA_OFFSET -8
94 .skip 1 /* pop %rcx */
95 CFI_ADJUST_CFA_OFFSET -8
97 .align 0x20,0 /* ret */
105 ENTRY(empty_zero_page)
108 #ifdef CONFIG_XEN_UNPRIVILEGED_GUEST
109 # define XEN_DOM0_CAP 0
110 # define XEN_DOM0_CAP_STR ""
112 # define XEN_DOM0_CAP (1 << XENFEAT_dom0)
113 # if CONFIG_XEN_COMPAT < 0x040200
114 # define XEN_DOM0_CAP_STR ""
116 # define XEN_DOM0_CAP_STR "|dom0"
120 #if CONFIG_XEN_COMPAT <= 0x030002
122 * __xen_guest information
128 .byte '0' + ((((\value) >> i) & 0xf) > 9) * ('0' - 'A' + 10) + (((\value) >> i) & 0xf)
133 .ascii "GUEST_OS=linux,GUEST_VER=2.6"
134 .ascii ",XEN_VER=xen-3.0"
135 .ascii ",VIRT_BASE=0x"
136 utoh __START_KERNEL_map
137 .ascii ",ELF_PADDR_OFFSET=0x"
138 utoh __START_KERNEL_map
139 .ascii ",VIRT_ENTRY=0x"
140 utoh (__START_KERNEL_map + __PHYSICAL_START)
141 .ascii ",HYPERCALL_PAGE=0x"
142 utoh (phys_hypercall_page >> PAGE_SHIFT)
143 .ascii ",FEATURES=writable_page_tables"
144 .ascii "|writable_descriptor_tables"
145 .ascii "|auto_translated_physmap"
146 .ascii "|supervisor_mode_kernel"
147 .ascii ",LOADER=generic"
149 #endif /* CONFIG_XEN_COMPAT <= 0x030002 */
151 ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS, .asciz "linux")
152 ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION, .asciz "2.6")
153 ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION, .asciz "xen-3.0")
154 ELFNOTE(Xen, XEN_ELFNOTE_VIRT_BASE, .quad __START_KERNEL_map)
155 #if CONFIG_XEN_COMPAT <= 0x030002
156 ELFNOTE(Xen, XEN_ELFNOTE_PADDR_OFFSET, .quad __START_KERNEL_map)
158 ELFNOTE(Xen, XEN_ELFNOTE_PADDR_OFFSET, .quad 0)
160 ELFNOTE(Xen, XEN_ELFNOTE_ENTRY, .quad startup_64)
161 ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, .quad hypercall_page)
162 ELFNOTE(Xen, XEN_ELFNOTE_L1_MFN_VALID, .quad _PAGE_PRESENT, _PAGE_PRESENT)
163 ELFNOTE(Xen, XEN_ELFNOTE_MOD_START_PFN, .long 1)
164 ELFNOTE(Xen, XEN_ELFNOTE_INIT_P2M, .quad VMEMMAP_START)
165 ELFNOTE(Xen, XEN_ELFNOTE_FEATURES, .ascii "writable_page_tables";
166 .ascii "|writable_descriptor_tables";
167 .ascii "|auto_translated_physmap";
168 .ascii "|supervisor_mode_kernel";
169 .asciz XEN_DOM0_CAP_STR)
170 ELFNOTE(Xen, XEN_ELFNOTE_SUPPORTED_FEATURES, .long XEN_DOM0_CAP |
171 (1 << XENFEAT_writable_page_tables) |
172 (1 << XENFEAT_writable_descriptor_tables) |
173 (1 << XENFEAT_auto_translated_physmap) |
174 (1 << XENFEAT_supervisor_mode_kernel))
175 ELFNOTE(Xen, XEN_ELFNOTE_LOADER, .asciz "generic")
176 ELFNOTE(Xen, XEN_ELFNOTE_SUSPEND_CANCEL, .long 1)