From 92fa6d087f54354e860c9796f260c9e526511252 Mon Sep 17 00:00:00 2001
From: HATAYAMA Daisuke <d.hatayama@jp.fujitsu.com>
Date: Tue, 13 Mar 2012 19:08:15 +0900
Subject: [PATCH 4/4] Add vmcore snapshot support

Currently, snap command uses /proc/iomem as memory map information
even if the kernel image it's currently analysing is dumpfile. For
dumpfile, I want to use the /proc/iomem information in the dumpfile.

This patch makes snap command first check whether the current kernel
image is live kernel or dumpfile and then select proper resource for
memory mapping information.

For an access to resource objects, I used the interface prepared in
the previous patch.

Signed-off-by: HATAYAMA Daisuke <d.hatayama@jp.fujitsu.com>
---
 extensions/snap.c |   54 ++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 51 insertions(+), 3 deletions(-)

diff --git a/extensions/snap.c b/extensions/snap.c
index dedc286..7f180fc 100644
--- a/extensions/snap.c
+++ b/extensions/snap.c
@@ -32,7 +32,10 @@ static struct command_table_entry command_table[] = {
 
 static char *generate_elf_header(int, int, char *);
 static int verify_paddr(physaddr_t);
-static void init_ram_segments(void);
+static void init_ram_segments_live_iomem(void);
+static void countup_ram_map(struct resource_data *);
+static void get_ram_map(struct resource_data *);
+static void init_ram_segments_vmcore_iomem(void);
 static int print_progress(const char *, ulong);
 
 #if defined(X86) || defined(X86_64) || defined(IA64) || defined(PPC64)
@@ -114,7 +117,10 @@ cmd_snap(void)
 	if (!filename)
                 cmd_usage(pc->curcmd, SYNOPSIS);
 
-	init_ram_segments();
+	if (ACTIVE())
+		init_ram_segments_live_iomem();
+	else
+		init_ram_segments_vmcore_iomem();
 
 	if (!(elf_header = generate_elf_header(type, fd, filename)))
 		error(FATAL, "cannot generate ELF header\n");
@@ -609,7 +615,7 @@ static struct ram_segments *ram_segments = NULL;
 static int nr_segments = 0;
 
 static void
-init_ram_segments(void)
+init_ram_segments_live_iomem(void)
 {
 	int i, errflag;
         FILE *iomem; 
@@ -676,6 +682,48 @@ fail_iomem:
 	return; 
 }
 
+static void countup_ram_map(struct resource_data *r)
+{
+	if (STREQ(r->name, "System RAM"))
+		nr_segments++;
+}
+
+static void get_ram_map(struct resource_data *r)
+{
+	struct ram_segments *seg;
+
+	if (STREQ(r->name, "System RAM")) {
+
+		seg = &ram_segments[nr_segments];
+
+		seg->start = PHYSPAGEBASE(r->start);
+		if (PAGEOFFSET(r->start))
+			seg->start += PAGESIZE();
+
+		seg->end = PHYSPAGEBASE(r->end);
+		if (PAGEOFFSET(r->end) == (PAGESIZE()-1))
+			seg->end += PAGESIZE();
+
+		nr_segments++;
+	}
+}
+
+static void init_ram_segments_vmcore_iomem(void)
+{
+	ulong root = symbol_value("iomem_resource");
+
+	foreach_resource_tree(root, countup_ram_map);
+
+	if (!nr_segments)
+		return;
+
+	ram_segments = (struct ram_segments *)
+		GETBUF(sizeof(struct ram_segments) * nr_segments);
+
+	nr_segments = 0;
+	foreach_resource_tree(root, get_ram_map);
+}
+
 static int
 verify_paddr(physaddr_t paddr)
 {
-- 
1.7.4.4

