[FOSS_TLK]tlk: arm: improve output during data abort handling
Chris Johnson [Tue, 23 Dec 2014 20:57:19 +0000 (12:57 -0800)]
Change-Id: I93642ee0ef21271f54d3bf421c168b32c9914222
Signed-off-by: Chris Johnson <cwj@nvidia.com>
Reviewed-on: http://git-master/r/715768
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Varun Wadekar <vwadekar@nvidia.com>
Tested-by: Varun Wadekar <vwadekar@nvidia.com>

arch/arm/arm/asm.S
arch/arm/arm/faults.c

index 9fffc7b..4b55c33 100644 (file)
@@ -103,7 +103,7 @@ FUNCTION(arm_context_switch)
 FUNCTION(arm_save_mode_regs)
        mrs             r1, cpsr
 
-#if ARM_ISA_ARMv6
+#if ARM_ISA_ARMV6 || ARM_ISA_ARMV7
        cps             #0x11                   /* fiq */
        str             r13, [r0], #4
        str             r14, [r0], #4
index 69b2d4e..0f96836 100644 (file)
 #include <assert.h>
 #include <arch.h>
 #include <arch/arm.h>
+#include <kernel/task.h>
 
+extern unsigned int ote_logger_enabled;
 #define MAX_FRAME_STRING_CHARS         64
 
+struct mode_str_ent {
+       uint32_t mode;
+       char *str;
+};
+
+static struct mode_str_ent mode_str[] = {
+       { .mode = MODE_USR, .str = "usr" },
+       { .mode = MODE_FIQ, .str = "fiq" },
+       { .mode = MODE_IRQ, .str = "irq" },
+       { .mode = MODE_SVC, .str = "svc" },
+       { .mode = MODE_MON, .str = "mon" },
+       { .mode = MODE_ABT, .str = "abt" },
+       { .mode = MODE_UND, .str = "und" },
+       { .mode = MODE_SYS, .str = "sys" },
+};
+
+static inline char *get_mode_str(uint32_t mode)
+{
+       uint32_t i;
+
+       for (i = 0; i < sizeof(mode_str) / sizeof(mode_str[0]); i++)
+               if (mode == mode_str[i].mode)
+                       return mode_str[i].str;
+       return NULL;
+}
+
 static void dump_fault_frame(struct arm_fault_frame *frame)
 {
        char str[MAX_FRAME_STRING_CHARS];
@@ -66,6 +94,7 @@ static void dump_fault_frame(struct arm_fault_frame *frame)
                case MODE_SVC: stack = regs.svc_r13; break;
                case MODE_UND: stack = regs.und_r13; break;
                case MODE_SYS: stack = regs.sys_r13; break;
+               case MODE_USR: stack = frame->usp; break;
                default:
                        stack = 0;
        }
@@ -167,6 +196,31 @@ fail:
 
 void arm_data_abort_handler(struct arm_fault_frame *frame)
 {
+       uint32_t dfar, dfsr;
+       uint32_t mode;
+
+       ote_logger_enabled = 0;
+       __asm volatile ("mrc    p15, 0, %0, c6, c0, 0" : "=r" (dfar));
+       __asm volatile ("mrc    p15, 0, %0, c5, c0, 0" : "=r" (dfsr));
+
+       dputs(CRITICAL, "TLK data abort handler\n");
+       printf("dfar: 0x%08x dfsr: 0x%08x\n", dfar, dfsr);
+       mode = frame->spsr & MODE_MASK;
+       printf("mode: 0x%02x / %s\n", mode, get_mode_str(mode));
+
+       if (mode == MODE_ABT) {
+               dputs(CRITICAL, "faulted in fault handler, just idle\n");
+               halt();
+               for(;;);
+       }
+
+       printf("current thread: %p (%s)\n", current_thread,
+               (current_thread) ? current_thread->name : NULL);
+       if (current_thread) {
+               task_t *task = current_thread->arch.task;
+               printf("current task: %p (%s)\n", task,
+                       (task) ? task->task_name : NULL);
+       }
        exception_die(frame, -8, "data abort, halting\n");
 }