diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2007-03-02 06:11:55 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2007-03-02 06:11:55 +0000 |
commit | b598146d1a6495e37a541155e84a68656e8d417c (patch) | |
tree | 5ac40829b66e0ddccc3d7c1058e48a3485307e3a /sys/arch/sh | |
parent | 5b3f6165185fde0cfa60cbcb08f04c98bc07b4ce (diff) |
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
Diffstat (limited to 'sys/arch/sh')
-rw-r--r-- | sys/arch/sh/include/cpu.h | 5 | ||||
-rw-r--r-- | sys/arch/sh/include/frame.h | 4 | ||||
-rw-r--r-- | sys/arch/sh/include/pcb.h | 10 | ||||
-rw-r--r-- | sys/arch/sh/include/ptrace.h | 4 | ||||
-rw-r--r-- | sys/arch/sh/include/reg.h | 41 | ||||
-rw-r--r-- | sys/arch/sh/include/setjmp.h | 19 | ||||
-rw-r--r-- | sys/arch/sh/include/signal.h | 24 | ||||
-rw-r--r-- | sys/arch/sh/sh/genassym.cf | 38 | ||||
-rw-r--r-- | sys/arch/sh/sh/locore_subr.S | 158 | ||||
-rw-r--r-- | sys/arch/sh/sh/process_machdep.c | 71 | ||||
-rw-r--r-- | sys/arch/sh/sh/sh_machdep.c | 124 | ||||
-rw-r--r-- | sys/arch/sh/sh/trap.c | 14 | ||||
-rw-r--r-- | sys/arch/sh/sh/vm_machdep.c | 45 |
13 files changed, 412 insertions, 145 deletions
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 fd7176d829a..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 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 2dbc63c7cfa..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 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 ec499656bb1..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 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 fb8887ca147..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 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 b742e598ef5..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 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 52c6fb4a19f..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 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; |