mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2025-12-24 21:37:11 +00:00
exception handler maintenance
This commit is contained in:
@@ -1,3 +1,19 @@
|
|||||||
|
2009-07-15 Sebastian Huber <sebastian.huber@embedded-brains.de>
|
||||||
|
|
||||||
|
* arm_exc_handler_high.c, arm_exc_handler_low.S, arm_exc_interrupt.S:
|
||||||
|
New files.
|
||||||
|
* Makefile.am: Update.
|
||||||
|
* rtems/score/cpu.h: Removed all generic comments. Changed inline
|
||||||
|
assembler of interrupt support functions. Removed operating system
|
||||||
|
support for fast interrupts (FIQ). Overall cleanup.
|
||||||
|
* cpu.c: Changed type of arm_cpu_mode to uint32_t to match the type in
|
||||||
|
_CPU_Context_Initialize(). Moved exception handler code into
|
||||||
|
'arm_exc_handler_high.c'. _CPU_ISR_install_vector() writes now only
|
||||||
|
if necessary.
|
||||||
|
* cpu_asm.S: Moved exception handler code into 'arm_exc_handler_low.S'.
|
||||||
|
* rtems/score/types.h: Removed superfluous defines.
|
||||||
|
* ChangeLog, thumb_isr.c: Removed files.
|
||||||
|
|
||||||
2009-05-05 Joel Sherrill <joel.sherrill@oarcorp.com>
|
2009-05-05 Joel Sherrill <joel.sherrill@oarcorp.com>
|
||||||
|
|
||||||
* rtems/score/cpu.h: Remove warnings.
|
* rtems/score/cpu.h: Remove warnings.
|
||||||
|
|||||||
@@ -11,8 +11,11 @@ include_rtems_score_HEADERS = rtems/score/cpu.h rtems/score/cpu_asm.h \
|
|||||||
|
|
||||||
noinst_LIBRARIES = libscorecpu.a
|
noinst_LIBRARIES = libscorecpu.a
|
||||||
libscorecpu_a_CPPFLAGS = $(AM_CPPFLAGS)
|
libscorecpu_a_CPPFLAGS = $(AM_CPPFLAGS)
|
||||||
libscorecpu_a_SOURCES = cpu.c cpu_asm.S
|
libscorecpu_a_SOURCES = cpu.c \
|
||||||
libscorecpu_a_SOURCES += thumb/thumb_isr.c
|
cpu_asm.S \
|
||||||
|
arm_exc_interrupt.S \
|
||||||
|
arm_exc_handler_low.S \
|
||||||
|
arm_exc_handler_high.c
|
||||||
|
|
||||||
include $(srcdir)/preinstall.am
|
include $(srcdir)/preinstall.am
|
||||||
include $(top_srcdir)/automake/local.am
|
include $(top_srcdir)/automake/local.am
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
|
/**
|
||||||
|
* @file
|
||||||
|
*
|
||||||
|
* ARM support code.
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ARM CPU Dependent Source
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* 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,6 +13,8 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 2007 Ray xu <rayx.cn@gmail.com>
|
* Copyright (c) 2007 Ray xu <rayx.cn@gmail.com>
|
||||||
*
|
*
|
||||||
|
* Copyright (c) 2009 embedded brains GmbH
|
||||||
|
*
|
||||||
* 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.rtems.com/license/LICENSE.
|
* http://www.rtems.com/license/LICENSE.
|
||||||
@@ -29,236 +34,86 @@
|
|||||||
* This variable can be used to change the running mode of the execution
|
* This variable can be used to change the running mode of the execution
|
||||||
* contexts.
|
* contexts.
|
||||||
*/
|
*/
|
||||||
|
uint32_t arm_cpu_mode = 0x13;
|
||||||
unsigned int arm_cpu_mode = 0x13;
|
|
||||||
|
|
||||||
/* _CPU_Initialize
|
|
||||||
*
|
|
||||||
* INPUT PARAMETERS: NONE
|
|
||||||
*
|
|
||||||
* This routine performs processor dependent initialization.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void _CPU_Initialize(void)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
*
|
|
||||||
* _CPU_ISR_Get_level - returns the current interrupt level
|
|
||||||
*/
|
|
||||||
#define str(x) #x
|
|
||||||
#define xstr(x) str(x)
|
|
||||||
#define L(x) #x "_" xstr(__LINE__)
|
|
||||||
|
|
||||||
#define TO_ARM_MODE(x) \
|
|
||||||
asm volatile ( \
|
|
||||||
".code 16 \n" \
|
|
||||||
L(x) "_thumb: \n" \
|
|
||||||
".align 2 \n" \
|
|
||||||
"push {lr} \n" \
|
|
||||||
"adr %0, "L(x) "_arm \n" \
|
|
||||||
"bl " L(x)" \n" \
|
|
||||||
"pop {pc} \n" \
|
|
||||||
".balign 4 \n" \
|
|
||||||
L(x) ": \n" \
|
|
||||||
"bx %0 \n" \
|
|
||||||
"nop \n" \
|
|
||||||
".pool \n" \
|
|
||||||
".code 32 \n" \
|
|
||||||
L(x) "_arm: \n" \
|
|
||||||
:"=&r" (reg))
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Switch to Thumb mode Veneer,ugly but safe
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define TO_THUMB_MODE(x) \
|
|
||||||
asm volatile ( \
|
|
||||||
".code 32 \n"\
|
|
||||||
"adr %0, "L(x) "_thumb +1 \n"\
|
|
||||||
"bx %0 \n"\
|
|
||||||
".pool \n"\
|
|
||||||
".thumb_func \n"\
|
|
||||||
L(x) "_thumb: \n"\
|
|
||||||
: "=&r" (reg))
|
|
||||||
|
|
||||||
#if (!defined(__THUMB_INTERWORK__) && !defined(__thumb__))
|
|
||||||
uint32_t _CPU_ISR_Get_level( void )
|
|
||||||
{
|
|
||||||
uint32_t reg = 0; /* to avoid warning */
|
|
||||||
asm volatile ("mrs %0, cpsr \n" \
|
|
||||||
"and %0, %0, #0xc0 \n" \
|
|
||||||
: "=r" (reg) \
|
|
||||||
: "0" (reg) );
|
|
||||||
return reg;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* _CPU_ISR_install_vector
|
|
||||||
*
|
|
||||||
* This kernel routine installs the RTEMS handler for the
|
|
||||||
* specified vector.
|
|
||||||
*
|
|
||||||
* Input parameters:
|
|
||||||
* vector - interrupt 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(
|
|
||||||
uint32_t vector,
|
|
||||||
proc_ptr new_handler,
|
|
||||||
proc_ptr *old_handler
|
|
||||||
)
|
|
||||||
{
|
|
||||||
/* pointer on the redirection table in RAM */
|
|
||||||
long *VectorTable = (long *)(MAX_EXCEPTIONS * 4);
|
|
||||||
|
|
||||||
if (old_handler != NULL) {
|
|
||||||
old_handler = *(proc_ptr *)(VectorTable + vector);
|
|
||||||
}
|
|
||||||
|
|
||||||
*(VectorTable + vector) = (long)new_handler ;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void _CPU_Context_Initialize(
|
void _CPU_Context_Initialize(
|
||||||
Context_Control *the_context,
|
Context_Control *the_context,
|
||||||
uint32_t *stack_base,
|
uint32_t *stack_base,
|
||||||
uint32_t size,
|
uint32_t size,
|
||||||
uint32_t new_level,
|
uint32_t new_level,
|
||||||
void *entry_point,
|
void *entry_point,
|
||||||
bool is_fp
|
bool is_fp
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
the_context->register_sp = (uint32_t)stack_base + size ;
|
the_context->register_sp = (uint32_t) stack_base + size ;
|
||||||
the_context->register_lr = (uint32_t)entry_point;
|
the_context->register_lr = (uint32_t) entry_point;
|
||||||
the_context->register_cpsr = new_level | arm_cpu_mode;
|
the_context->register_cpsr = new_level | arm_cpu_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Preprocessor magic for stringification of x */
|
||||||
|
#define _CPU_ISR_LEVEL_DO_STRINGOF( x) #x
|
||||||
|
#define _CPU_ISR_LEVEL_STRINGOF( x) _CPU_ISR_LEVEL_DO_STRINGOF( x)
|
||||||
|
|
||||||
/*
|
void _CPU_ISR_Set_level( uint32_t level )
|
||||||
* _CPU_Install_interrupt_stack - this function is empty since the
|
{
|
||||||
* BSP must set up the interrupt stacks.
|
uint32_t reg;
|
||||||
*/
|
|
||||||
|
asm volatile (
|
||||||
|
THUMB_TO_ARM
|
||||||
|
"mrs %0, cpsr\n"
|
||||||
|
"bic %0, %0, #" _CPU_ISR_LEVEL_STRINGOF( CPU_MODES_INTERRUPT_MASK ) "\n"
|
||||||
|
"orr %0, %0, %1\n"
|
||||||
|
"msr cpsr, %0\n"
|
||||||
|
ARM_TO_THUMB
|
||||||
|
: "=r" (reg)
|
||||||
|
: "r" (level)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t _CPU_ISR_Get_level( void )
|
||||||
|
{
|
||||||
|
uint32_t reg;
|
||||||
|
uint32_t level;
|
||||||
|
|
||||||
|
asm volatile (
|
||||||
|
THUMB_TO_ARM
|
||||||
|
"mrs %0, cpsr\n"
|
||||||
|
"and %1, %0, #" _CPU_ISR_LEVEL_STRINGOF( CPU_MODES_INTERRUPT_MASK ) "\n"
|
||||||
|
ARM_TO_THUMB
|
||||||
|
: "=r" (reg), "=r" (level)
|
||||||
|
);
|
||||||
|
|
||||||
|
return level;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _CPU_ISR_install_vector(
|
||||||
|
uint32_t vector,
|
||||||
|
proc_ptr new_handler,
|
||||||
|
proc_ptr *old_handler
|
||||||
|
)
|
||||||
|
{
|
||||||
|
/* Redirection table starts at the end of the vector table */
|
||||||
|
volatile uint32_t *table = (volatile uint32_t *) (MAX_EXCEPTIONS * 4);
|
||||||
|
|
||||||
|
uint32_t current_handler = table [vector];
|
||||||
|
|
||||||
|
/* The current handler is now the old one */
|
||||||
|
if (old_handler != NULL) {
|
||||||
|
*old_handler = (proc_ptr) current_handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write only if necessary to avoid writes to a maybe read-only memory */
|
||||||
|
if (current_handler != (uint32_t) new_handler) {
|
||||||
|
table [vector] = (uint32_t) new_handler;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void _CPU_Install_interrupt_stack( void )
|
void _CPU_Install_interrupt_stack( void )
|
||||||
{
|
{
|
||||||
|
/* This function is empty since the BSP must set up the interrupt stacks */
|
||||||
}
|
}
|
||||||
|
|
||||||
void _defaultExcHandler (CPU_Exception_frame *ctx)
|
void _CPU_Initialize( void )
|
||||||
{
|
{
|
||||||
printk("\n\r");
|
/* Do nothing */
|
||||||
printk("----------------------------------------------------------\n\r");
|
|
||||||
#if 1
|
|
||||||
printk("Exception 0x%x caught at PC 0x%x by thread %d\n",
|
|
||||||
ctx->register_ip, ctx->register_lr - 4,
|
|
||||||
_Thread_Executing->Object.id);
|
|
||||||
#endif
|
|
||||||
printk("----------------------------------------------------------\n\r");
|
|
||||||
printk("Processor execution context at time of the fault was :\n\r");
|
|
||||||
printk("----------------------------------------------------------\n\r");
|
|
||||||
#if 0
|
|
||||||
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");
|
|
||||||
#endif
|
|
||||||
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(void);
|
|
||||||
extern void _Exception_Handler_Abort(void);
|
|
||||||
extern void _exc_data_abort(void);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* FIXME: put comments here */
|
|
||||||
void rtems_exception_init_mngt(void)
|
|
||||||
{
|
|
||||||
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,
|
|
||||||
_exc_data_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);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define INSN_MASK 0xc5
|
|
||||||
|
|
||||||
#define INSN_STM1 0x80
|
|
||||||
#define INSN_STM2 0x84
|
|
||||||
#define INSN_STR 0x40
|
|
||||||
#define INSN_STRB 0x44
|
|
||||||
|
|
||||||
#define INSN_LDM1 0x81
|
|
||||||
#define INSN_LDM23 0x85
|
|
||||||
#define INSN_LDR 0x41
|
|
||||||
#define INSN_LDRB 0x45
|
|
||||||
|
|
||||||
#define GET_RD(x) ((x & 0x0000f000) >> 12)
|
|
||||||
#define GET_RN(x) ((x & 0x000f0000) >> 16)
|
|
||||||
|
|
||||||
#define GET_U(x) ((x & 0x00800000) >> 23)
|
|
||||||
#define GET_I(x) ((x & 0x02000000) >> 25)
|
|
||||||
|
|
||||||
#define GET_REG(r, ctx) (((uint32_t *)ctx)[r])
|
|
||||||
#define SET_REG(r, ctx, v) (((uint32_t *)ctx)[r] = v)
|
|
||||||
#define GET_OFFSET(insn) (insn & 0xfff)
|
|
||||||
|
|
||||||
|
|||||||
@@ -84,133 +84,3 @@ _restore:
|
|||||||
FUNC_START_ARM(_CPU_Context_restore)
|
FUNC_START_ARM(_CPU_Context_restore)
|
||||||
mov r1, r0
|
mov r1, r0
|
||||||
b _restore
|
b _restore
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* FIXME: _Exception_Handler_Undef_Swi is untested */
|
|
||||||
FUNC_START_ARM(_Exception_Handler_Undef_Swi)
|
|
||||||
/* FIXME: This should use load and store multiple instructions */
|
|
||||||
sub r13,r13,#SIZE_REGS
|
|
||||||
str r4, [r13, #REG_R4]
|
|
||||||
str r5, [r13, #REG_R5]
|
|
||||||
str r6, [r13, #REG_R6]
|
|
||||||
str r7, [r13, #REG_R7]
|
|
||||||
str r8, [r13, #REG_R8]
|
|
||||||
str r9, [r13, #REG_R9]
|
|
||||||
str r10, [r13, #REG_R10]
|
|
||||||
str r11, [r13, #REG_R11]
|
|
||||||
str sp, [r13, #REG_SP]
|
|
||||||
str lr, [r13, #REG_LR]
|
|
||||||
mrs r0, cpsr /* read the status */
|
|
||||||
and r0, r0,#0x1f /* we keep the mode as exception number */
|
|
||||||
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, =SWI_Handler
|
|
||||||
ldr lr, =_go_back_1
|
|
||||||
ldr pc,[r1] /* call handler */
|
|
||||||
_go_back_1:
|
|
||||||
ldr r4, [r13, #REG_R4]
|
|
||||||
ldr r5, [r13, #REG_R5]
|
|
||||||
ldr r6, [r13, #REG_R6]
|
|
||||||
ldr r7, [r13, #REG_R7]
|
|
||||||
ldr r8, [r13, #REG_R8]
|
|
||||||
ldr r9, [r13, #REG_R9]
|
|
||||||
ldr r10, [r13, #REG_R10]
|
|
||||||
ldr r11, [r13, #REG_R11]
|
|
||||||
ldr sp, [r13, #REG_SP]
|
|
||||||
ldr lr, [r13, #REG_LR]
|
|
||||||
add r13,r13,#SIZE_REGS
|
|
||||||
movs pc,r14 /* return */
|
|
||||||
|
|
||||||
/* FIXME: _Exception_Handler_Abort is untested */
|
|
||||||
FUNC_START_ARM(_Exception_Handler_Abort)
|
|
||||||
/* FIXME: This should use load and store multiple instructions */
|
|
||||||
sub r13,r13,#SIZE_REGS
|
|
||||||
str r4, [r13, #REG_R4]
|
|
||||||
str r5, [r13, #REG_R5]
|
|
||||||
str r6, [r13, #REG_R6]
|
|
||||||
str r7, [r13, #REG_R7]
|
|
||||||
str r8, [r13, #REG_R8]
|
|
||||||
str r9, [r13, #REG_R9]
|
|
||||||
str sp, [r13, #REG_R11]
|
|
||||||
str lr, [r13, #REG_SP]
|
|
||||||
str lr, [r13, #REG_LR]
|
|
||||||
mrs r0, cpsr /* read the status */
|
|
||||||
and r0, r0,#0x1f /* we keep the mode as exception number */
|
|
||||||
str r0, [r13, #REG_PC] /* we store it in a free place */
|
|
||||||
mov r0, r13 /* put frame address in ro (C arg 1) */
|
|
||||||
|
|
||||||
ldr r1, =_currentExcHandler
|
|
||||||
ldr lr, =_go_back_2
|
|
||||||
ldr pc,[r1] /* call handler */
|
|
||||||
_go_back_2:
|
|
||||||
ldr r4, [r13, #REG_R4]
|
|
||||||
ldr r5, [r13, #REG_R5]
|
|
||||||
ldr r6, [r13, #REG_R6]
|
|
||||||
ldr r7, [r13, #REG_R7]
|
|
||||||
ldr r8, [r13, #REG_R8]
|
|
||||||
ldr r9, [r13, #REG_R9]
|
|
||||||
ldr r10, [r13, #REG_R10]
|
|
||||||
ldr sp, [r13, #REG_R11]
|
|
||||||
ldr lr, [r13, #REG_SP]
|
|
||||||
ldr lr, [r13, #REG_LR]
|
|
||||||
add r13,r13,#SIZE_REGS
|
|
||||||
#ifdef __thumb__
|
|
||||||
subs r11, r14,#4
|
|
||||||
bx r11
|
|
||||||
nop
|
|
||||||
#else
|
|
||||||
subs pc,r14,#4 /* return */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define ABORT_REGS_OFFS 32-REG_R4
|
|
||||||
#define ABORT_SIZE_REGS SIZE_REGS+ABORT_REGS_OFFS
|
|
||||||
|
|
||||||
FUNC_START_ARM(_exc_data_abort)
|
|
||||||
sub sp, sp, #ABORT_SIZE_REGS /* reserve register frame */
|
|
||||||
stmia sp, {r0-r11}
|
|
||||||
add sp, sp, #ABORT_REGS_OFFS /* the Context_Control structure starts by CPSR, R4, ... */
|
|
||||||
|
|
||||||
str ip, [sp, #REG_PC] /* store R12 (ip) somewhere, oh hackery, hackery, hack */
|
|
||||||
str lr, [sp, #REG_LR]
|
|
||||||
|
|
||||||
mov r1, lr
|
|
||||||
ldr r0, [r1, #-8] /* r0 = bad instruction */
|
|
||||||
mrs r1, spsr /* r1 = spsr */
|
|
||||||
mov r2, r13 /* r2 = exception frame of Context_Control type */
|
|
||||||
#if defined(__thumb__)
|
|
||||||
.code 32
|
|
||||||
/*arm to thumb*/
|
|
||||||
adr r5, to_thumb + 1
|
|
||||||
bx r5
|
|
||||||
.code 16
|
|
||||||
to_thumb:
|
|
||||||
#endif
|
|
||||||
bl do_data_abort
|
|
||||||
#if defined(__thumb__)
|
|
||||||
/*back to arm*/
|
|
||||||
.code 16
|
|
||||||
thumb_to_arm:
|
|
||||||
.align 2
|
|
||||||
adr r5, arm_code
|
|
||||||
bx r5
|
|
||||||
nop
|
|
||||||
.code 32
|
|
||||||
arm_code:
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ldr lr, [sp, #REG_LR]
|
|
||||||
ldr ip, [sp, #REG_PC] /* restore R12 (ip) */
|
|
||||||
|
|
||||||
sub sp, sp, #ABORT_REGS_OFFS
|
|
||||||
ldmia sp, {r0-r11}
|
|
||||||
add sp, sp, #ABORT_SIZE_REGS
|
|
||||||
#ifdef __thumb__
|
|
||||||
subs r11, r14, #4 /* return to the instruction */
|
|
||||||
bx r11
|
|
||||||
nop
|
|
||||||
#else
|
|
||||||
subs pc, r14, #4
|
|
||||||
#endif
|
|
||||||
/* _AFTER_ the aborted one */
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -35,9 +35,6 @@ extern "C" {
|
|||||||
|
|
||||||
typedef uint16_t Priority_Bit_map_control;
|
typedef uint16_t Priority_Bit_map_control;
|
||||||
|
|
||||||
typedef void arm_cpu_isr;
|
|
||||||
typedef void (*arm_cpu_isr_entry)( void );
|
|
||||||
|
|
||||||
#ifdef RTEMS_DEPRECATED_TYPES
|
#ifdef RTEMS_DEPRECATED_TYPES
|
||||||
typedef bool boolean; /* Boolean value */
|
typedef bool boolean; /* Boolean value */
|
||||||
typedef float single_precision; /* single precision float */
|
typedef float single_precision; /* single precision float */
|
||||||
|
|||||||
Reference in New Issue
Block a user