fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / arch / i386 / kernel / head-xen.S
index 25ce032..0d39df3 100644 (file)
@@ -1,14 +1,16 @@
 
 
 .text
-#include <linux/config.h>
+#include <linux/elfnote.h>
 #include <linux/threads.h>
 #include <linux/linkage.h>
 #include <asm/segment.h>
 #include <asm/page.h>
+#include <asm/boot.h>
 #include <asm/thread_info.h>
 #include <asm/asm-offsets.h>
-#include <xen/interface/arch-x86_32.h>
+#include <xen/interface/xen.h>
+#include <xen/interface/elfnote.h>
 
 /*
  * References to members of the new_cpu_data structure.
 #define VIRT_ENTRY_OFFSET 0x0
 .org VIRT_ENTRY_OFFSET
 ENTRY(startup_32)
+
+#ifdef CONFIG_PARAVIRT
+        movl %cs, %eax
+        testl $0x3, %eax
+        jnz startup_paravirt
+#endif
+
        movl %esi,xen_start_info
        cld
 
+       call setup_pda
+
        /* Set up the stack pointer */
        movl $(init_thread_union+THREAD_SIZE),%esp
 
@@ -54,9 +65,12 @@ ENTRY(startup_32)
 
        movb $1,X86_HARD_MATH
 
-       xorl %eax,%eax                  # Clear FS/GS and LDT
+       xorl %eax,%eax                  # Clear FS and LDT
        movl %eax,%fs
-       movl %eax,%gs
+
+       movl $(__KERNEL_PDA),%eax
+       mov  %eax,%gs
+
        cld                     # gcc2 wants the direction flag cleared at all times
 
        call start_kernel
@@ -64,6 +78,47 @@ L6:
        jmp L6                  # main should never return here, but
                                # just in case, we know what happens.
 
+/*
+ * Point the GDT at this CPU's PDA.  This will be
+ * cpu_gdt_table and boot_pda.
+ */
+setup_pda:
+       /* get the PDA pointer */
+       movl $boot_pda, %eax
+
+       /* slot the PDA address into the GDT */
+       mov $cpu_gdt_table, %ecx
+       mov %ax, (__KERNEL_PDA+0+2)(%ecx)               /* base & 0x0000ffff */
+       shr $16, %eax
+       mov %al, (__KERNEL_PDA+4+0)(%ecx)               /* base & 0x00ff0000 */
+       mov %ah, (__KERNEL_PDA+4+3)(%ecx)               /* base & 0xff000000 */
+
+       # %esi still points to start_info, and no registers
+       # need to be preserved.
+
+       movl XEN_START_mfn_list(%esi), %ebx
+       movl $(cpu_gdt_table - __PAGE_OFFSET), %eax
+       shrl $PAGE_SHIFT, %eax
+       movl (%ebx,%eax,4), %ecx
+       pushl %ecx                      # frame number for set_gdt below
+
+       xorl %esi, %esi
+       xorl %edx, %edx
+       shldl $PAGE_SHIFT, %ecx, %edx
+       shll $PAGE_SHIFT, %ecx
+       orl $0x61, %ecx
+       movl $cpu_gdt_table, %ebx
+       movl $__HYPERVISOR_update_va_mapping, %eax
+       int $0x82
+
+       movl $(PAGE_SIZE_asm / 8), %ecx
+       movl %esp, %ebx
+       movl $__HYPERVISOR_set_gdt, %eax
+       int $0x82
+
+       popl %ecx
+       ret
+
 #define HYPERCALL_PAGE_OFFSET 0x1000
 .org HYPERCALL_PAGE_OFFSET
 ENTRY(hypercall_page)
@@ -86,10 +141,41 @@ ENTRY(empty_zero_page)
  * This starts the data section.
  */
 .data
+ENTRY(start_pda)
+       .long boot_pda
+
+#ifdef CONFIG_PARAVIRT
+startup_paravirt:
+       cld
+       movl $(init_thread_union+THREAD_SIZE),%esp
+
+       /* We take pains to preserve all the regs. */
+       pushl   %edx
+       pushl   %ecx
+       pushl   %eax
+
+       /* paravirt.o is last in link, and that probe fn never returns */
+       pushl   $__start_paravirtprobe
+1:
+       movl    0(%esp), %eax
+       pushl   (%eax)
+       movl    8(%esp), %eax
+       call    *(%esp)
+       popl    %eax
+
+       movl    4(%esp), %eax
+       movl    8(%esp), %ecx
+       movl    12(%esp), %edx
+
+       addl    $4, (%esp)
+       jmp     1b
+#endif
 
 /*
  * The Global Descriptor Table contains 28 quadwords, per-CPU.
  */
+       .section .data.page_aligned, "aw"
+       .align PAGE_SIZE_asm
 ENTRY(cpu_gdt_table)
        .quad 0x0000000000000000        /* NULL descriptor */
        .quad 0x0000000000000000        /* 0x0b reserved */
@@ -131,13 +217,15 @@ ENTRY(cpu_gdt_table)
        .quad 0x0000000000000000        /* 0xc0 APM CS 16 code (16 bit) */
        .quad 0x0000000000000000        /* 0xc8 APM DS    data */
 
-       .quad 0x0000000000000000        /* 0xd0 - ESPFIX 16-bit SS */
-       .quad 0x0000000000000000        /* 0xd8 - unused */
+       .quad 0x0000000000000000        /* 0xd0 - ESPFIX SS */
+       .quad 0x00cf92000000ffff        /* 0xd8 - PDA */
        .quad 0x0000000000000000        /* 0xe0 - unused */
        .quad 0x0000000000000000        /* 0xe8 - unused */
        .quad 0x0000000000000000        /* 0xf0 - unused */
        .quad 0x0000000000000000        /* 0xf8 - GDT entry 31: double-fault TSS */
+       .align PAGE_SIZE_asm
 
+#ifdef CONFIG_XEN_COMPAT_030002
 /*
  * __xen_guest information
  */
@@ -157,16 +245,12 @@ ENTRY(cpu_gdt_table)
        .ascii  ",XEN_VER=xen-3.0"
        .ascii  ",VIRT_BASE=0x"
                utoa __PAGE_OFFSET
-#ifdef CONFIG_XEN_COMPAT_030002
        .ascii  ",ELF_PADDR_OFFSET=0x"
                utoa __PAGE_OFFSET
-#else
-       .ascii  ",ELF_PADDR_OFFSET=0x0"
-#endif /* !CONFIG_XEN_COMPAT_030002 */
        .ascii  ",VIRT_ENTRY=0x"
-               utoa (__PAGE_OFFSET + __PHYSICAL_START + VIRT_ENTRY_OFFSET)
+               utoa (__PAGE_OFFSET + LOAD_PHYSICAL_ADDR + VIRT_ENTRY_OFFSET)
        .ascii  ",HYPERCALL_PAGE=0x"
-               utoa ((__PHYSICAL_START+HYPERCALL_PAGE_OFFSET)>>PAGE_SHIFT)
+               utoa ((LOAD_PHYSICAL_ADDR+HYPERCALL_PAGE_OFFSET)>>PAGE_SHIFT)
        .ascii  ",FEATURES=writable_page_tables"
        .ascii           "|writable_descriptor_tables"
        .ascii           "|auto_translated_physmap"
@@ -179,3 +263,24 @@ ENTRY(cpu_gdt_table)
 #endif
        .ascii  ",LOADER=generic"
        .byte   0
+#endif /* CONFIG_XEN_COMPAT_030002 */
+
+
+       ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS,       .asciz, "linux")       
+       ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION,  .asciz, "2.6")
+       ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION,    .asciz, "xen-3.0")
+       ELFNOTE(Xen, XEN_ELFNOTE_VIRT_BASE,      .long,  __PAGE_OFFSET)
+#ifdef CONFIG_XEN_COMPAT_030002
+       ELFNOTE(Xen, XEN_ELFNOTE_PADDR_OFFSET,   .long,  __PAGE_OFFSET)
+#else
+       ELFNOTE(Xen, XEN_ELFNOTE_PADDR_OFFSET,   .long,  0)
+#endif /* !CONFIG_XEN_COMPAT_030002 */
+       ELFNOTE(Xen, XEN_ELFNOTE_ENTRY,          .long,  startup_32)
+       ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, .long,  hypercall_page)
+       ELFNOTE(Xen, XEN_ELFNOTE_FEATURES,       .asciz, "writable_page_tables|writable_descriptor_tables|auto_translated_physmap|pae_pgdir_above_4gb|supervisor_mode_kernel")
+#ifdef CONFIG_X86_PAE
+       ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE,       .asciz, "yes")
+#else
+       ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE,       .asciz, "no")
+#endif
+       ELFNOTE(Xen, XEN_ELFNOTE_LOADER,         .asciz, "generic")