Changeset View
Changeset View
Standalone View
Standalone View
sys/sparc64/sparc64/trap.c
Show First 20 Lines • Show All 85 Lines • ▼ Show 20 Lines | |||||
#include <machine/tlb.h> | #include <machine/tlb.h> | ||||
#include <machine/tsb.h> | #include <machine/tsb.h> | ||||
#include <machine/watch.h> | #include <machine/watch.h> | ||||
void trap(struct trapframe *tf); | void trap(struct trapframe *tf); | ||||
void syscall(struct trapframe *tf); | void syscall(struct trapframe *tf); | ||||
static int trap_cecc(void); | static int trap_cecc(void); | ||||
static int trap_pfault(struct thread *td, struct trapframe *tf); | static bool trap_pfault(struct thread *td, struct trapframe *tf, int *signo, | ||||
int *ucode); | |||||
extern char copy_fault[]; | extern char copy_fault[]; | ||||
extern char copy_nofault_begin[]; | extern char copy_nofault_begin[]; | ||||
extern char copy_nofault_end[]; | extern char copy_nofault_end[]; | ||||
extern char fs_fault[]; | extern char fs_fault[]; | ||||
extern char fs_nofault_begin[]; | extern char fs_nofault_begin[]; | ||||
extern char fs_nofault_end[]; | extern char fs_nofault_end[]; | ||||
▲ Show 20 Lines • Show All 179 Lines • ▼ Show 20 Lines | if (td->td_cowgen != p->p_cowgen) | ||||
thread_cow_update(td); | thread_cow_update(td); | ||||
switch (tf->tf_type) { | switch (tf->tf_type) { | ||||
case T_DATA_MISS: | case T_DATA_MISS: | ||||
case T_DATA_PROTECTION: | case T_DATA_PROTECTION: | ||||
addr = tf->tf_sfar; | addr = tf->tf_sfar; | ||||
/* FALLTHROUGH */ | /* FALLTHROUGH */ | ||||
case T_INSTRUCTION_MISS: | case T_INSTRUCTION_MISS: | ||||
sig = trap_pfault(td, tf); | if (trap_pfault(td, tf, &sig, &ucode)) | ||||
sig = 0; | |||||
break; | break; | ||||
case T_FILL: | case T_FILL: | ||||
sig = rwindow_load(td, tf, 2); | sig = rwindow_load(td, tf, 2); | ||||
break; | break; | ||||
case T_FILL_RET: | case T_FILL_RET: | ||||
sig = rwindow_load(td, tf, 1); | sig = rwindow_load(td, tf, 1); | ||||
break; | break; | ||||
case T_SPILL: | case T_SPILL: | ||||
▲ Show 20 Lines • Show All 54 Lines • ▼ Show 20 Lines | #ifdef notyet | ||||
case T_PA_WATCHPOINT: | case T_PA_WATCHPOINT: | ||||
case T_VA_WATCHPOINT: | case T_VA_WATCHPOINT: | ||||
error = db_watch_trap(tf); | error = db_watch_trap(tf); | ||||
break; | break; | ||||
#endif | #endif | ||||
case T_DATA_MISS: | case T_DATA_MISS: | ||||
case T_DATA_PROTECTION: | case T_DATA_PROTECTION: | ||||
case T_INSTRUCTION_MISS: | case T_INSTRUCTION_MISS: | ||||
error = trap_pfault(td, tf); | error = !trap_pfault(td, tf, &sig, &ucode); | ||||
break; | break; | ||||
case T_DATA_EXCEPTION: | case T_DATA_EXCEPTION: | ||||
case T_MEM_ADDRESS_NOT_ALIGNED: | case T_MEM_ADDRESS_NOT_ALIGNED: | ||||
if ((tf->tf_sfsr & MMU_SFSR_FV) != 0 && | if ((tf->tf_sfsr & MMU_SFSR_FV) != 0 && | ||||
MMU_SFSR_GET_ASI(tf->tf_sfsr) == ASI_AIUP) { | MMU_SFSR_GET_ASI(tf->tf_sfsr) == ASI_AIUP) { | ||||
if (tf->tf_tpc >= (u_long)copy_nofault_begin && | if (tf->tf_tpc >= (u_long)copy_nofault_begin && | ||||
tf->tf_tpc <= (u_long)copy_nofault_end) { | tf->tf_tpc <= (u_long)copy_nofault_end) { | ||||
tf->tf_tpc = (u_long)copy_fault; | tf->tf_tpc = (u_long)copy_fault; | ||||
▲ Show 20 Lines • Show All 68 Lines • ▼ Show 20 Lines | trap_cecc(void) | ||||
stxa_sync(0, ASI_AFSR, ldxa(0, ASI_AFSR)); | stxa_sync(0, ASI_AFSR, ldxa(0, ASI_AFSR)); | ||||
corrected_ecc++; | corrected_ecc++; | ||||
printf("corrected ECC error\n"); | printf("corrected ECC error\n"); | ||||
/* Turn (non-)correctable error reporting back on. */ | /* Turn (non-)correctable error reporting back on. */ | ||||
stxa_sync(0, ASI_ESTATE_ERROR_EN_REG, eee); | stxa_sync(0, ASI_ESTATE_ERROR_EN_REG, eee); | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | static bool | ||||
trap_pfault(struct thread *td, struct trapframe *tf) | trap_pfault(struct thread *td, struct trapframe *tf, int *signo, int *ucode) | ||||
{ | { | ||||
vm_map_t map; | vm_map_t map; | ||||
struct proc *p; | struct proc *p; | ||||
vm_offset_t va; | vm_offset_t va; | ||||
vm_prot_t prot; | vm_prot_t prot; | ||||
vm_map_entry_t entry; | vm_map_entry_t entry; | ||||
u_long ctx; | u_long ctx; | ||||
int type; | int type; | ||||
▲ Show 20 Lines • Show All 47 Lines • ▼ Show 20 Lines | if (tf->tf_tpc >= (u_long)copy_nofault_begin && | ||||
return (0); | return (0); | ||||
} | } | ||||
vm_map_unlock_read(kernel_map); | vm_map_unlock_read(kernel_map); | ||||
} | } | ||||
map = kernel_map; | map = kernel_map; | ||||
} | } | ||||
/* Fault in the page. */ | /* Fault in the page. */ | ||||
rv = vm_fault(map, va, prot, VM_FAULT_NORMAL); | rv = vm_fault_trap(map, va, prot, VM_FAULT_NORMAL, signo, ucode); | ||||
CTR3(KTR_TRAP, "trap_pfault: return td=%p va=%#lx rv=%d", | CTR3(KTR_TRAP, "trap_pfault: return td=%p va=%#lx rv=%d", | ||||
td, va, rv); | td, va, rv); | ||||
if (rv == KERN_SUCCESS) | if (rv == KERN_SUCCESS) | ||||
return (0); | return (true); | ||||
if (ctx != TLB_CTX_KERNEL && (tf->tf_tstate & TSTATE_PRIV) != 0) { | if (ctx != TLB_CTX_KERNEL && (tf->tf_tstate & TSTATE_PRIV) != 0) { | ||||
if (tf->tf_tpc >= (u_long)fs_nofault_begin && | if (tf->tf_tpc >= (u_long)fs_nofault_begin && | ||||
tf->tf_tpc <= (u_long)fs_nofault_end) { | tf->tf_tpc <= (u_long)fs_nofault_end) { | ||||
tf->tf_tpc = (u_long)fs_fault; | tf->tf_tpc = (u_long)fs_fault; | ||||
tf->tf_tnpc = tf->tf_tpc + 4; | tf->tf_tnpc = tf->tf_tpc + 4; | ||||
return (0); | return (true); | ||||
} | } | ||||
if (tf->tf_tpc >= (u_long)copy_nofault_begin && | if (tf->tf_tpc >= (u_long)copy_nofault_begin && | ||||
tf->tf_tpc <= (u_long)copy_nofault_end) { | tf->tf_tpc <= (u_long)copy_nofault_end) { | ||||
tf->tf_tpc = (u_long)copy_fault; | tf->tf_tpc = (u_long)copy_fault; | ||||
tf->tf_tnpc = tf->tf_tpc + 4; | tf->tf_tnpc = tf->tf_tpc + 4; | ||||
return (0); | return (true); | ||||
} | } | ||||
} | } | ||||
return ((rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV); | return (false); | ||||
} | } | ||||
/* Maximum number of arguments that can be passed via the out registers. */ | /* Maximum number of arguments that can be passed via the out registers. */ | ||||
#define REG_MAXARGS 6 | #define REG_MAXARGS 6 | ||||
int | int | ||||
cpu_fetch_syscall_args(struct thread *td) | cpu_fetch_syscall_args(struct thread *td) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 73 Lines • Show Last 20 Lines |