summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/arm/shared/abort/simple_abort.c
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2007-05-15 18:03:05 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2007-05-15 18:03:05 +0000
commit40082322fad69256036fdf625b90d282def3b307 (patch)
tree5a566cb3b54375163d95e6bb12e6f00d7d51ce94 /c/src/lib/libbsp/arm/shared/abort/simple_abort.c
parent2007-05-15 Ray Xu <rayx@gmail.com> (diff)
downloadrtems-40082322fad69256036fdf625b90d282def3b307.tar.bz2
2007-05-15 Ray Xu <rayx@gmail.com>
* shared/abort/abort.c, shared/abort/simple_abort.c: New files.
Diffstat (limited to 'c/src/lib/libbsp/arm/shared/abort/simple_abort.c')
-rw-r--r--c/src/lib/libbsp/arm/shared/abort/simple_abort.c152
1 files changed, 152 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/arm/shared/abort/simple_abort.c b/c/src/lib/libbsp/arm/shared/abort/simple_abort.c
new file mode 100644
index 0000000000..98cf0f2bf3
--- /dev/null
+++ b/c/src/lib/libbsp/arm/shared/abort/simple_abort.c
@@ -0,0 +1,152 @@
+/*
+ * ARM CPU Dependent Source
+ *
+ * COPYRIGHT (c) 2007 Ray Xu.
+ * mailto: Rayx at gmail dot com
+ *
+ * COPYRIGHT (c) 2000 Canon Research Centre France SA.
+ * Emmanuel Raguet, mailto:raguet@crf.canon.fr
+ *
+ * Copyright (c) 2002 Advent Networks, Inc
+ * Jay Monkman <jmonkman@adventnetworks.com>
+ *
+ * This is a simple implement of abort
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ */
+#include <rtems/system.h>
+#include <rtems.h>
+
+#define INSN_MASK 0xc5
+
+#define INSN_STM1 0x80
+#define INSN_STM2 0x84
+#define INSN_STR 0x40
+#define INSN_STRB 0x44
+
+#define INSN_LDM1 0x81
+#define INSN_LDM23 0x85
+#define INSN_LDR 0x41
+#define INSN_LDRB 0x45
+
+#define GET_RD(x) ((x & 0x0000f000) >> 12)
+#define GET_RN(x) ((x & 0x000f0000) >> 16)
+
+#define GET_U(x) ((x & 0x00800000) >> 23)
+#define GET_I(x) ((x & 0x02000000) >> 25)
+
+#define GET_REG(r, ctx) (((uint32_t *)ctx)[r])
+#define SET_REG(r, ctx, v) (((uint32_t *)ctx)[r] = v)
+#define GET_OFFSET(insn) (insn & 0xfff)
+
+extern void printk(char *fmt, ...);
+
+
+char *_print_full_context_mode2txt[0x10]={
+ [0x0]="user", /* User */
+ [0x1]="fiq", /* FIQ - Fast Interrupt Request */
+ [0x2]="irq", /* IRQ - Interrupt Request */
+ [0x3]="super", /* Supervisor */
+ [0x7]="abort", /* Abort */
+ [0xb]="undef", /* Undefined */
+ [0xf]="system" /* System */
+ };
+
+void _print_full_context(uint32_t spsr)
+{
+ char *mode;
+ uint32_t prev_sp,prev_lr,cpsr,tmp;
+ int i;
+
+ printk("active thread thread 0x%08x\n", _Thread_Executing->Object.id);
+
+ mode=_print_full_context_mode2txt[(spsr&0x1f)-0x10];
+ if(!mode) mode="unknown";
+
+ asm volatile (" MRS %[cpsr], cpsr \n"
+ " ORR %[tmp], %[spsr], #0xc0 \n"
+ " MSR cpsr_c, %[tmp] \n"
+ " MOV %[prev_sp], sp \n"
+ " MOV %[prev_lr], lr \n"
+ " MSR cpsr_c, %[cpsr] \n"
+ : [prev_sp] "=&r" (prev_sp), [prev_lr] "=&r" (prev_lr),
+ [cpsr] "=&r" (cpsr), [tmp] "=&r" (tmp)
+ : [spsr] "r" (spsr)
+ : "cc");
+
+ printk("Previous sp=0x%08x lr=0x%08x and actual cpsr=%08x\n", prev_sp, prev_lr, cpsr);
+
+ for(i=0;i<48;){
+ printk(" 0x%08x",((uint32_t*)prev_sp)[i++]);
+ if((i%6) == 0)
+ printk("\n");
+ }
+
+}
+
+
+/* This function is supposed to figure out what caused the
+ * data abort, do that, then return.
+ *
+ * All unhandled instructions cause the system to hang.
+ */
+
+void do_data_abort(uint32_t insn, uint32_t spsr,
+ Context_Control *ctx)
+{
+ /* Clarify, which type is correct, CPU_Exception_frame or Context_Control */
+
+ uint8_t decode;
+ uint8_t insn_type;
+
+ uint32_t tmp;
+
+ decode = ((insn >> 20) & 0xff);
+
+ insn_type = decode & INSN_MASK;
+ switch(insn_type) {
+ case INSN_STM1:
+ printk("\n\nINSN_STM1\n");
+ break;
+ case INSN_STM2:
+ printk("\n\nINSN_STM2\n");
+ break;
+ case INSN_STR:
+ printk("\n\nINSN_STR\n");
+ break;
+ case INSN_STRB:
+ printk("\n\nINSN_STRB\n");
+ break;
+ case INSN_LDM1:
+ printk("\n\nINSN_LDM1\n");
+ break;
+ case INSN_LDM23:
+ printk("\n\nINSN_LDM23\n");
+ break;
+ case INSN_LDR:
+ printk("\n\nINSN_LDR\n");
+ break;
+ case INSN_LDRB:
+ printk("\n\nINSN_LDRB\n");
+ break;
+ default:
+ printk("\n\nUnrecognized instruction\n");
+ break;
+ }
+
+ printk("data_abort at address 0x%x, instruction: 0x%x, spsr = 0x%x\n",
+ ctx->register_lr - 8, insn, spsr);
+
+ _print_full_context(spsr);
+
+ /* disable interrupts, wait forever */
+ _CPU_ISR_Disable(tmp);
+ while(1) {
+ continue;
+ }
+ return;
+}
+