2002-07-17 Jay Monkman <jtm@smoothsmoothie.com>

* rtems/score/cpu_asm.h: Enhanced to include register offsets.
	* Makefile.am: Install rtems/score/cpu_asm.h.
	* cpu.c: Significantly enhanced including the implementation of
	_CPU_ISR_Get_level.
	* cpu_asm.S: Improved behavior of context switch and interrupt
	dispatching.
	* rtems/score/arm.h: Improved the CPU model name determination.
	* rtems/score/cpu.h: Improved interrupt disable/enable functions.
This commit is contained in:
Joel Sherrill
2002-07-17 17:14:31 +00:00
parent 74c402a2a3
commit 4f0b287a4a
14 changed files with 648 additions and 414 deletions

View File

@@ -1,3 +1,14 @@
2002-07-17 Jay Monkman <jtm@smoothsmoothie.com>
* rtems/score/cpu_asm.h: Enhanced to include register offsets.
* Makefile.am: Install rtems/score/cpu_asm.h.
* cpu.c: Significantly enhanced including the implementation of
_CPU_ISR_Get_level.
* cpu_asm.S: Improved behavior of context switch and interrupt
dispatching.
* rtems/score/arm.h: Improved the CPU model name determination.
* rtems/score/cpu.h: Improved interrupt disable/enable functions.
2002-07-05 Joel Sherrill <joel@OARcorp.com>
* rtems/score/cpu.h: Filled in something that was marked XXX.

View File

@@ -26,6 +26,7 @@ PREINSTALL_FILES = $(PROJECT_INCLUDE) $(include_HEADERS:%=$(PROJECT_INCLUDE)/%)
include_rtems_scoredir = $(includedir)/rtems/score
include_rtems_score_HEADERS = \
rtems/score/cpu.h \
rtems/score/cpu_asm.h \
rtems/score/arm.h \
rtems/score/types.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score \

View File

@@ -5,6 +5,9 @@
* COPYRIGHT (c) 2000 Canon Research Centre France SA.
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
*
* Copyright (c) 2002 Advent Networks, Inc
* Jay Monkman <jmonkman@adventnetworks.com>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
@@ -25,30 +28,32 @@
*
* INPUT PARAMETERS:
* cpu_table - CPU table to initialize
* thread_dispatch - address of disptaching routine
* thread_dispatch - address of ISR disptaching routine (unused)
*
*/
void _CPU_Initialize(
rtems_cpu_table *cpu_table,
void (*thread_dispatch) /* ignored on this CPU */
)
{
_CPU_Table = *cpu_table;
_CPU_Table = *cpu_table;
}
/*PAGE
/*
*
* _CPU_ISR_Get_level
* _CPU_ISR_Get_level - returns the current interrupt level
*/
unsigned32 _CPU_ISR_Get_level( void )
{
/*
* This routine returns the current interrupt level.
*/
return 0;
unsigned32 reg;
asm volatile ("mrs %0, cpsr \n" \
"and %0, %0, #0xc0 \n" \
: "=r" (reg));
return reg;
}
/*
@@ -59,28 +64,48 @@ unsigned32 _CPU_ISR_Get_level( void )
*
* Input parameters:
* vector - interrupt vector number
* old_handler - former ISR for this vector number
* new_handler - replacement ISR for this vector number
* old_handler - pointer to store former ISR for this vector number
*
* FIXME: This vector scheme should be changed to allow FIQ to be
* handled better. I'd like to be able to put VectorTable
* elsewhere - JTM
*
*
* Output parameters: NONE
*
*/
void _CPU_ISR_install_vector(
unsigned32 vector,
proc_ptr new_handler,
proc_ptr *old_handler
)
{
/* pointer on the redirection table in RAM */
long *VectorTable = (long *)(MAX_EXCEPTIONS * 4);
/* pointer on the redirection table in RAM */
long *VectorTable = (long *)(MAX_EXCEPTIONS * 4);
if (old_handler != NULL) {
old_handler = *(proc_ptr *)(VectorTable + vector);
}
if (old_handler != NULL)
old_handler = *(proc_ptr *)(VectorTable + vector);
*(VectorTable + vector) = (long)new_handler ;
*(VectorTable + vector) = (long)new_handler ;
}
void _CPU_Context_Initialize(
Context_Control *the_context,
unsigned32 *stack_base,
unsigned32 size,
unsigned32 new_level,
void *entry_point,
boolean is_fp
)
{
the_context->register_sp = ((unsigned32)(stack_base)) + (size) ;
the_context->register_pc = (entry_point);
the_context->register_cpsr = (new_level | 0x13);
}
/*PAGE
*
* _CPU_Install_interrupt_stack
@@ -88,6 +113,32 @@ void _CPU_ISR_install_vector(
void _CPU_Install_interrupt_stack( void )
{
/* FIXME: do something here */
#if 0
extern unsigned long _fiq_stack;
extern unsigned long _fiq_stack_size;
extern unsigned long _irq_stack;
extern unsigned long _irq_stack_size;
extern unsigned long _abt_stack;
extern unsigned long _abt_stack_size;
unsigned long *ptr;
int i;
ptr = &_fiq_stack;
for (i = 0; i < ((int)&_fiq_stack_size/4); i++) {
ptr[i] = 0x13131313;
}
ptr = &_irq_stack;
for (i = 0; i < ((int)&_irq_stack_size/4); i++) {
ptr[i] = 0xf0f0f0f0;
}
ptr = &_abt_stack;
for (i = 0; i < ((int)&_abt_stack_size/4); i++) {
ptr[i] = 0x55555555;
}
#endif
}
/*PAGE
@@ -110,60 +161,82 @@ void _CPU_Install_interrupt_stack( void )
void _CPU_Thread_Idle_body( void )
{
while(1);
while(1); /* FIXME: finish this */
/* insert your "halt" instruction here */ ;
}
void _defaultExcHandler (CPU_Exception_frame *ctx)
{
printk("----------------------------------------------------------\n");
printk("Exception %d caught at PC %x by thread %d\n",
ctx->register_pc, ctx->register_lr - 4,
_Thread_Executing->Object.id);
printk("----------------------------------------------------------\n");
printk("Processor execution context at time of the fault was :\n");
printk("----------------------------------------------------------\n");
printk(" r0 = %x r1 = %x r2 = %x r3 = %x\n",
ctx->register_r0, ctx->register_r1, ctx->register_r2, ctx->register_r3);
printk(" r4 = %x r5 = %x r6 = %x r7 = %x\n",
ctx->register_r4, ctx->register_r5, ctx->register_r6, ctx->register_r7);
printk(" r8 = %x r9 = %x r10 = %x\n",
ctx->register_r8, ctx->register_r9, ctx->register_r10);
printk(" fp = %x ip = %x sp = %x pc = %x\n",
ctx->register_fp, ctx->register_ip, ctx->register_sp, ctx->register_lr - 4);
printk("----------------------------------------------------------\n");
if (_ISR_Nest_level > 0) {
/*
* In this case we shall not delete the task interrupted as
* it has nothing to do with the fault. We cannot return either
* because the eip points to the faulty instruction so...
*/
printk("Exception while executing ISR!!!. System locked\n");
while(1);
}
else {
printk(" ************ FAULTY THREAD WILL BE DELETED **************\n");
rtems_task_delete(_Thread_Executing->Object.id);
}
printk("\n\r");
printk("----------------------------------------------------------\n\r");
printk("Exception 0x%x caught at PC 0x%x by thread %d\n",
ctx->register_pc, ctx->register_lr - 4,
_Thread_Executing->Object.id);
printk("----------------------------------------------------------\n\r");
printk("Processor execution context at time of the fault was :\n\r");
printk("----------------------------------------------------------\n\r");
printk(" r0 = %8x r1 = %8x r2 = %8x r3 = %8x\n\r",
ctx->register_r0, ctx->register_r1,
ctx->register_r2, ctx->register_r3);
printk(" r4 = %8x r5 = %8x r6 = %8x r7 = %8x\n\r",
ctx->register_r4, ctx->register_r5,
ctx->register_r6, ctx->register_r7);
printk(" r8 = %8x r9 = %8x r10 = %8x\n\r",
ctx->register_r8, ctx->register_r9, ctx->register_r10);
printk(" fp = %8x ip = %8x sp = %8x pc = %8x\n\r",
ctx->register_fp, ctx->register_ip,
ctx->register_sp, ctx->register_lr - 4);
printk("----------------------------------------------------------\n\r");
if (_ISR_Nest_level > 0) {
/*
* In this case we shall not delete the task interrupted as
* it has nothing to do with the fault. We cannot return either
* because the eip points to the faulty instruction so...
*/
printk("Exception while executing ISR!!!. System locked\n\r");
while(1);
}
else {
printk("*********** FAULTY THREAD WILL BE DELETED **************\n\r");
rtems_task_delete(_Thread_Executing->Object.id);
}
}
cpuExcHandlerType _currentExcHandler = _defaultExcHandler;
extern void _Exception_Handler_Undef_Swi();
extern void _Exception_Handler_Abort();
/* FIXME: put comments here */
void rtems_exception_init_mngt()
{
ISR_Level level;
ISR_Level level;
_CPU_ISR_Disable(level);
_CPU_ISR_install_vector(ARM_EXCEPTION_UNDEF, _Exception_Handler_Undef_Swi, NULL);
_CPU_ISR_install_vector(ARM_EXCEPTION_SWI, _Exception_Handler_Undef_Swi, NULL);
_CPU_ISR_install_vector(ARM_EXCEPTION_PREF_ABORT, _Exception_Handler_Abort , NULL);
_CPU_ISR_install_vector(ARM_EXCEPTION_DATA_ABORT, _Exception_Handler_Abort , NULL);
_CPU_ISR_install_vector(ARM_EXCEPTION_FIQ, _Exception_Handler_Abort , NULL);
_CPU_ISR_install_vector(ARM_EXCEPTION_IRQ, _Exception_Handler_Abort , NULL);
_CPU_ISR_install_vector(ARM_EXCEPTION_UNDEF,
_Exception_Handler_Undef_Swi,
NULL);
_CPU_ISR_install_vector(ARM_EXCEPTION_SWI,
_Exception_Handler_Undef_Swi,
NULL);
_CPU_ISR_install_vector(ARM_EXCEPTION_PREF_ABORT,
_Exception_Handler_Abort,
NULL);
_CPU_ISR_install_vector(ARM_EXCEPTION_DATA_ABORT,
_Exception_Handler_Abort,
NULL);
_CPU_ISR_install_vector(ARM_EXCEPTION_FIQ,
_Exception_Handler_Abort,
NULL);
_CPU_ISR_install_vector(ARM_EXCEPTION_IRQ,
_Exception_Handler_Abort,
NULL);
_CPU_ISR_Enable(level);
}

View File

@@ -1,8 +1,12 @@
/* cpu_asm.s
/*
* $Id$
*
* This file contains all assembly code for the ARM implementation
* of RTEMS.
*
* Copyright (c) 2002 by Advent Networks, Inc.
* Jay Monkman <jmonkman@adventnetworks.com>
*
* COPYRIGHT (c) 2000 Canon Research Centre France SA.
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
*
@@ -13,41 +17,33 @@
*/
#include <asm.h>
#include <rtems/score/cpu_asm.h>
/*
* Format of ARM Register structure
*/
.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_FP, 44
.set REG_IP, 48
.set REG_SP, 52
.set REG_LR, 56
.set REG_PC, 60
.set SIZE_REGS, REG_PC + 4
/*
* void _CPU_Context_switch( run_context, heir_context )
* void _CPU_Context_restore( run_context, heir_context )
*
* This routine performs a normal non-FP context.
*
* R0 = run_context R1 = heir_context
*
* R0 = run_context R1 = heir_context
*
* This function copies the current registers to where r0 points, then
* restores the ones from where r1 points.
*
*
* NOTE: The function should be able to only save/restore the registers
* that would be saved by a C function since the others have already
* been saved.
*
* It should also be able to use the stm/ldm instructions.
*
*/
.globl _CPU_Context_switch
_CPU_Context_switch:
/* FIXME: This should use load and store multiple instructions */
/* Start saving context */
str r2, [r0, #REG_R2]
str r3, [r0, #REG_R3]
str r4, [r0, #REG_R4]
@@ -57,9 +53,21 @@ _CPU_Context_switch:
str r8, [r0, #REG_R8]
str r9, [r0, #REG_R9]
str r10, [r0, #REG_R10]
str sp, [r0, #REG_SP]
str lr, [r0, #REG_PC]
str r11, [r0, #REG_R11]
str r12, [r0, #REG_R12]
str sp, [r0, #REG_SP]
str lr, [r0, #REG_PC] /* save LR at PC's location */
mrs r2, cpsr
str r2, [r0, #REG_CPSR]
/* Start restoring context */
ldr r2, [r1, #REG_CPSR]
msr cpsr, r2
ldr r2, [r1, #REG_R2]
ldr r3, [r1, #REG_R3]
ldr r4, [r1, #REG_R4]
@@ -68,25 +76,34 @@ _CPU_Context_switch:
ldr r7, [r1, #REG_R7]
ldr r8, [r1, #REG_R8]
ldr r9, [r1, #REG_R9]
ldr r10, [r1, #REG_R10]
ldr r10, [r1, #REG_R10]
ldr r11, [r1, #REG_R11]
ldr r12, [r1, #REG_R12]
ldr sp, [r1, #REG_SP]
ldr lr, [r1, #REG_PC]
ldr lr, [r1, #REG_PC]
mov pc, lr
/*
* NOTE: May be unnecessary to reload some registers.
*/
/*
* void _CPU_Context_restore( new_context )
*
* This routine performs a normal non-FP context.
* This function copies the restores the registers from where r0 points.
* It must match _CPU_Context_switch()
*
* NOTE: The function should be able to only save/restore the registers
* that would be saved by a C function since the others have already
* been saved.
*
* It should also be able to use the stm/ldm instructions.
*
*/
.globl _CPU_Context_restore
_CPU_Context_restore:
/* FIXME: This should use load and store multiple instructions */
ldr r2, [r0, #REG_CPSR]
msr cpsr, r2
ldr r2, [r0, #REG_R2]
ldr r2, [r0, #REG_R2]
ldr r3, [r0, #REG_R3]
ldr r4, [r0, #REG_R4]
ldr r5, [r0, #REG_R5]
@@ -94,14 +111,19 @@ _CPU_Context_restore:
ldr r7, [r0, #REG_R7]
ldr r8, [r0, #REG_R8]
ldr r9, [r0, #REG_R9]
ldr r10, [r0, #REG_R10]
ldr r10, [r0, #REG_R10]
ldr r11, [r1, #REG_R11]
ldr r12, [r1, #REG_R12]
ldr sp, [r0, #REG_SP]
ldr lr, [r0, #REG_PC]
mov pc, lr
/* FIXME: _Exception_Handler_Undef_Swi is untested */
.globl _Exception_Handler_Undef_Swi
_Exception_Handler_Undef_Swi:
/* FIXME: This should use load and store multiple instructions */
sub r13,r13,#SIZE_REGS
str r0, [r13, #REG_R0]
str r1, [r13, #REG_R1]
@@ -114,8 +136,8 @@ _Exception_Handler_Undef_Swi:
str r8, [r13, #REG_R8]
str r9, [r13, #REG_R9]
str r10, [r13, #REG_R10]
str fp, [r13, #REG_FP]
str ip, [r13, #REG_IP]
str r11, [r13, #REG_R11]
str r12, [r13, #REG_R12]
str sp, [r13, #REG_SP]
str lr, [r13, #REG_LR]
mrs r0, cpsr /* read the status */
@@ -123,7 +145,7 @@ _Exception_Handler_Undef_Swi:
str r0, [r13, #REG_PC] /* we store it in a free place */
mov r0, r13 /* put frame address in r0 (C arg 1) */
ldr r1, =_currentExcHandler
ldr r1, =SWI_Handler
ldr lr, =_go_back_1
ldr pc,[r1] /* call handler */
_go_back_1:
@@ -138,15 +160,17 @@ _go_back_1:
ldr r8, [r13, #REG_R8]
ldr r9, [r13, #REG_R9]
ldr r10, [r13, #REG_R10]
ldr fp, [r13, #REG_FP]
ldr ip, [r13, #REG_IP]
ldr r11, [r13, #REG_R11]
ldr r12, [r13, #REG_R12]
ldr sp, [r13, #REG_SP]
ldr lr, [r13, #REG_LR]
add r13,r13,#SIZE_REGS
movs pc,r14 /* return */
movs pc,r14 /* return */
/* FIXME: _Exception_Handler_Abort is untested */
.globl _Exception_Handler_Abort
_Exception_Handler_Abort:
/* FIXME: This should use load and store multiple instructions */
sub r13,r13,#SIZE_REGS
str r0, [r13, #REG_R0]
str r1, [r13, #REG_R1]
@@ -159,8 +183,8 @@ _Exception_Handler_Abort:
str r8, [r13, #REG_R8]
str r9, [r13, #REG_R9]
str r10, [r13, #REG_R10]
str sp, [r13, #REG_FP]
str lr, [r13, #REG_IP]
str sp, [r13, #REG_R11]
str lr, [r13, #REG_R12]
str lr, [r13, #REG_SP]
str lr, [r13, #REG_LR]
mrs r0, cpsr /* read the status */
@@ -183,11 +207,10 @@ _go_back_2:
ldr r8, [r13, #REG_R8]
ldr r9, [r13, #REG_R9]
ldr r10, [r13, #REG_R10]
ldr sp, [r13, #REG_FP]
ldr lr, [r13, #REG_IP]
ldr sp, [r13, #REG_R11]
ldr lr, [r13, #REG_R12]
ldr lr, [r13, #REG_SP]
ldr lr, [r13, #REG_LR]
add r13,r13,#SIZE_REGS
subs pc,r14,#4 /* return */

View File

@@ -1,12 +1,13 @@
/* no_cpu.h
*
* This file is an example (i.e. "no CPU") of the file which is
* created for each CPU family port of RTEMS.
/*
* $Id$
*
*
* COPYRIGHT (c) 2000 Canon Research Centre France SA.
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
*
* Copyright (c) 2002 Advent Networks, Inc.
* Jay Monkman <jmonkman@adventnetworks.com>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
@@ -28,16 +29,23 @@ extern "C" {
* dependent features are present in a particular member
* of the family.
*/
#if defined(__arm__)
#define CPU_MODEL_NAME "arm"
#define ARM_HAS_FPU 0
#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
#else
#error "Unsupported CPU Model"
# error "Unsupported CPU Model"
#endif
/*

View File

@@ -1,8 +1,10 @@
/* cpu.h
*
* This include file contains information pertaining to the arm
/*
* This include file contains information pertaining to the ARM
* processor.
*
* COPYRIGHT (c) 2002 Advent Networks, Inc.
* Jay Monkman <jmonkman@adventnetworks.com>
*
* COPYRIGHT (c) 2000 Canon Research Centre France SA.
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
*
@@ -10,8 +12,10 @@
* 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 */
#ifndef __CPU_h
#define __CPU_h
@@ -43,7 +47,7 @@ extern "C" {
* one subroutine call is avoided entirely.]
*/
#define CPU_INLINE_ENABLE_DISPATCH FALSE
#define CPU_INLINE_ENABLE_DISPATCH TRUE
/*
* Should the body of the search loops in _Thread_queue_Enqueue_priority
@@ -63,7 +67,7 @@ extern "C" {
* necessary to strike a balance when setting this parameter.
*/
#define CPU_UNROLL_ENQUEUE_PRIORITY FALSE
#define CPU_UNROLL_ENQUEUE_PRIORITY TRUE
/*
* Does RTEMS manage a dedicated interrupt stack in software?
@@ -99,14 +103,14 @@ extern "C" {
*
* If this is TRUE, CPU_ALLOCATE_INTERRUPT_STACK should also be TRUE.
*
* Only one of CPU_HAS_SOFTWARE_INTERRUPT_STACK and
* Only one of CPU_HAS_SOFTWARE_INTERRU
* 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
* procedure on that CPU.
*/
#define CPU_HAS_HARDWARE_INTERRUPT_STACK FALSE
#define CPU_HAS_HARDWARE_INTERRUPT_STACK TRUE
/*
* Does RTEMS allocate a dedicated interrupt stack in the Interrupt Manager?
@@ -118,7 +122,7 @@ extern "C" {
* or CPU_INSTALL_HARDWARE_INTERRUPT_STACK is TRUE.
*/
#define CPU_ALLOCATE_INTERRUPT_STACK FALSE
#define CPU_ALLOCATE_INTERRUPT_STACK TRUE
/*
* Does the RTEMS invoke the user's ISR with the vector number and
@@ -273,8 +277,8 @@ extern "C" {
*/
#define CPU_HAS_OWN_HOST_TO_NETWORK_ROUTINES FALSE
#define CPU_BIG_ENDIAN TRUE
#define CPU_LITTLE_ENDIAN FALSE
#define CPU_BIG_ENDIAN FALSE
#define CPU_LITTLE_ENDIAN TRUE
/*
* The following defines the number of bits actually used in the
@@ -282,7 +286,7 @@ extern "C" {
* CPU interrupt levels is defined by the routine _CPU_ISR_Set_level().
*/
#define CPU_MODES_INTERRUPT_MASK 0x00000001
#define CPU_MODES_INTERRUPT_MASK 0x000000c0
/*
* Processor defined structures
@@ -345,6 +349,7 @@ typedef struct {
unsigned32 register_sp;
unsigned32 register_lr;
unsigned32 register_pc;
unsigned32 register_cpsr;
} Context_Control;
typedef struct {
@@ -476,14 +481,14 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)();
* that a "reasonable" small application should not have any problems.
*/
#define CPU_STACK_MINIMUM_SIZE (1024*4)
#define CPU_STACK_MINIMUM_SIZE (1024*16)
/*
* CPU's worst alignment requirement for data types on a byte boundary. This
* alignment does not take into account the requirements for the stack.
*/
#define CPU_ALIGNMENT 8
#define CPU_ALIGNMENT 4
/*
* This number corresponds to the byte alignment requirement for the
@@ -522,7 +527,7 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)();
* NOTE: This must be a power of 2 either 0 or greater than CPU_ALIGNMENT.
*/
#define CPU_STACK_ALIGNMENT 32
#define CPU_STACK_ALIGNMENT 4
/* ISR handler macros */
@@ -537,14 +542,16 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)();
* level is returned in _level.
*/
#define _CPU_ISR_Disable( _level ) \
{ \
(_level) = 0; \
asm volatile ("MRS r0, cpsr \n" \
"ORR r0, r0, #0xc0 \n" \
"MSR cpsr, r0 \n" \
: : : "r0"); \
}
#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)
/*
* Enable interrupts to the previous level (returned by _CPU_ISR_Disable).
@@ -552,14 +559,17 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)();
* _level is not modified.
*/
#define _CPU_ISR_Enable( _level ) \
{ \
asm volatile ("MRS r0, cpsr \n" \
"AND r0, r0, #0xFFFFFF3F \n" \
"MSR cpsr, r0 \n" \
: : : "r0" ); \
}
#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)
/*
* This temporarily restores the interrupt to _level before immediately
* disabling them again. This is used to divide long RTEMS critical
@@ -567,8 +577,17 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)();
* modified.
*/
#define _CPU_ISR_Flash( _isr_cookie ) \
#define _CPU_ISR_Flash( _level ) \
{ \
int reg1; \
int reg2; \
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)); \
}
/*
@@ -586,8 +605,16 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)();
#define _CPU_ISR_Set_level( new_level ) \
{ \
int reg; \
asm volatile ("MRS %0, cpsr \n" \
"BIC %0, %0, #0xc0 \n" \
"ORR %0, %0, %2 \n" \
"MSR cpsr_c, %0 \n" \
: "=r" (reg) \
: "0" (reg), "r" (new_level)); \
}
unsigned32 _CPU_ISR_Get_level( void );
/* end of ISR handler macros */
@@ -615,12 +642,14 @@ unsigned32 _CPU_ISR_Get_level( void );
* where the PSR contains an enable FPU bit.
*/
#define _CPU_Context_Initialize( _the_context, _stack_base, _size, \
_isr, _entry_point, _is_fp ) \
{ \
(_the_context)->register_sp = ((unsigned32)(_stack_base)) + (_size) ; \
(_the_context)->register_pc = (_entry_point); \
}
void _CPU_Context_Initialize(
Context_Control *the_context,
unsigned32 *stack_base,
unsigned32 size,
unsigned32 new_level,
void *entry_point,
boolean is_fp
);
/*
* This routine is responsible for somehow restarting the currently

View File

@@ -1,69 +1,41 @@
/*
* cpu_asm.h
* $Id$
*
* Very loose template for an include file for the cpu_asm.? file
* if it is implemented as a ".S" file (preprocessed by cpp) instead
* of a ".s" file (preprocessed by gm4 or gasp).
*
* COPYRIGHT (c) 2000 Canon Research Centre France SA.
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
* Copyright (c) 2002 by Advent Networks, Inc.
* Jay Monkman <jmonkman@adventnetworks.com>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* This file is the include file for cpu_asm.S
*
*
*/
#ifndef __CPU_ASM_h
#define __CPU_ASM_h
/* pull in the generated offsets */
#include <rtems/score/offsets.h>
/* 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
/*
* Hardware General Registers
*/
/* put something here */
/*
* Hardware Floating Point Registers
*/
/* put something here */
/*
* Hardware Control Registers
*/
/* put something here */
/*
* Calling Convention
*/
/* put something here */
/*
* Temporary registers
*/
/* put something here */
/*
* Floating Point Registers - SW Conventions
*/
/* put something here */
/*
* Temporary floating point registers
*/
/* put something here */
#endif
/* end of file */

View File

@@ -1,3 +1,14 @@
2002-07-17 Jay Monkman <jtm@smoothsmoothie.com>
* rtems/score/cpu_asm.h: Enhanced to include register offsets.
* Makefile.am: Install rtems/score/cpu_asm.h.
* cpu.c: Significantly enhanced including the implementation of
_CPU_ISR_Get_level.
* cpu_asm.S: Improved behavior of context switch and interrupt
dispatching.
* rtems/score/arm.h: Improved the CPU model name determination.
* rtems/score/cpu.h: Improved interrupt disable/enable functions.
2002-07-05 Joel Sherrill <joel@OARcorp.com>
* rtems/score/cpu.h: Filled in something that was marked XXX.

View File

@@ -26,6 +26,7 @@ PREINSTALL_FILES = $(PROJECT_INCLUDE) $(include_HEADERS:%=$(PROJECT_INCLUDE)/%)
include_rtems_scoredir = $(includedir)/rtems/score
include_rtems_score_HEADERS = \
rtems/score/cpu.h \
rtems/score/cpu_asm.h \
rtems/score/arm.h \
rtems/score/types.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score \

View File

@@ -5,6 +5,9 @@
* COPYRIGHT (c) 2000 Canon Research Centre France SA.
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
*
* Copyright (c) 2002 Advent Networks, Inc
* Jay Monkman <jmonkman@adventnetworks.com>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
@@ -25,30 +28,32 @@
*
* INPUT PARAMETERS:
* cpu_table - CPU table to initialize
* thread_dispatch - address of disptaching routine
* thread_dispatch - address of ISR disptaching routine (unused)
*
*/
void _CPU_Initialize(
rtems_cpu_table *cpu_table,
void (*thread_dispatch) /* ignored on this CPU */
)
{
_CPU_Table = *cpu_table;
_CPU_Table = *cpu_table;
}
/*PAGE
/*
*
* _CPU_ISR_Get_level
* _CPU_ISR_Get_level - returns the current interrupt level
*/
unsigned32 _CPU_ISR_Get_level( void )
{
/*
* This routine returns the current interrupt level.
*/
return 0;
unsigned32 reg;
asm volatile ("mrs %0, cpsr \n" \
"and %0, %0, #0xc0 \n" \
: "=r" (reg));
return reg;
}
/*
@@ -59,28 +64,48 @@ unsigned32 _CPU_ISR_Get_level( void )
*
* Input parameters:
* vector - interrupt vector number
* old_handler - former ISR for this vector number
* new_handler - replacement ISR for this vector number
* old_handler - pointer to store former ISR for this vector number
*
* FIXME: This vector scheme should be changed to allow FIQ to be
* handled better. I'd like to be able to put VectorTable
* elsewhere - JTM
*
*
* Output parameters: NONE
*
*/
void _CPU_ISR_install_vector(
unsigned32 vector,
proc_ptr new_handler,
proc_ptr *old_handler
)
{
/* pointer on the redirection table in RAM */
long *VectorTable = (long *)(MAX_EXCEPTIONS * 4);
/* pointer on the redirection table in RAM */
long *VectorTable = (long *)(MAX_EXCEPTIONS * 4);
if (old_handler != NULL) {
old_handler = *(proc_ptr *)(VectorTable + vector);
}
if (old_handler != NULL)
old_handler = *(proc_ptr *)(VectorTable + vector);
*(VectorTable + vector) = (long)new_handler ;
*(VectorTable + vector) = (long)new_handler ;
}
void _CPU_Context_Initialize(
Context_Control *the_context,
unsigned32 *stack_base,
unsigned32 size,
unsigned32 new_level,
void *entry_point,
boolean is_fp
)
{
the_context->register_sp = ((unsigned32)(stack_base)) + (size) ;
the_context->register_pc = (entry_point);
the_context->register_cpsr = (new_level | 0x13);
}
/*PAGE
*
* _CPU_Install_interrupt_stack
@@ -88,6 +113,32 @@ void _CPU_ISR_install_vector(
void _CPU_Install_interrupt_stack( void )
{
/* FIXME: do something here */
#if 0
extern unsigned long _fiq_stack;
extern unsigned long _fiq_stack_size;
extern unsigned long _irq_stack;
extern unsigned long _irq_stack_size;
extern unsigned long _abt_stack;
extern unsigned long _abt_stack_size;
unsigned long *ptr;
int i;
ptr = &_fiq_stack;
for (i = 0; i < ((int)&_fiq_stack_size/4); i++) {
ptr[i] = 0x13131313;
}
ptr = &_irq_stack;
for (i = 0; i < ((int)&_irq_stack_size/4); i++) {
ptr[i] = 0xf0f0f0f0;
}
ptr = &_abt_stack;
for (i = 0; i < ((int)&_abt_stack_size/4); i++) {
ptr[i] = 0x55555555;
}
#endif
}
/*PAGE
@@ -110,60 +161,82 @@ void _CPU_Install_interrupt_stack( void )
void _CPU_Thread_Idle_body( void )
{
while(1);
while(1); /* FIXME: finish this */
/* insert your "halt" instruction here */ ;
}
void _defaultExcHandler (CPU_Exception_frame *ctx)
{
printk("----------------------------------------------------------\n");
printk("Exception %d caught at PC %x by thread %d\n",
ctx->register_pc, ctx->register_lr - 4,
_Thread_Executing->Object.id);
printk("----------------------------------------------------------\n");
printk("Processor execution context at time of the fault was :\n");
printk("----------------------------------------------------------\n");
printk(" r0 = %x r1 = %x r2 = %x r3 = %x\n",
ctx->register_r0, ctx->register_r1, ctx->register_r2, ctx->register_r3);
printk(" r4 = %x r5 = %x r6 = %x r7 = %x\n",
ctx->register_r4, ctx->register_r5, ctx->register_r6, ctx->register_r7);
printk(" r8 = %x r9 = %x r10 = %x\n",
ctx->register_r8, ctx->register_r9, ctx->register_r10);
printk(" fp = %x ip = %x sp = %x pc = %x\n",
ctx->register_fp, ctx->register_ip, ctx->register_sp, ctx->register_lr - 4);
printk("----------------------------------------------------------\n");
if (_ISR_Nest_level > 0) {
/*
* In this case we shall not delete the task interrupted as
* it has nothing to do with the fault. We cannot return either
* because the eip points to the faulty instruction so...
*/
printk("Exception while executing ISR!!!. System locked\n");
while(1);
}
else {
printk(" ************ FAULTY THREAD WILL BE DELETED **************\n");
rtems_task_delete(_Thread_Executing->Object.id);
}
printk("\n\r");
printk("----------------------------------------------------------\n\r");
printk("Exception 0x%x caught at PC 0x%x by thread %d\n",
ctx->register_pc, ctx->register_lr - 4,
_Thread_Executing->Object.id);
printk("----------------------------------------------------------\n\r");
printk("Processor execution context at time of the fault was :\n\r");
printk("----------------------------------------------------------\n\r");
printk(" r0 = %8x r1 = %8x r2 = %8x r3 = %8x\n\r",
ctx->register_r0, ctx->register_r1,
ctx->register_r2, ctx->register_r3);
printk(" r4 = %8x r5 = %8x r6 = %8x r7 = %8x\n\r",
ctx->register_r4, ctx->register_r5,
ctx->register_r6, ctx->register_r7);
printk(" r8 = %8x r9 = %8x r10 = %8x\n\r",
ctx->register_r8, ctx->register_r9, ctx->register_r10);
printk(" fp = %8x ip = %8x sp = %8x pc = %8x\n\r",
ctx->register_fp, ctx->register_ip,
ctx->register_sp, ctx->register_lr - 4);
printk("----------------------------------------------------------\n\r");
if (_ISR_Nest_level > 0) {
/*
* In this case we shall not delete the task interrupted as
* it has nothing to do with the fault. We cannot return either
* because the eip points to the faulty instruction so...
*/
printk("Exception while executing ISR!!!. System locked\n\r");
while(1);
}
else {
printk("*********** FAULTY THREAD WILL BE DELETED **************\n\r");
rtems_task_delete(_Thread_Executing->Object.id);
}
}
cpuExcHandlerType _currentExcHandler = _defaultExcHandler;
extern void _Exception_Handler_Undef_Swi();
extern void _Exception_Handler_Abort();
/* FIXME: put comments here */
void rtems_exception_init_mngt()
{
ISR_Level level;
ISR_Level level;
_CPU_ISR_Disable(level);
_CPU_ISR_install_vector(ARM_EXCEPTION_UNDEF, _Exception_Handler_Undef_Swi, NULL);
_CPU_ISR_install_vector(ARM_EXCEPTION_SWI, _Exception_Handler_Undef_Swi, NULL);
_CPU_ISR_install_vector(ARM_EXCEPTION_PREF_ABORT, _Exception_Handler_Abort , NULL);
_CPU_ISR_install_vector(ARM_EXCEPTION_DATA_ABORT, _Exception_Handler_Abort , NULL);
_CPU_ISR_install_vector(ARM_EXCEPTION_FIQ, _Exception_Handler_Abort , NULL);
_CPU_ISR_install_vector(ARM_EXCEPTION_IRQ, _Exception_Handler_Abort , NULL);
_CPU_ISR_install_vector(ARM_EXCEPTION_UNDEF,
_Exception_Handler_Undef_Swi,
NULL);
_CPU_ISR_install_vector(ARM_EXCEPTION_SWI,
_Exception_Handler_Undef_Swi,
NULL);
_CPU_ISR_install_vector(ARM_EXCEPTION_PREF_ABORT,
_Exception_Handler_Abort,
NULL);
_CPU_ISR_install_vector(ARM_EXCEPTION_DATA_ABORT,
_Exception_Handler_Abort,
NULL);
_CPU_ISR_install_vector(ARM_EXCEPTION_FIQ,
_Exception_Handler_Abort,
NULL);
_CPU_ISR_install_vector(ARM_EXCEPTION_IRQ,
_Exception_Handler_Abort,
NULL);
_CPU_ISR_Enable(level);
}

View File

@@ -1,8 +1,12 @@
/* cpu_asm.s
/*
* $Id$
*
* This file contains all assembly code for the ARM implementation
* of RTEMS.
*
* Copyright (c) 2002 by Advent Networks, Inc.
* Jay Monkman <jmonkman@adventnetworks.com>
*
* COPYRIGHT (c) 2000 Canon Research Centre France SA.
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
*
@@ -13,41 +17,33 @@
*/
#include <asm.h>
#include <rtems/score/cpu_asm.h>
/*
* Format of ARM Register structure
*/
.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_FP, 44
.set REG_IP, 48
.set REG_SP, 52
.set REG_LR, 56
.set REG_PC, 60
.set SIZE_REGS, REG_PC + 4
/*
* void _CPU_Context_switch( run_context, heir_context )
* void _CPU_Context_restore( run_context, heir_context )
*
* This routine performs a normal non-FP context.
*
* R0 = run_context R1 = heir_context
*
* R0 = run_context R1 = heir_context
*
* This function copies the current registers to where r0 points, then
* restores the ones from where r1 points.
*
*
* NOTE: The function should be able to only save/restore the registers
* that would be saved by a C function since the others have already
* been saved.
*
* It should also be able to use the stm/ldm instructions.
*
*/
.globl _CPU_Context_switch
_CPU_Context_switch:
/* FIXME: This should use load and store multiple instructions */
/* Start saving context */
str r2, [r0, #REG_R2]
str r3, [r0, #REG_R3]
str r4, [r0, #REG_R4]
@@ -57,9 +53,21 @@ _CPU_Context_switch:
str r8, [r0, #REG_R8]
str r9, [r0, #REG_R9]
str r10, [r0, #REG_R10]
str sp, [r0, #REG_SP]
str lr, [r0, #REG_PC]
str r11, [r0, #REG_R11]
str r12, [r0, #REG_R12]
str sp, [r0, #REG_SP]
str lr, [r0, #REG_PC] /* save LR at PC's location */
mrs r2, cpsr
str r2, [r0, #REG_CPSR]
/* Start restoring context */
ldr r2, [r1, #REG_CPSR]
msr cpsr, r2
ldr r2, [r1, #REG_R2]
ldr r3, [r1, #REG_R3]
ldr r4, [r1, #REG_R4]
@@ -68,25 +76,34 @@ _CPU_Context_switch:
ldr r7, [r1, #REG_R7]
ldr r8, [r1, #REG_R8]
ldr r9, [r1, #REG_R9]
ldr r10, [r1, #REG_R10]
ldr r10, [r1, #REG_R10]
ldr r11, [r1, #REG_R11]
ldr r12, [r1, #REG_R12]
ldr sp, [r1, #REG_SP]
ldr lr, [r1, #REG_PC]
ldr lr, [r1, #REG_PC]
mov pc, lr
/*
* NOTE: May be unnecessary to reload some registers.
*/
/*
* void _CPU_Context_restore( new_context )
*
* This routine performs a normal non-FP context.
* This function copies the restores the registers from where r0 points.
* It must match _CPU_Context_switch()
*
* NOTE: The function should be able to only save/restore the registers
* that would be saved by a C function since the others have already
* been saved.
*
* It should also be able to use the stm/ldm instructions.
*
*/
.globl _CPU_Context_restore
_CPU_Context_restore:
/* FIXME: This should use load and store multiple instructions */
ldr r2, [r0, #REG_CPSR]
msr cpsr, r2
ldr r2, [r0, #REG_R2]
ldr r2, [r0, #REG_R2]
ldr r3, [r0, #REG_R3]
ldr r4, [r0, #REG_R4]
ldr r5, [r0, #REG_R5]
@@ -94,14 +111,19 @@ _CPU_Context_restore:
ldr r7, [r0, #REG_R7]
ldr r8, [r0, #REG_R8]
ldr r9, [r0, #REG_R9]
ldr r10, [r0, #REG_R10]
ldr r10, [r0, #REG_R10]
ldr r11, [r1, #REG_R11]
ldr r12, [r1, #REG_R12]
ldr sp, [r0, #REG_SP]
ldr lr, [r0, #REG_PC]
mov pc, lr
/* FIXME: _Exception_Handler_Undef_Swi is untested */
.globl _Exception_Handler_Undef_Swi
_Exception_Handler_Undef_Swi:
/* FIXME: This should use load and store multiple instructions */
sub r13,r13,#SIZE_REGS
str r0, [r13, #REG_R0]
str r1, [r13, #REG_R1]
@@ -114,8 +136,8 @@ _Exception_Handler_Undef_Swi:
str r8, [r13, #REG_R8]
str r9, [r13, #REG_R9]
str r10, [r13, #REG_R10]
str fp, [r13, #REG_FP]
str ip, [r13, #REG_IP]
str r11, [r13, #REG_R11]
str r12, [r13, #REG_R12]
str sp, [r13, #REG_SP]
str lr, [r13, #REG_LR]
mrs r0, cpsr /* read the status */
@@ -123,7 +145,7 @@ _Exception_Handler_Undef_Swi:
str r0, [r13, #REG_PC] /* we store it in a free place */
mov r0, r13 /* put frame address in r0 (C arg 1) */
ldr r1, =_currentExcHandler
ldr r1, =SWI_Handler
ldr lr, =_go_back_1
ldr pc,[r1] /* call handler */
_go_back_1:
@@ -138,15 +160,17 @@ _go_back_1:
ldr r8, [r13, #REG_R8]
ldr r9, [r13, #REG_R9]
ldr r10, [r13, #REG_R10]
ldr fp, [r13, #REG_FP]
ldr ip, [r13, #REG_IP]
ldr r11, [r13, #REG_R11]
ldr r12, [r13, #REG_R12]
ldr sp, [r13, #REG_SP]
ldr lr, [r13, #REG_LR]
add r13,r13,#SIZE_REGS
movs pc,r14 /* return */
movs pc,r14 /* return */
/* FIXME: _Exception_Handler_Abort is untested */
.globl _Exception_Handler_Abort
_Exception_Handler_Abort:
/* FIXME: This should use load and store multiple instructions */
sub r13,r13,#SIZE_REGS
str r0, [r13, #REG_R0]
str r1, [r13, #REG_R1]
@@ -159,8 +183,8 @@ _Exception_Handler_Abort:
str r8, [r13, #REG_R8]
str r9, [r13, #REG_R9]
str r10, [r13, #REG_R10]
str sp, [r13, #REG_FP]
str lr, [r13, #REG_IP]
str sp, [r13, #REG_R11]
str lr, [r13, #REG_R12]
str lr, [r13, #REG_SP]
str lr, [r13, #REG_LR]
mrs r0, cpsr /* read the status */
@@ -183,11 +207,10 @@ _go_back_2:
ldr r8, [r13, #REG_R8]
ldr r9, [r13, #REG_R9]
ldr r10, [r13, #REG_R10]
ldr sp, [r13, #REG_FP]
ldr lr, [r13, #REG_IP]
ldr sp, [r13, #REG_R11]
ldr lr, [r13, #REG_R12]
ldr lr, [r13, #REG_SP]
ldr lr, [r13, #REG_LR]
add r13,r13,#SIZE_REGS
subs pc,r14,#4 /* return */

View File

@@ -1,12 +1,13 @@
/* no_cpu.h
*
* This file is an example (i.e. "no CPU") of the file which is
* created for each CPU family port of RTEMS.
/*
* $Id$
*
*
* COPYRIGHT (c) 2000 Canon Research Centre France SA.
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
*
* Copyright (c) 2002 Advent Networks, Inc.
* Jay Monkman <jmonkman@adventnetworks.com>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
@@ -28,16 +29,23 @@ extern "C" {
* dependent features are present in a particular member
* of the family.
*/
#if defined(__arm__)
#define CPU_MODEL_NAME "arm"
#define ARM_HAS_FPU 0
#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
#else
#error "Unsupported CPU Model"
# error "Unsupported CPU Model"
#endif
/*

View File

@@ -1,8 +1,10 @@
/* cpu.h
*
* This include file contains information pertaining to the arm
/*
* This include file contains information pertaining to the ARM
* processor.
*
* COPYRIGHT (c) 2002 Advent Networks, Inc.
* Jay Monkman <jmonkman@adventnetworks.com>
*
* COPYRIGHT (c) 2000 Canon Research Centre France SA.
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
*
@@ -10,8 +12,10 @@
* 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 */
#ifndef __CPU_h
#define __CPU_h
@@ -43,7 +47,7 @@ extern "C" {
* one subroutine call is avoided entirely.]
*/
#define CPU_INLINE_ENABLE_DISPATCH FALSE
#define CPU_INLINE_ENABLE_DISPATCH TRUE
/*
* Should the body of the search loops in _Thread_queue_Enqueue_priority
@@ -63,7 +67,7 @@ extern "C" {
* necessary to strike a balance when setting this parameter.
*/
#define CPU_UNROLL_ENQUEUE_PRIORITY FALSE
#define CPU_UNROLL_ENQUEUE_PRIORITY TRUE
/*
* Does RTEMS manage a dedicated interrupt stack in software?
@@ -99,14 +103,14 @@ extern "C" {
*
* If this is TRUE, CPU_ALLOCATE_INTERRUPT_STACK should also be TRUE.
*
* Only one of CPU_HAS_SOFTWARE_INTERRUPT_STACK and
* Only one of CPU_HAS_SOFTWARE_INTERRU
* 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
* procedure on that CPU.
*/
#define CPU_HAS_HARDWARE_INTERRUPT_STACK FALSE
#define CPU_HAS_HARDWARE_INTERRUPT_STACK TRUE
/*
* Does RTEMS allocate a dedicated interrupt stack in the Interrupt Manager?
@@ -118,7 +122,7 @@ extern "C" {
* or CPU_INSTALL_HARDWARE_INTERRUPT_STACK is TRUE.
*/
#define CPU_ALLOCATE_INTERRUPT_STACK FALSE
#define CPU_ALLOCATE_INTERRUPT_STACK TRUE
/*
* Does the RTEMS invoke the user's ISR with the vector number and
@@ -273,8 +277,8 @@ extern "C" {
*/
#define CPU_HAS_OWN_HOST_TO_NETWORK_ROUTINES FALSE
#define CPU_BIG_ENDIAN TRUE
#define CPU_LITTLE_ENDIAN FALSE
#define CPU_BIG_ENDIAN FALSE
#define CPU_LITTLE_ENDIAN TRUE
/*
* The following defines the number of bits actually used in the
@@ -282,7 +286,7 @@ extern "C" {
* CPU interrupt levels is defined by the routine _CPU_ISR_Set_level().
*/
#define CPU_MODES_INTERRUPT_MASK 0x00000001
#define CPU_MODES_INTERRUPT_MASK 0x000000c0
/*
* Processor defined structures
@@ -345,6 +349,7 @@ typedef struct {
unsigned32 register_sp;
unsigned32 register_lr;
unsigned32 register_pc;
unsigned32 register_cpsr;
} Context_Control;
typedef struct {
@@ -476,14 +481,14 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)();
* that a "reasonable" small application should not have any problems.
*/
#define CPU_STACK_MINIMUM_SIZE (1024*4)
#define CPU_STACK_MINIMUM_SIZE (1024*16)
/*
* CPU's worst alignment requirement for data types on a byte boundary. This
* alignment does not take into account the requirements for the stack.
*/
#define CPU_ALIGNMENT 8
#define CPU_ALIGNMENT 4
/*
* This number corresponds to the byte alignment requirement for the
@@ -522,7 +527,7 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)();
* NOTE: This must be a power of 2 either 0 or greater than CPU_ALIGNMENT.
*/
#define CPU_STACK_ALIGNMENT 32
#define CPU_STACK_ALIGNMENT 4
/* ISR handler macros */
@@ -537,14 +542,16 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)();
* level is returned in _level.
*/
#define _CPU_ISR_Disable( _level ) \
{ \
(_level) = 0; \
asm volatile ("MRS r0, cpsr \n" \
"ORR r0, r0, #0xc0 \n" \
"MSR cpsr, r0 \n" \
: : : "r0"); \
}
#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)
/*
* Enable interrupts to the previous level (returned by _CPU_ISR_Disable).
@@ -552,14 +559,17 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)();
* _level is not modified.
*/
#define _CPU_ISR_Enable( _level ) \
{ \
asm volatile ("MRS r0, cpsr \n" \
"AND r0, r0, #0xFFFFFF3F \n" \
"MSR cpsr, r0 \n" \
: : : "r0" ); \
}
#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)
/*
* This temporarily restores the interrupt to _level before immediately
* disabling them again. This is used to divide long RTEMS critical
@@ -567,8 +577,17 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)();
* modified.
*/
#define _CPU_ISR_Flash( _isr_cookie ) \
#define _CPU_ISR_Flash( _level ) \
{ \
int reg1; \
int reg2; \
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)); \
}
/*
@@ -586,8 +605,16 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)();
#define _CPU_ISR_Set_level( new_level ) \
{ \
int reg; \
asm volatile ("MRS %0, cpsr \n" \
"BIC %0, %0, #0xc0 \n" \
"ORR %0, %0, %2 \n" \
"MSR cpsr_c, %0 \n" \
: "=r" (reg) \
: "0" (reg), "r" (new_level)); \
}
unsigned32 _CPU_ISR_Get_level( void );
/* end of ISR handler macros */
@@ -615,12 +642,14 @@ unsigned32 _CPU_ISR_Get_level( void );
* where the PSR contains an enable FPU bit.
*/
#define _CPU_Context_Initialize( _the_context, _stack_base, _size, \
_isr, _entry_point, _is_fp ) \
{ \
(_the_context)->register_sp = ((unsigned32)(_stack_base)) + (_size) ; \
(_the_context)->register_pc = (_entry_point); \
}
void _CPU_Context_Initialize(
Context_Control *the_context,
unsigned32 *stack_base,
unsigned32 size,
unsigned32 new_level,
void *entry_point,
boolean is_fp
);
/*
* This routine is responsible for somehow restarting the currently

View File

@@ -1,69 +1,41 @@
/*
* cpu_asm.h
* $Id$
*
* Very loose template for an include file for the cpu_asm.? file
* if it is implemented as a ".S" file (preprocessed by cpp) instead
* of a ".s" file (preprocessed by gm4 or gasp).
*
* COPYRIGHT (c) 2000 Canon Research Centre France SA.
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
* Copyright (c) 2002 by Advent Networks, Inc.
* Jay Monkman <jmonkman@adventnetworks.com>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* This file is the include file for cpu_asm.S
*
*
*/
#ifndef __CPU_ASM_h
#define __CPU_ASM_h
/* pull in the generated offsets */
#include <rtems/score/offsets.h>
/* 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
/*
* Hardware General Registers
*/
/* put something here */
/*
* Hardware Floating Point Registers
*/
/* put something here */
/*
* Hardware Control Registers
*/
/* put something here */
/*
* Calling Convention
*/
/* put something here */
/*
* Temporary registers
*/
/* put something here */
/*
* Floating Point Registers - SW Conventions
*/
/* put something here */
/*
* Temporary floating point registers
*/
/* put something here */
#endif
/* end of file */