source: rtems/cpukit/score/cpu/arm/cpu.c @ d0279f6e

4.9
Last change on this file since d0279f6e was df4fcaa, checked in by Joel Sherrill <joel.sherrill@…>, on Sep 8, 2008 at 3:19:23 PM

2008-09-08 Joel Sherrill <joel.sherrill@…>

  • cpu.c: Remove extraneous spaces.
  • Property mode set to 100644
File size: 7.4 KB
Line 
1/*
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 *  Copyright (c) 2007 Ray xu <rayx.cn@gmail.com>
12 *
13 *  The license and distribution terms for this file may be
14 *  found in the file LICENSE in this distribution or at
15 *  http://www.rtems.com/license/LICENSE.
16 *
17 *  $Id$
18 */
19
20#include <rtems/system.h>
21#include <rtems.h>
22#include <rtems/bspIo.h>
23#include <rtems/score/isr.h>
24#include <rtems/score/wkspace.h>
25#include <rtems/score/thread.h>
26#include <rtems/score/cpu.h>
27
28/*
29 * This variable can be used to change the running mode of the execution
30 * contexts.
31 */
32
33unsigned int arm_cpu_mode = 0x13;
34
35/*  _CPU_Initialize
36 *
37 *  This routine performs processor dependent initialization.
38 *
39 *  INPUT PARAMETERS:
40 *    thread_dispatch - address of ISR disptaching routine (unused)
41 */
42
43void _CPU_Initialize(
44  void      (*thread_dispatch)      /* ignored on this CPU */
45)
46{
47}
48
49/*
50 *
51 *  _CPU_ISR_Get_level - returns the current interrupt level
52 */
53#define str(x) #x
54#define xstr(x) str(x)
55#define L(x) #x "_" xstr(__LINE__)
56
57#define TO_ARM_MODE(x)      \
58    asm volatile (          \
59    ".code  16           \n" \
60    L(x) "_thumb:        \n" \
61    ".align 2            \n" \
62    "push {lr}           \n" \
63    "adr %0, "L(x) "_arm \n" \
64    "bl " L(x)"         \n" \
65    "pop    {pc}        \n" \
66    ".balign 4          \n" \
67    L(x) ":             \n" \
68    "bx %0              \n" \
69    "nop                \n" \
70    ".pool              \n" \
71    ".code 32           \n" \
72    L(x) "_arm:         \n" \
73    :"=&r" (reg))
74 
75
76/*
77 * Switch to Thumb mode Veneer,ugly but safe
78 */
79
80#define TO_THUMB_MODE(x)    \
81    asm volatile (          \
82        ".code  32                  \n"\
83        "adr %0, "L(x) "_thumb +1   \n"\
84        "bx  %0                     \n"\
85        ".pool                      \n"\
86        ".thumb_func                \n"\
87        L(x) "_thumb:               \n"\
88        : "=&r" (reg))
89
90#if (!defined(__THUMB_INTERWORK__) &&  !defined(__thumb__))
91uint32_t   _CPU_ISR_Get_level( void )
92{
93    uint32_t   reg = 0; /* to avoid warning */
94    asm volatile ("mrs  %0, cpsr \n"           \
95                  "and  %0,  %0, #0xc0 \n"     \
96                  : "=r" (reg)                 \
97                  : "0" (reg) );
98    return reg;
99}
100#endif
101
102
103
104/*
105 *  _CPU_ISR_install_vector
106 *
107 *  This kernel routine installs the RTEMS handler for the
108 *  specified vector.
109 *
110 *  Input parameters:
111 *    vector      - interrupt vector number
112 *    new_handler - replacement ISR for this vector number
113 *    old_handler - pointer to store former ISR for this vector number
114 *
115 *  FIXME: This vector scheme should be changed to allow FIQ to be
116 *         handled better. I'd like to be able to put VectorTable
117 *         elsewhere - JTM
118 *
119 *
120 *  Output parameters:  NONE
121 *
122 */
123void _CPU_ISR_install_vector(
124  uint32_t    vector,
125  proc_ptr    new_handler,
126  proc_ptr   *old_handler
127)
128{
129    /* pointer on the redirection table in RAM */
130    long *VectorTable = (long *)(MAX_EXCEPTIONS * 4); 
131   
132    if (old_handler != NULL) {
133        old_handler = *(proc_ptr *)(VectorTable + vector);
134    }
135
136    *(VectorTable + vector) = (long)new_handler ;
137 
138}
139
140void _CPU_Context_Initialize(
141  Context_Control  *the_context,
142  uint32_t         *stack_base,
143  uint32_t          size,
144  uint32_t          new_level,
145  void             *entry_point,
146  bool              is_fp
147)
148{
149    the_context->register_sp = (uint32_t)stack_base + size ;
150    the_context->register_lr = (uint32_t)entry_point;
151    the_context->register_cpsr = new_level | arm_cpu_mode;
152}
153
154
155/*
156 *  _CPU_Install_interrupt_stack - this function is empty since the
157 *  BSP must set up the interrupt stacks.
158 */
159
160void _CPU_Install_interrupt_stack( void )
161{
162}
163
164void _defaultExcHandler (CPU_Exception_frame *ctx)
165{
166    printk("\n\r");
167    printk("----------------------------------------------------------\n\r");
168#if 1
169    printk("Exception 0x%x caught at PC 0x%x by thread %d\n",
170           ctx->register_ip, ctx->register_lr - 4,
171           _Thread_Executing->Object.id);
172#endif
173    printk("----------------------------------------------------------\n\r");
174    printk("Processor execution context at time of the fault was  :\n\r");
175    printk("----------------------------------------------------------\n\r");
176#if 0
177    printk(" r0  = %8x  r1  = %8x  r2  = %8x  r3  = %8x\n\r",
178           ctx->register_r0, ctx->register_r1,
179           ctx->register_r2, ctx->register_r3);
180    printk(" r4  = %8x  r5  = %8x  r6  = %8x  r7  = %8x\n\r",
181           ctx->register_r4, ctx->register_r5,
182           ctx->register_r6, ctx->register_r7);
183    printk(" r8  = %8x  r9  = %8x  r10 = %8x\n\r",
184           ctx->register_r8, ctx->register_r9, ctx->register_r10);
185    printk(" fp  = %8x  ip  = %8x  sp  = %8x  pc  = %8x\n\r",
186           ctx->register_fp, ctx->register_ip,
187           ctx->register_sp, ctx->register_lr - 4);
188    printk("----------------------------------------------------------\n\r");
189#endif   
190    if (_ISR_Nest_level > 0) {
191        /*
192         * In this case we shall not delete the task interrupted as
193         * it has nothing to do with the fault. We cannot return either
194         * because the eip points to the faulty instruction so...
195         */
196        printk("Exception while executing ISR!!!. System locked\n\r");
197        while(1);
198    }
199    else {
200        printk("*********** FAULTY THREAD WILL BE DELETED **************\n\r");
201        rtems_task_delete(_Thread_Executing->Object.id);
202    }
203}
204
205cpuExcHandlerType _currentExcHandler = _defaultExcHandler;
206
207extern void _Exception_Handler_Undef_Swi(void); 
208extern void _Exception_Handler_Abort(void); 
209extern void _exc_data_abort(void); 
210
211
212
213/* FIXME: put comments here */
214void rtems_exception_init_mngt(void)
215{
216        ISR_Level level;
217     
218      _CPU_ISR_Disable(level);
219      _CPU_ISR_install_vector(ARM_EXCEPTION_UNDEF,
220                              _Exception_Handler_Undef_Swi,
221                              NULL);
222 
223      _CPU_ISR_install_vector(ARM_EXCEPTION_SWI,
224                              _Exception_Handler_Undef_Swi,
225                              NULL);
226     
227      _CPU_ISR_install_vector(ARM_EXCEPTION_PREF_ABORT,
228                              _Exception_Handler_Abort,
229                              NULL);
230     
231      _CPU_ISR_install_vector(ARM_EXCEPTION_DATA_ABORT,
232                              _exc_data_abort,
233                              NULL);
234     
235      _CPU_ISR_install_vector(ARM_EXCEPTION_FIQ,       
236                              _Exception_Handler_Abort,
237                              NULL);
238     
239      _CPU_ISR_install_vector(ARM_EXCEPTION_IRQ, 
240                              _Exception_Handler_Abort,
241                              NULL);
242     
243      _CPU_ISR_Enable(level);
244}
245 
246#define INSN_MASK         0xc5
247
248#define INSN_STM1         0x80
249#define INSN_STM2         0x84
250#define INSN_STR          0x40
251#define INSN_STRB         0x44
252
253#define INSN_LDM1         0x81
254#define INSN_LDM23        0x85
255#define INSN_LDR          0x41
256#define INSN_LDRB         0x45
257
258#define GET_RD(x)         ((x & 0x0000f000) >> 12)
259#define GET_RN(x)         ((x & 0x000f0000) >> 16)
260
261#define GET_U(x)              ((x & 0x00800000) >> 23)
262#define GET_I(x)              ((x & 0x02000000) >> 25)
263
264#define GET_REG(r, ctx)      (((uint32_t *)ctx)[r])
265#define SET_REG(r, ctx, v)   (((uint32_t *)ctx)[r] = v)
266#define GET_OFFSET(insn)     (insn & 0xfff)
267
Note: See TracBrowser for help on using the repository browser.