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>
|
||||
|
||||
* 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_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 \
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
/*
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
/*
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user