ia64/xen-unstable

changeset 15292:a5ae31a91b10

x86: Return to real-mode when booting primary CPU, and gather
memory-map information (from int15{e820,e801,88} and int12 bios
calls).

Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Thu Jun 07 19:41:59 2007 +0100 (2007-06-07)
parents 56bab6f498ac
children 345ae2e61ba0
files xen/arch/x86/boot/Makefile xen/arch/x86/boot/head.S xen/arch/x86/boot/mem.S xen/arch/x86/boot/trampoline.S xen/arch/x86/boot/x86_32.S xen/arch/x86/setup.c xen/arch/x86/smpboot.c xen/include/asm-x86/config.h xen/include/asm-x86/e820.h
line diff
     1.1 --- a/xen/arch/x86/boot/Makefile	Thu Jun 07 16:44:04 2007 +0100
     1.2 +++ b/xen/arch/x86/boot/Makefile	Thu Jun 07 19:41:59 2007 +0100
     1.3 @@ -1,3 +1,3 @@
     1.4  obj-y += head.o
     1.5  
     1.6 -head.o: head.S trampoline.S $(TARGET_SUBARCH).S
     1.7 +head.o: head.S $(TARGET_SUBARCH).S trampoline.S mem.S
     2.1 --- a/xen/arch/x86/boot/head.S	Thu Jun 07 16:44:04 2007 +0100
     2.2 +++ b/xen/arch/x86/boot/head.S	Thu Jun 07 19:41:59 2007 +0100
     2.3 @@ -9,12 +9,15 @@
     2.4          .text
     2.5          .code32
     2.6  
     2.7 -#define SYM_PHYS(sym)       ((sym) - __XEN_VIRT_START)
     2.8 -#define SYM_TRAMP_PHYS(sym) ((sym) - trampoline_start + BOOT_TRAMPOLINE)
     2.9 +#undef bootsym_phys
    2.10 +#define sym_phys(sym)     ((sym) - __XEN_VIRT_START)
    2.11 +#define bootsym_phys(sym) ((sym) - trampoline_start + BOOT_TRAMPOLINE)
    2.12  
    2.13 -#define TRAMP_CS32 0x0008
    2.14 -#define TRAMP_CS64 0x0010
    2.15 -#define TRAMP_DS   0x0018
    2.16 +#define BOOT_CS32        0x0008
    2.17 +#define BOOT_CS64        0x0010
    2.18 +#define BOOT_DS          0x0018
    2.19 +#define BOOT_PSEUDORM_CS 0x0020
    2.20 +#define BOOT_PSEUDORM_DS 0x0028
    2.21  
    2.22  ENTRY(start)
    2.23          jmp     __start
    2.24 @@ -30,14 +33,16 @@ ENTRY(start)
    2.25          /* Checksum: must be the negated sum of the first two fields. */
    2.26          .long   -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
    2.27  
    2.28 +        .section .init.text
    2.29 +
    2.30  .Lbad_cpu_msg: .asciz "ERR: Not a 64-bit CPU!"
    2.31  .Lbad_ldr_msg: .asciz "ERR: Not a Multiboot bootloader!"
    2.32  
    2.33  bad_cpu:
    2.34 -        mov     $(SYM_PHYS(.Lbad_cpu_msg)),%esi # Error message
    2.35 +        mov     $(sym_phys(.Lbad_cpu_msg)),%esi # Error message
    2.36          jmp     print_err
    2.37  not_multiboot:
    2.38 -        mov     $(SYM_PHYS(.Lbad_ldr_msg)),%esi # Error message
    2.39 +        mov     $(sym_phys(.Lbad_ldr_msg)),%esi # Error message
    2.40  print_err:
    2.41          mov     $0xB8000,%edi  # VGA framebuffer
    2.42  1:      mov     (%esi),%bl
    2.43 @@ -56,16 +61,16 @@ 3:      in      %dx,%al
    2.44          jmp     1b
    2.45  
    2.46  gdt_boot_descr:
    2.47 -        .word   4*8-1
    2.48 -        .long   SYM_PHYS(trampoline_gdt)
    2.49 +        .word   6*8-1
    2.50 +        .long   sym_phys(trampoline_gdt)
    2.51  
    2.52  __start:
    2.53          cld
    2.54          cli
    2.55  
    2.56          /* Initialise GDT and basic data segments. */
    2.57 -        lgdt    %cs:SYM_PHYS(gdt_boot_descr)
    2.58 -        mov     $TRAMP_DS,%ecx
    2.59 +        lgdt    %cs:sym_phys(gdt_boot_descr)
    2.60 +        mov     $BOOT_DS,%ecx
    2.61          mov     %ecx,%ds
    2.62          mov     %ecx,%es
    2.63  
    2.64 @@ -74,11 +79,11 @@ gdt_boot_descr:
    2.65          jne     not_multiboot
    2.66  
    2.67          /* Save the Multiboot info structure for later use. */
    2.68 -        mov     %ebx,SYM_PHYS(multiboot_ptr)
    2.69 +        mov     %ebx,sym_phys(multiboot_ptr)
    2.70  
    2.71          /* Initialize BSS (no nasty surprises!) */
    2.72 -        mov     $SYM_PHYS(__bss_start),%edi
    2.73 -        mov     $SYM_PHYS(_end),%ecx
    2.74 +        mov     $sym_phys(__bss_start),%edi
    2.75 +        mov     $sym_phys(_end),%ecx
    2.76          sub     %edi,%ecx
    2.77          xor     %eax,%eax
    2.78          rep     stosb
    2.79 @@ -91,15 +96,15 @@ gdt_boot_descr:
    2.80          jbe     1f
    2.81          mov     $0x80000001,%eax
    2.82          cpuid
    2.83 -1:      mov     %edx,SYM_PHYS(cpuid_ext_features)
    2.84 +1:      mov     %edx,sym_phys(cpuid_ext_features)
    2.85  
    2.86  #if defined(__x86_64__)
    2.87          /* Check for availability of long mode. */
    2.88          bt      $29,%edx
    2.89          jnc     bad_cpu
    2.90          /* Initialise L2 identity-map and xen page table entries (16MB). */
    2.91 -        mov     $SYM_PHYS(l2_identmap),%edi
    2.92 -        mov     $SYM_PHYS(l2_xenmap),%esi
    2.93 +        mov     $sym_phys(l2_identmap),%edi
    2.94 +        mov     $sym_phys(l2_xenmap),%esi
    2.95          mov     $0x1e3,%eax                  /* PRESENT+RW+A+D+2MB+GLOBAL */
    2.96          mov     $8,%ecx
    2.97  1:      mov     %eax,(%edi)
    2.98 @@ -109,25 +114,25 @@ 1:      mov     %eax,(%edi)
    2.99          add     $(1<<L2_PAGETABLE_SHIFT),%eax
   2.100          loop    1b
   2.101          /* Initialise L3 identity-map page directory entries. */
   2.102 -        mov     $SYM_PHYS(l3_identmap),%edi
   2.103 -        mov     $(SYM_PHYS(l2_identmap)+7),%eax
   2.104 +        mov     $sym_phys(l3_identmap),%edi
   2.105 +        mov     $(sym_phys(l2_identmap)+7),%eax
   2.106          mov     $4,%ecx
   2.107  1:      mov     %eax,(%edi)
   2.108          add     $8,%edi
   2.109          add     $PAGE_SIZE,%eax
   2.110          loop    1b
   2.111          /* Initialise L3 xen-map page directory entry. */
   2.112 -        mov     $(SYM_PHYS(l2_xenmap)+7),%eax
   2.113 -        mov     %eax,SYM_PHYS(l3_xenmap) + (50*8)
   2.114 +        mov     $(sym_phys(l2_xenmap)+7),%eax
   2.115 +        mov     %eax,sym_phys(l3_xenmap) + (50*8)
   2.116          /* Hook indentity-map and xen-map L3 tables into PML4. */
   2.117 -        mov     $(SYM_PHYS(l3_identmap)+7),%eax
   2.118 -        mov     %eax,SYM_PHYS(idle_pg_table) + (  0*8) /* PML4[  0]: 1:1 map */
   2.119 -        mov     %eax,SYM_PHYS(idle_pg_table) + (262*8) /* PML4[262]: 1:1 map */
   2.120 -        mov     $(SYM_PHYS(l3_xenmap)+7),%eax
   2.121 -        mov     %eax,SYM_PHYS(idle_pg_table) + (261*8) /* PML4[261]: xen map */
   2.122 +        mov     $(sym_phys(l3_identmap)+7),%eax
   2.123 +        mov     %eax,sym_phys(idle_pg_table) + (  0*8) /* PML4[  0]: 1:1 map */
   2.124 +        mov     %eax,sym_phys(idle_pg_table) + (262*8) /* PML4[262]: 1:1 map */
   2.125 +        mov     $(sym_phys(l3_xenmap)+7),%eax
   2.126 +        mov     %eax,sym_phys(idle_pg_table) + (261*8) /* PML4[261]: xen map */
   2.127  #elif defined(CONFIG_X86_PAE)
   2.128          /* Initialize low and high mappings of memory with 2MB pages */
   2.129 -        mov     $SYM_PHYS(idle_pg_table_l2),%edi
   2.130 +        mov     $sym_phys(idle_pg_table_l2),%edi
   2.131          mov     $0xe3,%eax                   /* PRESENT+RW+A+D+2MB */
   2.132  1:      mov     %eax,__PAGE_OFFSET>>18(%edi) /* high mapping */
   2.133          stosl                                /* low mapping */
   2.134 @@ -142,7 +147,7 @@ 1:      stosl   /* low mappings cover up
   2.135          jne     1b
   2.136  #else
   2.137          /* Initialize low and high mappings of memory with 4MB pages */
   2.138 -        mov     $SYM_PHYS(idle_pg_table),%edi
   2.139 +        mov     $sym_phys(idle_pg_table),%edi
   2.140          mov     $0xe3,%eax                   /* PRESENT+RW+A+D+4MB */
   2.141  1:      mov     %eax,__PAGE_OFFSET>>20(%edi) /* high mapping */
   2.142          stosl                                /* low mapping */
   2.143 @@ -156,22 +161,20 @@ 1:      stosl   /* low mappings cover up
   2.144  #endif
   2.145  
   2.146          /* Copy bootstrap trampoline to low memory, below 1MB. */
   2.147 -        mov     $SYM_PHYS(trampoline_start),%esi
   2.148 -        mov     $SYM_TRAMP_PHYS(trampoline_start),%edi
   2.149 +        mov     $sym_phys(trampoline_start),%esi
   2.150 +        mov     $bootsym_phys(trampoline_start),%edi
   2.151          mov     $trampoline_end - trampoline_start,%ecx
   2.152          rep     movsb
   2.153  
   2.154 -        /* EBX == 0 indicates we are the BP (Boot Processor). */
   2.155 -        xor     %ebx,%ebx
   2.156 -
   2.157          /* Jump into the relocated trampoline. */
   2.158 -        jmp     $TRAMP_CS32,$SYM_TRAMP_PHYS(trampoline_protmode_entry)
   2.159 +        jmp     $BOOT_CS32,$bootsym_phys(trampoline_boot_cpu_entry)
   2.160  
   2.161          .globl trampoline_start, trampoline_end
   2.162  trampoline_start:
   2.163  #include "trampoline.S"
   2.164  trampoline_end:
   2.165  
   2.166 +        .text
   2.167  __high_start:
   2.168  #ifdef __x86_64__
   2.169  #include "x86_64.S"
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/xen/arch/x86/boot/mem.S	Thu Jun 07 19:41:59 2007 +0100
     3.3 @@ -0,0 +1,78 @@
     3.4 +        .code16
     3.5 +
     3.6 +#define SMAP    0x534d4150
     3.7 +#define E820MAX 128
     3.8 +
     3.9 +get_memory_map:
    3.10 +
    3.11 +.Lmeme820:
    3.12 +        xorl    %ebx, %ebx                      # continuation counter
    3.13 +        movw    $bootsym(e820map), %di             # point into the whitelist
    3.14 +                                                # so we can have the bios
    3.15 +                                                # directly write into it.
    3.16 +
    3.17 +1:      movl    $0x0000e820, %eax               # e820, upper word zeroed
    3.18 +        movl    $SMAP,%edx                      # ascii 'SMAP'
    3.19 +        movl    $20,%ecx                        # size of the e820rec
    3.20 +        pushw   %ds                             # data record.
    3.21 +        popw    %es
    3.22 +        int     $0x15
    3.23 +        jc      .Lmem88
    3.24 +
    3.25 +        cmpl    $SMAP,%eax                      # check the return is `SMAP'
    3.26 +        jne     .Lmem88
    3.27 +
    3.28 +        movb    bootsym(e820nr),%al             # up to 128 entries
    3.29 +        cmpb    $E820MAX,%al
    3.30 +        jae     .Lmem88
    3.31 +
    3.32 +        incb    bootsym(e820nr)
    3.33 +        movw    %di,%ax
    3.34 +        addw    $20,%ax
    3.35 +        movw    %ax,%di
    3.36 +        cmpl    $0,%ebx                         # check to see if
    3.37 +        jne     1b                              # %ebx is set to EOF
    3.38 +
    3.39 +.Lmem88:
    3.40 +        movb    $0x88, %ah
    3.41 +        int     $0x15
    3.42 +        movw    %ax,bootsym(highmem_kb)
    3.43 +
    3.44 +.Lmeme801:
    3.45 +        stc                                     # fix to work around buggy
    3.46 +        xorw    %cx,%cx                         # BIOSes which don't clear/set
    3.47 +        xorw    %dx,%dx                         # carry on pass/error of
    3.48 +                                                # e801h memory size call
    3.49 +                                                # or merely pass cx,dx though
    3.50 +                                                # without changing them.
    3.51 +        movw    $0xe801, %ax
    3.52 +        int     $0x15
    3.53 +        jc      .Lint12
    3.54 +
    3.55 +        cmpw    $0x0, %cx                       # Kludge to handle BIOSes
    3.56 +        jne     1f                              # which report their extended
    3.57 +        cmpw    $0x0, %dx                       # memory in AX/BX rather than
    3.58 +        jne     1f                              # CX/DX.  The spec I have read
    3.59 +        movw    %ax, %cx                        # seems to indicate AX/BX 
    3.60 +        movw    %bx, %dx                        # are more reasonable anyway...
    3.61 +1:      andl    $0xffff,%edx                    # clear sign extend
    3.62 +        shll    $6,%edx                         # and go from 64k to 1k chunks
    3.63 +        movl    %edx,bootsym(highmem_kb)        # store extended memory size
    3.64 +        andl    $0xffff,%ecx                    # clear sign extend
    3.65 +        addl    %ecx,bootsym(highmem_kb)        # and add lower memory into
    3.66 +
    3.67 +.Lint12:
    3.68 +        int     $0x12
    3.69 +        movw    %ax,bootsym(lowmem_kb)
    3.70 +
    3.71 +        ret
    3.72 +
    3.73 +        .globl e820map, e820nr, lowmem_kb, highmem_kb
    3.74 +e820map:
    3.75 +        .fill   E820MAX*20,1,0
    3.76 +e820nr:
    3.77 +        .byte   0
    3.78 +lowmem_kb:
    3.79 +        .long   0
    3.80 +highmem_kb:
    3.81 +        .long   0
     4.1 --- a/xen/arch/x86/boot/trampoline.S	Thu Jun 07 16:44:04 2007 +0100
     4.2 +++ b/xen/arch/x86/boot/trampoline.S	Thu Jun 07 19:41:59 2007 +0100
     4.3 @@ -1,28 +1,34 @@
     4.4          .code16
     4.5  
     4.6 +/* NB. bootsym() is only usable in real mode, or via BOOT_PSEUDORM_DS. */
     4.7 +#undef bootsym
     4.8 +#define bootsym(s) ((s)-trampoline_start)
     4.9 +
    4.10          .globl trampoline_realmode_entry
    4.11  trampoline_realmode_entry:
    4.12          nop                               # We use this byte as a progress flag
    4.13 -        movb    $0xA5,trampoline_cpu_started - trampoline_start
    4.14 +        movb    $0xA5,bootsym(trampoline_cpu_started)
    4.15          cld
    4.16          cli
    4.17 -        lidt    %cs:idt_48 - trampoline_start
    4.18 -        lgdt    %cs:gdt_48 - trampoline_start
    4.19 +        lidt    %cs:bootsym(idt_48)
    4.20 +        lgdt    %cs:bootsym(gdt_48)
    4.21          xor     %ax, %ax
    4.22          inc     %ax
    4.23          lmsw    %ax                       # CR0.PE = 1 (enter protected mode)
    4.24          mov     $1,%bl                    # EBX != 0 indicates we are an AP
    4.25          jmp     1f
    4.26 -1:      ljmpl   $TRAMP_CS32,$SYM_TRAMP_PHYS(trampoline_protmode_entry)
    4.27 +1:      ljmpl   $BOOT_CS32,$bootsym_phys(trampoline_protmode_entry)
    4.28  
    4.29  idt_48: .word   0, 0, 0 # base = limit = 0
    4.30 -gdt_48: .word   4*8-1
    4.31 -        .long   SYM_TRAMP_PHYS(trampoline_gdt)
    4.32 +gdt_48: .word   6*8-1
    4.33 +        .long   bootsym_phys(trampoline_gdt)
    4.34  trampoline_gdt:
    4.35          .quad   0x0000000000000000     /* 0x0000: unused */
    4.36          .quad   0x00cf9a000000ffff     /* 0x0008: ring 0 code, 32-bit mode */
    4.37          .quad   0x00af9a000000ffff     /* 0x0010: ring 0 code, 64-bit mode */
    4.38          .quad   0x00cf92000000ffff     /* 0x0018: ring 0 data */
    4.39 +        .quad   0x00009a090000ffff     /* 0x0020: real-mode code @ 0x90000 */
    4.40 +        .quad   0x000092090000ffff     /* 0x0028: real-mode data @ 0x90000 */
    4.41  
    4.42  cpuid_ext_features:
    4.43          .long   0
    4.44 @@ -38,7 +44,7 @@ trampoline_cpu_started:
    4.45          .code32
    4.46  trampoline_protmode_entry:
    4.47          /* Set up a few descriptors: on entry only CS is guaranteed good. */
    4.48 -        mov     $TRAMP_DS,%eax
    4.49 +        mov     $BOOT_DS,%eax
    4.50          mov     %eax,%ds
    4.51          mov     %eax,%es
    4.52  
    4.53 @@ -54,13 +60,13 @@ trampoline_protmode_entry:
    4.54          mov     %ecx,%cr4
    4.55  
    4.56          /* Load pagetable base register. */
    4.57 -        mov     $SYM_PHYS(idle_pg_table),%eax
    4.58 -        add     SYM_TRAMP_PHYS(trampoline_xen_phys_start),%eax
    4.59 +        mov     $sym_phys(idle_pg_table),%eax
    4.60 +        add     bootsym_phys(trampoline_xen_phys_start),%eax
    4.61          mov     %eax,%cr3
    4.62  
    4.63  #if CONFIG_PAGING_LEVELS != 2
    4.64          /* Set up EFER (Extended Feature Enable Register). */
    4.65 -        mov     SYM_TRAMP_PHYS(cpuid_ext_features),%edi
    4.66 +        mov     bootsym_phys(cpuid_ext_features),%edi
    4.67          test    $0x20100800,%edi /* SYSCALL/SYSRET, No Execute, Long Mode? */
    4.68          jz      .Lskip_efer
    4.69          movl    $MSR_EFER,%ecx
    4.70 @@ -84,7 +90,7 @@ 1:
    4.71  #if defined(__x86_64__)
    4.72  
    4.73          /* Now in compatibility mode. Long-jump into 64-bit mode. */
    4.74 -        ljmp    $TRAMP_CS64,$SYM_TRAMP_PHYS(start64)
    4.75 +        ljmp    $BOOT_CS64,$bootsym_phys(start64)
    4.76  
    4.77          .code64
    4.78  start64:
    4.79 @@ -108,3 +114,68 @@ high_start:
    4.80          ljmp    $(__HYPERVISOR_CS),$__high_start
    4.81  
    4.82  #endif
    4.83 +
    4.84 +        .code32
    4.85 +trampoline_boot_cpu_entry:
    4.86 +        /* Load pseudo-real-mode segments. */
    4.87 +        mov     $BOOT_PSEUDORM_DS,%eax
    4.88 +        mov     %eax,%ds
    4.89 +        mov     %eax,%es
    4.90 +        mov     %eax,%fs
    4.91 +        mov     %eax,%gs
    4.92 +        mov     %eax,%ss
    4.93 +
    4.94 +        /* Switch to pseudo-rm CS, enter real mode, and flush insn queue. */
    4.95 +        mov     %cr0,%eax
    4.96 +        dec     %eax
    4.97 +        ljmp    $BOOT_PSEUDORM_CS,$bootsym(1f)
    4.98 +        .code16
    4.99 +1:      mov     %eax,%cr0                 # CR0.PE = 0 (leave protected mode)
   4.100 +        jmp     1f
   4.101 +
   4.102 +        /* Load proper real-mode values into %cs, %ds, %es and %ss. */
   4.103 +1:      ljmp    $(BOOT_TRAMPOLINE>>4),$bootsym(1f)
   4.104 +1:      mov     $(BOOT_TRAMPOLINE>>4),%ax
   4.105 +        mov     %ax,%ds
   4.106 +        mov     %ax,%es
   4.107 +        mov     %ax,%ss
   4.108 +
   4.109 +        /* Stack grows down from 0x9200. Initialise IDT and enable irqs. */
   4.110 +        mov     $0x2000,%sp
   4.111 +        lidt    bootsym(rm_idt)
   4.112 +        sti
   4.113 +
   4.114 +        /*
   4.115 +         * Do real-mode work:
   4.116 +         *  1. Get memory map.
   4.117 +         */
   4.118 +        call    get_memory_map
   4.119 +
   4.120 +        /* Disable irqs before returning to protected mode. */
   4.121 +        cli
   4.122 +
   4.123 +        /* Enter protected mode, and flush insn queue. */
   4.124 +        xor     %ax,%ax
   4.125 +        inc     %ax
   4.126 +        lmsw    %ax                       # CR0.PE = 1 (enter protected mode)
   4.127 +        jmp     1f
   4.128 +
   4.129 +        /* Load proper protected-mode values into all segment registers. */
   4.130 +1:      ljmpl   $BOOT_CS32,$bootsym_phys(1f)
   4.131 +        .code32
   4.132 +1:      mov     $BOOT_DS,%eax
   4.133 +        mov     %eax,%ds
   4.134 +        mov     %eax,%es
   4.135 +        mov     %eax,%fs
   4.136 +        mov     %eax,%gs
   4.137 +        mov     %eax,%ss
   4.138 +
   4.139 +        /* EBX == 0 indicates we are the BP (Boot Processor). */
   4.140 +        xor     %ebx,%ebx
   4.141 +
   4.142 +        /* Jump to the common bootstrap entry point. */
   4.143 +        jmp     trampoline_protmode_entry
   4.144 +
   4.145 +rm_idt: .word   256*4-1, 0, 0
   4.146 +
   4.147 +#include "mem.S"
     5.1 --- a/xen/arch/x86/boot/x86_32.S	Thu Jun 07 16:44:04 2007 +0100
     5.2 +++ b/xen/arch/x86/boot/x86_32.S	Thu Jun 07 19:41:59 2007 +0100
     5.3 @@ -71,7 +71,7 @@ gdt_descr:
     5.4          .word   0
     5.5  nopaging_gdt_descr:
     5.6          .word   LAST_RESERVED_GDT_BYTE
     5.7 -        .long   SYM_PHYS(gdt_table) - FIRST_RESERVED_GDT_BYTE
     5.8 +        .long   sym_phys(gdt_table) - FIRST_RESERVED_GDT_BYTE
     5.9  
    5.10          .align PAGE_SIZE, 0
    5.11  /* NB. Rings != 0 get access up to MACH2PHYS_VIRT_END. This allows access to */
    5.12 @@ -93,8 +93,8 @@ ENTRY(gdt_table)
    5.13  #ifdef CONFIG_X86_PAE
    5.14          .align 32
    5.15  ENTRY(idle_pg_table)
    5.16 -        .long SYM_PHYS(idle_pg_table_l2) + 0*PAGE_SIZE + 0x01, 0
    5.17 -        .long SYM_PHYS(idle_pg_table_l2) + 1*PAGE_SIZE + 0x01, 0
    5.18 -        .long SYM_PHYS(idle_pg_table_l2) + 2*PAGE_SIZE + 0x01, 0
    5.19 -        .long SYM_PHYS(idle_pg_table_l2) + 3*PAGE_SIZE + 0x01, 0
    5.20 +        .long sym_phys(idle_pg_table_l2) + 0*PAGE_SIZE + 0x01, 0
    5.21 +        .long sym_phys(idle_pg_table_l2) + 1*PAGE_SIZE + 0x01, 0
    5.22 +        .long sym_phys(idle_pg_table_l2) + 2*PAGE_SIZE + 0x01, 0
    5.23 +        .long sym_phys(idle_pg_table_l2) + 3*PAGE_SIZE + 0x01, 0
    5.24  #endif
     6.1 --- a/xen/arch/x86/setup.c	Thu Jun 07 16:44:04 2007 +0100
     6.2 +++ b/xen/arch/x86/setup.c	Thu Jun 07 19:41:59 2007 +0100
     6.3 @@ -395,7 +395,22 @@ void __init __start_xen(multiboot_info_t
     6.4      if ( opt_xenheap_megabytes > 2048 )
     6.5          opt_xenheap_megabytes = 2048;
     6.6  
     6.7 -    if ( mbi->flags & MBI_MEMMAP )
     6.8 +    if ( bootsym(e820nr) != 0 )
     6.9 +    {
    6.10 +        e820_raw_nr = bootsym(e820nr);
    6.11 +        memcpy(e820_raw, bootsym(e820map), e820_raw_nr * sizeof(e820_raw[0]));
    6.12 +    }
    6.13 +    else if ( lowmem_kb )
    6.14 +    {
    6.15 +        e820_raw[0].addr = 0;
    6.16 +        e820_raw[0].size = lowmem_kb << 10;
    6.17 +        e820_raw[0].type = E820_RAM;
    6.18 +        e820_raw[1].addr = 0x100000;
    6.19 +        e820_raw[1].size = highmem_kb << 10;
    6.20 +        e820_raw[1].type = E820_RAM;
    6.21 +        e820_raw_nr = 2;
    6.22 +    }
    6.23 +    else if ( mbi->flags & MBI_MEMMAP )
    6.24      {
    6.25          while ( bytes < mbi->mmap_length )
    6.26          {
    6.27 @@ -412,7 +427,12 @@ void __init __start_xen(multiboot_info_t
    6.28               */
    6.29              if ( (map->base_addr_high == 0) && (map->length_high != 0) )
    6.30              {
    6.31 -                e820_warn = 1;
    6.32 +                if ( !e820_warn )
    6.33 +                {
    6.34 +                    printk("WARNING: Buggy e820 map detected and fixed "
    6.35 +                           "(truncated length fields).\n");
    6.36 +                    e820_warn = 1;
    6.37 +                }
    6.38                  map->length_high = 0;
    6.39              }
    6.40  
    6.41 @@ -442,14 +462,11 @@ void __init __start_xen(multiboot_info_t
    6.42          EARLY_FAIL("Bootloader provided no memory information.\n");
    6.43      }
    6.44  
    6.45 -    if ( e820_warn )
    6.46 -        printk("WARNING: Buggy e820 map detected and fixed "
    6.47 -               "(truncated length fields).\n");
    6.48 -
    6.49      /* Ensure that all E820 RAM regions are page-aligned and -sized. */
    6.50      for ( i = 0; i < e820_raw_nr; i++ )
    6.51      {
    6.52          uint64_t s, e;
    6.53 +
    6.54          if ( e820_raw[i].type != E820_RAM )
    6.55              continue;
    6.56          s = PFN_UP(e820_raw[i].addr);
    6.57 @@ -530,7 +547,7 @@ void __init __start_xen(multiboot_info_t
    6.58              /* Select relocation address. */
    6.59              e = (e - (opt_xenheap_megabytes << 20)) & ~mask;
    6.60              xen_phys_start = e;
    6.61 -            boot_trampoline_va(trampoline_xen_phys_start) = e;
    6.62 +            bootsym(trampoline_xen_phys_start) = e;
    6.63  
    6.64              /*
    6.65               * Perform relocation to new physical address.
     7.1 --- a/xen/arch/x86/smpboot.c	Thu Jun 07 16:44:04 2007 +0100
     7.2 +++ b/xen/arch/x86/smpboot.c	Thu Jun 07 19:41:59 2007 +0100
     7.3 @@ -55,7 +55,7 @@
     7.4  #include <smpboot_hooks.h>
     7.5  
     7.6  #define set_kernel_exec(x, y) (0)
     7.7 -#define setup_trampoline()    (boot_trampoline_pa(trampoline_realmode_entry))
     7.8 +#define setup_trampoline()    (bootsym_phys(trampoline_realmode_entry))
     7.9  
    7.10  /* Set if we find a B stepping CPU */
    7.11  static int __devinitdata smp_b_stepping;
    7.12 @@ -905,7 +905,7 @@ static int __devinit do_boot_cpu(int api
    7.13  		} else {
    7.14  			boot_error = 1;
    7.15  			mb();
    7.16 -			if (boot_trampoline_va(trampoline_cpu_started) == 0xA5)
    7.17 +			if (bootsym(trampoline_cpu_started) == 0xA5)
    7.18  				/* trampoline started but...? */
    7.19  				printk("Stuck ??\n");
    7.20  			else
    7.21 @@ -927,7 +927,7 @@ static int __devinit do_boot_cpu(int api
    7.22  	}
    7.23  
    7.24  	/* mark "stuck" area as not stuck */
    7.25 -	boot_trampoline_va(trampoline_cpu_started) = 0;
    7.26 +	bootsym(trampoline_cpu_started) = 0;
    7.27  	mb();
    7.28  
    7.29  	return boot_error;
     8.1 --- a/xen/include/asm-x86/config.h	Thu Jun 07 16:44:04 2007 +0100
     8.2 +++ b/xen/include/asm-x86/config.h	Thu Jun 07 19:41:59 2007 +0100
     8.3 @@ -86,10 +86,10 @@
     8.4  #define CONFIG_DMA_BITSIZE 32
     8.5  
     8.6  #define BOOT_TRAMPOLINE 0x90000
     8.7 -#define boot_trampoline_pa(sym)                                 \
     8.8 +#define bootsym_phys(sym)                                 \
     8.9      (((unsigned long)&(sym)-(unsigned long)&trampoline_start)+BOOT_TRAMPOLINE)
    8.10 -#define boot_trampoline_va(sym)                                 \
    8.11 -    (*RELOC_HIDE((typeof(&(sym)))__va(__pa(&(sym))),            \
    8.12 +#define bootsym(sym)                                      \
    8.13 +    (*RELOC_HIDE((typeof(&(sym)))__va(__pa(&(sym))),      \
    8.14                   BOOT_TRAMPOLINE-__pa(trampoline_start)))
    8.15  #ifndef __ASSEMBLY__
    8.16  extern char trampoline_start[], trampoline_end[];
     9.1 --- a/xen/include/asm-x86/e820.h	Thu Jun 07 16:44:04 2007 +0100
     9.2 +++ b/xen/include/asm-x86/e820.h	Thu Jun 07 19:41:59 2007 +0100
     9.3 @@ -13,4 +13,9 @@ struct e820map {
     9.4  extern unsigned long init_e820(struct e820entry *, int *);
     9.5  extern struct e820map e820;
     9.6  
     9.7 +/* These symbols live in the boot trampoline. */
     9.8 +extern struct e820entry e820map[];
     9.9 +extern unsigned char e820nr;
    9.10 +extern unsigned int lowmem_kb, highmem_kb;
    9.11 +
    9.12  #endif /*__E820_HEADER*/