Fw: [Fastboot] Re: [PATCH 3/6] ppc64-kdump-crash-memory-support

R Sharada sharada at in.ibm.com
Thu Jan 19 01:22:02 EST 2006


This patch apparently, for some strange reason, did not make it to the 
linuxppc64-dev mailing list. 
So, resending it again

Thanks and Regards,
Sharada
----- Forwarded message from R Sharada <sharada at in.ibm.com> -----

Date: Mon, 16 Jan 2006 20:40:52 +0530
From: R Sharada <sharada at in.ibm.com>
To: fastboot at osdl.org, linuxppc64-dev at ozlabs.org
Cc: 
Subject: [Fastboot] Re: [PATCH 3/6] ppc64-kdump-crash-memory-support
Reply-To: sharada at in.ibm.com



This patch provides the support for setting up te various
memory regions required for crashdump functionality.
- limit mem_min and mem_max to crash_base and crash_end
- create usable_memory_regions for use by second kernel
- exclude regions not to be dumped by second kernel.
For example - tce-table and crash reserved region
- include rtas region in crash_memory_ranges if it falls
within crash reserved region, as we want to obtain the
rtas image in the dump core file.




Signed-off-by: R Sharada <sharada at in.ibm.com>
Signed-off-by: Haren Myneni <hbabu at us.ibm.com>
---


diff -puN kexec/arch/ppc64/kexec-ppc64.c~ppc64-kdump-crash-memory-support kexec/arch/ppc64/kexec-ppc64.c
--- kexec-tools-1.101/kexec/arch/ppc64/kexec-ppc64.c~ppc64-kdump-crash-memory-support	2006-01-15 07:07:36.000000000 +0530
+++ kexec-tools-1.101-sharada/kexec/arch/ppc64/kexec-ppc64.c	2006-01-15 08:10:20.000000000 +0530
@@ -31,27 +31,23 @@
 #include "../../kexec.h"
 #include "../../kexec-syscall.h"
 #include "kexec-ppc64.h"
+#include "crashdump-ppc64.h"
 #include <arch/options.h>
 
-#define MAX_MEMORY_RANGES	64
-#define MAX_LINE	160
-#define MAXBYTES	128
 /* Platforms supported by kexec on PPC64 */
 #define PLATFORM_PSERIES	0x0100
 #define PLATFORM_PSERIES_LPAR	0x0101
 
-struct exclude_range {
-	unsigned long long start, end;
-};
 static struct exclude_range exclude_range[MAX_MEMORY_RANGES];
-
 static unsigned long long rmo_top;
 static unsigned int platform;
 static struct memory_range memory_range[MAX_MEMORY_RANGES];
 static struct memory_range base_memory_range[MAX_MEMORY_RANGES];
 unsigned long long memory_max = 0;
-static int nr_memory_ranges;
-static int nr_exclude_ranges;
+static int nr_memory_ranges, nr_exclude_ranges;
+unsigned long long crash_base, crash_size;
+
+static int sort_base_ranges();
 
 /* Get base memory ranges */
 static int get_base_ranges()
@@ -105,17 +101,44 @@ static int get_base_ranges()
 				((unsigned long long *)buf)[1];
 			base_memory_range[local_memory_ranges].type = RANGE_RAM;
 			local_memory_ranges++;
-#if 0
+#ifdef DEBUG
 			fprintf(stderr, "%016Lx-%016Lx : %x\n", memory_range[local_memory_ranges-1].start, memory_range[local_memory_ranges-1].end, memory_range[local_memory_ranges].type);
 #endif
 			fclose(file);
 		}
-		memory_max = base_memory_range[local_memory_ranges - 1].end;
 		closedir(dmem);
 	}
 	closedir(dir);
 	nr_memory_ranges = local_memory_ranges;
+	sort_base_ranges();
+	memory_max = base_memory_range[nr_memory_ranges - 1].end;
+#ifdef DEBUG
 	fprintf(stderr, "get base memory ranges:%d\n", nr_memory_ranges);
+#endif
+	return 0;
+}
+
+/* Sort the base ranges in memory - this is useful for ensuring that our
+ * ranges are in ascending order, even if device-tree read of memory nodes
+ * is done differently. Also, could be used for other range coalescing later
+ */
+static int sort_base_ranges()
+{
+	int i, j;
+	unsigned long long tstart, tend;
+
+	for (i = 0; i < nr_memory_ranges - 1; i++) {
+		for (j = 0; j < nr_memory_ranges - i - 1; j++) {
+			if (base_memory_range[j].start > base_memory_range[j+1].start) {
+				tstart = base_memory_range[j].start;
+				tend = base_memory_range[j].end;
+				base_memory_range[j].start = base_memory_range[j+1].start;
+				base_memory_range[j].end = base_memory_range[j+1].end;
+				base_memory_range[j+1].start = tstart;
+				base_memory_range[j+1].end = tend;
+			}
+		}
+	}
 	return 0;
 }
 
@@ -139,12 +162,17 @@ static int sort_ranges()
 	return 0;
 }
 
-/* Get devtree details and create exclude_range array */
-static int get_devtree_details()
+/* Get devtree details and create exclude_range array
+ * Also create usablemem_ranges for KEXEC_ON_CRASH
+ */
+static int get_devtree_details(unsigned long kexec_flags)
 {
 	unsigned long long rmo_base;
 	unsigned long long tce_base;
 	unsigned int tce_size;
+	unsigned int rtas_base, rtas_size;
+	unsigned long long htab_base, htab_size;
+	unsigned long long kernel_end;
 	char buf[MAXBYTES-1];
 	char device_tree[256] = "/proc/device-tree/";
 	char fname[256];
@@ -189,6 +217,7 @@ static int get_devtree_details()
 				return -1;
 			}
 			fclose(file);
+
 			memset(fname, 0, sizeof(fname));
 			strcpy(fname, device_tree);
 			strcat(fname, dentry->d_name);
@@ -199,7 +228,6 @@ static int get_devtree_details()
 				closedir(dir);
 				return -1;
 			}
-			unsigned long long kernel_end;
 			if (fread(&kernel_end, sizeof(unsigned long), 1, file) != 1) {
 				perror(fname);
 				fclose(file);
@@ -207,10 +235,62 @@ static int get_devtree_details()
 				closedir(dir);
 				return -1;
 			}
+			fclose(file);
+
 			/* Add kernel memory to exclude_range */
 			exclude_range[i].start = 0x0UL;
 			exclude_range[i].end = kernel_end;
 			i++;
+
+			if (kexec_flags & KEXEC_ON_CRASH) {
+				memset(fname, 0, sizeof(fname));
+				strcpy(fname, device_tree);
+				strcat(fname, dentry->d_name);
+				strcat(fname, "/linux,crashkernel-base");
+				if ((file = fopen(fname, "r")) == NULL) {
+					perror(fname);
+					closedir(cdir);
+					closedir(dir);
+					return -1;
+				}
+				if (fread(&crash_base, sizeof(unsigned long), 1,
+						file) != 1) {
+					perror(fname);
+					fclose(file);
+					closedir(cdir);
+					closedir(dir);
+					return -1;
+				}
+				fclose(file);
+
+				memset(fname, 0, sizeof(fname));
+				strcpy(fname, device_tree);
+				strcat(fname, dentry->d_name);
+				strcat(fname, "/linux,crashkernel-size");
+				if ((file = fopen(fname, "r")) == NULL) {
+					perror(fname);
+					closedir(cdir);
+					closedir(dir);
+					return -1;
+				}
+				if (fread(&crash_size, sizeof(unsigned long), 1,
+						file) != 1) {
+					perror(fname);
+					fclose(file);
+					closedir(cdir);
+					closedir(dir);
+					return -1;
+				}
+
+				if (crash_base > mem_min)
+					mem_min = crash_base;
+				if (crash_base + crash_size < mem_max)
+					mem_max = crash_base + crash_size;
+
+				add_usable_mem_rgns(0, crash_base + crash_size);
+				reserve(KDUMP_BACKUP_LIMIT, crash_base-KDUMP_BACKUP_LIMIT);
+			}
+
 			/* if LPAR, no need to read any more from /chosen */
 			if (platform != PLATFORM_PSERIES) {
 				closedir(cdir);
@@ -226,7 +306,6 @@ static int get_devtree_details()
 				closedir(dir);
 				return -1;
 			}
-			unsigned long long htab_base, htab_size;
 			if (fread(&htab_base, sizeof(unsigned long), 1, file) != 1) {
 				perror(fname);
 				fclose(file);
@@ -265,7 +344,6 @@ static int get_devtree_details()
 				closedir(dir);
 				return -1;
 			}
-			unsigned int rtas_base, rtas_size;
 			if (fread(&rtas_base, sizeof(unsigned int), 1, file) != 1) {
 				perror(fname);
 				fclose(file);
@@ -295,6 +373,8 @@ static int get_devtree_details()
 			exclude_range[i].start = rtas_base;
 			exclude_range[i].end = rtas_base + rtas_size;
 			i++;
+			if (kexec_flags & KEXEC_ON_CRASH)
+				add_usable_mem_rgns(rtas_base, rtas_size);
 		} /* rtas */
 
 		if (strncmp(dentry->d_name, "memory at 0", 8) == 0) {
@@ -314,8 +394,10 @@ static int get_devtree_details()
 			}
 			rmo_base = ((unsigned long long *)buf)[0];
 			rmo_top = rmo_base + ((unsigned long long *)buf)[1];
-			if (platform == PLATFORM_PSERIES)
-				if (memory_max > 0x40000000UL? (rmo_top = 0x40000000UL) : (rmo_top = memory_max));
+			if (platform == PLATFORM_PSERIES) {
+				if (rmo_top > 0x30000000UL)
+					rmo_top = 0x30000000UL;
+			}
 			fclose(file);
 			closedir(cdir);
 		} /* memory */
@@ -360,6 +442,8 @@ static int get_devtree_details()
 			exclude_range[i].start = tce_base;
 			exclude_range[i].end = tce_base + tce_size;
 			i++;
+			if (kexec_flags & KEXEC_ON_CRASH)
+				add_usable_mem_rgns(tce_base, tce_size);
 			closedir(cdir);
 		} /* pci */
 	}
@@ -368,7 +452,31 @@ static int get_devtree_details()
 	nr_exclude_ranges = i;
 
 	sort_ranges();
-#if 0
+
+	/* add crash_region and remove rtas range from exclude regions if it
+	 * lies within crash region
+	 */
+	if (kexec_flags & KEXEC_ON_CRASH) {
+		unsigned long new_crash_size;
+		if (crash_base < rtas_base &&
+			((crash_base + crash_size) > (rtas_base + rtas_size))){
+			new_crash_size = rtas_base - crash_base;
+			add_exclude_rgns(crash_base, new_crash_size);
+			new_crash_size = (crash_base + crash_size) - (rtas_base + rtas_size);
+			add_exclude_rgns(rtas_base + rtas_size, new_crash_size);
+		} else if (crash_base < rtas_base &&
+			((rtas_base + rtas_size) > (crash_base + crash_size))){
+			new_crash_size = rtas_base - crash_base;
+			add_exclude_rgns(crash_base, new_crash_size);
+		} else if (crash_base > rtas_base &&
+			((rtas_base + rtas_size) < (crash_base + crash_size))){
+			new_crash_size = (crash_base + crash_size) - (rtas_base + rtas_size);
+			add_exclude_rgns(rtas_base + rtas_size, new_crash_size);
+		} else
+			add_exclude_rgns(crash_base, crash_size);
+	}
+
+#ifdef DEBUG
 	int k;
 	for (k = 0; k < i; k++)
 		fprintf(stderr, "exclude_range sorted exclude_range[%d] start:%lx, end:%lx\n", k, exclude_range[k].start, exclude_range[k].end);
@@ -377,7 +485,7 @@ static int get_devtree_details()
 }
 
 /* Setup a sorted list of memory ranges. */
-int setup_memory_ranges(void)
+int setup_memory_ranges(unsigned long kexec_flags)
 {
 	int i, j = 0;
 
@@ -386,7 +494,7 @@ int setup_memory_ranges(void)
 	 */
 
 	get_base_ranges();
-	get_devtree_details();
+	get_devtree_details(kexec_flags);
 
 	for (i = 0; i < nr_exclude_ranges; i++) {
 		/* If first exclude range does not start with 0, include the
@@ -435,17 +543,18 @@ int setup_memory_ranges(void)
 			j--;
 			break;
 		}
-		if ((memory_range[j-1].start < rmo_top) && (memory_range[j-1].end >= rmo_top)) {
+		if ((memory_range[j-1].start < rmo_top) &&
+			(memory_range[j-1].end >= rmo_top)) {
 			memory_range[j-1].end = rmo_top;
 			break;
 		}
 	}
 	nr_memory_ranges = j;
 
-#if 0
+#ifdef DEBUG
 	int k;
 	for (k = 0; k < j; k++)
-		fprintf(stderr, "seup_memory_ranges memory_range[%d] start:%lx, end:%lx\n", k, memory_range[k].start, memory_range[k].end);
+		fprintf(stderr, "setup_memory_ranges memory_range[%d] start:%lx, end:%lx\n", k, memory_range[k].start, memory_range[k].end);
 #endif
 	return 0;
 }
@@ -454,7 +563,7 @@ int setup_memory_ranges(void)
 int get_memory_ranges(struct memory_range **range, int *ranges,
 			unsigned long kexec_flags)
 {
-	setup_memory_ranges();
+	setup_memory_ranges(kexec_flags);
 	*range = memory_range;
 	*ranges = nr_memory_ranges;
 	fprintf(stderr, "get memory ranges:%d\n", nr_memory_ranges);
diff -puN kexec/arch/ppc64/kexec-ppc64.h~ppc64-kdump-crash-memory-support kexec/arch/ppc64/kexec-ppc64.h
--- kexec-tools-1.101/kexec/arch/ppc64/kexec-ppc64.h~ppc64-kdump-crash-memory-support	2006-01-15 07:07:36.000000000 +0530
+++ kexec-tools-1.101-sharada/kexec/arch/ppc64/kexec-ppc64.h	2006-01-15 07:15:01.000000000 +0530
@@ -1,6 +1,12 @@
 #ifndef KEXEC_PPC64_H
 #define KEXEC_PPC64_H
 
+#define MAX_MEMORY_RANGES 256 /* TO FIX - needs to be dynamically set */
+#define MAXBYTES 128
+#define MAX_LINE 160
+
+int setup_memory_ranges(unsigned long kexec_flags);
+
 int elf_ppc64_probe(const char *buf, off_t len);
 int elf_ppc64_load(int argc, char **argv, const char *buf, off_t len,
 	struct kexec_info *info);
@@ -20,6 +26,10 @@ struct bootblock {
 		boot_physid;
 };
 
+struct exclude_range {
+        unsigned long long start, end;
+};
+
 typedef struct mem_rgns {
         unsigned int size;
         struct exclude_range ranges[MAX_MEMORY_RANGES];
diff -puN /dev/null kexec/arch/ppc64/crashdump-ppc64.c
--- /dev/null	2004-07-01 07:56:11.000000000 +0530
+++ kexec-tools-1.101-sharada/kexec/arch/ppc64/crashdump-ppc64.c	2006-01-15 08:06:29.000000000 +0530
@@ -0,0 +1,293 @@
+/*
+ * kexec: Linux boots Linux
+ *
+ * Created by: R Sharada (sharada at in.ibm.com)
+ * Copyright (C) IBM Corporation, 2005. All rights reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation (version 2 of the License).
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <limits.h>
+#include <elf.h>
+#include <dirent.h>
+#include "../../kexec.h"
+#include "../../kexec-elf.h"
+#include "../../kexec-syscall.h"
+#include "../../crashdump.h"
+#include "kexec-ppc64.h"
+#include "crashdump-ppc64.h"
+
+/* Stores a sorted list of RAM memory ranges for which to create elf headers.
+ * A separate program header is created for backup region
+ */
+static struct memory_range crash_memory_range[CRASH_MAX_MEMORY_RANGES];
+
+/*
+ * Used to save various memory ranges/regions needed for the captured
+ * kernel to boot. (lime memmap= option in other archs)
+ */
+mem_rgns_t usablemem_rgns = {0, };
+
+/* array to store memory regions to be excluded from elf header creation */
+mem_rgns_t exclude_rgns = {0, };
+
+static int sort_regions(mem_rgns_t *rgn);
+
+/* Reads the appropriate file and retrieves the SYSTEM RAM regions for whom to
+ * create Elf headers. Keeping it separate from get_memory_ranges() as
+ * requirements are different in the case of normal kexec and crashdumps.
+ *
+ * Normal kexec needs to look at all of available physical memory irrespective
+ * of the fact how much of it is being used by currently running kernel.
+ * Crashdumps need to have access to memory regions actually being used by
+ * running  kernel. Expecting a different file/data structure than /proc/iomem
+ * to look into down the line. May be something like /proc/kernelmem or may
+ * be zone data structures exported from kernel.
+ */
+static int get_crash_memory_ranges(struct memory_range **range, int *ranges)
+{
+
+	int memory_ranges = 0;
+	char device_tree[256] = "/proc/device-tree/";
+	char fname[256];
+	char buf[MAXBYTES-1];
+	DIR *dir, *dmem;
+	FILE *file;
+	struct dirent *dentry, *mentry;
+	int i, n, match;
+	unsigned long long start, end, cstart, cend;
+
+	/* create a separate program header for the backup region */
+	crash_memory_range[0].start = 0x0000000000000000;
+	crash_memory_range[0].end = 0x0000000000008000;
+	crash_memory_range[0].type = RANGE_RAM;
+	memory_ranges++;
+
+	if ((dir = opendir(device_tree)) == NULL) {
+		perror(device_tree);
+		return -1;
+	}
+	while ((dentry = readdir(dir)) != NULL) {
+		if (strncmp(dentry->d_name, "memory@", 7))
+			continue;
+		strcpy(fname, device_tree);
+		strcat(fname, dentry->d_name);
+		if ((dmem = opendir(fname)) == NULL) {
+			perror(fname);
+			closedir(dir);
+			return -1;
+		}
+		while ((mentry = readdir(dmem)) != NULL) {
+			if (strcmp(mentry->d_name, "reg"))
+				continue;
+			strcat(fname, "/reg");
+			if ((file = fopen(fname, "r")) == NULL) {
+				perror(fname);
+				closedir(dmem);
+				closedir(dir);
+				return -1;
+			}
+			if ((n = fread(buf, 1, MAXBYTES, file)) < 0) {
+				perror(fname);
+				fclose(file);
+				closedir(dmem);
+				closedir(dir);
+				return -1;
+			}
+			if (memory_ranges >= MAX_MEMORY_RANGES)
+				break;
+			start = ((unsigned long long *)buf)[0];
+			end = start + ((unsigned long long *)buf)[1];
+			if (start == 0 && end >= 0x8000)
+				start = 0x8000;
+			match = 0;
+			sort_regions(&exclude_rgns);
+
+			/* exclude crash reserved regions */
+			for (i = 0; i < exclude_rgns.size; i++) {
+				cstart = exclude_rgns.ranges[i].start;
+				cend = exclude_rgns.ranges[i].end;
+				if (cstart < end && cend > start) {
+					if ((cstart == start) && (cend == end)) {
+						match = 1;
+						continue;
+					}
+					if (start < cstart && end > cend) {
+						match = 1;
+						crash_memory_range[memory_ranges].start = start;
+						crash_memory_range[memory_ranges].end = cstart - 1;
+						crash_memory_range[memory_ranges].type = RANGE_RAM;
+						memory_ranges++;
+						crash_memory_range[memory_ranges].start = cend + 1;
+						crash_memory_range[memory_ranges].end = end;
+						crash_memory_range[memory_ranges].type = RANGE_RAM;
+						memory_ranges++;
+						break;
+					} else if (start < cstart) {
+						match = 1;
+						crash_memory_range[memory_ranges].start = start;
+						crash_memory_range[memory_ranges].end = cstart - 1;
+						crash_memory_range[memory_ranges].type = RANGE_RAM;
+						memory_ranges++;
+						end = cstart - 1;
+						continue;
+					} else if (end > cend){
+						match = 1;
+						crash_memory_range[memory_ranges].start = cend + 1;
+						crash_memory_range[memory_ranges].end = end;
+						crash_memory_range[memory_ranges].type = RANGE_RAM;
+						memory_ranges++;
+						start = cend + 1;
+						continue;
+					}
+				}
+
+			} /* end of for loop */
+			if (!match) {
+				crash_memory_range[memory_ranges].start = start;
+				crash_memory_range[memory_ranges].end  = end;
+				crash_memory_range[memory_ranges].type = RANGE_RAM;
+				memory_ranges++;
+			}
+
+			fclose(file);
+		}
+		closedir(dmem);
+	}
+	closedir(dir);
+
+	/*
+	 * Can not trust the memory regions order that we read from
+	 * device-tree. Hence, get the MAX end value.
+	 */
+	for (i = 0; i < memory_ranges; i++)
+		if (saved_max_mem < crash_memory_range[i].end)
+			saved_max_mem = crash_memory_range[i].end;
+
+	*range = crash_memory_range;
+	*ranges = memory_ranges;
+#if DEBUG
+	int i;
+	printf("CRASH MEMORY RANGES\n");
+	for(i = 0; i < *ranges; i++) {
+		start = crash_memory_range[i].start;
+		end = crash_memory_range[i].end;
+		fprintf(stderr, "%016Lx-%016Lx\n", start, end);
+	}
+#endif
+	return 0;
+}
+
+/*
+ * Used to save various memory regions needed for the captured kernel.
+ */
+
+void add_usable_mem_rgns(unsigned long long base, unsigned long long size)
+{
+	int i;
+	unsigned long long end = base + size;
+	unsigned long long ustart, uend;
+
+	base = _ALIGN_DOWN(base, PAGE_SIZE);
+	end = _ALIGN_UP(end, PAGE_SIZE);
+
+	for (i=0; i < usablemem_rgns.size; i++) {
+		ustart = usablemem_rgns.ranges[i].start;
+		uend = usablemem_rgns.ranges[i].end;
+		if (base < uend && end > ustart) {
+			if ((base >= ustart) && (end <= uend))
+				return;
+			if (base < ustart && end > uend) {
+				usablemem_rgns.ranges[i].start = base;
+				usablemem_rgns.ranges[i].end = end;
+				return;
+			} else if (base < ustart) {
+				usablemem_rgns.ranges[i].start = base;
+				return;
+			} else if (end > uend){
+				usablemem_rgns.ranges[i].end = end;
+				return;
+			}
+		}
+	}
+	usablemem_rgns.ranges[usablemem_rgns.size].start = base;
+	usablemem_rgns.ranges[usablemem_rgns.size++].end = end;
+
+#ifdef DEBUG
+	fprintf(stderr, "usable memory rgns size:%d base:%lx size:%lx\n", usablemem_rgns.size, base, size);
+#endif
+}
+
+/*
+ * Used to exclude various memory regions that do not need elf hdr generation
+ */
+
+void add_exclude_rgns(unsigned long long base, unsigned long long size)
+{
+	int i;
+	unsigned long long end = base + size;
+	unsigned long long xstart, xend;
+
+	for (i=0; i < exclude_rgns.size; i++) {
+		xstart = exclude_rgns.ranges[i].start;
+		xend = exclude_rgns.ranges[i].end;
+		if (base < xend && end > xstart) {
+			if ((base >= xstart) && (end <= xend))
+				return;
+			if (base < xstart && end > xend) {
+				exclude_rgns.ranges[i].start = base;
+				exclude_rgns.ranges[i].end = end;
+				return;
+			} else if (base < xstart) {
+				exclude_rgns.ranges[i].start = base;
+				exclude_rgns.ranges[i].end = xend;
+				return;
+			} else if (end > xend){
+				exclude_rgns.ranges[i].start = xstart;
+				exclude_rgns.ranges[i].end = end;
+				return;
+			}
+		}
+	}
+	exclude_rgns.ranges[exclude_rgns.size].start = base;
+	exclude_rgns.ranges[exclude_rgns.size++].end = end;
+
+#ifdef DEBUG
+	fprintf(stderr, "exclude rgns size:%d base:%lx end:%lx size:%lx\n", exclude_rgns.size, base, end, size);
+#endif
+}
+
+static int sort_regions(mem_rgns_t *rgn)
+{
+	int i, j;
+	unsigned long long tstart, tend;
+	for (i = 0; i < rgn->size; i++) {
+		for (j = 0; j < rgn->size - i - 1; j++) {
+			if (rgn->ranges[j].start > rgn->ranges[j+1].start) {
+				tstart = rgn->ranges[j].start;
+				tend = rgn->ranges[j].end;
+				rgn->ranges[j].start = rgn->ranges[j+1].start;
+				rgn->ranges[j].end = rgn->ranges[j+1].end;
+				rgn->ranges[j+1].start = tstart;
+				rgn->ranges[j+1].end = tend;
+			}
+		}
+	}
+	return 0;
+
+}
+
diff -puN kexec/arch/ppc64/crashdump-ppc64.h~ppc64-kdump-crash-memory-support kexec/arch/ppc64/crashdump-ppc64.h
--- kexec-tools-1.101/kexec/arch/ppc64/crashdump-ppc64.h~ppc64-kdump-crash-memory-support	2006-01-15 08:06:43.000000000 +0530
+++ kexec-tools-1.101-sharada/kexec/arch/ppc64/crashdump-ppc64.h	2006-01-15 08:09:45.000000000 +0530
@@ -1,7 +1,10 @@
 #ifndef CRASHDUMP_PPC64_H
 #define CRASHDUMP_PPC64_H
 
+int load_crashdump_segments(struct kexec_info *info, char *mod_cmdline,
+				unsigned long max_addr, unsigned long min_base);
 void add_usable_mem_rgns(unsigned long long base, unsigned long long size);
+void add_exclude_rgns(unsigned long long base, unsigned long long size);
 
 #define PAGE_OFFSET      0xC000000000000000
 #define KERNELBASE      PAGE_OFFSET
@@ -24,4 +27,7 @@ void add_usable_mem_rgns(unsigned long l
 #define _ALIGN_DOWN(addr,size)   ((addr)&(~((size)-1)))
 #define PAGE_SIZE      4096
 
+extern unsigned long long crash_base;
+extern unsigned long long crash_size;
+
 #endif /* CRASHDUMP_PPC64_H */
_

_______________________________________________
fastboot mailing list
fastboot at lists.osdl.org
https://lists.osdl.org/mailman/listinfo/fastboot


----- End forwarded message -----



More information about the Linuxppc64-dev mailing list