1 /* $NetBSD: sys_machdep.c,v 1.19 2010/07/07 01:20:49 chs 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.19 2010/07/07 01:20:49 chs 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 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 u_int64_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 case ALPHA_PCI_CONF_READWRITE: 192 { 193 struct alpha_pci_conf_readwrite_args args; 194 pcitag_t tag; 195 196 error = copyin(SCARG(uap, parms), &args, sizeof(args)); 197 if (error) 198 return (error); 199 200 if (alpha_pci_chipset == NULL) 201 return (EOPNOTSUPP); 202 203 if (args.bus > 0xff) /* XXX MAGIC NUMBER */ 204 return (EINVAL); 205 if (args.device > pci_bus_maxdevs(alpha_pci_chipset, args.bus)) 206 return (EINVAL); 207 if (args.function > 7) /* XXX MAGIC NUMBER */ 208 return (EINVAL); 209 if (args.reg > 0xff) /* XXX MAGIC NUMBER */ 210 return (EINVAL); 211 212 tag = pci_make_tag(alpha_pci_chipset, args.bus, args.device, 213 args.function); 214 215 if (args.write) 216 pci_conf_write(alpha_pci_chipset, tag, args.reg, 217 args.val); 218 else { 219 args.val = pci_conf_read(alpha_pci_chipset, tag, 220 args.reg); 221 error = copyout(&args, SCARG(uap, parms), sizeof(args)); 222 } 223 break; 224 } 225 226 default: 227 error = EINVAL; 228 break; 229 } 230 231 return (error); 232 } 233 234 int 235 cpu_lwp_setprivate(lwp_t *l, void *addr) 236 { 237 struct pcb *pcb; 238 239 pcb = lwp_getpcb(l); 240 pcb->pcb_hw.apcb_unique = (unsigned long)addr; 241 return 0; 242 } 243