diff options
author | Joel Sherrill <joel.sherrill@OARcorp.com> | 2007-05-15 18:03:05 +0000 |
---|---|---|
committer | Joel Sherrill <joel.sherrill@OARcorp.com> | 2007-05-15 18:03:05 +0000 |
commit | 40082322fad69256036fdf625b90d282def3b307 (patch) | |
tree | 5a566cb3b54375163d95e6bb12e6f00d7d51ce94 /c/src/lib/libbsp/arm/shared/abort | |
parent | 2007-05-15 Ray Xu <rayx@gmail.com> (diff) | |
download | rtems-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')
-rw-r--r-- | c/src/lib/libbsp/arm/shared/abort/abort.c | 161 | ||||
-rw-r--r-- | c/src/lib/libbsp/arm/shared/abort/simple_abort.c | 152 |
2 files changed, 313 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/arm/shared/abort/abort.c b/c/src/lib/libbsp/arm/shared/abort/abort.c new file mode 100644 index 0000000000..7222a58d9c --- /dev/null +++ b/c/src/lib/libbsp/arm/shared/abort/abort.c @@ -0,0 +1,161 @@ +/* + * 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> + * + * If you want a small footprint RTEMS, pls use simple_abort.c + * + * 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, ...); + +uint32_t g_data_abort_cnt = 0; +/*this is a big overhead for MCU only got 16K RAM*/ +uint32_t g_data_abort_insn_list[1024]; + + +char *_print_full_context_mode2txt[0x20]={ + [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]; + 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; + + g_data_abort_insn_list[g_data_abort_cnt & 0x3ff] = ctx->register_lr - 8; + g_data_abort_cnt++; + + 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; +} + 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; +} + |