diff options
author | 2007-03-02 06:11:52 +0000 | |
---|---|---|
committer | 2007-03-02 06:11:52 +0000 | |
commit | 243b5df446d5f4ce83bb376b1240a8a96ea22b23 (patch) | |
tree | dd88f5cc1fce930b7242a301dc74fdfff077b32c | |
parent | Sync rcsnum.c with OpenCVS, from Charles Longeau. (diff) | |
download | wireguard-openbsd-243b5df446d5f4ce83bb376b1240a8a96ea22b23.tar.xz wireguard-openbsd-243b5df446d5f4ce83bb376b1240a8a96ea22b23.zip |
Move landisk to hardware floating point. At the moment the FPU context is
always saved upon context switches, as FPU registers are heavily used for
long long computations (don't ask). Gcc default to -m4.
Credits to drahn@ otto@ and deraadt@ for feedback and help testing.
Upgrade procedure if you don't want to use the damn snapshots:
- build and install new kernel, reboot off it
- build new gcc, do not install it yet
- make includes
- install new gcc
- build and install lib/csu and lib/libc
- make build
27 files changed, 767 insertions, 293 deletions
diff --git a/gnu/usr.bin/gcc/gcc/config/sh/openbsd.h b/gnu/usr.bin/gcc/gcc/config/sh/openbsd.h index ce6af42e356..3d838d391d8 100644 --- a/gnu/usr.bin/gcc/gcc/config/sh/openbsd.h +++ b/gnu/usr.bin/gcc/gcc/config/sh/openbsd.h @@ -22,6 +22,9 @@ Boston, MA 02111-1307, USA. */ /* Get generic OpenBSD definitions. */ #include <openbsd.h> +#undef TARGET_CPU_DEFAULT +#define TARGET_CPU_DEFAULT SELECT_SH4 + #undef TARGET_DEFAULT #define TARGET_DEFAULT \ (TARGET_CPU_DEFAULT | USERMODE_BIT | TARGET_ENDIAN_DEFAULT) diff --git a/gnu/usr.bin/gcc/gcc/config/sh/t-openbsd b/gnu/usr.bin/gcc/gcc/config/sh/t-openbsd index 10e5077bdeb..e86e26fead9 100644 --- a/gnu/usr.bin/gcc/gcc/config/sh/t-openbsd +++ b/gnu/usr.bin/gcc/gcc/config/sh/t-openbsd @@ -1,5 +1,4 @@ -#TARGET_LIBGCC2_CFLAGS = -fpic -TARGET_LIBGCC2_CFLAGS = +TARGET_LIBGCC2_CFLAGS = -fpic LIB1ASMFUNCS_CACHE = _ic_invalidate LIB2FUNCS_EXTRA= diff --git a/lib/csu/sh/crt0.c b/lib/csu/sh/crt0.c index 1950cc9bf66..01be7a702a5 100644 --- a/lib/csu/sh/crt0.c +++ b/lib/csu/sh/crt0.c @@ -1,4 +1,4 @@ -/* $OpenBSD: crt0.c,v 1.1.1.1 2006/10/10 22:07:10 miod Exp $ */ +/* $OpenBSD: crt0.c,v 1.2 2007/03/02 06:11:54 miod Exp $ */ /* $NetBSD: crt0.c,v 1.10 2004/08/26 21:16:41 thorpej Exp $ */ /* @@ -76,6 +76,14 @@ ___start(int argc, char **argv, char **envp, void *ps_strings, { char *s; +#if defined(__SH4__) && !defined(__SH4_NOFPU__) + extern void __set_fpscr(unsigned int); + extern unsigned int __fpscr_values[2]; + + __set_fpscr(0); + __asm__ __volatile__ ("lds %0, fpscr" : : "r" (__fpscr_values[1])); +#endif + environ = envp; if ((__progname = argv[0]) != NULL) { /* NULL ptr if argc = 0 */ diff --git a/lib/libc/arch/sh/Makefile.inc b/lib/libc/arch/sh/Makefile.inc index c66a4959bb4..69a13eed486 100644 --- a/lib/libc/arch/sh/Makefile.inc +++ b/lib/libc/arch/sh/Makefile.inc @@ -1,6 +1 @@ -# $OpenBSD: Makefile.inc,v 1.3 2006/11/07 17:38:49 drahn Exp $ - -CPPFLAGS += -DSOFTFLOAT - -SOFTFLOAT_BITS=32 -.include <arch/sh/softfloat/Makefile.inc> +# $OpenBSD: Makefile.inc,v 1.4 2007/03/02 06:11:54 miod Exp $ diff --git a/lib/libc/arch/sh/gen/Makefile.inc b/lib/libc/arch/sh/gen/Makefile.inc index fb4af29eb92..8616cd7fff9 100644 --- a/lib/libc/arch/sh/gen/Makefile.inc +++ b/lib/libc/arch/sh/gen/Makefile.inc @@ -1,8 +1,7 @@ -# $OpenBSD: Makefile.inc,v 1.4 2006/11/06 15:14:50 drahn Exp $ +# $OpenBSD: Makefile.inc,v 1.5 2007/03/02 06:11:54 miod Exp $ SRCS+= flt_rounds.c isinf.c isnan.c infinity.c setjmp.S _setjmp.S sigsetjmp.S \ modf.c ldexp.c -#hardfloat only pieces -#SRCS+= fabs.c fpgetmask.c fpgetround.c fpgetsticky.c \ -# fpsetmask.c fpsetround.c fpsetsticky.c \ +SRCS+= fabs.c fpgetmask.c fpgetround.c fpgetsticky.c \ + fpsetmask.c fpsetround.c fpsetsticky.c diff --git a/lib/libc/arch/sh/gen/_setjmp.S b/lib/libc/arch/sh/gen/_setjmp.S index 3097458cbcb..a04fcb6cfb7 100644 --- a/lib/libc/arch/sh/gen/_setjmp.S +++ b/lib/libc/arch/sh/gen/_setjmp.S @@ -1,4 +1,4 @@ -/* $OpenBSD: _setjmp.S,v 1.1.1.1 2006/10/10 22:07:10 miod Exp $ */ +/* $OpenBSD: _setjmp.S,v 1.2 2007/03/02 06:11:54 miod Exp $ */ /* $NetBSD: _setjmp.S,v 1.7 2006/01/05 02:04:41 uwe Exp $ */ /*- @@ -49,37 +49,76 @@ */ ENTRY(_setjmp) - add #((_JB_HAS_MASK + 1) * 4), r4 - mov #0, r0 - mov.l r0, @-r4 /* no saved signal mask */ - mov.l r15, @-r4 - mov.l r14, @-r4 - mov.l r13, @-r4 - mov.l r12, @-r4 - mov.l r11, @-r4 - mov.l r10, @-r4 - mov.l r9, @-r4 - mov.l r8, @-r4 - sts.l pr, @-r4 + xor r0, r0 +#if defined(__SH4__) && !defined(__SH4_NOFPU__) + add #(_JBLEN * 4), r4 + sts fpscr, r1 + mov.l r1, @-r4 + lds r0, fpscr + sts.l fpul, @-r4 + fmov.s fr15, @-r4 + fmov.s fr14, @-r4 + fmov.s fr13, @-r4 + fmov.s fr12, @-r4 + frchg + fmov.s fr15, @-r4 + fmov.s fr14, @-r4 + fmov.s fr13, @-r4 + fmov.s fr12, @-r4 + lds r1, fpscr +#else + add #((_JBLEN - 10) * 4), r4 +#endif + sts.l mach, @-r4 + sts.l macl, @-r4 + mov.l r15, @-r4 + mov.l r14, @-r4 + mov.l r13, @-r4 + mov.l r12, @-r4 + mov.l r11, @-r4 + mov.l r10, @-r4 + mov.l r9, @-r4 + mov.l r8, @-r4 + sts.l pr, @-r4 + mov.l r0, @-r4 /* dummy signal mask */ rts - xor r0, r0 + mov.l r0, @-r4 /* no saved signal mask */ SET_ENTRY_SIZE(_setjmp) ENTRY(_longjmp) - lds.l @r4+, pr - mov.l @r4+, r8 - mov.l @r4+, r9 - mov.l @r4+, r10 - mov.l @r4+, r11 - mov.l @r4+, r12 - mov.l @r4+, r13 - mov.l @r4+, r14 - mov.l @r4+, r15 + add #8, r4 + lds.l @r4+, pr + mov.l @r4+, r8 + mov.l @r4+, r9 + mov.l @r4+, r10 + mov.l @r4+, r11 + mov.l @r4+, r12 + mov.l @r4+, r13 + mov.l @r4+, r14 + mov.l @r4+, r15 + lds.l @r4+, macl + lds.l @r4+, mach +#if defined(__SH4__) && !defined(__SH4_NOFPU__) + xor r0, r0 + lds r0, fpscr + frchg + fmov.s @r4+, fr12 + fmov.s @r4+, fr13 + fmov.s @r4+, fr14 + fmov.s @r4+, fr15 + frchg + fmov.s @r4+, fr12 + fmov.s @r4+, fr13 + fmov.s @r4+, fr14 + fmov.s @r4+, fr15 + lds.l @r4+, fpul + lds.l @r4+, fpscr +#endif - mov r5, r0 - tst r0, r0 + mov r5, r0 + tst r0, r0 bf .L0 - add #1, r0 + add #1, r0 .L0: rts nop diff --git a/lib/libc/arch/sh/gen/fabs.c b/lib/libc/arch/sh/gen/fabs.c index b31405a29d5..116e8b4139a 100644 --- a/lib/libc/arch/sh/gen/fabs.c +++ b/lib/libc/arch/sh/gen/fabs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fabs.c,v 1.2 2006/11/06 15:14:50 drahn Exp $ */ +/* $OpenBSD: fabs.c,v 1.3 2007/03/02 06:11:54 miod Exp $ */ /* * Copyright (c) 2006 Miodrag Vallat. * @@ -21,7 +21,7 @@ double fabs(double x) { -#ifdef __SH4__ +#if defined(__SH4__) && !defined(__SH4_NOFPU__) __asm__ __volatile__("fabs %0" : "=f"(x)); #else if (x < 0) diff --git a/lib/libc/arch/sh/gen/fpsetmask.c b/lib/libc/arch/sh/gen/fpsetmask.c index 582204eb0c1..122d9d36e70 100644 --- a/lib/libc/arch/sh/gen/fpsetmask.c +++ b/lib/libc/arch/sh/gen/fpsetmask.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fpsetmask.c,v 1.1.1.1 2006/10/10 22:07:10 miod Exp $ */ +/* $OpenBSD: fpsetmask.c,v 1.2 2007/03/02 06:11:54 miod Exp $ */ /* * Copyright (c) 2006 Miodrag Vallat. * @@ -23,7 +23,12 @@ fp_except fpsetmask(fp_except mask) { register_t fpscr, nfpscr; +#if defined(__SH4__) && !defined(__SH4_NOFPU__) + extern register_t __fpscr_values[2]; + __fpscr_values[0] = (__fpscr_values[0] & ~(0x1f << 7)) | (mask << 7); + __fpscr_values[1] = (__fpscr_values[1] & ~(0x1f << 7)) | (mask << 7); +#endif __asm__ __volatile__ ("sts fpscr, %0" : "=r" (fpscr)); nfpscr = (fpscr & ~(0x1f << 7)) | (mask << 7); __asm__ __volatile__ ("lds %0, fpscr" : : "r" (nfpscr)); diff --git a/lib/libc/arch/sh/gen/fpsetround.c b/lib/libc/arch/sh/gen/fpsetround.c index 08e6886b6e7..9090f647fce 100644 --- a/lib/libc/arch/sh/gen/fpsetround.c +++ b/lib/libc/arch/sh/gen/fpsetround.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fpsetround.c,v 1.1.1.1 2006/10/10 22:07:10 miod Exp $ */ +/* $OpenBSD: fpsetround.c,v 1.2 2007/03/02 06:11:54 miod Exp $ */ /* * Copyright (c) 2006 Miodrag Vallat. * @@ -23,10 +23,17 @@ fp_rnd fpsetround(fp_rnd rnd_dir) { register_t fpscr, nfpscr; +#if defined(__SH4__) && !defined(__SH4_NOFPU__) + extern register_t __fpscr_values[2]; +#endif __asm__ __volatile__ ("sts fpscr, %0" : "=r" (fpscr)); if (rnd_dir == FP_RN || rnd_dir == FP_RZ) { nfpscr = (fpscr & ~0x03) | rnd_dir; +#if defined(__SH4__) && !defined(__SH4_NOFPU__) + __fpscr_values[0] = (__fpscr_values[0] & ~0x03) | rnd_dir; + __fpscr_values[1] = (__fpscr_values[1] & ~0x03) | rnd_dir; +#endif __asm__ __volatile__ ("lds %0, fpscr" : : "r" (nfpscr)); } /* else how report an error? */ diff --git a/lib/libc/arch/sh/gen/fpsetsticky.c b/lib/libc/arch/sh/gen/fpsetsticky.c index 019de84f853..09f13bb94b5 100644 --- a/lib/libc/arch/sh/gen/fpsetsticky.c +++ b/lib/libc/arch/sh/gen/fpsetsticky.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fpsetsticky.c,v 1.1.1.1 2006/10/10 22:07:10 miod Exp $ */ +/* $OpenBSD: fpsetsticky.c,v 1.2 2007/03/02 06:11:54 miod Exp $ */ /* * Copyright (c) 2006 Miodrag Vallat. * @@ -23,7 +23,12 @@ fp_except fpsetsticky(fp_except mask) { register_t fpscr, nfpscr; +#if defined(__SH4__) && !defined(__SH4_NOFPU__) + extern register_t __fpscr_values[2]; + __fpscr_values[0] = (__fpscr_values[0] & ~(0x1f << 2)) | (mask << 2); + __fpscr_values[1] = (__fpscr_values[1] & ~(0x1f << 2)) | (mask << 2); +#endif __asm__ __volatile__ ("sts fpscr, %0" : "=r" (fpscr)); nfpscr = (fpscr & ~(0x1f << 2)) | (mask << 2); __asm__ __volatile__ ("lds %0, fpscr" : : "r" (nfpscr)); diff --git a/lib/libc/arch/sh/gen/setjmp.S b/lib/libc/arch/sh/gen/setjmp.S index 3f3dd5c74eb..67f33974420 100644 --- a/lib/libc/arch/sh/gen/setjmp.S +++ b/lib/libc/arch/sh/gen/setjmp.S @@ -1,4 +1,4 @@ -/* $OpenBSD: setjmp.S,v 1.1.1.1 2006/10/10 22:07:10 miod Exp $ */ +/* $OpenBSD: setjmp.S,v 1.2 2007/03/02 06:11:54 miod Exp $ */ /* $NetBSD: setjmp.S,v 1.10 2006/01/05 19:21:37 uwe Exp $ */ /*- @@ -50,73 +50,113 @@ ENTRY(setjmp) PIC_PROLOGUE(.L_got_1) - sts.l pr, @-sp - mov.l r4, @-sp + sts.l pr, @-sp + mov.l r4, @-sp mov.l .L_sigprocmask_1, r0 - mov r4, r6 - mov #1, r4 /* how = SIG_BLOCK */ - mov #0, r5 /* new = NULL */ + mov r4, r6 + mov #1, r4 /* how = SIG_BLOCK */ + mov #0, r5 /* new = NULL */ 1: CALL r0 - add #(_JB_SIGMASK * 4), r6 /* old = &sigmask */ + add #4, r6 /* old = &sigmask */ - mov.l @sp+, r4 - lds.l @sp+, pr + mov.l @sp+, r4 + lds.l @sp+, pr PIC_EPILOGUE - /* identical to _setjmp except that _JB_HAS_MASK is non-zero */ - add #((_JB_HAS_MASK + 1) * 4), r4 - mov #1, r0 - mov.l r0, @-r4 /* has signal mask */ - mov.l r15, @-r4 - mov.l r14, @-r4 - mov.l r13, @-r4 - mov.l r12, @-r4 - mov.l r11, @-r4 - mov.l r10, @-r4 - mov.l r9, @-r4 - mov.l r8, @-r4 - sts.l pr, @-r4 + /* identical to _setjmp except that the first word is non-zero */ +#if defined(__SH4__) && !defined(__SH4_NOFPU__) + add #(_JBLEN * 4), r4 + sts fpscr, r1 + xor r0, r0 + mov.l r1, @-r4 + lds r0, fpscr + sts.l fpul, @-r4 + fmov.s fr15, @-r4 + fmov.s fr14, @-r4 + fmov.s fr13, @-r4 + fmov.s fr12, @-r4 + frchg + fmov.s fr15, @-r4 + fmov.s fr14, @-r4 + fmov.s fr13, @-r4 + fmov.s fr12, @-r4 + lds r1, fpscr +#else + add #((_JBLEN - 10) * 4), r4 +#endif + sts.l mach, @-r4 + sts.l macl, @-r4 + mov.l r15, @-r4 + mov.l r14, @-r4 + mov.l r13, @-r4 + mov.l r12, @-r4 + mov.l r11, @-r4 + mov.l r10, @-r4 + mov.l r9, @-r4 + mov.l r8, @-r4 + sts.l pr, @-r4 + add #-4, r4 /* skip signal mask */ + mov #1, r0 + mov.l r0, @-r4 /* has signal mask */ rts - xor r0, r0 + xor r0, r0 .align 2 .L_got_1: PIC_GOT_DATUM .L_sigprocmask_1: CALL_DATUM(_C_LABEL(sigprocmask), 1b) SET_ENTRY_SIZE(setjmp) - ENTRY(longjmp) /* we won't return here, so we don't need to save pr and r12 */ PIC_PROLOGUE_NOSAVE(.L_got_2) - mov.l r5, @-sp - mov.l r4, @-sp + mov.l r5, @-sp + mov.l r4, @-sp mov.l .L_sigprocmask_2, r0 - mov r4, r5 - mov #3, r4 /* how = SIG_SETMASK */ - add #(_JB_SIGMASK * 4), r5 /* new = &sigmask */ + mov r4, r5 + mov #3, r4 /* how = SIG_SETMASK */ + add #4, r5 /* new = &sigmask */ 1: CALL r0 - mov #0, r6 /* old = NULL */ + mov #0, r6 /* old = NULL */ - mov.l @sp+, r4 - mov.l @sp+, r5 + mov.l @sp+, r4 + mov.l @sp+, r5 /* identical to _longjmp */ - lds.l @r4+, pr - mov.l @r4+, r8 - mov.l @r4+, r9 - mov.l @r4+, r10 - mov.l @r4+, r11 - mov.l @r4+, r12 - mov.l @r4+, r13 - mov.l @r4+, r14 - mov.l @r4+, r15 + add #8, r4 + lds.l @r4+, pr + mov.l @r4+, r8 + mov.l @r4+, r9 + mov.l @r4+, r10 + mov.l @r4+, r11 + mov.l @r4+, r12 + mov.l @r4+, r13 + mov.l @r4+, r14 + mov.l @r4+, r15 + lds.l @r4+, macl + lds.l @r4+, mach +#if defined(__SH4__) && !defined(__SH4_NOFPU__) + xor r0, r0 + lds r0, fpscr + frchg + fmov.s @r4+, fr12 + fmov.s @r4+, fr13 + fmov.s @r4+, fr14 + fmov.s @r4+, fr15 + frchg + fmov.s @r4+, fr12 + fmov.s @r4+, fr13 + fmov.s @r4+, fr14 + fmov.s @r4+, fr15 + lds.l @r4+, fpul + lds.l @r4+, fpscr +#endif - mov r5, r0 - tst r0, r0 /* make sure return value is non-zero */ + mov r5, r0 + tst r0, r0 /* make sure return value is non-zero */ bf .L0 - add #1, r0 + add #1, r0 .L0: rts nop diff --git a/lib/libc/arch/sh/gen/sigsetjmp.S b/lib/libc/arch/sh/gen/sigsetjmp.S index f1f6804d04c..f88913a73f1 100644 --- a/lib/libc/arch/sh/gen/sigsetjmp.S +++ b/lib/libc/arch/sh/gen/sigsetjmp.S @@ -1,4 +1,4 @@ -/* $OpenBSD: sigsetjmp.S,v 1.1.1.1 2006/10/10 22:07:10 miod Exp $ */ +/* $OpenBSD: sigsetjmp.S,v 1.2 2007/03/02 06:11:54 miod Exp $ */ /* $NetBSD: sigsetjmp.S,v 1.9 2006/01/05 19:21:37 uwe Exp $ */ /*- @@ -39,84 +39,123 @@ #include <machine/setjmp.h> ENTRY(sigsetjmp) - tst r5, r5 - bt 2f /* if (savemask == 0) */ + tst r5, r5 /* if (savemask == 0) */ + bt 2f - /* identical to longjmp except that _JB_HAS_MASK is in the argument */ + /* identical to setjmp */ PIC_PROLOGUE(.L_got_1) - sts.l pr, @-sp - mov.l r4, @-sp - mov.l r5, @-sp + sts.l pr, @-sp + mov.l r4, @-sp + mov.l r5, @-sp mov.l .L_sigprocmask_1, r0 - mov r4, r6 - mov #1, r4 /* how = SIG_BLOCK */ - mov #0, r5 /* new = NULL */ + mov r4, r6 + mov #1, r4 /* how = SIG_BLOCK */ + mov #0, r5 /* new = NULL */ 1: CALL r0 - add #(_JB_SIGMASK * 4), r6 /* old = &sigmask */ + add #4, r6 /* old = &sigmask */ - mov.l @sp+, r5 - mov.l @sp+, r4 - lds.l @sp+, pr + mov.l @sp+, r5 + mov.l @sp+, r4 + lds.l @sp+, pr PIC_EPILOGUE -2: /* identical to _setjmp except that _JB_HAS_MASK is in the argument */ - add #((_JB_HAS_MASK + 1) * 4), r4 - mov.l r5, @-r4 /* has signal mask? */ - mov.l r15, @-r4 - mov.l r14, @-r4 - mov.l r13, @-r4 - mov.l r12, @-r4 - mov.l r11, @-r4 - mov.l r10, @-r4 - mov.l r9, @-r4 - mov.l r8, @-r4 - sts.l pr, @-r4 +2: /* identical to _setjmp except that first word is in r5 */ +#if defined(__SH4__) && !defined(__SH4_NOFPU__) + add #(_JBLEN * 4), r4 + sts fpscr, r1 + xor r0, r0 + mov.l r1, @-r4 + lds r0, fpscr + sts.l fpul, @-r4 + fmov.s fr15, @-r4 + fmov.s fr14, @-r4 + fmov.s fr13, @-r4 + fmov.s fr12, @-r4 + frchg + fmov.s fr15, @-r4 + fmov.s fr14, @-r4 + fmov.s fr13, @-r4 + fmov.s fr12, @-r4 + lds r1, fpscr +#else + add #((_JBLEN - 10) * 4), r4 +#endif + sts.l mach, @-r4 + sts.l macl, @-r4 + mov.l r15, @-r4 + mov.l r14, @-r4 + mov.l r13, @-r4 + mov.l r12, @-r4 + mov.l r11, @-r4 + mov.l r10, @-r4 + mov.l r9, @-r4 + mov.l r8, @-r4 + sts.l pr, @-r4 + add #-4, r4 /* skip signal mask */ + mov.l r5, @-r4 /* has signal mask? */ rts - xor r0, r0 + xor r0, r0 .align 2 .L_got_1: PIC_GOT_DATUM .L_sigprocmask_1: CALL_DATUM(_C_LABEL(sigprocmask), 1b) SET_ENTRY_SIZE(sigsetjmp) - ENTRY(siglongjmp) - mov.l @(_JB_HAS_MASK * 4, r4), r0 - tst r0, r0 + mov.l @r4+, r0 + tst r0, r0 bt 2f /* if no mask */ /* identical to longjmp */ /* we won't return here, so we don't need to save pr and r12 */ PIC_PROLOGUE_NOSAVE(.L_got_2) - mov.l r5, @-sp - mov.l r4, @-sp + mov.l r5, @-sp + mov.l r4, @-sp mov.l .L_sigprocmask_2, r0 - mov r4, r5 - mov #3, r4 /* how = SIG_SETMASK */ - add #(_JB_SIGMASK * 4), r5 /* new = &sigmask */ + mov r4, r5 /* new = &sigmask */ + mov #3, r4 /* how = SIG_SETMASK */ 1: CALL r0 - mov #0, r6 /* old = NULL */ + mov #0, r6 /* old = NULL */ - mov.l @sp+, r4 - mov.l @sp+, r5 + mov.l @sp+, r4 + mov.l @sp+, r5 2: /* identical to _longjmp */ - lds.l @r4+, pr - mov.l @r4+, r8 - mov.l @r4+, r9 - mov.l @r4+, r10 - mov.l @r4+, r11 - mov.l @r4+, r12 - mov.l @r4+, r13 - mov.l @r4+, r14 - mov.l @r4+, r15 - - mov r5, r0 - tst r0, r0 /* make sure return value is non-zero */ + add #4, r4 + lds.l @r4+, pr + mov.l @r4+, r8 + mov.l @r4+, r9 + mov.l @r4+, r10 + mov.l @r4+, r11 + mov.l @r4+, r12 + mov.l @r4+, r13 + mov.l @r4+, r14 + mov.l @r4+, r15 + lds.l @r4+, macl + lds.l @r4+, mach +#if defined(__SH4__) && !defined(__SH4_NOFPU__) + xor r0, r0 + lds r0, fpscr + frchg + fmov.s @r4+, fr12 + fmov.s @r4+, fr13 + fmov.s @r4+, fr14 + fmov.s @r4+, fr15 + frchg + fmov.s @r4+, fr12 + fmov.s @r4+, fr13 + fmov.s @r4+, fr14 + fmov.s @r4+, fr15 + lds.l @r4+, fpul + lds.l @r4+, fpscr +#endif + + mov r5, r0 + tst r0, r0 /* make sure return value is non-zero */ bf .L0 - add #1, r0 + add #1, r0 .L0: rts nop diff --git a/lib/libpthread/arch/sh/uthread_machdep.c b/lib/libpthread/arch/sh/uthread_machdep.c index 675b4ce89c4..b507e01e440 100644 --- a/lib/libpthread/arch/sh/uthread_machdep.c +++ b/lib/libpthread/arch/sh/uthread_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uthread_machdep.c,v 1.1 2007/02/19 21:03:50 miod Exp $ */ +/* $OpenBSD: uthread_machdep.c,v 1.2 2007/03/02 06:11:54 miod Exp $ */ /* * Copyright (c) 2007 Miodrag Vallat. @@ -20,10 +20,12 @@ #include <pthread.h> #include "pthread_private.h" -#define STACK_ALIGNMENT 8 +#define STACK_ALIGNMENT 4 struct regframe { + /* return address */ register_t pr; + /* call-saved general registers */ register_t r14; register_t r13; register_t r12; @@ -31,6 +33,22 @@ struct regframe { register_t r10; register_t r9; register_t r8; + register_t macl; + register_t mach; +#if defined(__SH4__) && !defined(__SH4_NOFPU__) + /* call-saved floating point registers */ + register_t fr12; + register_t fr13; + register_t fr14; + register_t fr15; + register_t xd12; + register_t xd13; + register_t xd14; + register_t xd15; + /* floating point control registers */ + register_t fpul; + register_t fpscr; +#endif }; void @@ -42,10 +60,18 @@ _thread_machdep_init(struct _machdep_state* statep, void *base, int len, regs = (struct regframe *) (((u_int32_t)base + len - sizeof *regs) & ~(STACK_ALIGNMENT - 1)); regs->pr = (register_t)entry; +#if defined(__SH4__) && !defined(__SH4_NOFPU__) + __asm__ __volatile__ ("sts fpscr, %0" : "=r" (regs->fpscr)); +#endif statep->sp = (u_int)regs; } +/* + * Floating point state is saved with the general registers in + * _thread_machdep_switch(). + */ + void _thread_machdep_save_float_state(struct _machdep_state* statep) { diff --git a/lib/libpthread/arch/sh/uthread_machdep_asm.S b/lib/libpthread/arch/sh/uthread_machdep_asm.S index 702d5c04434..13b7111a692 100644 --- a/lib/libpthread/arch/sh/uthread_machdep_asm.S +++ b/lib/libpthread/arch/sh/uthread_machdep_asm.S @@ -1,4 +1,4 @@ -/* $OpenBSD: uthread_machdep_asm.S,v 1.1 2007/02/19 21:03:50 miod Exp $ */ +/* $OpenBSD: uthread_machdep_asm.S,v 1.2 2007/03/02 06:11:54 miod Exp $ */ /* * Copyright (c) 2007 Miodrag Vallat. @@ -27,7 +27,26 @@ ENTRY(_thread_machdep_switch) * On entry: r4 = new, r5 = oldsave */ - /* save caller-saved context on stack */ + /* + * Save current context on the stack. + */ +#if defined(__SH4__) && !defined(__SH4_NOFPU__) + sts.l fpscr, @-r15 + mov #0, r1 + sts.l fpul, @-r15 + lds r1, fpscr + fmov.s fr15, @-r15 /* note that we can't do double stores... */ + fmov.s fr14, @-r15 /* ...as we don't control stack alignment. */ + fmov.s fr13, @-r15 + fmov.s fr12, @-r15 + frchg + fmov.s fr15, @-r15 + fmov.s fr14, @-r15 + fmov.s fr13, @-r15 + fmov.s fr12, @-r15 +#endif + sts.l mach, @-r15 + sts.l macl, @-r15 mov.l r8, @-r15 mov.l r9, @-r15 mov.l r10, @-r15 @@ -37,13 +56,15 @@ ENTRY(_thread_machdep_switch) mov.l r14, @-r15 sts.l pr, @-r15 - /* save old stack */ + /* + * Switch stacks. + */ mov.l r15, @r5 - - /* switch stacks */ mov.l @r4, r15 - /* restore new context */ + /* + * Restore new context. + */ lds.l @r15+, pr mov.l @r15+, r14 mov.l @r15+, r13 @@ -51,5 +72,26 @@ ENTRY(_thread_machdep_switch) mov.l @r15+, r11 mov.l @r15+, r10 mov.l @r15+, r9 + mov.l @r15+, r8 + lds.l @r15+, macl +#if defined(__SH4__) && !defined(__SH4_NOFPU__) + mov #0, r1 + lds.l @r15+, mach + lds r1, fpscr + frchg + fmov.s @r15+, fr12 + fmov.s @r15+, fr13 + fmov.s @r15+, fr14 + fmov.s @r15+, fr15 + frchg + fmov.s @r15+, fr12 + fmov.s @r15+, fr13 + fmov.s @r15+, fr14 + fmov.s @r15+, fr15 + lds.l @r15+, fpul + rts + lds.l @r15+, fpscr +#else rts - mov.l @r15+, r8 + lds.l @r15+, mach +#endif diff --git a/sys/arch/sh/include/cpu.h b/sys/arch/sh/include/cpu.h index 28bd05964d9..721d3275b77 100644 --- a/sys/arch/sh/include/cpu.h +++ b/sys/arch/sh/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.4 2007/01/15 22:22:19 martin Exp $ */ +/* $OpenBSD: cpu.h,v 1.5 2007/03/02 06:11:54 miod Exp $ */ /* $NetBSD: cpu.h,v 1.41 2006/01/21 04:24:12 uwe Exp $ */ /*- @@ -204,6 +204,9 @@ void _cpu_spin(uint32_t); /* for delay loop. */ void delay(int); struct pcb; void savectx(struct pcb *); +struct fpreg; +void fpu_save(struct fpreg *); +void fpu_restore(struct fpreg *); void dumpsys(void); #endif /* _KERNEL */ #endif /* !_SH_CPU_H_ */ diff --git a/sys/arch/sh/include/frame.h b/sys/arch/sh/include/frame.h index 48d3205b8c2..720058b5461 100644 --- a/sys/arch/sh/include/frame.h +++ b/sys/arch/sh/include/frame.h @@ -1,4 +1,4 @@ -/* $OpenBSD: frame.h,v 1.1.1.1 2006/10/06 21:02:55 miod Exp $ */ +/* $OpenBSD: frame.h,v 1.2 2007/03/02 06:11:54 miod Exp $ */ /* $NetBSD: frame.h,v 1.14 2005/12/11 12:18:58 christos Exp $ */ /*- @@ -125,6 +125,8 @@ struct switchframe { int sf_r6_bank; int sf_sr; int sf_r7_bank; + int sf_macl; + int sf_mach; }; #endif /* !_SH_FRAME_H_ */ diff --git a/sys/arch/sh/include/pcb.h b/sys/arch/sh/include/pcb.h index a82e422b2a9..b723f2e4264 100644 --- a/sys/arch/sh/include/pcb.h +++ b/sys/arch/sh/include/pcb.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pcb.h,v 1.1.1.1 2006/10/06 21:02:55 miod Exp $ */ +/* $OpenBSD: pcb.h,v 1.2 2007/03/02 06:11:54 miod Exp $ */ /* $NetBSD: pcb.h,v 1.7 2002/05/09 12:28:08 uch Exp $ */ /*- @@ -41,15 +41,17 @@ #define _SH_PCB_H_ #include <sh/frame.h> +#include <sh/reg.h> struct pcb { - struct switchframe pcb_sf; /* kernel context for resume */ - caddr_t pcb_onfault; /* for copyin/out fault */ - int pcb_faultbail; /* bail out before call uvm_fault. */ + struct switchframe pcb_sf; /* kernel context for resume */ + caddr_t pcb_onfault; /* for copyin/out fault */ + struct fpreg pcb_fp; /* fp context for resume */ }; struct md_coredump { }; extern struct pcb *curpcb; + #endif /* !_SH_PCB_H_ */ diff --git a/sys/arch/sh/include/ptrace.h b/sys/arch/sh/include/ptrace.h index 9b9cbdd4cbe..ad381b82500 100644 --- a/sys/arch/sh/include/ptrace.h +++ b/sys/arch/sh/include/ptrace.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ptrace.h,v 1.2 2006/11/27 14:54:16 kettenis Exp $ */ +/* $OpenBSD: ptrace.h,v 1.3 2007/03/02 06:11:54 miod Exp $ */ /* $NetBSD: ptrace.h,v 1.3 2002/02/28 01:58:53 uch Exp $ */ /* @@ -38,3 +38,5 @@ #define PT_STEP (PT_FIRSTMACH + 0) #define PT_GETREGS (PT_FIRSTMACH + 1) #define PT_SETREGS (PT_FIRSTMACH + 2) +#define PT_GETFPREGS (PT_FIRSTMACH + 3) +#define PT_SETFPREGS (PT_FIRSTMACH + 4) diff --git a/sys/arch/sh/include/reg.h b/sys/arch/sh/include/reg.h index 24c75107abb..f7be0ba3129 100644 --- a/sys/arch/sh/include/reg.h +++ b/sys/arch/sh/include/reg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: reg.h,v 1.1.1.1 2006/10/06 21:02:55 miod Exp $ */ +/* $OpenBSD: reg.h,v 1.2 2007/03/02 06:11:54 miod Exp $ */ /* $NetBSD: reg.h,v 1.5 2005/12/11 12:18:58 christos Exp $ */ /*- @@ -73,7 +73,7 @@ /* * Registers accessible to ptrace(2) syscall for debugger * The machine-dependent code for PT_{SET,GET}REGS needs to - * use whichver order, defined above, is correct, so that it + * use whichever order, defined above, is correct, so that it * is all invisible to the user. */ struct reg { @@ -100,4 +100,41 @@ struct reg { int r_r0; }; +struct fpreg { + int fpr_fr0; + int fpr_fr1; + int fpr_fr2; + int fpr_fr3; + int fpr_fr4; + int fpr_fr5; + int fpr_fr6; + int fpr_fr7; + int fpr_fr8; + int fpr_fr9; + int fpr_fr10; + int fpr_fr11; + int fpr_fr12; + int fpr_fr13; + int fpr_fr14; + int fpr_fr15; + int fpr_xf0; + int fpr_xf1; + int fpr_xf2; + int fpr_xf3; + int fpr_xf4; + int fpr_xf5; + int fpr_xf6; + int fpr_xf7; + int fpr_xf8; + int fpr_xf9; + int fpr_xf10; + int fpr_xf11; + int fpr_xf12; + int fpr_xf13; + int fpr_xf14; + int fpr_xf15; + int fpr_fpul; + int fpr_fpscr; +}; + #endif /* !_SH_REG_H_ */ diff --git a/sys/arch/sh/include/setjmp.h b/sys/arch/sh/include/setjmp.h index a14c4d76082..a57a3748f1a 100644 --- a/sys/arch/sh/include/setjmp.h +++ b/sys/arch/sh/include/setjmp.h @@ -1,23 +1,8 @@ -/* $OpenBSD: setjmp.h,v 1.1.1.1 2006/10/06 21:02:55 miod Exp $ */ +/* $OpenBSD: setjmp.h,v 1.2 2007/03/02 06:11:54 miod Exp $ */ /* $NetBSD: setjmp.h,v 1.3 2006/01/05 00:50:23 uwe Exp $ */ /* * machine/setjmp.h: machine dependent setjmp-related information. */ -#define _JBLEN 14 /* size, in longs, of a jmp_buf */ - -#define _JB_REG_PR 0 -#define _JB_REG_R8 1 -#define _JB_REG_R9 2 -#define _JB_REG_R10 3 -#define _JB_REG_R11 4 -#define _JB_REG_R12 5 -#define _JB_REG_R13 6 -#define _JB_REG_R14 7 -#define _JB_REG_R15 8 - -#define _JB_HAS_MASK 9 -#define _JB_SIGMASK 10 /* occupies sizeof(sigset_t) = 4 slots */ - -#define _JB_REG_SP _JB_REG_R15 +#define _JBLEN 23 /* size, in longs, of a jmp_buf */ diff --git a/sys/arch/sh/include/signal.h b/sys/arch/sh/include/signal.h index 8083ffe2b36..c0565a5554a 100644 --- a/sys/arch/sh/include/signal.h +++ b/sys/arch/sh/include/signal.h @@ -1,4 +1,4 @@ -/* $OpenBSD: signal.h,v 1.1.1.1 2006/10/06 21:02:55 miod Exp $ */ +/* $OpenBSD: signal.h,v 1.2 2007/03/02 06:11:54 miod Exp $ */ /* $NetBSD: signal.h,v 1.12 2005/12/11 12:18:58 christos Exp $ */ /* @@ -36,6 +36,7 @@ #define _SH_SIGNAL_H_ #include <sys/cdefs.h> +#include <sh/reg.h> typedef int sig_atomic_t; @@ -48,25 +49,8 @@ typedef int sig_atomic_t; * a non-standard exit is performed. */ struct sigcontext { - int sc_spc; - int sc_ssr; - int sc_pr; - int sc_r14; - int sc_r13; - int sc_r12; - int sc_r11; - int sc_r10; - int sc_r9; - int sc_r8; - int sc_r7; - int sc_r6; - int sc_r5; - int sc_r4; - int sc_r3; - int sc_r2; - int sc_r1; - int sc_r0; - int sc_r15; + struct reg sc_reg; + struct fpreg sc_fpreg; int sc_onstack; /* sigstack state to restore */ diff --git a/sys/arch/sh/sh/genassym.cf b/sys/arch/sh/sh/genassym.cf index bdf770d57b1..04df820b33f 100644 --- a/sys/arch/sh/sh/genassym.cf +++ b/sys/arch/sh/sh/genassym.cf @@ -1,4 +1,4 @@ -# $OpenBSD: genassym.cf,v 1.1.1.1 2006/10/06 21:02:55 miod Exp $ +# $OpenBSD: genassym.cf,v 1.2 2007/03/02 06:11:54 miod Exp $ # $NetBSD: genassym.cf,v 1.10 2005/12/11 12:19:00 christos Exp $ #- @@ -41,7 +41,9 @@ include <sys/mbuf.h> include <sys/user.h> include <sys/errno.h> include <uvm/uvm_extern.h> +include <sh/fpu.h> include <sh/locore.h> +include <sh/reg.h> include <sh/vmparam.h> struct trapframe @@ -49,26 +51,6 @@ define TF_SIZE sizeof(struct trapframe) member tf_expevt member tf_ubc member tf_spc -member tf_ssr -member tf_macl -member tf_mach -member tf_pr -member tf_r14 -member tf_r13 -member tf_r12 -member tf_r11 -member tf_r10 -member tf_r9 -member tf_r8 -member tf_r7 -member tf_r6 -member tf_r5 -member tf_r4 -member tf_r3 -member tf_r2 -member tf_r1 -member tf_r0 -member tf_r15 struct proc member p_addr @@ -81,24 +63,16 @@ member P_MD_PCB p_md.md_pcb struct switchframe define SF_SIZE sizeof(struct switchframe) -member sf_sr member sf_r15 -member sf_r14 -member sf_r13 -member sf_r12 -member sf_r10 -member sf_r9 -member sf_r8 -member sf_pr member sf_r6_bank member sf_r7_bank -struct sigcontext -member SC_EFLAGS sc_ssr +struct fpreg +define FP_SIZE sizeof(struct fpreg) struct pcb member pcb_onfault -member pcb_faultbail +member pcb_fp export SONPROC export SRUN diff --git a/sys/arch/sh/sh/locore_subr.S b/sys/arch/sh/sh/locore_subr.S index 7e54ed205ed..de57709a5d5 100644 --- a/sys/arch/sh/sh/locore_subr.S +++ b/sys/arch/sh/sh/locore_subr.S @@ -1,6 +1,22 @@ -/* $OpenBSD: locore_subr.S,v 1.5 2006/12/14 14:56:23 kettenis Exp $ */ +/* $OpenBSD: locore_subr.S,v 1.6 2007/03/02 06:11:54 miod Exp $ */ /* $NetBSD: locore_subr.S,v 1.28 2006/01/23 22:52:09 uwe Exp $ */ +/* + * Copyright (c) 2007 Miodrag Vallat. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice, this permission notice, and the disclaimer below + * appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ /*- * Copyright (c) 2002 The NetBSD Foundation, Inc. * All rights reserved. @@ -49,8 +65,14 @@ * LINTSTUB: include <sh/locore.h> */ -#define SAVEPCB(reg,branch) \ +/* + * Save integer registers in the pcb. + * reg points to pcb->pcb_sf. + */ +#define SAVEPCB(reg) \ add #SF_SIZE, reg ; \ + sts.l mach, @-/**/reg ; \ + sts.l macl, @-/**/reg ; \ stc.l r7_bank,@-/**/reg ; \ stc.l sr, @-/**/reg ; \ stc.l r6_bank,@-/**/reg ; \ @@ -62,8 +84,98 @@ mov.l r12, @-/**/reg ; \ mov.l r13, @-/**/reg ; \ mov.l r14, @-/**/reg ; \ - branch ; \ - mov.l r15, @-/**/reg + mov.l r15, @-/**/reg + +/* + * Save floating point registers to a fpreg structure. + * reg points to the structure, tmp and tmp2 are two scratch integer registers. + */ +#define SAVEFP(reg, tmp, tmp2) \ + add #124, reg ; \ + sts fpscr, tmp2 ; \ + add #(FP_SIZE - 124), reg ; \ + mov #0, tmp; \ + mov.l tmp2, @-/**/reg ; \ + lds tmp, fpscr; \ + sts.l fpul, @-/**/reg ; \ + frchg; \ + fmov.s fr15, @-/**/reg ; \ + fmov.s fr14, @-/**/reg ; \ + fmov.s fr13, @-/**/reg ; \ + fmov.s fr12, @-/**/reg ; \ + fmov.s fr11, @-/**/reg ; \ + fmov.s fr10, @-/**/reg ; \ + fmov.s fr9, @-/**/reg ; \ + fmov.s fr8, @-/**/reg ; \ + fmov.s fr7, @-/**/reg ; \ + fmov.s fr6, @-/**/reg ; \ + fmov.s fr5, @-/**/reg ; \ + fmov.s fr4, @-/**/reg ; \ + fmov.s fr3, @-/**/reg ; \ + fmov.s fr2, @-/**/reg ; \ + fmov.s fr1, @-/**/reg ; \ + fmov.s fr0, @-/**/reg ; \ + frchg; \ + fmov.s fr15, @-/**/reg ; \ + fmov.s fr14, @-/**/reg ; \ + fmov.s fr13, @-/**/reg ; \ + fmov.s fr12, @-/**/reg ; \ + fmov.s fr11, @-/**/reg ; \ + fmov.s fr10, @-/**/reg ; \ + fmov.s fr9, @-/**/reg ; \ + fmov.s fr8, @-/**/reg ; \ + fmov.s fr7, @-/**/reg ; \ + fmov.s fr6, @-/**/reg ; \ + fmov.s fr5, @-/**/reg ; \ + fmov.s fr4, @-/**/reg ; \ + fmov.s fr3, @-/**/reg ; \ + fmov.s fr2, @-/**/reg ; \ + fmov.s fr1, @-/**/reg ; \ + fmov.s fr0, @-/**/reg ; \ + lds tmp2, fpscr + +/* + * Load floating point registers from a fpreg structure. + * reg points to the structure, tmp is a scratch integer register. + */ +#define LOADFP(reg, tmp) \ + mov #0, tmp; \ + lds tmp, fpscr; \ + fmov.s @/**/reg/**/+, fr0 ; \ + fmov.s @/**/reg/**/+, fr1 ; \ + fmov.s @/**/reg/**/+, fr2 ; \ + fmov.s @/**/reg/**/+, fr3 ; \ + fmov.s @/**/reg/**/+, fr4 ; \ + fmov.s @/**/reg/**/+, fr5 ; \ + fmov.s @/**/reg/**/+, fr6 ; \ + fmov.s @/**/reg/**/+, fr7 ; \ + fmov.s @/**/reg/**/+, fr8 ; \ + fmov.s @/**/reg/**/+, fr9 ; \ + fmov.s @/**/reg/**/+, fr10 ; \ + fmov.s @/**/reg/**/+, fr11 ; \ + fmov.s @/**/reg/**/+, fr12 ; \ + fmov.s @/**/reg/**/+, fr13 ; \ + fmov.s @/**/reg/**/+, fr14 ; \ + fmov.s @/**/reg/**/+, fr15 ; \ + frchg; \ + fmov.s @/**/reg/**/+, fr0 ; \ + fmov.s @/**/reg/**/+, fr1 ; \ + fmov.s @/**/reg/**/+, fr2 ; \ + fmov.s @/**/reg/**/+, fr3 ; \ + fmov.s @/**/reg/**/+, fr4 ; \ + fmov.s @/**/reg/**/+, fr5 ; \ + fmov.s @/**/reg/**/+, fr6 ; \ + fmov.s @/**/reg/**/+, fr7 ; \ + fmov.s @/**/reg/**/+, fr8 ; \ + fmov.s @/**/reg/**/+, fr9 ; \ + fmov.s @/**/reg/**/+, fr10 ; \ + fmov.s @/**/reg/**/+, fr11 ; \ + fmov.s @/**/reg/**/+, fr12 ; \ + fmov.s @/**/reg/**/+, fr13 ; \ + fmov.s @/**/reg/**/+, fr14 ; \ + fmov.s @/**/reg/**/+, fr15 ; \ + lds.l @/**/reg/**/+, fpul ; \ + lds.l @/**/reg/**/+, fpscr .text .align 5 /* align cache line size (32B) */ @@ -75,7 +187,9 @@ ENTRY(cpu_switch) /* Save current proc's context to switchframe */ mov.l .L_SF, r0 mov.l @(r0, r4), r1 - SAVEPCB(r1,) + SAVEPCB(r1) + add #PCB_FP, r1 + SAVEFP(r1, r8, r9) .L_find_and_switch: /* Search next proc. cpu_switch_search may or may not sleep. */ @@ -123,7 +237,13 @@ ENTRY(cpu_switch) lds.l @r1+, pr add #4, r1 /* r6_bank already restored */ ldc.l @r1+, sr + add #4, r1 /* r7_bank already restored */ + lds.l @r1+, macl + lds.l @r1+, mach + mov.l @(r0, r4), r1 + add #PCB_FP, r1 + LOADFP(r1, r0) rts nop .align 2 @@ -439,10 +559,36 @@ _C_LABEL(esigcode): * save struct switchframe. */ ENTRY(savectx) - SAVEPCB(r4, rts) + SAVEPCB(r4) + add #PCB_FP, r4 + SAVEFP(r4, r0, r1) + rts + nop SET_ENTRY_SIZE(savectx) /* + * void fpu_save(struct fpreg *fp) + * + * Saves fpu context. + */ +ENTRY(fpu_save) + SAVEFP(r4, r0, r1) + rts + nop + SET_ENTRY_SIZE(fpu_save) + +/* + * void fpu_restore(struct fpreg *fp) + * + * Restores fpu context. + */ +ENTRY(fpu_restore) + LOADFP(r4, r0) + rts + nop + SET_ENTRY_SIZE(fpu_restore) + +/* * LINTSTUB: Func: int copyout(const void *ksrc, void *udst, size_t len) * Copy len bytes into the user address space. */ diff --git a/sys/arch/sh/sh/process_machdep.c b/sys/arch/sh/sh/process_machdep.c index cc5f5ac8bc3..e38105eade5 100644 --- a/sys/arch/sh/sh/process_machdep.c +++ b/sys/arch/sh/sh/process_machdep.c @@ -1,7 +1,23 @@ -/* $OpenBSD: process_machdep.c,v 1.2 2006/11/28 18:52:23 kettenis Exp $ */ +/* $OpenBSD: process_machdep.c,v 1.3 2007/03/02 06:11:54 miod Exp $ */ /* $NetBSD: process_machdep.c,v 1.12 2006/01/21 04:12:22 uwe Exp $ */ /* + * Copyright (c) 2007 Miodrag Vallat. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice, this permission notice, and the disclaimer below + * appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/* * Copyright (c) 1993 The Regents of the University of California. * All rights reserved. * @@ -35,7 +51,6 @@ * From: * Id: procfs_i386.c,v 4.1 1993/12/17 10:47:45 jsp Rel */ - /* * Copyright (c) 1995, 1996, 1997 * Charles M. Hannum. All rights reserved. @@ -86,12 +101,18 @@ * and copy it into the regs structure (<machine/reg.h>). * The process is stopped at the time read_regs is called. * + * process_read_fpregs(proc, fpregs) + * Same as the above, but for floating-point registers. + * * process_write_regs(proc, regs) * Update the current register set from the passed in regs * structure. Take care to avoid clobbering special CPU * registers or privileged bits in the PSL. * The process is stopped at the time write_regs is called. * + * process_write_fpregs(proc, fpregs) + * Same as the above, but for floating-point registers. + * * process_sstep(proc) * Arrange for the process to trap after executing a single instruction. * @@ -108,13 +129,13 @@ #include <sys/vnode.h> #include <sys/ptrace.h> +#include <machine/cpu.h> #include <machine/psl.h> #include <machine/reg.h> static inline struct trapframe * process_frame(struct proc *p) { - return (p->p_md.md_regs); } @@ -148,6 +169,26 @@ process_read_regs(struct proc *p, struct reg *regs) return (0); } +int +process_read_fpregs(struct proc *p, struct fpreg *fpregs) +{ +#ifdef SH4 + if (CPU_IS_SH4) { + struct pcb *pcb = p->p_md.md_pcb; + + if (p == curproc) + fpu_save(&pcb->pcb_fp); + + bcopy(&pcb->pcb_fp, fpregs, sizeof(*fpregs)); + } +#endif +#ifdef SH3 + if (CPU_IS_SH3) + return (EINVAL); +#endif + return (0); +} + #ifdef PTRACE int @@ -158,9 +199,8 @@ process_write_regs(struct proc *p, struct reg *regs) /* * Check for security violations. */ - if (((regs->r_ssr ^ tf->tf_ssr) & PSL_USERSTATIC) != 0) { + if (((regs->r_ssr ^ tf->tf_ssr) & PSL_USERSTATIC) != 0) return (EINVAL); - } tf->tf_spc = regs->r_spc; tf->tf_ssr = regs->r_ssr; @@ -189,6 +229,27 @@ process_write_regs(struct proc *p, struct reg *regs) } int +process_write_fpregs(struct proc *p, struct fpreg *fpregs) +{ +#ifdef SH4 + if (CPU_IS_SH4) { + struct pcb *pcb = p->p_md.md_pcb; + + bcopy(fpregs, &pcb->pcb_fp, sizeof(*fpregs)); + + /* force update of live cpu registers */ + if (p == curproc) + fpu_restore(&pcb->pcb_fp); + } +#endif +#ifdef SH3 + if (CPU_IS_SH3) + return (EINVAL); +#endif + return (0); +} + +int process_sstep(struct proc *p, int sstep) { if (sstep) diff --git a/sys/arch/sh/sh/sh_machdep.c b/sys/arch/sh/sh/sh_machdep.c index 3bfe733676a..05b6bced8e8 100644 --- a/sys/arch/sh/sh/sh_machdep.c +++ b/sys/arch/sh/sh/sh_machdep.c @@ -1,6 +1,22 @@ -/* $OpenBSD: sh_machdep.c,v 1.8 2007/02/26 21:30:18 miod Exp $ */ +/* $OpenBSD: sh_machdep.c,v 1.9 2007/03/02 06:11:54 miod Exp $ */ /* $NetBSD: sh3_machdep.c,v 1.59 2006/03/04 01:13:36 uwe Exp $ */ +/* + * Copyright (c) 2007 Miodrag Vallat. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice, this permission notice, and the disclaimer below + * appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ /*- * Copyright (c) 1996, 1997, 1998, 2002 The NetBSD Foundation, Inc. * All rights reserved. @@ -37,7 +53,6 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ - /*- * Copyright (c) 1982, 1987, 1990 The Regents of the University of California. * All rights reserved. @@ -461,30 +476,36 @@ sendsig(sig_t catcher, int sig, int mask, u_long code, int type, sip = NULL; /* Save register context. */ - frame.sf_uc.sc_spc = tf->tf_spc; - frame.sf_uc.sc_ssr = tf->tf_ssr; - frame.sf_uc.sc_pr = tf->tf_pr; - frame.sf_uc.sc_r14 = tf->tf_r14; - frame.sf_uc.sc_r13 = tf->tf_r13; - frame.sf_uc.sc_r12 = tf->tf_r12; - frame.sf_uc.sc_r11 = tf->tf_r11; - frame.sf_uc.sc_r10 = tf->tf_r10; - frame.sf_uc.sc_r9 = tf->tf_r9; - frame.sf_uc.sc_r8 = tf->tf_r8; - frame.sf_uc.sc_r7 = tf->tf_r7; - frame.sf_uc.sc_r6 = tf->tf_r6; - frame.sf_uc.sc_r5 = tf->tf_r5; - frame.sf_uc.sc_r4 = tf->tf_r4; - frame.sf_uc.sc_r3 = tf->tf_r3; - frame.sf_uc.sc_r2 = tf->tf_r2; - frame.sf_uc.sc_r1 = tf->tf_r1; - frame.sf_uc.sc_r0 = tf->tf_r0; - frame.sf_uc.sc_r15 = tf->tf_r15; + frame.sf_uc.sc_reg.r_spc = tf->tf_spc; + frame.sf_uc.sc_reg.r_ssr = tf->tf_ssr; + frame.sf_uc.sc_reg.r_pr = tf->tf_pr; + frame.sf_uc.sc_reg.r_mach = tf->tf_mach; + frame.sf_uc.sc_reg.r_macl = tf->tf_macl; + frame.sf_uc.sc_reg.r_r15 = tf->tf_r15; + frame.sf_uc.sc_reg.r_r14 = tf->tf_r14; + frame.sf_uc.sc_reg.r_r13 = tf->tf_r13; + frame.sf_uc.sc_reg.r_r12 = tf->tf_r12; + frame.sf_uc.sc_reg.r_r11 = tf->tf_r11; + frame.sf_uc.sc_reg.r_r10 = tf->tf_r10; + frame.sf_uc.sc_reg.r_r9 = tf->tf_r9; + frame.sf_uc.sc_reg.r_r8 = tf->tf_r8; + frame.sf_uc.sc_reg.r_r7 = tf->tf_r7; + frame.sf_uc.sc_reg.r_r6 = tf->tf_r6; + frame.sf_uc.sc_reg.r_r5 = tf->tf_r5; + frame.sf_uc.sc_reg.r_r4 = tf->tf_r4; + frame.sf_uc.sc_reg.r_r3 = tf->tf_r3; + frame.sf_uc.sc_reg.r_r2 = tf->tf_r2; + frame.sf_uc.sc_reg.r_r1 = tf->tf_r1; + frame.sf_uc.sc_reg.r_r0 = tf->tf_r0; +#ifdef SH4 + if (CPU_IS_SH4) + fpu_save(&frame.sf_uc.sc_fpreg); +#endif + frame.sf_uc.sc_onstack = onstack; frame.sf_uc.sc_expevt = tf->tf_expevt; /* frame.sf_uc.sc_err = 0; */ frame.sf_uc.sc_mask = mask; - /* XXX tf_macl, tf_mach not saved */ if (copyout(&frame, fp, sizeof(frame)) != 0) { /* @@ -536,29 +557,35 @@ sys_sigreturn(struct proc *p, void *v, register_t *retval) tf = p->p_md.md_regs; /* Check for security violations. */ - if (((context.sc_ssr ^ tf->tf_ssr) & PSL_USERSTATIC) != 0) + if (((context.sc_reg.r_ssr ^ tf->tf_ssr) & PSL_USERSTATIC) != 0) return (EINVAL); - tf->tf_ssr = context.sc_ssr; - - tf->tf_r0 = context.sc_r0; - tf->tf_r1 = context.sc_r1; - tf->tf_r2 = context.sc_r2; - tf->tf_r3 = context.sc_r3; - tf->tf_r4 = context.sc_r4; - tf->tf_r5 = context.sc_r5; - tf->tf_r6 = context.sc_r6; - tf->tf_r7 = context.sc_r7; - tf->tf_r8 = context.sc_r8; - tf->tf_r9 = context.sc_r9; - tf->tf_r10 = context.sc_r10; - tf->tf_r11 = context.sc_r11; - tf->tf_r12 = context.sc_r12; - tf->tf_r13 = context.sc_r13; - tf->tf_r14 = context.sc_r14; - tf->tf_spc = context.sc_spc; - tf->tf_r15 = context.sc_r15; - tf->tf_pr = context.sc_pr; + tf->tf_spc = context.sc_reg.r_spc; + tf->tf_ssr = context.sc_reg.r_ssr; + tf->tf_macl = context.sc_reg.r_macl; + tf->tf_mach = context.sc_reg.r_mach; + tf->tf_pr = context.sc_reg.r_pr; + tf->tf_r13 = context.sc_reg.r_r13; + tf->tf_r12 = context.sc_reg.r_r12; + tf->tf_r11 = context.sc_reg.r_r11; + tf->tf_r10 = context.sc_reg.r_r10; + tf->tf_r9 = context.sc_reg.r_r9; + tf->tf_r8 = context.sc_reg.r_r8; + tf->tf_r7 = context.sc_reg.r_r7; + tf->tf_r6 = context.sc_reg.r_r6; + tf->tf_r5 = context.sc_reg.r_r5; + tf->tf_r4 = context.sc_reg.r_r4; + tf->tf_r3 = context.sc_reg.r_r3; + tf->tf_r2 = context.sc_reg.r_r2; + tf->tf_r1 = context.sc_reg.r_r1; + tf->tf_r0 = context.sc_reg.r_r0; + tf->tf_r15 = context.sc_reg.r_r15; + tf->tf_r14 = context.sc_reg.r_r14; + +#ifdef SH4 + if (CPU_IS_SH4) + fpu_restore(&context.sc_fpreg); +#endif /* Restore signal stack. */ if (context.sc_onstack) @@ -579,6 +606,7 @@ setregs(struct proc *p, struct exec_package *pack, u_long stack, register_t rval[2]) { struct trapframe *tf; + struct pcb *pcb = p->p_md.md_pcb; p->p_md.md_flags &= ~MDP_USEDFPU; @@ -603,6 +631,16 @@ setregs(struct proc *p, struct exec_package *pack, u_long stack, tf->tf_ssr = PSL_USERSET; tf->tf_r15 = stack; +#ifdef SH4 + if (CPU_IS_SH4) { + /* + * Clear floating point registers. + */ + bzero(&pcb->pcb_fp, sizeof(pcb->pcb_fp)); + fpu_restore(&pcb->pcb_fp); + } +#endif + rval[1] = 0; } diff --git a/sys/arch/sh/sh/trap.c b/sys/arch/sh/sh/trap.c index 2db0d410517..53b5489a438 100644 --- a/sys/arch/sh/sh/trap.c +++ b/sys/arch/sh/sh/trap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: trap.c,v 1.8 2007/02/06 23:14:11 miod Exp $ */ +/* $OpenBSD: trap.c,v 1.9 2007/03/02 06:11:54 miod Exp $ */ /* $NetBSD: exception.c,v 1.32 2006/09/04 23:57:52 uwe Exp $ */ /* $NetBSD: syscall.c,v 1.6 2006/03/07 07:21:50 thorpej Exp $ */ @@ -296,7 +296,8 @@ do_panic: else printf("EXPEVT 0x%03x", expevt); printf(" in %s mode\n", expevt & EXP_USER ? "user" : "kernel"); - printf(" spc %x ssr %x pr %x \n", tf->tf_spc, tf->tf_ssr, tf->tf_pr); + printf("va %p spc %p ssr %p pr %p \n", + va, tf->tf_spc, tf->tf_ssr, tf->tf_pr); panic("general_exception"); /* NOTREACHED */ @@ -402,15 +403,6 @@ tlb_exception(struct proc *p, struct trapframe *tf, uint32_t va) return; } - /* Page not found. call fault handler */ - if (!usermode && pmap != pmap_kernel() && - p->p_md.md_pcb->pcb_faultbail) { - TLB_ASSERT(p->p_md.md_pcb->pcb_onfault != NULL, - "no copyin/out fault handler (interrupt context)"); - tf->tf_spc = (int)p->p_md.md_pcb->pcb_onfault; - return; - } - err = uvm_fault(map, va, 0, ftype); /* User stack extension */ diff --git a/sys/arch/sh/sh/vm_machdep.c b/sys/arch/sh/sh/vm_machdep.c index cc2ff5dce54..db0441c37a5 100644 --- a/sys/arch/sh/sh/vm_machdep.c +++ b/sys/arch/sh/sh/vm_machdep.c @@ -1,6 +1,22 @@ -/* $OpenBSD: vm_machdep.c,v 1.7 2006/11/17 08:35:43 deraadt Exp $ */ +/* $OpenBSD: vm_machdep.c,v 1.8 2007/03/02 06:11:54 miod Exp $ */ /* $NetBSD: vm_machdep.c,v 1.53 2006/08/31 16:49:21 matt Exp $ */ +/* + * Copyright (c) 2007 Miodrag Vallat. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice, this permission notice, and the disclaimer below + * appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ /*- * Copyright (c) 2002 The NetBSD Foundation, Inc. All rights reserved. * Copyright (c) 1982, 1986 The Regents of the University of California. @@ -36,7 +52,6 @@ * * @(#)vm_machdep.c 7.3 (Berkeley) 5/13/91 */ - /*- * Copyright (c) 1995 Charles M. Hannum. All rights reserved. * Copyright (c) 1989, 1990 William Jolitz @@ -215,6 +230,19 @@ cpu_fork(struct proc *p1, struct proc *p2, void *stack, size_t stacksize, * kernel thread begin to run without restoring trapframe. */ sf->sf_sr = PSL_MD; /* kernel mode, interrupt enable */ + +#ifdef SH4 + if (CPU_IS_SH4) { + /* + * Propagate floating point registers to the new process + * (they are not in the trapframe). + */ + if (p1 == curproc) + fpu_save(&p1->p_md.md_pcb->pcb_fp); + bcopy(&p1->p_md.md_pcb->pcb_fp, &pcb->pcb_fp, + sizeof(struct fpreg)); + } +#endif } /* @@ -222,6 +250,7 @@ cpu_fork(struct proc *p1, struct proc *p2, void *stack, size_t stacksize, */ struct md_core { struct reg intreg; + struct fpreg fpreg; }; int @@ -242,6 +271,18 @@ cpu_coredump(struct proc *p, struct vnode *vp, struct ucred *cred, if (error) return error; +#ifdef SH4 + if (CPU_IS_SH4) { + error = process_read_fpregs(p, &md_core.fpreg); + if (error) + return error; + } +#endif +#ifdef SH3 + if (CPU_IS_SH3) + bzero(&md_core.fpreg, sizeof(md_core.fpreg)); +#endif + CORE_SETMAGIC(cseg, CORESEGMAGIC, MID_MACHINE, CORE_CPU); cseg.c_addr = 0; cseg.c_size = chdr->c_cpusize; |