- supported.conf: Added sparse_keymap (eeepc_laptop depends on it)
[linux-flexiantxendom0-3.2.10.git] / arch / x86 / kernel / head_32-xen.S
1
2
3 .text
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>
14 #include <asm/boot.h>
15 #include <asm/dwarf2.h>
16 #include <asm/percpu.h>
17 #include <xen/interface/xen.h>
18 #include <xen/interface/elfnote.h>
19
20 /*
21  * References to members of the new_cpu_data structure.
22  */
23
24 #define X86             new_cpu_data+CPUINFO_x86
25 #define X86_VENDOR      new_cpu_data+CPUINFO_x86_vendor
26 #define X86_MODEL       new_cpu_data+CPUINFO_x86_model
27 #define X86_MASK        new_cpu_data+CPUINFO_x86_mask
28 #define X86_HARD_MATH   new_cpu_data+CPUINFO_hard_math
29 #define X86_CPUID       new_cpu_data+CPUINFO_cpuid_level
30 #define X86_CAPABILITY  new_cpu_data+CPUINFO_x86_capability
31 #define X86_VENDOR_ID   new_cpu_data+CPUINFO_x86_vendor_id
32
33 __HEAD
34 #define VIRT_ENTRY_OFFSET 0x0
35 .org VIRT_ENTRY_OFFSET
36 ENTRY(startup_32)
37         movl %esi,xen_start_info
38         cld
39
40         /* Set up the stack pointer */
41         movl $(init_thread_union+THREAD_SIZE),%esp
42
43         /* get vendor info */
44         xorl %eax,%eax                  # call CPUID with 0 -> return vendor ID
45         XEN_CPUID
46         movl %eax,X86_CPUID             # save CPUID level
47         movl %ebx,X86_VENDOR_ID         # lo 4 chars
48         movl %edx,X86_VENDOR_ID+4       # next 4 chars
49         movl %ecx,X86_VENDOR_ID+8       # last 4 chars
50
51         movl $1,%eax            # Use the CPUID instruction to get CPU type
52         XEN_CPUID
53         movb %al,%cl            # save reg for future use
54         andb $0x0f,%ah          # mask processor family
55         movb %ah,X86
56         andb $0xf0,%al          # mask model
57         shrb $4,%al
58         movb %al,X86_MODEL
59         andb $0x0f,%cl          # mask mask revision
60         movb %cl,X86_MASK
61         movl %edx,X86_CAPABILITY
62
63         movb $1,X86_HARD_MATH
64
65 #ifdef CONFIG_CC_STACKPROTECTOR
66         /*
67          * The linker can't handle this by relocation.  Manually set
68          * base address in stack canary segment descriptor.
69          */
70         movl $per_cpu__gdt_page,%eax
71         movl $per_cpu__stack_canary,%ecx
72         movw %cx, 8 * GDT_ENTRY_STACK_CANARY + 2(%eax)
73         shrl $16, %ecx
74         movb %cl, 8 * GDT_ENTRY_STACK_CANARY + 4(%eax)
75         movb %ch, 8 * GDT_ENTRY_STACK_CANARY + 7(%eax)
76 #endif
77
78         # %esi still points to start_info, and no registers
79         # need to be preserved.
80
81         movl XEN_START_mfn_list(%esi), %ebx
82         movl $(per_cpu__gdt_page - __PAGE_OFFSET), %eax
83         shrl $PAGE_SHIFT, %eax
84         movl (%ebx,%eax,4), %ecx
85         pushl %ecx                      # frame number for set_gdt below
86
87         xorl %esi, %esi
88         xorl %edx, %edx
89         shldl $PAGE_SHIFT, %ecx, %edx
90         shll $PAGE_SHIFT, %ecx
91         orl $_PAGE_PRESENT|_PAGE_ACCESSED|_PAGE_DIRTY, %ecx
92         movl $per_cpu__gdt_page, %ebx
93         movl $__HYPERVISOR_update_va_mapping, %eax
94         int $0x82
95
96         movl $(PAGE_SIZE_asm / 8), %ecx
97         movl %esp, %ebx
98         movl $__HYPERVISOR_set_gdt, %eax
99         int $0x82
100
101         popl %ecx
102
103         movl $(__KERNEL_PERCPU), %eax
104         movl %eax,%fs                   # set this cpu's percpu
105
106         movl $(__KERNEL_STACK_CANARY),%eax
107         movl %eax,%gs
108
109         cld                     # gcc2 wants the direction flag cleared at all times
110
111         pushl $0                # fake return address for unwinder
112         jmp i386_start_kernel
113
114 #define HYPERCALL_PAGE_OFFSET 0x1000
115 .org HYPERCALL_PAGE_OFFSET
116 ENTRY(hypercall_page)
117         CFI_STARTPROC
118 .skip 0x1000
119         CFI_ENDPROC
120
121 /*
122  * BSS section
123  */
124 __PAGE_ALIGNED_BSS
125         .align PAGE_SIZE_asm
126 ENTRY(swapper_pg_fixmap)
127         .fill 1024,4,0
128 ENTRY(empty_zero_page)
129         .fill 4096,1,0
130
131 /*
132  * This starts the data section.
133  */
134 .data
135
136 #if CONFIG_XEN_COMPAT <= 0x030002
137 /*
138  * __xen_guest information
139  */
140 .macro utoa value
141  .if (\value) < 0 || (\value) >= 0x10
142         utoa (((\value)>>4)&0x0fffffff)
143  .endif
144  .if ((\value) & 0xf) < 10
145   .byte '0' + ((\value) & 0xf)
146  .else
147   .byte 'A' + ((\value) & 0xf) - 10
148  .endif
149 .endm
150
151 .section __xen_guest
152         .ascii  "GUEST_OS=linux,GUEST_VER=2.6"
153         .ascii  ",XEN_VER=xen-3.0"
154         .ascii  ",VIRT_BASE=0x"
155                 utoa __PAGE_OFFSET
156         .ascii  ",ELF_PADDR_OFFSET=0x"
157                 utoa __PAGE_OFFSET
158         .ascii  ",VIRT_ENTRY=0x"
159                 utoa (__PAGE_OFFSET + LOAD_PHYSICAL_ADDR + VIRT_ENTRY_OFFSET)
160         .ascii  ",HYPERCALL_PAGE=0x"
161                 utoa ((LOAD_PHYSICAL_ADDR+HYPERCALL_PAGE_OFFSET)>>PAGE_SHIFT)
162         .ascii  ",FEATURES=writable_page_tables"
163         .ascii           "|writable_descriptor_tables"
164         .ascii           "|auto_translated_physmap"
165         .ascii           "|pae_pgdir_above_4gb"
166         .ascii           "|supervisor_mode_kernel"
167 #ifdef CONFIG_X86_PAE
168         .ascii  ",PAE=yes[extended-cr3]"
169 #else
170         .ascii  ",PAE=no"
171 #endif
172         .ascii  ",LOADER=generic"
173         .byte   0
174 #endif /* CONFIG_XEN_COMPAT <= 0x030002 */
175
176
177         ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS,       .asciz "linux")
178         ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION,  .asciz "2.6")
179         ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION,    .asciz "xen-3.0")
180         ELFNOTE(Xen, XEN_ELFNOTE_VIRT_BASE,      .long __PAGE_OFFSET)
181 #if CONFIG_XEN_COMPAT <= 0x030002
182         ELFNOTE(Xen, XEN_ELFNOTE_PADDR_OFFSET,   .long __PAGE_OFFSET)
183 #else
184         ELFNOTE(Xen, XEN_ELFNOTE_PADDR_OFFSET,   .long 0)
185 #endif
186         ELFNOTE(Xen, XEN_ELFNOTE_ENTRY,          .long startup_32)
187         ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, .long hypercall_page)
188         ELFNOTE(Xen, XEN_ELFNOTE_HV_START_LOW,   .long HYPERVISOR_VIRT_START)
189         ELFNOTE(Xen, XEN_ELFNOTE_FEATURES,       .asciz "writable_page_tables|writable_descriptor_tables|auto_translated_physmap|pae_pgdir_above_4gb|supervisor_mode_kernel")
190 #ifdef CONFIG_X86_PAE
191         ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE,       .asciz "yes")
192         ELFNOTE(Xen, XEN_ELFNOTE_L1_MFN_VALID,   .quad _PAGE_PRESENT, _PAGE_PRESENT)
193 #else
194         ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE,       .asciz "no")
195         ELFNOTE(Xen, XEN_ELFNOTE_L1_MFN_VALID,   .long _PAGE_PRESENT, _PAGE_PRESENT)
196 #endif
197         ELFNOTE(Xen, XEN_ELFNOTE_LOADER,         .asciz "generic")
198         ELFNOTE(Xen, XEN_ELFNOTE_SUSPEND_CANCEL, .long 1)