diff --git a/include/Makefile b/include/Makefile index 55e9f0ff9d08..89d825d9762a 100644 --- a/include/Makefile +++ b/include/Makefile @@ -1,119 +1,119 @@ # @(#)Makefile 8.2 (Berkeley) 1/4/94 -# $Id: Makefile,v 1.87 1998/10/17 15:52:48 bde Exp $ +# $Id: Makefile,v 1.88 1998/12/19 00:21:13 dt Exp $ # # Doing a make install builds /usr/include # # The ``rm -rf''s used below are safe because rm doesn't follow symbolic # links. CLEANFILES= osreldate.h version vers.c SUBDIR= rpcsvc FILES= a.out.h ar.h assert.h bitstring.h ctype.h db.h dirent.h disktab.h \ dlfcn.h elf.h err.h fnmatch.h fstab.h \ - fts.h glob.h grp.h strhash.h histedit.h iso646.h \ + fts.h glob.h grp.h strhash.h histedit.h ieeefp.h iso646.h \ kvm.h limits.h link.h locale.h malloc.h memory.h mpool.h \ ndbm.h netdb.h nl_types.h nlist.h objformat.h \ paths.h pthread.h pthread_np.h pwd.h \ ranlib.h regex.h regexp.h resolv.h rune.h runetype.h setjmp.h sgtty.h \ signal.h stab.h stddef.h stdio.h stdlib.h string.h stringlist.h \ strings.h struct.h sysexits.h tar.h time.h timepps.h timers.h \ ttyent.h unistd.h utime.h utmp.h vis.h .if defined(WANT_CSRG_LIBM) FILES+= math.h .endif ARPAFILES= ftp.h inet.h nameser.h nameser_compat.h telnet.h tftp.h PROTOFILES= dumprestore.h routed.h rwhod.h talkd.h timed.h RPCFILES= auth.h auth_unix.h clnt.h pmap_clnt.h pmap_prot.h pmap_rmt.h \ rpc.h rpc_com.h rpc_msg.h svc.h svc_auth.h types.h xdr.h \ auth_des.h des.h des_crypt.h MFILES= float.h floatingpoint.h stdarg.h varargs.h # posix4/aio.h conflicts with dysons and isn't installed: PFILES= mqueue.h sched.h semaphore.h \ # aio.h LFILES= errno.h fcntl.h inttypes.h poll.h syslog.h termios.h LDIRS= cam msdosfs net netatalk netatm netinet netipx netkey netns nfs \ pccard posix4 sys vm LNOHEADERDIRS= isofs ufs LSUBDIRS= isofs/cd9660 ufs/ffs ufs/mfs ufs/ufs cam/scsi # Define SHARED to indicate whether you want symbolic links to the system # source (``symlinks''), or a separate copy (``copies''). ``symlinks'' is # probably only useful for developers and should be avoided if you do not # wish to tie your /usr/include and /usr/src together. #SHARED= symlinks SHARED?= copies all: osreldate.h osreldate.h: ${.CURDIR}/../sys/conf/newvers.sh \ ${.CURDIR}/../sys/sys/param.h @${ECHO} creating osreldate.h from newvers.sh setvar PARAMFILE ${.CURDIR}/../sys/sys/param.h; \ . ${.CURDIR}/../sys/conf/newvers.sh; \ echo "$$COPYRIGHT" > osreldate.h; \ echo \#'undef __FreeBSD_version' >> osreldate.h; \ echo \#'define __FreeBSD_version' $$RELDATE >> osreldate.h beforeinstall: ${SHARED} cd ${.CURDIR}; \ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \ ${FILES} ${DESTDIR}/usr/include cd ${.CURDIR}/arpa; \ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \ ${ARPAFILES} ${DESTDIR}/usr/include/arpa cd ${.CURDIR}/protocols; \ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \ ${PROTOFILES} ${DESTDIR}/usr/include/protocols cd ${.CURDIR}/rpc; \ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \ ${RPCFILES} ${DESTDIR}/usr/include/rpc ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \ ${.OBJDIR}/osreldate.h \ ${DESTDIR}/usr/include .for i in ${LFILES} ln -sf sys/$i ${DESTDIR}/usr/include/$i .endfor .for i in ${MFILES} ln -sf machine/$i ${DESTDIR}/usr/include/$i .endfor .for i in ${PFILES} ln -sf posix4/$i ${DESTDIR}/usr/include/$i .endfor copies: .for i in ${LDIRS} ${LNOHEADERDIRS} machine if [ -h ${DESTDIR}/usr/include/$i ]; then \ rm -f ${DESTDIR}/usr/include/$i; \ fi .endfor mtree -deU -f ${.CURDIR}/../etc/mtree/BSD.include.dist \ -p ${DESTDIR}/usr/include .for i in ${LDIRS} ${LSUBDIRS} cd ${.CURDIR}/../sys; \ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 $i/*.h \ ${DESTDIR}/usr/include/$i .endfor .if exists(${.CURDIR}/../sys/${MACHINE_ARCH}/include) cd ${.CURDIR}/../sys/${MACHINE_ARCH}/include; \ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 *.h \ ${DESTDIR}/usr/include/machine .endif symlinks: @${ECHO} "Setting up symlinks to kernel source tree..." .for i in ${LDIRS} ${LNOHEADERDIRS} rm -rf ${DESTDIR}/usr/include/$i ln -s ../../sys/$i ${DESTDIR}/usr/include/$i .endfor rm -rf ${DESTDIR}/usr/include/machine ln -s ../../sys/${MACHINE_ARCH}/include ${DESTDIR}/usr/include/machine .include diff --git a/include/ieeefp.h b/include/ieeefp.h new file mode 100644 index 000000000000..83db9a5574fe --- /dev/null +++ b/include/ieeefp.h @@ -0,0 +1,25 @@ +/* $NetBSD: ieeefp.h,v 1.4 1998/01/09 08:03:43 perry Exp $ */ + +/* + * Written by J.T. Conklin, Apr 6, 1995 + * Public domain. + */ + +#ifndef _IEEEFP_H_ +#define _IEEEFP_H_ + +#include +#include + +#ifdef i386 +#include +#else +extern fp_rnd fpgetround __P((void)); +extern fp_rnd fpsetround __P((fp_rnd)); +extern fp_except fpgetmask __P((void)); +extern fp_except fpsetmask __P((fp_except)); +extern fp_except fpgetsticky __P((void)); +extern fp_except fpsetsticky __P((fp_except)); +#endif /* i386 */ + +#endif /* _IEEEFP_H_ */ diff --git a/lib/libc/alpha/SYS.h b/lib/libc/alpha/SYS.h index cfc0909d8d32..15b7f8b9e853 100644 --- a/lib/libc/alpha/SYS.h +++ b/lib/libc/alpha/SYS.h @@ -1,130 +1,130 @@ -/* $Id: SYS.h,v 1.2 1998/06/09 22:43:34 jb Exp $ */ +/* $Id: SYS.h,v 1.3 1998/08/08 02:24:03 jb Exp $ */ /* From: NetBSD: SYS.h,v 1.5 1997/05/02 18:15:15 kleink Exp */ /* * Copyright (c) 1994, 1995 Carnegie-Mellon University. * All rights reserved. * * Author: Chris G. Demetriou * * Permission to use, copy, modify and distribute this software and * its documentation is hereby granted, provided that both the copyright * notice and this permission notice appear in all copies of the * software, derivative works or modified versions, and any portions * thereof, and that both notices appear in supporting documentation. * * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. * * Carnegie Mellon requests users of this software to return to * * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU * School of Computer Science * Carnegie Mellon University * Pittsburgh PA 15213-3890 * * any improvements or extensions that they make and grant Carnegie the * rights to redistribute these changes. */ #include #ifdef __NETBSD_SYSCALLS #include #else #include #endif #define CALLSYS_ERROR(name) \ CALLSYS_NOERROR(name); \ br gp, LLABEL(name,0); \ LLABEL(name,0): \ LDGP(gp); \ beq a3, LLABEL(name,1); \ - jmp zero, cerror; \ + jmp zero, .cerror; \ LLABEL(name,1): #define SYSCALL(name) \ LEAF(name,0); /* XXX # of args? */ \ CALLSYS_ERROR(name) #define SYSCALL_NOERROR(name) \ LEAF(name,0); /* XXX # of args? */ \ CALLSYS_NOERROR(name) #define RSYSCALL(name) \ SYSCALL(name); \ RET; \ END(name) #define RSYSCALL_NOERROR(name) \ SYSCALL_NOERROR(name); \ RET; \ END(name) #define PSEUDO(label,name) \ LEAF(label,0); /* XXX # of args? */ \ CALLSYS_ERROR(name); \ RET; \ END(label); #define PSEUDO_NOERROR(label,name) \ LEAF(label,0); /* XXX # of args? */ \ CALLSYS_NOERROR(name); \ RET; \ END(label); /* * Design note: * * The macros PSYSCALL() and PRSYSCALL() are intended for use where a * syscall needs to be renamed in the threaded library. When building * a normal library, they default to the traditional SYSCALL() and * RSYSCALL(). This avoids the need to #ifdef _THREAD_SAFE everywhere * that the renamed function needs to be called. */ #ifdef _THREAD_SAFE /* * For the thread_safe versions, we prepend _thread_sys_ to the function * name so that the 'C' wrapper can go around the real name. */ #define PCALL(name) \ CALL(___CONCAT(_thread_sys_,name)) #define PLEAF(name, args) \ LEAF(___CONCAT(_thread_sys_,name),args) #define PEND(name) \ END(___CONCAT(_thread_sys_,name)) #define PSYSCALL(name) \ PLEAF(name,0); /* XXX # of args? */ \ CALLSYS_ERROR(name) #define PRSYSCALL(name) \ PLEAF(name,0); /* XXX # of args? */ \ CALLSYS_ERROR(name) \ RET; \ PEND(name) #define PPSEUDO(label,name) \ PLEAF(label,0); /* XXX # of args? */ \ CALLSYS_ERROR(name); \ RET; \ PEND(label) #else /* * The non-threaded library defaults to traditional syscalls where * the function name matches the syscall name. */ #define PSYSCALL(x) SYSCALL(x) #define PRSYSCALL(x) RSYSCALL(x) #define PPSEUDO(x,y) PSEUDO(x,y) #define PLEAF(x,y) LEAF(x,y) #define PEND(x) END(x) #define PCALL(x) CALL(x) #endif diff --git a/lib/libc/alpha/gen/Makefile.inc b/lib/libc/alpha/gen/Makefile.inc index 3ff99f001439..cc7a87c10cff 100644 --- a/lib/libc/alpha/gen/Makefile.inc +++ b/lib/libc/alpha/gen/Makefile.inc @@ -1,47 +1,45 @@ -# $Id: Makefile.inc,v 1.3 1998/08/08 02:18:07 jb Exp $ +# $Id: Makefile.inc,v 1.4 1998/08/17 03:38:54 jb Exp $ SRCS+= _setjmp.S fabs.S frexp.c infinity.c isinf.c ldexp.c modf.c setjmp.S -SRCS+= flt_rounds.c - -#SRCS+= flt_rounds.c fpgetmask.c fpgetround.c fpgetsticky.c fpsetmask.c \ -# fpsetround.c fpsetsticky.c +SRCS+= flt_rounds.c fpgetmask.c fpgetround.c fpgetsticky.c fpsetmask.c \ + fpsetround.c fpsetsticky.c SRCS+= sigsetjmp.S SRCS+= __divqu.S __divq.S __divlu.S __divl.S SRCS+= __remqu.S __remq.S __remlu.S __reml.S CLEANFILES+= __divqu.S __divq.S __divlu.S __divl.S CLEANFILES+= __remqu.S __remq.S __remlu.S __reml.S __divqu.S: ${.CURDIR}/../libc/alpha/gen/divrem.m4 m4 -DNAME=__divqu -DOP=div -DS=false -DWORDSIZE=64 \ ${.ALLSRC} > ${.TARGET} __divq.S: ${.CURDIR}/../libc/alpha/gen/divrem.m4 m4 -DNAME=__divq -DOP=div -DS=true -DWORDSIZE=64 \ ${.ALLSRC} > ${.TARGET} __divlu.S: ${.CURDIR}/../libc/alpha/gen/divrem.m4 m4 -DNAME=__divlu -DOP=div -DS=false -DWORDSIZE=32 \ ${.ALLSRC} > ${.TARGET} __divl.S: ${.CURDIR}/../libc/alpha/gen/divrem.m4 m4 -DNAME=__divl -DOP=div -DS=true -DWORDSIZE=32 \ ${.ALLSRC} > ${.TARGET} __remqu.S: ${.CURDIR}/../libc/alpha/gen/divrem.m4 m4 -DNAME=__remqu -DOP=rem -DS=false -DWORDSIZE=64 \ ${.ALLSRC} > ${.TARGET} __remq.S: ${.CURDIR}/../libc/alpha/gen/divrem.m4 m4 -DNAME=__remq -DOP=rem -DS=true -DWORDSIZE=64 \ ${.ALLSRC} > ${.TARGET} __remlu.S: ${.CURDIR}/../libc/alpha/gen/divrem.m4 m4 -DNAME=__remlu -DOP=rem -DS=false -DWORDSIZE=32 \ ${.ALLSRC} > ${.TARGET} __reml.S: ${.CURDIR}/../libc/alpha/gen/divrem.m4 m4 -DNAME=__reml -DOP=rem -DS=true -DWORDSIZE=32 \ ${.ALLSRC} > ${.TARGET} diff --git a/lib/libc/alpha/gen/fpgetmask.c b/lib/libc/alpha/gen/fpgetmask.c index c52a7ef07112..516ae981d55c 100644 --- a/lib/libc/alpha/gen/fpgetmask.c +++ b/lib/libc/alpha/gen/fpgetmask.c @@ -1,42 +1,49 @@ /* $NetBSD: fpgetmask.c,v 1.1 1995/04/29 05:10:55 cgd Exp $ */ /* * Copyright (c) 1995 Christopher G. Demetriou * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Christopher G. Demetriou * for the NetBSD Project. * 4. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include #include +#include + +struct params { + u_int64_t mask; +}; fp_except fpgetmask() { + struct params p; - /* XXX */ - abort(); + sysarch(ALPHA_GET_FPMASK, (char *) &p); + return((fp_except) p.mask); } diff --git a/lib/libc/alpha/gen/fpgetround.c b/lib/libc/alpha/gen/fpgetround.c index 39b9b4744a6b..46976c2e4c11 100644 --- a/lib/libc/alpha/gen/fpgetround.c +++ b/lib/libc/alpha/gen/fpgetround.c @@ -1,49 +1,48 @@ /* $NetBSD: fpgetround.c,v 1.1 1995/04/29 05:09:55 cgd Exp $ */ /* * Copyright (c) 1995 Christopher G. Demetriou * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Christopher G. Demetriou * for the NetBSD Project. * 4. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include +#include fp_rnd fpgetround() { double fpcrval; u_int64_t old; - __asm__("trapb"); - __asm__("mf_fpcr %0" : "=f" (fpcrval)); - __asm__("trapb"); + GET_FPCR(fpcrval); old = *(u_int64_t *)&fpcrval; - return ((old >> 58) & 0x3); + return ((old & FPCR_DYN_MASK) >> FPCR_DYN_SHIFT); } diff --git a/lib/libc/alpha/gen/fpgetsticky.c b/lib/libc/alpha/gen/fpgetsticky.c index c36db3913d5f..c0ff4d75c88a 100644 --- a/lib/libc/alpha/gen/fpgetsticky.c +++ b/lib/libc/alpha/gen/fpgetsticky.c @@ -1,42 +1,48 @@ /* $NetBSD: fpgetsticky.c,v 1.1 1995/04/29 05:10:59 cgd Exp $ */ /* * Copyright (c) 1995 Christopher G. Demetriou * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Christopher G. Demetriou * for the NetBSD Project. * 4. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include #include +#include fp_except fpgetsticky() { + double fpcrval; + u_int64_t old; - /* XXX */ - abort(); + GET_FPCR(fpcrval); + old = *(u_int64_t *)&fpcrval; + return (((old >> IEEE_STATUS_TO_FPCR_SHIFT) & IEEE_STATUS_MASK) + >> IEEE_STATUS_TO_EXCSUM_SHIFT); } diff --git a/lib/libc/alpha/gen/fpsetmask.c b/lib/libc/alpha/gen/fpsetmask.c index 87fc5a2f4b4c..05201ce81d40 100644 --- a/lib/libc/alpha/gen/fpsetmask.c +++ b/lib/libc/alpha/gen/fpsetmask.c @@ -1,43 +1,51 @@ /* $NetBSD: fpsetmask.c,v 1.1 1995/04/29 05:11:01 cgd Exp $ */ /* * Copyright (c) 1995 Christopher G. Demetriou * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Christopher G. Demetriou * for the NetBSD Project. * 4. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include #include +#include + +struct params { + u_int64_t mask; +}; fp_except fpsetmask(mask) fp_except mask; { + struct params p; - /* XXX */ - abort(); + p.mask = (u_int64_t) mask; + sysarch(ALPHA_SET_FPMASK, (char *) &p); + return ((fp_except) p.mask); } diff --git a/lib/libc/alpha/gen/fpsetround.c b/lib/libc/alpha/gen/fpsetround.c index c28093cad87c..0d8f40af6d65 100644 --- a/lib/libc/alpha/gen/fpsetround.c +++ b/lib/libc/alpha/gen/fpsetround.c @@ -1,58 +1,55 @@ /* $NetBSD: fpsetround.c,v 1.1 1995/04/29 05:09:57 cgd Exp $ */ /* * Copyright (c) 1995 Christopher G. Demetriou * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Christopher G. Demetriou * for the NetBSD Project. * 4. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include +#include fp_rnd fpsetround(rnd_dir) fp_rnd rnd_dir; { double fpcrval; u_int64_t old, new; - __asm__("trapb"); - __asm__("mf_fpcr %0" : "=f" (fpcrval)); - __asm__("trapb"); + GET_FPCR(fpcrval); old = *(u_int64_t *)&fpcrval; - new = old & ~(long)0x0c00000000000000; - new = (long)rnd_dir << 58; - *(u_int64_t *)&fpcrval = new; + new = old & (~FPCR_DYN_MASK); + new |= ((long) rnd_dir << FPCR_DYN_SHIFT) & FPCR_DYN_MASK; - __asm__("trapb"); - __asm__("mt_fpcr %0" : : "f" (fpcrval)); - __asm__("trapb"); + *(u_int64_t *)&fpcrval = new; + SET_FPCR(fpcrval); - return ((old >> 58) & 0x3); + return ((old & FPCR_DYN_MASK) >> FPCR_DYN_SHIFT); } diff --git a/lib/libc/alpha/gen/fpsetsticky.c b/lib/libc/alpha/gen/fpsetsticky.c index 90a993ee642a..ae0d742f79f0 100644 --- a/lib/libc/alpha/gen/fpsetsticky.c +++ b/lib/libc/alpha/gen/fpsetsticky.c @@ -1,43 +1,55 @@ /* $NetBSD: fpsetsticky.c,v 1.1 1995/04/29 05:11:04 cgd Exp $ */ /* * Copyright (c) 1995 Christopher G. Demetriou * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Christopher G. Demetriou * for the NetBSD Project. * 4. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include #include +#include fp_except fpsetsticky(sticky) fp_except sticky; { + double fpcrval; + u_int64_t old,new ; - /* XXX */ - abort(); + GET_FPCR(fpcrval); + old = *(u_int64_t *)&fpcrval; + new = old & ~ (IEEE_STATUS_MASK << IEEE_STATUS_TO_FPCR_SHIFT); + new |= ((sticky << IEEE_STATUS_TO_EXCSUM_SHIFT) & IEEE_STATUS_MASK) + << IEEE_STATUS_TO_FPCR_SHIFT; + *(u_int64_t *)&fpcrval = new; + SET_FPCR(fpcrval); + + return (((old >> IEEE_STATUS_TO_FPCR_SHIFT) & IEEE_STATUS_MASK) + >> IEEE_STATUS_TO_EXCSUM_SHIFT); } diff --git a/lib/libc/alpha/sys/cerror.S b/lib/libc/alpha/sys/cerror.S index cce30068de6c..a3d2b1a24097 100644 --- a/lib/libc/alpha/sys/cerror.S +++ b/lib/libc/alpha/sys/cerror.S @@ -1,54 +1,54 @@ -/* $Id$ */ +/* $Id: cerror.S,v 1.2 1998/06/09 22:56:24 jb Exp $ */ /* From: NetBSD: cerror.S,v 1.4 1996/11/08 00:52:46 cgd Exp */ /* * Copyright (c) 1994, 1995 Carnegie-Mellon University. * All rights reserved. * * Author: Chris G. Demetriou * * Permission to use, copy, modify and distribute this software and * its documentation is hereby granted, provided that both the copyright * notice and this permission notice appear in all copies of the * software, derivative works or modified versions, and any portions * thereof, and that both notices appear in supporting documentation. * * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. * * Carnegie Mellon requests users of this software to return to * * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU * School of Computer Science * Carnegie Mellon University * Pittsburgh PA 15213-3890 * * any improvements or extensions that they make and grant Carnegie the * rights to redistribute these changes. */ #include "SYS.h" #define FRAME_SIZE 16 #define FRAME_RA_OFFSET 0 #define FRAME_V0_OFFSET 8 -NESTED(cerror, 0, FRAME_SIZE, ra, IM_RA|IM_V0, 0) +NESTED(.cerror, 0, FRAME_SIZE, ra, IM_RA|IM_V0, 0) br t0, L1 L1: LDGP(t0) lda sp, -FRAME_SIZE(sp) stq ra, FRAME_RA_OFFSET(sp) stq v0, FRAME_V0_OFFSET(sp) CALL(__error) ldq t0, FRAME_V0_OFFSET(sp) stl t0, 0(v0) ldiq v0, -1 ldq ra, FRAME_RA_OFFSET(sp) lda sp, FRAME_SIZE(sp) RET -END(cerror) +END(.cerror) diff --git a/lib/msun/Makefile b/lib/msun/Makefile index a0ca7405fbd7..c62ee87d0cac 100644 --- a/lib/msun/Makefile +++ b/lib/msun/Makefile @@ -1,169 +1,170 @@ # @(#)Makefile 5.1beta 93/09/24 -# $Id: Makefile,v 1.19 1997/04/15 14:05:28 bde Exp $ +# $Id: Makefile,v 1.20 1998/02/20 07:44:29 jb Exp $ # # ==================================================== # Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. # # Developed at SunPro, a Sun Microsystems, Inc. business. # Permission to use, copy, modify, and distribute this # software is freely granted, provided that this notice # is preserved. # ==================================================== # # # # There are two options in making libm at fdlibm compile time: # _IEEE_LIBM --- IEEE libm; smaller, and somewhat faster # _MULTI_LIBM --- Support multi-standard at runtime by # imposing wrapper functions defined in # fdlibm.h: # _IEEE_MODE -- IEEE # _XOPEN_MODE -- X/OPEN # _POSIX_MODE -- POSIX/ANSI # _SVID3_MODE -- SVID # # Here is how to set up CFLAGS to create the desired libm at # compile time: # # CFLAGS = -D_IEEE_LIBM ... IEEE libm (recommended) # CFLAGS = -D_SVID3_MODE ... Multi-standard supported # libm with SVID as the # default standard # CFLAGS = -D_XOPEN_MODE ... Multi-standard supported # libm with XOPEN as the # default standard # CFLAGS = -D_POSIX_MODE ... Multi-standard supported # libm with POSIX as the # default standard # CFLAGS = ... Multi-standard supported # libm with IEEE as the # default standard # .if ${MACHINE_ARCH} == "alpha" .PATH: ${.CURDIR)/alpha ARCH= alpha ARCH_SRCS = s_copysign.S s_copysignf.S # XXX Comment from NetBSD/Alpha: # XXX LINT SIGFPEs in e_exp.c's strtod(). FP underflow/denorm software # handling is broken (doesn't exist!) on the Alpha port. +CFLAGS += -mtrap-precision=i -mfp-trap-mode=su .elif ${MACHINE_ARCH} == "i386" ARCH= i387 ARCH_PREFIX= ${ARCH}_ ARCH_SRCS = e_acos.S e_asin.S e_atan2.S e_exp.S e_fmod.S e_log.S e_log10.S \ e_remainder.S e_scalb.S e_sqrt.S s_atan.S s_ceil.S s_copysign.S \ s_cos.S s_finite.S s_floor.S s_ilogb.S s_logb.S \ s_rint.S s_scalbn.S s_significand.S s_sin.S s_tan.S .elif ${MACHINE_ARCH} == "m68k" .PATH: ${.CURDIR}/mc68881 ARCH_SRCS = e_acos.S e_asin.S e_atanh.S e_cosh.S e_exp.S e_fmod.S e_log.S \ e_log10.S e_remainder.S e_scalb.S e_sinh.S e_sqrt.S s_atan.S \ s_ceil.S s_copysign.S s_cos.S s_expm1.S s_finite.S s_floor.S \ s_log1p.S s_logb.S s_rint.S s_scalbn.S s_sin.S s_tan.S s_tanh.S .endif # Broken # ARCH_SRCS+= s_log1p.S .PATH: ${.CURDIR}/man .PATH: ${.CURDIR}/src CFLAGS+= -D_IEEE_LIBM -D_ARCH_INDIRECT=${ARCH_PREFIX} LIB= m COMMON_SRCS = e_acos.c e_acosf.c e_acosh.c e_acoshf.c e_asin.c e_asinf.c \ e_atan2.c e_atan2f.c e_atanh.c e_atanhf.c e_cosh.c e_coshf.c e_exp.c \ e_expf.c e_fmod.c e_fmodf.c e_gamma.c e_gamma_r.c e_gammaf.c \ e_gammaf_r.c e_hypot.c e_hypotf.c e_j0.c e_j0f.c e_j1.c e_j1f.c \ e_jn.c e_jnf.c e_lgamma.c e_lgamma_r.c e_lgammaf.c e_lgammaf_r.c \ e_log.c e_log10.c e_log10f.c e_logf.c e_pow.c e_powf.c e_rem_pio2.c \ e_rem_pio2f.c e_remainder.c e_remainderf.c e_scalb.c e_scalbf.c \ e_sinh.c e_sinhf.c e_sqrt.c e_sqrtf.c \ get_hw_float.c \ k_cos.c k_cosf.c k_rem_pio2.c k_rem_pio2f.c k_sin.c k_sinf.c \ k_standard.c k_tan.c k_tanf.c \ s_asinh.c s_asinhf.c s_atan.c s_atanf.c s_cbrt.c s_cbrtf.c s_ceil.c \ s_ceilf.c s_copysign.c s_copysignf.c s_cos.c s_cosf.c s_erf.c s_erff.c \ s_expm1.c s_expm1f.c s_fabsf.c s_finite.c s_finitef.c \ s_floor.c s_floorf.c s_frexpf.c s_ilogb.c s_ilogbf.c \ s_isnanf.c s_ldexpf.c s_lib_version.c s_log1p.c \ s_log1pf.c s_logb.c s_logbf.c s_matherr.c s_modff.c \ s_nextafter.c s_nextafterf.c s_rint.c s_rintf.c s_scalbn.c s_scalbnf.c \ s_signgam.c s_significand.c s_significandf.c s_sin.c s_sinf.c s_tan.c \ s_tanf.c s_tanh.c s_tanhf.c \ w_acos.c w_acosf.c w_acosh.c w_acoshf.c w_asin.c w_asinf.c w_atan2.c \ w_atan2f.c w_atanh.c w_atanhf.c w_cabs.c w_cabsf.c w_cosh.c w_coshf.c \ w_drem.c w_dremf.c w_exp.c w_expf.c w_fmod.c w_fmodf.c w_gamma.c \ w_gamma_r.c w_gammaf.c w_gammaf_r.c w_hypot.c w_hypotf.c w_j0.c \ w_j0f.c w_j1.c w_j1f.c w_jn.c w_jnf.c w_lgamma.c w_lgamma_r.c \ w_lgammaf.c w_lgammaf_r.c w_log.c w_log10.c w_log10f.c w_logf.c \ w_pow.c w_powf.c w_remainder.c w_remainderf.c w_scalb.c w_scalbf.c \ w_sinh.c w_sinhf.c w_sqrt.c w_sqrtf.c \ w_y0.c w_y0f.c w_y1.c w_y1f.c w_yn.c w_ynf.c # FreeBSD's C library supplies these functions: #COMMON_SRCS+= s_fabs.c s_frexp.c s_isnan.c s_ldexp.c s_modf.c CLEANFILES+= ${RENAMED_ARCH_SRCS} RENAMED_ARCH_SRCS= ${ARCH_SRCS:S/^/${ARCH_PREFIX}/g} SRCS= ${COMMON_SRCS} ${RENAMED_ARCH_SRCS} # Generate rules to rename arch-specific sources to avoid conflicts. # The path to the arch-specific sources is given explicitly instead of # with `.PATH: ${.CURDIR}/${ARCH}' since otherwise bsd.lib.mk would # use .S.o rules instead of .c.o rules for the conflicting prefixes # (except after `make depend' it uses the correct rules!). .for i in ${ARCH_SRCS} ${ARCH_PREFIX}${i}: ${.CURDIR}/${ARCH}/${i} cp ${.ALLSRC} ${.TARGET} .endfor MANSRC= ${.CURDIR}/man MAN3+= acos.3 acosh.3 asin.3 asinh.3 atan.3 atan2.3 atanh.3 ceil.3 \ cos.3 cosh.3 erf.3 exp.3 fabs.3 floor.3 fmod.3 hypot.3 ieee.3 \ ieee_test.3 j0.3 lgamma.3 math.3 rint.3 sin.3 sinh.3 sqrt.3 \ tan.3 tanh.3 MLINKS+=acos.3 acosf.3 MLINKS+=acosh.3 acoshf.3 MLINKS+=asin.3 asinf.3 MLINKS+=asinh.3 asinhf.3 MLINKS+=atan.3 atanf.3 MLINKS+=atanh.3 atanhf.3 MLINKS+=atan2.3 atan2f.3 MLINKS+=ceil.3 ceilf.3 MLINKS+=cos.3 cosf.3 MLINKS+=cosh.3 coshf.3 MLINKS+=erf.3 erfc.3 erf.3 erff.3 erf.3 erfcf.3 MLINKS+=exp.3 expm1.3 exp.3 log.3 exp.3 log10.3 exp.3 log1p.3 exp.3 pow.3 \ exp.3 expf.3 exp.3 exp2.3 exp.3 exp2f.3 exp.3 exp10.3 exp.3 exp10f.3 \ exp.3 expm1f.3 exp.3 logf.3 exp.3 log2.3 exp.3 log2f.3 exp.3 powf.3 \ exp.3 log10f.3 exp.3 log1pf.3 MLINKS+=fabs.3 fabsf.3 MLINKS+=floor.3 floorf.3 MLINKS+=fmod.3 fmodf.3 MLINKS+=hypot.3 cabs.3 hypot.3 cabsf.3 hypot.3 hypotf.3 MLINKS+=ieee.3 copysign.3 ieee.3 copysignf.3 ieee.3 finite.3 ieee.3 finitef.3 \ ieee.3 ilogb.3 ieee.3 ilogbf.3 ieee.3 nextafter.3 ieee.3 nextafterf.3 \ ieee.3 remainder.3 ieee.3 remainderf.3 ieee.3 scalbn.3 ieee.3 scalbnf.3 MLINKS+=ieee_test.3 logb.3 ieee_test.3 logbf.3 MLINKS+=ieee_test.3 scalb.3 ieee_test.3 scalbf.3 MLINKS+=ieee_test.3 significand.3 ieee_test.3 significandf.3 MLINKS+=j0.3 j1.3 j0.3 jn.3 j0.3 y0.3 j0.3 y1.3 j0.3 y1f.3 j0.3 yn.3 MLINKS+=j0.3 j0f.3 j0.3 j1f.3 j0.3 jnf.3 j0.3 y0f.3 j0.3 ynf.3 MLINKS+=lgamma.3 gamma.3 lgamma.3 lgammaf.3 lgamma.3 gammaf.3 MLINKS+=rint.3 rintf.3 MLINKS+=sin.3 sinf.3 MLINKS+=sinh.3 sinhf.3 MLINKS+=sqrt.3 cbrt.3 sqrt.3 cbrtf.3 sqrt.3 sqrtf.3 MLINKS+=tan.3 tanf.3 MLINKS+=tanh.3 tanhf.3 # XXX we should have only one math.h, and a rule for installing .h's... beforeinstall: ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 ${.CURDIR}/src/math.h \ ${DESTDIR}/usr/include .include diff --git a/sys/alpha/alpha/machdep.c b/sys/alpha/alpha/machdep.c index e8240f15b702..39090de0c42d 100644 --- a/sys/alpha/alpha/machdep.c +++ b/sys/alpha/alpha/machdep.c @@ -1,1886 +1,1927 @@ /*- * Copyright (c) 1998 Doug Rabson * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: machdep.c,v 1.26 1998/12/04 22:54:42 archie Exp $ + * $Id: machdep.c,v 1.27 1998/12/16 16:28:56 bde Exp $ */ /*- * Copyright (c) 1998 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, * NASA Ames Research Center and by Chris G. Demetriou. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the NetBSD * Foundation, Inc. and its contributors. * 4. Neither the name of The NetBSD Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University. * All rights reserved. * * Author: Chris G. Demetriou * * Permission to use, copy, modify and distribute this software and * its documentation is hereby granted, provided that both the copyright * notice and this permission notice appear in all copies of the * software, derivative works or modified versions, and any portions * thereof, and that both notices appear in supporting documentation. * * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. * * Carnegie Mellon requests users of this software to return to * * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU * School of Computer Science * Carnegie Mellon University * Pittsburgh PA 15213-3890 * * any improvements or extensions that they make and grant Carnegie the * rights to redistribute these changes. */ #include "opt_ddb.h" #include "opt_simos.h" #include "opt_sysvipc.h" #include "opt_msgbuf.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef SYSVSHM #include #endif #ifdef SYSVMSG #include #endif #ifdef SYSVSEM #include #endif struct proc* curproc; struct proc* fpcurproc; struct pcb* curpcb; u_int64_t cycles_per_usec; u_int32_t cycles_per_sec; int whichqs, whichrtqs, whichidqs; int cold = 1; struct platform platform; alpha_chipset_t chipset; struct bootinfo_kernel bootinfo; struct timeval switchtime; struct user *proc0paddr; char machine[] = "alpha"; SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, machine, 0, ""); static char cpu_model[128]; SYSCTL_STRING(_hw, HW_MODEL, model, CTLFLAG_RD, cpu_model, 0, ""); #ifdef DDB /* start and end of kernel symbol table */ void *ksym_start, *ksym_end; #endif /* for cpu_sysctl() */ int alpha_unaligned_print = 1; /* warn about unaligned accesses */ int alpha_unaligned_fix = 1; /* fix up unaligned accesses */ int alpha_unaligned_sigbus = 0; /* don't SIGBUS on fixed-up accesses */ static void cpu_startup __P((void *)); SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL) static MALLOC_DEFINE(M_MBUF, "mbuf", "mbuf"); struct msgbuf *msgbufp=0; int bootverbose = 0, Maxmem = 0; long dumplo; int totalphysmem; /* total amount of physical memory in system */ int physmem; /* physical memory used by NetBSD + some rsvd */ int resvmem; /* amount of memory reserved for PROM */ int unusedmem; /* amount of memory for OS that we don't use */ int unknownmem; /* amount of memory with an unknown use */ int ncpus; /* number of cpus */ vm_offset_t phys_avail[10]; SYSCTL_INT(_hw, OID_AUTO, availpages, CTLFLAG_RD, &physmem, 0, ""); /* must be 2 less so 0 0 can signal end of chunks */ #define PHYS_AVAIL_ARRAY_END ((sizeof(phys_avail) / sizeof(vm_offset_t)) - 2) static void setup_netisrs __P((struct linker_set *)); /* XXX declare elsewhere */ static void identifycpu __P((void)); static vm_offset_t buffer_sva, buffer_eva; vm_offset_t clean_sva, clean_eva; static vm_offset_t pager_sva, pager_eva; extern struct linker_set netisr_set; #define offsetof(type, member) ((size_t)(&((type *)0)->member)) /* * Hooked into the shutdown chain; if the system is to be halted, * unconditionally drop back to the SRM console. */ static void alpha_srm_shutdown(int howto, void *junk) { if (howto & RB_HALT) alpha_pal_halt(); } static void cpu_startup(dummy) void *dummy; { register unsigned i; register caddr_t v; vm_offset_t maxaddr; vm_size_t size = 0; vm_offset_t firstaddr; vm_offset_t minaddr; if (boothowto & RB_VERBOSE) bootverbose++; /* * Good {morning,afternoon,evening,night}. */ printf(version); identifycpu(); /* startrtclock(); */ #ifdef PERFMON perfmon_init(); #endif printf("real memory = %ld (%ldK bytes)\n", alpha_ptob(Maxmem), alpha_ptob(Maxmem) / 1024); /* * Display any holes after the first chunk of extended memory. */ if (bootverbose) { int indx; printf("Physical memory chunk(s):\n"); for (indx = 0; phys_avail[indx + 1] != 0; indx += 2) { int size1 = phys_avail[indx + 1] - phys_avail[indx]; printf("0x%08lx - 0x%08lx, %d bytes (%d pages)\n", phys_avail[indx], phys_avail[indx + 1] - 1, size1, size1 / PAGE_SIZE); } } /* * Quickly wire in netisrs. */ setup_netisrs(&netisr_set); /* * Calculate callout wheel size */ for (callwheelsize = 1, callwheelbits = 0; callwheelsize < ncallout; callwheelsize <<= 1, ++callwheelbits) ; callwheelmask = callwheelsize - 1; /* * Allocate space for system data structures. * The first available kernel virtual address is in "v". * As pages of kernel virtual memory are allocated, "v" is incremented. * As pages of memory are allocated and cleared, * "firstaddr" is incremented. * An index into the kernel page table corresponding to the * virtual memory address maintained in "v" is kept in "mapaddr". */ /* * Make two passes. The first pass calculates how much memory is * needed and allocates it. The second pass assigns virtual * addresses to the various data structures. */ firstaddr = 0; again: v = (caddr_t)firstaddr; #define valloc(name, type, num) \ (name) = (type *)v; v = (caddr_t)((name)+(num)) #define valloclim(name, type, num, lim) \ (name) = (type *)v; v = (caddr_t)((lim) = ((name)+(num))) valloc(callout, struct callout, ncallout); valloc(callwheel, struct callout_tailq, callwheelsize); #ifdef SYSVSHM valloc(shmsegs, struct shmid_ds, shminfo.shmmni); #endif #ifdef SYSVSEM valloc(sema, struct semid_ds, seminfo.semmni); valloc(sem, struct sem, seminfo.semmns); /* This is pretty disgusting! */ valloc(semu, int, (seminfo.semmnu * seminfo.semusz) / sizeof(int)); #endif #ifdef SYSVMSG valloc(msgpool, char, msginfo.msgmax); valloc(msgmaps, struct msgmap, msginfo.msgseg); valloc(msghdrs, struct msg, msginfo.msgtql); valloc(msqids, struct msqid_ds, msginfo.msgmni); #endif if (nbuf == 0) { nbuf = 30; if( physmem > 1024) nbuf += min((physmem - 1024) / 8, 2048); } nswbuf = max(min(nbuf/4, 64), 16); valloc(swbuf, struct buf, nswbuf); valloc(buf, struct buf, nbuf); /* * End of first pass, size has been calculated so allocate memory */ if (firstaddr == 0) { size = (vm_size_t)(v - firstaddr); firstaddr = (vm_offset_t)kmem_alloc(kernel_map, round_page(size)); if (firstaddr == 0) panic("startup: no room for tables"); goto again; } /* * End of second pass, addresses have been assigned */ if ((vm_size_t)(v - firstaddr) != size) panic("startup: table size inconsistency"); clean_map = kmem_suballoc(kernel_map, &clean_sva, &clean_eva, (nbuf*BKVASIZE) + (nswbuf*MAXPHYS) + pager_map_size); buffer_map = kmem_suballoc(clean_map, &buffer_sva, &buffer_eva, (nbuf*BKVASIZE)); pager_map = kmem_suballoc(clean_map, &pager_sva, &pager_eva, (nswbuf*MAXPHYS) + pager_map_size); pager_map->system_map = 1; exec_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr, (16*(ARG_MAX+(PAGE_SIZE*3)))); /* * Finally, allocate mbuf pool. Since mclrefcnt is an off-size * we use the more space efficient malloc in place of kmem_alloc. */ { vm_offset_t mb_map_size; mb_map_size = nmbufs * MSIZE + nmbclusters * MCLBYTES; mb_map_size = roundup2(mb_map_size, max(MCLBYTES, PAGE_SIZE)); mclrefcnt = malloc(mb_map_size / MCLBYTES, M_MBUF, M_NOWAIT); bzero(mclrefcnt, mb_map_size / MCLBYTES); mb_map = kmem_suballoc(kmem_map, (vm_offset_t *)&mbutl, &maxaddr, mb_map_size); mb_map->system_map = 1; } /* * Initialize callouts */ SLIST_INIT(&callfree); for (i = 0; i < ncallout; i++) { SLIST_INSERT_HEAD(&callfree, &callout[i], c_links.sle); } for (i = 0; i < callwheelsize; i++) { TAILQ_INIT(&callwheel[i]); } #if defined(USERCONFIG) #if defined(USERCONFIG_BOOT) if (1) #else if (boothowto & RB_CONFIG) #endif { userconfig(); cninit(); /* the preferred console may have changed */ } #endif printf("avail memory = %ld (%ldK bytes)\n", ptoa(cnt.v_free_count), ptoa(cnt.v_free_count) / 1024); /* * Set up buffers, so they can be used to read disk labels. */ bufinit(); vm_pager_bufferinit(); at_shutdown_pri(alpha_srm_shutdown, 0, SHUTDOWN_FINAL, SHUTDOWN_PRI_LAST); } int register_netisr(num, handler) int num; netisr_t *handler; { if (num < 0 || num >= (sizeof(netisrs)/sizeof(*netisrs)) ) { printf("register_netisr: bad isr number: %d\n", num); return (EINVAL); } netisrs[num] = handler; return (0); } static void setup_netisrs(ls) struct linker_set *ls; { int i; const struct netisrtab *nit; for(i = 0; ls->ls_items[i]; i++) { nit = (const struct netisrtab *)ls->ls_items[i]; register_netisr(nit->nit_num, nit->nit_isr); } } /* * Retrieve the platform name from the DSR. */ const char * alpha_dsr_sysname() { struct dsrdb *dsr; const char *sysname; /* * DSR does not exist on early HWRPB versions. */ if (hwrpb->rpb_version < HWRPB_DSRDB_MINVERS) return (NULL); dsr = (struct dsrdb *)(((caddr_t)hwrpb) + hwrpb->rpb_dsrdb_off); sysname = (const char *)((caddr_t)dsr + (dsr->dsr_sysname_off + sizeof(u_int64_t))); return (sysname); } /* * Lookup the system specified system variation in the provided table, * returning the model string on match. */ const char * alpha_variation_name(u_int64_t variation, const struct alpha_variation_table *avtp) { int i; for (i = 0; avtp[i].avt_model != NULL; i++) if (avtp[i].avt_variation == variation) return (avtp[i].avt_model); return (NULL); } /* * Generate a default platform name based for unknown system variations. */ const char * alpha_unknown_sysname() { static char s[128]; /* safe size */ snprintf(s, sizeof(s), "%s family, unknown model variation 0x%lx", platform.family, hwrpb->rpb_variation & SV_ST_MASK); return ((const char *)s); } static void identifycpu(void) { + u_int64_t type, major, minor; + u_int64_t amask; + struct pcs *pcsp; + char *cpuname[] = { + "unknown", /* 0 */ + "EV3", /* 1 */ + "EV4 (21064)", /* 2 */ + "Simulation", /* 3 */ + "LCA Family", /* 4 */ + "EV5 (21164)", /* 5 */ + "EV45 (21064A)", /* 6 */ + "EV56 (21164A)", /* 7 */ + "EV6 (21264)", /* 8 */ + "PCA56 (21164PC)" /* 9 */ + }; /* * print out CPU identification information. */ printf("%s\n%s, %ldMHz\n", platform.family, platform.model, hwrpb->rpb_cc_freq / 1000000); /* XXX true for 21164? */ printf("%ld byte page size, %d processor%s.\n", hwrpb->rpb_page_size, ncpus, ncpus == 1 ? "" : "s"); #if 0 /* this isn't defined for any systems that we run on? */ printf("serial number 0x%lx 0x%lx\n", ((long *)hwrpb->rpb_ssn)[0], ((long *)hwrpb->rpb_ssn)[1]); /* and these aren't particularly useful! */ printf("variation: 0x%lx, revision 0x%lx\n", hwrpb->rpb_variation, *(long *)hwrpb->rpb_revision); #endif + pcsp = LOCATE_PCS(hwrpb, hwrpb->rpb_primary_cpu_id); + /* cpu type */ + type = pcsp->pcs_proc_type; + major = (type & PCS_PROC_MAJOR) >> PCS_PROC_MAJORSHIFT; + minor = (type & PCS_PROC_MINOR) >> PCS_PROC_MINORSHIFT; + if (major < sizeof(cpuname)/sizeof(char *)) + printf("CPU: %s major=%lu minor=%lu", + cpuname[major], major, minor); + else + printf("CPU: major=%lu minor=%lu\n", major, minor); + /* amask */ + if (major >= PCS_PROC_EV56) { + amask = 0xffffffff; /* 32 bit for printf */ + amask = (~alpha_amask(amask)) & amask; + printf(" extensions=0x%b\n", (u_int32_t) amask, + "\020" + "\001BWX" + "\002FIX" + "\003CIX" + "\011MVI" + "\012PRECISE" + ); + } else + printf("\n"); + /* PAL code */ + printf("OSF PAL rev: 0x%lx\n", pcsp->pcs_palrevisions[PALvar_OSF1]); } extern char kernel_text[], _end[]; void alpha_init(pfn, ptb, bim, bip, biv) u_long pfn; /* first free PFN number */ u_long ptb; /* PFN of current level 1 page table */ u_long bim; /* bootinfo magic */ u_long bip; /* bootinfo pointer */ u_long biv; /* bootinfo version */ { int phys_avail_cnt; char *bootinfo_msg; vm_offset_t kernstart, kernend; vm_offset_t kernstartpfn, kernendpfn, pfn0, pfn1; struct mddt *mddtp; struct mddt_cluster *memc; int i, mddtweird; int cputype; char* p; /* NO OUTPUT ALLOWED UNTIL FURTHER NOTICE */ /* * Turn off interrupts (not mchecks) and floating point. * Make sure the instruction and data streams are consistent. */ (void)alpha_pal_swpipl(ALPHA_PSL_IPL_HIGH); /* alpha_pal_wrfen(0); */ ALPHA_TBIA(); alpha_pal_imb(); /* * Get critical system information (if possible, from the * information provided by the boot program). */ bootinfo_msg = NULL; if (bim == BOOTINFO_MAGIC) { if (biv == 0) { /* backward compat */ biv = *(u_long *)bip; bip += 8; } switch (biv) { case 1: { struct bootinfo_v1 *v1p = (struct bootinfo_v1 *)bip; bootinfo.ssym = v1p->ssym; bootinfo.esym = v1p->esym; bootinfo.kernend = v1p->kernend; bootinfo.modptr = v1p->modptr; /* hwrpb may not be provided by boot block in v1 */ if (v1p->hwrpb != NULL) { bootinfo.hwrpb_phys = ((struct rpb *)v1p->hwrpb)->rpb_phys; bootinfo.hwrpb_size = v1p->hwrpbsize; } else { bootinfo.hwrpb_phys = ((struct rpb *)HWRPB_ADDR)->rpb_phys; bootinfo.hwrpb_size = ((struct rpb *)HWRPB_ADDR)->rpb_size; } bcopy(v1p->boot_flags, bootinfo.boot_flags, min(sizeof v1p->boot_flags, sizeof bootinfo.boot_flags)); bcopy(v1p->booted_kernel, bootinfo.booted_kernel, min(sizeof v1p->booted_kernel, sizeof bootinfo.booted_kernel)); /* booted dev not provided in bootinfo */ init_prom_interface((struct rpb *) ALPHA_PHYS_TO_K0SEG(bootinfo.hwrpb_phys)); prom_getenv(PROM_E_BOOTED_DEV, bootinfo.booted_dev, sizeof bootinfo.booted_dev); break; } default: bootinfo_msg = "unknown bootinfo version"; goto nobootinfo; } } else { bootinfo_msg = "boot program did not pass bootinfo"; nobootinfo: bootinfo.ssym = (u_long)&_end; bootinfo.esym = (u_long)&_end; #ifdef SIMOS { char* p = (char*)bootinfo.ssym + 8; if (p[EI_MAG0] == ELFMAG0 && p[EI_MAG1] == ELFMAG1 && p[EI_MAG2] == ELFMAG2 && p[EI_MAG3] == ELFMAG3) { bootinfo.ssym = (u_long) p; bootinfo.esym = (u_long)p + *(u_long*)(p - 8); } } #endif bootinfo.hwrpb_phys = ((struct rpb *)HWRPB_ADDR)->rpb_phys; bootinfo.hwrpb_size = ((struct rpb *)HWRPB_ADDR)->rpb_size; init_prom_interface((struct rpb *)HWRPB_ADDR); prom_getenv(PROM_E_BOOTED_OSFLAGS, bootinfo.boot_flags, sizeof bootinfo.boot_flags); #ifndef SIMOS prom_getenv(PROM_E_BOOTED_FILE, bootinfo.booted_kernel, sizeof bootinfo.booted_kernel); #endif prom_getenv(PROM_E_BOOTED_DEV, bootinfo.booted_dev, sizeof bootinfo.booted_dev); } /* * Initialize the kernel's mapping of the RPB. It's needed for * lots of things. */ hwrpb = (struct rpb *)ALPHA_PHYS_TO_K0SEG(bootinfo.hwrpb_phys); /* * Remember how many cycles there are per microsecond, * so that we can use delay(). Round up, for safety. */ cycles_per_usec = (hwrpb->rpb_cc_freq + 999999) / 1000000; /* * Remember how many cycles per closk for coping with missed * clock interrupts. */ cycles_per_sec = hwrpb->rpb_cc_freq; /* * Initalize the (temporary) bootstrap console interface, so * we can use printf until the VM system starts being setup. * The real console is initialized before then. */ init_bootstrap_console(); /* OUTPUT NOW ALLOWED */ /* delayed from above */ if (bootinfo_msg) printf("WARNING: %s (0x%lx, 0x%lx, 0x%lx)\n", bootinfo_msg, bim, bip, biv); /* * Point interrupt/exception vectors to our own. */ alpha_pal_wrent(XentInt, ALPHA_KENTRY_INT); alpha_pal_wrent(XentArith, ALPHA_KENTRY_ARITH); alpha_pal_wrent(XentMM, ALPHA_KENTRY_MM); alpha_pal_wrent(XentIF, ALPHA_KENTRY_IF); alpha_pal_wrent(XentUna, ALPHA_KENTRY_UNA); alpha_pal_wrent(XentSys, ALPHA_KENTRY_SYS); /* * Clear pending machine checks and error reports, and enable * system- and processor-correctable error reporting. */ alpha_pal_wrmces(alpha_pal_rdmces() & ~(ALPHA_MCES_DSC|ALPHA_MCES_DPC)); /* * Find out what hardware we're on, and do basic initialization. */ cputype = hwrpb->rpb_type; if (cputype >= ncpuinit) { platform_not_supported(cputype); /* NOTREACHED */ } cpuinit[cputype].init(cputype); snprintf(cpu_model, sizeof(cpu_model), "%s", platform.model); /* * Initalize the real console, so the the bootstrap console is * no longer necessary. */ if (platform.cons_init) platform.cons_init(); /* NO MORE FIRMWARE ACCESS ALLOWED */ #ifdef _PMAP_MAY_USE_PROM_CONSOLE /* * XXX (unless _PMAP_MAY_USE_PROM_CONSOLE is defined and * XXX pmap_uses_prom_console() evaluates to non-zero.) */ #endif /* * find out this system's page size */ if (hwrpb->rpb_page_size != PAGE_SIZE) panic("page size %ld != 8192?!", hwrpb->rpb_page_size); /* * Find the beginning and end of the kernel (and leave a * bit of space before the beginning for the bootstrap * stack). */ kernstart = trunc_page(kernel_text) - 2 * PAGE_SIZE; #ifdef DDB ksym_start = (void *)bootinfo.ssym; ksym_end = (void *)bootinfo.esym; kernend = (vm_offset_t)round_page(ksym_end); #else kernend = (vm_offset_t)round_page(_end); #endif /* But if the bootstrap tells us otherwise, believe it! */ if (bootinfo.kernend) kernend = round_page(bootinfo.kernend); preload_metadata = (caddr_t)bootinfo.modptr; kern_envp = bootinfo.envp; kernstartpfn = atop(ALPHA_K0SEG_TO_PHYS(kernstart)); kernendpfn = atop(ALPHA_K0SEG_TO_PHYS(kernend)); #ifdef SIMOS /* * SimOS console puts the bootstrap stack after kernel */ kernendpfn += 4; #endif /* * Find out how much memory is available, by looking at * the memory cluster descriptors. This also tries to do * its best to detect things things that have never been seen * before... */ mddtp = (struct mddt *)(((caddr_t)hwrpb) + hwrpb->rpb_memdat_off); /* MDDT SANITY CHECKING */ mddtweird = 0; if (mddtp->mddt_cluster_cnt < 2) { mddtweird = 1; printf("WARNING: weird number of mem clusters: %ld\n", mddtp->mddt_cluster_cnt); } #ifdef DEBUG_CLUSTER printf("Memory cluster count: %d\n", mddtp->mddt_cluster_cnt); #endif phys_avail_cnt = 0; for (i = 0; i < mddtp->mddt_cluster_cnt; i++) { memc = &mddtp->mddt_clusters[i]; #ifdef DEBUG_CLUSTER printf("MEMC %d: pfn 0x%lx cnt 0x%lx usage 0x%lx\n", i, memc->mddt_pfn, memc->mddt_pg_cnt, memc->mddt_usage); #endif totalphysmem += memc->mddt_pg_cnt; if (memc->mddt_usage & MDDT_mbz) { mddtweird = 1; printf("WARNING: mem cluster %d has weird " "usage 0x%lx\n", i, memc->mddt_usage); unknownmem += memc->mddt_pg_cnt; continue; } if (memc->mddt_usage & MDDT_NONVOLATILE) { /* XXX should handle these... */ printf("WARNING: skipping non-volatile mem " "cluster %d\n", i); unusedmem += memc->mddt_pg_cnt; continue; } if (memc->mddt_usage & MDDT_PALCODE) { resvmem += memc->mddt_pg_cnt; continue; } /* * We have a memory cluster available for system * software use. We must determine if this cluster * holds the kernel. */ /* * XXX If the kernel uses the PROM console, we only use the * XXX memory after the kernel in the first system segment, * XXX to avoid clobbering prom mapping, data, etc. */ if (!pmap_uses_prom_console() || physmem == 0) { physmem += memc->mddt_pg_cnt; pfn0 = memc->mddt_pfn; pfn1 = memc->mddt_pfn + memc->mddt_pg_cnt; if (pfn0 <= kernendpfn && kernstartpfn <= pfn1) { /* * Must compute the location of the kernel * within the segment. */ #ifdef DEBUG_CLUSTER printf("Cluster %d contains kernel\n", i); #endif if (!pmap_uses_prom_console()) { if (pfn0 < kernstartpfn) { /* * There is a chunk before the kernel. */ #ifdef DEBUG_CLUSTER printf("Loading chunk before kernel: " "0x%lx / 0x%lx\n", pfn0, kernstartpfn); #endif phys_avail[phys_avail_cnt] = alpha_ptob(pfn0); phys_avail[phys_avail_cnt+1] = alpha_ptob(kernstartpfn); phys_avail_cnt += 2; } } if (kernendpfn < pfn1) { /* * There is a chunk after the kernel. */ #ifdef DEBUG_CLUSTER printf("Loading chunk after kernel: " "0x%lx / 0x%lx\n", kernendpfn, pfn1); #endif phys_avail[phys_avail_cnt] = alpha_ptob(kernendpfn); phys_avail[phys_avail_cnt+1] = alpha_ptob(pfn1); phys_avail_cnt += 2; } } else { /* * Just load this cluster as one chunk. */ #ifdef DEBUG_CLUSTER printf("Loading cluster %d: 0x%lx / 0x%lx\n", i, pfn0, pfn1); #endif phys_avail[phys_avail_cnt] = alpha_ptob(pfn0); phys_avail[phys_avail_cnt+1] = alpha_ptob(pfn1); phys_avail_cnt += 2; } } } phys_avail[phys_avail_cnt] = 0; /* * Dump out the MDDT if it looks odd... */ if (mddtweird) { printf("\n"); printf("complete memory cluster information:\n"); for (i = 0; i < mddtp->mddt_cluster_cnt; i++) { printf("mddt %d:\n", i); printf("\tpfn %lx\n", mddtp->mddt_clusters[i].mddt_pfn); printf("\tcnt %lx\n", mddtp->mddt_clusters[i].mddt_pg_cnt); printf("\ttest %lx\n", mddtp->mddt_clusters[i].mddt_pg_test); printf("\tbva %lx\n", mddtp->mddt_clusters[i].mddt_v_bitaddr); printf("\tbpa %lx\n", mddtp->mddt_clusters[i].mddt_p_bitaddr); printf("\tbcksum %lx\n", mddtp->mddt_clusters[i].mddt_bit_cksum); printf("\tusage %lx\n", mddtp->mddt_clusters[i].mddt_usage); } printf("\n"); } Maxmem = physmem; /* * Initialize error message buffer (at end of core). */ { size_t sz = round_page(MSGBUF_SIZE); int i = phys_avail_cnt - 2; char* cp; /* shrink so that it'll fit in the last segment */ if (phys_avail[i+1] - phys_avail[i] < sz) sz = phys_avail[i+1] - phys_avail[i]; phys_avail[i+1] -= sz; msgbufp = (struct msgbuf*) ALPHA_PHYS_TO_K0SEG(phys_avail[i+1]); msgbufinit(msgbufp, MSGBUF_SIZE); /* Remove the last segment if it now has no pages. */ if (phys_avail[i] == phys_avail[i+1]) phys_avail[i] = 0; /* warn if the message buffer had to be shrunk */ if (sz != round_page(MSGBUFSIZE)) printf("WARNING: %ld bytes not available for msgbuf in last cluster (%ld used)\n", round_page(MSGBUFSIZE), sz); } /* * Init mapping for u page(s) for proc 0 */ proc0.p_addr = proc0paddr = (struct user *)pmap_steal_memory(UPAGES * PAGE_SIZE); /* * Initialize the virtual memory system, and set the * page table base register in proc 0's PCB. */ pmap_bootstrap(ALPHA_PHYS_TO_K0SEG(alpha_ptob(ptb)), hwrpb->rpb_max_asn); /* * Initialize the rest of proc 0's PCB, and cache its physical * address. */ proc0.p_md.md_pcbpaddr = (struct pcb *)ALPHA_K0SEG_TO_PHYS((vm_offset_t)&proc0paddr->u_pcb); /* * Set the kernel sp, reserving space for an (empty) trapframe, * and make proc0's trapframe pointer point to it for sanity. */ proc0paddr->u_pcb.pcb_hw.apcb_ksp = (u_int64_t)proc0paddr + USPACE - sizeof(struct trapframe); proc0.p_md.md_tf = (struct trapframe *)proc0paddr->u_pcb.pcb_hw.apcb_ksp; /* * Look at arguments passed to us and compute boothowto. */ boothowto = RB_SINGLE; #ifdef KADB boothowto |= RB_KDB; #endif /* boothowto |= RB_KDB | RB_GDB; */ for (p = bootinfo.boot_flags; p && *p != '\0'; p++) { /* * Note that we'd really like to differentiate case here, * but the Alpha AXP Architecture Reference Manual * says that we shouldn't. */ switch (*p) { case 'a': /* autoboot */ case 'A': boothowto &= ~RB_SINGLE; break; #ifdef DEBUG case 'c': /* crash dump immediately after autoconfig */ case 'C': boothowto |= RB_DUMP; break; #endif #if defined(DDB) case 'd': /* break into the kernel debugger ASAP */ case 'D': boothowto |= RB_KDB; break; case 'g': /* use kernel gdb */ case 'G': boothowto |= RB_GDB; break; #endif case 'h': /* always halt, never reboot */ case 'H': boothowto |= RB_HALT; break; #if 0 case 'm': /* mini root present in memory */ case 'M': boothowto |= RB_MINIROOT; break; #endif case 'n': /* askname */ case 'N': boothowto |= RB_ASKNAME; break; case 's': /* single-user (default, supported for sanity) */ case 'S': boothowto |= RB_SINGLE; break; case 'v': case 'V': bootverbose = 1; break; default: printf("Unrecognized boot flag '%c'.\n", *p); break; } } /* * Initialize debuggers, and break into them if appropriate. */ #ifdef DDB kdb_init(); if (boothowto & RB_KDB) Debugger("Boot flags requested debugger"); #endif /* * Figure out the number of cpus in the box, from RPB fields. * Really. We mean it. */ for (i = 0; i < hwrpb->rpb_pcs_cnt; i++) { struct pcs *pcsp; pcsp = (struct pcs *)((char *)hwrpb + hwrpb->rpb_pcs_off + (i * hwrpb->rpb_pcs_size)); if ((pcsp->pcs_flags & PCS_PP) != 0) ncpus++; } /* * Figure out our clock frequency, from RPB fields. */ hz = hwrpb->rpb_intr_freq >> 12; if (!(60 <= hz && hz <= 10240)) { hz = 1024; #ifdef DIAGNOSTIC printf("WARNING: unbelievable rpb_intr_freq: %ld (%d hz)\n", hwrpb->rpb_intr_freq, hz); #endif } alpha_pal_wrfen(0); } void bzero(void *buf, size_t len) { caddr_t p = buf; while (((vm_offset_t) p & (sizeof(u_long) - 1)) && len) { *p++ = 0; len--; } while (len >= sizeof(u_long) * 8) { *(u_long*) p = 0; *((u_long*) p + 1) = 0; *((u_long*) p + 2) = 0; *((u_long*) p + 3) = 0; len -= sizeof(u_long) * 8; *((u_long*) p + 4) = 0; *((u_long*) p + 5) = 0; *((u_long*) p + 6) = 0; *((u_long*) p + 7) = 0; p += sizeof(u_long) * 8; } while (len >= sizeof(u_long)) { *(u_long*) p = 0; len -= sizeof(u_long); p += sizeof(u_long); } while (len) { *p++ = 0; len--; } } /* * Wait "n" microseconds. */ void DELAY(int n) { #ifndef SIMOS long N = cycles_per_usec * (n); while (N > 0) /* XXX */ N -= 3; /* XXX */ #endif } /* * The following primitives manipulate the run queues. _whichqs tells which * of the 32 queues _qs have processes in them. Setrunqueue puts processes * into queues, Remrunqueue removes them from queues. The running process is * on no queue, other processes are on a queue related to p->p_priority, * divided by 4 actually to shrink the 0-127 range of priorities into the 32 * available queues. */ #define P_FORW(p) ((struct proc*) (p)->p_procq.tqe_next) #define P_BACK(p) ((struct proc*) (p)->p_procq.tqe_prev) #define INSRQ(qs, whichqs, pri, p) \ do { \ whichqs |= (1 << pri); \ P_FORW(p) = (struct proc *)&qs[pri]; \ P_BACK(p) = qs[pri].ph_rlink; \ P_FORW(P_BACK(p)) = p; \ qs[pri].ph_rlink = p; \ } while(0) #define REMRQ(qs, whichqs, pri, p) \ do { \ if (!(whichqs & (1 << pri))) \ panic(#whichqs); \ P_FORW(P_BACK(p)) = P_FORW(p); \ P_BACK(P_FORW(p)) = P_BACK(p); \ P_BACK(p) = NULL; \ if ((struct proc *)&qs[pri] == qs[pri].ph_link) \ whichqs &= ~(1 << pri); \ } while(0) /* * setrunqueue(p) * proc *p; * * Call should be made at splclock(), and p->p_stat should be SRUN. */ void setrunqueue(p) struct proc *p; { int pri; #if 0 /* firewall: p->p_back must be NULL */ if (p->p_procq.tqe_prev != NULL) panic("setrunqueue"); #endif if (p->p_rtprio.type == RTP_PRIO_NORMAL) { /* normal priority */ pri = p->p_priority >> 2; INSRQ(qs, whichqs, pri, p); } else { /* realtime or idle */ pri = p->p_rtprio.prio; if (p->p_rtprio.type == RTP_PRIO_REALTIME #ifdef P1003_1B || p->p_rtprio.type == RTP_PRIO_FIFO #endif ) { /* realtime priority */ INSRQ(rtqs, whichrtqs, pri, p); } else { /* idle priority */ INSRQ(idqs, whichidqs, pri, p); } } } /* * remrq(p) * * Call should be made at splclock(). */ void remrq(p) struct proc *p; { int pri; if (p->p_rtprio.type == RTP_PRIO_NORMAL) { /* normal priority */ pri = p->p_priority >> 2; REMRQ(qs, whichqs, pri, p); } else { /* realtime or idle */ pri = p->p_rtprio.prio; if (p->p_rtprio.type == RTP_PRIO_REALTIME #ifdef P1003_1B || p->p_rtprio.type == RTP_PRIO_FIFO #endif ) { /* realtime priority */ REMRQ(rtqs, whichrtqs, pri, p); } else { /* idle priority */ REMRQ(rtqs, whichrtqs, pri, p); } } } /* * Send an interrupt to process. * * Stack is set up to allow sigcode stored * at top to call routine, followed by kcall * to sigreturn routine below. After sigreturn * resets the signal mask, the stack, and the * frame pointer, it returns to the user * specified pc, psl. */ void sendsig(sig_t catcher, int sig, int mask, u_long code) { struct proc *p = curproc; struct sigcontext *scp, ksc; struct trapframe *frame; struct sigacts *psp = p->p_sigacts; int oonstack, fsize, rndfsize; frame = p->p_md.md_tf; oonstack = psp->ps_sigstk.ss_flags & SS_ONSTACK; fsize = sizeof ksc; rndfsize = ((fsize + 15) / 16) * 16; /* * Allocate and validate space for the signal handler * context. Note that if the stack is in P0 space, the * call to grow() is a nop, and the useracc() check * will fail if the process has not already allocated * the space with a `brk'. */ if ((psp->ps_flags & SAS_ALTSTACK) && !oonstack && (psp->ps_sigonstack & sigmask(sig))) { scp = (struct sigcontext *)((caddr_t)psp->ps_sigstk.ss_sp + psp->ps_sigstk.ss_size - rndfsize); psp->ps_sigstk.ss_flags |= SS_ONSTACK; } else scp = (struct sigcontext *)(alpha_pal_rdusp() - rndfsize); if ((u_long)scp <= USRSTACK - ctob(p->p_vmspace->vm_ssize)) #if defined(UVM) (void)uvm_grow(p, (u_long)scp); #else (void)grow(p, (u_long)scp); #endif #ifdef DEBUG if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) printf("sendsig(%d): sig %d ssp %p usp %p\n", p->p_pid, sig, &oonstack, scp); #endif #if defined(UVM) if (uvm_useracc((caddr_t)scp, fsize, B_WRITE) == 0) { #else if (useracc((caddr_t)scp, fsize, B_WRITE) == 0) { #endif #ifdef DEBUG if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) printf("sendsig(%d): useracc failed on sig %d\n", p->p_pid, sig); #endif /* * Process has trashed its stack; give it an illegal * instruction to halt it in its tracks. */ SIGACTION(p, SIGILL) = SIG_DFL; sig = sigmask(SIGILL); p->p_sigignore &= ~sig; p->p_sigcatch &= ~sig; p->p_sigmask &= ~sig; psignal(p, SIGILL); return; #if !defined(UVM) /* this construct will balance braces for ctags(1) */ } #else } #endif /* * Build the signal context to be used by sigreturn. */ ksc.sc_onstack = oonstack; ksc.sc_mask = mask; ksc.sc_pc = frame->tf_regs[FRAME_PC]; ksc.sc_ps = frame->tf_regs[FRAME_PS]; /* copy the registers. */ fill_regs(p, (struct reg *)ksc.sc_regs); ksc.sc_regs[R_ZERO] = 0xACEDBADE; /* magic number */ ksc.sc_regs[R_SP] = alpha_pal_rdusp(); /* save the floating-point state, if necessary, then copy it. */ if (p == fpcurproc) { alpha_pal_wrfen(1); savefpstate(&p->p_addr->u_pcb.pcb_fp); alpha_pal_wrfen(0); fpcurproc = NULL; } ksc.sc_ownedfp = p->p_md.md_flags & MDP_FPUSED; bcopy(&p->p_addr->u_pcb.pcb_fp, (struct fpreg *)ksc.sc_fpregs, sizeof(struct fpreg)); ksc.sc_fp_control = p->p_addr->u_pcb.pcb_fp_control; bzero(ksc.sc_reserved, sizeof ksc.sc_reserved); /* XXX */ ksc.sc_xxx1[0] = 0; /* XXX */ ksc.sc_xxx1[1] = 0; /* XXX */ ksc.sc_traparg_a0 = frame->tf_regs[FRAME_TRAPARG_A0]; ksc.sc_traparg_a1 = frame->tf_regs[FRAME_TRAPARG_A1]; ksc.sc_traparg_a2 = frame->tf_regs[FRAME_TRAPARG_A2]; ksc.sc_xxx2[0] = 0; /* XXX */ ksc.sc_xxx2[1] = 0; /* XXX */ ksc.sc_xxx2[2] = 0; /* XXX */ #ifdef COMPAT_OSF1 /* * XXX Create an OSF/1-style sigcontext and associated goo. */ #endif /* * copy the frame out to userland. */ (void) copyout((caddr_t)&ksc, (caddr_t)scp, fsize); #ifdef DEBUG if (sigdebug & SDB_FOLLOW) printf("sendsig(%d): sig %d scp %p code %lx\n", p->p_pid, sig, scp, code); #endif /* * Set up the registers to return to sigcode. */ frame->tf_regs[FRAME_PC] = PS_STRINGS - (esigcode - sigcode); frame->tf_regs[FRAME_A0] = sig; frame->tf_regs[FRAME_A1] = code; frame->tf_regs[FRAME_A2] = (u_int64_t)scp; frame->tf_regs[FRAME_T12] = (u_int64_t)catcher; /* t12 is pv */ alpha_pal_wrusp((unsigned long)scp); #ifdef DEBUG if (sigdebug & SDB_FOLLOW) printf("sendsig(%d): pc %lx, catcher %lx\n", p->p_pid, frame->tf_regs[FRAME_PC], frame->tf_regs[FRAME_A3]); if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) printf("sendsig(%d): sig %d returns\n", p->p_pid, sig); #endif } /* * System call to cleanup state after a signal * has been taken. Reset signal mask and * stack state from context left by sendsig (above). * Return to previous pc and psl as specified by * context left by sendsig. Check carefully to * make sure that the user has not modified the * state to gain improper privileges. */ int sigreturn(struct proc *p, struct sigreturn_args /* { struct sigcontext *sigcntxp; } */ *uap) { struct sigcontext *scp, ksc; scp = uap->sigcntxp; #ifdef DEBUG if (sigdebug & SDB_FOLLOW) printf("sigreturn: pid %d, scp %p\n", p->p_pid, scp); #endif if (ALIGN(scp) != (u_int64_t)scp) return (EINVAL); /* * Test and fetch the context structure. * We grab it all at once for speed. */ #if defined(UVM) if (uvm_useracc((caddr_t)scp, sizeof (*scp), B_WRITE) == 0 || copyin((caddr_t)scp, (caddr_t)&ksc, sizeof ksc)) return (EINVAL); #else if (useracc((caddr_t)scp, sizeof (*scp), B_WRITE) == 0 || copyin((caddr_t)scp, (caddr_t)&ksc, sizeof ksc)) return (EINVAL); #endif if (ksc.sc_regs[R_ZERO] != 0xACEDBADE) /* magic number */ return (EINVAL); /* * Restore the user-supplied information */ if (ksc.sc_onstack) p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK; else p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK; p->p_sigmask = ksc.sc_mask &~ sigcantmask; set_regs(p, (struct reg *)ksc.sc_regs); p->p_md.md_tf->tf_regs[FRAME_PC] = ksc.sc_pc; p->p_md.md_tf->tf_regs[FRAME_PS] = (ksc.sc_ps | ALPHA_PSL_USERSET) & ~ALPHA_PSL_USERCLR; alpha_pal_wrusp(ksc.sc_regs[R_SP]); /* XXX ksc.sc_ownedfp ? */ if (p == fpcurproc) fpcurproc = NULL; bcopy((struct fpreg *)ksc.sc_fpregs, &p->p_addr->u_pcb.pcb_fp, sizeof(struct fpreg)); p->p_addr->u_pcb.pcb_fp_control = ksc.sc_fp_control; #ifdef DEBUG if (sigdebug & SDB_FOLLOW) printf("sigreturn(%d): returns\n", p->p_pid); #endif return (EJUSTRETURN); } /* * Machine dependent boot() routine * * I haven't seen anything to put here yet * Possibly some stuff might be grafted back here from boot() */ void cpu_boot(int howto) { } /* * Shutdown the CPU as much as possible */ void cpu_halt(void) { /*alpha_pal_halt(); */ prom_halt(1); } /* * Clear registers on exec */ void setregs(struct proc *p, u_long entry, u_long stack) { struct trapframe *tfp = p->p_md.md_tf; bzero(tfp->tf_regs, FRAME_SIZE * sizeof tfp->tf_regs[0]); bzero(&p->p_addr->u_pcb.pcb_fp, sizeof p->p_addr->u_pcb.pcb_fp); p->p_addr->u_pcb.pcb_fp_control = (IEEE_TRAP_ENABLE_INV | IEEE_TRAP_ENABLE_DZE | IEEE_TRAP_ENABLE_OVF); p->p_addr->u_pcb.pcb_fp.fpr_cr = (FPCR_DYN_NORMAL | FPCR_INED | FPCR_UNFD); alpha_pal_wrusp(stack); tfp->tf_regs[FRAME_PS] = ALPHA_PSL_USERSET; tfp->tf_regs[FRAME_PC] = entry & ~3; tfp->tf_regs[FRAME_A0] = stack; /* a0 = sp */ tfp->tf_regs[FRAME_A1] = 0; /* a1 = rtld cleanup */ tfp->tf_regs[FRAME_A2] = 0; /* a2 = rtld object */ tfp->tf_regs[FRAME_A3] = PS_STRINGS; /* a3 = ps_strings */ tfp->tf_regs[FRAME_T12] = tfp->tf_regs[FRAME_PC]; /* a.k.a. PV */ p->p_md.md_flags &= ~MDP_FPUSED; if (fpcurproc == p) fpcurproc = NULL; } int ptrace_set_pc(struct proc *p, unsigned long addr) { struct trapframe *tp = p->p_md.md_tf; tp->tf_regs[FRAME_PC] = addr; return 0; } static int ptrace_read_int(struct proc *p, vm_offset_t addr, u_int32_t *v) { struct iovec iov; struct uio uio; iov.iov_base = (caddr_t) v; iov.iov_len = sizeof(u_int32_t); uio.uio_iov = &iov; uio.uio_iovcnt = 1; uio.uio_offset = (off_t)addr; uio.uio_resid = sizeof(u_int32_t); uio.uio_segflg = UIO_SYSSPACE; uio.uio_rw = UIO_READ; uio.uio_procp = p; return procfs_domem(curproc, p, NULL, &uio); } static int ptrace_write_int(struct proc *p, vm_offset_t addr, u_int32_t v) { struct iovec iov; struct uio uio; iov.iov_base = (caddr_t) &v; iov.iov_len = sizeof(u_int32_t); uio.uio_iov = &iov; uio.uio_iovcnt = 1; uio.uio_offset = (off_t)addr; uio.uio_resid = sizeof(u_int32_t); uio.uio_segflg = UIO_SYSSPACE; uio.uio_rw = UIO_WRITE; uio.uio_procp = p; return procfs_domem(curproc, p, NULL, &uio); } static u_int64_t ptrace_read_register(struct proc *p, int regno) { static int reg_to_frame[32] = { FRAME_V0, FRAME_T0, FRAME_T1, FRAME_T2, FRAME_T3, FRAME_T4, FRAME_T5, FRAME_T6, FRAME_T7, FRAME_S0, FRAME_S1, FRAME_S2, FRAME_S3, FRAME_S4, FRAME_S5, FRAME_S6, FRAME_A0, FRAME_A1, FRAME_A2, FRAME_A3, FRAME_A4, FRAME_A5, FRAME_T8, FRAME_T9, FRAME_T10, FRAME_T11, FRAME_RA, FRAME_T12, FRAME_AT, FRAME_GP, FRAME_SP, -1, /* zero */ }; if (regno == R_ZERO) return 0; return p->p_md.md_tf->tf_regs[reg_to_frame[regno]]; } static int ptrace_clear_bpt(struct proc *p, struct mdbpt *bpt) { return ptrace_write_int(p, bpt->addr, bpt->contents); } static int ptrace_set_bpt(struct proc *p, struct mdbpt *bpt) { int error; u_int32_t bpins = 0x00000080; error = ptrace_read_int(p, bpt->addr, &bpt->contents); if (error) return error; return ptrace_write_int(p, bpt->addr, bpins); } int ptrace_clear_single_step(struct proc *p) { if (p->p_md.md_flags & MDP_STEP2) { ptrace_clear_bpt(p, &p->p_md.md_sstep[1]); ptrace_clear_bpt(p, &p->p_md.md_sstep[0]); p->p_md.md_flags &= ~MDP_STEP2; } else if (p->p_md.md_flags & MDP_STEP1) { ptrace_clear_bpt(p, &p->p_md.md_sstep[0]); p->p_md.md_flags &= ~MDP_STEP1; } return 0; } int ptrace_single_step(struct proc *p) { int error; vm_offset_t pc = p->p_md.md_tf->tf_regs[FRAME_PC]; alpha_instruction ins; vm_offset_t addr[2]; /* places to set breakpoints */ int count = 0; /* count of breakpoints */ if (p->p_md.md_flags & (MDP_STEP1|MDP_STEP2)) panic("ptrace_single_step: step breakpoints not removed"); error = ptrace_read_int(p, pc, &ins.bits); if (error) return error; switch (ins.branch_format.opcode) { case op_j: /* Jump: target is register value */ addr[0] = ptrace_read_register(p, ins.jump_format.rs) & ~3; count = 1; break; case op_br: case op_fbeq: case op_fblt: case op_fble: case op_bsr: case op_fbne: case op_fbge: case op_fbgt: case op_blbc: case op_beq: case op_blt: case op_ble: case op_blbs: case op_bne: case op_bge: case op_bgt: /* Branch: target is pc+4+4*displacement */ addr[0] = pc + 4; addr[1] = pc + 4 + 4 * ins.branch_format.displacement; count = 2; break; default: addr[0] = pc + 4; count = 1; } p->p_md.md_sstep[0].addr = addr[0]; if (error = ptrace_set_bpt(p, &p->p_md.md_sstep[0])) return error; if (count == 2) { p->p_md.md_sstep[1].addr = addr[1]; if (error = ptrace_set_bpt(p, &p->p_md.md_sstep[1])) { ptrace_clear_bpt(p, &p->p_md.md_sstep[0]); return error; } p->p_md.md_flags |= MDP_STEP2; } else p->p_md.md_flags |= MDP_STEP1; return 0; } int ptrace_read_u_check(p, addr, len) struct proc *p; vm_offset_t addr; size_t len; { vm_offset_t gap; if ((vm_offset_t) (addr + len) < addr) return EPERM; if ((vm_offset_t) (addr + len) <= sizeof(struct user)) return 0; gap = (char *) p->p_md.md_tf - (char *) p->p_addr; if ((vm_offset_t) addr < gap) return EPERM; if ((vm_offset_t) (addr + len) <= (vm_offset_t) (gap + sizeof(struct trapframe))) return 0; return EPERM; } int ptrace_write_u(struct proc *p, vm_offset_t off, long data) { struct trapframe frame_copy; vm_offset_t min; struct trapframe *tp; /* * Privileged kernel state is scattered all over the user area. * Only allow write access to parts of regs and to fpregs. */ min = (char *)p->p_md.md_tf - (char *)p->p_addr; if (off >= min && off <= min + sizeof(struct trapframe) - sizeof(int)) { tp = p->p_md.md_tf; #if 0 frame_copy = *tp; *(int *)((char *)&frame_copy + (off - min)) = data; if (!EFLAGS_SECURE(frame_copy.tf_eflags, tp->tf_eflags) || !CS_SECURE(frame_copy.tf_cs)) return (EINVAL); #endif *(int*)((char *)p->p_addr + off) = data; return (0); } min = offsetof(struct user, u_pcb) + offsetof(struct pcb, pcb_fp); if (off >= min && off <= min + sizeof(struct fpreg) - sizeof(int)) { *(int*)((char *)p->p_addr + off) = data; return (0); } return (EFAULT); } int alpha_pa_access(vm_offset_t pa) { #if 0 int i; for (i = 0; phys_avail[i] != 0; i += 2) { if (pa < phys_avail[i]) continue; if (pa < phys_avail[i+1]) return VM_PROT_READ|VM_PROT_WRITE; } return 0; #else return VM_PROT_READ|VM_PROT_WRITE; #endif } int fill_regs(p, regs) struct proc *p; struct reg *regs; { struct pcb *pcb = &p->p_addr->u_pcb; struct trapframe *tp = p->p_md.md_tf; tp = p->p_md.md_tf; #define C(r) regs->r_regs[R_ ## r] = tp->tf_regs[FRAME_ ## r] C(V0); C(T0); C(T1); C(T2); C(T3); C(T4); C(T5); C(T6); C(T7); C(S0); C(S1); C(S2); C(S3); C(S4); C(S5); C(S6); C(A0); C(A1); C(A2); C(A3); C(A4); C(A5); C(T8); C(T9); C(T10); C(T11); C(RA); C(T12); C(AT); C(GP); #undef C regs->r_regs[R_ZERO] = tp->tf_regs[FRAME_PC]; regs->r_regs[R_SP] = pcb->pcb_hw.apcb_usp; return (0); } int set_regs(p, regs) struct proc *p; struct reg *regs; { struct pcb *pcb = &p->p_addr->u_pcb; struct trapframe *tp = p->p_md.md_tf; tp = p->p_md.md_tf; #define C(r) tp->tf_regs[FRAME_ ## r] = regs->r_regs[R_ ## r] C(V0); C(T0); C(T1); C(T2); C(T3); C(T4); C(T5); C(T6); C(T7); C(S0); C(S1); C(S2); C(S3); C(S4); C(S5); C(S6); C(A0); C(A1); C(A2); C(A3); C(A4); C(A5); C(T8); C(T9); C(T10); C(T11); C(RA); C(T12); C(AT); C(GP); #undef C tp->tf_regs[FRAME_PC] = regs->r_regs[R_ZERO]; pcb->pcb_hw.apcb_usp = regs->r_regs[R_SP]; return (0); } int fill_fpregs(p, fpregs) struct proc *p; struct fpreg *fpregs; { if (p == fpcurproc) { alpha_pal_wrfen(1); savefpstate(&p->p_addr->u_pcb.pcb_fp); alpha_pal_wrfen(0); } bcopy(&p->p_addr->u_pcb.pcb_fp, fpregs, sizeof *fpregs); return (0); } int set_fpregs(p, fpregs) struct proc *p; struct fpreg *fpregs; { if (p == fpcurproc) fpcurproc = NULL; bcopy(fpregs, &p->p_addr->u_pcb.pcb_fp, sizeof *fpregs); return (0); } #ifndef DDB void Debugger(const char *msg) { printf("Debugger(\"%s\") called.\n", msg); } #endif /* no DDB */ #include /* * Determine the size of the transfer, and make sure it is * within the boundaries of the partition. Adjust transfer * if needed, and signal errors or early completion. */ int bounds_check_with_label(struct buf *bp, struct disklabel *lp, int wlabel) { #if 0 struct partition *p = lp->d_partitions + dkpart(bp->b_dev); int labelsect = lp->d_partitions[0].p_offset; int maxsz = p->p_size, sz = (bp->b_bcount + DEV_BSIZE - 1) >> DEV_BSHIFT; /* overwriting disk label ? */ /* XXX should also protect bootstrap in first 8K */ if (bp->b_blkno + p->p_offset <= LABELSECTOR + labelsect && #if LABELSECTOR != 0 bp->b_blkno + p->p_offset + sz > LABELSECTOR + labelsect && #endif (bp->b_flags & B_READ) == 0 && wlabel == 0) { bp->b_error = EROFS; goto bad; } #if defined(DOSBBSECTOR) && defined(notyet) /* overwriting master boot record? */ if (bp->b_blkno + p->p_offset <= DOSBBSECTOR && (bp->b_flags & B_READ) == 0 && wlabel == 0) { bp->b_error = EROFS; goto bad; } #endif /* beyond partition? */ if (bp->b_blkno < 0 || bp->b_blkno + sz > maxsz) { /* if exactly at end of disk, return an EOF */ if (bp->b_blkno == maxsz) { bp->b_resid = bp->b_bcount; return(0); } /* or truncate if part of it fits */ sz = maxsz - bp->b_blkno; if (sz <= 0) { bp->b_error = EINVAL; goto bad; } bp->b_bcount = sz << DEV_BSHIFT; } bp->b_pblkno = bp->b_blkno + p->p_offset; return(1); bad: bp->b_flags |= B_ERROR; #endif return(-1); } static int sysctl_machdep_adjkerntz SYSCTL_HANDLER_ARGS { int error; error = sysctl_handle_int(oidp, oidp->oid_arg1, oidp->oid_arg2, req); if (!error && req->newptr) resettodr(); return (error); } SYSCTL_PROC(_machdep, CPU_ADJKERNTZ, adjkerntz, CTLTYPE_INT|CTLFLAG_RW, &adjkerntz, 0, sysctl_machdep_adjkerntz, "I", ""); SYSCTL_INT(_machdep, CPU_DISRTCSET, disable_rtc_set, CTLFLAG_RW, &disable_rtc_set, 0, ""); SYSCTL_INT(_machdep, CPU_WALLCLOCK, wall_cmos_clock, CTLFLAG_RW, &wall_cmos_clock, 0, ""); diff --git a/sys/alpha/alpha/sys_machdep.c b/sys/alpha/alpha/sys_machdep.c index 6ff5956f6591..0d89b8fbba96 100644 --- a/sys/alpha/alpha/sys_machdep.c +++ b/sys/alpha/alpha/sys_machdep.c @@ -1,108 +1,153 @@ /*- * Copyright (c) 1990 The Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * from: @(#)sys_machdep.c 5.5 (Berkeley) 1/19/91 - * $Id: sys_machdep.c,v 1.1 1998/06/10 10:53:27 dfr Exp $ + * $Id: sys_machdep.c,v 1.2 1998/11/15 18:25:15 dfr Exp $ * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* for kernel_map */ +#include + #ifndef _SYS_SYSPROTO_H_ struct sysarch_args { int op; char *parms; }; #endif static int alpha_sethae(struct proc *p, char *args); +static int alpha_get_fpmask(struct proc *p, char *args); +static int alpha_set_fpmask(struct proc *p, char *args); int sysarch(p, uap) struct proc *p; register struct sysarch_args *uap; { int error = 0; switch(SCARG(uap,op)) { case ALPHA_SETHAE: error = alpha_sethae(p, uap->parms); break; + case ALPHA_GET_FPMASK: + error = alpha_get_fpmask(p, uap->parms); + break; + case ALPHA_SET_FPMASK: + error = alpha_set_fpmask(p, uap->parms); + break; default: error = EINVAL; break; } return (error); } struct alpha_sethae_args { u_int64_t hae; }; static int alpha_sethae(struct proc *p, char *args) { int error; struct alpha_sethae_args ua; if (error = copyin(args, &ua, sizeof(struct alpha_sethae_args))) return (error); if (securelevel > 0) return (EPERM); if (error = suser(p->p_ucred, &p->p_acflag)) return error; p->p_md.md_flags |= MDP_HAEUSED; p->p_md.md_hae = ua.hae; return (0); } + +struct alpha_fpmask_args { + u_int64_t mask; +}; + +static int +alpha_get_fpmask(struct proc *p, char *args) +{ + int error; + struct alpha_fpmask_args ua; + + ua.mask = p->p_addr->u_pcb.pcb_fp_control; + error = copyout(&ua, args, sizeof(struct alpha_fpmask_args)); + + return (error); +} + +static int +alpha_set_fpmask(struct proc *p, char *args) +{ + int error; + u_int64_t oldmask, *fp_control; + struct alpha_fpmask_args ua; + + if (error = copyin(args, &ua, sizeof(struct alpha_fpmask_args))) + return (error); + + fp_control = &p->p_addr->u_pcb.pcb_fp_control; + oldmask = *fp_control; + *fp_control = ua.mask & IEEE_TRAP_ENABLE_MASK; + ua.mask = oldmask; + + error = copyout(&ua, args, sizeof(struct alpha_fpmask_args)); + return (error); +} diff --git a/sys/alpha/include/alpha_cpu.h b/sys/alpha/include/alpha_cpu.h index 5107274ff18b..4bd105066045 100644 --- a/sys/alpha/include/alpha_cpu.h +++ b/sys/alpha/include/alpha_cpu.h @@ -1,328 +1,330 @@ -/* $Id: alpha_cpu.h,v 1.2 1998/06/10 10:54:21 dfr Exp $ */ +/* $Id: alpha_cpu.h,v 1.3 1998/06/14 13:45:10 dfr Exp $ */ /* From: NetBSD: alpha_cpu.h,v 1.15 1997/09/20 19:02:34 mjacob Exp */ /* * Copyright (c) 1996 Carnegie-Mellon University. * All rights reserved. * * Author: Chris G. Demetriou * * Permission to use, copy, modify and distribute this software and * its documentation is hereby granted, provided that both the copyright * notice and this permission notice appear in all copies of the * software, derivative works or modified versions, and any portions * thereof, and that both notices appear in supporting documentation. * * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. * * Carnegie Mellon requests users of this software to return to * * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU * School of Computer Science * Carnegie Mellon University * Pittsburgh PA 15213-3890 * * any improvements or extensions that they make and grant Carnegie the * rights to redistribute these changes. */ #ifndef __ALPHA_ALPHA_CPU_H__ #define __ALPHA_ALPHA_CPU_H__ /* * Alpha CPU + OSF/1 PALcode definitions for use by the kernel. * * Definitions for: * * Process Control Block * Interrupt/Exception/Syscall Stack Frame * Processor Status Register * Machine Check Error Summary Register * Machine Check Logout Area * Virtual Memory Management * Kernel Entry Vectors * MMCSR Fault Type Codes * Translation Buffer Invalidation * * and miscellaneous PALcode operations. */ /* * Process Control Block definitions [OSF/1 PALcode Specific] */ struct alpha_pcb { unsigned long apcb_ksp; /* kernel stack ptr */ unsigned long apcb_usp; /* user stack ptr */ unsigned long apcb_ptbr; /* page table base reg */ unsigned int apcb_cpc; /* charged process cycles */ unsigned int apcb_asn; /* address space number */ unsigned long apcb_unique; /* process unique value */ unsigned long apcb_flags; /* flags; see below */ unsigned long apcb_decrsv0; /* DEC reserved */ unsigned long apcb_decrsv1; /* DEC reserved */ }; #define ALPHA_PCB_FLAGS_FEN 0x0000000000000001 #define ALPHA_PCB_FLAGS_PME 0x4000000000000000 /* * Interrupt/Exception/Syscall "Hardware" (really PALcode) * Stack Frame definitions * * These are quadword offsets from the sp on kernel entry, i.e. * to get to the value in question you access (sp + (offset * 8)). * * On syscall entry, A0-A2 aren't written to memory but space * _is_ reserved for them. */ #define ALPHA_HWFRAME_PS 0 /* processor status register */ #define ALPHA_HWFRAME_PC 1 /* program counter */ #define ALPHA_HWFRAME_GP 2 /* global pointer */ #define ALPHA_HWFRAME_A0 3 /* a0 */ #define ALPHA_HWFRAME_A1 4 /* a1 */ #define ALPHA_HWFRAME_A2 5 /* a2 */ #define ALPHA_HWFRAME_SIZE 6 /* 6 8-byte words */ /* * Processor Status Register [OSF/1 PALcode Specific] * * Includes user/kernel mode bit, interrupt priority levels, etc. */ #define ALPHA_PSL_USERMODE 0x0008 /* set -> user mode */ #define ALPHA_PSL_IPL_MASK 0x0007 /* interrupt level mask */ #define ALPHA_PSL_IPL_0 0x0000 /* all interrupts enabled */ #define ALPHA_PSL_IPL_SOFT 0x0001 /* software ints disabled */ #define ALPHA_PSL_IPL_IO 0x0004 /* I/O dev ints disabled */ #define ALPHA_PSL_IPL_CLOCK 0x0005 /* clock ints disabled */ #define ALPHA_PSL_IPL_HIGH 0x0006 /* all but mchecks disabled */ #define ALPHA_PSL_MUST_BE_ZERO 0xfffffffffffffff0 /* Convenience constants: what must be set/clear in user mode */ #define ALPHA_PSL_USERSET ALPHA_PSL_USERMODE #define ALPHA_PSL_USERCLR (ALPHA_PSL_MUST_BE_ZERO | ALPHA_PSL_IPL_MASK) /* * Interrupt Type Code Definitions [OSF/1 PALcode Specific] */ #define ALPHA_INTR_XPROC 0 /* interprocessor interrupt */ #define ALPHA_INTR_CLOCK 1 /* clock interrupt */ #define ALPHA_INTR_ERROR 2 /* correctable error or mcheck */ #define ALPHA_INTR_DEVICE 3 /* device interrupt */ #define ALPHA_INTR_PERF 4 /* performance counter */ #define ALPHA_INTR_PASSIVE 5 /* passive release */ /* * Machine Check Error Summary Register definitions [OSF/1 PALcode Specific] * * The following bits are values as read. On write, _PCE, _SCE, and * _MIP are "write 1 to clear." */ #define ALPHA_MCES_IMP \ 0xffffffff00000000 /* impl. dependent */ #define ALPHA_MCES_RSVD \ 0x00000000ffffffe0 /* reserved */ #define ALPHA_MCES_DSC \ 0x0000000000000010 /* disable system correctable error reporting */ #define ALPHA_MCES_DPC \ 0x0000000000000008 /* disable processor correctable error reporting */ #define ALPHA_MCES_PCE \ 0x0000000000000004 /* processor correctable error in progress */ #define ALPHA_MCES_SCE \ 0x0000000000000002 /* system correctable error in progress */ #define ALPHA_MCES_MIP \ 0x0000000000000001 /* machine check in progress */ /* * Machine Check Error Summary Register definitions [OSF/1 PALcode Specific] */ struct alpha_logout_area { unsigned int la_frame_size; /* frame size */ unsigned int la_flags; /* flags; see below */ unsigned int la_cpu_offset; /* offset to cpu area */ unsigned int la_system_offset; /* offset to system area */ }; #define ALPHA_LOGOUT_FLAGS_RETRY 0x80000000 /* OK to continue */ #define ALPHA_LOGOUT_FLAGS_SE 0x40000000 /* second error */ #define ALPHA_LOGOUT_FLAGS_SBZ 0x3fffffff /* should be zero */ #define ALPHA_LOGOUT_NOT_BUILT \ (struct alpha_logout_area *)0xffffffffffffffff) #define ALPHA_LOGOUT_PAL_AREA(lap) \ (unsigned long *)((unsigned char *)(lap) + 16) #define ALPHA_LOGOUT_PAL_SIZE(lap) \ ((lap)->la_cpu_offset - 16) #define ALPHA_LOGOUT_CPU_AREA(lap) \ (unsigned long *)((unsigned char *)(lap) + (lap)->la_cpu_offset) #define ALPHA_LOGOUT_CPU_SIZE(lap) \ ((lap)->la_system_offset - (lap)->la_cpu_offset) #define ALPHA_LOGOUT_SYSTEM_AREA(lap) \ (unsigned long *)((unsigned char *)(lap) + (lap)->la_system_offset) #define ALPHA_LOGOUT_SYSTEM_SIZE(lap) \ ((lap)->la_frame_size - (lap)->la_system_offset) /* * Virtual Memory Management definitions [OSF/1 PALcode Specific] * * Includes user and kernel space addresses and information, * page table entry definitions, etc. * * NOTE THAT THESE DEFINITIONS MAY CHANGE IN FUTURE ALPHA CPUS! */ #define ALPHA_PGSHIFT 13 /* bits that index within page */ #define ALPHA_PTSHIFT 10 /* bits that index within page tables */ #define ALPHA_PGBYTES (1 << ALPHA_PGSHIFT) #define ALPHA_L3SHIFT ALPHA_PGSHIFT #define ALPHA_L2SHIFT (ALPHA_L3SHIFT+ALPHA_PTSHIFT) #define ALPHA_L1SHIFT (ALPHA_L2SHIFT+ALPHA_PTSHIFT) #define ALPHA_USEG_BASE 0 /* virtual */ #define ALPHA_USEG_END 0x000003ffffffffffLL #define ALPHA_K0SEG_BASE 0xfffffc0000000000LL /* direct-mapped */ #define ALPHA_K0SEG_END 0xfffffdffffffffffLL #define ALPHA_K1SEG_BASE 0xfffffe0000000000LL /* virtual */ #define ALPHA_K1SEG_END 0xffffffffffffffffLL #define ALPHA_K0SEG_TO_PHYS(x) ((x) & ~ALPHA_K0SEG_BASE) #define ALPHA_PHYS_TO_K0SEG(x) ((x) | ALPHA_K0SEG_BASE) #define ALPHA_PTE_VALID 0x0001 #define ALPHA_PTE_FAULT_ON_READ 0x0002 #define ALPHA_PTE_FAULT_ON_WRITE 0x0004 #define ALPHA_PTE_FAULT_ON_EXECUTE 0x0008 #define ALPHA_PTE_ASM 0x0010 /* addr. space match */ #define ALPHA_PTE_GRANULARITY 0x0060 /* granularity hint */ #define ALPHA_PTE_PROT 0xff00 #define ALPHA_PTE_KR 0x0100 #define ALPHA_PTE_UR 0x0200 #define ALPHA_PTE_KW 0x1000 #define ALPHA_PTE_UW 0x2000 #define ALPHA_PTE_WRITE (ALPHA_PTE_KW | ALPHA_PTE_UW) #define ALPHA_PTE_SOFTWARE 0xffff0000 #define ALPHA_PTE_PFN 0xffffffff00000000 #define ALPHA_PTE_TO_PFN(pte) ((u_long)(pte) >> 32) #define ALPHA_PTE_FROM_PFN(pfn) ((u_long)(pfn) << 32) typedef unsigned long alpha_pt_entry_t; /* * Kernel Entry Vectors. [OSF/1 PALcode Specific] */ #define ALPHA_KENTRY_INT 0 #define ALPHA_KENTRY_ARITH 1 #define ALPHA_KENTRY_MM 2 #define ALPHA_KENTRY_IF 3 #define ALPHA_KENTRY_UNA 4 #define ALPHA_KENTRY_SYS 5 /* * MMCSR Fault Type Codes. [OSF/1 PALcode Specific] */ #define ALPHA_MMCSR_INVALTRANS 0 #define ALPHA_MMCSR_ACCESS 1 #define ALPHA_MMCSR_FOR 2 #define ALPHA_MMCSR_FOE 3 #define ALPHA_MMCSR_FOW 4 /* * Instruction Fault Type Codes. [OSF/1 PALcode Specific] */ #define ALPHA_IF_CODE_BPT 0 #define ALPHA_IF_CODE_BUGCHK 1 #define ALPHA_IF_CODE_GENTRAP 2 #define ALPHA_IF_CODE_FEN 3 #define ALPHA_IF_CODE_OPDEC 4 /* * Translation Buffer Invalidation definitions [OSF/1 PALcode Specific] */ #define ALPHA_TBIA() alpha_pal_tbi(-2, 0) /* all TB entries */ #define ALPHA_TBIAP() alpha_pal_tbi(-1, 0) /* all per-process */ #define ALPHA_TBISI(va) alpha_pal_tbi(1, (va)) /* ITB entry for va */ #define ALPHA_TBISD(va) alpha_pal_tbi(2, (va)) /* DTB entry for va */ #define ALPHA_TBIS(va) alpha_pal_tbi(3, (va)) /* all for va */ /* * Bits used in the amask instruction [EV56 and later] */ #define ALPHA_AMASK_BWX 0x0001 /* byte/word extension */ -#define ALPHA_AMASK_CIX 0x0002 /* count extension */ -#define ALPHA_AMASK_MAX 0x0100 /* multimedia extension */ +#define ALPHA_AMASK_FIX 0x0002 /* sqrt and f <-> i conversion extension */ +#define ALPHA_AMASK_CIX 0x0004 /* count extension */ +#define ALPHA_AMASK_MVI 0x0100 /* multimedia extension */ +#define ALPHA_AMASK_PRECISE 0x0200 /* Precise arithmetic traps */ /* * Chip family IDs returned by implver instruction */ #define ALPHA_IMPLVER_EV4 0 /* LCA/EV4/EV45 */ #define ALPHA_IMPLVER_EV5 1 /* EV5/EV56/PCA56 */ #define ALPHA_IMPLVER_EV6 2 /* EV6 */ /* * Stubs for Alpha instructions normally inaccessible from C. */ unsigned long alpha_amask __P((unsigned long)); unsigned long alpha_implver __P((void)); unsigned long alpha_rpcc __P((void)); void alpha_mb __P((void)); void alpha_wmb __P((void)); u_int8_t alpha_ldbu __P((volatile u_int8_t *)); u_int16_t alpha_ldwu __P((volatile u_int16_t *)); void alpha_stb __P((volatile u_int8_t *, u_int8_t)); void alpha_stw __P((volatile u_int16_t *, u_int16_t)); u_int8_t alpha_sextb __P((u_int8_t)); u_int16_t alpha_sextw __P((u_int16_t)); /* * Stubs for OSF/1 PALcode operations. */ void alpha_pal_imb __P((void)); void alpha_pal_cflush __P((unsigned long)); void alpha_pal_draina __P((void)); void alpha_pal_halt __P((void)) __attribute__((__noreturn__)); unsigned long alpha_pal_rdmces __P((void)); unsigned long alpha_pal_rdps __P((void)); unsigned long alpha_pal_rdusp __P((void)); unsigned long alpha_pal_rdval __P((void)); unsigned long alpha_pal_swpctx __P((unsigned long)); unsigned long alpha_pal_swpipl __P((unsigned long)); unsigned long _alpha_pal_swpipl __P((unsigned long)); /* for profiling */ void alpha_pal_tbi __P((unsigned long, vm_offset_t)); unsigned long alpha_pal_whami __P((void)); void alpha_pal_wrent __P((void *, unsigned long)); void alpha_pal_wrfen __P((unsigned long)); void alpha_pal_wripir __P((unsigned long)); void alpha_pal_wrusp __P((unsigned long)); void alpha_pal_wrvptptr __P((unsigned long)); void alpha_pal_wrmces __P((unsigned long)); void alpha_pal_wrval __P((unsigned long)); #endif /* __ALPHA_ALPHA_CPU_H__ */ diff --git a/sys/alpha/include/fpu.h b/sys/alpha/include/fpu.h index d4a767e66ebd..c9efceed0293 100644 --- a/sys/alpha/include/fpu.h +++ b/sys/alpha/include/fpu.h @@ -1,114 +1,124 @@ /*- * Copyright (c) 1998 Doug Rabson * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id$ + * $Id: fpu.h,v 1.1 1998/12/04 10:52:48 dfr Exp $ */ #ifndef _MACHINE_FPU_H_ #define _MACHINE_FPU_H_ /* * Floating point control register bits. * * From Alpha AXP Architecture Reference Manual, Instruction * Descriptions (I) PP 4-69. */ #define FPCR_INVD (1LL << 49) /* Invalid Operation DIsable */ #define FPCR_DZED (1LL << 50) /* Division by Zero Disable */ #define FPCR_OVFD (1LL << 51) /* Overflow Disable */ #define FPCR_INV (1LL << 52) /* Invalid Operation */ #define FPCR_DZE (1LL << 53) /* Division by Zero */ #define FPCR_OVF (1LL << 54) /* Overflow */ #define FPCR_UNF (1LL << 55) /* Underflow */ #define FPCR_INE (1LL << 56) /* Inexact Result */ #define FPCR_IOV (1LL << 57) /* Integer Overflow */ #define FPCR_DYN_CHOPPED (0LL << 58) /* Chopped rounding mode */ #define FPCR_DYN_MINUS (1LL << 58) /* Minus infinity */ #define FPCR_DYN_NORMAL (2LL << 58) /* Normal rounding */ #define FPCR_DYN_PLUS (3LL << 58) /* Plus infinity */ #define FPCR_DYN_MASK (3LL << 58) /* Rounding mode mask */ #define FPCR_DYN_SHIFT 58 #define FPCR_UNDZ (1LL << 60) /* Underflow to Zero */ #define FPCR_UNFD (1LL << 61) /* Underflow Disable */ #define FPCR_INED (1LL << 62) /* Inexact Disable */ #define FPCR_SUM (1LL << 63) /* Summary Bit */ #define FPCR_MASK (~0LL << 49) /* * Exception summary bits. * * From Alpha AXP Architecture Reference Manual, DEC OSF/1 Exceptions * and Interrupts (II-B) PP 5-5. */ #define EXCSUM_SWC (1LL << 0) /* Software completion */ #define EXCSUM_INV (1LL << 1) /* Invalid operation */ #define EXCSUM_DZE (1LL << 2) /* Division by zero */ #define EXCSUM_OVF (1LL << 3) /* Overflow */ #define EXCSUM_UNF (1LL << 4) /* Underflow */ #define EXCSUM_INE (1LL << 5) /* Inexact result */ #define EXCSUM_IOV (1LL << 6) /* Integer overflow */ /* * Definitions for IEEE trap enables. These are implemented in * software and should be compatible with OSF/1 and Linux. */ /* read/write flags */ #define IEEE_TRAP_ENABLE_INV (1LL << 1) /* Invalid operation */ #define IEEE_TRAP_ENABLE_DZE (1LL << 2) /* Division by zero */ #define IEEE_TRAP_ENABLE_OVF (1LL << 3) /* Overflow */ #define IEEE_TRAP_ENABLE_UNF (1LL << 4) /* Underflow */ #define IEEE_TRAP_ENABLE_INE (1LL << 5) /* Inexact result */ #define IEEE_TRAP_ENABLE_MASK (IEEE_TRAP_ENABLE_INV \ | IEEE_TRAP_ENABLE_DZE \ | IEEE_TRAP_ENABLE_OVF \ | IEEE_TRAP_ENABLE_UNF \ | IEEE_TRAP_ENABLE_INE) /* read only flags */ #define IEEE_STATUS_INV (1LL << 17) /* Invalid operation */ #define IEEE_STATUS_DZE (1LL << 18) /* Division by zero */ #define IEEE_STATUS_OVF (1LL << 19) /* Overflow */ #define IEEE_STATUS_UNF (1LL << 20) /* Underflow */ #define IEEE_STATUS_INE (1LL << 21) /* Inexact result */ #define IEEE_STATUS_MASK (IEEE_STATUS_INV \ | IEEE_STATUS_DZE \ | IEEE_STATUS_OVF \ | IEEE_STATUS_UNF \ | IEEE_STATUS_INE) #define IEEE_STATUS_TO_EXCSUM_SHIFT 16 /* convert to excsum */ #define IEEE_STATUS_TO_FPCR_SHIFT 35 /* convert to fpcr */ #define IEEE_INHERIT (1LL << 63) /* inherit on fork */ +/* read and write floating point control register */ +#define GET_FPCR(x) \ + __asm__("trapb"); \ + __asm__("mf_fpcr %0" : "=f" (x)); \ + __asm__("trapb") +#define SET_FPCR(x) \ + __asm__("trapb"); \ + __asm__("mt_fpcr %0" : : "f" (x)); \ + __asm__("trapb") + #ifdef KERNEL extern int fp_software_completion(u_int64_t regmask, struct proc *p); #endif #endif /* ! _MACHINE_FPU_H_ */ diff --git a/sys/alpha/include/ieeefp.h b/sys/alpha/include/ieeefp.h index c0f4c2f4035c..a838e9891955 100644 --- a/sys/alpha/include/ieeefp.h +++ b/sys/alpha/include/ieeefp.h @@ -1,27 +1,29 @@ -/* $Id$ */ +/* $Id: ieeefp.h,v 1.1.1.1 1998/03/09 05:43:16 jb Exp $ */ /* From: NetBSD: ieeefp.h,v 1.2 1997/04/06 08:47:28 cgd Exp */ /* * Written by J.T. Conklin, Apr 28, 1995 * Public domain. */ #ifndef _ALPHA_IEEEFP_H_ #define _ALPHA_IEEEFP_H_ typedef int fp_except; -#define FP_X_INV 0x01 /* invalid operation exception */ -#define FP_X_DZ 0x02 /* divide-by-zero exception */ -#define FP_X_OFL 0x04 /* overflow exception */ -#define FP_X_UFL 0x08 /* underflow exception */ -#define FP_X_IMP 0x10 /* imprecise (loss of precision; "inexact") */ -#define FP_X_IOV 0x20 /* integer overflow XXX? */ +#define FP_X_INV (1LL << 1) /* invalid operation exception */ +#define FP_X_DZ (1LL << 2) /* divide-by-zero exception */ +#define FP_X_OFL (1LL << 3) /* overflow exception */ +#define FP_X_UFL (1LL << 4) /* underflow exception */ +#define FP_X_IMP (1LL << 5) /* imprecise(inexact) exception */ +#if 0 +#define FP_X_IOV (1LL << 6) /* integer overflow XXX? */ +#endif typedef enum { FP_RZ=0, /* round to zero (truncate) */ FP_RM=1, /* round toward negative infinity */ FP_RN=2, /* round to nearest representable number */ FP_RP=3 /* round toward positive infinity */ } fp_rnd; #endif /* _ALPHA_IEEEFP_H_ */ diff --git a/sys/alpha/include/sysarch.h b/sys/alpha/include/sysarch.h index 61806f80e1c0..e0e0a6b9b617 100644 --- a/sys/alpha/include/sysarch.h +++ b/sys/alpha/include/sysarch.h @@ -1,54 +1,56 @@ /*- * Copyright (c) 1993 The Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id$ + * $Id: sysarch.h,v 1.1 1998/11/17 10:40:07 dfr Exp $ */ /* * Architecture specific syscalls (alpha) */ #ifndef _MACHINE_SYSARCH_H_ #define _MACHINE_SYSARCH_H_ -#define ALPHA_SETHAE 0 +#define ALPHA_SETHAE 0 +#define ALPHA_GET_FPMASK 1 +#define ALPHA_SET_FPMASK 2 #ifndef KERNEL #include union descriptor; __BEGIN_DECLS int alpha_sethae __P((u_int64_t)); __END_DECLS #endif /* !KERNEL */ #endif /* !_MACHINE_SYSARCH_H_ */