[PATCH 3/6] ppc64-kdump-crash-memory-support
R Sharada
sharada at in.ibm.com
Tue Jan 17 02:10:52 EST 2006
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 */
_
More information about the Linuxppc64-dev
mailing list