OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rtems-20020807/] [cpukit/] [score/] [cpu/] [arm/] [cpu.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1026 ivang
/*
2
 *  ARM CPU Dependent Source
3
 *
4
 *
5
 *  COPYRIGHT (c) 2000 Canon Research Centre France SA.
6
 *  Emmanuel Raguet, mailto:raguet@crf.canon.fr
7
 *
8
 *  Copyright (c) 2002 Advent Networks, Inc
9
 *      Jay Monkman <jmonkman@adventnetworks.com>
10
 *
11
 *  The license and distribution terms for this file may be
12
 *  found in the file LICENSE in this distribution or at
13
 *  http://www.OARcorp.com/rtems/license.html.
14
 *
15
 */
16
 
17
#include <rtems/system.h>
18
#include <rtems.h>
19
#include <rtems/bspIo.h>
20
#include <rtems/score/isr.h>
21
#include <rtems/score/wkspace.h>
22
#include <rtems/score/thread.h>
23
#include <rtems/score/cpu.h>
24
 
25
/*  _CPU_Initialize
26
 *
27
 *  This routine performs processor dependent initialization.
28
 *
29
 *  INPUT PARAMETERS:
30
 *    cpu_table       - CPU table to initialize
31
 *    thread_dispatch - address of ISR disptaching routine (unused)
32
 *
33
 */
34
 
35
unsigned32 g_data_abort_cnt = 0;
36
unsigned32 g_data_abort_insn_list[1024];
37
 
38
void _CPU_Initialize(
39
  rtems_cpu_table  *cpu_table,
40
  void      (*thread_dispatch)      /* ignored on this CPU */
41
)
42
{
43
    _CPU_Table = *cpu_table;
44
}
45
 
46
/*
47
 *
48
 *  _CPU_ISR_Get_level - returns the current interrupt level
49
 */
50
 
51
unsigned32 _CPU_ISR_Get_level( void )
52
{
53
    unsigned32 reg;
54
 
55
    asm volatile ("mrs  %0, cpsr \n"           \
56
                  "and  %0,  %0, #0xc0 \n"     \
57
                  : "=r" (reg)                 \
58
                  : "0" (reg) );
59
 
60
    return reg;
61
}
62
 
63
/*
64
 *  _CPU_ISR_install_vector
65
 *
66
 *  This kernel routine installs the RTEMS handler for the
67
 *  specified vector.
68
 *
69
 *  Input parameters:
70
 *    vector      - interrupt vector number
71
 *    new_handler - replacement ISR for this vector number
72
 *    old_handler - pointer to store former ISR for this vector number
73
 *
74
 *  FIXME: This vector scheme should be changed to allow FIQ to be
75
 *         handled better. I'd like to be able to put VectorTable
76
 *         elsewhere - JTM
77
 *
78
 *
79
 *  Output parameters:  NONE
80
 *
81
 */
82
void _CPU_ISR_install_vector(
83
  unsigned32  vector,
84
  proc_ptr    new_handler,
85
  proc_ptr   *old_handler
86
)
87
{
88
    /* pointer on the redirection table in RAM */
89
    long *VectorTable = (long *)(MAX_EXCEPTIONS * 4);
90
 
91
    if (old_handler != NULL) {
92
        old_handler = *(proc_ptr *)(VectorTable + vector);
93
    }
94
 
95
    *(VectorTable + vector) = (long)new_handler ;
96
 
97
}
98
 
99
void _CPU_Context_Initialize(
100
  Context_Control  *the_context,
101
  unsigned32       *stack_base,
102
  unsigned32        size,
103
  unsigned32        new_level,
104
  void             *entry_point,
105
  boolean           is_fp
106
)
107
{
108
    the_context->register_sp = (unsigned32)stack_base + size ;
109
    the_context->register_lr = (unsigned32)entry_point;
110
    the_context->register_cpsr = new_level | 0x13;
111
}
112
 
113
 
114
/*
115
 *  _CPU_Install_interrupt_stack - this function is empty since the
116
 *  BSP must set up the interrupt stacks.
117
 */
118
 
119
void _CPU_Install_interrupt_stack( void )
120
{
121
}
122
 
123
void _defaultExcHandler (CPU_Exception_frame *ctx)
124
{
125
    printk("\n\r");
126
    printk("----------------------------------------------------------\n\r");
127
#if 0
128
    printk("Exception 0x%x caught at PC 0x%x by thread %d\n",
129
           ctx->register_pc, ctx->register_lr - 4,
130
           _Thread_Executing->Object.id);
131
#endif
132
    printk("----------------------------------------------------------\n\r");
133
    printk("Processor execution context at time of the fault was  :\n\r");
134
    printk("----------------------------------------------------------\n\r");
135
#if 0
136
    printk(" r0  = %8x  r1  = %8x  r2  = %8x  r3  = %8x\n\r",
137
           ctx->register_r0, ctx->register_r1,
138
           ctx->register_r2, ctx->register_r3);
139
    printk(" r4  = %8x  r5  = %8x  r6  = %8x  r7  = %8x\n\r",
140
           ctx->register_r4, ctx->register_r5,
141
           ctx->register_r6, ctx->register_r7);
142
    printk(" r8  = %8x  r9  = %8x  r10 = %8x\n\r",
143
           ctx->register_r8, ctx->register_r9, ctx->register_r10);
144
    printk(" fp  = %8x  ip  = %8x  sp  = %8x  pc  = %8x\n\r",
145
           ctx->register_fp, ctx->register_ip,
146
           ctx->register_sp, ctx->register_lr - 4);
147
    printk("----------------------------------------------------------\n\r");
148
#endif    
149
    if (_ISR_Nest_level > 0) {
150
        /*
151
         * In this case we shall not delete the task interrupted as
152
         * it has nothing to do with the fault. We cannot return either
153
         * because the eip points to the faulty instruction so...
154
         */
155
        printk("Exception while executing ISR!!!. System locked\n\r");
156
        while(1);
157
    }
158
    else {
159
        printk("*********** FAULTY THREAD WILL BE DELETED **************\n\r");
160
        rtems_task_delete(_Thread_Executing->Object.id);
161
    }
162
}
163
 
164
cpuExcHandlerType _currentExcHandler = _defaultExcHandler;
165
 
166
extern void _Exception_Handler_Undef_Swi();
167
extern void _Exception_Handler_Abort();
168
extern void _exc_data_abort();
169
/* FIXME: put comments here */
170
void rtems_exception_init_mngt()
171
{
172
        ISR_Level level;
173
 
174
      _CPU_ISR_Disable(level);
175
      _CPU_ISR_install_vector(ARM_EXCEPTION_UNDEF,
176
                              _Exception_Handler_Undef_Swi,
177
                              NULL);
178
 
179
      _CPU_ISR_install_vector(ARM_EXCEPTION_SWI,
180
                              _Exception_Handler_Undef_Swi,
181
                              NULL);
182
 
183
      _CPU_ISR_install_vector(ARM_EXCEPTION_PREF_ABORT,
184
                              _Exception_Handler_Abort,
185
                              NULL);
186
 
187
      _CPU_ISR_install_vector(ARM_EXCEPTION_DATA_ABORT,
188
                              _exc_data_abort,
189
                              NULL);
190
 
191
      _CPU_ISR_install_vector(ARM_EXCEPTION_FIQ,
192
                              _Exception_Handler_Abort,
193
                              NULL);
194
 
195
      _CPU_ISR_install_vector(ARM_EXCEPTION_IRQ,
196
                              _Exception_Handler_Abort,
197
                              NULL);
198
 
199
      _CPU_ISR_Enable(level);
200
}
201
 
202
#define INSN_MASK         0xc5
203
 
204
#define INSN_STM1         0x80
205
#define INSN_STM2         0x84
206
#define INSN_STR          0x40
207
#define INSN_STRB         0x44
208
 
209
#define INSN_LDM1         0x81
210
#define INSN_LDM23        0x85
211
#define INSN_LDR          0x41
212
#define INSN_LDRB         0x45
213
 
214
#define GET_RD(x)         ((x & 0x0000f000) >> 12)
215
#define GET_RN(x)         ((x & 0x000f0000) >> 16)
216
 
217
#define GET_U(x)              ((x & 0x00800000) >> 23)
218
#define GET_I(x)              ((x & 0x02000000) >> 25)
219
 
220
#define GET_REG(r, ctx)      (((unsigned32 *)ctx)[r])
221
#define SET_REG(r, ctx, v)   (((unsigned32 *)ctx)[r] = v)
222
#define GET_OFFSET(insn)     (insn & 0xfff)
223
 
224
 
225
/* This function is supposed to figure out what caused the
226
 * data abort, do that, then return.
227
 *
228
 * All unhandled instructions cause the system to hang.
229
 */
230
 
231
void do_data_abort(unsigned32 insn, unsigned32 spsr,
232
                   CPU_Exception_frame *ctx)
233
{
234
    unsigned8  decode;
235
    unsigned8  insn_type;
236
 
237
    unsigned32 rn;
238
    unsigned32 rd;
239
 
240
    unsigned8  *src_addr;
241
    unsigned8  *dest_addr;
242
    unsigned32  tmp;
243
 
244
    g_data_abort_insn_list[g_data_abort_cnt & 0x3ff] = ctx->register_lr - 8;
245
    g_data_abort_cnt++;
246
 
247
    decode = ((insn >> 20) & 0xff);
248
 
249
    insn_type = decode & INSN_MASK;
250
    switch(insn_type) {
251
    case INSN_STM1:
252
        printk("\n\nINSN_STM1\n");
253
        break;
254
    case INSN_STM2:
255
        printk("\n\nINSN_STM2\n");
256
        break;
257
    case INSN_STR:
258
        printk("\n\nINSN_STR\n");
259
        break;
260
    case INSN_STRB:
261
        printk("\n\nINSN_STRB\n");
262
        break;
263
    case INSN_LDM1:
264
        printk("\n\nINSN_LDM1\n");
265
        break;
266
    case INSN_LDM23:
267
        printk("\n\nINSN_LDM23\n");
268
        break;
269
    case INSN_LDR:
270
        printk("\n\nINSN_LDR\n");
271
 
272
        rn = GET_RN(insn);
273
        rd = GET_RD(insn);
274
 
275
        /* immediate offset/index */
276
        if (GET_I(insn) == 0) {
277
            switch(decode & 0x12) {  /* P and W bits */
278
            case 0x00:  /* P=0, W=0 -> base is updated, post-indexed */
279
                printk("\tPost-indexed\n");
280
                break;
281
            case 0x02:  /* P=0, W=1 -> user mode access */
282
                printk("\tUser mode\n");
283
                break;
284
            case 0x10:  /* P=1, W=0 -> base not updated */
285
                src_addr = GET_REG(rn, ctx);
286
                if (GET_U(insn) == 0) {
287
                    src_addr -= GET_OFFSET(insn);
288
                } else {
289
                    src_addr += GET_OFFSET(insn);
290
                }
291
                tmp = (src_addr[0] |
292
                       (src_addr[1] << 8) |
293
                       (src_addr[2] << 16) |
294
                       (src_addr[3] << 24));
295
                SET_REG(rd, ctx, tmp);
296
                return;
297
                break;
298
            case 0x12:  /* P=1, W=1 -> base is updated, pre-indexed */
299
                printk("\tPre-indexed\n");
300
                break;
301
            }
302
        }
303
        break;
304
    case INSN_LDRB:
305
        printk("\n\nINSN_LDRB\n");
306
        break;
307
    default:
308
        printk("\n\nUnrecognized instruction\n");
309
        break;
310
    }
311
 
312
    printk("data_abort at address 0x%x, instruction: 0x%x,   spsr = 0x%x\n",
313
           ctx->register_lr - 8, insn, spsr);
314
 
315
    /* disable interrupts, wait forever */
316
    _CPU_ISR_Disable(tmp);
317
    while(1) {
318
        continue;
319
    }
320
    return;
321
}
322
 
323
 
324
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.