diff --git a/sys/sparc64/include/fp.h b/sys/sparc64/include/fp.h index a5caf9ea3b5..bf0d79a8aba 100644 --- a/sys/sparc64/include/fp.h +++ b/sys/sparc64/include/fp.h @@ -27,26 +27,13 @@ #ifndef _MACHINE_FP_H_ #define _MACHINE_FP_H_ -/* A block of 8 double-precision (16 single-precision) FP registers. */ -struct fpblock { - u_int fpb_i[16]; -}; - -struct fpstate { - struct fpblock fp_fb[4]; -}; - #ifdef _KERNEL -struct pcb; -struct thread; - /* - * Note: The pointers passed to the next two functions must be aligned on - * 64 byte boundaries. + * Note: The pointer passed to savefpctx must be aligned on a 64 byte + * boundary. */ -void savefpctx(struct fpstate *); -void restorefpctx(struct fpstate *); +void savefpctx(uint32_t *fp); #endif /* _KERNEL */ #endif /* !_MACHINE_FP_H_ */ diff --git a/sys/sparc64/include/pcb.h b/sys/sparc64/include/pcb.h index 2d847b97dab..c1e00f1f294 100644 --- a/sys/sparc64/include/pcb.h +++ b/sys/sparc64/include/pcb.h @@ -29,14 +29,13 @@ #ifndef _MACHINE_PCB_H_ #define _MACHINE_PCB_H_ -#include #include #define MAXWIN 8 -/* NOTE: pcb_fpstate must be aligned on a 64 byte boundary. */ +/* NOTE: pcb_ufp must be aligned on a 64 byte boundary. */ struct pcb { - struct fpstate pcb_fpstate; + uint32_t pcb_ufp[64]; u_long pcb_sp; u_long pcb_pc; u_long pcb_nsaved; diff --git a/sys/sparc64/sparc64/exception.S b/sys/sparc64/sparc64/exception.S index 5fa41d32c0b..3a4cb6cd7e6 100644 --- a/sys/sparc64/sparc64/exception.S +++ b/sys/sparc64/sparc64/exception.S @@ -482,18 +482,6 @@ END(rsf_fatal) .endr .endm - .macro tl0_fp_restore - wr %g0, FPRS_FEF, %fprs - wr %g0, ASI_BLK_S, %asi - ldda [PCB_REG + PCB_FPSTATE + FP_FB0] %asi, %f0 - ldda [PCB_REG + PCB_FPSTATE + FP_FB1] %asi, %f16 - ldda [PCB_REG + PCB_FPSTATE + FP_FB2] %asi, %f32 - ldda [PCB_REG + PCB_FPSTATE + FP_FB3] %asi, %f48 - membar #Sync - done - .align 32 - .endm - .macro tl0_insn_excptn wrpr %g0, PSTATE_ALT, %pstate wr %g0, ASI_IMMU, %asi @@ -1188,6 +1176,23 @@ END(tl0_sftrap) .align 32 .endm + .macro tl0_fp_restore + ba,a %xcc, tl0_fp_restore + nop + .align 32 + .endm + +ENTRY(tl0_fp_restore) + wr %g0, FPRS_FEF, %fprs + wr %g0, ASI_BLK_S, %asi + ldda [PCB_REG + PCB_UFP + (0 * 64)] %asi, %f0 + ldda [PCB_REG + PCB_UFP + (1 * 64)] %asi, %f16 + ldda [PCB_REG + PCB_UFP + (2 * 64)] %asi, %f32 + ldda [PCB_REG + PCB_UFP + (3 * 64)] %asi, %f48 + membar #Sync + done +END(tl0_fp_restore) + .macro tl1_insn_excptn wrpr %g0, PSTATE_ALT, %pstate wr %g0, ASI_IMMU, %asi diff --git a/sys/sparc64/sparc64/genassym.c b/sys/sparc64/sparc64/genassym.c index 5a5d626a0d7..b0389b97084 100644 --- a/sys/sparc64/sparc64/genassym.c +++ b/sys/sparc64/sparc64/genassym.c @@ -243,7 +243,7 @@ ASSYM(TD_PCB, offsetof(struct thread, td_pcb)); ASSYM(TD_PROC, offsetof(struct thread, td_proc)); ASSYM(PCB_SIZEOF, sizeof(struct pcb)); -ASSYM(PCB_FPSTATE, offsetof(struct pcb, pcb_fpstate)); +ASSYM(PCB_UFP, offsetof(struct pcb, pcb_ufp)); ASSYM(PCB_SP, offsetof(struct pcb, pcb_sp)); ASSYM(PCB_PC, offsetof(struct pcb, pcb_pc)); ASSYM(PCB_NSAVED, offsetof(struct pcb, pcb_nsaved)); @@ -255,11 +255,6 @@ ASSYM(PM_ACTIVE, offsetof(struct pmap, pm_active)); ASSYM(PM_CONTEXT, offsetof(struct pmap, pm_context)); ASSYM(PM_TSB, offsetof(struct pmap, pm_tsb)); -ASSYM(FP_FB0, offsetof(struct fpstate, fp_fb[0])); -ASSYM(FP_FB1, offsetof(struct fpstate, fp_fb[1])); -ASSYM(FP_FB2, offsetof(struct fpstate, fp_fb[2])); -ASSYM(FP_FB3, offsetof(struct fpstate, fp_fb[3])); - ASSYM(CCFSZ, sizeof(struct frame)); ASSYM(SPOFF, SPOFF); diff --git a/sys/sparc64/sparc64/machdep.c b/sys/sparc64/sparc64/machdep.c index fa2ba40fa1c..9936386f6aa 100644 --- a/sys/sparc64/sparc64/machdep.c +++ b/sys/sparc64/sparc64/machdep.c @@ -682,8 +682,7 @@ fill_fpregs(struct thread *td, struct fpreg *fpregs) pcb = td->td_pcb; tf = td->td_frame; - bcopy(pcb->pcb_fpstate.fp_fb, fpregs->fr_regs, - sizeof(pcb->pcb_fpstate.fp_fb)); + bcopy(pcb->pcb_ufp, fpregs->fr_regs, sizeof(fpregs->fr_regs)); fpregs->fr_fsr = tf->tf_fsr; fpregs->fr_gsr = tf->tf_gsr; return (0); @@ -697,8 +696,7 @@ set_fpregs(struct thread *td, struct fpreg *fpregs) pcb = td->td_pcb; tf = td->td_frame; - bcopy(fpregs->fr_regs, pcb->pcb_fpstate.fp_fb, - sizeof(fpregs->fr_regs)); + bcopy(fpregs->fr_regs, pcb->pcb_ufp, sizeof(pcb->pcb_ufp)); tf->tf_fsr = fpregs->fr_fsr; tf->tf_gsr = fpregs->fr_gsr; return (0); diff --git a/sys/sparc64/sparc64/swtch.S b/sys/sparc64/sparc64/swtch.S index 03203e214a5..402928d3221 100644 --- a/sys/sparc64/sparc64/swtch.S +++ b/sys/sparc64/sparc64/swtch.S @@ -68,10 +68,10 @@ ENTRY(cpu_switch) nop wr %g0, FPRS_FEF, %fprs wr %g0, ASI_BLK_S, %asi - stda %f0, [%l1 + PCB_FPSTATE + FP_FB0] %asi - stda %f16, [%l1 + PCB_FPSTATE + FP_FB1] %asi - stda %f32, [%l1 + PCB_FPSTATE + FP_FB2] %asi - stda %f48, [%l1 + PCB_FPSTATE + FP_FB3] %asi + stda %f0, [%l1 + PCB_UFP + (0 * 64)] %asi + stda %f16, [%l1 + PCB_UFP + (1 * 64)] %asi + stda %f32, [%l1 + PCB_UFP + (2 * 64)] %asi + stda %f48, [%l1 + PCB_UFP + (3 * 64)] %asi membar #Sync wr %g0, 0, %fprs andn %l3, FPRS_FEF, %l3 @@ -278,31 +278,16 @@ ENTRY(savectx) END(savectx) /* - * void savefpctx(struct fpstate *); + * void savefpctx(uint32_t *); */ ENTRY(savefpctx) wr %g0, FPRS_FEF, %fprs wr %g0, ASI_BLK_S, %asi - stda %f0, [%o0 + PCB_FPSTATE + FP_FB0] %asi - stda %f16, [%o0 + PCB_FPSTATE + FP_FB1] %asi - stda %f32, [%o0 + PCB_FPSTATE + FP_FB2] %asi - stda %f48, [%o0 + PCB_FPSTATE + FP_FB3] %asi + stda %f0, [%o0 + (0 * 64)] %asi + stda %f16, [%o0 + (1 * 64)] %asi + stda %f32, [%o0 + (2 * 64)] %asi + stda %f48, [%o0 + (3 * 64)] %asi membar #Sync retl wr %g0, 0, %fprs END(savefpctx) - -/* - * void restorefpctx(struct fpstate *); - */ -ENTRY(restorefpctx) - wr %g0, FPRS_FEF, %fprs - wr %g0, ASI_BLK_S, %asi - ldda [%o0 + PCB_FPSTATE + FP_FB0] %asi, %f0 - ldda [%o0 + PCB_FPSTATE + FP_FB1] %asi, %f16 - ldda [%o0 + PCB_FPSTATE + FP_FB2] %asi, %f32 - ldda [%o0 + PCB_FPSTATE + FP_FB3] %asi, %f48 - membar #Sync - retl - wr %g0, 0, %fprs -END(restorefpctx) diff --git a/sys/sparc64/sparc64/vm_machdep.c b/sys/sparc64/sparc64/vm_machdep.c index 510765e6eda..ef15cdf5952 100644 --- a/sys/sparc64/sparc64/vm_machdep.c +++ b/sys/sparc64/sparc64/vm_machdep.c @@ -71,6 +71,7 @@ #include #include +#include #include #include #include @@ -186,11 +187,10 @@ cpu_fork(struct thread *td1, struct proc *p2, struct thread *td2, int flags) /* * Ensure that p1's pcb is up to date. */ - if ((td1->td_frame->tf_fprs & FPRS_FEF) != 0) { - mtx_lock_spin(&sched_lock); - savefpctx(&pcb1->pcb_fpstate); - mtx_unlock_spin(&sched_lock); - } + critical_enter(); + if ((td1->td_frame->tf_fprs & FPRS_FEF) != 0) + savefpctx(pcb1->pcb_ufp); + critical_exit(); /* Make sure the copied windows are spilled. */ flushw(); /* Copy the pcb (this will copy the windows saved in the pcb, too). */