1 /* $NetBSD: sys_machdep.c,v 1.22 2021/02/28 21:34:34 tnn Exp $ */
2
3 /*-
4 * Copyright (c) 2000 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jason R. Thorpe.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 /*
33 * Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
34 * All rights reserved.
35 *
36 * Author: Chris G. Demetriou
37 *
38 * Permission to use, copy, modify and distribute this software and
39 * its documentation is hereby granted, provided that both the copyright
40 * notice and this permission notice appear in all copies of the
41 * software, derivative works or modified versions, and any portions
42 * thereof, and that both notices appear in supporting documentation.
43 *
44 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
45 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
46 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
47 *
48 * Carnegie Mellon requests users of this software to return to
49 *
50 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
51 * School of Computer Science
52 * Carnegie Mellon University
53 * Pittsburgh PA 15213-3890
54 *
55 * any improvements or extensions that they make and grant Carnegie the
56 * rights to redistribute these changes.
57 */
58
59 #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
60
61 __KERNEL_RCSID(0, "$NetBSD: sys_machdep.c,v 1.22 2021/02/28 21:34:34 tnn Exp $");
62
63 #include <sys/param.h>
64 #include <sys/systm.h>
65 #include <sys/device.h>
66 #include <sys/proc.h>
67 #include <sys/cpu.h>
68
69 #include <sys/mount.h>
70 #include <sys/syscallargs.h>
71
72 #include <machine/fpu.h>
73 #include <machine/sysarch.h>
74
75 #include <dev/pci/pcivar.h>
76
77 u_int alpha_bus_window_count[ALPHA_BUS_TYPE_MAX + 1];
78
79 int (*alpha_bus_get_window)(int, int,
80 struct alpha_bus_space_translation *);
81
82 struct alpha_pci_chipset *alpha_pci_chipset;
83
84 int
sys_sysarch(struct lwp * l,const struct sys_sysarch_args * uap,register_t * retval)85 sys_sysarch(struct lwp *l, const struct sys_sysarch_args *uap, register_t *retval)
86 {
87 /* {
88 syscallarg(int) op;
89 syscallarg(void *) parms;
90 } */
91 int error = 0;
92
93 switch(SCARG(uap, op)) {
94 case ALPHA_FPGETMASK:
95 *retval = FP_C_TO_NETBSD_MASK(l->l_md.md_flags);
96 break;
97 case ALPHA_FPGETSTICKY:
98 *retval = FP_C_TO_NETBSD_FLAG(l->l_md.md_flags);
99 break;
100 case ALPHA_FPSETMASK:
101 case ALPHA_FPSETSTICKY:
102 {
103 fp_except m;
104 uint64_t md_flags;
105 struct alpha_fp_except_args args;
106
107 error = copyin(SCARG(uap, parms), &args, sizeof args);
108 if (error)
109 return error;
110 m = args.mask;
111 md_flags = l->l_md.md_flags;
112 switch (SCARG(uap, op)) {
113 case ALPHA_FPSETMASK:
114 *retval = FP_C_TO_NETBSD_MASK(md_flags);
115 md_flags = SET_FP_C_MASK(md_flags, m);
116 break;
117 case ALPHA_FPSETSTICKY:
118 *retval = FP_C_TO_NETBSD_FLAG(md_flags);
119 md_flags = SET_FP_C_FLAG(md_flags, m);
120 break;
121 }
122 alpha_write_fp_c(l, md_flags);
123 break;
124 }
125 case ALPHA_GET_FP_C:
126 {
127 struct alpha_fp_c_args args;
128
129 args.fp_c = alpha_read_fp_c(l);
130 error = copyout(&args, SCARG(uap, parms), sizeof args);
131 break;
132 }
133 case ALPHA_SET_FP_C:
134 {
135 struct alpha_fp_c_args args;
136
137 error = copyin(SCARG(uap, parms), &args, sizeof args);
138 if (error)
139 return (error);
140 if ((args.fp_c >> 63) != 0)
141 args.fp_c |= IEEE_INHERIT;
142 alpha_write_fp_c(l, args.fp_c);
143 break;
144 }
145 case ALPHA_BUS_GET_WINDOW_COUNT:
146 {
147 struct alpha_bus_get_window_count_args args;
148
149 error = copyin(SCARG(uap, parms), &args, sizeof(args));
150 if (error)
151 return (error);
152
153 if (args.type > ALPHA_BUS_TYPE_MAX)
154 return (EINVAL);
155
156 if (alpha_bus_window_count[args.type] == 0)
157 return (EOPNOTSUPP);
158
159 args.count = alpha_bus_window_count[args.type];
160 error = copyout(&args, SCARG(uap, parms), sizeof(args));
161 break;
162 }
163
164 case ALPHA_BUS_GET_WINDOW:
165 {
166 struct alpha_bus_space_translation abst;
167 struct alpha_bus_get_window_args args;
168
169 error = copyin(SCARG(uap, parms), &args, sizeof(args));
170 if (error)
171 return (error);
172
173 if (args.type > ALPHA_BUS_TYPE_MAX)
174 return (EINVAL);
175
176 if (alpha_bus_window_count[args.type] == 0)
177 return (EOPNOTSUPP);
178
179 if (args.window >= alpha_bus_window_count[args.type])
180 return (EINVAL);
181
182 error = (*alpha_bus_get_window)(args.type, args.window,
183 &abst);
184 if (error)
185 return (error);
186
187 error = copyout(&abst, args.translation, sizeof(abst));
188 break;
189 }
190
191 #if NPCI > 0
192 case ALPHA_PCI_CONF_READWRITE:
193 {
194 struct alpha_pci_conf_readwrite_args args;
195 pcitag_t tag;
196
197 error = copyin(SCARG(uap, parms), &args, sizeof(args));
198 if (error)
199 return (error);
200
201 if (alpha_pci_chipset == NULL)
202 return (EOPNOTSUPP);
203
204 if (args.bus > 0xff) /* XXX MAGIC NUMBER */
205 return (EINVAL);
206 if (args.device > pci_bus_maxdevs(alpha_pci_chipset, args.bus))
207 return (EINVAL);
208 if (args.function > 7) /* XXX MAGIC NUMBER */
209 return (EINVAL);
210 if (args.reg > 0xff) /* XXX MAGIC NUMBER */
211 return (EINVAL);
212
213 tag = pci_make_tag(alpha_pci_chipset, args.bus, args.device,
214 args.function);
215
216 if (args.write)
217 pci_conf_write(alpha_pci_chipset, tag, args.reg,
218 args.val);
219 else {
220 args.val = pci_conf_read(alpha_pci_chipset, tag,
221 args.reg);
222 error = copyout(&args, SCARG(uap, parms), sizeof(args));
223 }
224 break;
225 }
226 #endif
227
228 default:
229 error = EINVAL;
230 break;
231 }
232
233 return (error);
234 }
235
236 int
cpu_lwp_setprivate(lwp_t * l,void * addr)237 cpu_lwp_setprivate(lwp_t *l, void *addr)
238 {
239 struct pcb *pcb;
240
241 pcb = lwp_getpcb(l);
242 pcb->pcb_hw.apcb_unique = (unsigned long)addr;
243 if (l == curlwp)
244 alpha_pal_wrunique(pcb->pcb_hw.apcb_unique);
245 return 0;
246 }
247