]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/alpha/alpha/sys_machdep.c
This commit was generated by cvs2svn to compensate for changes in r57093,
[FreeBSD/FreeBSD.git] / sys / alpha / alpha / sys_machdep.c
1 /*-
2  * Copyright (c) 1990 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *      This product includes software developed by the University of
16  *      California, Berkeley and its contributors.
17  * 4. Neither the name of the University nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  *      from: @(#)sys_machdep.c 5.5 (Berkeley) 1/19/91
34  * $FreeBSD$
35  *
36  */
37
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/sysproto.h>
41 #include <sys/sysent.h>
42 #include <sys/proc.h>
43
44 #include <vm/vm.h>
45 #include <sys/lock.h>
46 #include <vm/pmap.h>
47 #include <vm/vm_map.h>
48 #include <vm/vm_extern.h>
49
50 #include <sys/user.h>
51
52 #include <machine/cpu.h>
53 #include <machine/sysarch.h>
54
55 #include <vm/vm_kern.h>         /* for kernel_map */
56
57 #include <machine/fpu.h>
58
59 #ifndef _SYS_SYSPROTO_H_
60 struct sysarch_args {
61         int op;
62         char *parms;
63 };
64 #endif
65
66 static int alpha_sethae(struct proc *p, char *args);
67 static int alpha_get_fpmask(struct proc *p, char *args);
68 static int alpha_set_fpmask(struct proc *p, char *args);
69 static int alpha_set_uac(struct proc *p, char *args);
70 static int alpha_get_uac(struct proc *p, char *args);
71
72 int
73 sysarch(p, uap)
74         struct proc *p;
75         register struct sysarch_args *uap;
76 {
77         int error = 0;
78
79         switch(SCARG(uap,op)) {
80         case ALPHA_SETHAE:
81                 error = alpha_sethae(p, uap->parms);
82                 break;
83         case ALPHA_GET_FPMASK:
84                 error = alpha_get_fpmask(p, uap->parms);
85                 break;
86         case ALPHA_SET_FPMASK:
87                 error = alpha_set_fpmask(p, uap->parms);
88                 break;
89         case ALPHA_SET_UAC:
90                 error = alpha_set_uac(p, uap->parms);
91                 break;
92         case ALPHA_GET_UAC:
93                 error = alpha_get_uac(p, uap->parms);
94                 break;
95             
96         default:
97                 error = EINVAL;
98                 break;
99         }
100         return (error);
101 }
102
103 struct alpha_sethae_args {
104         u_int64_t hae;
105 };
106
107 static int
108 alpha_sethae(struct proc *p, char *args)
109 {
110         int error;
111         struct alpha_sethae_args ua;
112
113         error = copyin(args, &ua, sizeof(struct alpha_sethae_args));
114         if (error)
115                 return (error);
116
117         if (securelevel > 0)
118                 return (EPERM);
119
120         error = suser(p);
121         if (error)
122                 return (error);
123
124         p->p_md.md_flags |= MDP_HAEUSED;
125         p->p_md.md_hae = ua.hae;
126
127         return (0);
128 }
129
130 struct alpha_fpmask_args {
131         u_int64_t mask;
132 };
133
134 static  int
135 alpha_get_fpmask(struct proc *p, char *args)
136 {
137         int error;
138         struct alpha_fpmask_args ua;
139
140         ua.mask = p->p_addr->u_pcb.pcb_fp_control;
141         error = copyout(&ua, args, sizeof(struct alpha_fpmask_args));
142
143         return (error);
144 }
145
146 static  int
147 alpha_set_fpmask(struct proc *p, char *args)
148 {
149         int error;
150         u_int64_t oldmask, *fp_control;
151         struct alpha_fpmask_args ua;
152         
153         error = copyin(args, &ua, sizeof(struct alpha_fpmask_args));
154         if (error)
155                 return (error);
156
157         fp_control = &p->p_addr->u_pcb.pcb_fp_control;
158         oldmask = *fp_control;
159         *fp_control = ua.mask & IEEE_TRAP_ENABLE_MASK;
160         ua.mask = oldmask;
161
162         error = copyout(&ua, args, sizeof(struct alpha_fpmask_args));
163         return (error);
164 }
165
166 static  int
167 alpha_set_uac(struct proc *p, char *args)
168 {
169         int error, s;
170         unsigned long uac;
171
172         error = copyin(args, &uac, sizeof(uac));
173         if (error)
174                 return (error);
175
176         if (p->p_pptr) {
177                 s = splimp();
178                 if (p->p_pptr) {
179                         p->p_pptr->p_md.md_flags &= ~MDP_UAC_MASK;
180                         p->p_pptr->p_md.md_flags |= uac & MDP_UAC_MASK;
181                 } else
182                         error = ESRCH;
183                 splx(s);
184         }
185         return error;
186 }
187
188 static  int
189 alpha_get_uac(struct proc *p, char *args)
190 {
191         int error, s;
192         unsigned long uac;
193
194         error = ESRCH;
195         if (p->p_pptr) {
196                 s = splimp();
197                 if (p->p_pptr) {
198                         uac = p->p_pptr->p_md.md_flags & MDP_UAC_MASK;
199                         error = copyout(&uac, args, sizeof(uac));
200                 }
201                 splx(s);
202         }
203         return error;
204 }