Merge to Fedora kernel-2.6.18-1.2224_FC5 patched with stable patch-2.6.18.1-vs2.0...
[linux-2.6.git] / arch / i386 / kernel / head-xen.S
1
2
3 .text
4 #include <linux/elfnote.h>
5 #include <linux/threads.h>
6 #include <linux/linkage.h>
7 #include <asm/segment.h>
8 #include <asm/page.h>
9 #include <asm/thread_info.h>
10 #include <asm/asm-offsets.h>
11 #include <xen/interface/arch-x86_32.h>
12 #include <xen/interface/elfnote.h>
13
14 /*
15  * References to members of the new_cpu_data structure.
16  */
17
18 #define X86             new_cpu_data+CPUINFO_x86
19 #define X86_VENDOR      new_cpu_data+CPUINFO_x86_vendor
20 #define X86_MODEL       new_cpu_data+CPUINFO_x86_model
21 #define X86_MASK        new_cpu_data+CPUINFO_x86_mask
22 #define X86_HARD_MATH   new_cpu_data+CPUINFO_hard_math
23 #define X86_CPUID       new_cpu_data+CPUINFO_cpuid_level
24 #define X86_CAPABILITY  new_cpu_data+CPUINFO_x86_capability
25 #define X86_VENDOR_ID   new_cpu_data+CPUINFO_x86_vendor_id
26
27 #define VIRT_ENTRY_OFFSET 0x0
28 .org VIRT_ENTRY_OFFSET
29 ENTRY(startup_32)
30         movl %esi,xen_start_info
31         cld
32
33         /* Set up the stack pointer */
34         movl $(init_thread_union+THREAD_SIZE),%esp
35
36         /* get vendor info */
37         xorl %eax,%eax                  # call CPUID with 0 -> return vendor ID
38         XEN_CPUID
39         movl %eax,X86_CPUID             # save CPUID level
40         movl %ebx,X86_VENDOR_ID         # lo 4 chars
41         movl %edx,X86_VENDOR_ID+4       # next 4 chars
42         movl %ecx,X86_VENDOR_ID+8       # last 4 chars
43
44         movl $1,%eax            # Use the CPUID instruction to get CPU type
45         XEN_CPUID
46         movb %al,%cl            # save reg for future use
47         andb $0x0f,%ah          # mask processor family
48         movb %ah,X86
49         andb $0xf0,%al          # mask model
50         shrb $4,%al
51         movb %al,X86_MODEL
52         andb $0x0f,%cl          # mask mask revision
53         movb %cl,X86_MASK
54         movl %edx,X86_CAPABILITY
55
56         movb $1,X86_HARD_MATH
57
58         xorl %eax,%eax                  # Clear FS/GS and LDT
59         movl %eax,%fs
60         movl %eax,%gs
61         cld                     # gcc2 wants the direction flag cleared at all times
62
63         call start_kernel
64 L6:
65         jmp L6                  # main should never return here, but
66                                 # just in case, we know what happens.
67
68 #define HYPERCALL_PAGE_OFFSET 0x1000
69 .org HYPERCALL_PAGE_OFFSET
70 ENTRY(hypercall_page)
71 .skip 0x1000
72
73 /*
74  * Real beginning of normal "text" segment
75  */
76 ENTRY(stext)
77 ENTRY(_stext)
78
79 /*
80  * BSS section
81  */
82 .section ".bss.page_aligned","w"
83 ENTRY(empty_zero_page)
84         .fill 4096,1,0
85
86 /*
87  * This starts the data section.
88  */
89 .data
90
91 /*
92  * The Global Descriptor Table contains 28 quadwords, per-CPU.
93  */
94 ENTRY(cpu_gdt_table)
95         .quad 0x0000000000000000        /* NULL descriptor */
96         .quad 0x0000000000000000        /* 0x0b reserved */
97         .quad 0x0000000000000000        /* 0x13 reserved */
98         .quad 0x0000000000000000        /* 0x1b reserved */
99         .quad 0x0000000000000000        /* 0x20 unused */
100         .quad 0x0000000000000000        /* 0x28 unused */
101         .quad 0x0000000000000000        /* 0x33 TLS entry 1 */
102         .quad 0x0000000000000000        /* 0x3b TLS entry 2 */
103         .quad 0x0000000000000000        /* 0x43 TLS entry 3 */
104         .quad 0x0000000000000000        /* 0x4b reserved */
105         .quad 0x0000000000000000        /* 0x53 reserved */
106         .quad 0x0000000000000000        /* 0x5b reserved */
107
108         .quad 0x00cf9a000000ffff        /* 0x60 kernel 4GB code at 0x00000000 */
109         .quad 0x00cf92000000ffff        /* 0x68 kernel 4GB data at 0x00000000 */
110         .quad 0x00cffa000000ffff        /* 0x73 user 4GB code at 0x00000000 */
111         .quad 0x00cff2000000ffff        /* 0x7b user 4GB data at 0x00000000 */
112
113         .quad 0x0000000000000000        /* 0x80 TSS descriptor */
114         .quad 0x0000000000000000        /* 0x88 LDT descriptor */
115
116         /*
117          * Segments used for calling PnP BIOS have byte granularity.
118          * They code segments and data segments have fixed 64k limits,
119          * the transfer segment sizes are set at run time.
120          */
121         .quad 0x0000000000000000        /* 0x90 32-bit code */
122         .quad 0x0000000000000000        /* 0x98 16-bit code */
123         .quad 0x0000000000000000        /* 0xa0 16-bit data */
124         .quad 0x0000000000000000        /* 0xa8 16-bit data */
125         .quad 0x0000000000000000        /* 0xb0 16-bit data */
126
127         /*
128          * The APM segments have byte granularity and their bases
129          * are set at run time.  All have 64k limits.
130          */
131         .quad 0x0000000000000000        /* 0xb8 APM CS    code */
132         .quad 0x0000000000000000        /* 0xc0 APM CS 16 code (16 bit) */
133         .quad 0x0000000000000000        /* 0xc8 APM DS    data */
134
135         .quad 0x0000000000000000        /* 0xd0 - ESPFIX 16-bit SS */
136         .quad 0x0000000000000000        /* 0xd8 - unused */
137         .quad 0x0000000000000000        /* 0xe0 - unused */
138         .quad 0x0000000000000000        /* 0xe8 - unused */
139         .quad 0x0000000000000000        /* 0xf0 - unused */
140         .quad 0x0000000000000000        /* 0xf8 - GDT entry 31: double-fault TSS */
141
142 #ifdef CONFIG_XEN_COMPAT_030002
143 /*
144  * __xen_guest information
145  */
146 .macro utoa value
147  .if (\value) < 0 || (\value) >= 0x10
148         utoa (((\value)>>4)&0x0fffffff)
149  .endif
150  .if ((\value) & 0xf) < 10
151   .byte '0' + ((\value) & 0xf)
152  .else
153   .byte 'A' + ((\value) & 0xf) - 10
154  .endif
155 .endm
156
157 .section __xen_guest
158         .ascii  "GUEST_OS=linux,GUEST_VER=2.6"
159         .ascii  ",XEN_VER=xen-3.0"
160         .ascii  ",VIRT_BASE=0x"
161                 utoa __PAGE_OFFSET
162         .ascii  ",ELF_PADDR_OFFSET=0x"
163                 utoa __PAGE_OFFSET
164         .ascii  ",VIRT_ENTRY=0x"
165                 utoa (__PAGE_OFFSET + __PHYSICAL_START + VIRT_ENTRY_OFFSET)
166         .ascii  ",HYPERCALL_PAGE=0x"
167                 utoa ((__PHYSICAL_START+HYPERCALL_PAGE_OFFSET)>>PAGE_SHIFT)
168         .ascii  ",FEATURES=writable_page_tables"
169         .ascii           "|writable_descriptor_tables"
170         .ascii           "|auto_translated_physmap"
171         .ascii           "|pae_pgdir_above_4gb"
172         .ascii           "|supervisor_mode_kernel"
173 #ifdef CONFIG_X86_PAE
174         .ascii  ",PAE=yes[extended-cr3]"
175 #else
176         .ascii  ",PAE=no"
177 #endif
178         .ascii  ",LOADER=generic"
179         .byte   0
180 #endif /* CONFIG_XEN_COMPAT_030002 */
181
182
183         ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS,       .asciz, "linux")       
184         ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION,  .asciz, "2.6")
185         ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION,    .asciz, "xen-3.0")
186         ELFNOTE(Xen, XEN_ELFNOTE_VIRT_BASE,      .long,  __PAGE_OFFSET)
187 #ifdef CONFIG_XEN_COMPAT_030002
188         ELFNOTE(Xen, XEN_ELFNOTE_PADDR_OFFSET,   .long,  __PAGE_OFFSET)
189 #else
190         ELFNOTE(Xen, XEN_ELFNOTE_PADDR_OFFSET,   .long,  0)
191 #endif /* !CONFIG_XEN_COMPAT_030002 */
192         ELFNOTE(Xen, XEN_ELFNOTE_ENTRY,          .long,  startup_32)
193         ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, .long,  hypercall_page)
194         ELFNOTE(Xen, XEN_ELFNOTE_FEATURES,       .asciz, "writable_page_tables|writable_descriptor_tables|auto_translated_physmap|pae_pgdir_above_4gb|supervisor_mode_kernel")
195 #ifdef CONFIG_X86_PAE
196         ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE,       .asciz, "yes")
197 #else
198         ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE,       .asciz, "no")
199 #endif
200         ELFNOTE(Xen, XEN_ELFNOTE_LOADER,         .asciz, "generic")