]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/sparc64/sparc64/rwindow.c
Merge OpenSSL 1.0.2p.
[FreeBSD/FreeBSD.git] / sys / sparc64 / sparc64 / rwindow.c
1 /*-
2  * SPDX-License-Identifier: BSD-3-Clause
3  *
4  * Copyright (c) 1997 Berkeley Software Design, Inc. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. Berkeley Software Design Inc's name may not be used to endorse or
15  *    promote products derived from this software without specific prior
16  *    written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY BERKELEY SOFTWARE DESIGN INC ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL BERKELEY SOFTWARE DESIGN INC BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  *
30  *      from: BSDI: trap.c,v 1.17.2.9 1999/10/19 15:29:52 cp Exp
31  * $FreeBSD$
32  */
33
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/ktr.h>
37 #include <sys/proc.h>
38
39 #include <machine/frame.h>
40 #include <machine/pcb.h>
41
42 CTASSERT((1 << RW_SHIFT) == sizeof(struct rwindow));
43
44 int
45 rwindow_load(struct thread *td, struct trapframe *tf, int n)
46 {
47         struct rwindow rw;
48         u_long usp;
49         int error;
50         int i;
51
52         CTR3(KTR_TRAP, "rwindow_load: td=%p (%s) n=%d",
53             td, td->td_proc->p_comm, n);
54
55         /*
56          * In case current window is still only on-chip, push it out;
57          * if it cannot get all the way out, we cannot continue either.
58          */
59         if ((error = rwindow_save(td)) != 0)
60                 return (error);
61         usp = tf->tf_out[6];
62         for (i = 0; i < n; i++) {
63                 CTR1(KTR_TRAP, "rwindow_load: usp=%#lx", usp);
64                 usp += SPOFF;
65                 if ((error = (usp & 0x7)) != 0)
66                         break;
67                 error = copyin((void *)usp, &rw, sizeof rw);
68                 usp = rw.rw_in[6];
69         }
70         CTR1(KTR_TRAP, "rwindow_load: error=%d", error);
71         return (error == 0 ? 0 : SIGILL);
72 }
73
74 int
75 rwindow_save(struct thread *td)
76 {
77         struct rwindow *rw;
78         struct pcb *pcb;
79         u_long *ausp;
80         u_long usp;
81         int error;
82         int i;
83
84         pcb = td->td_pcb;
85         CTR3(KTR_TRAP, "rwindow_save: td=%p (%s) nsaved=%d", td,
86             td->td_proc->p_comm, pcb->pcb_nsaved);
87
88         flushw();
89         KASSERT(pcb->pcb_nsaved < MAXWIN,
90             ("rwindow_save: pcb_nsaved > MAXWIN"));
91         if ((i = pcb->pcb_nsaved) == 0)
92                 return (0);
93         ausp = pcb->pcb_rwsp;
94         rw = pcb->pcb_rw;
95         error = 0;
96         do {
97                 usp = *ausp;
98                 CTR1(KTR_TRAP, "rwindow_save: usp=%#lx", usp);
99                 usp += SPOFF;
100                 if ((error = (usp & 0x7)) != 0)
101                         break;
102                 error = copyout(rw, (void *)usp, sizeof *rw);
103                 if (error)
104                         break;
105                 ausp++;
106                 rw++;
107         } while (--i > 0);
108         CTR1(KTR_TRAP, "rwindow_save: error=%d", error);
109         if (error == 0)
110                 pcb->pcb_nsaved = 0;
111         return (error == 0 ? 0 : SIGILL);
112 }