Changeset View
Changeset View
Standalone View
Standalone View
sys/riscv/riscv/trap.c
Show First 20 Lines • Show All 152 Lines • ▼ Show 20 Lines | dump_regs(struct trapframe *frame) | ||||
printf("gp == 0x%016lx\n", frame->tf_gp); | printf("gp == 0x%016lx\n", frame->tf_gp); | ||||
printf("tp == 0x%016lx\n", frame->tf_tp); | printf("tp == 0x%016lx\n", frame->tf_tp); | ||||
printf("sepc == 0x%016lx\n", frame->tf_sepc); | printf("sepc == 0x%016lx\n", frame->tf_sepc); | ||||
printf("sstatus == 0x%016lx\n", frame->tf_sstatus); | printf("sstatus == 0x%016lx\n", frame->tf_sstatus); | ||||
} | } | ||||
static void | static void | ||||
svc_handler(struct trapframe *frame) | svc_handler(void) | ||||
mhorne: IMO we should either keep the trapframe argument or just inline the contents of `svc_handler`… | |||||
{ | { | ||||
struct thread *td; | struct thread *td; | ||||
td = curthread; | td = curthread; | ||||
KASSERT(td->td_frame == frame, | |||||
("%s: td_frame %p != frame %p", __func__, td->td_frame, frame)); | |||||
syscallenter(td); | syscallenter(td); | ||||
syscallret(td); | syscallret(td); | ||||
} | } | ||||
static void | static void | ||||
data_abort(struct trapframe *frame, int usermode) | data_abort(struct trapframe *frame, int usermode) | ||||
{ | { | ||||
struct vm_map *map; | struct vm_map *map; | ||||
▲ Show 20 Lines • Show All 148 Lines • ▼ Show 20 Lines | do_trap_user(struct trapframe *frame) | ||||
td = curthread; | td = curthread; | ||||
td->td_frame = frame; | td->td_frame = frame; | ||||
pcb = td->td_pcb; | pcb = td->td_pcb; | ||||
/* Ensure we came from usermode, interrupts disabled */ | /* Ensure we came from usermode, interrupts disabled */ | ||||
KASSERT((csr_read(sstatus) & (SSTATUS_SPP | SSTATUS_SIE)) == 0, | KASSERT((csr_read(sstatus) & (SSTATUS_SPP | SSTATUS_SIE)) == 0, | ||||
("Came from U mode with interrupts enabled")); | ("Came from U mode with interrupts enabled")); | ||||
if (__predict_true(frame->tf_scause == EXCP_USER_ECALL)) { | |||||
KASSERT(td->td_frame == frame, | |||||
mhorneUnsubmitted Not Done Inline ActionsThis assert seems less useful than before, since the assignment it checks for is now visible a few lines prior. mhorne: This assert seems less useful than before, since the assignment it checks for is now visible a… | |||||
("%s: td_frame %p != frame %p", __func__, td->td_frame, frame)); | |||||
intr_enable(); | |||||
frame->tf_sepc += 4; | |||||
svc_handler(); | |||||
return; | |||||
} | |||||
exception = frame->tf_scause & EXCP_MASK; | exception = frame->tf_scause & EXCP_MASK; | ||||
if (frame->tf_scause & EXCP_INTR) { | if (frame->tf_scause & EXCP_INTR) { | ||||
/* Interrupt */ | /* Interrupt */ | ||||
riscv_cpu_intr(frame); | riscv_cpu_intr(frame); | ||||
return; | return; | ||||
} | } | ||||
intr_enable(); | intr_enable(); | ||||
CTR3(KTR_TRAP, "do_trap_user: curthread: %p, sepc: %lx, frame: %p", | CTR3(KTR_TRAP, "do_trap_user: curthread: %p, sepc: %lx, frame: %p", | ||||
curthread, frame->tf_sepc, frame); | curthread, frame->tf_sepc, frame); | ||||
switch (exception) { | switch (exception) { | ||||
case EXCP_FAULT_LOAD: | case EXCP_FAULT_LOAD: | ||||
case EXCP_FAULT_STORE: | case EXCP_FAULT_STORE: | ||||
case EXCP_FAULT_FETCH: | case EXCP_FAULT_FETCH: | ||||
call_trapsignal(td, SIGBUS, BUS_ADRERR, (void *)frame->tf_sepc, | call_trapsignal(td, SIGBUS, BUS_ADRERR, (void *)frame->tf_sepc, | ||||
exception); | exception); | ||||
userret(td, frame); | userret(td, frame); | ||||
break; | break; | ||||
case EXCP_STORE_PAGE_FAULT: | case EXCP_STORE_PAGE_FAULT: | ||||
case EXCP_LOAD_PAGE_FAULT: | case EXCP_LOAD_PAGE_FAULT: | ||||
case EXCP_INST_PAGE_FAULT: | case EXCP_INST_PAGE_FAULT: | ||||
data_abort(frame, 1); | data_abort(frame, 1); | ||||
break; | |||||
case EXCP_USER_ECALL: | |||||
frame->tf_sepc += 4; /* Next instruction */ | |||||
svc_handler(frame); | |||||
break; | break; | ||||
case EXCP_ILLEGAL_INSTRUCTION: | case EXCP_ILLEGAL_INSTRUCTION: | ||||
#ifdef FPE | #ifdef FPE | ||||
if ((pcb->pcb_fpflags & PCB_FP_STARTED) == 0) { | if ((pcb->pcb_fpflags & PCB_FP_STARTED) == 0) { | ||||
/* | /* | ||||
* May be a FPE trap. Enable FPE usage | * May be a FPE trap. Enable FPE usage | ||||
* for this thread and try again. | * for this thread and try again. | ||||
*/ | */ | ||||
Show All 22 Lines |
IMO we should either keep the trapframe argument or just inline the contents of svc_handler completely.