ia64/xen-unstable

changeset 3344:e57bbce13b4a

bitkeeper revision 1.1159.170.72 (41d3eaaftC1Zqz_rl9bIUUcTSZFIjg)

Add e820 parsing to Xen. Currently not hooked into heap initialisation:
this is the next step.
author kaf24@scramble.cl.cam.ac.uk
date Thu Dec 30 11:46:55 2004 +0000 (2004-12-30)
parents 1c1c7c231198
children b3b0139a17e0 1b41e54d74f6
files .rootkeys xen/arch/x86/e820.c xen/arch/x86/setup.c xen/include/asm-x86/e820.h xen/include/xen/multiboot.h
line diff
     1.1 --- a/.rootkeys	Wed Dec 29 15:49:53 2004 +0000
     1.2 +++ b/.rootkeys	Thu Dec 30 11:46:55 2004 +0000
     1.3 @@ -655,6 +655,7 @@ 40e42bdbNu4MjI750THP_8J1S-Sa0g xen/arch/
     1.4  3ddb79bcUrk2EIaM5VsT6wUudH1kkg xen/arch/x86/delay.c
     1.5  40e34414WiQO4h2m3tcpaCPn7SyYyg xen/arch/x86/dom0_ops.c
     1.6  3ddb79bc1_2bAt67x9MFCP4AZrQnvQ xen/arch/x86/domain.c
     1.7 +41d3eaae6GSDo3ZJDfK3nvQsJux-PQ xen/arch/x86/e820.c
     1.8  3ddb79bcY5zW7KhvI9gvfuPi3ZumEg xen/arch/x86/extable.c
     1.9  3fe443fdDDb0Sw6NQBCk4GQapayfTA xen/arch/x86/flushtlb.c
    1.10  3ddb79bcesE5E-lS4QhRhlqXxqj9cA xen/arch/x86/i387.c
    1.11 @@ -791,6 +792,7 @@ 3ddb79c3r9-31dIsewPV3P3i8HALsQ xen/inclu
    1.12  3ddb79c34BFiXjBJ_cCKB0aCsV1IDw xen/include/asm-x86/desc.h
    1.13  40715b2dTokMLYGSuD58BnxOqyWVew xen/include/asm-x86/div64.h
    1.14  3e20b82fl1jmQiKdLy7fxMcutfpjWA xen/include/asm-x86/domain_page.h
    1.15 +41d3eaaeIBzW621S1oa0c2yk7X43qQ xen/include/asm-x86/e820.h
    1.16  3ddb79c3NU8Zy40OTrq3D-i30Y3t4A xen/include/asm-x86/fixmap.h
    1.17  3e2d29944GI24gf7vOP_7x8EyuqxeA xen/include/asm-x86/flushtlb.h
    1.18  3ddb79c39o75zPP0T1aQQ4mNrCAN2w xen/include/asm-x86/hardirq.h
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/xen/arch/x86/e820.c	Thu Dec 30 11:46:55 2004 +0000
     2.3 @@ -0,0 +1,357 @@
     2.4 +#include <xen/config.h>
     2.5 +#include <xen/init.h>
     2.6 +#include <xen/lib.h>
     2.7 +#include <asm/e820.h>
     2.8 +
     2.9 +struct e820map e820;
    2.10 +
    2.11 +static void __init limit_regions(unsigned long long size)
    2.12 +{
    2.13 +    unsigned long long current_addr = 0;
    2.14 +    int i;
    2.15 +
    2.16 +#if 0
    2.17 +    if (efi_enabled) {
    2.18 +        for (i = 0; i < memmap.nr_map; i++) {
    2.19 +            current_addr = memmap.map[i].phys_addr +
    2.20 +                (memmap.map[i].num_pages << 12);
    2.21 +            if (memmap.map[i].type == EFI_CONVENTIONAL_MEMORY) {
    2.22 +                if (current_addr >= size) {
    2.23 +                    memmap.map[i].num_pages -=
    2.24 +                        (((current_addr-size) + PAGE_SIZE-1) >> PAGE_SHIFT);
    2.25 +                    memmap.nr_map = i + 1;
    2.26 +                    return;
    2.27 +                }
    2.28 +            }
    2.29 +        }
    2.30 +    }
    2.31 +#endif
    2.32 +
    2.33 +    for (i = 0; i < e820.nr_map; i++) {
    2.34 +        if (e820.map[i].type == E820_RAM) {
    2.35 +            current_addr = e820.map[i].addr + e820.map[i].size;
    2.36 +            if (current_addr >= size) {
    2.37 +                e820.map[i].size -= current_addr-size;
    2.38 +                e820.nr_map = i + 1;
    2.39 +                return;
    2.40 +            }
    2.41 +        }
    2.42 +    }
    2.43 +}
    2.44 +
    2.45 +static void __init add_memory_region(unsigned long long start,
    2.46 +                                     unsigned long long size, int type)
    2.47 +{
    2.48 +    int x;
    2.49 +
    2.50 +    /*if (!efi_enabled)*/ {
    2.51 +        x = e820.nr_map;
    2.52 +
    2.53 +        if (x == E820MAX) {
    2.54 +            printk(KERN_ERR "Ooops! Too many entries in the memory map!\n");
    2.55 +            return;
    2.56 +        }
    2.57 +
    2.58 +        e820.map[x].addr = start;
    2.59 +        e820.map[x].size = size;
    2.60 +        e820.map[x].type = type;
    2.61 +        e820.nr_map++;
    2.62 +    }
    2.63 +} /* add_memory_region */
    2.64 +
    2.65 +#define E820_DEBUG	1
    2.66 +
    2.67 +static void __init print_memory_map(char *who)
    2.68 +{
    2.69 +    int i;
    2.70 +
    2.71 +    for (i = 0; i < e820.nr_map; i++) {
    2.72 +        printk(" %s: %016Lx - %016Lx ", who,
    2.73 +               e820.map[i].addr,
    2.74 +               e820.map[i].addr + e820.map[i].size);
    2.75 +        switch (e820.map[i].type) {
    2.76 +        case E820_RAM:	printk("(usable)\n");
    2.77 +            break;
    2.78 +        case E820_RESERVED:
    2.79 +            printk("(reserved)\n");
    2.80 +            break;
    2.81 +        case E820_ACPI:
    2.82 +            printk("(ACPI data)\n");
    2.83 +            break;
    2.84 +        case E820_NVS:
    2.85 +            printk("(ACPI NVS)\n");
    2.86 +            break;
    2.87 +        default:	printk("type %u\n", e820.map[i].type);
    2.88 +            break;
    2.89 +        }
    2.90 +    }
    2.91 +}
    2.92 +
    2.93 +/*
    2.94 + * Sanitize the BIOS e820 map.
    2.95 + *
    2.96 + * Some e820 responses include overlapping entries.  The following 
    2.97 + * replaces the original e820 map with a new one, removing overlaps.
    2.98 + *
    2.99 + */
   2.100 +struct change_member {
   2.101 +    struct e820entry *pbios; /* pointer to original bios entry */
   2.102 +    unsigned long long addr; /* address for this change point */
   2.103 +};
   2.104 +static struct change_member change_point_list[2*E820MAX] __initdata;
   2.105 +static struct change_member *change_point[2*E820MAX] __initdata;
   2.106 +static struct e820entry *overlap_list[E820MAX] __initdata;
   2.107 +static struct e820entry new_bios[E820MAX] __initdata;
   2.108 +
   2.109 +static int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map)
   2.110 +{
   2.111 +    struct change_member *change_tmp;
   2.112 +    unsigned long current_type, last_type;
   2.113 +    unsigned long long last_addr;
   2.114 +    int chgidx, still_changing;
   2.115 +    int overlap_entries;
   2.116 +    int new_bios_entry;
   2.117 +    int old_nr, new_nr, chg_nr;
   2.118 +    int i;
   2.119 +
   2.120 +    /*
   2.121 +      Visually we're performing the following (1,2,3,4 = memory types)...
   2.122 +
   2.123 +      Sample memory map (w/overlaps):
   2.124 +      ____22__________________
   2.125 +      ______________________4_
   2.126 +      ____1111________________
   2.127 +      _44_____________________
   2.128 +      11111111________________
   2.129 +      ____________________33__
   2.130 +      ___________44___________
   2.131 +      __________33333_________
   2.132 +      ______________22________
   2.133 +      ___________________2222_
   2.134 +      _________111111111______
   2.135 +      _____________________11_
   2.136 +      _________________4______
   2.137 +
   2.138 +      Sanitized equivalent (no overlap):
   2.139 +      1_______________________
   2.140 +      _44_____________________
   2.141 +      ___1____________________
   2.142 +      ____22__________________
   2.143 +      ______11________________
   2.144 +      _________1______________
   2.145 +      __________3_____________
   2.146 +      ___________44___________
   2.147 +      _____________33_________
   2.148 +      _______________2________
   2.149 +      ________________1_______
   2.150 +      _________________4______
   2.151 +      ___________________2____
   2.152 +      ____________________33__
   2.153 +      ______________________4_
   2.154 +    */
   2.155 +
   2.156 +    /* if there's only one memory region, don't bother */
   2.157 +    if (*pnr_map < 2)
   2.158 +        return -1;
   2.159 +
   2.160 +    old_nr = *pnr_map;
   2.161 +
   2.162 +    /* bail out if we find any unreasonable addresses in bios map */
   2.163 +    for (i=0; i<old_nr; i++)
   2.164 +        if (biosmap[i].addr + biosmap[i].size < biosmap[i].addr)
   2.165 +            return -1;
   2.166 +
   2.167 +    /* create pointers for initial change-point information (for sorting) */
   2.168 +    for (i=0; i < 2*old_nr; i++)
   2.169 +        change_point[i] = &change_point_list[i];
   2.170 +
   2.171 +    /* record all known change-points (starting and ending addresses),
   2.172 +       omitting those that are for empty memory regions */
   2.173 +    chgidx = 0;
   2.174 +    for (i=0; i < old_nr; i++)	{
   2.175 +        if (biosmap[i].size != 0) {
   2.176 +            change_point[chgidx]->addr = biosmap[i].addr;
   2.177 +            change_point[chgidx++]->pbios = &biosmap[i];
   2.178 +            change_point[chgidx]->addr = biosmap[i].addr + biosmap[i].size;
   2.179 +            change_point[chgidx++]->pbios = &biosmap[i];
   2.180 +        }
   2.181 +    }
   2.182 +    chg_nr = chgidx;    	/* true number of change-points */
   2.183 +
   2.184 +    /* sort change-point list by memory addresses (low -> high) */
   2.185 +    still_changing = 1;
   2.186 +    while (still_changing)	{
   2.187 +        still_changing = 0;
   2.188 +        for (i=1; i < chg_nr; i++)  {
   2.189 +            /* if <current_addr> > <last_addr>, swap */
   2.190 +            /* or, if current=<start_addr> & last=<end_addr>, swap */
   2.191 +            if ((change_point[i]->addr < change_point[i-1]->addr) ||
   2.192 +                ((change_point[i]->addr == change_point[i-1]->addr) &&
   2.193 +                 (change_point[i]->addr == change_point[i]->pbios->addr) &&
   2.194 +                 (change_point[i-1]->addr != change_point[i-1]->pbios->addr))
   2.195 +                )
   2.196 +            {
   2.197 +                change_tmp = change_point[i];
   2.198 +                change_point[i] = change_point[i-1];
   2.199 +                change_point[i-1] = change_tmp;
   2.200 +                still_changing=1;
   2.201 +            }
   2.202 +        }
   2.203 +    }
   2.204 +
   2.205 +    /* create a new bios memory map, removing overlaps */
   2.206 +    overlap_entries=0;	 /* number of entries in the overlap table */
   2.207 +    new_bios_entry=0;	 /* index for creating new bios map entries */
   2.208 +    last_type = 0;		 /* start with undefined memory type */
   2.209 +    last_addr = 0;		 /* start with 0 as last starting address */
   2.210 +    /* loop through change-points, determining affect on the new bios map */
   2.211 +    for (chgidx=0; chgidx < chg_nr; chgidx++)
   2.212 +    {
   2.213 +        /* keep track of all overlapping bios entries */
   2.214 +        if (change_point[chgidx]->addr == change_point[chgidx]->pbios->addr)
   2.215 +        {
   2.216 +            /* add map entry to overlap list (> 1 entry implies an overlap) */
   2.217 +            overlap_list[overlap_entries++]=change_point[chgidx]->pbios;
   2.218 +        }
   2.219 +        else
   2.220 +        {
   2.221 +            /* remove entry from list (order independent, so swap with last) */
   2.222 +            for (i=0; i<overlap_entries; i++)
   2.223 +            {
   2.224 +                if (overlap_list[i] == change_point[chgidx]->pbios)
   2.225 +                    overlap_list[i] = overlap_list[overlap_entries-1];
   2.226 +            }
   2.227 +            overlap_entries--;
   2.228 +        }
   2.229 +        /* if there are overlapping entries, decide which "type" to use */
   2.230 +        /* (larger value takes precedence -- 1=usable, 2,3,4,4+=unusable) */
   2.231 +        current_type = 0;
   2.232 +        for (i=0; i<overlap_entries; i++)
   2.233 +            if (overlap_list[i]->type > current_type)
   2.234 +                current_type = overlap_list[i]->type;
   2.235 +        /* continue building up new bios map based on this information */
   2.236 +        if (current_type != last_type)	{
   2.237 +            if (last_type != 0)	 {
   2.238 +                new_bios[new_bios_entry].size =
   2.239 +                    change_point[chgidx]->addr - last_addr;
   2.240 +				/* move forward only if the new size was non-zero */
   2.241 +                if (new_bios[new_bios_entry].size != 0)
   2.242 +                    if (++new_bios_entry >= E820MAX)
   2.243 +                        break; 	/* no more space left for new bios entries */
   2.244 +            }
   2.245 +            if (current_type != 0)	{
   2.246 +                new_bios[new_bios_entry].addr = change_point[chgidx]->addr;
   2.247 +                new_bios[new_bios_entry].type = current_type;
   2.248 +                last_addr=change_point[chgidx]->addr;
   2.249 +            }
   2.250 +            last_type = current_type;
   2.251 +        }
   2.252 +    }
   2.253 +    new_nr = new_bios_entry;   /* retain count for new bios entries */
   2.254 +
   2.255 +    /* copy new bios mapping into original location */
   2.256 +    memcpy(biosmap, new_bios, new_nr*sizeof(struct e820entry));
   2.257 +    *pnr_map = new_nr;
   2.258 +
   2.259 +    return 0;
   2.260 +}
   2.261 +
   2.262 +/*
   2.263 + * Copy the BIOS e820 map into a safe place.
   2.264 + *
   2.265 + * Sanity-check it while we're at it..
   2.266 + *
   2.267 + * If we're lucky and live on a modern system, the setup code
   2.268 + * will have given us a memory map that we can use to properly
   2.269 + * set up memory.  If we aren't, we'll fake a memory map.
   2.270 + *
   2.271 + * We check to see that the memory map contains at least 2 elements
   2.272 + * before we'll use it, because the detection code in setup.S may
   2.273 + * not be perfect and most every PC known to man has two memory
   2.274 + * regions: one from 0 to 640k, and one from 1mb up.  (The IBM
   2.275 + * thinkpad 560x, for example, does not cooperate with the memory
   2.276 + * detection code.)
   2.277 + */
   2.278 +static int __init copy_e820_map(struct e820entry * biosmap, int nr_map)
   2.279 +{
   2.280 +    /* Only one memory region (or negative)? Ignore it */
   2.281 +    if (nr_map < 2)
   2.282 +        return -1;
   2.283 +
   2.284 +    do {
   2.285 +        unsigned long long start = biosmap->addr;
   2.286 +        unsigned long long size = biosmap->size;
   2.287 +        unsigned long long end = start + size;
   2.288 +        unsigned long type = biosmap->type;
   2.289 +
   2.290 +        /* Overflow in 64 bits? Ignore the memory map. */
   2.291 +        if (start > end)
   2.292 +            return -1;
   2.293 +
   2.294 +        /*
   2.295 +         * Some BIOSes claim RAM in the 640k - 1M region.
   2.296 +         * Not right. Fix it up.
   2.297 +         */
   2.298 +        if (type == E820_RAM) {
   2.299 +            if (start < 0x100000ULL && end > 0xA0000ULL) {
   2.300 +                if (start < 0xA0000ULL)
   2.301 +                    add_memory_region(start, 0xA0000ULL-start, type);
   2.302 +                if (end <= 0x100000ULL)
   2.303 +                    continue;
   2.304 +                start = 0x100000ULL;
   2.305 +                size = end - start;
   2.306 +            }
   2.307 +        }
   2.308 +        add_memory_region(start, size, type);
   2.309 +    } while (biosmap++,--nr_map);
   2.310 +    return 0;
   2.311 +}
   2.312 +
   2.313 +
   2.314 +/*
   2.315 + * Find the highest page frame number we have available
   2.316 + */
   2.317 +static unsigned long __init find_max_pfn(void)
   2.318 +{
   2.319 +    int i;
   2.320 +    unsigned long max_pfn = 0;
   2.321 +
   2.322 +#if 0
   2.323 +    if (efi_enabled) {
   2.324 +        efi_memmap_walk(efi_find_max_pfn, &max_pfn);
   2.325 +        return;
   2.326 +    }
   2.327 +#endif
   2.328 +
   2.329 +    for (i = 0; i < e820.nr_map; i++) {
   2.330 +        unsigned long start, end;
   2.331 +        /* RAM? */
   2.332 +        if (e820.map[i].type != E820_RAM)
   2.333 +            continue;
   2.334 +        start = PFN_UP(e820.map[i].addr);
   2.335 +        end = PFN_DOWN(e820.map[i].addr + e820.map[i].size);
   2.336 +        if (start >= end)
   2.337 +            continue;
   2.338 +        if (end > max_pfn)
   2.339 +            max_pfn = end;
   2.340 +    }
   2.341 +
   2.342 +    return max_pfn;
   2.343 +}
   2.344 +
   2.345 +static char * __init machine_specific_memory_setup(
   2.346 +    struct e820entry *raw, int raw_nr)
   2.347 +{
   2.348 +    char nr = (char)raw_nr;
   2.349 +    char *who = "Pseudo-e820";
   2.350 +    sanitize_e820_map(raw, &nr);
   2.351 +    (void)copy_e820_map(raw, nr);
   2.352 +    return who;
   2.353 +}
   2.354 +
   2.355 +unsigned long init_e820(struct e820entry *raw, int raw_nr)
   2.356 +{
   2.357 +    printk(KERN_INFO "Physical RAM map:\n");
   2.358 +    print_memory_map(machine_specific_memory_setup(raw, raw_nr));
   2.359 +    return find_max_pfn();
   2.360 +}
     3.1 --- a/xen/arch/x86/setup.c	Wed Dec 29 15:49:53 2004 +0000
     3.2 +++ b/xen/arch/x86/setup.c	Thu Dec 30 11:46:55 2004 +0000
     3.3 @@ -19,6 +19,7 @@
     3.4  #include <asm/domain_page.h>
     3.5  #include <asm/pdb.h>
     3.6  #include <asm/shadow.h>
     3.7 +#include <asm/e820.h>
     3.8  
     3.9  /* opt_dom0_mem: Kilobytes of memory allocated to domain 0. */
    3.10  static unsigned int opt_dom0_mem = 16000;
    3.11 @@ -467,10 +468,12 @@ void __init __start_xen(multiboot_info_t
    3.12      unsigned long max_mem;
    3.13      unsigned long dom0_memory_start, dom0_memory_end;
    3.14      unsigned long initial_images_start, initial_images_end;
    3.15 +    struct e820entry e820_raw[E820MAX];
    3.16 +    int e820_raw_nr = 0, bytes = 0;
    3.17  
    3.18      /* Parse the command-line options. */
    3.19 -    cmdline = (unsigned char *)(mbi->cmdline ? __va(mbi->cmdline) : NULL);
    3.20 -    cmdline_parse(cmdline);
    3.21 +    if ( (mbi->flags & MBI_CMDLINE) && (mbi->cmdline != 0) )
    3.22 +        cmdline_parse(__va(mbi->cmdline));
    3.23  
    3.24      /* Must do this early -- e.g., spinlocks rely on get_current(). */
    3.25      set_current(&idle0_task);
    3.26 @@ -480,28 +483,53 @@ void __init __start_xen(multiboot_info_t
    3.27  
    3.28      init_console();
    3.29  
    3.30 -    /* We require memory and module information. */
    3.31 -    if ( (mbi->flags & 9) != 9 )
    3.32 +    /* Check that we have at least one Multiboot module. */
    3.33 +    if ( !(mbi->flags & MBI_MODULES) || (mbi->mods_count == 0) )
    3.34      {
    3.35 -        printk("FATAL ERROR: Bad flags passed by bootloader: 0x%x\n", 
    3.36 -               (unsigned)mbi->flags);
    3.37 -        for ( ; ; ) ;
    3.38 -    }
    3.39 -
    3.40 -    if ( mbi->mods_count == 0 )
    3.41 -    {
    3.42 -        printk("Require at least one Multiboot module!\n");
    3.43 +        printk("FATAL ERROR: Require at least one Multiboot module.\n");
    3.44          for ( ; ; ) ;
    3.45      }
    3.46  
    3.47      if ( opt_xenheap_megabytes < 4 )
    3.48      {
    3.49 -        printk("Xen heap size is too small to safely continue!\n");
    3.50 +        printk("FATAL ERROR: Xen heap is too small to safely continue!\n");
    3.51          for ( ; ; ) ;
    3.52      }
    3.53  
    3.54      xenheap_phys_end = opt_xenheap_megabytes << 20;
    3.55  
    3.56 +    if ( mbi->flags & MBI_MEMMAP )
    3.57 +    {
    3.58 +        while ( bytes < mbi->mmap_length )
    3.59 +        {
    3.60 +            memory_map_t *map = __va(mbi->mmap_addr + bytes);
    3.61 +            e820_raw[e820_raw_nr].addr = 
    3.62 +                ((u64)map->base_addr_high << 32) | (u64)map->base_addr_low;
    3.63 +            e820_raw[e820_raw_nr].size = 
    3.64 +                ((u64)map->length_high << 32) | (u64)map->length_low;
    3.65 +            e820_raw[e820_raw_nr].type = 
    3.66 +                (map->type > E820_NVS) ? E820_RESERVED : map->type;
    3.67 +            e820_raw_nr++;
    3.68 +            bytes += map->size + 4;
    3.69 +        }
    3.70 +    }
    3.71 +    else if ( mbi->flags & MBI_MEMLIMITS )
    3.72 +    {
    3.73 +        e820_raw[0].addr = 0;
    3.74 +        e820_raw[0].size = mbi->mem_lower << 10;
    3.75 +        e820_raw[0].type = E820_RAM;
    3.76 +        e820_raw[0].addr = 0x100000;
    3.77 +        e820_raw[0].size = mbi->mem_upper << 10;
    3.78 +        e820_raw[0].type = E820_RAM;
    3.79 +        e820_raw_nr = 2;
    3.80 +    }
    3.81 +    else
    3.82 +    {
    3.83 +        printk("FATAL ERROR: Bootloader provided no memory information.\n");
    3.84 +        for ( ; ; ) ;
    3.85 +    }
    3.86 +
    3.87 +    max_mem = max_page = init_e820(e820_raw, e820_raw_nr);
    3.88      max_mem = max_page = (mbi->mem_upper+1024) >> (PAGE_SHIFT - 10);
    3.89  
    3.90  #if defined(__i386__)
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/xen/include/asm-x86/e820.h	Thu Dec 30 11:46:55 2004 +0000
     4.3 @@ -0,0 +1,33 @@
     4.4 +#ifndef __E820_HEADER
     4.5 +#define __E820_HEADER
     4.6 +
     4.7 +#include <asm/page.h>
     4.8 +
     4.9 +#define E820MAX	32
    4.10 +
    4.11 +#define E820_RAM	1
    4.12 +#define E820_RESERVED	2
    4.13 +#define E820_ACPI	3
    4.14 +#define E820_NVS	4
    4.15 +
    4.16 +#ifndef __ASSEMBLY__
    4.17 +struct e820entry {
    4.18 +    u64 addr;
    4.19 +    u64 size;
    4.20 +    u32 type;
    4.21 +} __attribute__((packed));
    4.22 +
    4.23 +struct e820map {
    4.24 +    int nr_map;
    4.25 +    struct e820entry map[E820MAX];
    4.26 +};
    4.27 +
    4.28 +extern unsigned long init_e820(struct e820entry *, int);
    4.29 +extern struct e820map e820;
    4.30 +
    4.31 +#endif /*!__ASSEMBLY__*/
    4.32 +
    4.33 +#define PFN_DOWN(_p)  ((_p)&PAGE_MASK)
    4.34 +#define PFN_UP(_p)    (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
    4.35 +
    4.36 +#endif /*__E820_HEADER*/
     5.1 --- a/xen/include/xen/multiboot.h	Wed Dec 29 15:49:53 2004 +0000
     5.2 +++ b/xen/include/xen/multiboot.h	Thu Dec 30 11:46:55 2004 +0000
     5.3 @@ -21,6 +21,13 @@
     5.4  /* The magic number passed by a Multiboot-compliant boot loader. */
     5.5  #define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002
     5.6  
     5.7 +#define MBI_MEMLIMITS  (1<<0)
     5.8 +#define MBI_DRIVES     (1<<1)
     5.9 +#define MBI_CMDLINE    (1<<2)
    5.10 +#define MBI_MODULES    (1<<3)
    5.11 +#define MBI_MEMMAP     (1<<6)
    5.12 +#define MBI_LOADERNAME (1<<9)
    5.13 +
    5.14  /* The symbol table for a.out.  */
    5.15  typedef struct {
    5.16      u32 tabsize;