- Update Xen patches to 3.3-rc5 and c/s 1157.
[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 #include <xen/interface/features.h>
20
21 /*
22  * References to members of the new_cpu_data structure.
23  */
24
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
33
34 __HEAD
35 #define VIRT_ENTRY_OFFSET 0x0
36 .org VIRT_ENTRY_OFFSET
37 ENTRY(startup_32)
38         movl %esi,xen_start_info
39         cld
40
41         /* Set up the stack pointer */
42         movl $(init_thread_union+THREAD_SIZE),%esp
43
44         /* get vendor info */
45         xorl %eax,%eax                  # call CPUID with 0 -> return vendor ID
46         XEN_CPUID
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
51
52         movl $1,%eax            # Use the CPUID instruction to get CPU type
53         XEN_CPUID
54         movb %al,%cl            # save reg for future use
55         andb $0x0f,%ah          # mask processor family
56         movb %ah,X86
57         andb $0xf0,%al          # mask model
58         shrb $4,%al
59         movb %al,X86_MODEL
60         andb $0x0f,%cl          # mask mask revision
61         movb %cl,X86_MASK
62         movl %edx,X86_CAPABILITY
63
64 #ifdef CONFIG_CC_STACKPROTECTOR
65         /*
66          * The linker can't handle this by relocation.  Manually set
67          * base address in stack canary segment descriptor.
68          */
69         movl $gdt_page,%eax
70         movl $stack_canary,%ecx
71         movw %cx, 8 * GDT_ENTRY_STACK_CANARY + 2(%eax)
72         shrl $16, %ecx
73         movb %cl, 8 * GDT_ENTRY_STACK_CANARY + 4(%eax)
74         movb %ch, 8 * GDT_ENTRY_STACK_CANARY + 7(%eax)
75 #endif
76
77         # %esi still points to start_info, and no registers
78         # need to be preserved.
79
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
85
86         xorl %esi, %esi
87         xorl %edx, %edx
88         shldl $PAGE_SHIFT, %ecx, %edx
89         shll $PAGE_SHIFT, %ecx
90         orl $_PAGE_PRESENT|_PAGE_ACCESSED|_PAGE_DIRTY, %ecx
91         movl $gdt_page, %ebx
92         movl $__HYPERVISOR_update_va_mapping, %eax
93         int $0x82
94
95         movl $(PAGE_SIZE / 8), %ecx
96         movl %esp, %ebx
97         movl $__HYPERVISOR_set_gdt, %eax
98         int $0x82
99
100         popl %ecx
101
102         movl $(__KERNEL_PERCPU), %eax
103         movl %eax,%fs                   # set this cpu's percpu
104
105         movl $(__KERNEL_STACK_CANARY),%eax
106         movl %eax,%gs
107
108         cld                     # gcc2 wants the direction flag cleared at all times
109
110         pushl $0                # fake return address for unwinder
111         jmp i386_start_kernel
112
113 #define HYPERCALL_PAGE_OFFSET 0x1000
114 .org HYPERCALL_PAGE_OFFSET
115 ENTRY(hypercall_page)
116         CFI_STARTPROC
117 .skip 0x1000
118         CFI_ENDPROC
119
120 /*
121  * BSS section
122  */
123 __PAGE_ALIGNED_BSS
124         .align PAGE_SIZE
125 ENTRY(swapper_pg_fixmap)
126         .fill 1024,4,0
127 ENTRY(empty_zero_page)
128         .fill 4096,1,0
129
130 /*
131  * This starts the data section.
132  */
133 .data
134
135 #ifdef CONFIG_XEN_UNPRIVILEGED_GUEST
136 # define XEN_DOM0_CAP           0
137 # define XEN_DOM0_CAP_STR       ""
138 #else
139 # define XEN_DOM0_CAP           (1 << XENFEAT_dom0)
140 # if CONFIG_XEN_COMPAT < 0x040200
141 #  define XEN_DOM0_CAP_STR      ""
142 # else
143 #  define XEN_DOM0_CAP_STR      "|dom0"
144 # endif
145 #endif
146
147 #if CONFIG_XEN_COMPAT <= 0x030002
148 /*
149  * __xen_guest information
150  */
151 .macro utoa value
152  .if (\value) < 0 || (\value) >= 0x10
153         utoa (((\value)>>4)&0x0fffffff)
154  .endif
155  .if ((\value) & 0xf) < 10
156   .byte '0' + ((\value) & 0xf)
157  .else
158   .byte 'A' + ((\value) & 0xf) - 10
159  .endif
160 .endm
161
162 .section __xen_guest
163         .ascii  "GUEST_OS=linux,GUEST_VER=2.6"
164         .ascii  ",XEN_VER=xen-3.0"
165         .ascii  ",VIRT_BASE=0x"
166                 utoa __PAGE_OFFSET
167         .ascii  ",ELF_PADDR_OFFSET=0x"
168                 utoa __PAGE_OFFSET
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]"
180 #else
181         .ascii  ",PAE=no"
182 #endif
183         .ascii  ",LOADER=generic"
184         .byte   0
185 #endif /* CONFIG_XEN_COMPAT <= 0x030002 */
186
187
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)
194 #else
195         ELFNOTE(Xen, XEN_ELFNOTE_PADDR_OFFSET,   .long 0)
196 #endif
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)
215 #else
216         ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE,       .asciz "no")
217         ELFNOTE(Xen, XEN_ELFNOTE_L1_MFN_VALID,   .long _PAGE_PRESENT, _PAGE_PRESENT)
218 #endif
219         ELFNOTE(Xen, XEN_ELFNOTE_LOADER,         .asciz "generic")
220         ELFNOTE(Xen, XEN_ELFNOTE_SUSPEND_CANCEL, .long 1)