ARM: Allow to mask data aborts
Sometimes it's useful to test if a memory operation works or aborts. This adds data_abort_mask() to ignore data aborts and data_abort_unmask() to enable them again. This is used in the next step for the 'md' command so that illegal addresses just show 'xxxxxxxx' instead of crashing the system. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
This commit is contained in:
parent
86759346ba
commit
b42a3e2f68
|
@ -88,6 +88,21 @@
|
||||||
movs pc, lr
|
movs pc, lr
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
|
.macro try_data_abort
|
||||||
|
ldr r13, =arm_ignore_data_abort @ check try mode
|
||||||
|
ldr r13, [r13]
|
||||||
|
cmp r13, #0
|
||||||
|
beq do_abort_\@
|
||||||
|
ldr r13, =arm_data_abort_occurred
|
||||||
|
str r13, [r13]
|
||||||
|
mrs r13, spsr @ read saved CPSR
|
||||||
|
tst r13, #1<<5 @ check Thumb mode
|
||||||
|
subeq lr, #4 @ next ARM instr
|
||||||
|
subne lr, #6 @ next Thumb instr
|
||||||
|
movs pc, lr
|
||||||
|
do_abort_\@:
|
||||||
|
.endm
|
||||||
|
|
||||||
.macro get_irq_stack @ setup IRQ stack
|
.macro get_irq_stack @ setup IRQ stack
|
||||||
ldr sp, IRQ_STACK_START
|
ldr sp, IRQ_STACK_START
|
||||||
.endm
|
.endm
|
||||||
|
@ -122,6 +137,7 @@ prefetch_abort:
|
||||||
|
|
||||||
.align 5
|
.align 5
|
||||||
data_abort:
|
data_abort:
|
||||||
|
try_data_abort
|
||||||
get_bad_stack
|
get_bad_stack
|
||||||
bad_save_user_regs
|
bad_save_user_regs
|
||||||
bl do_data_abort
|
bl do_data_abort
|
||||||
|
@ -202,5 +218,11 @@ _fiq: .word fiq
|
||||||
|
|
||||||
.section .data
|
.section .data
|
||||||
.align 4
|
.align 4
|
||||||
|
.global arm_ignore_data_abort
|
||||||
|
arm_ignore_data_abort:
|
||||||
|
.word arm_ignore_data_abort /* When != 0 data aborts are ignored */
|
||||||
|
.global arm_data_abort_occurred
|
||||||
|
arm_data_abort_occurred:
|
||||||
|
.word arm_data_abort_occurred /* set != 0 by the data abort handler */
|
||||||
abort_stack:
|
abort_stack:
|
||||||
.space 8
|
.space 8
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
|
#include <abort.h>
|
||||||
#include <asm/ptrace.h>
|
#include <asm/ptrace.h>
|
||||||
#include <asm/unwind.h>
|
#include <asm/unwind.h>
|
||||||
|
|
||||||
|
@ -161,3 +162,19 @@ void do_irq (struct pt_regs *pt_regs)
|
||||||
printf ("interrupt request\n");
|
printf ("interrupt request\n");
|
||||||
do_exception(pt_regs);
|
do_exception(pt_regs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern volatile int arm_ignore_data_abort;
|
||||||
|
extern volatile int arm_data_abort_occurred;
|
||||||
|
|
||||||
|
void data_abort_mask(void)
|
||||||
|
{
|
||||||
|
arm_data_abort_occurred = 0;
|
||||||
|
arm_ignore_data_abort = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int data_abort_unmask(void)
|
||||||
|
{
|
||||||
|
arm_ignore_data_abort = 0;
|
||||||
|
|
||||||
|
return arm_data_abort_occurred != 0;
|
||||||
|
}
|
||||||
|
|
|
@ -5,4 +5,8 @@
|
||||||
#define ARCH_HAS_STACK_DUMP
|
#define ARCH_HAS_STACK_DUMP
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_ARM_EXCEPTIONS
|
||||||
|
#define ARCH_HAS_DATA_ABORT_MASK
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* _BAREBOX_H_ */
|
#endif /* _BAREBOX_H_ */
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
#ifndef __ABORT_H
|
||||||
|
#define __ABORT_H
|
||||||
|
|
||||||
|
#include <asm/barebox.h>
|
||||||
|
|
||||||
|
#ifdef ARCH_HAS_DATA_ABORT_MASK
|
||||||
|
|
||||||
|
/*
|
||||||
|
* data_abort_mask - ignore data aborts
|
||||||
|
*
|
||||||
|
* If data aborts are ignored the data abort handler
|
||||||
|
* will just return.
|
||||||
|
*/
|
||||||
|
void data_abort_mask(void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* data_abort_unmask - Enable data aborts
|
||||||
|
*
|
||||||
|
* returns true if a data abort has happened between calling data_abort_mask()
|
||||||
|
* and data_abort_unmask()
|
||||||
|
*/
|
||||||
|
int data_abort_unmask(void);
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
static inline void data_abort_mask(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int data_abort_unmask(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __ABORT_H */
|
Loading…
Reference in New Issue