summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKhalid Aziz <khalid.aziz@hp.com>2006-07-27 11:23:25 -0600
committerEric W. Biederman <ebiederm@xmission.com>2006-07-27 11:23:25 -0600
commit8889df7a1b19aebcc2a9d5f101b1b37aebc721c3 (patch)
tree6f68d817e81a15c42627642deb5b9fdedb12c525
parentbad9296125c088cbeaf747c0d7d909274e22e0ab (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.c92
-rw-r--r--kexec/arch/ia64/kexec-ia64.h2
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);