arm64: extend ESR/SPSR registers to 64b
For the Exception Syndrome Register, ESR_ELx, the upper 32b were previously unused, but now may contain additional exception info as of Armv8.7 (FEAT_LS64). Extend ESR from u32->u64 in exception handling code to support this. In addition, also extend Saved Program Status Register SPSR_ELx in the same way to allow for future extensions. Reviewed by: andrew Sponsored by: Arm Ltd Differential Revision: https://reviews.freebsd.org/D38983
This commit is contained in:
parent
c6b3f47fed
commit
2ecbbcc7ca
@ -102,18 +102,18 @@ db_stack_trace_cmd(struct thread *td, struct unwind_state *frame)
|
|||||||
|
|
||||||
switch (frame_type) {
|
switch (frame_type) {
|
||||||
case FRAME_SYNC:
|
case FRAME_SYNC:
|
||||||
db_printf("--- exception, esr %#x\n",
|
db_printf("--- exception, esr %#lx\n",
|
||||||
tf->tf_esr);
|
tf->tf_esr);
|
||||||
break;
|
break;
|
||||||
case FRAME_IRQ:
|
case FRAME_IRQ:
|
||||||
db_printf("--- interrupt\n");
|
db_printf("--- interrupt\n");
|
||||||
break;
|
break;
|
||||||
case FRAME_SERROR:
|
case FRAME_SERROR:
|
||||||
db_printf("--- system error, esr %#x\n",
|
db_printf("--- system error, esr %#lx\n",
|
||||||
tf->tf_esr);
|
tf->tf_esr);
|
||||||
break;
|
break;
|
||||||
case FRAME_UNHANDLED:
|
case FRAME_UNHANDLED:
|
||||||
db_printf("--- unhandled exception, esr %#x\n",
|
db_printf("--- unhandled exception, esr %#lx\n",
|
||||||
tf->tf_esr);
|
tf->tf_esr);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -67,7 +67,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
mrs x12, esr_el1
|
mrs x12, esr_el1
|
||||||
stp x18, lr, [sp, #(TF_SP - TF_X)]!
|
stp x18, lr, [sp, #(TF_SP - TF_X)]!
|
||||||
str x10, [sp, #(TF_ELR)]
|
str x10, [sp, #(TF_ELR)]
|
||||||
stp w11, w12, [sp, #(TF_SPSR)]
|
stp x11, x12, [sp, #(TF_SPSR)]
|
||||||
mrs x18, tpidr_el1
|
mrs x18, tpidr_el1
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
|
@ -457,7 +457,7 @@ int
|
|||||||
set_mcontext(struct thread *td, mcontext_t *mcp)
|
set_mcontext(struct thread *td, mcontext_t *mcp)
|
||||||
{
|
{
|
||||||
struct trapframe *tf = td->td_frame;
|
struct trapframe *tf = td->td_frame;
|
||||||
uint32_t spsr;
|
uint64_t spsr;
|
||||||
|
|
||||||
spsr = mcp->mc_gpregs.gp_spsr;
|
spsr = mcp->mc_gpregs.gp_spsr;
|
||||||
if ((spsr & PSR_M_MASK) != PSR_M_EL0t ||
|
if ((spsr & PSR_M_MASK) != PSR_M_EL0t ||
|
||||||
|
@ -212,7 +212,7 @@ align_abort(struct thread *td, struct trapframe *frame, uint64_t esr,
|
|||||||
if (!lower) {
|
if (!lower) {
|
||||||
print_registers(frame);
|
print_registers(frame);
|
||||||
print_gp_register("far", far);
|
print_gp_register("far", far);
|
||||||
printf(" esr: %.8lx\n", esr);
|
printf(" esr: %.16lx\n", esr);
|
||||||
panic("Misaligned access from kernel space!");
|
panic("Misaligned access from kernel space!");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -329,7 +329,7 @@ data_abort(struct thread *td, struct trapframe *frame, uint64_t esr,
|
|||||||
WARN_GIANTOK, NULL, "Kernel page fault") != 0) {
|
WARN_GIANTOK, NULL, "Kernel page fault") != 0) {
|
||||||
print_registers(frame);
|
print_registers(frame);
|
||||||
print_gp_register("far", far);
|
print_gp_register("far", far);
|
||||||
printf(" esr: %.8lx\n", esr);
|
printf(" esr: %.16lx\n", esr);
|
||||||
panic("data abort in critical section or under mutex");
|
panic("data abort in critical section or under mutex");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -370,7 +370,7 @@ data_abort(struct thread *td, struct trapframe *frame, uint64_t esr,
|
|||||||
printf("Fatal data abort:\n");
|
printf("Fatal data abort:\n");
|
||||||
print_registers(frame);
|
print_registers(frame);
|
||||||
print_gp_register("far", far);
|
print_gp_register("far", far);
|
||||||
printf(" esr: %.8lx\n", esr);
|
printf(" esr: %.16lx\n", esr);
|
||||||
|
|
||||||
#ifdef KDB
|
#ifdef KDB
|
||||||
if (debugger_on_trap) {
|
if (debugger_on_trap) {
|
||||||
@ -429,7 +429,7 @@ print_registers(struct trapframe *frame)
|
|||||||
printf(" sp: %16lx\n", frame->tf_sp);
|
printf(" sp: %16lx\n", frame->tf_sp);
|
||||||
print_gp_register(" lr", frame->tf_lr);
|
print_gp_register(" lr", frame->tf_lr);
|
||||||
print_gp_register("elr", frame->tf_elr);
|
print_gp_register("elr", frame->tf_elr);
|
||||||
printf("spsr: %8x\n", frame->tf_spsr);
|
printf("spsr: %16lx\n", frame->tf_spsr);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef VFP
|
#ifdef VFP
|
||||||
@ -496,7 +496,7 @@ do_el1h_sync(struct thread *td, struct trapframe *frame)
|
|||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
print_registers(frame);
|
print_registers(frame);
|
||||||
printf(" esr: %.8lx\n", esr);
|
printf(" esr: %.16lx\n", esr);
|
||||||
panic("VFP exception in the kernel");
|
panic("VFP exception in the kernel");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -510,7 +510,7 @@ do_el1h_sync(struct thread *td, struct trapframe *frame)
|
|||||||
} else {
|
} else {
|
||||||
print_registers(frame);
|
print_registers(frame);
|
||||||
print_gp_register("far", far);
|
print_gp_register("far", far);
|
||||||
printf(" esr: %.8lx\n", esr);
|
printf(" esr: %.16lx\n", esr);
|
||||||
panic("Unhandled EL1 %s abort: %x",
|
panic("Unhandled EL1 %s abort: %x",
|
||||||
exception == EXCP_INSN_ABORT ? "instruction" :
|
exception == EXCP_INSN_ABORT ? "instruction" :
|
||||||
"data", dfsc);
|
"data", dfsc);
|
||||||
@ -624,7 +624,7 @@ do_el0_sync(struct thread *td, struct trapframe *frame, uint64_t far)
|
|||||||
else {
|
else {
|
||||||
print_registers(frame);
|
print_registers(frame);
|
||||||
print_gp_register("far", far);
|
print_gp_register("far", far);
|
||||||
printf(" esr: %.8lx\n", esr);
|
printf(" esr: %.16lx\n", esr);
|
||||||
panic("Unhandled EL0 %s abort: %x",
|
panic("Unhandled EL0 %s abort: %x",
|
||||||
exception == EXCP_INSN_ABORT_L ? "instruction" :
|
exception == EXCP_INSN_ABORT_L ? "instruction" :
|
||||||
"data", dfsc);
|
"data", dfsc);
|
||||||
@ -716,7 +716,7 @@ do_serror(struct trapframe *frame)
|
|||||||
|
|
||||||
print_registers(frame);
|
print_registers(frame);
|
||||||
print_gp_register("far", far);
|
print_gp_register("far", far);
|
||||||
printf(" esr: %.8lx\n", esr);
|
printf(" esr: %.16lx\n", esr);
|
||||||
panic("Unhandled System Error");
|
panic("Unhandled System Error");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -730,6 +730,6 @@ unhandled_exception(struct trapframe *frame)
|
|||||||
|
|
||||||
print_registers(frame);
|
print_registers(frame);
|
||||||
print_gp_register("far", far);
|
print_gp_register("far", far);
|
||||||
printf(" esr: %.8lx\n", esr);
|
printf(" esr: %.16lx\n", esr);
|
||||||
panic("Unhandled exception");
|
panic("Unhandled exception");
|
||||||
}
|
}
|
||||||
|
@ -45,8 +45,9 @@ struct trapframe {
|
|||||||
uint64_t tf_sp;
|
uint64_t tf_sp;
|
||||||
uint64_t tf_lr;
|
uint64_t tf_lr;
|
||||||
uint64_t tf_elr;
|
uint64_t tf_elr;
|
||||||
uint32_t tf_spsr;
|
uint64_t tf_spsr;
|
||||||
uint32_t tf_esr;
|
uint64_t tf_esr;
|
||||||
|
uint64_t pad; /* struct must be 16B aligned */
|
||||||
uint64_t tf_x[30];
|
uint64_t tf_x[30];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ struct reg {
|
|||||||
__uint64_t lr;
|
__uint64_t lr;
|
||||||
__uint64_t sp;
|
__uint64_t sp;
|
||||||
__uint64_t elr;
|
__uint64_t elr;
|
||||||
__uint32_t spsr;
|
__uint64_t spsr;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct reg32 {
|
struct reg32 {
|
||||||
|
@ -38,8 +38,7 @@ struct gpregs {
|
|||||||
__register_t gp_lr;
|
__register_t gp_lr;
|
||||||
__register_t gp_sp;
|
__register_t gp_sp;
|
||||||
__register_t gp_elr;
|
__register_t gp_elr;
|
||||||
__uint32_t gp_spsr;
|
__uint64_t gp_spsr;
|
||||||
int gp_pad;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct fpregs {
|
struct fpregs {
|
||||||
|
Loading…
Reference in New Issue
Block a user