4 #include <linux/elfnote.h>
5 #include <linux/threads.h>
6 #include <linux/linkage.h>
7 #include <asm/segment.h>
10 #include <asm/thread_info.h>
11 #include <asm/asm-offsets.h>
12 #include <xen/interface/xen.h>
13 #include <xen/interface/elfnote.h>
16 * References to members of the new_cpu_data structure.
19 #define X86 new_cpu_data+CPUINFO_x86
20 #define X86_VENDOR new_cpu_data+CPUINFO_x86_vendor
21 #define X86_MODEL new_cpu_data+CPUINFO_x86_model
22 #define X86_MASK new_cpu_data+CPUINFO_x86_mask
23 #define X86_HARD_MATH new_cpu_data+CPUINFO_hard_math
24 #define X86_CPUID new_cpu_data+CPUINFO_cpuid_level
25 #define X86_CAPABILITY new_cpu_data+CPUINFO_x86_capability
26 #define X86_VENDOR_ID new_cpu_data+CPUINFO_x86_vendor_id
28 #define VIRT_ENTRY_OFFSET 0x0
29 .org VIRT_ENTRY_OFFSET
32 #ifdef CONFIG_PARAVIRT
38 movl %esi,xen_start_info
43 /* Set up the stack pointer */
44 movl $(init_thread_union+THREAD_SIZE),%esp
47 xorl %eax,%eax # call CPUID with 0 -> return vendor ID
49 movl %eax,X86_CPUID # save CPUID level
50 movl %ebx,X86_VENDOR_ID # lo 4 chars
51 movl %edx,X86_VENDOR_ID+4 # next 4 chars
52 movl %ecx,X86_VENDOR_ID+8 # last 4 chars
54 movl $1,%eax # Use the CPUID instruction to get CPU type
56 movb %al,%cl # save reg for future use
57 andb $0x0f,%ah # mask processor family
59 andb $0xf0,%al # mask model
62 andb $0x0f,%cl # mask mask revision
64 movl %edx,X86_CAPABILITY
68 xorl %eax,%eax # Clear FS and LDT
71 movl $(__KERNEL_PDA),%eax
74 cld # gcc2 wants the direction flag cleared at all times
78 jmp L6 # main should never return here, but
79 # just in case, we know what happens.
82 * Point the GDT at this CPU's PDA. This will be
83 * cpu_gdt_table and boot_pda.
86 /* get the PDA pointer */
89 /* slot the PDA address into the GDT */
90 mov $cpu_gdt_table, %ecx
91 mov %ax, (__KERNEL_PDA+0+2)(%ecx) /* base & 0x0000ffff */
93 mov %al, (__KERNEL_PDA+4+0)(%ecx) /* base & 0x00ff0000 */
94 mov %ah, (__KERNEL_PDA+4+3)(%ecx) /* base & 0xff000000 */
96 # %esi still points to start_info, and no registers
97 # need to be preserved.
99 movl XEN_START_mfn_list(%esi), %ebx
100 movl $(cpu_gdt_table - __PAGE_OFFSET), %eax
101 shrl $PAGE_SHIFT, %eax
102 movl (%ebx,%eax,4), %ecx
103 pushl %ecx # frame number for set_gdt below
107 shldl $PAGE_SHIFT, %ecx, %edx
108 shll $PAGE_SHIFT, %ecx
110 movl $cpu_gdt_table, %ebx
111 movl $__HYPERVISOR_update_va_mapping, %eax
114 movl $(PAGE_SIZE_asm / 8), %ecx
116 movl $__HYPERVISOR_set_gdt, %eax
122 #define HYPERCALL_PAGE_OFFSET 0x1000
123 .org HYPERCALL_PAGE_OFFSET
124 ENTRY(hypercall_page)
128 * Real beginning of normal "text" segment
136 .section ".bss.page_aligned","w"
137 ENTRY(empty_zero_page)
141 * This starts the data section.
147 #ifdef CONFIG_PARAVIRT
150 movl $(init_thread_union+THREAD_SIZE),%esp
152 /* We take pains to preserve all the regs. */
157 /* paravirt.o is last in link, and that probe fn never returns */
158 pushl $__start_paravirtprobe
175 * The Global Descriptor Table contains 28 quadwords, per-CPU.
177 .section .data.page_aligned, "aw"
180 .quad 0x0000000000000000 /* NULL descriptor */
181 .quad 0x0000000000000000 /* 0x0b reserved */
182 .quad 0x0000000000000000 /* 0x13 reserved */
183 .quad 0x0000000000000000 /* 0x1b reserved */
184 .quad 0x0000000000000000 /* 0x20 unused */
185 .quad 0x0000000000000000 /* 0x28 unused */
186 .quad 0x0000000000000000 /* 0x33 TLS entry 1 */
187 .quad 0x0000000000000000 /* 0x3b TLS entry 2 */
188 .quad 0x0000000000000000 /* 0x43 TLS entry 3 */
189 .quad 0x0000000000000000 /* 0x4b reserved */
190 .quad 0x0000000000000000 /* 0x53 reserved */
191 .quad 0x0000000000000000 /* 0x5b reserved */
193 .quad 0x00cf9a000000ffff /* 0x60 kernel 4GB code at 0x00000000 */
194 .quad 0x00cf92000000ffff /* 0x68 kernel 4GB data at 0x00000000 */
195 .quad 0x00cffa000000ffff /* 0x73 user 4GB code at 0x00000000 */
196 .quad 0x00cff2000000ffff /* 0x7b user 4GB data at 0x00000000 */
198 .quad 0x0000000000000000 /* 0x80 TSS descriptor */
199 .quad 0x0000000000000000 /* 0x88 LDT descriptor */
202 * Segments used for calling PnP BIOS have byte granularity.
203 * They code segments and data segments have fixed 64k limits,
204 * the transfer segment sizes are set at run time.
206 .quad 0x0000000000000000 /* 0x90 32-bit code */
207 .quad 0x0000000000000000 /* 0x98 16-bit code */
208 .quad 0x0000000000000000 /* 0xa0 16-bit data */
209 .quad 0x0000000000000000 /* 0xa8 16-bit data */
210 .quad 0x0000000000000000 /* 0xb0 16-bit data */
213 * The APM segments have byte granularity and their bases
214 * are set at run time. All have 64k limits.
216 .quad 0x0000000000000000 /* 0xb8 APM CS code */
217 .quad 0x0000000000000000 /* 0xc0 APM CS 16 code (16 bit) */
218 .quad 0x0000000000000000 /* 0xc8 APM DS data */
220 .quad 0x0000000000000000 /* 0xd0 - ESPFIX SS */
221 .quad 0x00cf92000000ffff /* 0xd8 - PDA */
222 .quad 0x0000000000000000 /* 0xe0 - unused */
223 .quad 0x0000000000000000 /* 0xe8 - unused */
224 .quad 0x0000000000000000 /* 0xf0 - unused */
225 .quad 0x0000000000000000 /* 0xf8 - GDT entry 31: double-fault TSS */
228 #ifdef CONFIG_XEN_COMPAT_030002
230 * __xen_guest information
233 .if (\value) < 0 || (\value) >= 0x10
234 utoa (((\value)>>4)&0x0fffffff)
236 .if ((\value) & 0xf) < 10
237 .byte '0' + ((\value) & 0xf)
239 .byte 'A' + ((\value) & 0xf) - 10
244 .ascii "GUEST_OS=linux,GUEST_VER=2.6"
245 .ascii ",XEN_VER=xen-3.0"
246 .ascii ",VIRT_BASE=0x"
248 .ascii ",ELF_PADDR_OFFSET=0x"
250 .ascii ",VIRT_ENTRY=0x"
251 utoa (__PAGE_OFFSET + LOAD_PHYSICAL_ADDR + VIRT_ENTRY_OFFSET)
252 .ascii ",HYPERCALL_PAGE=0x"
253 utoa ((LOAD_PHYSICAL_ADDR+HYPERCALL_PAGE_OFFSET)>>PAGE_SHIFT)
254 .ascii ",FEATURES=writable_page_tables"
255 .ascii "|writable_descriptor_tables"
256 .ascii "|auto_translated_physmap"
257 .ascii "|pae_pgdir_above_4gb"
258 .ascii "|supervisor_mode_kernel"
259 #ifdef CONFIG_X86_PAE
260 .ascii ",PAE=yes[extended-cr3]"
264 .ascii ",LOADER=generic"
266 #endif /* CONFIG_XEN_COMPAT_030002 */
269 ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS, .asciz, "linux")
270 ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION, .asciz, "2.6")
271 ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION, .asciz, "xen-3.0")
272 ELFNOTE(Xen, XEN_ELFNOTE_VIRT_BASE, .long, __PAGE_OFFSET)
273 #ifdef CONFIG_XEN_COMPAT_030002
274 ELFNOTE(Xen, XEN_ELFNOTE_PADDR_OFFSET, .long, __PAGE_OFFSET)
276 ELFNOTE(Xen, XEN_ELFNOTE_PADDR_OFFSET, .long, 0)
277 #endif /* !CONFIG_XEN_COMPAT_030002 */
278 ELFNOTE(Xen, XEN_ELFNOTE_ENTRY, .long, startup_32)
279 ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, .long, hypercall_page)
280 ELFNOTE(Xen, XEN_ELFNOTE_FEATURES, .asciz, "writable_page_tables|writable_descriptor_tables|auto_translated_physmap|pae_pgdir_above_4gb|supervisor_mode_kernel")
281 #ifdef CONFIG_X86_PAE
282 ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE, .asciz, "yes")
284 ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE, .asciz, "no")
286 ELFNOTE(Xen, XEN_ELFNOTE_LOADER, .asciz, "generic")