summaryrefslogtreecommitdiffstats
path: root/cpukit/score/cpu/arm/rtems/score
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2002-07-30 23:16:40 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2002-07-30 23:16:40 +0000
commitfa237002ab54222f18109be49dcb8368c253b107 (patch)
treed30d1039ae2ee7aec82f05a479c8d0c716fe0243 /cpukit/score/cpu/arm/rtems/score
parent2002-07-30 Joel Sherrill <joel@OARcorp.com> (diff)
downloadrtems-fa237002ab54222f18109be49dcb8368c253b107.tar.bz2
2002-07-30 Jay Monkman <jtm@smoothsmoothie.com>
* cpu.c, cpu_asm.S, rtems/score/arm.h, rtems/score/cpu.h, rtems/score/cpu_asm.h, rtems/score/types.h: ARM port works well enough to run all sptests, tmtests, and ttcp. In addition to general cleanup, there has been considerable optimization to interrupt disable/enable, endian swapping, and context switching.
Diffstat (limited to 'cpukit/score/cpu/arm/rtems/score')
-rw-r--r--cpukit/score/cpu/arm/rtems/score/arm.h49
-rw-r--r--cpukit/score/cpu/arm/rtems/score/cpu.h215
-rw-r--r--cpukit/score/cpu/arm/rtems/score/cpu_asm.h32
-rw-r--r--cpukit/score/cpu/arm/rtems/score/types.h29
4 files changed, 151 insertions, 174 deletions
diff --git a/cpukit/score/cpu/arm/rtems/score/arm.h b/cpukit/score/cpu/arm/rtems/score/arm.h
index 05aed89892..7d8d135488 100644
--- a/cpukit/score/cpu/arm/rtems/score/arm.h
+++ b/cpukit/score/cpu/arm/rtems/score/arm.h
@@ -29,25 +29,44 @@ extern "C" {
* dependent features are present in a particular member
* of the family.
*/
-#if defined(__arm9__)
-# define CPU_MODEL_NAME "arm9"
-# define ARM_HAS_FPU 0
-#elif defined(__arm9tdmi__)
-# define CPU_MODEL_NAME "arm9tdmi"
-# define ARM_HAS_FPU 0
-#elif defined(__arm7__)
-# define CPU_MODEL_NAME "arm7"
-# define ARM_HAS_FPU 0
-#elif defined(__arm7tdmi__)
-# define CPU_MODEL_NAME "arm7tdmi"
-# define ARM_HAS_FPU 0
-#elif defined(__arm__)
-# define CPU_MODEL_NAME "unknown ARM"
-# define ARM_HAS_FPU 0
+#if defined(__ARM_ARCH_4__)
+# define CPU_MODEL_NAME "ARMv4"
+# define ARM_HAS_CLZ 0
+# define ARM_HAS_THUMB 0
+
+#elif defined(__ARM_ARCH_4T__)
+# define CPU_MODEL_NAME "ARMv4T"
+# define ARM_HAS_CLZ 0
+# define ARM_HAS_THUMB 1
+
+#elif defined(__ARM_ARCH_5__)
+# define CPU_MODEL_NAME "ARMv5"
+# define ARM_HAS_CLZ 1
+# define ARM_HAS_THUMB 0
+
+#elif defined(__ARM_ARCH_5T__)
+# define CPU_MODEL_NAME "ARMv5T"
+# define ARM_HAS_CLZ 1
+# define ARM_HAS_THUMB 1
+
+#elif defined(__ARM_ARCH_5E__)
+# define CPU_MODEL_NAME "ARMv5E"
+# define ARM_HAS_CLZ 1
+# define ARM_HAS_THUMB 0
+
+#elif defined(__ARM_ARCH_5TE__)
+# define CPU_MODEL_NAME "ARMv5TE"
+# define ARM_HAS_CLZ 1
+# define ARM_HAS_THUMB 1
+
#else
# error "Unsupported CPU Model"
+
#endif
+/* All ARM CPUs are assumed to not have floating point units */
+#define ARM_HAS_FPU 0
+
/*
* Define the name of the CPU family.
*/
diff --git a/cpukit/score/cpu/arm/rtems/score/cpu.h b/cpukit/score/cpu/arm/rtems/score/cpu.h
index 7074d0022e..7468d998c5 100644
--- a/cpukit/score/cpu/arm/rtems/score/cpu.h
+++ b/cpukit/score/cpu/arm/rtems/score/cpu.h
@@ -1,8 +1,10 @@
/*
+ * $RCSfile$
+ *
* This include file contains information pertaining to the ARM
* processor.
*
- * COPYRIGHT (c) 2002 Advent Networks, Inc.
+ * Copyright (c) 2002 Advent Networks, Inc.
* Jay Monkman <jmonkman@adventnetworks.com>
*
* COPYRIGHT (c) 2000 Canon Research Centre France SA.
@@ -12,7 +14,6 @@
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
- * $Id$
*/
/* FIXME: finish commenting/cleaning up this file */
@@ -25,7 +26,7 @@ extern "C" {
#include <rtems/score/arm.h> /* pick up machine definitions */
#ifndef ASM
-#include <rtems/score/types.h>
+#include <rtems/score/armtypes.h>
#endif
/* conditional compilation parameters */
@@ -103,7 +104,7 @@ extern "C" {
*
* If this is TRUE, CPU_ALLOCATE_INTERRUPT_STACK should also be TRUE.
*
- * Only one of CPU_HAS_SOFTWARE_INTERRU
+ * Only one of CPU_HAS_SOFTWARE_INTERRUPT_STACK and
* CPU_HAS_HARDWARE_INTERRUPT_STACK should be set to TRUE. It is
* possible that both are FALSE for a particular CPU. Although it
* is unclear what that would imply about the interrupt processing
@@ -122,7 +123,7 @@ extern "C" {
* or CPU_INSTALL_HARDWARE_INTERRUPT_STACK is TRUE.
*/
-#define CPU_ALLOCATE_INTERRUPT_STACK TRUE
+#define CPU_ALLOCATE_INTERRUPT_STACK FALSE
/*
* Does the RTEMS invoke the user's ISR with the vector number and
@@ -141,7 +142,7 @@ extern "C" {
* If there is a FP coprocessor such as the i387 or mc68881, then
* the answer is TRUE.
*
- * The macro name "NO_CPU_HAS_FPU" should be made CPU specific.
+ * The macro name "ARM_HAS_FPU" should be made CPU specific.
* It indicates whether or not this CPU model has FP support. For
* example, it would be possible to have an i386_nofp CPU model
* which set this to false to indicate that you have an i386 without
@@ -331,12 +332,8 @@ extern "C" {
* this is enough information for RTEMS, it is probably not enough for
* a debugger such as gdb. But that is another problem.
*/
-
typedef struct {
- unsigned32 register_r0;
- unsigned32 register_r1;
- unsigned32 register_r2;
- unsigned32 register_r3;
+ unsigned32 register_cpsr;
unsigned32 register_r4;
unsigned32 register_r5;
unsigned32 register_r6;
@@ -345,18 +342,23 @@ typedef struct {
unsigned32 register_r9;
unsigned32 register_r10;
unsigned32 register_fp;
- unsigned32 register_ip;
unsigned32 register_sp;
unsigned32 register_lr;
unsigned32 register_pc;
- unsigned32 register_cpsr;
} Context_Control;
typedef struct {
double some_float_register;
} Context_Control_fp;
-typedef Context_Control CPU_Exception_frame;
+typedef struct {
+ unsigned32 register_r0;
+ unsigned32 register_r1;
+ unsigned32 register_r2;
+ unsigned32 register_r3;
+ unsigned32 register_ip;
+ unsigned32 register_lr;
+} CPU_Exception_frame;
typedef void (*cpuExcHandlerType) (CPU_Exception_frame*);
extern cpuExcHandlerType _currentExcHandler;
@@ -372,7 +374,7 @@ typedef CPU_Exception_frame CPU_Interrupt_frame;
/*
* The following table contains the information required to configure
- * the ARM processor specific parameters.
+ * the XXX processor specific parameters.
*/
typedef struct {
@@ -396,7 +398,9 @@ typedef struct {
*/
/*
- * Macros to access NO_CPU specific additions to the CPU Table
+ * Macros to access ARM specific additions to the CPU Table
+ *
+ * none required
*/
/* There are no CPU specific additions to the CPU Table for this port. */
@@ -411,40 +415,6 @@ typedef struct {
SCORE_EXTERN Context_Control_fp _CPU_Null_fp_context;
/*
- * On some CPUs, RTEMS supports a software managed interrupt stack.
- * This stack is allocated by the Interrupt Manager and the switch
- * is performed in _ISR_Handler. These variables contain pointers
- * to the lowest and highest addresses in the chunk of memory allocated
- * for the interrupt stack. Since it is unknown whether the stack
- * grows up or down (in general), this give the CPU dependent
- * code the option of picking the version it wants to use.
- *
- * NOTE: These two variables are required if the macro
- * CPU_HAS_SOFTWARE_INTERRUPT_STACK is defined as TRUE.
- */
-
-SCORE_EXTERN void *_CPU_Interrupt_stack_low;
-SCORE_EXTERN void *_CPU_Interrupt_stack_high;
-
-/*
- * With some compilation systems, it is difficult if not impossible to
- * call a high-level language routine from assembly language. This
- * is especially true of commercial Ada compilers and name mangling
- * C++ ones. This variable can be optionally defined by the CPU porter
- * and contains the address of the routine _Thread_Dispatch. This
- * can make it easier to invoke that routine at the end of the interrupt
- * sequence (if a dispatch is necessary).
- */
-
-SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)();
-
-/*
- * Nothing prevents the porter from declaring more CPU specific variables.
- */
-
-/* XXX: if needed, put more variables here */
-
-/*
* The size of the floating point context area. On some CPUs this
* will not be a "sizeof" because the format of the floating point
* area is not defined -- only the size is. This is usually on
@@ -481,7 +451,7 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)();
* that a "reasonable" small application should not have any problems.
*/
-#define CPU_STACK_MINIMUM_SIZE (1024*16)
+#define CPU_STACK_MINIMUM_SIZE (1024*4)
/*
* CPU's worst alignment requirement for data types on a byte boundary. This
@@ -535,7 +505,7 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)();
* Support routine to initialize the RTEMS vector table after it is allocated.
*/
-#define _CPU_Initialize_vectors()
+#define _CPU_Initialize_vectors()
/*
* Disable all interrupts for an RTEMS critical section. The previous
@@ -543,15 +513,13 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)();
*/
#define _CPU_ISR_Disable( _level ) \
- do { \
- int reg; \
- asm volatile ("MRS %0, cpsr \n" \
- "ORR %1, %0, #0xc0 \n" \
- "MSR cpsr, %1 \n" \
- "AND %0, %0, #0xc0 \n" \
- : "=r" (_level), "=r" (reg) \
- : "0" (_level), "1" (reg)); \
- } while (0)
+ { \
+ int reg; \
+ asm volatile ("MRS %0, cpsr \n" \
+ "ORR %1, %0, #0xc0 \n" \
+ "MSR cpsr, %1 \n" \
+ : "=&r" (_level), "=&r" (reg)); \
+ }
/*
* Enable interrupts to the previous level (returned by _CPU_ISR_Disable).
@@ -560,15 +528,10 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)();
*/
#define _CPU_ISR_Enable( _level ) \
- do { \
- int reg; \
- asm volatile ("MRS %0, cpsr \n" \
- "BIC %0, %0, #0xc0 \n" \
- "ORR %0, %0, %2 \n" \
- "MSR cpsr, %0 \n" \
- : "=r" (reg) \
- : "0" (reg), "r" (_level)); \
- } while (0)
+ { \
+ asm volatile ("MSR cpsr, %0 \n" \
+ : : "r" (_level)); \
+ }
/*
* This temporarily restores the interrupt to _level before immediately
@@ -579,15 +542,12 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)();
#define _CPU_ISR_Flash( _level ) \
{ \
- int reg1; \
- int reg2; \
+ int reg; \
asm volatile ("MRS %0, cpsr \n" \
- "BIC %1, %0, #0xc0 \n" \
- "ORR %1, %1, %4 \n" \
"MSR cpsr, %1 \n" \
"MSR cpsr, %0 \n" \
- : "=r" (reg1), "=r" (reg2) \
- : "0" (reg1), "1" (reg2), "r" (_level)); \
+ : "=&r" (reg) \
+ : "r" (_level)); \
}
/*
@@ -603,15 +563,15 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)();
* The get routine usually must be implemented as a subroutine.
*/
-#define _CPU_ISR_Set_level( new_level ) \
- { \
+#define _CPU_ISR_Set_level( new_level ) \
+ { \
int reg; \
asm volatile ("MRS %0, cpsr \n" \
- "BIC %0, %0, #0xc0 \n" \
+ "BIC %0, %0, #0xc0 \n" \
"ORR %0, %0, %2 \n" \
- "MSR cpsr_c, %0 \n" \
- : "=r" (reg) \
- : "0" (reg), "r" (new_level)); \
+ "MSR cpsr_c, %0 \n" \
+ : "=r" (reg) \
+ : "r" (reg), "0" (reg)); \
}
@@ -708,9 +668,17 @@ void _CPU_Context_Initialize(
* halts/stops the CPU.
*/
-#define _CPU_Fatal_halt( _error ) \
- { \
- }
+#define _CPU_Fatal_halt( _error ) \
+ do { \
+ int _level; \
+ _CPU_ISR_Disable( _level ); \
+ asm volatile ("mov r0, %0\n" \
+ : "=r" (_error) \
+ : "0" (_error) \
+ : "r0" ); \
+ while(1) ; \
+ } while(0);
+
/* end of Fatal Error manager macros */
@@ -770,18 +738,17 @@ void _CPU_Context_Initialize(
* where bit_set_table[ 16 ] has values which indicate the first
* bit set
*/
+#if (ARM_HAS_CLZ == 0)
+# define CPU_USE_GENERIC_BITFIELD_CODE TRUE
+# define CPU_USE_GENERIC_BITFIELD_DATA TRUE
+#else
+# define CPU_USE_GENERIC_BITFIELD_CODE FALSE
+# define CPU_USE_GENERIC_BITFIELD_DATA FALSE
-#define CPU_USE_GENERIC_BITFIELD_CODE TRUE
-#define CPU_USE_GENERIC_BITFIELD_DATA TRUE
-
-#if (CPU_USE_GENERIC_BITFIELD_CODE == FALSE)
-
-#define _CPU_Bitfield_Find_first_bit( _value, _output ) \
- { \
- (_output) = 0; /* do something to prevent warnings */ \
- }
-
-#endif
+# define _CPU_Bitfield_Find_first_bit( _value, _output ) \
+ { \
+ (_output) = 0; /* do something to prevent warnings */ \
+ }
/* end of Bitfield handler macros */
@@ -791,12 +758,10 @@ void _CPU_Context_Initialize(
* for that routine.
*/
-#if (CPU_USE_GENERIC_BITFIELD_CODE == FALSE)
-#define _CPU_Priority_Mask( _bit_number ) \
- ( 1 << (_bit_number) )
+# define _CPU_Priority_Mask( _bit_number ) \
+ ( 1 << (_bit_number) )
-#endif
/*
* This routine translates the bit numbers returned by
@@ -805,11 +770,11 @@ void _CPU_Context_Initialize(
* for that routine.
*/
-#if (CPU_USE_GENERIC_BITFIELD_CODE == FALSE)
-#define _CPU_Priority_bits_index( _priority ) \
- (_priority)
+# define _CPU_Priority_bits_index( _priority ) \
+ (_priority)
+# error "Implement CLZ verson of priority bit functions for ARMv5"
#endif
/* end of Priority handler macros */
@@ -863,17 +828,6 @@ void _CPU_ISR_install_vector(
void _CPU_Install_interrupt_stack( void );
/*
- * _CPU_Thread_Idle_body
- *
- * This routine is the CPU dependent IDLE thread body.
- *
- * NOTE: It need only be provided if CPU_PROVIDES_IDLE_THREAD_BODY
- * is TRUE.
- */
-
-void _CPU_Thread_Idle_body( void );
-
-/*
* _CPU_Context_switch
*
* This routine switches from the run context to the heir context.
@@ -897,6 +851,7 @@ void _CPU_Context_restore(
Context_Control *new_context
);
+#if (ARM_HAS_FPU == 1)
/*
* _CPU_Context_save_fp
*
@@ -916,6 +871,7 @@ void _CPU_Context_save_fp(
void _CPU_Context_restore_fp(
void **fp_context_ptr
);
+#endif /* (ARM_HAS_FPU == 1) */
/* The following routine swaps the endian format of an unsigned int.
* It must be static because it is referenced indirectly.
@@ -941,19 +897,28 @@ static inline unsigned int CPU_swap_u32(
unsigned int value
)
{
- unsigned32 byte1, byte2, byte3, byte4, swapped;
-
- byte4 = (value >> 24) & 0xff;
- byte3 = (value >> 16) & 0xff;
- byte2 = (value >> 8) & 0xff;
- byte1 = value & 0xff;
-
- swapped = (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4;
- return( swapped );
+ unsigned32 tmp;
+ asm volatile ("EOR %1, %0, %0, ROR #16\n" \
+ "BIC %1, %1, #0xff0000\n" \
+ "MOV %0, %0, ROR #8\n" \
+ "EOR %0, %0, %1, LSR #8\n" \
+ : "=&r" (value), "=&r" (tmp) \
+ : "0" (value));
+
+ return value;
}
-#define CPU_swap_u16( value ) \
- (((value&0xff) << 8) | ((value >> 8)&0xff))
+static inline unsigned16 CPU_swap_u16(unsigned16 value)
+{
+ unsigned32 tmp = value; /* make compiler warnings go away */
+ asm volatile ("MOV %1, %0, LSR #8\n" \
+ "BIC %0, %0, #0xff00\n" \
+ "MOV %0, %0, LSL #8\n" \
+ "ORR %0, %0, %1\n" \
+ : "=&r" (value), "=&r" (tmp) \
+ : "0" (value));
+ return value;
+}
#ifdef __cplusplus
}
diff --git a/cpukit/score/cpu/arm/rtems/score/cpu_asm.h b/cpukit/score/cpu/arm/rtems/score/cpu_asm.h
index 2c13347578..9cc5577a56 100644
--- a/cpukit/score/cpu/arm/rtems/score/cpu_asm.h
+++ b/cpukit/score/cpu/arm/rtems/score/cpu_asm.h
@@ -18,24 +18,18 @@
/* Registers saved in context switch: */
-.set REG_R0, 0
-.set REG_R1, 4
-.set REG_R2, 8
-.set REG_R3, 12
-.set REG_R4, 16
-.set REG_R5, 20
-.set REG_R6, 24
-.set REG_R7, 28
-.set REG_R8, 32
-.set REG_R9, 36
-.set REG_R10, 40
-.set REG_R11, 44
-.set REG_R12, 48
-.set REG_SP, 52
-.set REG_LR, 56
-.set REG_PC, 60
-.set REG_CPSR, 64
-.set SIZE_REGS, REG_CPSR + 4
-
+.set REG_CPSR, 0
+.set REG_R4, 4
+.set REG_R5, 8
+.set REG_R6, 12
+.set REG_R7, 16
+.set REG_R8, 20
+.set REG_R9, 24
+.set REG_R10, 28
+.set REG_R11, 32
+.set REG_SP, 36
+.set REG_LR, 40
+.set REG_PC, 44
+.set SIZE_REGS, REG_PC + 4
#endif
diff --git a/cpukit/score/cpu/arm/rtems/score/types.h b/cpukit/score/cpu/arm/rtems/score/types.h
index 4408046d4e..dc790a2b0b 100644
--- a/cpukit/score/cpu/arm/rtems/score/types.h
+++ b/cpukit/score/cpu/arm/rtems/score/types.h
@@ -25,25 +25,24 @@ extern "C" {
* This section defines the basic types for this processor.
*/
-typedef unsigned char unsigned8; /* unsigned 8-bit integer */
-typedef unsigned short unsigned16; /* unsigned 16-bit integer */
-typedef unsigned int unsigned32; /* unsigned 32-bit integer */
-typedef unsigned long long unsigned64; /* unsigned 64-bit integer */
+typedef unsigned char unsigned8; /* unsigned 8-bit integer */
+typedef unsigned short unsigned16; /* unsigned 16-bit integer */
+typedef unsigned int unsigned32; /* unsigned 32-bit integer */
+typedef unsigned long long unsigned64; /* unsigned 64-bit integer */
-typedef unsigned16 Priority_Bit_map_control;
+typedef signed char signed8; /* 8-bit signed integer */
+typedef signed short signed16; /* 16-bit signed integer */
+typedef signed int signed32; /* 32-bit signed integer */
+typedef signed long long signed64; /* 64 bit signed integer */
-typedef signed char signed8; /* 8-bit signed integer */
-typedef signed short signed16; /* 16-bit signed integer */
-typedef signed int signed32; /* 32-bit signed integer */
-typedef signed long long signed64; /* 64 bit signed integer */
+typedef unsigned32 boolean; /* Boolean value */
+typedef unsigned16 Priority_Bit_map_control;
-typedef unsigned32 boolean; /* Boolean value */
+typedef float single_precision; /* single precision float */
+typedef double double_precision; /* double precision float */
-typedef float single_precision; /* single precision float */
-typedef double double_precision; /* double precision float */
-
-typedef void no_cpu_isr;
-typedef void ( *no_cpu_isr_entry )( void );
+typedef void arm_cpu_isr;
+typedef void ( *arm_cpu_isr_entry )( void );
#ifdef __cplusplus
}