upgrade to linux 2.6.10-1.12_FC2
[linux-2.6.git] / arch / ia64 / kernel / efi.c
index 7b23f4d..cbe5585 100644 (file)
@@ -28,6 +28,7 @@
 
 #include <asm/io.h>
 #include <asm/kregs.h>
+#include <asm/meminit.h>
 #include <asm/pgtable.h>
 #include <asm/processor.h>
 #include <asm/mca.h>
@@ -324,12 +325,12 @@ efi_memmap_walk (efi_freemem_callback_t callback, void *arg)
                 * [granule_addr - first_non_wb_addr) is guaranteed to
                 * be contiguous WB memory.
                 */
-               granule_addr = md->phys_addr & ~(IA64_GRANULE_SIZE - 1);
+               granule_addr = GRANULEROUNDDOWN(md->phys_addr);
                first_non_wb_addr = max(first_non_wb_addr, granule_addr);
 
                if (first_non_wb_addr < md->phys_addr) {
                        trim_bottom(md, granule_addr + IA64_GRANULE_SIZE);
-                       granule_addr = md->phys_addr & ~(IA64_GRANULE_SIZE - 1);
+                       granule_addr = GRANULEROUNDDOWN(md->phys_addr);
                        first_non_wb_addr = max(first_non_wb_addr, granule_addr);
                }
 
@@ -343,24 +344,36 @@ efi_memmap_walk (efi_freemem_callback_t callback, void *arg)
                                break;          /* non-WB or hole */
                }
 
-               last_granule_addr = first_non_wb_addr & ~(IA64_GRANULE_SIZE - 1);
+               last_granule_addr = GRANULEROUNDDOWN(first_non_wb_addr);
                if (last_granule_addr < md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT))
                        trim_top(md, last_granule_addr);
 
                if (is_available_memory(md)) {
-                       if (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) > max_addr) {
-                               if (md->phys_addr > max_addr)
+                       if (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) >= max_addr) {
+                               if (md->phys_addr >= max_addr)
                                        continue;
                                md->num_pages = (max_addr - md->phys_addr) >> EFI_PAGE_SHIFT;
+                               first_non_wb_addr = max_addr;
                        }
 
                        if (total_mem >= mem_limit)
                                continue;
-                       total_mem += (md->num_pages << EFI_PAGE_SHIFT);
-                       if (total_mem > mem_limit) {
-                               md->num_pages -= ((total_mem - mem_limit) >> EFI_PAGE_SHIFT);
-                               max_addr = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT);
+
+                       if (total_mem + (md->num_pages << EFI_PAGE_SHIFT) > mem_limit) {
+                               unsigned long limit_addr = md->phys_addr;
+
+                               limit_addr += mem_limit - total_mem;
+                               limit_addr = GRANULEROUNDDOWN(limit_addr);
+
+                               if (md->phys_addr > limit_addr)
+                                       continue;
+
+                               md->num_pages = (limit_addr - md->phys_addr) >>
+                                               EFI_PAGE_SHIFT;
+                               first_non_wb_addr = max_addr = md->phys_addr +
+                                             (md->num_pages << EFI_PAGE_SHIFT);
                        }
+                       total_mem += (md->num_pages << EFI_PAGE_SHIFT);
 
                        if (md->num_pages == 0)
                                continue;
@@ -495,13 +508,13 @@ efi_init (void)
        for (cp = saved_command_line; *cp; ) {
                if (memcmp(cp, "mem=", 4) == 0) {
                        cp += 4;
-                       mem_limit = memparse(cp, &end) - 2;
+                       mem_limit = memparse(cp, &end);
                        if (end != cp)
                                break;
                        cp = end;
                } else if (memcmp(cp, "max_addr=", 9) == 0) {
                        cp += 9;
-                       max_addr = memparse(cp, &end) - 1;
+                       max_addr = GRANULEROUNDDOWN(memparse(cp, &end));
                        if (end != cp)
                                break;
                        cp = end;