forked from Imagelibrary/rtems
2007-05-15 Ray Xu <rayx@gmail.com>
* shared/abort/abort.c, shared/abort/simple_abort.c: New files.
This commit is contained in:
@@ -1,3 +1,7 @@
|
||||
2007-05-15 Ray Xu <rayx@gmail.com>
|
||||
|
||||
* shared/abort/abort.c, shared/abort/simple_abort.c: New files.
|
||||
|
||||
2007-05-15 Ray Xu <rayx@gmail.com>
|
||||
|
||||
* Makefile.am: Add abort.rel since it is now in the BSP shared source,
|
||||
|
||||
161
c/src/lib/libbsp/arm/shared/abort/abort.c
Normal file
161
c/src/lib/libbsp/arm/shared/abort/abort.c
Normal file
@@ -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;
|
||||
}
|
||||
|
||||
152
c/src/lib/libbsp/arm/shared/abort/simple_abort.c
Normal file
152
c/src/lib/libbsp/arm/shared/abort/simple_abort.c
Normal file
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user