diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./bin/ksh/tree.c src-sh4-fpu/./bin/ksh/tree.c --- src.orig/./bin/ksh/tree.c 2005-06-27 04:09:00.000000000 +0900 +++ src-sh4-fpu/./bin/ksh/tree.c 2009-07-21 21:41:00.000000000 +0900 @@ -423,7 +423,7 @@ register struct shf *shf; int indent; const char *fmt; - register va_list va; + va_list va; { register int c; diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./crypto/external/bsd/openssl/lib/libcrypto/Makefile src-sh4-fpu/./crypto/external/bsd/openssl/lib/libcrypto/Makefile --- src.orig/./crypto/external/bsd/openssl/lib/libcrypto/Makefile 2009-07-20 08:30:42.000000000 +0900 +++ src-sh4-fpu/./crypto/external/bsd/openssl/lib/libcrypto/Makefile 2009-07-21 19:55:24.000000000 +0900 @@ -121,6 +121,10 @@ COPTS.eng_padlock.c = -Wno-stack-protector +.if ${MACHINE_GNU_ARCH} == "sh4le" || ${MACHINE_GNU_ARCH} == "sh4" +COPTS.asn1_par.c+= -O0 +.endif + INCSDIR=/usr/include/openssl .include diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./distrib/sets/lists/comp/ad.sh3 src-sh4-fpu/./distrib/sets/lists/comp/ad.sh3 --- src.orig/./distrib/sets/lists/comp/ad.sh3 2008-09-10 08:01:37.000000000 +0900 +++ src-sh4-fpu/./distrib/sets/lists/comp/ad.sh3 2009-07-21 20:23:43.000000000 +0900 @@ -17,6 +17,7 @@ ./usr/include/sh3/endian.h comp-c-include ./usr/include/sh3/endian_machdep.h comp-c-include ./usr/include/sh3/float.h comp-c-include +./usr/include/sh3/fpu.h comp-c-include ./usr/include/sh3/frame.h comp-c-include ./usr/include/sh3/ieee.h comp-c-include ./usr/include/sh3/ieeefp.h comp-c-include diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./external/ibm-public/postfix/libexec/smtpd/Makefile src-sh4-fpu/./external/ibm-public/postfix/libexec/smtpd/Makefile --- src.orig/./external/ibm-public/postfix/libexec/smtpd/Makefile 2009-06-26 03:21:55.000000000 +0900 +++ src-sh4-fpu/./external/ibm-public/postfix/libexec/smtpd/Makefile 2009-07-21 21:32:49.000000000 +0900 @@ -24,4 +24,8 @@ DPADD+= ${LIBPUTIL} LDADD+= ${LIBPUTIL} +.if ${MACHINE_GNU_ARCH} == "sh4le" || ${MACHINE_GNU_ARCH} == "sh4" +COPTS.smtpd_check.c+= -O0 +.endif + .include diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./lib/libkrb5/Makefile src-sh4-fpu/./lib/libkrb5/Makefile --- src.orig/./lib/libkrb5/Makefile 2009-07-21 15:02:33.000000000 +0900 +++ src-sh4-fpu/./lib/libkrb5/Makefile 2009-07-21 20:16:52.000000000 +0900 @@ -746,5 +746,9 @@ FILESDIR= /usr/share/examples/kerberos .endif +.if ${MACHINE_GNU_ARCH} == "sh4le" || ${MACHINE_GNU_ARCH} == "sh4" +COPTS.crypto.c+= -O0 +.endif + .include .include diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./lib/libwrap/Makefile src-sh4-fpu/./lib/libwrap/Makefile --- src.orig/./lib/libwrap/Makefile 2007-05-28 21:06:22.000000000 +0900 +++ src-sh4-fpu/./lib/libwrap/Makefile 2009-07-21 19:53:32.000000000 +0900 @@ -19,4 +19,8 @@ .include "Makefile.cflags" +.if ${MACHINE_GNU_ARCH} == "sh4le" || ${MACHINE_GNU_ARCH} == "sh4" +COPTS.hosts_access.c+= -O0 +.endif + .include diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./makeBuild.sh src-sh4-fpu/./makeBuild.sh --- src.orig/./makeBuild.sh 1970-01-01 09:00:00.000000000 +0900 +++ src-sh4-fpu/./makeBuild.sh 2009-07-21 15:43:55.000000000 +0900 @@ -0,0 +1,44 @@ +#!/bin/sh + +progname=$0 + +usage() { + echo "Usage: ${progname} " + exit 1 +} + +if [ x"$1" = x ]; then + usage +fi +target_machine="$1" +shift + +if [ x"$1" = x ]; then + usage +fi +build_date=$1 +shift + +if [ x"$1" = x ]; then + usage +fi +operation=$1 +shift + +LANG=C; export LANG +LC_ALL=C; export LC_ALL +LC_CTYPE=C; export LC_CTYPE + +if [ -x /usr/pkg/bin/sudo ]; then + SUDO=/usr/pkg/bin/sudo +fi + +time ${SUDO} ./build.sh -m ${target_machine} \ + -D /home/snapshot/${build_date}/root/${target_machine} \ + -R /home/snapshot/${build_date}/release \ + -T /usr/local/netbsd-tools \ + $@ \ + ${operation} \ + 2>&1 | tee makeBuild-${target_machine}.log +retval=$? +exit ${retval} diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./share/mk/bsd.own.mk src-sh4-fpu/./share/mk/bsd.own.mk --- src.orig/./share/mk/bsd.own.mk 2009-07-08 20:59:12.000000000 +0900 +++ src-sh4-fpu/./share/mk/bsd.own.mk 2009-07-21 22:35:48.000000000 +0900 @@ -541,8 +541,13 @@ GCC_CONFIG_TUNE.i386=nocona GCC_CONFIG_TUNE.x86_64=nocona GNU_ARCH.m68000=m68010 +.if ${MACHINE} == "landisk" +GNU_ARCH.sh3eb=sh4 +GNU_ARCH.sh3el=sh4le +.else GNU_ARCH.sh3eb=sh GNU_ARCH.sh3el=shle +.endif GNU_ARCH.mips64eb=mips64 MACHINE_GNU_ARCH=${GNU_ARCH.${MACHINE_ARCH}:U${MACHINE_ARCH}} @@ -557,6 +562,10 @@ ${MACHINE_CPU} == "m68k" || \ ${MACHINE_GNU_ARCH} == "sh" || \ ${MACHINE_GNU_ARCH} == "shle" || \ + ${MACHINE_GNU_ARCH} == "sh4" || \ + ${MACHINE_GNU_ARCH} == "sh4le" || \ + ${MACHINE_GNU_ARCH} == "sh4a" || \ + ${MACHINE_GNU_ARCH} == "sh4ale" || \ ${MACHINE_ARCH} == "sparc" || \ ${MACHINE_ARCH} == "vax") MACHINE_GNU_PLATFORM?=${MACHINE_GNU_ARCH}--netbsdelf diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./sys/arch/sh3/conf/files.sh3 src-sh4-fpu/./sys/arch/sh3/conf/files.sh3 --- src.orig/./sys/arch/sh3/conf/files.sh3 2008-11-22 15:00:26.000000000 +0900 +++ src-sh4-fpu/./sys/arch/sh3/conf/files.sh3 2009-07-08 23:14:57.000000000 +0900 @@ -29,6 +29,9 @@ file arch/sh3/sh3/devreg.c sh3 & sh4 file arch/sh3/sh3/exception.c file arch/sh3/sh3/exception_vector.S +file arch/sh3/sh3/fpu.c +file arch/sh3/sh3/fpu_sh3.c sh3 +file arch/sh3/sh3/fpu_sh4.c sh4 file arch/sh3/sh3/interrupt.c file arch/sh3/sh3/kgdb_machdep.c kgdb file arch/sh3/sh3/kobj_machdep.c modular diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./sys/arch/sh3/include/Makefile src-sh4-fpu/./sys/arch/sh3/include/Makefile --- src.orig/./sys/arch/sh3/include/Makefile 2007-02-10 06:55:12.000000000 +0900 +++ src-sh4-fpu/./sys/arch/sh3/include/Makefile 2009-07-21 20:09:43.000000000 +0900 @@ -7,7 +7,7 @@ cdefs.h coff_machdep.h cpu.h cputypes.h \ disklabel.h \ elf_machdep.h endian.h endian_machdep.h \ - float.h frame.h \ + float.h fpu.h frame.h \ ieee.h ieeefp.h \ int_const.h int_fmtio.h int_limits.h int_mwgwtypes.h int_types.h \ intr.h \ diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./sys/arch/sh3/include/cpu.h src-sh4-fpu/./sys/arch/sh3/include/cpu.h --- src.orig/./sys/arch/sh3/include/cpu.h 2008-03-23 13:30:39.000000000 +0900 +++ src-sh4-fpu/./sys/arch/sh3/include/cpu.h 2009-07-08 22:41:06.000000000 +0900 @@ -60,6 +60,7 @@ int ci_mtx_oldspl; int ci_want_resched; int ci_idepth; + struct lwp *ci_fpulwp; /* current owner of FPU */ }; extern struct cpu_info cpu_info_store; diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./sys/arch/sh3/include/fpu.h src-sh4-fpu/./sys/arch/sh3/include/fpu.h --- src.orig/./sys/arch/sh3/include/fpu.h 1970-01-01 09:00:00.000000000 +0900 +++ src-sh4-fpu/./sys/arch/sh3/include/fpu.h 2009-07-13 21:25:20.000000000 +0900 @@ -0,0 +1,169 @@ +/* $NetBSD$ */ + +/*- + * Copyright (c) 2009 The NetBSD Foundation, Inc. + * 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 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. + */ + +#ifndef _SH3_FPU_H_ +#define _SH3_FPU_H_ + +#if defined(_KERNEL) + +struct lwp; +struct ksiginfo; +struct trapframe; + +void sh_fpu_init(void); + +#ifdef SH3 +void sh3_fpu_enable(void); +void sh3_fpu_save_lwp(struct lwp *); +void sh3_fpu_exit_lwp(struct lwp *, int); +int sh3_fpu_exception(struct lwp *, struct trapframe *, struct ksiginfo *); +#endif + +#ifdef SH4 +void sh4_fpu_enable(void); +void sh4_fpu_save_lwp(struct lwp *); +void sh4_fpu_exit_lwp(struct lwp *, int); +int sh4_fpu_exception(struct lwp *, struct trapframe *, struct ksiginfo *); +#endif + +#if defined(SH3) && defined(SH4) +extern void (*__sh_fpu_enable)(void); +extern void (*__sh_fpu_save_lwp)(struct lwp *); +extern void (*__sh_fpu_exit_lwp)(struct lwp *, int); +extern int (*__sh_fpu_exception)(struct lwp *, struct trapframe *, + struct ksiginfo *); + +#define sh_fpu_enable() (*__sh_fpu_enable)() +#define sh_fpu_save_lwp(l) (*__sh_fpu_save_lwp)(l) +#define sh_fpu_exit_lwp(l, c) (*__sh_fpu_exit_lwp)(l, c) +#define sh_fpu_exception(l,t,s) (*__sh_fpu_exception)(l,t,s) +#define CPU_HAS_FPU (CPU_IS_SH4) + +#elif defined(SH3) + +#define sh_fpu_enable() sh3_fpu_enable() +#define sh_fpu_save_lwp(l) sh3_fpu_save_lwp(l) +#define sh_fpu_exit_lwp(l, c) sh3_fpu_exit_lwp(l, c) +#define sh_fpu_exception(l,t,s) sh3_fpu_exception(l,t,s) +#define CPU_HAS_FPU (0) /* XXX: SH3E */ + +#elif defined(SH4) + +#define sh_fpu_enable() sh4_fpu_enable() +#define sh_fpu_save_lwp(l) sh4_fpu_save_lwp(l) +#define sh_fpu_exit_lwp(l, c) sh4_fpu_exit_lwp(l, c) +#define sh_fpu_exception(l,t,s) sh4_fpu_exception(l,t,s) +#define CPU_HAS_FPU (1) + +#endif /* SH3 && SH4 */ + +#endif /* _KERNEL */ + +#if !defined(__ASSEMBLER__) +/* FPU control register access */ +static __inline int __unused +get_fpscr(void) +{ + int r; + + asm volatile ("sts fpscr, %0" : "=r"(r)); + + return r; +} + +static __inline void __unused +set_fpscr(int r) +{ + + asm volatile ("lds %0, fpscr" :: "r"(r)); +} + +static __inline int __unused +get_fpul(void) +{ + int r; + + asm volatile ("sts fpul, %0" : "=r"(r)); + + return r; +} + +static __inline void __unused +set_fpul(int r) +{ + + asm volatile ("lds %0, fpul" :: "r"(r)); +} +#endif /* !__ASSEMBLER__ */ + +/* + * FPU register definition + */ +#define FPREGS_PER_BANK 0x10 +#define FP_BANK_BIT 0x10 + +/* fpscr bit */ +#define FPSCR_RM (0x03 << 0) /* Round mode */ +#define RM_NEAREST (0x00 << 0) /* nearest (SH4 only) */ +#define RM_ZERO (0x01 << 0) /* round to zero */ +#define FPSCR_FLAG (0x1f << 2) /* FPU exception flag: VZOUI */ +#define FPSCR_ENABLE (0x1f << 7) /* FPU exception enable: VZOUI */ +#define FPSCR_CAUSE (0x3f << 12) /* FPU exception cause: EVZOUI */ +#define FPSCR_DN (0x01 << 18) /* Denormal mode: 0=denormal (SH4 only), 1=0 */ +#define FPSCR_PR (0x01 << 19) /* precision (SH4 only): 0=float, 1=double */ +#define FPSCR_SZ (0x01 << 20) /* fmov size (SH4 only): 0=32, 1=64 */ +#define FPSCR_FR (0x01 << 21) /* register bank (SH4 only) */ +#define FPSCR_MASK (0x003fffff) + +/* FPU exception flag/enable/cause bit */ +#define FP_I_BIT (1 << 0) /* inexact result (SH4 only) */ +#define FP_U_BIT (1 << 1) /* underflow (SH4 only) */ +#define FP_O_BIT (1 << 2) /* overflow (SH4 only) */ +#define FP_Z_BIT (1 << 3) /* divide by zero */ +#define FP_V_BIT (1 << 4) /* invalid operation */ +#define FP_E_BIT (1 << 5) /* FPU error (SH4 only) */ +#define FP_ALL_BIT (FP_I_BIT|FP_U_BIT|FP_O_BIT|FP_Z_BIT|FP_V_BIT) + +/* FPU exception flag/enable/cause shift bits */ +#define FP_FLAG_SHIFT 2 +#define FP_ENABLE_SHIFT 7 +#define FP_CAUSE_SHIFT 12 + +#define FP_FLAG_MASK FP_ALL_BIT +#define FP_ENABLE_MASK FP_ALL_BIT +#define FP_CAUSE_MASK (FP_ALL_BIT|FP_E_BIT) + +#define FP_FLAG(r) (((r) >> FP_FLAG_SHIFT) & FP_FLAG_MASK) +#define FP_ENABLE(r) (((r) >> FP_ENABLE_SHIFT) & FP_ENABLE_MASK) +#define FP_CAUSE(r) (((r) >> FP_CAUSE_SHIFT) & FP_CAUSE_MASK) + +/* fpscr initial value */ +#define SH3_FPSCR_INIT (RM_ZERO|FPSCR_DN) +#define SH4_FPSCR_INIT (RM_NEAREST|FPSCR_PR) + +#endif /* !_SH3_FPU_H_ */ diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./sys/arch/sh3/include/mcontext.h src-sh4-fpu/./sys/arch/sh3/include/mcontext.h --- src.orig/./sys/arch/sh3/include/mcontext.h 2008-06-05 23:46:01.000000000 +0900 +++ src-sh4-fpu/./sys/arch/sh3/include/mcontext.h 2009-07-08 22:41:43.000000000 +0900 @@ -65,9 +65,43 @@ /* Convenience synonym */ #define _REG_SP _REG_R15 +#define _REG_FPSCR 0 +#define _REG_FPUL 1 +#define _REG_FR0 2 +#define _REG_FR1 3 +#define _REG_FR2 4 +#define _REG_FR3 5 +#define _REG_FR4 6 +#define _REG_FR5 7 +#define _REG_FR6 8 +#define _REG_FR7 9 +#define _REG_FR8 10 +#define _REG_FR9 11 +#define _REG_FR10 12 +#define _REG_FR11 13 +#define _REG_FR12 14 +#define _REG_FR13 15 +#define _REG_FR14 16 +#define _REG_FR15 17 +#define _REG_FR16 18 +#define _REG_FR17 19 +#define _REG_FR18 20 +#define _REG_FR19 21 +#define _REG_FR20 22 +#define _REG_FR21 23 +#define _REG_FR22 24 +#define _REG_FR23 25 +#define _REG_FR24 26 +#define _REG_FR25 27 +#define _REG_FR26 28 +#define _REG_FR27 29 +#define _REG_FR28 30 +#define _REG_FR29 31 +#define _REG_FR30 32 +#define _REG_FR31 33 + /* * FPU state description. - * XXX: kernel doesn't support FPU yet, so this is just a placeholder. */ typedef struct { int __fpr_fpscr; diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./sys/arch/sh3/include/pcb.h src-sh4-fpu/./sys/arch/sh3/include/pcb.h --- src.orig/./sys/arch/sh3/include/pcb.h 2008-04-29 11:39:26.000000000 +0900 +++ src-sh4-fpu/./sys/arch/sh3/include/pcb.h 2009-07-11 03:56:21.000000000 +0900 @@ -33,12 +33,16 @@ #define _SH3_PCB_H_ #include +#include struct pcb { struct switchframe pcb_sf; /* kernel context for resume */ void * pcb_onfault; /* for copyin/out fault */ int pcb_faultbail; /* bail out before call uvm_fault. */ + struct cpu_info * pcb_fpcpu; /* CPU with our FP state */ + __fpregset_t pcb_fpu; /* floating point registers */ }; extern struct pcb *curpcb; + #endif /* !_SH3_PCB_H_ */ diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./sys/arch/sh3/include/proc.h src-sh4-fpu/./sys/arch/sh3/include/proc.h --- src.orig/./sys/arch/sh3/include/proc.h 2008-02-16 07:22:38.000000000 +0900 +++ src-sh4-fpu/./sys/arch/sh3/include/proc.h 2009-07-08 22:42:30.000000000 +0900 @@ -57,7 +57,7 @@ }; /* md_flags */ -#define MDP_USEDFPU 0x0001 /* has used the FPU */ +#define MDL_USEDFPU 0x0001 /* has used the FPU */ struct lwp; diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./sys/arch/sh3/include/psl.h src-sh4-fpu/./sys/arch/sh3/include/psl.h --- src.orig/./sys/arch/sh3/include/psl.h 2008-01-05 11:05:53.000000000 +0900 +++ src-sh4-fpu/./sys/arch/sh3/include/psl.h 2009-07-08 22:43:10.000000000 +0900 @@ -45,16 +45,17 @@ #define PSL_IMASK 0x000000f0 /* Interrupt Mask bit */ #define PSL_QBIT 0x00000100 /* Q bit */ #define PSL_MBIT 0x00000200 /* M bit */ +#define PSL_FDBIT 0x00008000 /* FD bit (SH4 only) */ #define PSL_BL 0x10000000 /* Exception Block bit */ #define PSL_RB 0x20000000 /* Register Bank bit */ #define PSL_MD 0x40000000 /* Processor Mode bit */ /* 1 = kernel, 0 = user */ #define PSL_MBO 0x00000000 /* must be one bits */ -#define PSL_MBZ 0x8ffffc0c /* must be zero bits */ +#define PSL_MBZ 0x8fff7c0c /* must be zero bits */ #define PSL_USERSET 0 -#define PSL_USERSTATIC (PSL_BL|PSL_RB|PSL_MD|PSL_IMASK|PSL_MBO|PSL_MBZ) +#define PSL_USERSTATIC (PSL_BL|PSL_RB|PSL_MD|PSL_FDBIT|PSL_IMASK|PSL_MBO|PSL_MBZ) #define KERNELMODE(sr) ((sr) & PSL_MD) diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./sys/arch/sh3/include/ptrace.h src-sh4-fpu/./sys/arch/sh3/include/ptrace.h --- src.orig/./sys/arch/sh3/include/ptrace.h 2008-10-30 11:36:05.000000000 +0900 +++ src-sh4-fpu/./sys/arch/sh3/include/ptrace.h 2009-07-08 22:44:09.000000000 +0900 @@ -43,14 +43,17 @@ #define PT_GETREGS (PT_FIRSTMACH + 3) #define PT_SETREGS (PT_FIRSTMACH + 4) +#define PT_GETFPREGS (PT_FIRSTMACH + 5) +#define PT_SETFPREGS (PT_FIRSTMACH + 6) #define PT_MACHDEP_STRINGS \ "(unused)", \ "PT___GETREGS40", \ "PT___SETREGS40", \ "PT_GETREGS", \ - "PT_SETREGS", - + "PT_SETREGS", \ + "PT_GETFPREGS", \ + "PT_SETFPREGS", #ifdef _KERNEL #ifdef _KERNEL_OPT diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./sys/arch/sh3/include/reg.h src-sh4-fpu/./sys/arch/sh3/include/reg.h --- src.orig/./sys/arch/sh3/include/reg.h 2008-10-30 11:36:05.000000000 +0900 +++ src-sh4-fpu/./sys/arch/sh3/include/reg.h 2009-07-09 20:52:23.000000000 +0900 @@ -129,4 +129,17 @@ int r_r0; }; + +/* + * Registers accessible to ptrace(2) syscall for debugger + * The machine-dependent code for PT_FP{SET,GET}REGS needs to + * use whichever order, defined above, is correct, so that it + * is all invisible to the user. + */ +struct fpreg { + int fpr_fpscr; + int fpr_fpul; + int fpr_fr[32]; +}; + #endif /* !_SH3_REG_H_ */ diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./sys/arch/sh3/sh3/exception.c src-sh4-fpu/./sys/arch/sh3/sh3/exception.c --- src.orig/./sys/arch/sh3/sh3/exception.c 2008-12-20 01:06:35.000000000 +0900 +++ src-sh4-fpu/./sys/arch/sh3/sh3/exception.c 2009-07-09 17:09:14.000000000 +0900 @@ -101,6 +101,7 @@ #include #include +#include #include #include #include @@ -219,6 +220,17 @@ ksi.ksi_addr = (void *)tf->tf_spc; goto trapsignal; + case EXPEVT_FPU_DISABLE | EXP_USER: /* FALLTHROUGH */ + case EXPEVT_FPU_SLOT_DISABLE | EXP_USER: + sh_fpu_enable(); + break; + + case EXPEVT_FPU | EXP_USER: + KSI_INIT_TRAP(&ksi); + if (sh_fpu_exception(l, tf, &ksi)) + goto do_panic; + goto trapsignal; + default: goto do_panic; } diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./sys/arch/sh3/sh3/fpu.c src-sh4-fpu/./sys/arch/sh3/sh3/fpu.c --- src.orig/./sys/arch/sh3/sh3/fpu.c 1970-01-01 09:00:00.000000000 +0900 +++ src-sh4-fpu/./sys/arch/sh3/sh3/fpu.c 2009-07-10 20:31:25.000000000 +0900 @@ -0,0 +1,66 @@ +/* $NetBSD$ */ + +/*- + * Copyright (c) 2009 The NetBSD Foundation, Inc. + * 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 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. + */ + +#include +__KERNEL_RCSID(0, "$NetBSD$"); + +#include +#include + +#include + +#if defined(SH3) && defined(SH4) +void (*__sh_fpu_enable)(void); +void (*__sh_fpu_save_lwp)(struct lwp *); +void (*__sh_fpu_exit_lwp)(struct lwp *, int); +int (*__sh_fpu_exception)(struct lwp *, struct trapframe *, struct ksiginfo *); +#endif /* SH3 && SH4 */ + +void +sh_fpu_init(void) +{ + + /* + * Assign function hooks but only if both SH3 and SH4 are defined. + * They are called directly otherwise. See . + */ +#if defined(SH3) && defined(SH4) + if (CPU_IS_SH3) { + __sh_fpu_enable = sh3_fpu_enable; + __sh_fpu_save_lwp = sh3_fpu_save_lwp; + __sh_fpu_exit_lwp = sh3_fpu_exit_lwp; + __sh_fpu_exception = sh3_fpu_exception; + } else if (CPU_IS_SH4) { + __sh_fpu_enable = sh4_fpu_enable; + __sh_fpu_save_lwp = sh4_fpu_save_lwp; + __sh_fpu_exit_lwp = sh4_fpu_exit_lwp; + __sh_fpu_exception = sh4_fpu_exception; + } else + panic("sh_fpu_init: unknown CPU type"); +#endif /* SH3 && SH4 */ +} diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./sys/arch/sh3/sh3/fpu_sh3.c src-sh4-fpu/./sys/arch/sh3/sh3/fpu_sh3.c --- src.orig/./sys/arch/sh3/sh3/fpu_sh3.c 1970-01-01 09:00:00.000000000 +0900 +++ src-sh4-fpu/./sys/arch/sh3/sh3/fpu_sh3.c 2009-07-10 20:32:04.000000000 +0900 @@ -0,0 +1,76 @@ +/* $NetBSD$ */ + +/*- + * Copyright (c) 2009 The NetBSD Foundation, Inc. + * 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 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. + */ + +#include +__KERNEL_RCSID(0, "$NetBSD$"); + +#include +#include +#include + +#include +#include + +/* + * SH3 FPU + */ + +void +sh3_fpu_enable(void) +{ + + /* Nothing to do. */ +} + +/*ARGSUSED*/ +void +sh3_fpu_save_lwp(struct lwp *l) +{ + + panic("sh3_fpu_save_lwp: not supported"); +} + +/*ARGSUSED*/ +void +sh3_fpu_exit_lwp(struct lwp *l, int clean) +{ + + panic("sh3_fpu_exit_lwp: not supported"); +} + +/*ARGSUSED*/ +int +sh3_fpu_exception(struct lwp *l, struct trapframe *tf, struct ksiginfo *ksi) +{ + + ksi->ksi_signo = SIGFPE; + ksi->ksi_code = FPE_FLTINV; + ksi->ksi_addr = (void *)tf->tf_spc; + + return 0; /* trapsignal */ +} diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./sys/arch/sh3/sh3/fpu_sh4.c src-sh4-fpu/./sys/arch/sh3/sh3/fpu_sh4.c --- src.orig/./sys/arch/sh3/sh3/fpu_sh4.c 1970-01-01 09:00:00.000000000 +0900 +++ src-sh4-fpu/./sys/arch/sh3/sh3/fpu_sh4.c 2009-07-10 20:52:10.000000000 +0900 @@ -0,0 +1,319 @@ +/* $NetBSD$ */ + +/*- + * Copyright (c) 2009 The NetBSD Foundation, Inc. + * 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 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. + */ + +#include +__KERNEL_RCSID(0, "$NetBSD$"); + +#include +#include +#include +#include + +#include + +#if defined(FPUDEBUG) +#define DPRINTF(s) printf s +#else +#define DPRINTF(s) +#endif + +static inline int +get_sr(void) +{ + int r; + + __asm volatile ("stc sr, %0" : "=r"(r)); + + return r; +} + +static inline void +set_sr(int r) +{ + + __asm volatile ("ldc %0, sr" :: "r"(r)); +} + +static void +sh4_fpu_save_regs(__fpregset_t *fp) +{ + int sr; + int fpscr; + + DPRINTF(("%s\n", __func__)); + + sr = get_sr(); + set_sr(sr & ~PSL_FDBIT); + + fpscr = get_fpscr(); + + /* save FPU register */ + set_fpscr((fpscr | FPSCR_FR) & ~FPSCR_SZ); + __asm volatile ( + "mov %0, r4\n\t" + "fmov.s fr15, @-r4\n\t" + "fmov.s fr14, @-r4\n\t" + "fmov.s fr13, @-r4\n\t" + "fmov.s fr12, @-r4\n\t" + "fmov.s fr11, @-r4\n\t" + "fmov.s fr10, @-r4\n\t" + "fmov.s fr9, @-r4\n\t" + "fmov.s fr8, @-r4\n\t" + "fmov.s fr7, @-r4\n\t" + "fmov.s fr6, @-r4\n\t" + "fmov.s fr5, @-r4\n\t" + "fmov.s fr4, @-r4\n\t" + "fmov.s fr3, @-r4\n\t" + "fmov.s fr2, @-r4\n\t" + "fmov.s fr1, @-r4\n\t" + "fmov.s fr0, @-r4\n\t" + "frchg\n\t" + "fmov.s fr15, @-r4\n\t" + "fmov.s fr14, @-r4\n\t" + "fmov.s fr13, @-r4\n\t" + "fmov.s fr12, @-r4\n\t" + "fmov.s fr11, @-r4\n\t" + "fmov.s fr10, @-r4\n\t" + "fmov.s fr9, @-r4\n\t" + "fmov.s fr8, @-r4\n\t" + "fmov.s fr7, @-r4\n\t" + "fmov.s fr6, @-r4\n\t" + "fmov.s fr5, @-r4\n\t" + "fmov.s fr4, @-r4\n\t" + "fmov.s fr3, @-r4\n\t" + "fmov.s fr2, @-r4\n\t" + "fmov.s fr1, @-r4\n\t" + "fmov.s fr0, @-r4" + :: "r"(&fp->__fpr_regs[32])); + + /* save FPU control register */ + fp->__fpr_fpul = get_fpul(); + fp->__fpr_fpscr = fpscr; + + set_fpscr(fpscr); + + set_sr(sr); +} + +static void +sh4_fpu_load_regs(__fpregset_t *fp) +{ + int sr; + int fpscr; + + DPRINTF(("%s\n", __func__)); + + sr = get_sr(); + set_sr(sr & ~PSL_FDBIT); + + fpscr = get_fpscr(); + + /* load FPU registers */ + set_fpscr(fpscr & ~(FPSCR_FR|FPSCR_SZ)); + __asm volatile ( + "mov %0, r4\n\t" + "fmov.s @r4+, fr0\n\t" + "fmov.s @r4+, fr1\n\t" + "fmov.s @r4+, fr2\n\t" + "fmov.s @r4+, fr3\n\t" + "fmov.s @r4+, fr4\n\t" + "fmov.s @r4+, fr5\n\t" + "fmov.s @r4+, fr6\n\t" + "fmov.s @r4+, fr7\n\t" + "fmov.s @r4+, fr8\n\t" + "fmov.s @r4+, fr9\n\t" + "fmov.s @r4+, fr10\n\t" + "fmov.s @r4+, fr11\n\t" + "fmov.s @r4+, fr12\n\t" + "fmov.s @r4+, fr13\n\t" + "fmov.s @r4+, fr14\n\t" + "fmov.s @r4+, fr15\n\t" + "frchg\n\t" + "fmov.s @r4+, fr0\n\t" + "fmov.s @r4+, fr1\n\t" + "fmov.s @r4+, fr2\n\t" + "fmov.s @r4+, fr3\n\t" + "fmov.s @r4+, fr4\n\t" + "fmov.s @r4+, fr5\n\t" + "fmov.s @r4+, fr6\n\t" + "fmov.s @r4+, fr7\n\t" + "fmov.s @r4+, fr8\n\t" + "fmov.s @r4+, fr9\n\t" + "fmov.s @r4+, fr10\n\t" + "fmov.s @r4+, fr11\n\t" + "fmov.s @r4+, fr12\n\t" + "fmov.s @r4+, fr13\n\t" + "fmov.s @r4+, fr14\n\t" + "fmov.s @r4+, fr15\n\t" + :: "r"(&fp->__fpr_regs[0])); + + /* load FPU control register */ + set_fpul(fp->__fpr_fpul); + set_fpscr(fp->__fpr_fpscr); + + set_sr(sr); +} + +/* + * Save current CPU's FPU state. + */ +static void +sh4_fpu_save_cpu(void) +{ + struct cpu_info *ci = curcpu(); + struct lwp *l; + struct pcb *pcb; + int s; + + DPRINTF(("%s: lwp=%p\n", __func__, ci->ci_fpulwp)); + + s = _cpu_intr_suspend(); + + l = ci->ci_fpulwp; + if (l == NULL) + goto out; + + pcb = &l->l_addr->u_pcb; + sh4_fpu_save_regs(&pcb->pcb_fpu); + + ci->ci_fpulwp->l_md.md_regs->tf_ssr |= PSL_FDBIT; + ci->ci_fpulwp = NULL; + pcb->pcb_fpcpu = NULL; +out: + _cpu_intr_resume(s); +} + +void +sh4_fpu_enable(void) +{ + struct cpu_info *ci = curcpu(); + struct lwp *l = curlwp; + struct pcb *pcb = &l->l_addr->u_pcb; + int s; + + DPRINTF(("%s: lwp=%p\n", __func__, l)); + + s = _cpu_intr_suspend(); + + if ((l->l_md.md_flags & MDL_USEDFPU) == 0) { + DPRINTF(("%s: !MDL_USEDFPU\n", __func__)); + memset(&pcb->pcb_fpu, 0, sizeof(pcb->pcb_fpu)); + pcb->pcb_fpu.__fpr_fpscr = SH4_FPSCR_INIT; + l->l_md.md_flags |= MDL_USEDFPU; + } + + /* + * If we own the CPU but FP is disabled, simply enable it and return. + */ + if (ci->ci_fpulwp == l) + goto out; + + if (ci->ci_fpulwp != NULL) + sh4_fpu_save_cpu(); + sh4_fpu_load_regs(&pcb->pcb_fpu); + + ci->ci_fpulwp = l; + pcb->pcb_fpcpu = ci; +out: + l->l_md.md_regs->tf_ssr &= ~PSL_FDBIT; + _cpu_intr_resume(s); +} + +void +sh4_fpu_save_lwp(struct lwp *l) +{ + struct cpu_info * const ci = curcpu(); + + DPRINTF(("%s: lwp=%p\n", __func__, l)); + + /* + * If the state is in the current CPU, + * just flush the current CPU's state. + */ + if (ci->ci_fpulwp == l) { + DPRINTF(("%s: do sh4_fpu_save_cpu\n", __func__)); + sh4_fpu_save_cpu(); + } +} + +void +sh4_fpu_exit_lwp(struct lwp *l, int clean) +{ + struct pcb *pcb = &l->l_addr->u_pcb; + + DPRINTF(("%s: lwp=%p, clean=%d\n", __func__, l, clean)); + + KASSERT(l == pcb->pcb_fpcpu->ci_fpulwp); + pcb->pcb_fpcpu->ci_fpulwp->l_md.md_regs->tf_ssr |= PSL_FDBIT; + pcb->pcb_fpcpu->ci_fpulwp = NULL; + pcb->pcb_fpcpu = NULL; + + if (clean) { + DPRINTF(("%s: do clean\n", __func__)); + /* Ensure we restart with a clean slate. */ + l->l_md.md_flags &= ~MDL_USEDFPU; + } +} + +int +sh4_fpu_exception(struct lwp *l, struct trapframe *tf, struct ksiginfo *ksi) +{ + static const int cause2sigcode[6] = { + FPE_FLTRES, /* FP_I_BIT */ + FPE_FLTUND, /* FP_U_BIT */ + FPE_FLTOVF, /* FP_O_BIT */ + FPE_FLTDIV, /* FP_Z_BIT */ + FPE_FLTINV, /* FP_V_BIT */ + FPE_FLTRES /* FP_E_BIT */ + }; + int fpscr; + int cause; + int i; + + fpscr = get_fpscr(); + + cause = FP_CAUSE(fpscr); + cause &= FP_ENABLE(fpscr) | FP_E_BIT; + + DPRINTF(("fpscr = 0x%x, cause = 0x%x\n", fpscr, cause)); + + ksi->ksi_signo = SIGFPE; + ksi->ksi_addr = (void *)tf->tf_spc; + + for (i = 0; i < __arraycount(cause2sigcode); i++) { + if (cause & (1 << i)) { + ksi->ksi_code = cause2sigcode[i]; + break; + } + } + if (i == __arraycount(cause2sigcode)) { + ksi->ksi_code = FPE_FLTINV; + } + + return 0; /* trapsignal */ +} diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./sys/arch/sh3/sh3/process_machdep.c src-sh4-fpu/./sys/arch/sh3/sh3/process_machdep.c --- src.orig/./sys/arch/sh3/sh3/process_machdep.c 2008-10-30 11:36:05.000000000 +0900 +++ src-sh4-fpu/./sys/arch/sh3/sh3/process_machdep.c 2009-07-08 23:10:21.000000000 +0900 @@ -88,6 +88,7 @@ #include #include +#include #include #include @@ -142,6 +143,27 @@ return (0); } +int +process_read_fpregs(struct lwp *l, struct fpreg *fpregs) +{ + __fpregset_t *fp; + int i; + + if (CPU_HAS_FPU) { + fp = &l->l_md.md_pcb->pcb_fpu; + + fpregs->fpr_fpscr = fp->__fpr_fpscr; + fpregs->fpr_fpul = fp->__fpr_fpul; + for (i = 0; i < __arraycount(fpregs->fpr_fr); i++) { + fpregs->fpr_fr[i] = fp->__fpr_regs[i]; + } + } else { + memset(fpregs, 0, sizeof(struct fpreg)); + } + + return (0); +} + #endif /* PTRACE || COREDUMP */ @@ -186,6 +208,24 @@ return (0); } +int +process_write_fpregs(struct lwp *l, const struct fpreg *fpregs) +{ + __fpregset_t *fp; + int i; + + if (CPU_HAS_FPU) { + fp = &l->l_md.md_pcb->pcb_fpu; + + fp->__fpr_fpscr = fpregs->fpr_fpscr; + fp->__fpr_fpul = fpregs->fpr_fpul; + for (i = 0; i < __arraycount(fp->__fpr_regs); i++) { + fp->__fpr_regs[i] = fpregs->fpr_fr[i]; + } + } + + return (0); +} #ifdef __HAVE_PTRACE_MACHDEP diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./sys/arch/sh3/sh3/sh3_machdep.c src-sh4-fpu/./sys/arch/sh3/sh3/sh3_machdep.c --- src.orig/./sys/arch/sh3/sh3/sh3_machdep.c 2009-03-21 18:58:59.000000000 +0900 +++ src-sh4-fpu/./sys/arch/sh3/sh3/sh3_machdep.c 2009-07-11 03:06:54.000000000 +0900 @@ -101,6 +101,7 @@ #include #include #include +#include #include #include #include @@ -160,6 +161,9 @@ /* MMU access ops. */ sh_mmu_init(); + /* FPU access ops. */ + sh_fpu_init(); + /* Hardclock, RTC initialize. */ machine_clock_init(); @@ -414,6 +418,7 @@ cpu_getmcontext(struct lwp *l, mcontext_t *mcp, unsigned int *flags) { const struct trapframe *tf = l->l_md.md_regs; + const struct pcb *pcb = &l->l_addr->u_pcb; __greg_t *gr = mcp->__gregs; __greg_t ras_pc; @@ -447,14 +452,21 @@ *flags |= _UC_CPU; - /* FPU context is currently not handled by the kernel. */ - memset(&mcp->__fpregs, 0, sizeof (mcp->__fpregs)); + if ((l->l_md.md_flags & MDL_USEDFPU) != 0) { + if (pcb->pcb_fpcpu) { + sh_fpu_save_lwp(l); + } + memcpy(&mcp->__fpregs, &pcb->pcb_fpu, sizeof(mcp->__fpregs)); + *flags |= _UC_FPU; + } else + memset(&mcp->__fpregs, 0, sizeof(mcp->__fpregs)); } int cpu_setmcontext(struct lwp *l, const mcontext_t *mcp, unsigned int flags) { struct trapframe *tf = l->l_md.md_regs; + struct pcb *pcb = &l->l_addr->u_pcb; const __greg_t *gr = mcp->__gregs; struct proc *p = l->l_proc; @@ -488,12 +500,12 @@ tf->tf_r15 = gr[_REG_R15]; } -#if 0 - /* XXX: FPU context is currently not handled by the kernel. */ - if (flags & _UC_FPU) { - /* TODO */; + if ((flags & _UC_FPU) != 0) { + if (pcb->pcb_fpcpu) { + sh_fpu_exit_lwp(l, false); + } + memcpy(&pcb->pcb_fpu, &mcp->__fpregs, sizeof(pcb->pcb_fpu)); } -#endif mutex_enter(p->p_lock); if (flags & _UC_SETSTACK) @@ -513,11 +525,13 @@ { struct trapframe *tf; - l->l_md.md_flags &= ~MDP_USEDFPU; + l->l_md.md_flags &= ~MDL_USEDFPU; tf = l->l_md.md_regs; tf->tf_ssr = PSL_USERSET; + if (CPU_HAS_FPU) + tf->tf_ssr |= PSL_FDBIT; /* disable FPU */ tf->tf_spc = pack->ep_entry; tf->tf_pr = 0; diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./sys/arch/sh3/sh3/vm_machdep.c src-sh4-fpu/./sys/arch/sh3/sh3/vm_machdep.c --- src.orig/./sys/arch/sh3/sh3/vm_machdep.c 2008-11-22 06:15:53.000000000 +0900 +++ src-sh4-fpu/./sys/arch/sh3/sh3/vm_machdep.c 2009-07-11 03:55:34.000000000 +0900 @@ -102,6 +102,7 @@ #include #include +#include #include #include #include @@ -135,12 +136,25 @@ cpu_lwp_fork(struct lwp *l1, struct lwp *l2, void *stack, size_t stacksize, void (*func)(void *), void *arg) { + struct pcb *pcb = &l2->l_addr->u_pcb; struct switchframe *sf; #if 0 /* FIXME: probably wrong for yamt-idlelwp */ KDASSERT(l1 == curlwp || l1 == &lwp0); #endif + /* + * If fpuproc != p1, then the fpu h/w state is irrelevant and the + * state had better already be in the pcb. This is true for forks + * but not for dumps. + * + * If fpuproc == p1, then we have to save the fpu h/w state to + * p1's pcb so that we can copy it. + */ + if (l1->l_addr->u_pcb.pcb_fpcpu) { + sh_fpu_save_lwp(l1); + } + sh3_setup_uarea(l2); l2->l_md.md_flags = l1->l_md.md_flags; @@ -151,6 +165,10 @@ if (stack != NULL) l2->l_md.md_regs->tf_r15 = (u_int)stack + stacksize; + /* Copy FPU context */ + pcb->pcb_fpcpu = l1->l_addr->u_pcb.pcb_fpcpu; + memcpy(&pcb->pcb_fpu, &l1->l_addr->u_pcb.pcb_fpu, sizeof(pcb->pcb_fpu)); + /* When l2 is switched to, jump to the trampoline */ sf = &l2->l_md.md_pcb->pcb_sf; sf->sf_pr = (int)lwp_trampoline; @@ -175,6 +193,8 @@ sh3_setup_uarea(l); l->l_md.md_regs->tf_ssr = PSL_USERSET; + if (CPU_HAS_FPU) + l->l_md.md_regs->tf_ssr |= PSL_FDBIT; /* disable FPU */ /* When lwp is switched to, jump to the trampoline */ sf = &l->l_md.md_pcb->pcb_sf; @@ -293,18 +313,23 @@ /* - * Exit hook + * cpu_lwp_free is called from exit() to let machine-dependent + * code free machine-dependent resources. Note that this routine + * must not block. */ void cpu_lwp_free(struct lwp *l, int proc) { - /* Nothing to do */ + /* If we were using the FPU, forget about it. */ + if (l->l_addr->u_pcb.pcb_fpcpu) { + sh_fpu_exit_lwp(l, true); + } } - /* - * lwp_free() hook + * cpu_lwp_free2 is called when an LWP is being reaped. + * This routine may block. */ void cpu_lwp_free2(struct lwp *l)