Changeset View
Changeset View
Standalone View
Standalone View
sys/arm64/arm64/trap.c
Show First 20 Lines • Show All 354 Lines • ▼ Show 20 Lines | print_registers(struct trapframe *frame) | ||||
printf(" lr: %16lx\n", frame->tf_lr); | printf(" lr: %16lx\n", frame->tf_lr); | ||||
printf(" elr: %16lx\n", frame->tf_elr); | printf(" elr: %16lx\n", frame->tf_elr); | ||||
printf("spsr: %8x\n", frame->tf_spsr); | printf("spsr: %8x\n", frame->tf_spsr); | ||||
} | } | ||||
void | void | ||||
do_el1h_sync(struct thread *td, struct trapframe *frame) | do_el1h_sync(struct thread *td, struct trapframe *frame) | ||||
{ | { | ||||
struct trapframe *oframe; | |||||
uint32_t exception; | uint32_t exception; | ||||
uint64_t esr, far; | uint64_t esr, far; | ||||
int dfsc; | int dfsc; | ||||
/* Read the esr register to get the exception details */ | /* Read the esr register to get the exception details */ | ||||
esr = frame->tf_esr; | esr = frame->tf_esr; | ||||
exception = ESR_ELx_EXCEPTION(esr); | exception = ESR_ELx_EXCEPTION(esr); | ||||
#ifdef KDTRACE_HOOKS | #ifdef KDTRACE_HOOKS | ||||
if (dtrace_trap_func != NULL && (*dtrace_trap_func)(frame, exception)) | if (dtrace_trap_func != NULL && (*dtrace_trap_func)(frame, exception)) | ||||
return; | return; | ||||
#endif | #endif | ||||
CTR4(KTR_TRAP, | CTR4(KTR_TRAP, | ||||
"do_el1_sync: curthread: %p, esr %lx, elr: %lx, frame: %p", td, | "do_el1_sync: curthread: %p, esr %lx, elr: %lx, frame: %p", td, | ||||
esr, frame->tf_elr, frame); | esr, frame->tf_elr, frame); | ||||
oframe = td->td_frame; | |||||
switch (exception) { | switch (exception) { | ||||
case EXCP_BRK: | |||||
case EXCP_WATCHPT_EL1: | |||||
case EXCP_SOFTSTP_EL1: | |||||
break; | |||||
default: | |||||
td->td_frame = frame; | |||||
break; | |||||
} | |||||
switch (exception) { | |||||
case EXCP_FP_SIMD: | case EXCP_FP_SIMD: | ||||
case EXCP_TRAP_FP: | case EXCP_TRAP_FP: | ||||
#ifdef VFP | #ifdef VFP | ||||
if ((td->td_pcb->pcb_fpflags & PCB_FP_KERN) != 0) { | if ((td->td_pcb->pcb_fpflags & PCB_FP_KERN) != 0) { | ||||
vfp_restore_state(); | vfp_restore_state(); | ||||
} else | } else | ||||
#endif | #endif | ||||
{ | { | ||||
Show All 22 Lines | |||||
#ifdef KDTRACE_HOOKS | #ifdef KDTRACE_HOOKS | ||||
if ((esr & ESR_ELx_ISS_MASK) == 0x40d && \ | if ((esr & ESR_ELx_ISS_MASK) == 0x40d && \ | ||||
dtrace_invop_jump_addr != 0) { | dtrace_invop_jump_addr != 0) { | ||||
dtrace_invop_jump_addr(frame); | dtrace_invop_jump_addr(frame); | ||||
break; | break; | ||||
} | } | ||||
#endif | #endif | ||||
#ifdef KDB | #ifdef KDB | ||||
kdb_trap(exception, 0, | kdb_trap(exception, 0, frame); | ||||
(td->td_frame != NULL) ? td->td_frame : frame); | |||||
#else | #else | ||||
panic("No debugger in kernel.\n"); | panic("No debugger in kernel.\n"); | ||||
#endif | #endif | ||||
frame->tf_elr += 4; | |||||
break; | break; | ||||
andrew: You need to remove this so the next instruction is executed | |||||
Not Done Inline ActionsIs it not now going to just return and immediately re-trap on the same breakpoint instruction? jrtc27: Is it not now going to just return and immediately re-trap on the same breakpoint instruction? | |||||
Done Inline ActionsFor ddb, tf_elr is advanced by BKPT_SKIP in db_stop_at_pc. For gdb, the client advances the PC. Previously this would have been applied to td->td_frame, not frame, hence the need for the manual increment here. mhorne: For ddb, `tf_elr` is advanced by `BKPT_SKIP` in `db_stop_at_pc`. For gdb, the client advances… | |||||
Not Done Inline ActionsOk thanks jrtc27: Ok thanks | |||||
case EXCP_WATCHPT_EL1: | case EXCP_WATCHPT_EL1: | ||||
case EXCP_SOFTSTP_EL1: | case EXCP_SOFTSTP_EL1: | ||||
#ifdef KDB | #ifdef KDB | ||||
kdb_trap(exception, 0, | kdb_trap(exception, 0, frame); | ||||
(td->td_frame != NULL) ? td->td_frame : frame); | |||||
#else | #else | ||||
panic("No debugger in kernel.\n"); | panic("No debugger in kernel.\n"); | ||||
#endif | #endif | ||||
break; | break; | ||||
case EXCP_UNKNOWN: | case EXCP_UNKNOWN: | ||||
if (undef_insn(1, frame)) | if (undef_insn(1, frame)) | ||||
break; | break; | ||||
/* FALLTHROUGH */ | /* FALLTHROUGH */ | ||||
default: | default: | ||||
print_registers(frame); | print_registers(frame); | ||||
printf(" far: %16lx\n", READ_SPECIALREG(far_el1)); | printf(" far: %16lx\n", READ_SPECIALREG(far_el1)); | ||||
panic("Unknown kernel exception %x esr_el1 %lx\n", exception, | panic("Unknown kernel exception %x esr_el1 %lx\n", exception, | ||||
esr); | esr); | ||||
} | } | ||||
td->td_frame = oframe; | |||||
} | } | ||||
void | void | ||||
do_el0_sync(struct thread *td, struct trapframe *frame) | do_el0_sync(struct thread *td, struct trapframe *frame) | ||||
{ | { | ||||
pcpu_bp_harden bp_harden; | pcpu_bp_harden bp_harden; | ||||
uint32_t exception; | uint32_t exception; | ||||
uint64_t esr, far; | uint64_t esr, far; | ||||
▲ Show 20 Lines • Show All 145 Lines • Show Last 20 Lines |
You need to remove this so the next instruction is executed