This patch makes kexec tool use /proc/iomem to determine memory layout
on ia64. This is based upon code written by Zou Nan hai.

Signed-off-by:  Khalid Aziz ,[EMAIL PROTECTED]>
---
diff -urNp kexec-tools-1.101/kexec/arch/ia64/kexec-ia64.c 
kexec-tools-1.101-kh/kexec/arch/ia64/kexec-ia64.c
--- kexec-tools-1.101/kexec/arch/ia64/kexec-ia64.c      2006-05-03 
12:09:16.000000000 -0600
+++ kexec-tools-1.101-kh/kexec/arch/ia64/kexec-ia64.c   2006-05-03 
15:40:23.000000000 -0600
@@ -34,36 +34,80 @@
 #include "kexec-ia64.h"
 #include <arch/options.h>
 
-#define MAX_MEMORY_RANGES 64
 static struct memory_range memory_range[MAX_MEMORY_RANGES];
 
 /* Return a sorted list of available memory ranges. */
 int get_memory_ranges(struct memory_range **range, int *ranges,
                                unsigned long kexec_flags)
 {
-       int memory_ranges;
-       /*
-        * /proc/iomem on ia64 does not show where all memory is. If
-        * that is fixed up, we can make use of that to validate
-        * the memory range kernel will be loade din. Until then.....
-        * -- Khalid Aziz
-        */
-       
-       /* Note that the ia64 architecture mandates all systems will
-        * have at least 64MB at 0-64M.  The SGI altix does not follow
-        * that restriction, but a reasonable guess is better than nothing
-        * at all.
-        * -- Eric Biederman
-        */
-       fprintf(stderr, "Warning assuming memory at 0-64MB is present\n");
-       memory_ranges = 0;
-       memory_range[memory_ranges].start = 0x00100000;
-       memory_range[memory_ranges].end   = 0x10000000;
-       memory_range[memory_ranges].type  = RANGE_RAM;
-       memory_ranges++;
-       *range = memory_range;
-       *ranges = memory_ranges;
-       return 0;
+       const char iomem[]= "/proc/iomem";
+       int memory_ranges = 0;
+       char line[MAX_LINE];
+       FILE *fp;
+       fp = fopen(iomem, "r");
+       if (!fp) {
+               fprintf(stderr, "Cannot open %s: %s\n", 
+                       iomem, strerror(errno));
+               return -1;
+       }
+
+       while(fgets(line, sizeof(line), fp) != 0) {
+               unsigned long start, end;
+               char *str;
+               int type;
+               int consumed;
+               int count;
+               if (memory_ranges >= MAX_MEMORY_RANGES)
+                       break;
+               count = sscanf(line, "%lx-%lx : %n",
+                               &start, &end, &consumed);
+               if (count != 2) 
+                       continue;
+               str = line + consumed;
+               end = end + 1;
+               if (memcmp(str, "System RAM\n", 11) == 0) {
+                       type = RANGE_RAM;
+               } 
+               else if (memcmp(str, "reserved\n", 9) == 0) {
+                       type = RANGE_RESERVED;
+               }
+               else if (memcmp(str, "Crash kernel\n", 13) == 0) {
+                       /* Redefine the memory region boundaries if kernel
+                        * exports the limits and if it is panic kernel.
+                        * Override user values only if kernel exported 
+                        * values are subset of user defined values.
+                        */
+                       
+                       if (kexec_flags & KEXEC_ON_CRASH) {
+                               if (start > mem_min)
+                                       mem_min = start;
+                               if (end < mem_max)
+                                       mem_max = end;
+                       }
+                       continue;
+               } else
+                       continue;
+               /* 
+                * Check if this memory range can be coalesced with 
+                * the previous range
+                */
+               if ((memory_ranges > 0) && 
+                       (start == memory_range[memory_ranges-1].end) &&
+                       (type == memory_range[memory_ranges-1].type)) {
+                       memory_range[memory_ranges-1].end = end;
+               }
+               else {
+                       memory_range[memory_ranges].start = start;
+                       memory_range[memory_ranges].end = end;
+                       memory_range[memory_ranges].type = type;
+                       memory_ranges++;
+               }
+       }
+       fclose(fp);
+       *range = memory_range;
+       *ranges = memory_ranges;
+
+       return 0;
 }
 
 /* Supported file types and callbacks */
diff -urNp kexec-tools-1.101/kexec/arch/ia64/kexec-ia64.h 
kexec-tools-1.101-kh/kexec/arch/ia64/kexec-ia64.h
--- kexec-tools-1.101/kexec/arch/ia64/kexec-ia64.h      2004-12-19 
16:52:38.000000000 -0700
+++ kexec-tools-1.101-kh/kexec/arch/ia64/kexec-ia64.h   2006-05-03 
15:40:07.000000000 -0600
@@ -1,6 +1,8 @@
 #ifndef KEXEC_IA64_H
 #define KEXEC_IA64_H
 
+#define MAX_MEMORY_RANGES 1024
+
 int elf_ia64_probe(const char *buf, off_t len);
 int elf_ia64_load(int argc, char **argv, const char *buf, off_t len,
        struct kexec_info *info);
---


-- 
Khalid

====================================================================
Khalid Aziz                       Open Source and Linux Organization
(970)898-9214                                        Hewlett-Packard
[EMAIL PROTECTED]                                  Fort Collins, CO

"The Linux kernel is subject to relentless development" 
                                - Alessandro Rubini


_______________________________________________
fastboot mailing list
[email protected]
https://lists.osdl.org/mailman/listinfo/fastboot

Reply via email to