Home | History | Annotate | Line # | Download | only in alpha
      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 (at) 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
     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
    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