forked from Imagelibrary/rtems
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:
@@ -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>
|
2002-07-05 Joel Sherrill <joel@OARcorp.com>
|
||||||
|
|
||||||
* rtems/score/cpu.h: Filled in something that was marked XXX.
|
* rtems/score/cpu.h: Filled in something that was marked XXX.
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ PREINSTALL_FILES = $(PROJECT_INCLUDE) $(include_HEADERS:%=$(PROJECT_INCLUDE)/%)
|
|||||||
include_rtems_scoredir = $(includedir)/rtems/score
|
include_rtems_scoredir = $(includedir)/rtems/score
|
||||||
include_rtems_score_HEADERS = \
|
include_rtems_score_HEADERS = \
|
||||||
rtems/score/cpu.h \
|
rtems/score/cpu.h \
|
||||||
|
rtems/score/cpu_asm.h \
|
||||||
rtems/score/arm.h \
|
rtems/score/arm.h \
|
||||||
rtems/score/types.h
|
rtems/score/types.h
|
||||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score \
|
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score \
|
||||||
|
|||||||
@@ -5,6 +5,9 @@
|
|||||||
* COPYRIGHT (c) 2000 Canon Research Centre France SA.
|
* COPYRIGHT (c) 2000 Canon Research Centre France SA.
|
||||||
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
|
* 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
|
* The license and distribution terms for this file may be
|
||||||
* found in the file LICENSE in this distribution or at
|
* found in the file LICENSE in this distribution or at
|
||||||
* http://www.OARcorp.com/rtems/license.html.
|
* http://www.OARcorp.com/rtems/license.html.
|
||||||
@@ -25,30 +28,32 @@
|
|||||||
*
|
*
|
||||||
* INPUT PARAMETERS:
|
* INPUT PARAMETERS:
|
||||||
* cpu_table - CPU table to initialize
|
* cpu_table - CPU table to initialize
|
||||||
* thread_dispatch - address of disptaching routine
|
* thread_dispatch - address of ISR disptaching routine (unused)
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
void _CPU_Initialize(
|
void _CPU_Initialize(
|
||||||
rtems_cpu_table *cpu_table,
|
rtems_cpu_table *cpu_table,
|
||||||
void (*thread_dispatch) /* ignored on this CPU */
|
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 )
|
unsigned32 _CPU_ISR_Get_level( void )
|
||||||
{
|
{
|
||||||
/*
|
unsigned32 reg;
|
||||||
* This routine returns the current interrupt level.
|
|
||||||
*/
|
asm volatile ("mrs %0, cpsr \n" \
|
||||||
|
"and %0, %0, #0xc0 \n" \
|
||||||
return 0;
|
: "=r" (reg));
|
||||||
|
|
||||||
|
return reg;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -59,28 +64,48 @@ unsigned32 _CPU_ISR_Get_level( void )
|
|||||||
*
|
*
|
||||||
* Input parameters:
|
* Input parameters:
|
||||||
* vector - interrupt vector number
|
* vector - interrupt vector number
|
||||||
* old_handler - former ISR for this vector number
|
|
||||||
* new_handler - replacement 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
|
* Output parameters: NONE
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void _CPU_ISR_install_vector(
|
void _CPU_ISR_install_vector(
|
||||||
unsigned32 vector,
|
unsigned32 vector,
|
||||||
proc_ptr new_handler,
|
proc_ptr new_handler,
|
||||||
proc_ptr *old_handler
|
proc_ptr *old_handler
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
/* pointer on the redirection table in RAM */
|
/* pointer on the redirection table in RAM */
|
||||||
long *VectorTable = (long *)(MAX_EXCEPTIONS * 4);
|
long *VectorTable = (long *)(MAX_EXCEPTIONS * 4);
|
||||||
|
|
||||||
|
if (old_handler != NULL) {
|
||||||
|
old_handler = *(proc_ptr *)(VectorTable + vector);
|
||||||
|
}
|
||||||
|
|
||||||
if (old_handler != NULL)
|
*(VectorTable + vector) = (long)new_handler ;
|
||||||
old_handler = *(proc_ptr *)(VectorTable + vector);
|
|
||||||
*(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
|
/*PAGE
|
||||||
*
|
*
|
||||||
* _CPU_Install_interrupt_stack
|
* _CPU_Install_interrupt_stack
|
||||||
@@ -88,6 +113,32 @@ void _CPU_ISR_install_vector(
|
|||||||
|
|
||||||
void _CPU_Install_interrupt_stack( void )
|
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
|
/*PAGE
|
||||||
@@ -110,60 +161,82 @@ void _CPU_Install_interrupt_stack( void )
|
|||||||
void _CPU_Thread_Idle_body( void )
|
void _CPU_Thread_Idle_body( void )
|
||||||
{
|
{
|
||||||
|
|
||||||
while(1);
|
while(1); /* FIXME: finish this */
|
||||||
/* insert your "halt" instruction here */ ;
|
/* insert your "halt" instruction here */ ;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _defaultExcHandler (CPU_Exception_frame *ctx)
|
void _defaultExcHandler (CPU_Exception_frame *ctx)
|
||||||
{
|
{
|
||||||
printk("----------------------------------------------------------\n");
|
printk("\n\r");
|
||||||
printk("Exception %d caught at PC %x by thread %d\n",
|
printk("----------------------------------------------------------\n\r");
|
||||||
ctx->register_pc, ctx->register_lr - 4,
|
printk("Exception 0x%x caught at PC 0x%x by thread %d\n",
|
||||||
_Thread_Executing->Object.id);
|
ctx->register_pc, ctx->register_lr - 4,
|
||||||
printk("----------------------------------------------------------\n");
|
_Thread_Executing->Object.id);
|
||||||
printk("Processor execution context at time of the fault was :\n");
|
printk("----------------------------------------------------------\n\r");
|
||||||
printk("----------------------------------------------------------\n");
|
printk("Processor execution context at time of the fault was :\n\r");
|
||||||
printk(" r0 = %x r1 = %x r2 = %x r3 = %x\n",
|
printk("----------------------------------------------------------\n\r");
|
||||||
ctx->register_r0, ctx->register_r1, ctx->register_r2, ctx->register_r3);
|
printk(" r0 = %8x r1 = %8x r2 = %8x r3 = %8x\n\r",
|
||||||
printk(" r4 = %x r5 = %x r6 = %x r7 = %x\n",
|
ctx->register_r0, ctx->register_r1,
|
||||||
ctx->register_r4, ctx->register_r5, ctx->register_r6, ctx->register_r7);
|
ctx->register_r2, ctx->register_r3);
|
||||||
printk(" r8 = %x r9 = %x r10 = %x\n",
|
printk(" r4 = %8x r5 = %8x r6 = %8x r7 = %8x\n\r",
|
||||||
ctx->register_r8, ctx->register_r9, ctx->register_r10);
|
ctx->register_r4, ctx->register_r5,
|
||||||
printk(" fp = %x ip = %x sp = %x pc = %x\n",
|
ctx->register_r6, ctx->register_r7);
|
||||||
ctx->register_fp, ctx->register_ip, ctx->register_sp, ctx->register_lr - 4);
|
printk(" r8 = %8x r9 = %8x r10 = %8x\n\r",
|
||||||
printk("----------------------------------------------------------\n");
|
ctx->register_r8, ctx->register_r9, ctx->register_r10);
|
||||||
|
printk(" fp = %8x ip = %8x sp = %8x pc = %8x\n\r",
|
||||||
if (_ISR_Nest_level > 0) {
|
ctx->register_fp, ctx->register_ip,
|
||||||
/*
|
ctx->register_sp, ctx->register_lr - 4);
|
||||||
* In this case we shall not delete the task interrupted as
|
printk("----------------------------------------------------------\n\r");
|
||||||
* it has nothing to do with the fault. We cannot return either
|
|
||||||
* because the eip points to the faulty instruction so...
|
if (_ISR_Nest_level > 0) {
|
||||||
*/
|
/*
|
||||||
printk("Exception while executing ISR!!!. System locked\n");
|
* In this case we shall not delete the task interrupted as
|
||||||
while(1);
|
* it has nothing to do with the fault. We cannot return either
|
||||||
}
|
* because the eip points to the faulty instruction so...
|
||||||
else {
|
*/
|
||||||
printk(" ************ FAULTY THREAD WILL BE DELETED **************\n");
|
printk("Exception while executing ISR!!!. System locked\n\r");
|
||||||
rtems_task_delete(_Thread_Executing->Object.id);
|
while(1);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
printk("*********** FAULTY THREAD WILL BE DELETED **************\n\r");
|
||||||
|
rtems_task_delete(_Thread_Executing->Object.id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cpuExcHandlerType _currentExcHandler = _defaultExcHandler;
|
cpuExcHandlerType _currentExcHandler = _defaultExcHandler;
|
||||||
|
|
||||||
extern void _Exception_Handler_Undef_Swi();
|
extern void _Exception_Handler_Undef_Swi();
|
||||||
extern void _Exception_Handler_Abort();
|
extern void _Exception_Handler_Abort();
|
||||||
|
/* FIXME: put comments here */
|
||||||
void rtems_exception_init_mngt()
|
void rtems_exception_init_mngt()
|
||||||
{
|
{
|
||||||
ISR_Level level;
|
ISR_Level level;
|
||||||
|
|
||||||
_CPU_ISR_Disable(level);
|
_CPU_ISR_Disable(level);
|
||||||
_CPU_ISR_install_vector(ARM_EXCEPTION_UNDEF, _Exception_Handler_Undef_Swi, NULL);
|
_CPU_ISR_install_vector(ARM_EXCEPTION_UNDEF,
|
||||||
_CPU_ISR_install_vector(ARM_EXCEPTION_SWI, _Exception_Handler_Undef_Swi, NULL);
|
_Exception_Handler_Undef_Swi,
|
||||||
_CPU_ISR_install_vector(ARM_EXCEPTION_PREF_ABORT, _Exception_Handler_Abort , NULL);
|
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_SWI,
|
||||||
_CPU_ISR_install_vector(ARM_EXCEPTION_IRQ, _Exception_Handler_Abort , NULL);
|
_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);
|
_CPU_ISR_Enable(level);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,12 @@
|
|||||||
/* cpu_asm.s
|
/*
|
||||||
|
* $Id$
|
||||||
*
|
*
|
||||||
* This file contains all assembly code for the ARM implementation
|
* This file contains all assembly code for the ARM implementation
|
||||||
* of RTEMS.
|
* of RTEMS.
|
||||||
*
|
*
|
||||||
|
* Copyright (c) 2002 by Advent Networks, Inc.
|
||||||
|
* Jay Monkman <jmonkman@adventnetworks.com>
|
||||||
|
*
|
||||||
* COPYRIGHT (c) 2000 Canon Research Centre France SA.
|
* COPYRIGHT (c) 2000 Canon Research Centre France SA.
|
||||||
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
|
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
|
||||||
*
|
*
|
||||||
@@ -13,41 +17,33 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <asm.h>
|
#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_switch( run_context, heir_context )
|
||||||
|
* void _CPU_Context_restore( run_context, heir_context )
|
||||||
*
|
*
|
||||||
* This routine performs a normal non-FP 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
|
.globl _CPU_Context_switch
|
||||||
|
|
||||||
_CPU_Context_switch:
|
_CPU_Context_switch:
|
||||||
|
/* FIXME: This should use load and store multiple instructions */
|
||||||
|
/* Start saving context */
|
||||||
str r2, [r0, #REG_R2]
|
str r2, [r0, #REG_R2]
|
||||||
str r3, [r0, #REG_R3]
|
str r3, [r0, #REG_R3]
|
||||||
str r4, [r0, #REG_R4]
|
str r4, [r0, #REG_R4]
|
||||||
@@ -57,9 +53,21 @@ _CPU_Context_switch:
|
|||||||
str r8, [r0, #REG_R8]
|
str r8, [r0, #REG_R8]
|
||||||
str r9, [r0, #REG_R9]
|
str r9, [r0, #REG_R9]
|
||||||
str r10, [r0, #REG_R10]
|
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 r2, [r1, #REG_R2]
|
||||||
ldr r3, [r1, #REG_R3]
|
ldr r3, [r1, #REG_R3]
|
||||||
ldr r4, [r1, #REG_R4]
|
ldr r4, [r1, #REG_R4]
|
||||||
@@ -68,25 +76,34 @@ _CPU_Context_switch:
|
|||||||
ldr r7, [r1, #REG_R7]
|
ldr r7, [r1, #REG_R7]
|
||||||
ldr r8, [r1, #REG_R8]
|
ldr r8, [r1, #REG_R8]
|
||||||
ldr r9, [r1, #REG_R9]
|
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 sp, [r1, #REG_SP]
|
||||||
ldr lr, [r1, #REG_PC]
|
ldr lr, [r1, #REG_PC]
|
||||||
mov pc, lr
|
mov pc, lr
|
||||||
|
|
||||||
/*
|
|
||||||
* NOTE: May be unnecessary to reload some registers.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* void _CPU_Context_restore( new_context )
|
* 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
|
.globl _CPU_Context_restore
|
||||||
|
|
||||||
_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 r3, [r0, #REG_R3]
|
||||||
ldr r4, [r0, #REG_R4]
|
ldr r4, [r0, #REG_R4]
|
||||||
ldr r5, [r0, #REG_R5]
|
ldr r5, [r0, #REG_R5]
|
||||||
@@ -94,14 +111,19 @@ _CPU_Context_restore:
|
|||||||
ldr r7, [r0, #REG_R7]
|
ldr r7, [r0, #REG_R7]
|
||||||
ldr r8, [r0, #REG_R8]
|
ldr r8, [r0, #REG_R8]
|
||||||
ldr r9, [r0, #REG_R9]
|
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 sp, [r0, #REG_SP]
|
||||||
ldr lr, [r0, #REG_PC]
|
ldr lr, [r0, #REG_PC]
|
||||||
mov pc, lr
|
mov pc, lr
|
||||||
|
|
||||||
|
|
||||||
|
/* FIXME: _Exception_Handler_Undef_Swi is untested */
|
||||||
.globl _Exception_Handler_Undef_Swi
|
.globl _Exception_Handler_Undef_Swi
|
||||||
_Exception_Handler_Undef_Swi:
|
_Exception_Handler_Undef_Swi:
|
||||||
|
/* FIXME: This should use load and store multiple instructions */
|
||||||
sub r13,r13,#SIZE_REGS
|
sub r13,r13,#SIZE_REGS
|
||||||
str r0, [r13, #REG_R0]
|
str r0, [r13, #REG_R0]
|
||||||
str r1, [r13, #REG_R1]
|
str r1, [r13, #REG_R1]
|
||||||
@@ -114,8 +136,8 @@ _Exception_Handler_Undef_Swi:
|
|||||||
str r8, [r13, #REG_R8]
|
str r8, [r13, #REG_R8]
|
||||||
str r9, [r13, #REG_R9]
|
str r9, [r13, #REG_R9]
|
||||||
str r10, [r13, #REG_R10]
|
str r10, [r13, #REG_R10]
|
||||||
str fp, [r13, #REG_FP]
|
str r11, [r13, #REG_R11]
|
||||||
str ip, [r13, #REG_IP]
|
str r12, [r13, #REG_R12]
|
||||||
str sp, [r13, #REG_SP]
|
str sp, [r13, #REG_SP]
|
||||||
str lr, [r13, #REG_LR]
|
str lr, [r13, #REG_LR]
|
||||||
mrs r0, cpsr /* read the status */
|
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 */
|
str r0, [r13, #REG_PC] /* we store it in a free place */
|
||||||
mov r0, r13 /* put frame address in r0 (C arg 1) */
|
mov r0, r13 /* put frame address in r0 (C arg 1) */
|
||||||
|
|
||||||
ldr r1, =_currentExcHandler
|
ldr r1, =SWI_Handler
|
||||||
ldr lr, =_go_back_1
|
ldr lr, =_go_back_1
|
||||||
ldr pc,[r1] /* call handler */
|
ldr pc,[r1] /* call handler */
|
||||||
_go_back_1:
|
_go_back_1:
|
||||||
@@ -138,15 +160,17 @@ _go_back_1:
|
|||||||
ldr r8, [r13, #REG_R8]
|
ldr r8, [r13, #REG_R8]
|
||||||
ldr r9, [r13, #REG_R9]
|
ldr r9, [r13, #REG_R9]
|
||||||
ldr r10, [r13, #REG_R10]
|
ldr r10, [r13, #REG_R10]
|
||||||
ldr fp, [r13, #REG_FP]
|
ldr r11, [r13, #REG_R11]
|
||||||
ldr ip, [r13, #REG_IP]
|
ldr r12, [r13, #REG_R12]
|
||||||
ldr sp, [r13, #REG_SP]
|
ldr sp, [r13, #REG_SP]
|
||||||
ldr lr, [r13, #REG_LR]
|
ldr lr, [r13, #REG_LR]
|
||||||
add r13,r13,#SIZE_REGS
|
add r13,r13,#SIZE_REGS
|
||||||
movs pc,r14 /* return */
|
movs pc,r14 /* return */
|
||||||
|
|
||||||
|
/* FIXME: _Exception_Handler_Abort is untested */
|
||||||
.globl _Exception_Handler_Abort
|
.globl _Exception_Handler_Abort
|
||||||
_Exception_Handler_Abort:
|
_Exception_Handler_Abort:
|
||||||
|
/* FIXME: This should use load and store multiple instructions */
|
||||||
sub r13,r13,#SIZE_REGS
|
sub r13,r13,#SIZE_REGS
|
||||||
str r0, [r13, #REG_R0]
|
str r0, [r13, #REG_R0]
|
||||||
str r1, [r13, #REG_R1]
|
str r1, [r13, #REG_R1]
|
||||||
@@ -159,8 +183,8 @@ _Exception_Handler_Abort:
|
|||||||
str r8, [r13, #REG_R8]
|
str r8, [r13, #REG_R8]
|
||||||
str r9, [r13, #REG_R9]
|
str r9, [r13, #REG_R9]
|
||||||
str r10, [r13, #REG_R10]
|
str r10, [r13, #REG_R10]
|
||||||
str sp, [r13, #REG_FP]
|
str sp, [r13, #REG_R11]
|
||||||
str lr, [r13, #REG_IP]
|
str lr, [r13, #REG_R12]
|
||||||
str lr, [r13, #REG_SP]
|
str lr, [r13, #REG_SP]
|
||||||
str lr, [r13, #REG_LR]
|
str lr, [r13, #REG_LR]
|
||||||
mrs r0, cpsr /* read the status */
|
mrs r0, cpsr /* read the status */
|
||||||
@@ -183,11 +207,10 @@ _go_back_2:
|
|||||||
ldr r8, [r13, #REG_R8]
|
ldr r8, [r13, #REG_R8]
|
||||||
ldr r9, [r13, #REG_R9]
|
ldr r9, [r13, #REG_R9]
|
||||||
ldr r10, [r13, #REG_R10]
|
ldr r10, [r13, #REG_R10]
|
||||||
ldr sp, [r13, #REG_FP]
|
ldr sp, [r13, #REG_R11]
|
||||||
ldr lr, [r13, #REG_IP]
|
ldr lr, [r13, #REG_R12]
|
||||||
ldr lr, [r13, #REG_SP]
|
ldr lr, [r13, #REG_SP]
|
||||||
ldr lr, [r13, #REG_LR]
|
ldr lr, [r13, #REG_LR]
|
||||||
add r13,r13,#SIZE_REGS
|
add r13,r13,#SIZE_REGS
|
||||||
subs pc,r14,#4 /* return */
|
subs pc,r14,#4 /* return */
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
/* no_cpu.h
|
/*
|
||||||
*
|
* $Id$
|
||||||
* This file is an example (i.e. "no CPU") of the file which is
|
|
||||||
* created for each CPU family port of RTEMS.
|
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* COPYRIGHT (c) 2000 Canon Research Centre France SA.
|
* COPYRIGHT (c) 2000 Canon Research Centre France SA.
|
||||||
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
|
* 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
|
* The license and distribution terms for this file may be
|
||||||
* found in the file LICENSE in this distribution or at
|
* found in the file LICENSE in this distribution or at
|
||||||
* http://www.OARcorp.com/rtems/license.html.
|
* http://www.OARcorp.com/rtems/license.html.
|
||||||
@@ -28,16 +29,23 @@ extern "C" {
|
|||||||
* dependent features are present in a particular member
|
* dependent features are present in a particular member
|
||||||
* of the family.
|
* of the family.
|
||||||
*/
|
*/
|
||||||
|
#if defined(__arm9__)
|
||||||
#if defined(__arm__)
|
# define CPU_MODEL_NAME "arm9"
|
||||||
|
# define ARM_HAS_FPU 0
|
||||||
#define CPU_MODEL_NAME "arm"
|
#elif defined(__arm9tdmi__)
|
||||||
#define ARM_HAS_FPU 0
|
# 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
|
#else
|
||||||
|
# error "Unsupported CPU Model"
|
||||||
#error "Unsupported CPU Model"
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -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.
|
* processor.
|
||||||
*
|
*
|
||||||
|
* COPYRIGHT (c) 2002 Advent Networks, Inc.
|
||||||
|
* Jay Monkman <jmonkman@adventnetworks.com>
|
||||||
|
*
|
||||||
* COPYRIGHT (c) 2000 Canon Research Centre France SA.
|
* COPYRIGHT (c) 2000 Canon Research Centre France SA.
|
||||||
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
|
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
|
||||||
*
|
*
|
||||||
@@ -10,8 +12,10 @@
|
|||||||
* found in the file LICENSE in this distribution or at
|
* found in the file LICENSE in this distribution or at
|
||||||
* http://www.OARcorp.com/rtems/license.html.
|
* http://www.OARcorp.com/rtems/license.html.
|
||||||
*
|
*
|
||||||
|
* $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* FIXME: finish commenting/cleaning up this file */
|
||||||
#ifndef __CPU_h
|
#ifndef __CPU_h
|
||||||
#define __CPU_h
|
#define __CPU_h
|
||||||
|
|
||||||
@@ -43,7 +47,7 @@ extern "C" {
|
|||||||
* one subroutine call is avoided entirely.]
|
* 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
|
* 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.
|
* 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?
|
* 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.
|
* 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
|
* CPU_HAS_HARDWARE_INTERRUPT_STACK should be set to TRUE. It is
|
||||||
* possible that both are FALSE for a particular CPU. Although it
|
* possible that both are FALSE for a particular CPU. Although it
|
||||||
* is unclear what that would imply about the interrupt processing
|
* is unclear what that would imply about the interrupt processing
|
||||||
* procedure on that CPU.
|
* 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?
|
* 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.
|
* 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
|
* 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_HAS_OWN_HOST_TO_NETWORK_ROUTINES FALSE
|
||||||
#define CPU_BIG_ENDIAN TRUE
|
#define CPU_BIG_ENDIAN FALSE
|
||||||
#define CPU_LITTLE_ENDIAN FALSE
|
#define CPU_LITTLE_ENDIAN TRUE
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The following defines the number of bits actually used in the
|
* 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().
|
* 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
|
* Processor defined structures
|
||||||
@@ -345,6 +349,7 @@ typedef struct {
|
|||||||
unsigned32 register_sp;
|
unsigned32 register_sp;
|
||||||
unsigned32 register_lr;
|
unsigned32 register_lr;
|
||||||
unsigned32 register_pc;
|
unsigned32 register_pc;
|
||||||
|
unsigned32 register_cpsr;
|
||||||
} Context_Control;
|
} Context_Control;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -476,14 +481,14 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)();
|
|||||||
* that a "reasonable" small application should not have any problems.
|
* 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
|
* CPU's worst alignment requirement for data types on a byte boundary. This
|
||||||
* alignment does not take into account the requirements for the stack.
|
* 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
|
* 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.
|
* 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 */
|
/* ISR handler macros */
|
||||||
|
|
||||||
@@ -537,14 +542,16 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)();
|
|||||||
* level is returned in _level.
|
* level is returned in _level.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define _CPU_ISR_Disable( _level ) \
|
#define _CPU_ISR_Disable( _level ) \
|
||||||
{ \
|
do { \
|
||||||
(_level) = 0; \
|
int reg; \
|
||||||
asm volatile ("MRS r0, cpsr \n" \
|
asm volatile ("MRS %0, cpsr \n" \
|
||||||
"ORR r0, r0, #0xc0 \n" \
|
"ORR %1, %0, #0xc0 \n" \
|
||||||
"MSR cpsr, r0 \n" \
|
"MSR cpsr, %1 \n" \
|
||||||
: : : "r0"); \
|
"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).
|
* 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.
|
* _level is not modified.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define _CPU_ISR_Enable( _level ) \
|
#define _CPU_ISR_Enable( _level ) \
|
||||||
{ \
|
do { \
|
||||||
asm volatile ("MRS r0, cpsr \n" \
|
int reg; \
|
||||||
"AND r0, r0, #0xFFFFFF3F \n" \
|
asm volatile ("MRS %0, cpsr \n" \
|
||||||
"MSR cpsr, r0 \n" \
|
"BIC %0, %0, #0xc0 \n" \
|
||||||
: : : "r0" ); \
|
"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
|
* This temporarily restores the interrupt to _level before immediately
|
||||||
* disabling them again. This is used to divide long RTEMS critical
|
* disabling them again. This is used to divide long RTEMS critical
|
||||||
@@ -567,8 +577,17 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)();
|
|||||||
* modified.
|
* 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 ) \
|
#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 );
|
unsigned32 _CPU_ISR_Get_level( void );
|
||||||
|
|
||||||
/* end of ISR handler macros */
|
/* end of ISR handler macros */
|
||||||
@@ -615,12 +642,14 @@ unsigned32 _CPU_ISR_Get_level( void );
|
|||||||
* where the PSR contains an enable FPU bit.
|
* where the PSR contains an enable FPU bit.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define _CPU_Context_Initialize( _the_context, _stack_base, _size, \
|
void _CPU_Context_Initialize(
|
||||||
_isr, _entry_point, _is_fp ) \
|
Context_Control *the_context,
|
||||||
{ \
|
unsigned32 *stack_base,
|
||||||
(_the_context)->register_sp = ((unsigned32)(_stack_base)) + (_size) ; \
|
unsigned32 size,
|
||||||
(_the_context)->register_pc = (_entry_point); \
|
unsigned32 new_level,
|
||||||
}
|
void *entry_point,
|
||||||
|
boolean is_fp
|
||||||
|
);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This routine is responsible for somehow restarting the currently
|
* This routine is responsible for somehow restarting the currently
|
||||||
|
|||||||
@@ -1,69 +1,41 @@
|
|||||||
/*
|
/*
|
||||||
* cpu_asm.h
|
* $Id$
|
||||||
*
|
*
|
||||||
* Very loose template for an include file for the cpu_asm.? file
|
* Copyright (c) 2002 by Advent Networks, Inc.
|
||||||
* if it is implemented as a ".S" file (preprocessed by cpp) instead
|
* Jay Monkman <jmonkman@adventnetworks.com>
|
||||||
* of a ".s" file (preprocessed by gm4 or gasp).
|
|
||||||
*
|
|
||||||
* COPYRIGHT (c) 2000 Canon Research Centre France SA.
|
|
||||||
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
|
|
||||||
*
|
*
|
||||||
* The license and distribution terms for this file may be
|
* The license and distribution terms for this file may be
|
||||||
* found in the file LICENSE in this distribution or at
|
* found in the file LICENSE in this distribution or at
|
||||||
* http://www.OARcorp.com/rtems/license.html.
|
* http://www.OARcorp.com/rtems/license.html.
|
||||||
*
|
*
|
||||||
|
* This file is the include file for cpu_asm.S
|
||||||
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __CPU_ASM_h
|
#ifndef __CPU_ASM_h
|
||||||
#define __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
|
#endif
|
||||||
|
|
||||||
/* end of 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>
|
2002-07-05 Joel Sherrill <joel@OARcorp.com>
|
||||||
|
|
||||||
* rtems/score/cpu.h: Filled in something that was marked XXX.
|
* rtems/score/cpu.h: Filled in something that was marked XXX.
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ PREINSTALL_FILES = $(PROJECT_INCLUDE) $(include_HEADERS:%=$(PROJECT_INCLUDE)/%)
|
|||||||
include_rtems_scoredir = $(includedir)/rtems/score
|
include_rtems_scoredir = $(includedir)/rtems/score
|
||||||
include_rtems_score_HEADERS = \
|
include_rtems_score_HEADERS = \
|
||||||
rtems/score/cpu.h \
|
rtems/score/cpu.h \
|
||||||
|
rtems/score/cpu_asm.h \
|
||||||
rtems/score/arm.h \
|
rtems/score/arm.h \
|
||||||
rtems/score/types.h
|
rtems/score/types.h
|
||||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score \
|
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score \
|
||||||
|
|||||||
@@ -5,6 +5,9 @@
|
|||||||
* COPYRIGHT (c) 2000 Canon Research Centre France SA.
|
* COPYRIGHT (c) 2000 Canon Research Centre France SA.
|
||||||
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
|
* 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
|
* The license and distribution terms for this file may be
|
||||||
* found in the file LICENSE in this distribution or at
|
* found in the file LICENSE in this distribution or at
|
||||||
* http://www.OARcorp.com/rtems/license.html.
|
* http://www.OARcorp.com/rtems/license.html.
|
||||||
@@ -25,30 +28,32 @@
|
|||||||
*
|
*
|
||||||
* INPUT PARAMETERS:
|
* INPUT PARAMETERS:
|
||||||
* cpu_table - CPU table to initialize
|
* cpu_table - CPU table to initialize
|
||||||
* thread_dispatch - address of disptaching routine
|
* thread_dispatch - address of ISR disptaching routine (unused)
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
void _CPU_Initialize(
|
void _CPU_Initialize(
|
||||||
rtems_cpu_table *cpu_table,
|
rtems_cpu_table *cpu_table,
|
||||||
void (*thread_dispatch) /* ignored on this CPU */
|
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 )
|
unsigned32 _CPU_ISR_Get_level( void )
|
||||||
{
|
{
|
||||||
/*
|
unsigned32 reg;
|
||||||
* This routine returns the current interrupt level.
|
|
||||||
*/
|
asm volatile ("mrs %0, cpsr \n" \
|
||||||
|
"and %0, %0, #0xc0 \n" \
|
||||||
return 0;
|
: "=r" (reg));
|
||||||
|
|
||||||
|
return reg;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -59,28 +64,48 @@ unsigned32 _CPU_ISR_Get_level( void )
|
|||||||
*
|
*
|
||||||
* Input parameters:
|
* Input parameters:
|
||||||
* vector - interrupt vector number
|
* vector - interrupt vector number
|
||||||
* old_handler - former ISR for this vector number
|
|
||||||
* new_handler - replacement 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
|
* Output parameters: NONE
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void _CPU_ISR_install_vector(
|
void _CPU_ISR_install_vector(
|
||||||
unsigned32 vector,
|
unsigned32 vector,
|
||||||
proc_ptr new_handler,
|
proc_ptr new_handler,
|
||||||
proc_ptr *old_handler
|
proc_ptr *old_handler
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
/* pointer on the redirection table in RAM */
|
/* pointer on the redirection table in RAM */
|
||||||
long *VectorTable = (long *)(MAX_EXCEPTIONS * 4);
|
long *VectorTable = (long *)(MAX_EXCEPTIONS * 4);
|
||||||
|
|
||||||
|
if (old_handler != NULL) {
|
||||||
|
old_handler = *(proc_ptr *)(VectorTable + vector);
|
||||||
|
}
|
||||||
|
|
||||||
if (old_handler != NULL)
|
*(VectorTable + vector) = (long)new_handler ;
|
||||||
old_handler = *(proc_ptr *)(VectorTable + vector);
|
|
||||||
*(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
|
/*PAGE
|
||||||
*
|
*
|
||||||
* _CPU_Install_interrupt_stack
|
* _CPU_Install_interrupt_stack
|
||||||
@@ -88,6 +113,32 @@ void _CPU_ISR_install_vector(
|
|||||||
|
|
||||||
void _CPU_Install_interrupt_stack( void )
|
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
|
/*PAGE
|
||||||
@@ -110,60 +161,82 @@ void _CPU_Install_interrupt_stack( void )
|
|||||||
void _CPU_Thread_Idle_body( void )
|
void _CPU_Thread_Idle_body( void )
|
||||||
{
|
{
|
||||||
|
|
||||||
while(1);
|
while(1); /* FIXME: finish this */
|
||||||
/* insert your "halt" instruction here */ ;
|
/* insert your "halt" instruction here */ ;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _defaultExcHandler (CPU_Exception_frame *ctx)
|
void _defaultExcHandler (CPU_Exception_frame *ctx)
|
||||||
{
|
{
|
||||||
printk("----------------------------------------------------------\n");
|
printk("\n\r");
|
||||||
printk("Exception %d caught at PC %x by thread %d\n",
|
printk("----------------------------------------------------------\n\r");
|
||||||
ctx->register_pc, ctx->register_lr - 4,
|
printk("Exception 0x%x caught at PC 0x%x by thread %d\n",
|
||||||
_Thread_Executing->Object.id);
|
ctx->register_pc, ctx->register_lr - 4,
|
||||||
printk("----------------------------------------------------------\n");
|
_Thread_Executing->Object.id);
|
||||||
printk("Processor execution context at time of the fault was :\n");
|
printk("----------------------------------------------------------\n\r");
|
||||||
printk("----------------------------------------------------------\n");
|
printk("Processor execution context at time of the fault was :\n\r");
|
||||||
printk(" r0 = %x r1 = %x r2 = %x r3 = %x\n",
|
printk("----------------------------------------------------------\n\r");
|
||||||
ctx->register_r0, ctx->register_r1, ctx->register_r2, ctx->register_r3);
|
printk(" r0 = %8x r1 = %8x r2 = %8x r3 = %8x\n\r",
|
||||||
printk(" r4 = %x r5 = %x r6 = %x r7 = %x\n",
|
ctx->register_r0, ctx->register_r1,
|
||||||
ctx->register_r4, ctx->register_r5, ctx->register_r6, ctx->register_r7);
|
ctx->register_r2, ctx->register_r3);
|
||||||
printk(" r8 = %x r9 = %x r10 = %x\n",
|
printk(" r4 = %8x r5 = %8x r6 = %8x r7 = %8x\n\r",
|
||||||
ctx->register_r8, ctx->register_r9, ctx->register_r10);
|
ctx->register_r4, ctx->register_r5,
|
||||||
printk(" fp = %x ip = %x sp = %x pc = %x\n",
|
ctx->register_r6, ctx->register_r7);
|
||||||
ctx->register_fp, ctx->register_ip, ctx->register_sp, ctx->register_lr - 4);
|
printk(" r8 = %8x r9 = %8x r10 = %8x\n\r",
|
||||||
printk("----------------------------------------------------------\n");
|
ctx->register_r8, ctx->register_r9, ctx->register_r10);
|
||||||
|
printk(" fp = %8x ip = %8x sp = %8x pc = %8x\n\r",
|
||||||
if (_ISR_Nest_level > 0) {
|
ctx->register_fp, ctx->register_ip,
|
||||||
/*
|
ctx->register_sp, ctx->register_lr - 4);
|
||||||
* In this case we shall not delete the task interrupted as
|
printk("----------------------------------------------------------\n\r");
|
||||||
* it has nothing to do with the fault. We cannot return either
|
|
||||||
* because the eip points to the faulty instruction so...
|
if (_ISR_Nest_level > 0) {
|
||||||
*/
|
/*
|
||||||
printk("Exception while executing ISR!!!. System locked\n");
|
* In this case we shall not delete the task interrupted as
|
||||||
while(1);
|
* it has nothing to do with the fault. We cannot return either
|
||||||
}
|
* because the eip points to the faulty instruction so...
|
||||||
else {
|
*/
|
||||||
printk(" ************ FAULTY THREAD WILL BE DELETED **************\n");
|
printk("Exception while executing ISR!!!. System locked\n\r");
|
||||||
rtems_task_delete(_Thread_Executing->Object.id);
|
while(1);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
printk("*********** FAULTY THREAD WILL BE DELETED **************\n\r");
|
||||||
|
rtems_task_delete(_Thread_Executing->Object.id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cpuExcHandlerType _currentExcHandler = _defaultExcHandler;
|
cpuExcHandlerType _currentExcHandler = _defaultExcHandler;
|
||||||
|
|
||||||
extern void _Exception_Handler_Undef_Swi();
|
extern void _Exception_Handler_Undef_Swi();
|
||||||
extern void _Exception_Handler_Abort();
|
extern void _Exception_Handler_Abort();
|
||||||
|
/* FIXME: put comments here */
|
||||||
void rtems_exception_init_mngt()
|
void rtems_exception_init_mngt()
|
||||||
{
|
{
|
||||||
ISR_Level level;
|
ISR_Level level;
|
||||||
|
|
||||||
_CPU_ISR_Disable(level);
|
_CPU_ISR_Disable(level);
|
||||||
_CPU_ISR_install_vector(ARM_EXCEPTION_UNDEF, _Exception_Handler_Undef_Swi, NULL);
|
_CPU_ISR_install_vector(ARM_EXCEPTION_UNDEF,
|
||||||
_CPU_ISR_install_vector(ARM_EXCEPTION_SWI, _Exception_Handler_Undef_Swi, NULL);
|
_Exception_Handler_Undef_Swi,
|
||||||
_CPU_ISR_install_vector(ARM_EXCEPTION_PREF_ABORT, _Exception_Handler_Abort , NULL);
|
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_SWI,
|
||||||
_CPU_ISR_install_vector(ARM_EXCEPTION_IRQ, _Exception_Handler_Abort , NULL);
|
_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);
|
_CPU_ISR_Enable(level);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,12 @@
|
|||||||
/* cpu_asm.s
|
/*
|
||||||
|
* $Id$
|
||||||
*
|
*
|
||||||
* This file contains all assembly code for the ARM implementation
|
* This file contains all assembly code for the ARM implementation
|
||||||
* of RTEMS.
|
* of RTEMS.
|
||||||
*
|
*
|
||||||
|
* Copyright (c) 2002 by Advent Networks, Inc.
|
||||||
|
* Jay Monkman <jmonkman@adventnetworks.com>
|
||||||
|
*
|
||||||
* COPYRIGHT (c) 2000 Canon Research Centre France SA.
|
* COPYRIGHT (c) 2000 Canon Research Centre France SA.
|
||||||
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
|
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
|
||||||
*
|
*
|
||||||
@@ -13,41 +17,33 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <asm.h>
|
#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_switch( run_context, heir_context )
|
||||||
|
* void _CPU_Context_restore( run_context, heir_context )
|
||||||
*
|
*
|
||||||
* This routine performs a normal non-FP 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
|
.globl _CPU_Context_switch
|
||||||
|
|
||||||
_CPU_Context_switch:
|
_CPU_Context_switch:
|
||||||
|
/* FIXME: This should use load and store multiple instructions */
|
||||||
|
/* Start saving context */
|
||||||
str r2, [r0, #REG_R2]
|
str r2, [r0, #REG_R2]
|
||||||
str r3, [r0, #REG_R3]
|
str r3, [r0, #REG_R3]
|
||||||
str r4, [r0, #REG_R4]
|
str r4, [r0, #REG_R4]
|
||||||
@@ -57,9 +53,21 @@ _CPU_Context_switch:
|
|||||||
str r8, [r0, #REG_R8]
|
str r8, [r0, #REG_R8]
|
||||||
str r9, [r0, #REG_R9]
|
str r9, [r0, #REG_R9]
|
||||||
str r10, [r0, #REG_R10]
|
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 r2, [r1, #REG_R2]
|
||||||
ldr r3, [r1, #REG_R3]
|
ldr r3, [r1, #REG_R3]
|
||||||
ldr r4, [r1, #REG_R4]
|
ldr r4, [r1, #REG_R4]
|
||||||
@@ -68,25 +76,34 @@ _CPU_Context_switch:
|
|||||||
ldr r7, [r1, #REG_R7]
|
ldr r7, [r1, #REG_R7]
|
||||||
ldr r8, [r1, #REG_R8]
|
ldr r8, [r1, #REG_R8]
|
||||||
ldr r9, [r1, #REG_R9]
|
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 sp, [r1, #REG_SP]
|
||||||
ldr lr, [r1, #REG_PC]
|
ldr lr, [r1, #REG_PC]
|
||||||
mov pc, lr
|
mov pc, lr
|
||||||
|
|
||||||
/*
|
|
||||||
* NOTE: May be unnecessary to reload some registers.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* void _CPU_Context_restore( new_context )
|
* 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
|
.globl _CPU_Context_restore
|
||||||
|
|
||||||
_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 r3, [r0, #REG_R3]
|
||||||
ldr r4, [r0, #REG_R4]
|
ldr r4, [r0, #REG_R4]
|
||||||
ldr r5, [r0, #REG_R5]
|
ldr r5, [r0, #REG_R5]
|
||||||
@@ -94,14 +111,19 @@ _CPU_Context_restore:
|
|||||||
ldr r7, [r0, #REG_R7]
|
ldr r7, [r0, #REG_R7]
|
||||||
ldr r8, [r0, #REG_R8]
|
ldr r8, [r0, #REG_R8]
|
||||||
ldr r9, [r0, #REG_R9]
|
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 sp, [r0, #REG_SP]
|
||||||
ldr lr, [r0, #REG_PC]
|
ldr lr, [r0, #REG_PC]
|
||||||
mov pc, lr
|
mov pc, lr
|
||||||
|
|
||||||
|
|
||||||
|
/* FIXME: _Exception_Handler_Undef_Swi is untested */
|
||||||
.globl _Exception_Handler_Undef_Swi
|
.globl _Exception_Handler_Undef_Swi
|
||||||
_Exception_Handler_Undef_Swi:
|
_Exception_Handler_Undef_Swi:
|
||||||
|
/* FIXME: This should use load and store multiple instructions */
|
||||||
sub r13,r13,#SIZE_REGS
|
sub r13,r13,#SIZE_REGS
|
||||||
str r0, [r13, #REG_R0]
|
str r0, [r13, #REG_R0]
|
||||||
str r1, [r13, #REG_R1]
|
str r1, [r13, #REG_R1]
|
||||||
@@ -114,8 +136,8 @@ _Exception_Handler_Undef_Swi:
|
|||||||
str r8, [r13, #REG_R8]
|
str r8, [r13, #REG_R8]
|
||||||
str r9, [r13, #REG_R9]
|
str r9, [r13, #REG_R9]
|
||||||
str r10, [r13, #REG_R10]
|
str r10, [r13, #REG_R10]
|
||||||
str fp, [r13, #REG_FP]
|
str r11, [r13, #REG_R11]
|
||||||
str ip, [r13, #REG_IP]
|
str r12, [r13, #REG_R12]
|
||||||
str sp, [r13, #REG_SP]
|
str sp, [r13, #REG_SP]
|
||||||
str lr, [r13, #REG_LR]
|
str lr, [r13, #REG_LR]
|
||||||
mrs r0, cpsr /* read the status */
|
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 */
|
str r0, [r13, #REG_PC] /* we store it in a free place */
|
||||||
mov r0, r13 /* put frame address in r0 (C arg 1) */
|
mov r0, r13 /* put frame address in r0 (C arg 1) */
|
||||||
|
|
||||||
ldr r1, =_currentExcHandler
|
ldr r1, =SWI_Handler
|
||||||
ldr lr, =_go_back_1
|
ldr lr, =_go_back_1
|
||||||
ldr pc,[r1] /* call handler */
|
ldr pc,[r1] /* call handler */
|
||||||
_go_back_1:
|
_go_back_1:
|
||||||
@@ -138,15 +160,17 @@ _go_back_1:
|
|||||||
ldr r8, [r13, #REG_R8]
|
ldr r8, [r13, #REG_R8]
|
||||||
ldr r9, [r13, #REG_R9]
|
ldr r9, [r13, #REG_R9]
|
||||||
ldr r10, [r13, #REG_R10]
|
ldr r10, [r13, #REG_R10]
|
||||||
ldr fp, [r13, #REG_FP]
|
ldr r11, [r13, #REG_R11]
|
||||||
ldr ip, [r13, #REG_IP]
|
ldr r12, [r13, #REG_R12]
|
||||||
ldr sp, [r13, #REG_SP]
|
ldr sp, [r13, #REG_SP]
|
||||||
ldr lr, [r13, #REG_LR]
|
ldr lr, [r13, #REG_LR]
|
||||||
add r13,r13,#SIZE_REGS
|
add r13,r13,#SIZE_REGS
|
||||||
movs pc,r14 /* return */
|
movs pc,r14 /* return */
|
||||||
|
|
||||||
|
/* FIXME: _Exception_Handler_Abort is untested */
|
||||||
.globl _Exception_Handler_Abort
|
.globl _Exception_Handler_Abort
|
||||||
_Exception_Handler_Abort:
|
_Exception_Handler_Abort:
|
||||||
|
/* FIXME: This should use load and store multiple instructions */
|
||||||
sub r13,r13,#SIZE_REGS
|
sub r13,r13,#SIZE_REGS
|
||||||
str r0, [r13, #REG_R0]
|
str r0, [r13, #REG_R0]
|
||||||
str r1, [r13, #REG_R1]
|
str r1, [r13, #REG_R1]
|
||||||
@@ -159,8 +183,8 @@ _Exception_Handler_Abort:
|
|||||||
str r8, [r13, #REG_R8]
|
str r8, [r13, #REG_R8]
|
||||||
str r9, [r13, #REG_R9]
|
str r9, [r13, #REG_R9]
|
||||||
str r10, [r13, #REG_R10]
|
str r10, [r13, #REG_R10]
|
||||||
str sp, [r13, #REG_FP]
|
str sp, [r13, #REG_R11]
|
||||||
str lr, [r13, #REG_IP]
|
str lr, [r13, #REG_R12]
|
||||||
str lr, [r13, #REG_SP]
|
str lr, [r13, #REG_SP]
|
||||||
str lr, [r13, #REG_LR]
|
str lr, [r13, #REG_LR]
|
||||||
mrs r0, cpsr /* read the status */
|
mrs r0, cpsr /* read the status */
|
||||||
@@ -183,11 +207,10 @@ _go_back_2:
|
|||||||
ldr r8, [r13, #REG_R8]
|
ldr r8, [r13, #REG_R8]
|
||||||
ldr r9, [r13, #REG_R9]
|
ldr r9, [r13, #REG_R9]
|
||||||
ldr r10, [r13, #REG_R10]
|
ldr r10, [r13, #REG_R10]
|
||||||
ldr sp, [r13, #REG_FP]
|
ldr sp, [r13, #REG_R11]
|
||||||
ldr lr, [r13, #REG_IP]
|
ldr lr, [r13, #REG_R12]
|
||||||
ldr lr, [r13, #REG_SP]
|
ldr lr, [r13, #REG_SP]
|
||||||
ldr lr, [r13, #REG_LR]
|
ldr lr, [r13, #REG_LR]
|
||||||
add r13,r13,#SIZE_REGS
|
add r13,r13,#SIZE_REGS
|
||||||
subs pc,r14,#4 /* return */
|
subs pc,r14,#4 /* return */
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
/* no_cpu.h
|
/*
|
||||||
*
|
* $Id$
|
||||||
* This file is an example (i.e. "no CPU") of the file which is
|
|
||||||
* created for each CPU family port of RTEMS.
|
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* COPYRIGHT (c) 2000 Canon Research Centre France SA.
|
* COPYRIGHT (c) 2000 Canon Research Centre France SA.
|
||||||
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
|
* 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
|
* The license and distribution terms for this file may be
|
||||||
* found in the file LICENSE in this distribution or at
|
* found in the file LICENSE in this distribution or at
|
||||||
* http://www.OARcorp.com/rtems/license.html.
|
* http://www.OARcorp.com/rtems/license.html.
|
||||||
@@ -28,16 +29,23 @@ extern "C" {
|
|||||||
* dependent features are present in a particular member
|
* dependent features are present in a particular member
|
||||||
* of the family.
|
* of the family.
|
||||||
*/
|
*/
|
||||||
|
#if defined(__arm9__)
|
||||||
#if defined(__arm__)
|
# define CPU_MODEL_NAME "arm9"
|
||||||
|
# define ARM_HAS_FPU 0
|
||||||
#define CPU_MODEL_NAME "arm"
|
#elif defined(__arm9tdmi__)
|
||||||
#define ARM_HAS_FPU 0
|
# 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
|
#else
|
||||||
|
# error "Unsupported CPU Model"
|
||||||
#error "Unsupported CPU Model"
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -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.
|
* processor.
|
||||||
*
|
*
|
||||||
|
* COPYRIGHT (c) 2002 Advent Networks, Inc.
|
||||||
|
* Jay Monkman <jmonkman@adventnetworks.com>
|
||||||
|
*
|
||||||
* COPYRIGHT (c) 2000 Canon Research Centre France SA.
|
* COPYRIGHT (c) 2000 Canon Research Centre France SA.
|
||||||
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
|
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
|
||||||
*
|
*
|
||||||
@@ -10,8 +12,10 @@
|
|||||||
* found in the file LICENSE in this distribution or at
|
* found in the file LICENSE in this distribution or at
|
||||||
* http://www.OARcorp.com/rtems/license.html.
|
* http://www.OARcorp.com/rtems/license.html.
|
||||||
*
|
*
|
||||||
|
* $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* FIXME: finish commenting/cleaning up this file */
|
||||||
#ifndef __CPU_h
|
#ifndef __CPU_h
|
||||||
#define __CPU_h
|
#define __CPU_h
|
||||||
|
|
||||||
@@ -43,7 +47,7 @@ extern "C" {
|
|||||||
* one subroutine call is avoided entirely.]
|
* 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
|
* 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.
|
* 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?
|
* 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.
|
* 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
|
* CPU_HAS_HARDWARE_INTERRUPT_STACK should be set to TRUE. It is
|
||||||
* possible that both are FALSE for a particular CPU. Although it
|
* possible that both are FALSE for a particular CPU. Although it
|
||||||
* is unclear what that would imply about the interrupt processing
|
* is unclear what that would imply about the interrupt processing
|
||||||
* procedure on that CPU.
|
* 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?
|
* 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.
|
* 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
|
* 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_HAS_OWN_HOST_TO_NETWORK_ROUTINES FALSE
|
||||||
#define CPU_BIG_ENDIAN TRUE
|
#define CPU_BIG_ENDIAN FALSE
|
||||||
#define CPU_LITTLE_ENDIAN FALSE
|
#define CPU_LITTLE_ENDIAN TRUE
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The following defines the number of bits actually used in the
|
* 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().
|
* 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
|
* Processor defined structures
|
||||||
@@ -345,6 +349,7 @@ typedef struct {
|
|||||||
unsigned32 register_sp;
|
unsigned32 register_sp;
|
||||||
unsigned32 register_lr;
|
unsigned32 register_lr;
|
||||||
unsigned32 register_pc;
|
unsigned32 register_pc;
|
||||||
|
unsigned32 register_cpsr;
|
||||||
} Context_Control;
|
} Context_Control;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -476,14 +481,14 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)();
|
|||||||
* that a "reasonable" small application should not have any problems.
|
* 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
|
* CPU's worst alignment requirement for data types on a byte boundary. This
|
||||||
* alignment does not take into account the requirements for the stack.
|
* 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
|
* 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.
|
* 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 */
|
/* ISR handler macros */
|
||||||
|
|
||||||
@@ -537,14 +542,16 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)();
|
|||||||
* level is returned in _level.
|
* level is returned in _level.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define _CPU_ISR_Disable( _level ) \
|
#define _CPU_ISR_Disable( _level ) \
|
||||||
{ \
|
do { \
|
||||||
(_level) = 0; \
|
int reg; \
|
||||||
asm volatile ("MRS r0, cpsr \n" \
|
asm volatile ("MRS %0, cpsr \n" \
|
||||||
"ORR r0, r0, #0xc0 \n" \
|
"ORR %1, %0, #0xc0 \n" \
|
||||||
"MSR cpsr, r0 \n" \
|
"MSR cpsr, %1 \n" \
|
||||||
: : : "r0"); \
|
"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).
|
* 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.
|
* _level is not modified.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define _CPU_ISR_Enable( _level ) \
|
#define _CPU_ISR_Enable( _level ) \
|
||||||
{ \
|
do { \
|
||||||
asm volatile ("MRS r0, cpsr \n" \
|
int reg; \
|
||||||
"AND r0, r0, #0xFFFFFF3F \n" \
|
asm volatile ("MRS %0, cpsr \n" \
|
||||||
"MSR cpsr, r0 \n" \
|
"BIC %0, %0, #0xc0 \n" \
|
||||||
: : : "r0" ); \
|
"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
|
* This temporarily restores the interrupt to _level before immediately
|
||||||
* disabling them again. This is used to divide long RTEMS critical
|
* disabling them again. This is used to divide long RTEMS critical
|
||||||
@@ -567,8 +577,17 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)();
|
|||||||
* modified.
|
* 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 ) \
|
#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 );
|
unsigned32 _CPU_ISR_Get_level( void );
|
||||||
|
|
||||||
/* end of ISR handler macros */
|
/* end of ISR handler macros */
|
||||||
@@ -615,12 +642,14 @@ unsigned32 _CPU_ISR_Get_level( void );
|
|||||||
* where the PSR contains an enable FPU bit.
|
* where the PSR contains an enable FPU bit.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define _CPU_Context_Initialize( _the_context, _stack_base, _size, \
|
void _CPU_Context_Initialize(
|
||||||
_isr, _entry_point, _is_fp ) \
|
Context_Control *the_context,
|
||||||
{ \
|
unsigned32 *stack_base,
|
||||||
(_the_context)->register_sp = ((unsigned32)(_stack_base)) + (_size) ; \
|
unsigned32 size,
|
||||||
(_the_context)->register_pc = (_entry_point); \
|
unsigned32 new_level,
|
||||||
}
|
void *entry_point,
|
||||||
|
boolean is_fp
|
||||||
|
);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This routine is responsible for somehow restarting the currently
|
* This routine is responsible for somehow restarting the currently
|
||||||
|
|||||||
@@ -1,69 +1,41 @@
|
|||||||
/*
|
/*
|
||||||
* cpu_asm.h
|
* $Id$
|
||||||
*
|
*
|
||||||
* Very loose template for an include file for the cpu_asm.? file
|
* Copyright (c) 2002 by Advent Networks, Inc.
|
||||||
* if it is implemented as a ".S" file (preprocessed by cpp) instead
|
* Jay Monkman <jmonkman@adventnetworks.com>
|
||||||
* of a ".s" file (preprocessed by gm4 or gasp).
|
|
||||||
*
|
|
||||||
* COPYRIGHT (c) 2000 Canon Research Centre France SA.
|
|
||||||
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
|
|
||||||
*
|
*
|
||||||
* The license and distribution terms for this file may be
|
* The license and distribution terms for this file may be
|
||||||
* found in the file LICENSE in this distribution or at
|
* found in the file LICENSE in this distribution or at
|
||||||
* http://www.OARcorp.com/rtems/license.html.
|
* http://www.OARcorp.com/rtems/license.html.
|
||||||
*
|
*
|
||||||
|
* This file is the include file for cpu_asm.S
|
||||||
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __CPU_ASM_h
|
#ifndef __CPU_ASM_h
|
||||||
#define __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
|
#endif
|
||||||
|
|
||||||
/* end of file */
|
|
||||||
|
|||||||
Reference in New Issue
Block a user