144290Swollman/*- 244290Swollman * Copyright (c) 1997 Berkeley Software Design, Inc. All rights reserved. 344290Swollman * 444290Swollman * Redistribution and use in source and binary forms, with or without 544290Swollman * modification, are permitted provided that the following conditions 644290Swollman * are met: 744290Swollman * 1. Redistributions of source code must retain the above copyright 844290Swollman * notice, this list of conditions and the following disclaimer. 944290Swollman * 2. Redistributions in binary form must reproduce the above copyright 1044290Swollman * notice, this list of conditions and the following disclaimer in the 1144290Swollman * documentation and/or other materials provided with the distribution. 1244290Swollman * 3. Berkeley Software Design Inc's name may not be used to endorse or 1344290Swollman * promote products derived from this software without specific prior 1444290Swollman * written permission. 1544290Swollman * 1644290Swollman * THIS SOFTWARE IS PROVIDED BY BERKELEY SOFTWARE DESIGN INC ``AS IS'' AND 1744290Swollman * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1844290Swollman * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1944290Swollman * ARE DISCLAIMED. IN NO EVENT SHALL BERKELEY SOFTWARE DESIGN INC BE LIABLE 2044290Swollman * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2144290Swollman * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2244290Swollman * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2344290Swollman * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2444290Swollman * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2544290Swollman * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2644290Swollman * SUCH DAMAGE. 2744290Swollman * 2844290Swollman * from: BSDI: trap.c,v 1.17.2.9 1999/10/19 15:29:52 cp Exp 2944290Swollman * $FreeBSD$ 3044290Swollman */ 3144290Swollman 3244290Swollman#include <sys/param.h> 3344290Swollman#include <sys/systm.h> 3444290Swollman#include <sys/ktr.h> 3544290Swollman#include <sys/proc.h> 3644290Swollman 3744290Swollman#include <machine/frame.h> 3844290Swollman#include <machine/pcb.h> 3944290Swollman 4044290SwollmanCTASSERT((1 << RW_SHIFT) == sizeof(struct rwindow)); 4144290Swollman 4244290Swollmanint 4344290Swollmanrwindow_load(struct thread *td, struct trapframe *tf, int n) 4444290Swollman{ 4544290Swollman struct rwindow rw; 4644290Swollman u_long usp; 4744290Swollman int error; 4844290Swollman int i; 4944290Swollman 5044290Swollman CTR3(KTR_TRAP, "rwindow_load: td=%p (%s) n=%d", 5144290Swollman td, td->td_proc->p_comm, n); 5244290Swollman 5344290Swollman /* 5444290Swollman * In case current window is still only on-chip, push it out; 5544290Swollman * if it cannot get all the way out, we cannot continue either. 5644290Swollman */ 5750476Speter if ((error = rwindow_save(td)) != 0) 5844290Swollman return (error); 5944290Swollman usp = tf->tf_out[6]; 6044290Swollman for (i = 0; i < n; i++) { 6144290Swollman CTR1(KTR_TRAP, "rwindow_load: usp=%#lx", usp); 6244290Swollman usp += SPOFF; 6344290Swollman if ((error = (usp & 0x7)) != 0) 6444290Swollman break; 6544290Swollman error = copyin((void *)usp, &rw, sizeof rw); 6644290Swollman usp = rw.rw_in[6]; 6744290Swollman } 6844290Swollman CTR1(KTR_TRAP, "rwindow_load: error=%d", error); 6944290Swollman return (error == 0 ? 0 : SIGILL); 7044290Swollman} 7144290Swollman 7244290Swollmanint 7344290Swollmanrwindow_save(struct thread *td) 7444290Swollman{ 7544290Swollman struct rwindow *rw; 7644290Swollman struct pcb *pcb; 7744290Swollman u_long *ausp; 7844290Swollman u_long usp; 7944290Swollman int error; 8044290Swollman int i; 8144290Swollman 8244290Swollman pcb = td->td_pcb; 8344301Swollman CTR3(KTR_TRAP, "rwindow_save: td=%p (%s) nsaved=%d", td, 8444290Swollman td->td_proc->p_comm, pcb->pcb_nsaved); 8544290Swollman 8644290Swollman flushw(); 8744290Swollman KASSERT(pcb->pcb_nsaved < MAXWIN, 8844290Swollman ("rwindow_save: pcb_nsaved > MAXWIN")); 8944301Swollman if ((i = pcb->pcb_nsaved) == 0) 9044290Swollman return (0); 9144290Swollman ausp = pcb->pcb_rwsp; 9244290Swollman rw = pcb->pcb_rw; 9344290Swollman error = 0; 9444290Swollman do { 9544290Swollman usp = *ausp; 9644290Swollman CTR1(KTR_TRAP, "rwindow_save: usp=%#lx", usp); 97 usp += SPOFF; 98 if ((error = (usp & 0x7)) != 0) 99 break; 100 error = copyout(rw, (void *)usp, sizeof *rw); 101 if (error) 102 break; 103 ausp++; 104 rw++; 105 } while (--i > 0); 106 CTR1(KTR_TRAP, "rwindow_save: error=%d", error); 107 if (error == 0) 108 pcb->pcb_nsaved = 0; 109 return (error == 0 ? 0 : SIGILL); 110} 111