ia64/xen-unstable

view linux-2.6-xen-sparse/arch/x86_64/kernel/head-xen.S @ 8758:57e6d7218427

Fix hypercall_page location on x86_64.

Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
author cl349@firebug.cl.cam.ac.uk
date Fri Feb 03 18:45:14 2006 +0000 (2006-02-03)
parents 2494b4e00cbb
children 1bc2d1fe503c
line source
1 /*
2 * linux/arch/x86_64/kernel/head.S -- start in 32bit and switch to 64bit
3 *
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 *
9 * $Id: head.S,v 1.49 2002/03/19 17:39:25 ak Exp $
10 *
11 * Jun Nakajima <jun.nakajima@intel.com>
12 * Modified for Xen
13 */
16 #include <linux/linkage.h>
18 .section __xen_guest
19 .ascii "GUEST_OS=linux,GUEST_VER=2.6"
20 .ascii ",XEN_VER=xen-3.0"
21 .ascii ",VIRT_BASE=0xffffffff80000000"
22 .ascii ",HYPERCALL_PAGE=0x10a" /* __pa(hypercall_page) >> 12 */
23 .ascii ",LOADER=generic"
24 .byte 0
26 #include <linux/threads.h>
27 #include <linux/init.h>
28 #include <asm/desc.h>
29 #include <asm/segment.h>
30 #include <asm/page.h>
31 #include <asm/msr.h>
32 #include <asm/cache.h>
34 /* we are not able to switch in one step to the final KERNEL ADRESS SPACE
35 * because we need identity-mapped pages on setup so define __START_KERNEL to
36 * 0x100000 for this stage
37 *
38 */
40 .text
41 .code64
42 .globl startup_64
43 startup_64:
44 ENTRY(_start)
45 movq %rsi,xen_start_info(%rip)
47 #ifdef CONFIG_SMP
48 ENTRY(startup_64_smp)
49 #endif /* CONFIG_SMP */
51 cld
53 movq init_rsp(%rip),%rsp
54 /* zero EFLAGS after setting rsp */
55 pushq $0
56 popfq
57 movq initial_code(%rip),%rax
58 jmp *%rax
60 /* SMP bootup changes these two */
61 .globl initial_code
62 initial_code:
63 .quad x86_64_start_kernel
64 .globl init_rsp
65 init_rsp:
66 .quad init_thread_union+THREAD_SIZE-8
68 ENTRY(early_idt_handler)
69 xorl %eax,%eax
70 movq 8(%rsp),%rsi # get rip
71 movq (%rsp),%rdx
72 leaq early_idt_msg(%rip),%rdi
73 1: hlt # generate #GP
74 jmp 1b
76 early_idt_msg:
77 .asciz "PANIC: early exception rip %lx error %lx cr2 %lx\n"
79 #if 0
80 ENTRY(lgdt_finish)
81 movl $(__USER_DS),%eax # DS/ES contains default USER segment
82 movw %ax,%ds
83 movw %ax,%es
84 movl $(__KERNEL_DS),%eax
85 movw %ax,%ss # after changing gdt.
86 popq %rax # get the retrun address
87 pushq $(__KERNEL_CS)
88 pushq %rax
89 lretq
90 #endif
92 ENTRY(stext)
93 ENTRY(_stext)
95 $page = 0
96 #define NEXT_PAGE(name) \
97 $page = $page + 1; \
98 .org $page * 0x1000; \
99 phys_/**/name = $page * 0x1000 + __PHYSICAL_START; \
100 ENTRY(name)
102 NEXT_PAGE(init_level4_pgt)
103 /* This gets initialized in x86_64_start_kernel */
104 .fill 512,8,0
106 /*
107 * We update two pgd entries to make kernel and user pgd consistent
108 * at pgd_populate(). It can be used for kernel modules. So we place
109 * this page here for those cases to avoid memory corruption.
110 * We also use this page to establish the initiali mapping for
111 * vsyscall area.
112 */
113 NEXT_PAGE(init_level4_user_pgt)
114 .fill 512,8,0
116 /*
117 * In Xen the following pre-initialized pgt entries are re-initialized.
118 */
119 NEXT_PAGE(level3_kernel_pgt)
120 .fill 510,8,0
121 /* (2^48-(2*1024*1024*1024)-((2^39)*511))/(2^30) = 510 */
122 .quad phys_level2_kernel_pgt | 0x007
123 .fill 1,8,0
125 NEXT_PAGE(level2_ident_pgt)
126 /* 40MB for bootup. */
127 i = 0
128 .rept 20
129 .quad i << 21 | 0x083
130 i = i + 1
131 .endr
132 /* Temporary mappings for the super early allocator in arch/x86_64/mm/init.c */
133 .globl temp_boot_pmds
134 temp_boot_pmds:
135 .fill 492,8,0
137 NEXT_PAGE(level2_kernel_pgt)
138 /* 40MB kernel mapping. The kernel code cannot be bigger than that.
139 When you change this change KERNEL_TEXT_SIZE in page.h too. */
140 /* (2^48-(2*1024*1024*1024)-((2^39)*511)-((2^30)*510)) = 0 */
141 i = 0
142 .rept 20
143 .quad i << 21 | 0x183
144 i = i + 1
145 .endr
146 /* Module mapping starts here */
147 .fill 492,8,0
149 /*
150 * This is used for vsyscall area mapping as we have a different
151 * level4 page table for user.
152 */
153 NEXT_PAGE(level3_user_pgt)
154 .fill 512,8,0
156 NEXT_PAGE(cpu_gdt_table)
157 /* The TLS descriptors are currently at a different place compared to i386.
158 Hopefully nobody expects them at a fixed place (Wine?) */
159 .quad 0x0000000000000000 /* NULL descriptor */
160 .quad 0x0 /* unused */
161 .quad 0x00affa000000ffff /* __KERNEL_CS */
162 .quad 0x00cff2000000ffff /* __KERNEL_DS */
163 .quad 0x00cffa000000ffff /* __USER32_CS */
164 .quad 0x00cff2000000ffff /* __USER_DS, __USER32_DS */
165 .quad 0x00affa000000ffff /* __USER_CS */
166 .quad 0x00cffa000000ffff /* __KERNEL32_CS */
167 .quad 0,0 /* TSS */
168 .quad 0,0 /* LDT */
169 .quad 0,0,0 /* three TLS descriptors */
170 .quad 0 /* unused */
171 gdt_end:
172 #if 0
173 /* asm/segment.h:GDT_ENTRIES must match this */
174 /* This should be a multiple of the cache line size */
175 /* GDTs of other CPUs are now dynamically allocated */
177 /* zero the remaining page */
178 .fill PAGE_SIZE / 8 - GDT_ENTRIES,8,0
179 #endif
181 NEXT_PAGE(empty_zero_page)
183 NEXT_PAGE(level3_physmem_pgt)
184 .quad phys_level2_kernel_pgt | 0x007 /* so that __va works even before pagetable_init */
186 NEXT_PAGE(hypercall_page)
187 .if (phys_hypercall_page - 0x10a000)
188 /* cause compiler error if the hypercall_page is at a
189 * different address than expected. */
190 .quad __adjust_hypercall_page_in_header
191 .endif
193 #undef NEXT_PAGE
195 .data
197 #ifndef CONFIG_XEN
198 #ifdef CONFIG_ACPI_SLEEP
199 .align PAGE_SIZE
200 ENTRY(wakeup_level4_pgt)
201 .quad phys_level3_ident_pgt | 0x007
202 .fill 255,8,0
203 .quad phys_level3_physmem_pgt | 0x007
204 .fill 254,8,0
205 /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */
206 .quad phys_level3_kernel_pgt | 0x007
207 #endif
209 #ifndef CONFIG_HOTPLUG_CPU
210 __INITDATA
211 #endif
212 /*
213 * This default setting generates an ident mapping at address 0x100000
214 * and a mapping for the kernel that precisely maps virtual address
215 * 0xffffffff80000000 to physical address 0x000000. (always using
216 * 2Mbyte large pages provided by PAE mode)
217 */
218 .align PAGE_SIZE
219 ENTRY(boot_level4_pgt)
220 .quad phys_level3_ident_pgt | 0x007
221 .fill 255,8,0
222 .quad phys_level3_physmem_pgt | 0x007
223 .fill 254,8,0
224 /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */
225 .quad phys_level3_kernel_pgt | 0x007
226 #endif
228 .data
230 .align 16
231 .globl cpu_gdt_descr
232 cpu_gdt_descr:
233 .word gdt_end-cpu_gdt_table
234 gdt:
235 .quad cpu_gdt_table
236 #ifdef CONFIG_SMP
237 .rept NR_CPUS-1
238 .word 0
239 .quad 0
240 .endr
241 #endif
243 /* We need valid kernel segments for data and code in long mode too
244 * IRET will check the segment types kkeil 2000/10/28
245 * Also sysret mandates a special GDT layout
246 */
248 .align PAGE_SIZE
250 ENTRY(idt_table)
251 .rept 256
252 .quad 0
253 .quad 0
254 .endr