4 #include <linux/elfnote.h>
5 #include <linux/threads.h>
6 #include <linux/init.h>
7 #include <linux/linkage.h>
8 #include <asm/segment.h>
9 #include <asm/page_types.h>
10 #include <asm/pgtable_types.h>
11 #include <asm/cache.h>
12 #include <asm/thread_info.h>
13 #include <asm/asm-offsets.h>
15 #include <asm/dwarf2.h>
16 #include <asm/percpu.h>
17 #include <xen/interface/xen.h>
18 #include <xen/interface/elfnote.h>
19 #include <xen/interface/features.h>
22 * References to members of the new_cpu_data structure.
25 #define X86 new_cpu_data+CPUINFO_x86
26 #define X86_VENDOR new_cpu_data+CPUINFO_x86_vendor
27 #define X86_MODEL new_cpu_data+CPUINFO_x86_model
28 #define X86_MASK new_cpu_data+CPUINFO_x86_mask
29 #define X86_HARD_MATH new_cpu_data+CPUINFO_hard_math
30 #define X86_CPUID new_cpu_data+CPUINFO_cpuid_level
31 #define X86_CAPABILITY new_cpu_data+CPUINFO_x86_capability
32 #define X86_VENDOR_ID new_cpu_data+CPUINFO_x86_vendor_id
35 #define VIRT_ENTRY_OFFSET 0x0
36 .org VIRT_ENTRY_OFFSET
38 movl %esi,xen_start_info
41 /* Set up the stack pointer */
42 movl $(init_thread_union+THREAD_SIZE),%esp
45 xorl %eax,%eax # call CPUID with 0 -> return vendor ID
47 movl %eax,X86_CPUID # save CPUID level
48 movl %ebx,X86_VENDOR_ID # lo 4 chars
49 movl %edx,X86_VENDOR_ID+4 # next 4 chars
50 movl %ecx,X86_VENDOR_ID+8 # last 4 chars
52 movl $1,%eax # Use the CPUID instruction to get CPU type
54 movb %al,%cl # save reg for future use
55 andb $0x0f,%ah # mask processor family
57 andb $0xf0,%al # mask model
60 andb $0x0f,%cl # mask mask revision
62 movl %edx,X86_CAPABILITY
64 #ifdef CONFIG_CC_STACKPROTECTOR
66 * The linker can't handle this by relocation. Manually set
67 * base address in stack canary segment descriptor.
70 movl $stack_canary,%ecx
71 movw %cx, 8 * GDT_ENTRY_STACK_CANARY + 2(%eax)
73 movb %cl, 8 * GDT_ENTRY_STACK_CANARY + 4(%eax)
74 movb %ch, 8 * GDT_ENTRY_STACK_CANARY + 7(%eax)
77 # %esi still points to start_info, and no registers
78 # need to be preserved.
80 movl XEN_START_mfn_list(%esi), %ebx
81 movl $(gdt_page - __PAGE_OFFSET), %eax
82 shrl $PAGE_SHIFT, %eax
83 movl (%ebx,%eax,4), %ecx
84 pushl %ecx # frame number for set_gdt below
88 shldl $PAGE_SHIFT, %ecx, %edx
89 shll $PAGE_SHIFT, %ecx
90 orl $_PAGE_PRESENT|_PAGE_ACCESSED|_PAGE_DIRTY, %ecx
92 movl $__HYPERVISOR_update_va_mapping, %eax
95 movl $(PAGE_SIZE / 8), %ecx
97 movl $__HYPERVISOR_set_gdt, %eax
102 movl $(__KERNEL_PERCPU), %eax
103 movl %eax,%fs # set this cpu's percpu
105 movl $(__KERNEL_STACK_CANARY),%eax
108 cld # gcc2 wants the direction flag cleared at all times
110 pushl $0 # fake return address for unwinder
111 jmp i386_start_kernel
113 #define HYPERCALL_PAGE_OFFSET 0x1000
114 .org HYPERCALL_PAGE_OFFSET
115 ENTRY(hypercall_page)
125 ENTRY(swapper_pg_fixmap)
127 ENTRY(empty_zero_page)
131 * This starts the data section.
135 #ifdef CONFIG_XEN_UNPRIVILEGED_GUEST
136 # define XEN_DOM0_CAP 0
137 # define XEN_DOM0_CAP_STR ""
139 # define XEN_DOM0_CAP (1 << XENFEAT_dom0)
140 # if CONFIG_XEN_COMPAT < 0x040200
141 # define XEN_DOM0_CAP_STR ""
143 # define XEN_DOM0_CAP_STR "|dom0"
147 #if CONFIG_XEN_COMPAT <= 0x030002
149 * __xen_guest information
152 .if (\value) < 0 || (\value) >= 0x10
153 utoa (((\value)>>4)&0x0fffffff)
155 .if ((\value) & 0xf) < 10
156 .byte '0' + ((\value) & 0xf)
158 .byte 'A' + ((\value) & 0xf) - 10
163 .ascii "GUEST_OS=linux,GUEST_VER=2.6"
164 .ascii ",XEN_VER=xen-3.0"
165 .ascii ",VIRT_BASE=0x"
167 .ascii ",ELF_PADDR_OFFSET=0x"
169 .ascii ",VIRT_ENTRY=0x"
170 utoa (__PAGE_OFFSET + LOAD_PHYSICAL_ADDR + VIRT_ENTRY_OFFSET)
171 .ascii ",HYPERCALL_PAGE=0x"
172 utoa ((LOAD_PHYSICAL_ADDR+HYPERCALL_PAGE_OFFSET)>>PAGE_SHIFT)
173 .ascii ",FEATURES=writable_page_tables"
174 .ascii "|writable_descriptor_tables"
175 .ascii "|auto_translated_physmap"
176 .ascii "|pae_pgdir_above_4gb"
177 .ascii "|supervisor_mode_kernel"
178 #ifdef CONFIG_X86_PAE
179 .ascii ",PAE=yes[extended-cr3]"
183 .ascii ",LOADER=generic"
185 #endif /* CONFIG_XEN_COMPAT <= 0x030002 */
188 ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS, .asciz "linux")
189 ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION, .asciz "2.6")
190 ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION, .asciz "xen-3.0")
191 ELFNOTE(Xen, XEN_ELFNOTE_VIRT_BASE, .long __PAGE_OFFSET)
192 #if CONFIG_XEN_COMPAT <= 0x030002
193 ELFNOTE(Xen, XEN_ELFNOTE_PADDR_OFFSET, .long __PAGE_OFFSET)
195 ELFNOTE(Xen, XEN_ELFNOTE_PADDR_OFFSET, .long 0)
197 ELFNOTE(Xen, XEN_ELFNOTE_ENTRY, .long startup_32)
198 ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, .long hypercall_page)
199 ELFNOTE(Xen, XEN_ELFNOTE_HV_START_LOW, .long HYPERVISOR_VIRT_START)
200 ELFNOTE(Xen, XEN_ELFNOTE_FEATURES, .ascii "writable_page_tables";
201 .ascii "|writable_descriptor_tables";
202 .ascii "|auto_translated_physmap";
203 .ascii "|pae_pgdir_above_4gb";
204 .ascii "|supervisor_mode_kernel";
205 .asciz XEN_DOM0_CAP_STR)
206 ELFNOTE(Xen, XEN_ELFNOTE_SUPPORTED_FEATURES, .long XEN_DOM0_CAP |
207 (1 << XENFEAT_writable_page_tables) |
208 (1 << XENFEAT_writable_descriptor_tables) |
209 (1 << XENFEAT_auto_translated_physmap) |
210 (1 << XENFEAT_pae_pgdir_above_4gb) |
211 (1 << XENFEAT_supervisor_mode_kernel))
212 #ifdef CONFIG_X86_PAE
213 ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE, .asciz "yes")
214 ELFNOTE(Xen, XEN_ELFNOTE_L1_MFN_VALID, .quad _PAGE_PRESENT, _PAGE_PRESENT)
216 ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE, .asciz "no")
217 ELFNOTE(Xen, XEN_ELFNOTE_L1_MFN_VALID, .long _PAGE_PRESENT, _PAGE_PRESENT)
219 ELFNOTE(Xen, XEN_ELFNOTE_LOADER, .asciz "generic")
220 ELFNOTE(Xen, XEN_ELFNOTE_SUSPEND_CANCEL, .long 1)