Changeset View
Changeset View
Standalone View
Standalone View
head/sys/riscv/riscv/trap.c
Show First 20 Lines • Show All 74 Lines • ▼ Show 20 Lines | |||||
extern register_t fsu_intr_fault; | extern register_t fsu_intr_fault; | ||||
/* Called from exception.S */ | /* Called from exception.S */ | ||||
void do_trap_supervisor(struct trapframe *); | void do_trap_supervisor(struct trapframe *); | ||||
void do_trap_user(struct trapframe *); | void do_trap_user(struct trapframe *); | ||||
static __inline void | static __inline void | ||||
call_trapsignal(struct thread *td, int sig, int code, void *addr) | call_trapsignal(struct thread *td, int sig, int code, void *addr, int trapno) | ||||
{ | { | ||||
ksiginfo_t ksi; | ksiginfo_t ksi; | ||||
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 = addr; | ksi.ksi_addr = addr; | ||||
ksi.ksi_trapno = trapno; | |||||
trapsignal(td, &ksi); | trapsignal(td, &ksi); | ||||
} | } | ||||
int | int | ||||
cpu_fetch_syscall_args(struct thread *td) | cpu_fetch_syscall_args(struct thread *td) | ||||
{ | { | ||||
struct proc *p; | struct proc *p; | ||||
register_t *ap; | register_t *ap; | ||||
▲ Show 20 Lines • Show All 120 Lines • ▼ Show 20 Lines | #endif | ||||
} | } | ||||
if (pmap_fault_fixup(map->pmap, va, ftype)) | if (pmap_fault_fixup(map->pmap, va, ftype)) | ||||
goto done; | goto done; | ||||
error = vm_fault_trap(map, va, ftype, VM_FAULT_NORMAL, &sig, &ucode); | error = vm_fault_trap(map, va, ftype, VM_FAULT_NORMAL, &sig, &ucode); | ||||
if (error != KERN_SUCCESS) { | if (error != KERN_SUCCESS) { | ||||
if (usermode) { | if (usermode) { | ||||
call_trapsignal(td, sig, ucode, (void *)stval); | call_trapsignal(td, sig, ucode, (void *)stval, | ||||
frame->tf_scause & EXCP_MASK); | |||||
} else { | } else { | ||||
if (pcb->pcb_onfault != 0) { | if (pcb->pcb_onfault != 0) { | ||||
frame->tf_a[0] = error; | frame->tf_a[0] = error; | ||||
frame->tf_sepc = pcb->pcb_onfault; | frame->tf_sepc = pcb->pcb_onfault; | ||||
return; | return; | ||||
} | } | ||||
goto fatal; | goto fatal; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 112 Lines • ▼ Show 20 Lines | if ((pcb->pcb_fpflags & PCB_FP_STARTED) == 0) { | ||||
*/ | */ | ||||
fpe_state_clear(); | fpe_state_clear(); | ||||
frame->tf_sstatus &= ~SSTATUS_FS_MASK; | frame->tf_sstatus &= ~SSTATUS_FS_MASK; | ||||
frame->tf_sstatus |= SSTATUS_FS_CLEAN; | frame->tf_sstatus |= SSTATUS_FS_CLEAN; | ||||
pcb->pcb_fpflags |= PCB_FP_STARTED; | pcb->pcb_fpflags |= PCB_FP_STARTED; | ||||
break; | break; | ||||
} | } | ||||
#endif | #endif | ||||
call_trapsignal(td, SIGILL, ILL_ILLTRP, (void *)frame->tf_sepc); | call_trapsignal(td, SIGILL, ILL_ILLTRP, (void *)frame->tf_sepc, | ||||
exception); | |||||
userret(td, frame); | userret(td, frame); | ||||
break; | break; | ||||
case EXCP_BREAKPOINT: | case EXCP_BREAKPOINT: | ||||
call_trapsignal(td, SIGTRAP, TRAP_BRKPT, (void *)frame->tf_sepc); | call_trapsignal(td, SIGTRAP, TRAP_BRKPT, (void *)frame->tf_sepc, | ||||
exception); | |||||
userret(td, frame); | userret(td, frame); | ||||
break; | break; | ||||
default: | default: | ||||
dump_regs(frame); | dump_regs(frame); | ||||
panic("Unknown userland exception %x, trap value %lx\n", | panic("Unknown userland exception %x, trap value %lx\n", | ||||
exception, frame->tf_stval); | exception, frame->tf_stval); | ||||
} | } | ||||
} | } |