[PATCH 3/4] crash: add ARM diskdump support

Mika Westerberg ext-mika.1.westerberg at nokia.com
Wed Jun 30 06:09:11 EDT 2010


This patch adds support for reading diskdumps (generated by makedumpfile) for
ARM architecture.

Signed-off-by: Mika Westerberg <ext-mika.1.westerberg at nokia.com>
---
 diskdump.c |   50 +++++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 47 insertions(+), 3 deletions(-)

diff --git a/diskdump.c b/diskdump.c
index 79e72ad..2a22057 100644
--- a/diskdump.c
+++ b/diskdump.c
@@ -249,6 +249,9 @@ restart:
 	else if (STRNEQ(header->utsname.machine, "ppc64") &&
 	    machine_type_mismatch(file, "PPC64", NULL, 0))
 		goto err;
+	else if (STRNEQ(header->utsname.machine, "arm") &&
+	    machine_type_mismatch(file, "ARM", NULL, 0))
+		goto err;
 
 	if (header->block_size != block_size) {
 		block_size = header->block_size;
@@ -335,7 +338,9 @@ restart:
 
 	dd->header = header;
 
-	if (machine_type("X86"))
+	if (machine_type("ARM"))
+		dd->machine_type = EM_ARM;
+	else if (machine_type("X86"))
 		dd->machine_type = EM_386;
 	else if (machine_type("X86_64"))
 		dd->machine_type = EM_X86_64;
@@ -516,6 +521,33 @@ page_is_cached(physaddr_t paddr)
 }
 
 /*
+ * Translate physical address in paddr to PFN number. This means normally that
+ * we just shift paddr by some constant. Some architectures need special
+ * handling for this, however.
+ */
+static ulong
+paddr_to_pfn(physaddr_t paddr)
+{
+	ulong pfn;
+
+	switch (dd->machine_type) {
+	case EM_ARM:
+		/*
+		 * In ARM, PFN 0 means first page in kernel direct-mapped view.
+		 * This is also first page in mem_map as well.
+		 */
+		pfn = (paddr - machdep->machspec->phys_base) >> dd->block_shift;
+		break;
+
+	default:
+		pfn = paddr >> dd->block_shift;
+		break;
+	}
+
+	return pfn;
+}
+
+/*
  *  Cache the page's data.
  *
  *  If an empty page cache location is available, take it.  Otherwise, evict
@@ -560,7 +592,7 @@ cache_page(physaddr_t paddr)
 	dd->page_cache_hdr[i].pg_hit_count++;
 
 	/* find page descriptor */
-	pfn = paddr >> dd->block_shift;
+	pfn = paddr_to_pfn(paddr);
 	desc_pos = pfn_to_pos(pfn);
 	seek_offset = dd->data_offset
 			+ (off_t)(desc_pos - 1)*sizeof(page_desc_t);
@@ -613,7 +645,7 @@ read_diskdump(int fd, void *bufptr, int cnt, ulong addr, physaddr_t paddr)
 	physaddr_t curpaddr;
 	ulong pfn, page_offset;
 
-	pfn = paddr >> dd->block_shift;
+	pfn = paddr_to_pfn(paddr);
 
 	if (KDUMP_SPLIT()) {
 		/* Find proper dd */
@@ -687,6 +719,12 @@ get_diskdump_regs_ppc64(struct bt_info *bt, ulong *eip, ulong *esp)
 	machdep->get_stack_frame(bt, eip, esp);
 }
 
+static void
+get_diskdump_regs_arm(struct bt_info *bt, ulong *eip, ulong *esp)
+{
+	machdep->get_stack_frame(bt, eip, esp);
+}
+
 /*
  *  Send the request to the proper architecture hander.
  */
@@ -696,6 +734,10 @@ get_diskdump_regs(struct bt_info *bt, ulong *eip, ulong *esp)
 {
 	switch (dd->machine_type) 
 	{
+	case EM_ARM:
+		get_diskdump_regs_arm(bt, eip, esp);
+		break;
+
 	case EM_386:
 		return get_netdump_regs_x86(bt, eip, esp);
 		break;
@@ -784,6 +826,8 @@ __diskdump_memory_dump(FILE *fp)
         fprintf(fp, "      machine_type: %d ", dd->machine_type);
 	switch (dd->machine_type)
 	{
+	case EM_ARM:
+		fprintf(fp, "(EM_ARM)\n"); break;
 	case EM_386:
 		fprintf(fp, "(EM_386)\n"); break;
 	case EM_X86_64:
-- 
1.5.6.5




More information about the linux-arm-kernel mailing list