-
-#define FOR64_TRANSITION 1
-
-#ifdef FOR64_TRANSITION
-
-struct osigreturn_args {
- struct ucontext *uctx;
-};
-
-/* ARGSUSED */
-int
-osigreturn(p, uap, retval)
- struct proc *p;
- struct osigreturn_args *uap;
- int *retval;
-{
- struct ucontext uctx;
- struct ucontext *p_uctx;
- struct mcontext64 mctx64;
- struct mcontext64 *p_64mctx;
- struct mcontext *p_mctx;
- int error;
- thread_act_t th_act;
- struct sigacts *ps = p->p_sigacts;
- sigset_t mask;
- register sig_t action;
- unsigned long state_count;
- unsigned int state_flavor;
- struct uthread * ut;
- int vec_used = 0;
- void *tsptr, *fptr, *vptr, *mactx;
- void ppc_checkthreadstate(void *, int);
-
- th_act = current_act();
- /* lets use the larger one */
- mactx = (void *)&mctx64;
-
- ut = (struct uthread *)get_bsdthread_info(th_act);
- if (error = copyin(uap->uctx, &uctx, sizeof(struct ucontext))) {
- return(error);
- }
- if (error = copyin(uctx.uc_mcontext, mactx, uctx.uc_mcsize)) {
- return(error);
- }
-
- if (uctx.uc_onstack & 01)
- p->p_sigacts->ps_sigstk.ss_flags |= SA_ONSTACK;
- else
- p->p_sigacts->ps_sigstk.ss_flags &= ~SA_ONSTACK;
-
- ut->uu_sigmask = uctx.uc_sigmask & ~sigcantmask;
- if (ut->uu_siglist & ~ut->uu_sigmask)
- signal_setast(current_act());
-
- vec_used = 0;
- switch (uctx.uc_mcsize) {
- case UC_FLAVOR64_VEC_SIZE :
- vec_used = 1;
- case UC_FLAVOR64_SIZE : {
- p_64mctx = (struct mcontext64 *)mactx;
- tsptr = (void *)&p_64mctx->ss;
- fptr = (void *)&p_64mctx->fs;
- vptr = (void *)&p_64mctx->vs;
- state_flavor = PPC_THREAD_STATE64;
- state_count = PPC_THREAD_STATE64_COUNT;
- }
- break;
- case UC_FLAVOR_VEC_SIZE :
- vec_used = 1;
- case UC_FLAVOR_SIZE:
- default: {
- p_mctx = (struct mcontext *)mactx;
- tsptr = (void *)&p_mctx->ss;
- fptr = (void *)&p_mctx->fs;
- vptr = (void *)&p_mctx->vs;
- state_flavor = PPC_THREAD_STATE;
- state_count = PPC_THREAD_STATE_COUNT;
- }
- break;
- } /* switch () */
-
- /* validate the thread state, set/reset appropriate mode bits in srr1 */
- (void)ppc_checkthreadstate(tsptr, state_flavor);
-
- if (thread_setstatus(th_act, state_flavor, tsptr, &state_count) != KERN_SUCCESS) {
- return(EINVAL);
- }
-
- state_count = PPC_FLOAT_STATE_COUNT;
- if (thread_setstatus(th_act, PPC_FLOAT_STATE, fptr, &state_count) != KERN_SUCCESS) {
- return(EINVAL);
- }
-
- mask = sigmask(SIGFPE);
- if (((ut->uu_sigmask & mask) == 0) && (p->p_sigcatch & mask) && ((p->p_sigignore & mask) == 0)) {
- action = ps->ps_sigact[SIGFPE];
- if((action != SIG_DFL) && (action != SIG_IGN)) {
- thread_enable_fpe(th_act, 1);
- }
- }
-
- if (vec_used) {
- state_count = PPC_VECTOR_STATE_COUNT;
- if (thread_setstatus(th_act, PPC_VECTOR_STATE, vptr, &state_count) != KERN_SUCCESS) {
- return(EINVAL);
- }
- }
- return (EJUSTRETURN);
-}
-
-#endif /* FOR64_TRANSITION */
-