This commit was generated by cvs2svn to compensate for changes in r925,
[linux-2.6.git] / arch / xen / x86_64 / kernel / head.S
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  */
14
15
16 #include <linux/linkage.h>
17
18 .section __xen_guest
19         .ascii  "GUEST_OS=linux,GUEST_VER=2.6,XEN_VER=3.0,VIRT_BASE=0xffffffff80100000"
20         .ascii  ",LOADER=generic"
21 /*      .ascii  ",PT_MODE_WRITABLE" */
22         .byte   0
23                 
24       
25 #include <linux/threads.h>
26 #include <asm/desc.h>
27 #include <asm/segment.h>
28 #include <asm/page.h>
29 #include <asm/msr.h>
30 #include <asm/cache.h>
31 /* #include <asm/thread_info.h> */
32         
33         
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  */
39
40         .text
41         .code64
42 ENTRY(_start)
43         cld                
44         movq init_rsp(%rip),%rsp
45         /* Copy the necessary stuff from xen_start_info structure. */
46         movq  $xen_start_info_union,%rdi
47         movq  $64,%rcx          /* sizeof (union xen_start_info_union) / sizeof (long) */
48         rep movsq
49
50 #ifdef CONFIG_SMP
51         ENTRY(startup_64_smp)
52         cld
53 #endif /* CONFIG_SMP */
54
55         /* zero EFLAGS after setting rsp */
56         pushq $0
57         popfq
58         movq    initial_code(%rip),%rax
59         jmp     *%rax
60
61         /* SMP bootup changes these two */      
62         .globl  initial_code
63 initial_code:
64         .quad   x86_64_start_kernel
65         .globl init_rsp
66 init_rsp:
67         .quad  init_thread_union+THREAD_SIZE-8
68
69 ENTRY(early_idt_handler)
70         xorl %eax,%eax
71         movq 8(%rsp),%rsi       # get rip
72         movq (%rsp),%rdx
73         leaq early_idt_msg(%rip),%rdi
74 1:      hlt                     # generate #GP
75         jmp 1b
76
77 early_idt_msg:
78         .asciz "PANIC: early exception rip %lx error %lx cr2 %lx\n"
79
80 #if 0
81 ENTRY(lgdt_finish)
82         movl $(__USER_DS),%eax          # DS/ES contains default USER segment
83         movw %ax,%ds
84         movw %ax,%es
85         movl $(__KERNEL_DS),%eax        
86         movw %ax,%ss                    # after changing gdt.
87         popq %rax                       # get the retrun address
88         pushq $(__KERNEL_CS)
89         pushq %rax
90         lretq
91 #endif 
92
93 ENTRY(stext)
94 ENTRY(_stext)
95
96         /*
97          * This default setting generates an ident mapping at address 0x100000
98          * and a mapping for the kernel that precisely maps virtual address
99          * 0xffffffff80000000 to physical address 0x000000. (always using
100          * 2Mbyte large pages provided by PAE mode)
101          */
102 .org 0x1000
103 ENTRY(init_level4_pgt)
104         .fill   512,8,0
105
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 .org 0x2000
114 ENTRY(init_level4_user_pgt)
115         .fill   512,8,0
116
117         /*
118          * This is used for vsyscall area mapping as we have a different
119          * level4 page table for user.
120          */
121 .org 0x3000
122 ENTRY(level3_user_pgt)
123         .fill   512,8,0
124
125 .org 0x4000
126 ENTRY(cpu_gdt_table)
127 /* The TLS descriptors are currently at a different place compared to i386.
128    Hopefully nobody expects them at a fixed place (Wine?) */
129         .quad   0x0000000000000000      /* NULL descriptor */
130         .quad   0x008ffa000000ffff      /* __KERNEL_COMPAT32_CS */      
131         .quad   0x00affa000000ffff      /* __KERNEL_CS */
132         .quad   0x00cff2000000ffff      /* __KERNEL_DS */
133         
134         .quad   0x00cffa000000ffff      /* __USER32_CS */
135         .quad   0x00cff2000000ffff      /* __USER_DS, __USER32_DS  */           
136         .quad   0x00affa000000ffff      /* __USER_CS */
137         .quad   0x00cffa000000ffff      /* __KERNEL32_CS */        
138         .quad   0,0                     /* TSS */
139         .quad   0                       /* LDT */
140         .quad   0,0,0                   /* three TLS descriptors */ 
141         .quad   0                       /* unused now */
142
143 gdt_end:        
144         /* asm/segment.h:GDT_ENTRIES must match this */ 
145         /* This should be a multiple of the cache line size */
146         /* GDTs of other CPUs: */       
147         .fill (GDT_SIZE * NR_CPUS) - (gdt_end - cpu_gdt_table)
148
149 .org 0x5000
150 ENTRY(empty_zero_page)
151
152 .org 0x6000
153 ENTRY(empty_bad_page)
154
155 .org 0x7000
156 ENTRY(empty_bad_pte_table)
157
158 .org 0x8000
159 ENTRY(empty_bad_pmd_table)
160
161         .org 0x9000
162 #ifdef CONFIG_ACPI_SLEEP
163 ENTRY(wakeup_level4_pgt)
164         .quad   0x0000000000102007              /* -> level3_ident_pgt */
165         .fill   255,8,0
166         .quad   0x000000000010a007
167         .fill   254,8,0
168         /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */
169         .quad   0x0000000000103007              /* -> level3_kernel_pgt */
170 #endif
171
172         .data
173
174         .align 16
175         .globl cpu_gdt_descr
176 cpu_gdt_descr:
177         .word   gdt_end-cpu_gdt_table
178 gdt:
179         .quad   cpu_gdt_table
180 #ifdef CONFIG_SMP
181         .rept   NR_CPUS-1
182         .word   0
183         .quad   0
184         .endr
185 #endif
186
187 ENTRY(gdt_table32)
188         .quad   0x0000000000000000      /* This one is magic */
189         .quad   0x0000000000000000      /* unused */
190         .quad   0x00af9a000000ffff      /* __KERNEL_CS */
191 gdt32_end:      
192         
193 /* We need valid kernel segments for data and code in long mode too
194  * IRET will check the segment types  kkeil 2000/10/28
195  * Also sysret mandates a special GDT layout 
196  */
197                                 
198 #if 0                                   
199 .align L1_CACHE_BYTES
200 #endif
201         .align  L1_CACHE_BYTES
202 ENTRY(idt_table)        
203         .rept   256
204         .quad   0
205         .quad   0
206         .endr
207