Changeset View
Changeset View
Standalone View
Standalone View
head/sys/arm/arm/trap-v6.c
Show First 20 Lines • Show All 163 Lines • ▼ Show 20 Lines | static const struct abort aborts[] = { | ||||
{abort_fatal, "Undefined Code (0x40B)"}, | {abort_fatal, "Undefined Code (0x40B)"}, | ||||
{abort_fatal, "Parity Error on Translation (L1)"}, | {abort_fatal, "Parity Error on Translation (L1)"}, | ||||
{abort_fatal, "Undefined Code (0x40D)"}, | {abort_fatal, "Undefined Code (0x40D)"}, | ||||
{abort_fatal, "Parity Error on Translation (L2)"}, | {abort_fatal, "Parity Error on Translation (L2)"}, | ||||
{abort_fatal, "Undefined Code (0x40F)"} | {abort_fatal, "Undefined Code (0x40F)"} | ||||
}; | }; | ||||
static __inline void | static __inline void | ||||
call_trapsignal(struct thread *td, int sig, int code, vm_offset_t addr) | call_trapsignal(struct thread *td, int sig, int code, vm_offset_t addr, | ||||
int trapno) | |||||
{ | { | ||||
ksiginfo_t ksi; | ksiginfo_t ksi; | ||||
CTR4(KTR_TRAP, "%s: addr: %#x, sig: %d, code: %d", | CTR4(KTR_TRAP, "%s: addr: %#x, sig: %d, code: %d", | ||||
__func__, addr, sig, code); | __func__, addr, sig, code); | ||||
/* | /* | ||||
* TODO: some info would be nice to know | * TODO: some info would be nice to know | ||||
* if we are serving data or prefetch abort. | * if we are serving data or prefetch abort. | ||||
*/ | */ | ||||
ksiginfo_init_trap(&ksi); | ksiginfo_init_trap(&ksi); | ||||
ksi.ksi_signo = sig; | ksi.ksi_signo = sig; | ||||
ksi.ksi_code = code; | ksi.ksi_code = code; | ||||
ksi.ksi_addr = (void *)addr; | ksi.ksi_addr = (void *)addr; | ||||
ksi.ksi_trapno = trapno; | |||||
trapsignal(td, &ksi); | trapsignal(td, &ksi); | ||||
} | } | ||||
/* | /* | ||||
* abort_imprecise() handles the following abort: | * abort_imprecise() handles the following abort: | ||||
* | * | ||||
* FAULT_EA_IMPREC - Imprecise External Abort | * FAULT_EA_IMPREC - Imprecise External Abort | ||||
* | * | ||||
▲ Show 20 Lines • Show All 51 Lines • ▼ Show 20 Lines | |||||
abort_debug(struct trapframe *tf, u_int fsr, u_int prefetch, bool usermode, | abort_debug(struct trapframe *tf, u_int fsr, u_int prefetch, bool usermode, | ||||
u_int far) | u_int far) | ||||
{ | { | ||||
if (usermode) { | if (usermode) { | ||||
struct thread *td; | struct thread *td; | ||||
td = curthread; | td = curthread; | ||||
call_trapsignal(td, SIGTRAP, TRAP_BRKPT, far); | call_trapsignal(td, SIGTRAP, TRAP_BRKPT, far, FAULT_DEBUG); | ||||
userret(td, tf); | userret(td, tf); | ||||
} else { | } else { | ||||
#ifdef KDB | #ifdef KDB | ||||
kdb_trap((prefetch) ? T_BREAKPOINT : T_WATCHPOINT, 0, tf); | kdb_trap((prefetch) ? T_BREAKPOINT : T_WATCHPOINT, 0, tf); | ||||
#else | #else | ||||
printf("No debugger in kernel.\n"); | printf("No debugger in kernel.\n"); | ||||
#endif | #endif | ||||
} | } | ||||
▲ Show 20 Lines • Show All 254 Lines • ▼ Show 20 Lines | if (!usermode) { | ||||
CTR2(KTR_TRAP, "%s: vm_fault() failed with %d", __func__, rv); | CTR2(KTR_TRAP, "%s: vm_fault() failed with %d", __func__, rv); | ||||
abort_fatal(tf, idx, fsr, far, prefetch, td, &ksig); | abort_fatal(tf, idx, fsr, far, prefetch, td, &ksig); | ||||
return; | return; | ||||
} | } | ||||
ksig.addr = far; | ksig.addr = far; | ||||
do_trapsignal: | do_trapsignal: | ||||
call_trapsignal(td, ksig.sig, ksig.code, ksig.addr); | call_trapsignal(td, ksig.sig, ksig.code, ksig.addr, idx); | ||||
out: | out: | ||||
if (usermode) | if (usermode) | ||||
userret(td, tf); | userret(td, tf); | ||||
} | } | ||||
/* | /* | ||||
* abort_fatal() handles the following data aborts: | * abort_fatal() handles the following data aborts: | ||||
* | * | ||||
▲ Show 20 Lines • Show All 131 Lines • Show Last 20 Lines |