source: rtems/c/src/lib/libbsp/arm/shared/abort/abort.c @ b7765d62

4.115
Last change on this file since b7765d62 was 2ee9d3d, checked in by Ralf Corsepius <ralf.corsepius@…>, on 02/11/11 at 11:49:52

2011-02-11 Ralf Corsépius <ralf.corsepius@…>

  • shared/abort/abort.c, shared/abort/simple_abort.c: Use "asm" instead of "asm" for improved c99-compliance.
  • Property mode set to 100644
File size: 4.2 KB
Line 
1/*
2 *  ARM CPU Dependent Source
3 *
4 *  COPYRIGHT (c) 2007 Ray Xu.
5 *  mailto: Rayx at gmail dot com
6 *
7 *  COPYRIGHT (c) 2000 Canon Research Centre France SA.
8 *  Emmanuel Raguet, mailto:raguet@crf.canon.fr
9 *
10 *  Copyright (c) 2002 Advent Networks, Inc
11 *      Jay Monkman <jmonkman@adventnetworks.com>
12 *
13 *  If you want a small footprint RTEMS, pls use simple_abort.c
14 *
15 *  The license and distribution terms for this file may be
16 *  found in the file LICENSE in this distribution or at
17 *  http://www.rtems.com/license/LICENSE.
18 *
19 */
20
21#include <rtems/system.h>
22#include <rtems.h>
23#include <rtems/bspIo.h>
24
25#define INSN_MASK         0xc5
26
27#define INSN_STM1         0x80
28#define INSN_STM2         0x84
29#define INSN_STR          0x40
30#define INSN_STRB         0x44
31
32#define INSN_LDM1         0x81
33#define INSN_LDM23        0x85
34#define INSN_LDR          0x41
35#define INSN_LDRB         0x45
36
37#define GET_RD(x)         ((x & 0x0000f000) >> 12)
38#define GET_RN(x)         ((x & 0x000f0000) >> 16)
39
40#define GET_U(x)              ((x & 0x00800000) >> 23)
41#define GET_I(x)              ((x & 0x02000000) >> 25)
42
43#define GET_REG(r, ctx)      (((uint32_t   *)ctx)[r])
44#define SET_REG(r, ctx, v)   (((uint32_t   *)ctx)[r] = v)
45#define GET_OFFSET(insn)     (insn & 0xfff)
46
47uint32_t        g_data_abort_cnt = 0;
48/*this is a big overhead for MCU only got 16K RAM*/
49uint32_t        g_data_abort_insn_list[1024];
50
51
52char *_print_full_context_mode2txt[0x20]={
53   [0x0]="user",  /* User */
54        [0x1]="fiq",   /* FIQ - Fast Interrupt Request */
55        [0x2]="irq",   /* IRQ - Interrupt Request */
56        [0x3]="super", /* Supervisor */
57        [0x7]="abort", /* Abort */
58        [0xb]="undef", /* Undefined */
59        [0xf]="system" /* System */
60    };
61
62
63void _print_full_context(uint32_t spsr)
64{
65    char *mode;
66    uint32_t prev_sp,prev_lr,cpsr,arm_switch_reg;
67    int i;
68
69    printk("active thread thread 0x%08x\n", _Thread_Executing->Object.id);
70
71    mode=_print_full_context_mode2txt[spsr&0x1f];
72    if(!mode) mode="unknown";
73
74    __asm__ volatile (ARM_SWITCH_TO_ARM
75              " MRS  %[cpsr], cpsr \n"
76              " ORR  %[arm_switch_reg], %[spsr], #0xc0 \n"
77              " MSR  cpsr_c, %[arm_switch_reg] \n"
78              " MOV  %[prev_sp], sp \n"
79              " MOV  %[prev_lr], lr \n"
80              " MSR  cpsr_c, %[cpsr] \n"
81              ARM_SWITCH_BACK
82              : [arm_switch_reg] "=&r" (arm_switch_reg), [prev_sp] "=&r" (prev_sp), [prev_lr] "=&r" (prev_lr),
83                [cpsr] "=&r" (cpsr)
84              : [spsr] "r" (spsr)
85              : "cc");
86
87    printk("Previous sp=0x%08x lr=0x%08x and actual cpsr=%08x\n",
88           prev_sp, prev_lr, cpsr);
89
90    for(i=0;i<48;){
91        printk(" 0x%08x",((uint32_t*)prev_sp)[i++]);
92        if((i%6) == 0)
93            printk("\n");
94    }
95
96}
97
98
99/* This function is supposed to figure out what caused the
100 * data abort, do that, then return.
101 *
102 * All unhandled instructions cause the system to hang.
103 */
104
105void do_data_abort(uint32_t   insn, uint32_t   spsr,
106                    Context_Control *ctx)
107{
108    /* Clarify, which type is correct, CPU_Exception_frame or Context_Control */
109    uint8_t               decode;
110    uint8_t               insn_type;
111    rtems_interrupt_level level;
112
113    g_data_abort_insn_list[g_data_abort_cnt & 0x3ff] = ctx->register_lr - 8;
114    g_data_abort_cnt++;
115
116    decode = ((insn >> 20) & 0xff);
117
118    insn_type = decode & INSN_MASK;
119    switch(insn_type) {
120    case INSN_STM1:
121        printk("\n\nINSN_STM1\n");
122        break;
123    case INSN_STM2:
124        printk("\n\nINSN_STM2\n");
125        break;
126    case INSN_STR:
127        printk("\n\nINSN_STR\n");
128        break;
129    case INSN_STRB:
130        printk("\n\nINSN_STRB\n");
131        break;
132    case INSN_LDM1:
133        printk("\n\nINSN_LDM1\n");
134        break;
135    case INSN_LDM23:
136        printk("\n\nINSN_LDM23\n");
137        break;
138    case INSN_LDR:
139        printk("\n\nINSN_LDR\n");
140        break;
141    case INSN_LDRB:
142        printk("\n\nINSN_LDRB\n");
143        break;
144    default:
145        printk("\n\nUnrecognized instruction\n");
146        break;
147    }
148
149    printk("data_abort at address 0x%x, instruction: 0x%x,   spsr = 0x%x\n",
150           ctx->register_lr - 8, insn, spsr);
151
152    _print_full_context(spsr);
153
154    /* disable interrupts, wait forever */
155    rtems_interrupt_disable(level);
156    while(1) {
157        continue;
158    }
159    return;
160}
161
Note: See TracBrowser for help on using the repository browser.