mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-10-14 02:27:39 -04:00
arm: factor all exception handlers out of the crt0.S files
Remove the implementations of all exceptions handlers from the various crt0.S files and have a single implementation in system-arm.h The new implementation is weak so that it can be overwritten by some specific code (like the unwinder) Change-Id: Ib3e041ed6037376bbe0e79286057e1051640dd90 Reviewed-on: http://gerrit.rockbox.org/205 Reviewed-by: Marcin Bukat <marcin.bukat@gmail.com>
This commit is contained in:
parent
bb0e4cc543
commit
f33330c0ff
11 changed files with 50 additions and 312 deletions
|
@ -137,38 +137,6 @@ newstart:
|
||||||
ldr ip, =main @ make sure we are using the virtual address
|
ldr ip, =main @ make sure we are using the virtual address
|
||||||
bx ip
|
bx ip
|
||||||
|
|
||||||
/* All illegal exceptions call into UIE with exception address as first
|
|
||||||
* parameter. This is calculated differently depending on which exception
|
|
||||||
* we're in. Second parameter is exception number, used for a string lookup
|
|
||||||
* in UIE. */
|
|
||||||
undef_instr_handler:
|
|
||||||
sub r0, lr, #4 @ r0 points to the faulty ARM instruction
|
|
||||||
#ifdef USE_THUMB
|
|
||||||
mrs r1, spsr
|
|
||||||
tst r1, #(1<<5) @ T bit set ?
|
|
||||||
subne r0, lr, #2 @ if yes, r0 points to the faulty THUMB instruction
|
|
||||||
#endif /* USE_THUMB */
|
|
||||||
mov r1, #0
|
|
||||||
b UIE
|
|
||||||
|
|
||||||
/* We run sys mode most of the time, and should never see a software
|
|
||||||
* exception being thrown. Make it illegal and call UIE. */
|
|
||||||
software_int_handler:
|
|
||||||
reserved_handler:
|
|
||||||
sub r0, lr, #4
|
|
||||||
mov r1, #4
|
|
||||||
b UIE
|
|
||||||
|
|
||||||
prefetch_abort_handler:
|
|
||||||
sub r0, lr, #4
|
|
||||||
mov r1, #1
|
|
||||||
b UIE
|
|
||||||
|
|
||||||
data_abort_handler:
|
|
||||||
sub r0, lr, #8
|
|
||||||
mov r1, #2
|
|
||||||
b UIE
|
|
||||||
|
|
||||||
/* Cache-align interrupt stacks */
|
/* Cache-align interrupt stacks */
|
||||||
.balign 32
|
.balign 32
|
||||||
|
|
||||||
|
|
|
@ -161,38 +161,6 @@ remap:
|
||||||
1:
|
1:
|
||||||
b 1b
|
b 1b
|
||||||
|
|
||||||
/* All illegal exceptions call into UIE with exception address as first
|
|
||||||
* parameter. This is calculated differently depending on which exception
|
|
||||||
* we're in. Second parameter is exception number, used for a string lookup
|
|
||||||
* in UIE. */
|
|
||||||
undef_instr_handler:
|
|
||||||
sub r0, lr, #4 @ r0 points to the faulty ARM instruction
|
|
||||||
#ifdef USE_THUMB
|
|
||||||
mrs r1, spsr
|
|
||||||
tst r1, #(1<<5) @ T bit set ?
|
|
||||||
subne r0, lr, #2 @ if yes, r0 points to the faulty THUMB instruction
|
|
||||||
#endif /* USE_THUMB */
|
|
||||||
mov r1, #0
|
|
||||||
b UIE
|
|
||||||
|
|
||||||
/* We run sys mode most of the time, and should never see a software
|
|
||||||
* exception being thrown. Make it illegal and call UIE. */
|
|
||||||
software_int_handler:
|
|
||||||
reserved_handler:
|
|
||||||
sub r0, lr, #4
|
|
||||||
mov r1, #4
|
|
||||||
b UIE
|
|
||||||
|
|
||||||
prefetch_abort_handler:
|
|
||||||
sub r0, lr, #4
|
|
||||||
mov r1, #1
|
|
||||||
b UIE
|
|
||||||
|
|
||||||
data_abort_handler:
|
|
||||||
sub r0, lr, #8
|
|
||||||
mov r1, #2
|
|
||||||
b UIE
|
|
||||||
|
|
||||||
/* 256 words of IRQ stack */
|
/* 256 words of IRQ stack */
|
||||||
.space 256*4
|
.space 256*4
|
||||||
irq_stack:
|
irq_stack:
|
||||||
|
|
|
@ -326,35 +326,6 @@ remap_end:
|
||||||
.word 0 @ fiq_handler
|
.word 0 @ fiq_handler
|
||||||
#endif /* BOOTLOADER */
|
#endif /* BOOTLOADER */
|
||||||
|
|
||||||
.text
|
|
||||||
|
|
||||||
/* All illegal exceptions call into UIE with exception address as first
|
|
||||||
* parameter. This is calculated differently depending on which exception
|
|
||||||
* we're in. Second parameter is exception number, used for a string lookup
|
|
||||||
* in UIE. */
|
|
||||||
undef_instr_handler:
|
|
||||||
sub r0, lr, #4
|
|
||||||
mov r1, #0
|
|
||||||
b UIE
|
|
||||||
|
|
||||||
/* We run sys mode most of the time, and should never see a software
|
|
||||||
* exception being thrown. Make it illegal and call UIE. */
|
|
||||||
software_int_handler:
|
|
||||||
reserved_handler:
|
|
||||||
sub r0, lr, #4
|
|
||||||
mov r1, #4
|
|
||||||
b UIE
|
|
||||||
|
|
||||||
prefetch_abort_handler:
|
|
||||||
sub r0, lr, #4
|
|
||||||
mov r1, #1
|
|
||||||
b UIE
|
|
||||||
|
|
||||||
data_abort_handler:
|
|
||||||
sub r0, lr, #8
|
|
||||||
mov r1, #2
|
|
||||||
b UIE
|
|
||||||
|
|
||||||
/* 256 words of IRQ stack */
|
/* 256 words of IRQ stack */
|
||||||
.section .bss
|
.section .bss
|
||||||
.balign 32
|
.balign 32
|
||||||
|
|
|
@ -196,30 +196,3 @@ entry_point:
|
||||||
bhi 1b
|
bhi 1b
|
||||||
|
|
||||||
bl main
|
bl main
|
||||||
|
|
||||||
/* All illegal exceptions call into UIE with exception address as first
|
|
||||||
* parameter. This is calculated differently depending on which exception
|
|
||||||
* we're in. Second parameter is exception number, used for a string lookup
|
|
||||||
* in UIE. */
|
|
||||||
undef_instr_handler:
|
|
||||||
sub r0, lr, #4
|
|
||||||
mov r1, #0
|
|
||||||
b UIE
|
|
||||||
|
|
||||||
prefetch_abort_handler:
|
|
||||||
sub r0, lr, #4
|
|
||||||
mov r1, #1
|
|
||||||
b UIE
|
|
||||||
|
|
||||||
data_abort_handler:
|
|
||||||
sub r0, lr, #8
|
|
||||||
mov r1, #2
|
|
||||||
b UIE
|
|
||||||
|
|
||||||
/* We run sys mode most of the time, and should never see a software
|
|
||||||
* exception being thrown. Make it illegal and call UIE */
|
|
||||||
software_int_handler:
|
|
||||||
reserved_handler:
|
|
||||||
sub r0, lr, #4
|
|
||||||
mov r1, #5
|
|
||||||
b UIE
|
|
||||||
|
|
|
@ -565,35 +565,6 @@ stackmunge:
|
||||||
*/
|
*/
|
||||||
b vectors
|
b vectors
|
||||||
|
|
||||||
/* All illegal exceptions call into UIE with exception address as first
|
|
||||||
parameter. This is calculated differently depending on which exception
|
|
||||||
we're in. Second parameter is exception number, used for a string lookup
|
|
||||||
in UIE.
|
|
||||||
*/
|
|
||||||
undef_instr_handler:
|
|
||||||
sub r0, lr, #4
|
|
||||||
mov r1, #0
|
|
||||||
b UIE
|
|
||||||
|
|
||||||
/* We run sys mode most of the time, and should never see a software
|
|
||||||
exception being thrown. Make it illegal and call UIE.
|
|
||||||
*/
|
|
||||||
software_int_handler:
|
|
||||||
reserved_handler:
|
|
||||||
sub r0, lr, #4
|
|
||||||
mov r1, #4
|
|
||||||
b UIE
|
|
||||||
|
|
||||||
prefetch_abort_handler:
|
|
||||||
sub r0, lr, #4
|
|
||||||
mov r1, #1
|
|
||||||
b UIE
|
|
||||||
|
|
||||||
data_abort_handler:
|
|
||||||
sub r0, lr, #8
|
|
||||||
mov r1, #2
|
|
||||||
b UIE
|
|
||||||
|
|
||||||
#if defined(BOOTLOADER)
|
#if defined(BOOTLOADER)
|
||||||
fiq_handler:
|
fiq_handler:
|
||||||
b UIE
|
b UIE
|
||||||
|
|
|
@ -507,33 +507,3 @@ start_loc:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bl main
|
bl main
|
||||||
|
|
||||||
.text
|
|
||||||
/* .global UIE*/
|
|
||||||
|
|
||||||
/* All illegal exceptions call into UIE with exception address as first
|
|
||||||
* parameter. This is calculated differently depending on which exception
|
|
||||||
* we're in. Second parameter is exception number, used for a string lookup
|
|
||||||
* in UIE. */
|
|
||||||
undef_instr_handler:
|
|
||||||
sub r0, lr, #4
|
|
||||||
mov r1, #0
|
|
||||||
b UIE
|
|
||||||
|
|
||||||
/* We run sys mode most of the time, and should never see a software
|
|
||||||
* exception being thrown. Make it illegal and call UIE. */
|
|
||||||
software_int_handler:
|
|
||||||
reserved_handler:
|
|
||||||
sub r0, lr, #4
|
|
||||||
mov r1, #4
|
|
||||||
b UIE
|
|
||||||
|
|
||||||
prefetch_abort_handler:
|
|
||||||
sub r0, lr, #4
|
|
||||||
mov r1, #1
|
|
||||||
b UIE
|
|
||||||
|
|
||||||
data_abort_handler:
|
|
||||||
sub r0, lr, #8
|
|
||||||
mov r1, #2
|
|
||||||
b UIE
|
|
||||||
|
|
|
@ -179,33 +179,3 @@ start_loc:
|
||||||
bhi 1b
|
bhi 1b
|
||||||
|
|
||||||
bl main
|
bl main
|
||||||
|
|
||||||
.text
|
|
||||||
/* .global UIE*/
|
|
||||||
|
|
||||||
/* All illegal exceptions call into UIE with exception address as first
|
|
||||||
* parameter. This is calculated differently depending on which exception
|
|
||||||
* we're in. Second parameter is exception number, used for a string lookup
|
|
||||||
* in UIE. */
|
|
||||||
undef_instr_handler:
|
|
||||||
sub r0, lr, #4
|
|
||||||
mov r1, #0
|
|
||||||
b UIE
|
|
||||||
|
|
||||||
/* We run sys mode most of the time, and should never see a software
|
|
||||||
* exception being thrown. Make it illegal and call UIE. */
|
|
||||||
software_int_handler:
|
|
||||||
reserved_handler:
|
|
||||||
sub r0, lr, #4
|
|
||||||
mov r1, #4
|
|
||||||
b UIE
|
|
||||||
|
|
||||||
prefetch_abort_handler:
|
|
||||||
sub r0, lr, #4
|
|
||||||
mov r1, #1
|
|
||||||
b UIE
|
|
||||||
|
|
||||||
data_abort_handler:
|
|
||||||
sub r0, lr, #8
|
|
||||||
mov r1, #2
|
|
||||||
b UIE
|
|
||||||
|
|
|
@ -36,6 +36,56 @@ static const char* const uiename[] = {
|
||||||
"SWI"
|
"SWI"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void __attribute__((weak,naked)) data_abort_handler(void)
|
||||||
|
{
|
||||||
|
asm volatile(
|
||||||
|
"sub r0, lr, #8 \n"
|
||||||
|
"mov r1, #2 \n"
|
||||||
|
"b UIE \n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __attribute__((weak,naked)) software_int_handler(void)
|
||||||
|
{
|
||||||
|
asm volatile(
|
||||||
|
"sub r0, lr, #4 \n"
|
||||||
|
"mov r1, #4 \n"
|
||||||
|
"b UIE \n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __attribute__((weak,naked)) reserved_handler(void)
|
||||||
|
{
|
||||||
|
asm volatile(
|
||||||
|
"sub r0, lr, #4 \n"
|
||||||
|
"mov r1, #4 \n"
|
||||||
|
"b UIE \n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __attribute__((weak,naked)) prefetch_abort_handler(void)
|
||||||
|
{
|
||||||
|
asm volatile(
|
||||||
|
"sub r0, lr, #4 \n"
|
||||||
|
"mov r1, #1 \n"
|
||||||
|
"b UIE \n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __attribute__((weak,naked)) undef_instr_handler(void)
|
||||||
|
{
|
||||||
|
asm volatile(
|
||||||
|
"sub r0, lr, #4 \n"
|
||||||
|
#ifdef USE_THUMB
|
||||||
|
"mrs r1, spsr \n"
|
||||||
|
"tst r1, #(1 << 5) \n" // T bit set ?
|
||||||
|
"subne r0, lr, #2 \n" // if yes, offset to THUMB instruction
|
||||||
|
#endif
|
||||||
|
"mov r1, #0 \n"
|
||||||
|
"b UIE \n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/* Unexpected Interrupt or Exception handler. Currently only deals with
|
/* Unexpected Interrupt or Exception handler. Currently only deals with
|
||||||
exceptions, but will deal with interrupts later.
|
exceptions, but will deal with interrupts later.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -212,35 +212,6 @@ vectors_end:
|
||||||
|
|
||||||
.text
|
.text
|
||||||
|
|
||||||
/* All illegal exceptions call into UIE with exception address as first
|
|
||||||
parameter. This is calculated differently depending on which exception
|
|
||||||
we're in. Second parameter is exception number, used for a string lookup
|
|
||||||
in UIE.
|
|
||||||
*/
|
|
||||||
undef_instr_handler:
|
|
||||||
sub r0, lr, #4
|
|
||||||
mov r1, #0
|
|
||||||
b UIE
|
|
||||||
|
|
||||||
/* We run sys mode most of the time, and should never see a software
|
|
||||||
exception being thrown. Make it illegal and call UIE.
|
|
||||||
*/
|
|
||||||
software_int_handler:
|
|
||||||
reserved_handler:
|
|
||||||
sub r0, lr, #4
|
|
||||||
mov r1, #4
|
|
||||||
b UIE
|
|
||||||
|
|
||||||
prefetch_abort_handler:
|
|
||||||
sub r0, lr, #4
|
|
||||||
mov r1, #1
|
|
||||||
b UIE
|
|
||||||
|
|
||||||
data_abort_handler:
|
|
||||||
sub r0, lr, #8
|
|
||||||
mov r1, #2
|
|
||||||
b UIE
|
|
||||||
|
|
||||||
irq_handler:
|
irq_handler:
|
||||||
stmfd sp!, {r0-r3, r12, lr}
|
stmfd sp!, {r0-r3, r12, lr}
|
||||||
bl irq
|
bl irq
|
||||||
|
|
|
@ -282,35 +282,6 @@ vectors_end:
|
||||||
|
|
||||||
.text
|
.text
|
||||||
|
|
||||||
/* All illegal exceptions call into UIE with exception address as first
|
|
||||||
parameter. This is calculated differently depending on which exception
|
|
||||||
we're in. Second parameter is exception number, used for a string lookup
|
|
||||||
in UIE.
|
|
||||||
*/
|
|
||||||
undef_instr_handler:
|
|
||||||
sub r0, lr, #4
|
|
||||||
mov r1, #0
|
|
||||||
b UIE
|
|
||||||
|
|
||||||
/* We run sys mode most of the time, and should never see a software
|
|
||||||
exception being thrown. Make it illegal and call UIE.
|
|
||||||
*/
|
|
||||||
software_int_handler:
|
|
||||||
reserved_handler:
|
|
||||||
sub r0, lr, #4
|
|
||||||
mov r1, #4
|
|
||||||
b UIE
|
|
||||||
|
|
||||||
prefetch_abort_handler:
|
|
||||||
sub r0, lr, #4
|
|
||||||
mov r1, #1
|
|
||||||
b UIE
|
|
||||||
|
|
||||||
data_abort_handler:
|
|
||||||
sub r0, lr, #8
|
|
||||||
mov r1, #2
|
|
||||||
b UIE
|
|
||||||
|
|
||||||
#ifdef BOOTLOADER
|
#ifdef BOOTLOADER
|
||||||
fiq_handler:
|
fiq_handler:
|
||||||
subs pc, lr, #4
|
subs pc, lr, #4
|
||||||
|
|
|
@ -291,51 +291,6 @@ _delay_cycles:
|
||||||
.ltorg
|
.ltorg
|
||||||
.size _delay_cycles, .-_delay_cycles
|
.size _delay_cycles, .-_delay_cycles
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* Unused exception vectors. These call the UIE function. *
|
|
||||||
* Arguements are: *
|
|
||||||
* r0: PC of exception *
|
|
||||||
* r1: Exception number. *
|
|
||||||
* Exception numbers are as defined: *
|
|
||||||
* 0: Undefined Instruction *
|
|
||||||
* 1: Prefetch Abort *
|
|
||||||
* 2: Data Abort *
|
|
||||||
* 3: DIV0 *
|
|
||||||
* 4: SWI *
|
|
||||||
* The exceptions return operations are documented in section A2.6 of the *
|
|
||||||
* ARM Architecture Reference Manual. *
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
/* A2.6.3: Undefined Instruction Exception - LR=PC of next instruction */
|
|
||||||
_undefined_instruction:
|
|
||||||
sub r0, lr, #4
|
|
||||||
mov r1, #0
|
|
||||||
bl UIE
|
|
||||||
|
|
||||||
/* A2.6.4: Software Interrupt exception - These should not happen in Rockbox,
|
|
||||||
* make it illegal
|
|
||||||
*/
|
|
||||||
_software_interrupt:
|
|
||||||
sub r0, lr, #4
|
|
||||||
mov r1, #4
|
|
||||||
bl UIE
|
|
||||||
|
|
||||||
/* A2.6.5 Prefetch Abort - This is also the BKPT instruction since this is a
|
|
||||||
* v5 target. Pass it on to UIE since it is not currently used.
|
|
||||||
*/
|
|
||||||
_prefetch_abort:
|
|
||||||
sub r0, lr, #4
|
|
||||||
mov r1, #1
|
|
||||||
bl UIE
|
|
||||||
|
|
||||||
/* A2.6.6 Data Abort - There was a memory abort, can return after fixing cause
|
|
||||||
* with the LR address.
|
|
||||||
*/
|
|
||||||
_data_abort:
|
|
||||||
sub r0, lr, #8
|
|
||||||
mov r1, #2
|
|
||||||
bl UIE
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* _dead_loop: Something really unexpected happened (like a reserved *
|
* _dead_loop: Something really unexpected happened (like a reserved *
|
||||||
* exception). Just hang. *
|
* exception). Just hang. *
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue