xref: /netbsd/sys/compat/linux/arch/alpha/linux_osf1.c (revision d50c96bb)
1*d50c96bbSriastradh /*	$NetBSD: linux_osf1.c,v 1.5 2021/09/07 11:43:03 riastradh Exp $	*/
2710f9455Smaxv 
3710f9455Smaxv /*
4710f9455Smaxv  * Copyright (c) 1999 Christopher G. Demetriou.  All rights reserved.
5710f9455Smaxv  *
6710f9455Smaxv  * Redistribution and use in source and binary forms, with or without
7710f9455Smaxv  * modification, are permitted provided that the following conditions
8710f9455Smaxv  * are met:
9710f9455Smaxv  * 1. Redistributions of source code must retain the above copyright
10710f9455Smaxv  *    notice, this list of conditions and the following disclaimer.
11710f9455Smaxv  * 2. Redistributions in binary form must reproduce the above copyright
12710f9455Smaxv  *    notice, this list of conditions and the following disclaimer in the
13710f9455Smaxv  *    documentation and/or other materials provided with the distribution.
14710f9455Smaxv  * 3. All advertising materials mentioning features or use of this software
15710f9455Smaxv  *    must display the following acknowledgement:
16710f9455Smaxv  *      This product includes software developed by Christopher G. Demetriou
17710f9455Smaxv  *	for the NetBSD Project.
18710f9455Smaxv  * 4. The name of the author may not be used to endorse or promote products
19710f9455Smaxv  *    derived from this software without specific prior written permission
20710f9455Smaxv  *
21710f9455Smaxv  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22710f9455Smaxv  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23710f9455Smaxv  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24710f9455Smaxv  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25710f9455Smaxv  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26710f9455Smaxv  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27710f9455Smaxv  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28710f9455Smaxv  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29710f9455Smaxv  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30710f9455Smaxv  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31710f9455Smaxv  */
32710f9455Smaxv 
33710f9455Smaxv #include <sys/cdefs.h>
34*d50c96bbSriastradh __KERNEL_RCSID(0, "$NetBSD: linux_osf1.c,v 1.5 2021/09/07 11:43:03 riastradh Exp $");
35710f9455Smaxv 
36710f9455Smaxv #include <sys/param.h>
37710f9455Smaxv #include <sys/systm.h>
38710f9455Smaxv #include <sys/namei.h>
39710f9455Smaxv #include <sys/proc.h>
40710f9455Smaxv #include <sys/file.h>
41710f9455Smaxv #include <sys/filedesc.h>
42710f9455Smaxv #include <sys/kernel.h>
43710f9455Smaxv #include <sys/mount.h>
44710f9455Smaxv #include <sys/vnode.h>
45710f9455Smaxv #include <sys/wait.h>
46710f9455Smaxv #include <sys/select.h>
47710f9455Smaxv #include <sys/syscallargs.h>
48710f9455Smaxv #include <sys/vfs_syscalls.h>
49710f9455Smaxv 
50710f9455Smaxv #include <machine/alpha.h>
51710f9455Smaxv #include <machine/cpuconf.h>
52710f9455Smaxv #include <machine/rpb.h>
53710f9455Smaxv #include <machine/fpu.h>
54710f9455Smaxv 
55710f9455Smaxv #include <compat/common/compat_util.h>
56710f9455Smaxv #include <compat/linux/common/linux_types.h>
57710f9455Smaxv #include <compat/linux/common/linux_signal.h>
58710f9455Smaxv #include <compat/linux/arch/alpha/linux_signal.h>
59710f9455Smaxv #include <compat/linux/arch/alpha/linux_osf1.h>
60710f9455Smaxv #include <compat/linux/linux_syscallargs.h>
61710f9455Smaxv 
62710f9455Smaxv #include <net/if.h>
63710f9455Smaxv #include <netinet/in.h>
64710f9455Smaxv 
65710f9455Smaxv #include <nfs/rpcv2.h>
66710f9455Smaxv #include <nfs/nfsproto.h>
67710f9455Smaxv #include <nfs/nfs.h>
68710f9455Smaxv #include <nfs/nfsmount.h>
69710f9455Smaxv 
70710f9455Smaxv #include <ufs/ufs/quota.h>
71710f9455Smaxv #include <ufs/ufs/ufsmount.h>
72710f9455Smaxv 
73710f9455Smaxv #include <machine/vmparam.h>
74710f9455Smaxv 
75710f9455Smaxv const struct emul_flags_xtab osf1_wait_options_xtab[] = {
76710f9455Smaxv     {	OSF1_WNOHANG,		OSF1_WNOHANG,		WNOHANG		},
77710f9455Smaxv     {	OSF1_WUNTRACED,		OSF1_WUNTRACED,		WUNTRACED	},
78710f9455Smaxv     {	0								}
79710f9455Smaxv };
80710f9455Smaxv 
81710f9455Smaxv const struct emul_flags_xtab osf1_nfs_mount_flags_xtab[] = {
82710f9455Smaxv     {	OSF1_NFSMNT_SOFT,	OSF1_NFSMNT_SOFT,	NFSMNT_SOFT,	},
83710f9455Smaxv     {	OSF1_NFSMNT_WSIZE,	OSF1_NFSMNT_WSIZE,	NFSMNT_WSIZE,	},
84710f9455Smaxv     {	OSF1_NFSMNT_RSIZE,	OSF1_NFSMNT_RSIZE,	NFSMNT_RSIZE,	},
85710f9455Smaxv     {	OSF1_NFSMNT_TIMEO,	OSF1_NFSMNT_TIMEO,	NFSMNT_TIMEO,	},
86710f9455Smaxv     {	OSF1_NFSMNT_RETRANS,	OSF1_NFSMNT_RETRANS,	NFSMNT_RETRANS,	},
87710f9455Smaxv #if 0 /* no equivalent; needs special handling, see below */
88710f9455Smaxv     {	OSF1_NFSMNT_HOSTNAME,	OSF1_NFSMNT_HOSTNAME,	???,		},
89710f9455Smaxv #endif
90710f9455Smaxv     {	OSF1_NFSMNT_INT,	OSF1_NFSMNT_INT,	NFSMNT_INT,	},
91710f9455Smaxv     {	OSF1_NFSMNT_NOCONN,	OSF1_NFSMNT_NOCONN,	NFSMNT_NOCONN,	},
92710f9455Smaxv #if 0 /* no equivalents */
93710f9455Smaxv     {	OSF1_NFSMNT_NOAC,	OSF1_NFSMNT_NOAC,	???,		},
94710f9455Smaxv     {	OSF1_NFSMNT_ACREGMIN,	OSF1_NFSMNT_ACREGMIN,	???,		},
95710f9455Smaxv     {	OSF1_NFSMNT_ACREGMAX,	OSF1_NFSMNT_ACREGMAX,	???,		},
96710f9455Smaxv     {	OSF1_NFSMNT_ACDIRMIN,	OSF1_NFSMNT_ACDIRMIN,	???,		},
97710f9455Smaxv     {	OSF1_NFSMNT_ACDIRMAX,	OSF1_NFSMNT_ACDIRMAX,	???,		},
98710f9455Smaxv     {	OSF1_NFSMNT_NOCTO,	OSF1_NFSMNT_NOCTO,	???,		},
99710f9455Smaxv     {	OSF1_NFSMNT_POSIX,	OSF1_NFSMNT_POSIX,	???,		},
100710f9455Smaxv     {	OSF1_NFSMNT_AUTO,	OSF1_NFSMNT_AUTO,	???,		},
101710f9455Smaxv     {	OSF1_NFSMNT_SEC,	OSF1_NFSMNT_SEC,	???,		},
102710f9455Smaxv     {	OSF1_NFSMNT_TCP,	OSF1_NFSMNT_TCP,	???,		},
103710f9455Smaxv     {	OSF1_NFSMNT_PROPLIST,	OSF1_NFSMNT_PROPLIST,	???,		},
104710f9455Smaxv #endif
105710f9455Smaxv     {	0								}
106710f9455Smaxv };
107710f9455Smaxv 
108710f9455Smaxv static void
osf1_cvt_rusage_from_native(const struct rusage * ru,struct osf1_rusage * oru)109710f9455Smaxv osf1_cvt_rusage_from_native(const struct rusage *ru, struct osf1_rusage *oru)
110710f9455Smaxv {
111710f9455Smaxv 
112*d50c96bbSriastradh 	memset(oru, 0, sizeof(*oru));
113*d50c96bbSriastradh 
114710f9455Smaxv 	oru->ru_utime.tv_sec = ru->ru_utime.tv_sec;
115710f9455Smaxv 	oru->ru_utime.tv_usec = ru->ru_utime.tv_usec;
116710f9455Smaxv 
117710f9455Smaxv 	oru->ru_stime.tv_sec = ru->ru_stime.tv_sec;
118710f9455Smaxv 	oru->ru_stime.tv_usec = ru->ru_stime.tv_usec;
119710f9455Smaxv 
120710f9455Smaxv 	oru->ru_maxrss = ru->ru_maxrss;
121710f9455Smaxv 	oru->ru_ixrss = ru->ru_ixrss;
122710f9455Smaxv 	oru->ru_idrss = ru->ru_idrss;
123710f9455Smaxv 	oru->ru_isrss = ru->ru_isrss;
124710f9455Smaxv 	oru->ru_minflt = ru->ru_minflt;
125710f9455Smaxv 	oru->ru_majflt = ru->ru_majflt;
126710f9455Smaxv 	oru->ru_nswap = ru->ru_nswap;
127710f9455Smaxv 	oru->ru_inblock = ru->ru_inblock;
128710f9455Smaxv 	oru->ru_oublock = ru->ru_oublock;
129710f9455Smaxv 	oru->ru_msgsnd = ru->ru_msgsnd;
130710f9455Smaxv 	oru->ru_msgrcv = ru->ru_msgrcv;
131710f9455Smaxv 	oru->ru_nsignals = ru->ru_nsignals;
132710f9455Smaxv 	oru->ru_nvcsw = ru->ru_nvcsw;
133710f9455Smaxv 	oru->ru_nivcsw = ru->ru_nivcsw;
134710f9455Smaxv }
135710f9455Smaxv 
136710f9455Smaxv static void
osf1_cvt_statfs_from_native(const struct statvfs * bsfs,struct osf1_statfs * osfs)137710f9455Smaxv osf1_cvt_statfs_from_native(const struct statvfs *bsfs, struct osf1_statfs *osfs)
138710f9455Smaxv {
139710f9455Smaxv 
140*d50c96bbSriastradh 	memset(osfs, 0, sizeof(*osfs));
141710f9455Smaxv 	if (!strncmp(MOUNT_FFS, bsfs->f_fstypename, sizeof(bsfs->f_fstypename)))
142710f9455Smaxv 		osfs->f_type = OSF1_MOUNT_UFS;
143710f9455Smaxv 	else if (!strncmp(MOUNT_NFS, bsfs->f_fstypename, sizeof(bsfs->f_fstypename)))
144710f9455Smaxv 		osfs->f_type = OSF1_MOUNT_NFS;
145710f9455Smaxv 	else if (!strncmp(MOUNT_MFS, bsfs->f_fstypename, sizeof(bsfs->f_fstypename)))
146710f9455Smaxv 		osfs->f_type = OSF1_MOUNT_MFS;
147710f9455Smaxv 	else
148710f9455Smaxv 		/* uh oh...  XXX = PC, CDFS, PROCFS, etc. */
149710f9455Smaxv 		osfs->f_type = OSF1_MOUNT_ADDON;
150710f9455Smaxv 	osfs->f_flags = bsfs->f_flag;		/* XXX translate */
151710f9455Smaxv 	osfs->f_fsize = bsfs->f_frsize;
152710f9455Smaxv 	osfs->f_bsize = bsfs->f_bsize;
153710f9455Smaxv 	osfs->f_blocks = bsfs->f_blocks;
154710f9455Smaxv 	osfs->f_bfree = bsfs->f_bfree;
155710f9455Smaxv 	osfs->f_bavail = bsfs->f_bavail;
156710f9455Smaxv 	osfs->f_files = bsfs->f_files;
157710f9455Smaxv 	osfs->f_ffree = bsfs->f_ffree;
158710f9455Smaxv 	memcpy(&osfs->f_fsid, &bsfs->f_fsidx, sizeof osfs->f_fsid);
159710f9455Smaxv 	/* osfs->f_spare zeroed above */
160710f9455Smaxv 	memcpy(osfs->f_mntonname, bsfs->f_mntonname, sizeof osfs->f_mntonname);
161710f9455Smaxv 	memcpy(osfs->f_mntfromname, bsfs->f_mntfromname,
162710f9455Smaxv 	    sizeof osfs->f_mntfromname);
163710f9455Smaxv 	/* XXX osfs->f_xxx should be filled in... */
164710f9455Smaxv }
165710f9455Smaxv 
166710f9455Smaxv /* --------------------------------------------------------------------- */
167710f9455Smaxv 
168710f9455Smaxv int
linux_sys_osf1_wait4(struct lwp * l,const struct linux_sys_osf1_wait4_args * uap,register_t * retval)169710f9455Smaxv linux_sys_osf1_wait4(struct lwp *l, const struct linux_sys_osf1_wait4_args *uap, register_t *retval)
170710f9455Smaxv {
171710f9455Smaxv 	struct osf1_rusage osf1_rusage;
172710f9455Smaxv 	struct rusage netbsd_rusage;
173710f9455Smaxv 	unsigned long leftovers;
174710f9455Smaxv 	int error, status;
175710f9455Smaxv 	int options = SCARG(uap, options);
176710f9455Smaxv 	int pid = SCARG(uap, pid);
177710f9455Smaxv 
178710f9455Smaxv 	/* translate options */
179710f9455Smaxv 	options = emul_flags_translate(osf1_wait_options_xtab,
180710f9455Smaxv 	    options, &leftovers);
181710f9455Smaxv 	if (leftovers != 0)
182710f9455Smaxv 		return (EINVAL);
183710f9455Smaxv 
184710f9455Smaxv 	error = do_sys_wait(&pid, &status, options,
185710f9455Smaxv 	    SCARG(uap, rusage) != NULL ? &netbsd_rusage : NULL);
186710f9455Smaxv 
187710f9455Smaxv 	retval[0] = pid;
188710f9455Smaxv 	if (pid == 0)
189710f9455Smaxv 		return error;
190710f9455Smaxv 
191710f9455Smaxv 	if (SCARG(uap, rusage)) {
192710f9455Smaxv 		osf1_cvt_rusage_from_native(&netbsd_rusage, &osf1_rusage);
193710f9455Smaxv 		error = copyout(&osf1_rusage, SCARG(uap, rusage),
194710f9455Smaxv 		    sizeof osf1_rusage);
195710f9455Smaxv 	}
196710f9455Smaxv 
197710f9455Smaxv 	if (error == 0 && SCARG(uap, status))
198710f9455Smaxv 		error = copyout(&status, SCARG(uap, status), sizeof(status));
199710f9455Smaxv 
200710f9455Smaxv 	return error;
201710f9455Smaxv }
202710f9455Smaxv 
203710f9455Smaxv #define	OSF1_MNT_WAIT		0x1
204710f9455Smaxv #define	OSF1_MNT_NOWAIT		0x2
205710f9455Smaxv 
206710f9455Smaxv #define	OSF1_MNT_FORCE		0x1
207710f9455Smaxv #define	OSF1_MNT_NOFORCE	0x2
208710f9455Smaxv 
209710f9455Smaxv /* acceptable flags for various calls */
210710f9455Smaxv #define	OSF1_GETFSSTAT_FLAGS	(OSF1_MNT_WAIT|OSF1_MNT_NOWAIT)
211710f9455Smaxv #define	OSF1_MOUNT_FLAGS	0xffffffff			/* XXX */
212710f9455Smaxv #define	OSF1_UNMOUNT_FLAGS	(OSF1_MNT_FORCE|OSF1_MNT_NOFORCE)
213710f9455Smaxv 
214710f9455Smaxv static int
osf1_mount_mfs(struct lwp * l,const struct linux_sys_osf1_mount_args * uap)215710f9455Smaxv osf1_mount_mfs(struct lwp *l, const struct linux_sys_osf1_mount_args *uap)
216710f9455Smaxv {
217710f9455Smaxv 	struct osf1_mfs_args osf_ma;
218710f9455Smaxv 	struct mfs_args bsd_ma;
219710f9455Smaxv 	int error;
220710f9455Smaxv 	register_t dummy;
221710f9455Smaxv 
222710f9455Smaxv 	if ((error = copyin(SCARG(uap, data), &osf_ma, sizeof osf_ma)))
223710f9455Smaxv 		return error;
224710f9455Smaxv 
225710f9455Smaxv 	memset(&bsd_ma, 0, sizeof bsd_ma);
226710f9455Smaxv 	bsd_ma.fspec = osf_ma.name;
227710f9455Smaxv 	/* XXX export args */
228710f9455Smaxv 	bsd_ma.base = osf_ma.base;
229710f9455Smaxv 	bsd_ma.size = osf_ma.size;
230710f9455Smaxv 
231710f9455Smaxv 	return do_sys_mount(l, "mfs", UIO_SYSSPACE, SCARG(uap, path),
232710f9455Smaxv 	    SCARG(uap, flags), &bsd_ma, UIO_SYSSPACE, sizeof bsd_ma, &dummy);
233710f9455Smaxv }
234710f9455Smaxv 
235710f9455Smaxv static int
osf1_mount_nfs(struct lwp * l,const struct linux_sys_osf1_mount_args * uap)236710f9455Smaxv osf1_mount_nfs(struct lwp *l, const struct linux_sys_osf1_mount_args *uap)
237710f9455Smaxv {
238710f9455Smaxv 	struct osf1_nfs_args osf_na;
239710f9455Smaxv 	struct nfs_args bsd_na;
240710f9455Smaxv 	int error;
241710f9455Smaxv 	unsigned long leftovers;
242710f9455Smaxv 	register_t dummy;
243710f9455Smaxv 
244710f9455Smaxv 	if ((error = copyin(SCARG(uap, data), &osf_na, sizeof osf_na)))
245710f9455Smaxv 		return error;
246710f9455Smaxv 
247710f9455Smaxv 	memset(&bsd_na, 0, sizeof bsd_na);
248710f9455Smaxv 	bsd_na.addr = (struct sockaddr *)osf_na.addr;
249710f9455Smaxv 	bsd_na.addrlen = sizeof (struct sockaddr_in);
250710f9455Smaxv 	bsd_na.fh = osf_na.fh;
251710f9455Smaxv 
252710f9455Smaxv         /* translate flags */
253710f9455Smaxv         bsd_na.flags = emul_flags_translate(osf1_nfs_mount_flags_xtab,
254710f9455Smaxv             osf_na.flags, &leftovers);
255710f9455Smaxv 	if (leftovers & OSF1_NFSMNT_HOSTNAME) {
256710f9455Smaxv 		leftovers &= ~OSF1_NFSMNT_HOSTNAME;
257710f9455Smaxv 		bsd_na.hostname = osf_na.hostname;
258710f9455Smaxv 	} else {
259710f9455Smaxv 		/* XXX FILL IN HOST NAME WITH IPADDR? */
260710f9455Smaxv 	}
261710f9455Smaxv 	if (leftovers & OSF1_NFSMNT_TCP) {
262710f9455Smaxv 		leftovers &= ~OSF1_NFSMNT_TCP;
263710f9455Smaxv 		bsd_na.sotype = SOCK_DGRAM;
264710f9455Smaxv 		bsd_na.proto = 0;
265710f9455Smaxv 	} else {
266710f9455Smaxv 		bsd_na.sotype = SOCK_STREAM;
267710f9455Smaxv 		bsd_na.proto = 0;
268710f9455Smaxv 	}
269710f9455Smaxv         if (leftovers != 0)
270710f9455Smaxv                 return (EINVAL);
271710f9455Smaxv 
272710f9455Smaxv 	/* copy structure elements based on flags */
273710f9455Smaxv 	if (bsd_na.flags & NFSMNT_WSIZE)
274710f9455Smaxv 		bsd_na.wsize = osf_na.wsize;
275710f9455Smaxv 	if (bsd_na.flags & NFSMNT_RSIZE)
276710f9455Smaxv 		bsd_na.rsize = osf_na.rsize;
277710f9455Smaxv 	if (bsd_na.flags & NFSMNT_TIMEO)
278710f9455Smaxv 		bsd_na.timeo = osf_na.timeo;
279710f9455Smaxv 	if (bsd_na.flags & NFSMNT_RETRANS)
280710f9455Smaxv 		bsd_na.retrans = osf_na.retrans;
281710f9455Smaxv 
282710f9455Smaxv 	return do_sys_mount(l, "nfs", UIO_SYSSPACE, SCARG(uap, path),
283710f9455Smaxv 	    SCARG(uap, flags), &bsd_na, UIO_SYSSPACE, sizeof bsd_na, &dummy);
284710f9455Smaxv }
285710f9455Smaxv 
286710f9455Smaxv int
linux_sys_osf1_mount(struct lwp * l,const struct linux_sys_osf1_mount_args * uap,register_t * retval)287710f9455Smaxv linux_sys_osf1_mount(struct lwp *l, const struct linux_sys_osf1_mount_args *uap, register_t *retval)
288710f9455Smaxv {
289710f9455Smaxv 
290710f9455Smaxv 	if (SCARG(uap, flags) & ~OSF1_MOUNT_FLAGS)
291710f9455Smaxv 		return (EINVAL);
292710f9455Smaxv 
293710f9455Smaxv 	/* XXX - xlate flags */
294710f9455Smaxv 
295710f9455Smaxv 	switch (SCARG(uap, type)) {
296710f9455Smaxv 	case OSF1_MOUNT_NFS:
297710f9455Smaxv 		return osf1_mount_nfs(l, uap);
298710f9455Smaxv 		break;
299710f9455Smaxv 
300710f9455Smaxv 	case OSF1_MOUNT_MFS:
301710f9455Smaxv 		return osf1_mount_mfs(l, uap);
302710f9455Smaxv 
303710f9455Smaxv 	default:
304710f9455Smaxv 		return (EINVAL);
305710f9455Smaxv 	}
306710f9455Smaxv }
307710f9455Smaxv 
308710f9455Smaxv int
linux_sys_osf1_set_program_attributes(struct lwp * l,const struct linux_sys_osf1_set_program_attributes_args * uap,register_t * retval)309710f9455Smaxv linux_sys_osf1_set_program_attributes(struct lwp *l, const struct linux_sys_osf1_set_program_attributes_args *uap, register_t *retval)
310710f9455Smaxv {
311710f9455Smaxv 	struct proc *p = l->l_proc;
312710f9455Smaxv 	segsz_t tsize, dsize;
313710f9455Smaxv 
314710f9455Smaxv 	tsize = btoc(SCARG(uap, tsize));
315710f9455Smaxv 	dsize = btoc(SCARG(uap, dsize));
316710f9455Smaxv 
317710f9455Smaxv 	if (dsize > p->p_rlimit[RLIMIT_DATA].rlim_cur)
318710f9455Smaxv 		return (ENOMEM);
3195f59585eSchristos #ifdef MAXTSIZ
320710f9455Smaxv 	if (tsize > MAXTSIZ)
321710f9455Smaxv 		return (ENOMEM);
3225f59585eSchristos #endif
323710f9455Smaxv 
324710f9455Smaxv 	/* XXXSMP unlocked */
325710f9455Smaxv 	p->p_vmspace->vm_taddr = SCARG(uap, taddr);
326710f9455Smaxv 	p->p_vmspace->vm_tsize = tsize;
327710f9455Smaxv 	p->p_vmspace->vm_daddr = SCARG(uap, daddr);
328710f9455Smaxv 	p->p_vmspace->vm_dsize = dsize;
329710f9455Smaxv 
330710f9455Smaxv 	return (0);
331710f9455Smaxv }
332710f9455Smaxv 
333710f9455Smaxv int
linux_sys_osf1_setitimer(struct lwp * l,const struct linux_sys_osf1_setitimer_args * uap,register_t * retval)334710f9455Smaxv linux_sys_osf1_setitimer(struct lwp *l, const struct linux_sys_osf1_setitimer_args *uap, register_t *retval)
335710f9455Smaxv {
336710f9455Smaxv 	struct osf1_itimerval o_itv, o_oitv;
337710f9455Smaxv 	struct itimerval b_itv, b_oitv;
338710f9455Smaxv 	int which;
339710f9455Smaxv 	int error;
340710f9455Smaxv 
341710f9455Smaxv 	switch (SCARG(uap, which)) {
342710f9455Smaxv 	case OSF1_ITIMER_REAL:
343710f9455Smaxv 		which = ITIMER_REAL;
344710f9455Smaxv 		break;
345710f9455Smaxv 
346710f9455Smaxv 	case OSF1_ITIMER_VIRTUAL:
347710f9455Smaxv 		which = ITIMER_VIRTUAL;
348710f9455Smaxv 		break;
349710f9455Smaxv 
350710f9455Smaxv 	case OSF1_ITIMER_PROF:
351710f9455Smaxv 		which = ITIMER_PROF;
352710f9455Smaxv 		break;
353710f9455Smaxv 
354710f9455Smaxv 	default:
355710f9455Smaxv 		return (EINVAL);
356710f9455Smaxv 	}
357710f9455Smaxv 
358710f9455Smaxv 	/* get the OSF/1 itimerval argument */
359710f9455Smaxv 	error = copyin(SCARG(uap, itv), &o_itv, sizeof o_itv);
360710f9455Smaxv 	if (error != 0)
361710f9455Smaxv 		return error;
362710f9455Smaxv 
363710f9455Smaxv 	/* fill in and the NetBSD timeval */
364710f9455Smaxv 	memset(&b_itv, 0, sizeof b_itv);
365710f9455Smaxv 	b_itv.it_interval.tv_sec = o_itv.it_interval.tv_sec;
366710f9455Smaxv 	b_itv.it_interval.tv_usec = o_itv.it_interval.tv_usec;
367710f9455Smaxv 	b_itv.it_value.tv_sec = o_itv.it_value.tv_sec;
368710f9455Smaxv 	b_itv.it_value.tv_usec = o_itv.it_value.tv_usec;
369710f9455Smaxv 
370710f9455Smaxv 	if (SCARG(uap, oitv) != NULL) {
371710f9455Smaxv 		dogetitimer(l->l_proc, which, &b_oitv);
372710f9455Smaxv 		if (error)
373710f9455Smaxv 			return error;
374710f9455Smaxv 	}
375710f9455Smaxv 
376710f9455Smaxv 	error = dosetitimer(l->l_proc, which, &b_itv);
377710f9455Smaxv 
378710f9455Smaxv 	if (error == 0 || SCARG(uap, oitv) == NULL)
379710f9455Smaxv 		return error;
380710f9455Smaxv 
381710f9455Smaxv 	/* fill in and copy out the old timeval */
382710f9455Smaxv 	memset(&o_oitv, 0, sizeof o_oitv);
383710f9455Smaxv 	o_oitv.it_interval.tv_sec = b_oitv.it_interval.tv_sec;
384710f9455Smaxv 	o_oitv.it_interval.tv_usec = b_oitv.it_interval.tv_usec;
385710f9455Smaxv 	o_oitv.it_value.tv_sec = b_oitv.it_value.tv_sec;
386710f9455Smaxv 	o_oitv.it_value.tv_usec = b_oitv.it_value.tv_usec;
387710f9455Smaxv 
388710f9455Smaxv 	return copyout(&o_oitv, SCARG(uap, oitv), sizeof o_oitv);
389710f9455Smaxv }
390710f9455Smaxv 
391710f9455Smaxv int
linux_sys_osf1_select(struct lwp * l,const struct linux_sys_osf1_select_args * uap,register_t * retval)392710f9455Smaxv linux_sys_osf1_select(struct lwp *l, const struct linux_sys_osf1_select_args *uap,
393710f9455Smaxv     register_t *retval)
394710f9455Smaxv {
395710f9455Smaxv 	struct osf1_timeval otv;
396710f9455Smaxv 	struct timespec ats, *ts = NULL;
397710f9455Smaxv 	int error;
398710f9455Smaxv 
399710f9455Smaxv 	if (SCARG(uap, tv)) {
400710f9455Smaxv 		/* get the OSF/1 timeval argument */
401710f9455Smaxv 		error = copyin(SCARG(uap, tv), &otv, sizeof otv);
402710f9455Smaxv 		if (error != 0)
403710f9455Smaxv 			return error;
404710f9455Smaxv 
405710f9455Smaxv 		ats.tv_sec = otv.tv_sec;
406710f9455Smaxv 		ats.tv_nsec = otv.tv_usec * 1000;
407710f9455Smaxv 		ts = &ats;
408710f9455Smaxv 	}
409710f9455Smaxv 
410710f9455Smaxv 	return selcommon(retval, SCARG(uap, nd), SCARG(uap, in),
411710f9455Smaxv 	    SCARG(uap, ou), SCARG(uap, ex), ts, NULL);
412710f9455Smaxv }
413710f9455Smaxv 
414710f9455Smaxv int
linux_sys_osf1_gettimeofday(struct lwp * l,const struct linux_sys_osf1_gettimeofday_args * uap,register_t * retval)415710f9455Smaxv linux_sys_osf1_gettimeofday(struct lwp *l, const struct linux_sys_osf1_gettimeofday_args *uap, register_t *retval)
416710f9455Smaxv {
417710f9455Smaxv 	struct osf1_timeval otv;
418710f9455Smaxv 	struct osf1_timezone otz;
419710f9455Smaxv 	struct timeval tv;
420710f9455Smaxv 	int error;
421710f9455Smaxv 
422710f9455Smaxv 	microtime(&tv);
423710f9455Smaxv 	memset(&otv, 0, sizeof otv);
424710f9455Smaxv 	otv.tv_sec = tv.tv_sec;
425710f9455Smaxv 	otv.tv_usec = tv.tv_usec;
4261612b2beSchristos 	error = copyout(&otv, SCARG(uap, tv), sizeof otv);
427710f9455Smaxv 
428710f9455Smaxv 	if (error == 0 && SCARG(uap, tzp) != NULL) {
429710f9455Smaxv 		memset(&otz, 0, sizeof otz);
430710f9455Smaxv 		error = copyout(&otz, SCARG(uap, tzp), sizeof otz);
431710f9455Smaxv 	}
432710f9455Smaxv 	return (error);
433710f9455Smaxv }
434710f9455Smaxv 
435710f9455Smaxv int
linux_sys_osf1_getrusage(struct lwp * l,const struct linux_sys_osf1_getrusage_args * uap,register_t * retval)436710f9455Smaxv linux_sys_osf1_getrusage(struct lwp *l, const struct linux_sys_osf1_getrusage_args *uap, register_t *retval)
437710f9455Smaxv {
438710f9455Smaxv 	int error, who;
439710f9455Smaxv 	struct osf1_rusage osf1_rusage;
440710f9455Smaxv 	struct rusage ru;
441710f9455Smaxv 	struct proc *p = l->l_proc;
442710f9455Smaxv 
443710f9455Smaxv 
444710f9455Smaxv 	switch (SCARG(uap, who)) {
445710f9455Smaxv 	case OSF1_RUSAGE_SELF:
446710f9455Smaxv 		who = RUSAGE_SELF;
447710f9455Smaxv 		break;
448710f9455Smaxv 
449710f9455Smaxv 	case OSF1_RUSAGE_CHILDREN:
450710f9455Smaxv 		who = RUSAGE_CHILDREN;
451710f9455Smaxv 		break;
452710f9455Smaxv 
453710f9455Smaxv 	case OSF1_RUSAGE_THREAD:		/* XXX not supported */
454710f9455Smaxv 	default:
455710f9455Smaxv 		return EINVAL;
456710f9455Smaxv 	}
457710f9455Smaxv 
458710f9455Smaxv 	error = getrusage1(p, who, &ru);
459710f9455Smaxv 	if (error != 0)
460710f9455Smaxv 		return error;
461710f9455Smaxv 
462710f9455Smaxv 	osf1_cvt_rusage_from_native(&ru, &osf1_rusage);
463710f9455Smaxv 
464710f9455Smaxv 	return copyout(&osf1_rusage, SCARG(uap, rusage), sizeof osf1_rusage);
465710f9455Smaxv }
466710f9455Smaxv 
467710f9455Smaxv int
linux_sys_osf1_settimeofday(struct lwp * l,const struct linux_sys_osf1_settimeofday_args * uap,register_t * retval)468710f9455Smaxv linux_sys_osf1_settimeofday(struct lwp *l, const struct linux_sys_osf1_settimeofday_args *uap, register_t *retval)
469710f9455Smaxv {
470710f9455Smaxv 	struct osf1_timeval otv;
471710f9455Smaxv 	struct timeval tv, *tvp;
472710f9455Smaxv 	int error = 0;
473710f9455Smaxv 
474710f9455Smaxv 	if (SCARG(uap, tv) == NULL)
475710f9455Smaxv 		tvp = NULL;
476710f9455Smaxv 	else {
477710f9455Smaxv 		/* get the OSF/1 timeval argument */
478710f9455Smaxv 		error = copyin(SCARG(uap, tv), &otv, sizeof otv);
479710f9455Smaxv 		if (error != 0)
480710f9455Smaxv 			return error;
481710f9455Smaxv 
482710f9455Smaxv 		tv.tv_sec = otv.tv_sec;
483710f9455Smaxv 		tv.tv_usec = otv.tv_usec;
484710f9455Smaxv 		tvp = &tv;
485710f9455Smaxv 	}
486710f9455Smaxv 
487710f9455Smaxv 	/* NetBSD ignores the timezone field */
488710f9455Smaxv 
489710f9455Smaxv 	return settimeofday1(tvp, false, (const void *)SCARG(uap, tzp), l, true);
490710f9455Smaxv }
491710f9455Smaxv 
492710f9455Smaxv int
linux_sys_osf1_utimes(struct lwp * l,const struct linux_sys_osf1_utimes_args * uap,register_t * retval)493710f9455Smaxv linux_sys_osf1_utimes(struct lwp *l, const struct linux_sys_osf1_utimes_args *uap, register_t *retval)
494710f9455Smaxv {
495710f9455Smaxv 	struct osf1_timeval otv;
496710f9455Smaxv 	struct timeval tv[2], *tvp;
497710f9455Smaxv 	int error;
498710f9455Smaxv 
499710f9455Smaxv 	if (SCARG(uap, tptr) == NULL)
500710f9455Smaxv 		tvp = NULL;
501710f9455Smaxv 	else {
502710f9455Smaxv 		/* get the OSF/1 timeval argument */
503710f9455Smaxv 		error = copyin(SCARG(uap, tptr), &otv, sizeof otv);
504710f9455Smaxv 		if (error != 0)
505710f9455Smaxv 			return error;
506710f9455Smaxv 
507710f9455Smaxv 		/* fill in and copy out the NetBSD timeval */
508710f9455Smaxv 		tv[0].tv_sec = otv.tv_sec;
509710f9455Smaxv 		tv[0].tv_usec = otv.tv_usec;
510710f9455Smaxv 		/* Set access and modified to the same time */
511710f9455Smaxv 		tv[1].tv_sec = otv.tv_sec;
512710f9455Smaxv 		tv[1].tv_usec = otv.tv_usec;
513710f9455Smaxv 		tvp = tv;
514710f9455Smaxv 	}
515710f9455Smaxv 
516710f9455Smaxv 	return do_sys_utimes(l, NULL, SCARG(uap, path), FOLLOW,
517710f9455Smaxv 			    tvp, UIO_SYSSPACE);
518710f9455Smaxv }
519710f9455Smaxv 
520710f9455Smaxv int
linux_sys_osf1_statfs(struct lwp * l,const struct linux_sys_osf1_statfs_args * uap,register_t * retval)521710f9455Smaxv linux_sys_osf1_statfs(struct lwp *l, const struct linux_sys_osf1_statfs_args *uap, register_t *retval)
522710f9455Smaxv {
523710f9455Smaxv 	struct mount *mp;
524710f9455Smaxv 	struct statvfs *sp;
525710f9455Smaxv 	struct osf1_statfs osfs;
526710f9455Smaxv 	int error;
527710f9455Smaxv 	struct vnode *vp;
528710f9455Smaxv 
529710f9455Smaxv 	error = namei_simple_user(SCARG(uap, path),
530710f9455Smaxv 				NSM_FOLLOW_TRYEMULROOT, &vp);
531710f9455Smaxv 	if (error != 0)
532710f9455Smaxv 		return (error);
533710f9455Smaxv 	mp = vp->v_mount;
534710f9455Smaxv 	sp = &mp->mnt_stat;
535710f9455Smaxv 	vrele(vp);
536710f9455Smaxv 	if ((error = VFS_STATVFS(mp, sp)))
537710f9455Smaxv 		return (error);
538710f9455Smaxv 	sp->f_flag = mp->mnt_flag & MNT_VISFLAGMASK;
539710f9455Smaxv 	osf1_cvt_statfs_from_native(sp, &osfs);
540710f9455Smaxv 	return copyout(&osfs, SCARG(uap, buf), uimin(sizeof osfs,
541710f9455Smaxv 	    SCARG(uap, len)));
542710f9455Smaxv }
543710f9455Smaxv 
544710f9455Smaxv int
linux_sys_osf1_fstatfs(struct lwp * l,const struct linux_sys_osf1_fstatfs_args * uap,register_t * retval)545710f9455Smaxv linux_sys_osf1_fstatfs(struct lwp *l, const struct linux_sys_osf1_fstatfs_args *uap, register_t *retval)
546710f9455Smaxv {
547710f9455Smaxv 	file_t *fp;
548710f9455Smaxv 	struct mount *mp;
549710f9455Smaxv 	struct statvfs *sp;
550710f9455Smaxv 	struct osf1_statfs osfs;
551710f9455Smaxv 	int error;
552710f9455Smaxv 
553710f9455Smaxv 	/* fd_getvnode() will use the descriptor for us */
554710f9455Smaxv 	if ((error = fd_getvnode(SCARG(uap, fd), &fp)))
555710f9455Smaxv 		return (error);
556710f9455Smaxv 	mp = fp->f_vnode->v_mount;
557710f9455Smaxv 	sp = &mp->mnt_stat;
558710f9455Smaxv 	if ((error = VFS_STATVFS(mp, sp)))
559710f9455Smaxv 		goto out;
560710f9455Smaxv 	sp->f_flag = mp->mnt_flag & MNT_VISFLAGMASK;
561710f9455Smaxv 	osf1_cvt_statfs_from_native(sp, &osfs);
562710f9455Smaxv 	error = copyout(&osfs, SCARG(uap, buf), uimin(sizeof osfs,
563710f9455Smaxv 	    SCARG(uap, len)));
564710f9455Smaxv  out:
565710f9455Smaxv  	fd_putfile(SCARG(uap, fd));
566710f9455Smaxv 	return (error);
567710f9455Smaxv }
568710f9455Smaxv 
569710f9455Smaxv int
linux_sys_osf1_sysinfo(struct lwp * l,const struct linux_sys_osf1_sysinfo_args * uap,register_t * retval)570710f9455Smaxv linux_sys_osf1_sysinfo(struct lwp *l, const struct linux_sys_osf1_sysinfo_args *uap, register_t *retval)
571710f9455Smaxv {
572710f9455Smaxv 	const char *string;
573710f9455Smaxv 	size_t slen;
574710f9455Smaxv 	int error;
575710f9455Smaxv 
576710f9455Smaxv 	error = 0;
577710f9455Smaxv 	switch (SCARG(uap, cmd)) {
578710f9455Smaxv 	case OSF1_SI_SYSNAME:
579710f9455Smaxv 		string = ostype;
580710f9455Smaxv 		break;
581710f9455Smaxv 
582710f9455Smaxv 	case OSF1_SI_HOSTNAME:
583710f9455Smaxv 		string = hostname;
584710f9455Smaxv 		break;
585710f9455Smaxv 
586710f9455Smaxv 	case OSF1_SI_RELEASE:
587710f9455Smaxv 		string = osrelease;
588710f9455Smaxv 		break;
589710f9455Smaxv 
590710f9455Smaxv 	case OSF1_SI_VERSION:
591710f9455Smaxv 		goto should_handle;
592710f9455Smaxv 
593710f9455Smaxv 	case OSF1_SI_MACHINE:
594710f9455Smaxv 		string = MACHINE;
595710f9455Smaxv 		break;
596710f9455Smaxv 
597710f9455Smaxv 	case OSF1_SI_ARCHITECTURE:
598710f9455Smaxv 		string = MACHINE_ARCH;
599710f9455Smaxv 		break;
600710f9455Smaxv 
601710f9455Smaxv 	case OSF1_SI_HW_SERIAL:
602710f9455Smaxv 		string = "666";			/* OSF/1 emulation?  YES! */
603710f9455Smaxv 		break;
604710f9455Smaxv 
605710f9455Smaxv 	case OSF1_SI_HW_PROVIDER:
606710f9455Smaxv 		string = "unknown";
607710f9455Smaxv 		break;
608710f9455Smaxv 
609710f9455Smaxv 	case OSF1_SI_SRPC_DOMAIN:
610710f9455Smaxv 		goto dont_care;
611710f9455Smaxv 
612710f9455Smaxv 	case OSF1_SI_SET_HOSTNAME:
613710f9455Smaxv 		goto should_handle;
614710f9455Smaxv 
615710f9455Smaxv 	case OSF1_SI_SET_SYSNAME:
616710f9455Smaxv 		goto should_handle;
617710f9455Smaxv 
618710f9455Smaxv 	case OSF1_SI_SET_SRPC_DOMAIN:
619710f9455Smaxv 		goto dont_care;
620710f9455Smaxv 
621710f9455Smaxv 	default:
622710f9455Smaxv should_handle:
623710f9455Smaxv 		printf("osf1_sys_sysinfo(%d, %p, 0x%lx)\n", SCARG(uap, cmd),
624710f9455Smaxv 		    SCARG(uap, buf), SCARG(uap,len));
625710f9455Smaxv dont_care:
626710f9455Smaxv 		return (EINVAL);
627710f9455Smaxv 	};
628710f9455Smaxv 
629710f9455Smaxv 	slen = strlen(string) + 1;
630710f9455Smaxv 	if (SCARG(uap, buf)) {
631710f9455Smaxv 		error = copyout(string, SCARG(uap, buf),
632710f9455Smaxv 				uimin(slen, SCARG(uap, len)));
633710f9455Smaxv 		if (!error && (SCARG(uap, len) > 0) && (SCARG(uap, len) < slen))
634e3f92458Sthorpej 			error = ustore_char(SCARG(uap, buf)
635e3f92458Sthorpej 					    + SCARG(uap, len) - 1, 0);
636710f9455Smaxv 	}
637710f9455Smaxv 	if (!error)
638710f9455Smaxv 		retval[0] = slen;
639710f9455Smaxv 
640710f9455Smaxv 	return (error);
641710f9455Smaxv }
642710f9455Smaxv 
643710f9455Smaxv int
linux_sys_osf1_usleep_thread(struct lwp * l,const struct linux_sys_osf1_usleep_thread_args * uap,register_t * retval)644710f9455Smaxv linux_sys_osf1_usleep_thread(struct lwp *l, const struct linux_sys_osf1_usleep_thread_args *uap, register_t *retval)
645710f9455Smaxv {
646710f9455Smaxv 	struct osf1_timeval otv, endotv;
647710f9455Smaxv 	struct timeval tv, ntv, endtv;
648710f9455Smaxv 	u_long ticks;
649710f9455Smaxv 	int error;
650710f9455Smaxv 
651710f9455Smaxv 	if ((error = copyin(SCARG(uap, sleep), &otv, sizeof otv)))
652710f9455Smaxv 		return (error);
653710f9455Smaxv 	tv.tv_sec = otv.tv_sec;
654710f9455Smaxv 	tv.tv_usec = otv.tv_usec;
655710f9455Smaxv 
656710f9455Smaxv 	ticks = howmany((u_long)tv.tv_sec * 1000000 + tv.tv_usec, tick);
657710f9455Smaxv 	if (ticks == 0)
658710f9455Smaxv 		ticks = 1;
659710f9455Smaxv 
660710f9455Smaxv 	getmicrotime(&tv);
661710f9455Smaxv 
662710f9455Smaxv 	tsleep(l, PUSER|PCATCH, "uslpthrd", ticks);	/* XXX */
663710f9455Smaxv 
664710f9455Smaxv 	if (SCARG(uap, slept) != NULL) {
665710f9455Smaxv 		getmicrotime(&ntv);
666710f9455Smaxv 		timersub(&ntv, &tv, &endtv);
667710f9455Smaxv 		if (endtv.tv_sec < 0 || endtv.tv_usec < 0)
668710f9455Smaxv 			endtv.tv_sec = endtv.tv_usec = 0;
669710f9455Smaxv 
670*d50c96bbSriastradh 		memset(&endotv, 0, sizeof(endotv));
671710f9455Smaxv 		endotv.tv_sec = endtv.tv_sec;
672710f9455Smaxv 		endotv.tv_usec = endtv.tv_usec;
673710f9455Smaxv 		error = copyout(&endotv, SCARG(uap, slept), sizeof endotv);
674710f9455Smaxv 	}
675710f9455Smaxv 	return (error);
676710f9455Smaxv }
677710f9455Smaxv 
678710f9455Smaxv int
linux_sys_osf1_getsysinfo(struct lwp * l,const struct linux_sys_osf1_getsysinfo_args * uap,register_t * retval)679710f9455Smaxv linux_sys_osf1_getsysinfo(struct lwp *l, const struct linux_sys_osf1_getsysinfo_args *uap, register_t *retval)
680710f9455Smaxv {
681710f9455Smaxv 	extern int ncpus;
682710f9455Smaxv 	int error;
683710f9455Smaxv 	int unit;
684710f9455Smaxv 	long percpu;
685710f9455Smaxv 	long proctype;
686710f9455Smaxv 	u_int64_t fpflags;
687710f9455Smaxv 	struct osf1_cpu_info cpuinfo;
688710f9455Smaxv 	const void *data;
689710f9455Smaxv 	size_t datalen;
690710f9455Smaxv 
691710f9455Smaxv 	error = 0;
692710f9455Smaxv 
693710f9455Smaxv 	switch(SCARG(uap, op))
694710f9455Smaxv 	{
695710f9455Smaxv 	case OSF_GET_MAX_UPROCS:
696710f9455Smaxv 		data = &maxproc;
697710f9455Smaxv 		datalen = sizeof(maxproc);
698710f9455Smaxv 		break;
699710f9455Smaxv 	case OSF_GET_PHYSMEM:
700710f9455Smaxv 		data = &physmem;
701710f9455Smaxv 		datalen = sizeof(physmem);
702710f9455Smaxv 		break;
703710f9455Smaxv 	case OSF_GET_MAX_CPU:
704710f9455Smaxv 	case OSF_GET_CPUS_IN_BOX:
705710f9455Smaxv 		data = &ncpus;
706710f9455Smaxv 		datalen = sizeof(ncpus);
707710f9455Smaxv 		break;
708710f9455Smaxv 	case OSF_GET_IEEE_FP_CONTROL:
709710f9455Smaxv 		if (((fpflags = alpha_read_fp_c(l)) & IEEE_INHERIT) != 0) {
710710f9455Smaxv 			fpflags |= 1ULL << 63;
711710f9455Smaxv 			fpflags &= ~IEEE_INHERIT;
712710f9455Smaxv 		}
713710f9455Smaxv 		data = &fpflags;
714710f9455Smaxv 		datalen = sizeof(fpflags);
715710f9455Smaxv 		break;
716710f9455Smaxv 	case OSF_GET_CPU_INFO:
717710f9455Smaxv 		memset(&cpuinfo, 0, sizeof(cpuinfo));
718710f9455Smaxv #ifdef __alpha__
719710f9455Smaxv 		unit = alpha_pal_whami();
720710f9455Smaxv #else
721710f9455Smaxv 		unit = 0; /* XXX */
722710f9455Smaxv #endif
723710f9455Smaxv 		cpuinfo.current_cpu = unit;
724710f9455Smaxv 		cpuinfo.cpus_in_box = ncpus;
725710f9455Smaxv 		cpuinfo.cpu_type = LOCATE_PCS(hwrpb, unit)->pcs_proc_type;
726710f9455Smaxv 		cpuinfo.ncpus = ncpus;
727710f9455Smaxv 		cpuinfo.cpus_present = ncpus;
728710f9455Smaxv 		cpuinfo.cpus_running = ncpus;
729710f9455Smaxv 		cpuinfo.cpu_binding = 1;
730710f9455Smaxv 		cpuinfo.cpu_ex_binding = 0;
731710f9455Smaxv 		cpuinfo.mhz = hwrpb->rpb_cc_freq / 1000000;
732710f9455Smaxv 		data = &cpuinfo;
733710f9455Smaxv 		datalen = sizeof(cpuinfo);
734710f9455Smaxv 		break;
735710f9455Smaxv 	case OSF_GET_PROC_TYPE:
736710f9455Smaxv #ifdef __alpha__
737710f9455Smaxv 		unit = alpha_pal_whami();
738710f9455Smaxv 		proctype = LOCATE_PCS(hwrpb, unit)->pcs_proc_type;
739710f9455Smaxv #else
740710f9455Smaxv 		proctype = 0;	/* XXX */
741710f9455Smaxv #endif
742710f9455Smaxv 		data = &proctype;
743710f9455Smaxv 		datalen = sizeof(percpu);
744710f9455Smaxv 		break;
745710f9455Smaxv 	case OSF_GET_HWRPB: /* note -- osf/1 doesn't have rpb_tbhint[8] */
746710f9455Smaxv 		data = hwrpb;
747710f9455Smaxv 		datalen = hwrpb->rpb_size;
748710f9455Smaxv 		break;
749710f9455Smaxv 	case OSF_GET_PLATFORM_NAME:
750710f9455Smaxv 		data = platform.model;
751710f9455Smaxv 		datalen = strlen(platform.model) + 1;
752710f9455Smaxv 		break;
753710f9455Smaxv 	default:
754710f9455Smaxv 		printf("osf1_getsysinfo called with unknown op=%ld\n",
755710f9455Smaxv 		       SCARG(uap, op));
756710f9455Smaxv 		/* return EINVAL; */
757710f9455Smaxv 		return 0;
758710f9455Smaxv 	}
759710f9455Smaxv 
760710f9455Smaxv 	if (SCARG(uap, nbytes) < datalen)
761710f9455Smaxv 		return (EINVAL);
762710f9455Smaxv 	error = copyout(data, SCARG(uap, buffer), datalen);
763710f9455Smaxv 	if (!error)
764710f9455Smaxv 		retval[0] = 1;
765710f9455Smaxv 	return (error);
766710f9455Smaxv }
767710f9455Smaxv 
768710f9455Smaxv int
linux_sys_osf1_setsysinfo(struct lwp * l,const struct linux_sys_osf1_setsysinfo_args * uap,register_t * retval)769710f9455Smaxv linux_sys_osf1_setsysinfo(struct lwp *l, const struct linux_sys_osf1_setsysinfo_args *uap, register_t *retval)
770710f9455Smaxv {
771710f9455Smaxv 	u_int64_t temp;
772710f9455Smaxv 	int error;
773710f9455Smaxv 
774710f9455Smaxv 	error = 0;
775710f9455Smaxv 
776710f9455Smaxv 	switch(SCARG(uap, op)) {
777710f9455Smaxv 	case OSF_SET_IEEE_FP_CONTROL:
778710f9455Smaxv 
779710f9455Smaxv 		if ((error = copyin(SCARG(uap, buffer), &temp, sizeof(temp))))
780710f9455Smaxv 			break;
781710f9455Smaxv 		if (temp >> 63 != 0)
782710f9455Smaxv 			temp |= IEEE_INHERIT;
783710f9455Smaxv 		alpha_write_fp_c(l, temp);
784710f9455Smaxv 		break;
785710f9455Smaxv 	default:
786710f9455Smaxv 		uprintf("osf1_setsysinfo called with op=%ld\n", SCARG(uap, op));
787710f9455Smaxv 		//error = EINVAL;
788710f9455Smaxv 	}
789710f9455Smaxv 	retval[0] = 0;
790710f9455Smaxv 	return (error);
791710f9455Smaxv }
792