182906Sjake/*- 282906Sjake * Copyright (c) 1997 Berkeley Software Design, Inc. All rights reserved. 382906Sjake * 482906Sjake * Redistribution and use in source and binary forms, with or without 582906Sjake * modification, are permitted provided that the following conditions 682906Sjake * are met: 782906Sjake * 1. Redistributions of source code must retain the above copyright 882906Sjake * notice, this list of conditions and the following disclaimer. 982906Sjake * 2. Redistributions in binary form must reproduce the above copyright 1082906Sjake * notice, this list of conditions and the following disclaimer in the 1182906Sjake * documentation and/or other materials provided with the distribution. 1282906Sjake * 3. Berkeley Software Design Inc's name may not be used to endorse or 1382906Sjake * promote products derived from this software without specific prior 1482906Sjake * written permission. 1582906Sjake * 1682906Sjake * THIS SOFTWARE IS PROVIDED BY BERKELEY SOFTWARE DESIGN INC ``AS IS'' AND 1782906Sjake * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1882906Sjake * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1982906Sjake * ARE DISCLAIMED. IN NO EVENT SHALL BERKELEY SOFTWARE DESIGN INC BE LIABLE 2082906Sjake * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2182906Sjake * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2282906Sjake * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2382906Sjake * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2482906Sjake * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2582906Sjake * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2682906Sjake * SUCH DAMAGE. 2782906Sjake * 2882906Sjake * from: BSDI: trap.c,v 1.17.2.9 1999/10/19 15:29:52 cp Exp 2982906Sjake * $FreeBSD$ 3082906Sjake */ 3182906Sjake 3282906Sjake#include <sys/param.h> 3382906Sjake#include <sys/systm.h> 3482906Sjake#include <sys/ktr.h> 3582906Sjake#include <sys/proc.h> 3682906Sjake 3782906Sjake#include <machine/frame.h> 38138129Sdas#include <machine/pcb.h> 3982906Sjake 4089046SjakeCTASSERT((1 << RW_SHIFT) == sizeof(struct rwindow)); 4188640Sjake 4282906Sjakeint 4383366Sjulianrwindow_load(struct thread *td, struct trapframe *tf, int n) 4482906Sjake{ 4582906Sjake struct rwindow rw; 4682906Sjake u_long usp; 4782906Sjake int error; 4882906Sjake int i; 4982906Sjake 5088640Sjake CTR3(KTR_TRAP, "rwindow_load: td=%p (%s) n=%d", 5188640Sjake td, td->td_proc->p_comm, n); 5288640Sjake 5382906Sjake /* 5482906Sjake * In case current window is still only on-chip, push it out; 5582906Sjake * if it cannot get all the way out, we cannot continue either. 5682906Sjake */ 5783366Sjulian if ((error = rwindow_save(td)) != 0) 5882906Sjake return (error); 5982906Sjake usp = tf->tf_out[6]; 6082906Sjake for (i = 0; i < n; i++) { 6182906Sjake CTR1(KTR_TRAP, "rwindow_load: usp=%#lx", usp); 6282906Sjake usp += SPOFF; 6395134Sjake if ((error = (usp & 0x7)) != 0) 6495134Sjake break; 6582906Sjake error = copyin((void *)usp, &rw, sizeof rw); 6682906Sjake usp = rw.rw_in[6]; 6782906Sjake } 6882906Sjake CTR1(KTR_TRAP, "rwindow_load: error=%d", error); 69105939Sjake return (error == 0 ? 0 : SIGILL); 7082906Sjake} 7182906Sjake 7282906Sjakeint 7383366Sjulianrwindow_save(struct thread *td) 7482906Sjake{ 7582906Sjake struct rwindow *rw; 7682906Sjake struct pcb *pcb; 7782906Sjake u_long *ausp; 7882906Sjake u_long usp; 7982906Sjake int error; 8082906Sjake int i; 8182906Sjake 8283366Sjulian pcb = td->td_pcb; 8383366Sjulian CTR3(KTR_TRAP, "rwindow_save: td=%p (%s) nsaved=%d", td, 8488640Sjake td->td_proc->p_comm, pcb->pcb_nsaved); 8588640Sjake 8688640Sjake flushw(); 87135885Skensmith KASSERT(pcb->pcb_nsaved < MAXWIN, 88135885Skensmith ("rwindow_save: pcb_nsaved > MAXWIN")); 8988640Sjake if ((i = pcb->pcb_nsaved) == 0) 9082906Sjake return (0); 9182906Sjake ausp = pcb->pcb_rwsp; 9282906Sjake rw = pcb->pcb_rw; 9382906Sjake error = 0; 9482906Sjake do { 9582906Sjake usp = *ausp; 9682906Sjake CTR1(KTR_TRAP, "rwindow_save: usp=%#lx", usp); 9782906Sjake usp += SPOFF; 9895134Sjake if ((error = (usp & 0x7)) != 0) 9995134Sjake break; 10082906Sjake error = copyout(rw, (void *)usp, sizeof *rw); 10182906Sjake if (error) 10282906Sjake break; 10382906Sjake ausp++; 10482906Sjake rw++; 10582906Sjake } while (--i > 0); 10682906Sjake CTR1(KTR_TRAP, "rwindow_save: error=%d", error); 10782906Sjake if (error == 0) 10882906Sjake pcb->pcb_nsaved = 0; 109105939Sjake return (error == 0 ? 0 : SIGILL); 11082906Sjake} 111