source: rtems/cpukit/score/cpu/arm/rtems/score/cpu.h @ 39c8fdb

4.104.11
Last change on this file since 39c8fdb was 39c8fdb, checked in by Thomas Doerfler <Thomas.Doerfler@…>, on Jan 12, 2010 at 3:03:22 PM

add support for lpc32xx

  • Property mode set to 100644
File size: 10.8 KB
Line 
1/**
2 * @file rtems/score/cpu.h
3 */
4
5/*
6 * $Id$
7 *
8 *  This include file contains information pertaining to the ARM
9 *  processor.
10 *
11 *  Copyright (c) 2009 embedded brains GmbH.
12 *
13 *  Copyright (c) 2007 Ray Xu <Rayx.cn@gmail.com>
14 *
15 *  Copyright (c) 2006 OAR Corporation
16 *
17 *  Copyright (c) 2002 Advent Networks, Inc.
18 *        Jay Monkman <jmonkman@adventnetworks.com>
19 *
20 *  COPYRIGHT (c) 2000 Canon Research Centre France SA.
21 *  Emmanuel Raguet, mailto:raguet@crf.canon.fr
22 *
23 *  The license and distribution terms for this file may be
24 *  found in the file LICENSE in this distribution or at
25 *  http://www.rtems.com/license/LICENSE.
26 *
27 */
28
29#ifndef _RTEMS_SCORE_CPU_H
30#define _RTEMS_SCORE_CPU_H
31
32#include <rtems/score/arm.h>
33
34#ifndef ASM
35  #include <rtems/score/types.h>
36#endif
37
38#ifndef TRUE
39  #warning "TRUE not defined"
40  #define TRUE 1
41#endif
42
43#ifndef FALSE
44  #warning "FALSE not defined"
45  #define FALSE 0
46#endif
47
48#ifdef __thumb__
49  #define ARM_SWITCH_REGISTERS uint32_t arm_switch_reg
50  #define ARM_SWITCH_TO_ARM ".align 2\nbx pc\n.arm\n"
51  #define ARM_SWITCH_BACK "add %[arm_switch_reg], pc, #1\nbx %[arm_switch_reg]\n.thumb\n"
52  #define ARM_SWITCH_OUTPUT [arm_switch_reg] "=&r" (arm_switch_reg)
53  #define ARM_SWITCH_ADDITIONAL_OUTPUT , ARM_SWITCH_OUTPUT
54#else
55  #define ARM_SWITCH_REGISTERS
56  #define ARM_SWITCH_TO_ARM
57  #define ARM_SWITCH_BACK
58  #define ARM_SWITCH_OUTPUT
59  #define ARM_SWITCH_ADDITIONAL_OUTPUT
60#endif
61
62#define ARM_PSR_N (1 << 31)
63#define ARM_PSR_Z (1 << 30)
64#define ARM_PSR_C (1 << 29)
65#define ARM_PSR_V (1 << 28)
66#define ARM_PSR_Q (1 << 27)
67#define ARM_PSR_J (1 << 24)
68#define ARM_PSR_GE_SHIFT 16
69#define ARM_PSR_GE_MASK (0xf << ARM_PSR_GE_SHIFT)
70#define ARM_PSR_E (1 << 9)
71#define ARM_PSR_A (1 << 8)
72#define ARM_PSR_I (1 << 7)
73#define ARM_PSR_F (1 << 6)
74#define ARM_PSR_T (1 << 5)
75#define ARM_PSR_M_SHIFT 0
76#define ARM_PSR_M_MASK (0x1f << ARM_PSR_M_SHIFT)
77#define ARM_PSR_M_USR 0x10
78#define ARM_PSR_M_FIQ 0x11
79#define ARM_PSR_M_IRQ 0x12
80#define ARM_PSR_M_SVC 0x13
81#define ARM_PSR_M_ABT 0x17
82#define ARM_PSR_M_UND 0x1b
83#define ARM_PSR_M_SYS 0x1f
84
85/* If someone uses THUMB we assume she wants minimal code size */
86#ifdef __thumb__
87  #define CPU_INLINE_ENABLE_DISPATCH FALSE
88#else
89  #define CPU_INLINE_ENABLE_DISPATCH TRUE
90#endif
91
92#if defined(__ARMEL__)
93  #define CPU_BIG_ENDIAN FALSE
94  #define CPU_LITTLE_ENDIAN TRUE
95#elif defined(__ARMEB__)
96  #define CPU_BIG_ENDIAN TRUE
97  #define CPU_LITTLE_ENDIAN FALSE
98#else
99  #error "unknown endianness"
100#endif
101
102#define CPU_UNROLL_ENQUEUE_PRIORITY TRUE
103
104#define CPU_HAS_SOFTWARE_INTERRUPT_STACK FALSE
105
106#define CPU_HAS_HARDWARE_INTERRUPT_STACK TRUE
107
108#define CPU_ALLOCATE_INTERRUPT_STACK FALSE
109
110#define CPU_ISR_PASSES_FRAME_POINTER 0
111
112#if ( ARM_HAS_FPU == 1 )
113  #define CPU_HARDWARE_FP TRUE
114#else
115  #define CPU_HARDWARE_FP FALSE
116#endif
117
118#define CPU_SOFTWARE_FP FALSE
119
120#define CPU_ALL_TASKS_ARE_FP FALSE
121
122#define CPU_IDLE_TASK_IS_FP FALSE
123
124#define CPU_USE_DEFERRED_FP_SWITCH FALSE
125
126#define CPU_PROVIDES_IDLE_THREAD_BODY FALSE
127
128#define CPU_STACK_GROWS_UP FALSE
129
130/* XXX Why 32? */
131#define CPU_STRUCTURE_ALIGNMENT __attribute__ ((aligned (32)))
132
133/*
134 * The interrupt mask disables only normal interrupts (IRQ).
135 *
136 * In order to support fast interrupts (FIQ) such that they can do something
137 * useful, we have to disable the operating system support for FIQs.  Having
138 * operating system support for them would require that FIQs are disabled
139 * during critical sections of the operating system and application.  At this
140 * level IRQs and FIQs would be equal.  It is true that FIQs could interrupt
141 * the non critical sections of IRQs, so here they would have a small
142 * advantage.  Without operating system support, the FIQs can execute at any
143 * time (of course not during the service of another FIQ). If someone needs
144 * operating system support for a FIQ, she can trigger a software interrupt and
145 * service the request in a two-step process.
146 */
147#define CPU_MODES_INTERRUPT_MASK 0x80
148
149#define CPU_CONTEXT_FP_SIZE sizeof( Context_Control_fp )
150
151#define CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK 0
152
153#define CPU_INTERRUPT_NUMBER_OF_VECTORS 8
154
155#define CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER (CPU_INTERRUPT_NUMBER_OF_VECTORS - 1)
156
157#define CPU_PROVIDES_ISR_IS_IN_PROGRESS FALSE
158
159#define CPU_STACK_MINIMUM_SIZE (1024 * 4)
160
161#define CPU_ALIGNMENT 4
162
163#define CPU_HEAP_ALIGNMENT CPU_ALIGNMENT
164
165#define CPU_PARTITION_ALIGNMENT CPU_ALIGNMENT
166
167#define CPU_STACK_ALIGNMENT 4
168
169/*
170 * Bitfield handler macros.
171 *
172 * If we had a particularly fast function for finding the first
173 * bit set in a word, it would go here. Since we don't (*), we'll
174 * just use the universal macros.
175 *
176 * (*) On ARM V5 and later, there's a CLZ function which could be
177 *     used to implement much quicker than the default macro.
178 */
179
180#define CPU_USE_GENERIC_BITFIELD_CODE TRUE
181
182#define CPU_USE_GENERIC_BITFIELD_DATA TRUE
183
184#define CPU_ENABLE_C_ISR_DISPATCH_IMPLEMENTATION TRUE
185
186#ifndef ASM
187
188#ifdef __cplusplus
189extern "C" {
190#endif
191
192typedef enum {
193  ARM_EXCEPTION_RESET = 0,
194  ARM_EXCEPTION_UNDEF = 1,
195  ARM_EXCEPTION_SWI = 2,
196  ARM_EXCEPTION_PREF_ABORT = 3,
197  ARM_EXCEPTION_DATA_ABORT = 4,
198  ARM_EXCEPTION_RESERVED = 5,
199  ARM_EXCEPTION_IRQ = 6,
200  ARM_EXCEPTION_FIQ = 7,
201  MAX_EXCEPTIONS = 8
202} Arm_symbolic_exception_name;
203
204typedef struct {
205  uint32_t register_cpsr;
206  uint32_t register_r4;
207  uint32_t register_r5;
208  uint32_t register_r6;
209  uint32_t register_r7;
210  uint32_t register_r8;
211  uint32_t register_r9;
212  uint32_t register_r10;
213  uint32_t register_fp;
214  uint32_t register_sp;
215  uint32_t register_lr;
216  uint32_t register_pc;
217} Context_Control;
218
219/* XXX This is out of date */
220typedef struct {
221  uint32_t register_r0;
222  uint32_t register_r1;
223  uint32_t register_r2;
224  uint32_t register_r3;
225  uint32_t register_ip;
226  uint32_t register_lr;
227} CPU_Exception_frame;
228
229typedef CPU_Exception_frame CPU_Interrupt_frame;
230
231typedef struct {
232  /* Not supported */
233} Context_Control_fp;
234
235SCORE_EXTERN Context_Control_fp _CPU_Null_fp_context;
236
237static inline uint32_t arm_interrupt_disable( void )
238{
239  uint32_t arm_switch_reg;
240  uint32_t level;
241
242  asm volatile (
243    ARM_SWITCH_TO_ARM
244    "mrs %[level], cpsr\n"
245    "orr %[arm_switch_reg], %[level], #0x80\n"
246    "msr cpsr, %[arm_switch_reg]\n"
247    ARM_SWITCH_BACK
248    : [arm_switch_reg] "=&r" (arm_switch_reg), [level] "=&r" (level)
249  );
250
251  return level;
252}
253
254static inline void arm_interrupt_enable( uint32_t level )
255{
256  ARM_SWITCH_REGISTERS;
257
258  asm volatile (
259    ARM_SWITCH_TO_ARM
260    "msr cpsr, %[level]\n"
261    ARM_SWITCH_BACK
262    : ARM_SWITCH_OUTPUT
263    : [level] "r" (level)
264  );
265}
266
267static inline void arm_interrupt_flash( uint32_t level )
268{
269  uint32_t arm_switch_reg;
270
271  asm volatile (
272    ARM_SWITCH_TO_ARM
273    "mrs %[arm_switch_reg], cpsr\n"
274    "msr cpsr, %[level]\n"
275    "msr cpsr, %[arm_switch_reg]\n"
276    ARM_SWITCH_BACK
277    : [arm_switch_reg] "=&r" (arm_switch_reg)
278    : [level] "r" (level)
279  );
280}
281
282static inline uint32_t arm_status_irq_enable( void )
283{
284  uint32_t arm_switch_reg;
285  uint32_t psr;
286
287  RTEMS_COMPILER_MEMORY_BARRIER();
288
289  asm volatile (
290    ARM_SWITCH_TO_ARM
291    "mrs %[psr], cpsr\n"
292    "bic %[arm_switch_reg], %[psr], #0x80\n"
293    "msr cpsr, %[arm_switch_reg]\n"
294    ARM_SWITCH_BACK
295    : [arm_switch_reg] "=&r" (arm_switch_reg), [psr] "=&r" (psr)
296  );
297
298  return psr;
299}
300
301static inline void arm_status_restore( uint32_t psr )
302{
303  ARM_SWITCH_REGISTERS;
304
305  asm volatile (
306    ARM_SWITCH_TO_ARM
307    "msr cpsr, %[psr]\n"
308    ARM_SWITCH_BACK
309    : ARM_SWITCH_OUTPUT
310    : [psr] "r" (psr)
311  );
312
313  RTEMS_COMPILER_MEMORY_BARRIER();
314}
315
316#define _CPU_ISR_Disable( _isr_cookie ) \
317  do { \
318    _isr_cookie = arm_interrupt_disable(); \
319  } while (0)
320
321#define _CPU_ISR_Enable( _isr_cookie )  \
322  arm_interrupt_enable( _isr_cookie )
323
324#define _CPU_ISR_Flash( _isr_cookie ) \
325  arm_interrupt_flash( _isr_cookie )
326
327void _CPU_ISR_Set_level( uint32_t level );
328
329uint32_t _CPU_ISR_Get_level( void );
330
331void _CPU_Context_Initialize(
332  Context_Control *the_context,
333  uint32_t *stack_base,
334  uint32_t size,
335  uint32_t new_level,
336  void *entry_point,
337  bool is_fp
338);
339
340#define _CPU_Context_Get_SP( _context ) \
341  (_context)->register_sp
342
343#define _CPU_Context_Restart_self( _the_context ) \
344   _CPU_Context_restore( (_the_context) );
345
346#define _CPU_Context_Fp_start( _base, _offset ) \
347   ( (void *) _Addresses_Add_offset( (_base), (_offset) ) )
348
349#define _CPU_Context_Initialize_fp( _destination ) \
350  do { \
351    *(*(_destination)) = _CPU_Null_fp_context; \
352  } while (0)
353
354#define _CPU_Fatal_halt( _err )             \
355   do {                                     \
356     uint32_t _level;                       \
357     uint32_t _error = _err;                \
358     _CPU_ISR_Disable( _level );            \
359     asm volatile ("mov r0, %0\n"           \
360                   : "=r" (_error)          \
361                   : "0" (_error)           \
362                   : "r0" );                \
363     while (1);                             \
364   } while (0);
365
366void _CPU_Initialize( void );
367
368#define _CPU_Initialize_vectors()
369
370void _CPU_ISR_install_vector(
371  uint32_t vector,
372  proc_ptr new_handler,
373  proc_ptr *old_handler
374);
375
376void _CPU_Install_interrupt_stack( void );
377
378void _CPU_Context_switch( Context_Control *run, Context_Control *heir );
379
380void _CPU_Context_restore( Context_Control *new_context )
381       RTEMS_COMPILER_NO_RETURN_ATTRIBUTE;
382
383void _CPU_Context_save_fp( Context_Control_fp **fp_context_ptr );
384
385void _CPU_Context_restore_fp( Context_Control_fp **fp_context_ptr );
386
387static inline uint32_t CPU_swap_u32( uint32_t value )
388{
389#if defined(__thumb__)
390  uint32_t byte1, byte2, byte3, byte4, swapped;
391
392  byte4 = (value >> 24) & 0xff;
393  byte3 = (value >> 16) & 0xff;
394  byte2 = (value >> 8)  & 0xff;
395  byte1 =  value & 0xff;
396
397  swapped = (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4;
398  return swapped;
399#else
400  uint32_t tmp = value; /* make compiler warnings go away */
401  asm volatile ("EOR %1, %0, %0, ROR #16\n"
402                "BIC %1, %1, #0xff0000\n"
403                "MOV %0, %0, ROR #8\n"
404                "EOR %0, %0, %1, LSR #8\n"
405                : "=r" (value), "=r" (tmp)
406                : "0" (value), "1" (tmp));
407  return value;
408#endif
409}
410
411static inline uint16_t CPU_swap_u16( uint16_t value )
412{
413  return (uint16_t) (((value & 0xffU) << 8) | ((value >> 8) & 0xffU));
414}
415
416/* XXX */
417
418extern uint32_t arm_cpu_mode;
419
420typedef struct {
421  uint32_t r0;
422  uint32_t r1;
423  uint32_t r2;
424  uint32_t r3;
425  uint32_t r4;
426  uint32_t r5;
427  uint32_t r6;
428  uint32_t r7;
429  uint32_t r8;
430  uint32_t r9;
431  uint32_t r10;
432  uint32_t r11;
433  uint32_t r12;
434  uint32_t sp;
435  uint32_t lr;
436  uint32_t pc;
437  uint32_t cpsr;
438} arm_cpu_context;
439
440typedef void arm_exc_abort_handler( arm_cpu_context *context );
441
442void arm_exc_data_abort_set_handler( arm_exc_abort_handler handler );
443
444void arm_exc_data_abort( void );
445
446void arm_exc_prefetch_abort_set_handler( arm_exc_abort_handler handler );
447
448void arm_exc_prefetch_abort( void );
449
450void bsp_interrupt_dispatch( void );
451
452void arm_exc_interrupt( void );
453
454void arm_exc_undefined( void );
455
456#ifdef __cplusplus
457}
458#endif
459
460#endif /* ASM */
461
462#endif /* _RTEMS_SCORE_CPU_H */
Note: See TracBrowser for help on using the repository browser.