diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/conf/files.sparc64 | 1 | ||||
-rw-r--r-- | sys/sparc64/include/asi.h | 11 | ||||
-rw-r--r-- | sys/sparc64/include/globaldata.h | 1 | ||||
-rw-r--r-- | sys/sparc64/include/pcb.h | 5 | ||||
-rw-r--r-- | sys/sparc64/include/pcpu.h | 1 | ||||
-rw-r--r-- | sys/sparc64/include/pstate.h | 13 | ||||
-rw-r--r-- | sys/sparc64/sparc64/exception.S | 1 | ||||
-rw-r--r-- | sys/sparc64/sparc64/exception.s | 1 | ||||
-rw-r--r-- | sys/sparc64/sparc64/genassym.c | 29 | ||||
-rw-r--r-- | sys/sparc64/sparc64/locore.S | 2 | ||||
-rw-r--r-- | sys/sparc64/sparc64/locore.s | 2 | ||||
-rw-r--r-- | sys/sparc64/sparc64/machdep.c | 16 | ||||
-rw-r--r-- | sys/sparc64/sparc64/pmap.c | 6 | ||||
-rw-r--r-- | sys/sparc64/sparc64/swtch.S | 89 | ||||
-rw-r--r-- | sys/sparc64/sparc64/swtch.s | 89 | ||||
-rw-r--r-- | sys/sparc64/sparc64/trap.c | 38 | ||||
-rw-r--r-- | sys/sparc64/sparc64/vm_machdep.c | 7 |
17 files changed, 276 insertions, 36 deletions
diff --git a/sys/conf/files.sparc64 b/sys/conf/files.sparc64 index ee8c88f..3938690 100644 --- a/sys/conf/files.sparc64 +++ b/sys/conf/files.sparc64 @@ -20,6 +20,7 @@ sparc64/sparc64/elf_machdep.c standard # now normal. # sparc64/sparc64/locore.s standard sparc64/sparc64/exception.s standard +sparc64/sparc64/fp.c standard sparc64/sparc64/machdep.c standard sparc64/sparc64/pmap.c standard sparc64/sparc64/procfs_machdep.c standard diff --git a/sys/sparc64/include/asi.h b/sys/sparc64/include/asi.h index 34f146d..ee7588d 100644 --- a/sys/sparc64/include/asi.h +++ b/sys/sparc64/include/asi.h @@ -90,4 +90,15 @@ #define ASI_DTLB_TAG_READ_REG 0x5e #define ASI_DMMU_DEMAP 0x5f +#define ASI_BLK_AUIP 0x70 +#define ASI_BLK_AIUS 0x71 +#define ASI_BLK_AIUPL 0x78 +#define ASI_BLK_AIUSL 0x79 +#define ASI_BLK_COMMIT_S 0xe0 +#define ASI_BLK_COMMIT_P 0xe1 +#define ASI_BLK_P 0xf0 +#define ASI_BLK_S 0xf1 +#define ASI_BLK_PL 0xf8 +#define ASI_BLK_SL 0xf9 + #endif /* !_MACHINE_ASI_H_ */ diff --git a/sys/sparc64/include/globaldata.h b/sys/sparc64/include/globaldata.h index 7af3375..20fe891 100644 --- a/sys/sparc64/include/globaldata.h +++ b/sys/sparc64/include/globaldata.h @@ -37,7 +37,6 @@ struct globaldata { SLIST_ENTRY(globaldata) gd_allcpu; struct pcb *gd_curpcb; struct proc *gd_curproc; - struct proc *gd_fpcurproc; struct proc *gd_idleproc; u_int gd_cpuid; u_int gd_other_cpus; diff --git a/sys/sparc64/include/pcb.h b/sys/sparc64/include/pcb.h index d5ad7eb..d5dd720 100644 --- a/sys/sparc64/include/pcb.h +++ b/sys/sparc64/include/pcb.h @@ -29,7 +29,12 @@ #ifndef _MACHINE_PCB_H_ #define _MACHINE_PCB_H_ +#include <machine/fp.h> +#include <machine/pstate.h> + +/* NOTE: pcb_fpstate must be aligned on a 64 byte boundary. */ struct pcb { + struct fpstate pcb_fpstate; u_long pcb_fp; u_long pcb_pc; caddr_t pcb_onfault; diff --git a/sys/sparc64/include/pcpu.h b/sys/sparc64/include/pcpu.h index 7af3375..20fe891 100644 --- a/sys/sparc64/include/pcpu.h +++ b/sys/sparc64/include/pcpu.h @@ -37,7 +37,6 @@ struct globaldata { SLIST_ENTRY(globaldata) gd_allcpu; struct pcb *gd_curpcb; struct proc *gd_curproc; - struct proc *gd_fpcurproc; struct proc *gd_idleproc; u_int gd_cpuid; u_int gd_other_cpus; diff --git a/sys/sparc64/include/pstate.h b/sys/sparc64/include/pstate.h index 8ff55f3..07301eb 100644 --- a/sys/sparc64/include/pstate.h +++ b/sys/sparc64/include/pstate.h @@ -47,6 +47,19 @@ #define PSTATE_MG (1<<10) #define PSTATE_IG (1<<11) +#define TSTATE_PSTATE_SHIFT 8 +#define TSTATE_PSTATE(x) ((x) << TSTATE_PSTATE_SHIFT) +#define TSTATE_AG TSTATE_PSTATE(PSTATE_AG) +#define TSTATE_IE TSTATE_PSTATE(PSTATE_IE) +#define TSTATE_PRIV TSTATE_PSTATE(PSTATE_PRIV) +#define TSTATE_AM TSTATE_PSTATE(PSTATE_AM) +#define TSTATE_PEF TSTATE_PSTATE(PSTATE_PEF) +#define TSTATE_RED TSTATE_PSTATE(PSTATE_RED) +#define TSTATE_TLE TSTATE_PSTATE(PSTATE_TLE) +#define TSTATE_CLE TSTATE_PSTATE(PSTATE_CLE) +#define TSTATE_MG TSTATE_PSTATE(PSTATE_MG) +#define TSTATE_IG TSTATE_PSTATE(PSTATE_IG) + #define VER_MANUF_SHIFT (48) #define VER_IMPL_SHIFT (32) #define VER_MASK_SHIFT (24) diff --git a/sys/sparc64/sparc64/exception.S b/sys/sparc64/sparc64/exception.S index 9abc581..3eee42c 100644 --- a/sys/sparc64/sparc64/exception.S +++ b/sys/sparc64/sparc64/exception.S @@ -536,6 +536,7 @@ tl1_breakpoint: tl1_reserved 128 ! 0x380-0x3ff reserved ENTRY(tl0_trap) + /* In every trap from tl0, we need to set PSTATE.PEF. */ illtrap END(tl0_trap) diff --git a/sys/sparc64/sparc64/exception.s b/sys/sparc64/sparc64/exception.s index 9abc581..3eee42c 100644 --- a/sys/sparc64/sparc64/exception.s +++ b/sys/sparc64/sparc64/exception.s @@ -536,6 +536,7 @@ tl1_breakpoint: tl1_reserved 128 ! 0x380-0x3ff reserved ENTRY(tl0_trap) + /* In every trap from tl0, we need to set PSTATE.PEF. */ illtrap END(tl0_trap) diff --git a/sys/sparc64/sparc64/genassym.c b/sys/sparc64/sparc64/genassym.c index ba956f8..cc7eeb4 100644 --- a/sys/sparc64/sparc64/genassym.c +++ b/sys/sparc64/sparc64/genassym.c @@ -40,6 +40,7 @@ #include <machine/asi.h> #include <machine/vmparam.h> #include <machine/cpufunc.h> +#include <machine/fp.h> #include <machine/frame.h> #include <machine/globals.h> #include <machine/pcb.h> @@ -50,6 +51,13 @@ #include <machine/tlb.h> #include <machine/tsb.h> +/* + * XXX: gas, as of version 2.11.2, does not know this ASI (and some other + * UltraSparc specific ones). This definition will probably get us into trouble + * as soon as they are added. + */ +ASSYM(ASI_BLK_S, ASI_BLK_S); + ASSYM(EFAULT, EFAULT); ASSYM(ENAMETOOLONG, ENAMETOOLONG); @@ -63,6 +71,17 @@ ASSYM(PSTATE_PEF, PSTATE_PEF); ASSYM(PSTATE_MG, PSTATE_MG); ASSYM(PSTATE_IG, PSTATE_IG); +ASSYM(TSTATE_AG, TSTATE_AG); +ASSYM(TSTATE_IE, TSTATE_IE); +ASSYM(TSTATE_PRIV, TSTATE_PRIV); +ASSYM(TSTATE_PEF, TSTATE_PEF); +ASSYM(TSTATE_MG, TSTATE_MG); +ASSYM(TSTATE_IG, TSTATE_IG); + +ASSYM(FPRS_DL, FPRS_DL); +ASSYM(FPRS_DU, FPRS_DU); +ASSYM(FPRS_FEF, FPRS_FEF); + ASSYM(TTE_SHIFT, TTE_SHIFT); ASSYM(STTE_SHIFT, STTE_SHIFT); ASSYM(TSB_PRIMARY_BUCKET_SHIFT, TSB_PRIMARY_BUCKET_SHIFT); @@ -97,7 +116,6 @@ ASSYM(TT_CTX_SHIFT, TT_CTX_SHIFT); ASSYM(GD_CURPROC, offsetof(struct globaldata, gd_curproc)); ASSYM(GD_CURPCB, offsetof(struct globaldata, gd_curpcb)); -ASSYM(GD_FPCURPROC, offsetof(struct globaldata, gd_fpcurproc)); ASSYM(JB_FP, offsetof(struct _jmp_buf, _jb[_JB_FP])); ASSYM(JB_PC, offsetof(struct _jmp_buf, _jb[_JB_PC])); @@ -105,11 +123,20 @@ ASSYM(JB_SP, offsetof(struct _jmp_buf, _jb[_JB_SP])); ASSYM(P_ADDR, offsetof(struct proc, p_addr)); ASSYM(P_VMSPACE, offsetof(struct proc, p_vmspace)); +ASSYM(P_FRAME, offsetof(struct proc, p_frame)); +ASSYM(PCB_FPSTATE, offsetof(struct pcb, pcb_fpstate)); ASSYM(PCB_FP, offsetof(struct pcb, pcb_fp)); ASSYM(PCB_PC, offsetof(struct pcb, pcb_pc)); ASSYM(PCB_ONFAULT, offsetof(struct pcb, pcb_onfault)); +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(FP_FSR, offsetof(struct fpstate, fp_fsr)); +ASSYM(FP_FPRS, offsetof(struct fpstate, fp_fprs)); + ASSYM(F_L0, offsetof(struct frame, f_local[0])); ASSYM(F_L1, offsetof(struct frame, f_local[1])); ASSYM(F_L2, offsetof(struct frame, f_local[2])); diff --git a/sys/sparc64/sparc64/locore.S b/sys/sparc64/sparc64/locore.S index cdde7b9..2d809e5 100644 --- a/sys/sparc64/sparc64/locore.S +++ b/sys/sparc64/sparc64/locore.S @@ -34,7 +34,7 @@ * void _start(struct bootinfo *bi, u_long ofw_vec) */ ENTRY(_start) - wrpr %g0, PSTATE_IE|PSTATE_PRIV, %pstate + wrpr %g0, PSTATE_IE | PSTATE_PRIV | PSTATE_PEF, %pstate mov %o0, %g1 mov %o1, %g2 flushw diff --git a/sys/sparc64/sparc64/locore.s b/sys/sparc64/sparc64/locore.s index cdde7b9..2d809e5 100644 --- a/sys/sparc64/sparc64/locore.s +++ b/sys/sparc64/sparc64/locore.s @@ -34,7 +34,7 @@ * void _start(struct bootinfo *bi, u_long ofw_vec) */ ENTRY(_start) - wrpr %g0, PSTATE_IE|PSTATE_PRIV, %pstate + wrpr %g0, PSTATE_IE | PSTATE_PRIV | PSTATE_PEF, %pstate mov %o0, %g1 mov %o1, %g2 flushw diff --git a/sys/sparc64/sparc64/machdep.c b/sys/sparc64/sparc64/machdep.c index d831b40..faacd0d 100644 --- a/sys/sparc64/sparc64/machdep.c +++ b/sys/sparc64/sparc64/machdep.c @@ -80,7 +80,12 @@ struct mtx Giant; struct mtx sched_lock; struct globaldata __globaldata; -char user0[UPAGES * PAGE_SIZE]; +/* + * This needs not be aligned as the other user areas, provided that process 0 + * does not have an fp state (which it doesn't normally). + * This constraint is only here for debugging. + */ +char user0[UPAGES * PAGE_SIZE] __attribute__ ((aligned (64))); struct user *proc0paddr; vm_offset_t clean_sva; @@ -303,6 +308,7 @@ sparc64_init(struct bootinfo *bi, ofw_vec_t *vec) proc0.p_addr = (struct user *)user0; tf = (struct trapframe *)(user0 + UPAGES * PAGE_SIZE - sizeof(*tf)); proc0.p_frame = tf; + tf->tf_tstate = 0; /* * Initialize the per-cpu pointer so we can set curproc. @@ -389,6 +395,14 @@ ptrace_single_step(struct proc *p) void setregs(struct proc *p, u_long entry, u_long stack, u_long ps_strings) { + struct pcb *pcb; + + pcb = &p->p_addr->u_pcb; + mtx_lock_spin(&sched_lock); + fp_init_pcb(pcb); + /* XXX */ + p->p_frame->tf_tstate &= ~TSTATE_PEF; + mtx_unlock_spin(&sched_lock); TODO; } diff --git a/sys/sparc64/sparc64/pmap.c b/sys/sparc64/sparc64/pmap.c index b46b0be..d34114a 100644 --- a/sys/sparc64/sparc64/pmap.c +++ b/sys/sparc64/sparc64/pmap.c @@ -257,6 +257,12 @@ pmap_bootstrap(vm_offset_t skpa, vm_offset_t ekva) virtual_avail += PAGE_SIZE; CADDR2 = virtual_avail; virtual_avail += PAGE_SIZE; + + /* + * Set the secondary context to be the kernel context (needed for + * fp block operations in the kernel). + */ + stxa(AA_DMMU_SCXR, ASI_DMMU, TLB_CTX_KERNEL); } /* diff --git a/sys/sparc64/sparc64/swtch.S b/sys/sparc64/sparc64/swtch.S index e437522..f9445c4 100644 --- a/sys/sparc64/sparc64/swtch.S +++ b/sys/sparc64/sparc64/swtch.S @@ -30,17 +30,57 @@ #include "assym.s" +/* + * Save and restore FPU state. This is done at switch time. + * We could use FPRS_DL and FPRS_DU; however, it is accessible to non-privileged + * software, so it is avoided for compatabilities sake. + * savefp clobbers %fprs. + */ + .macro savefp state, tmp + rd %fprs, \tmp + stx \tmp, [\state + FP_FPRS] + or \tmp, FPRS_FEF, \tmp + wr \tmp, 0, %fprs + stx %fsr, [\state + FP_FSR] + rd %asi, \tmp + wr %g0, ASI_BLK_S, %asi + stda %f0, [\state + FP_FB0] %asi + stda %f16, [\state + FP_FB1] %asi + stda %f32, [\state + FP_FB2] %asi + stda %f48, [\state + FP_FB3] %asi + wr \tmp, 0, %asi + membar #Sync + .endm + + .macro restrfp state, tmp + rd %fprs, \tmp + or \tmp, FPRS_FEF, \tmp + wr \tmp, 0, %fprs + rd %asi, \tmp + wr %g0, ASI_BLK_S, %asi + ldda [\state + FP_FB0] %asi, %f0 + ldda [\state + FP_FB1] %asi, %f16 + ldda [\state + FP_FB2] %asi, %f32 + ldda [\state + FP_FB3] %asi, %f48 + wr \tmp, 0, %asi + membar #Sync + ldx [\state + FP_FSR], %fsr + ldx [\state + FP_FPRS], \tmp + wr \tmp, 0, %fprs + .endm + ENTRY(cpu_switch) save %sp, -CCFSZ, %sp call chooseproc ldx [PCPU(CURPROC)], %l0 cmp %l0, %o0 - be,pn %xcc, 2f - ldx [PCPU(FPCURPROC)], %l2 - cmp %l0, %l2 - bne,pt %xcc, 1f + be,pn %xcc, 3f + ldx [%l0 + P_FRAME], %l2 + ldx [%l2 + TF_TSTATE], %l2 + andcc %l2, TSTATE_PEF, %l2 + be,pt %xcc, 1f ldx [PCPU(CURPCB)], %l1 - PANIC("cpu_switch: fpcurproc", %i0) + savefp %l1 + PCB_FPSTATE, %l3 1: flushw wrpr %g0, 0, %cleanwin stx %fp, [%l1 + PCB_FP] @@ -48,22 +88,43 @@ ENTRY(cpu_switch) ldx [%o0 + P_ADDR], %o1 ldx [%o1 + U_PCB + PCB_FP], %fp ldx [%o1 + U_PCB + PCB_PC], %i7 - stx %o0, [PCPU(CURPROC)] - stx %o1, [PCPU(CURPCB)] + ldx [%o0 + P_FRAME], %l2 + ldx [%l2 + TF_TSTATE], %l2 + andcc %l2, TSTATE_PEF, %l2 + be,pt %xcc, 2f + stx %o0, [PCPU(CURPROC)] + restrfp %o1 + U_PCB + PCB_FPSTATE, %l4 +2: stx %o1, [PCPU(CURPCB)] sub %fp, CCFSZ, %sp -2: ret +3: ret restore END(cpu_switch) ENTRY(savectx) save %sp, -CCFSZ, %sp flushw - ldx [PCPU(FPCURPROC)], %l0 - brz,pt %l0, 1f - nop - illtrap -1: stx %fp, [%i0 + PCB_FP] - stx %i7, [%i0 + PCB_PC] + ldx [PCPU(CURPROC)], %l0 + ldx [%l0 + P_FRAME], %l0 + ldx [%l0 + TF_TSTATE], %l0 + andcc %l0, TSTATE_PEF, %l0 + be,pt %xcc, 1f + stx %fp, [%i0 + PCB_FP] + add %i0, PCB_FPSTATE, %o0 + call savefpctx +1: stx %i7, [%i0 + PCB_PC] ret restore %g0, 0, %o0 END(savectx) + +ENTRY(savefpctx) + rd %fprs, %o2 + savefp %o0, %o1 + retl + wr %o2, 0, %fprs +END(savefpctx) + +ENTRY(restorefpctx) + restrfp %o0, %o1 + retl + nop +END(restorefpctx) diff --git a/sys/sparc64/sparc64/swtch.s b/sys/sparc64/sparc64/swtch.s index e437522..f9445c4 100644 --- a/sys/sparc64/sparc64/swtch.s +++ b/sys/sparc64/sparc64/swtch.s @@ -30,17 +30,57 @@ #include "assym.s" +/* + * Save and restore FPU state. This is done at switch time. + * We could use FPRS_DL and FPRS_DU; however, it is accessible to non-privileged + * software, so it is avoided for compatabilities sake. + * savefp clobbers %fprs. + */ + .macro savefp state, tmp + rd %fprs, \tmp + stx \tmp, [\state + FP_FPRS] + or \tmp, FPRS_FEF, \tmp + wr \tmp, 0, %fprs + stx %fsr, [\state + FP_FSR] + rd %asi, \tmp + wr %g0, ASI_BLK_S, %asi + stda %f0, [\state + FP_FB0] %asi + stda %f16, [\state + FP_FB1] %asi + stda %f32, [\state + FP_FB2] %asi + stda %f48, [\state + FP_FB3] %asi + wr \tmp, 0, %asi + membar #Sync + .endm + + .macro restrfp state, tmp + rd %fprs, \tmp + or \tmp, FPRS_FEF, \tmp + wr \tmp, 0, %fprs + rd %asi, \tmp + wr %g0, ASI_BLK_S, %asi + ldda [\state + FP_FB0] %asi, %f0 + ldda [\state + FP_FB1] %asi, %f16 + ldda [\state + FP_FB2] %asi, %f32 + ldda [\state + FP_FB3] %asi, %f48 + wr \tmp, 0, %asi + membar #Sync + ldx [\state + FP_FSR], %fsr + ldx [\state + FP_FPRS], \tmp + wr \tmp, 0, %fprs + .endm + ENTRY(cpu_switch) save %sp, -CCFSZ, %sp call chooseproc ldx [PCPU(CURPROC)], %l0 cmp %l0, %o0 - be,pn %xcc, 2f - ldx [PCPU(FPCURPROC)], %l2 - cmp %l0, %l2 - bne,pt %xcc, 1f + be,pn %xcc, 3f + ldx [%l0 + P_FRAME], %l2 + ldx [%l2 + TF_TSTATE], %l2 + andcc %l2, TSTATE_PEF, %l2 + be,pt %xcc, 1f ldx [PCPU(CURPCB)], %l1 - PANIC("cpu_switch: fpcurproc", %i0) + savefp %l1 + PCB_FPSTATE, %l3 1: flushw wrpr %g0, 0, %cleanwin stx %fp, [%l1 + PCB_FP] @@ -48,22 +88,43 @@ ENTRY(cpu_switch) ldx [%o0 + P_ADDR], %o1 ldx [%o1 + U_PCB + PCB_FP], %fp ldx [%o1 + U_PCB + PCB_PC], %i7 - stx %o0, [PCPU(CURPROC)] - stx %o1, [PCPU(CURPCB)] + ldx [%o0 + P_FRAME], %l2 + ldx [%l2 + TF_TSTATE], %l2 + andcc %l2, TSTATE_PEF, %l2 + be,pt %xcc, 2f + stx %o0, [PCPU(CURPROC)] + restrfp %o1 + U_PCB + PCB_FPSTATE, %l4 +2: stx %o1, [PCPU(CURPCB)] sub %fp, CCFSZ, %sp -2: ret +3: ret restore END(cpu_switch) ENTRY(savectx) save %sp, -CCFSZ, %sp flushw - ldx [PCPU(FPCURPROC)], %l0 - brz,pt %l0, 1f - nop - illtrap -1: stx %fp, [%i0 + PCB_FP] - stx %i7, [%i0 + PCB_PC] + ldx [PCPU(CURPROC)], %l0 + ldx [%l0 + P_FRAME], %l0 + ldx [%l0 + TF_TSTATE], %l0 + andcc %l0, TSTATE_PEF, %l0 + be,pt %xcc, 1f + stx %fp, [%i0 + PCB_FP] + add %i0, PCB_FPSTATE, %o0 + call savefpctx +1: stx %i7, [%i0 + PCB_PC] ret restore %g0, 0, %o0 END(savectx) + +ENTRY(savefpctx) + rd %fprs, %o2 + savefp %o0, %o1 + retl + wr %o2, 0, %fprs +END(savefpctx) + +ENTRY(restorefpctx) + restrfp %o0, %o1 + retl + nop +END(restorefpctx) diff --git a/sys/sparc64/sparc64/trap.c b/sys/sparc64/sparc64/trap.c index 7aec69b..40548d9 100644 --- a/sys/sparc64/sparc64/trap.c +++ b/sys/sparc64/sparc64/trap.c @@ -29,9 +29,12 @@ #include "opt_ddb.h" #include <sys/param.h> +#include <sys/lock.h> #include <sys/mutex.h> #include <sys/systm.h> #include <sys/proc.h> +#include <sys/sysent.h> +#include <sys/user.h> #include <vm/vm.h> #include <vm/vm_param.h> @@ -39,6 +42,7 @@ #include <vm/vm_page.h> #include <machine/frame.h> +#include <machine/pcb.h> #include <machine/pv.h> #include <machine/trap.h> #include <machine/tte.h> @@ -84,8 +88,27 @@ const char *trap_msg[] = { void trap(struct trapframe *tf) { + u_quad_t sticks; + struct proc *p; + int ucode; + int sig; + + p = curproc; + ucode = tf->tf_type; /* XXX */ + + mtx_lock_spin(&sched_lock); + sticks = p->p_sticks; + mtx_unlock_spin(&sched_lock); switch (tf->tf_type) { + case T_FP_DISABLED: + if (fp_enable_proc(p)) + goto user; + else { + sig = SIGFPE; + goto trapsig; + } + break; #ifdef DDB case T_BREAKPOINT | T_KERNEL: if (kdb_trap(tf) != 0) @@ -96,4 +119,19 @@ trap(struct trapframe *tf) break; } panic("trap: %s", trap_msg[tf->tf_type & ~T_KERNEL]); + +trapsig: + mtx_lock(&Giant); + /* Translate fault for emulators. */ + if (p->p_sysent->sv_transtrap != NULL) + sig = (p->p_sysent->sv_transtrap)(sig, tf->tf_type); + + trapsignal(p, sig, ucode); + mtx_unlock(&Giant); +user: + userret(p, tf, sticks); + if (mtx_owned(&Giant)) + mtx_unlock(&Giant); +out: + return; } diff --git a/sys/sparc64/sparc64/vm_machdep.c b/sys/sparc64/sparc64/vm_machdep.c index b14c9a4..ed9b6b1 100644 --- a/sys/sparc64/sparc64/vm_machdep.c +++ b/sys/sparc64/sparc64/vm_machdep.c @@ -58,10 +58,13 @@ cpu_fork(struct proc *p1, struct proc *p2, int flags) if ((flags & RFPROC) == 0) return; - if (PCPU_GET(fpcurproc) == p1) - panic("cpu_fork: save fp state\n"); pcb = &p2->p_addr->u_pcb; + if ((p1->p_frame->tf_tstate & TSTATE_PEF) != 0) { + mtx_lock_spin(&sched_lock); + savefpctx(&p1->p_addr->u_pcb.pcb_fpstate); + mtx_unlock_spin(&sched_lock); + } bcopy(&p1->p_addr->u_pcb, pcb, sizeof(*pcb)); tf = (struct trapframe *)((caddr_t)pcb + UPAGES * PAGE_SIZE) - 1; |