diff options
author | Khalid Aziz <khalid.aziz@hp.com> | 2006-07-27 11:23:25 -0600 |
---|---|---|
committer | Eric W. Biederman <ebiederm@xmission.com> | 2006-07-27 11:23:25 -0600 |
commit | 8889df7a1b19aebcc2a9d5f101b1b37aebc721c3 (patch) | |
tree | 6f68d817e81a15c42627642deb5b9fdedb12c525 | |
parent | bad9296125c088cbeaf747c0d7d909274e22e0ab (diff) |
ia64 use /proc/iomem
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 <khalid.aziz@hp.com>
Signed-off-by: Maneesh Soni <maneesh@in.ibm.com>
-rw-r--r-- | kexec/arch/ia64/kexec-ia64.c | 92 | ||||
-rw-r--r-- | kexec/arch/ia64/kexec-ia64.h | 2 |
2 files changed, 70 insertions, 24 deletions
diff --git a/kexec/arch/ia64/kexec-ia64.c b/kexec/arch/ia64/kexec-ia64.c index 01ba805..c11d36c 100644 --- a/kexec/arch/ia64/kexec-ia64.c +++ b/kexec/arch/ia64/kexec-ia64.c @@ -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 --git a/kexec/arch/ia64/kexec-ia64.h b/kexec/arch/ia64/kexec-ia64.h index df49852..b5419bb 100644 --- a/kexec/arch/ia64/kexec-ia64.h +++ b/kexec/arch/ia64/kexec-ia64.h @@ -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); |