diff options
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/hppa/hppa/fpemu.S | 122 | ||||
-rw-r--r-- | sys/arch/hppa/hppa/locore.S | 218 | ||||
-rw-r--r-- | sys/arch/hppa/hppa/machdep.c | 11 | ||||
-rw-r--r-- | sys/arch/hppa/hppa/trap.c | 74 | ||||
-rw-r--r-- | sys/arch/hppa/hppa/vm_machdep.c | 14 | ||||
-rw-r--r-- | sys/arch/hppa/include/cpu.h | 8 |
6 files changed, 287 insertions, 160 deletions
diff --git a/sys/arch/hppa/hppa/fpemu.S b/sys/arch/hppa/hppa/fpemu.S index 927c42fc848..7f398491587 100644 --- a/sys/arch/hppa/hppa/fpemu.S +++ b/sys/arch/hppa/hppa/fpemu.S @@ -1,7 +1,7 @@ -/* $OpenBSD: fpemu.S,v 1.6 2002/09/15 09:34:09 mickey Exp $ */ +/* $OpenBSD: fpemu.S,v 1.7 2002/10/07 14:38:34 mickey Exp $ */ /* - * Copyright (c) 2000 Michael Shalayeff + * Copyright (c) 2000,2002 Michael Shalayeff * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -35,12 +35,12 @@ #define FPEMU_VERSION (1 << 11) -#define FP_TABLE2(name, ep0, ep1, ep2, ep3) \ +#define FP_TABLE2(name,ep0,ep1,ep2,ep3) \ ldil L%$fpemu_tbl$name, t1 ! \ ldo R%$fpemu_tbl$name(t1), t1 ! \ ldwx,s r1(t1), t2 ! \ bv r0(t2) ! \ - nop ! \ + copy r0, ret0 ! \ .label $fpemu_tbl$name ! \ .import __CONCAT(__CONCAT(ep0,_),name), code ! \ .import __CONCAT(__CONCAT(ep1,_),name), code ! \ @@ -75,49 +75,52 @@ .text /* - * fpu_emulate(iir) + * fpu_emulate(iir,0,fpregs) */ LEAF_ENTRY(fpu_emulate) - extru arg0, 22, 2, arg3 + copy arg0, t4 extru arg0, 18, 3, r31 - comib,= 1, arg3, $fpu_cln1 - nop + extru arg0, 20, 2, r1 + extru arg0, 22, 2, t3 + subi,<> 1, t3, r0 extru arg0, 16, 2, r31 -$fpu_cln1 /* * theoreticaly we would need to determine the fpu instruction * exception type (there could be 4 of those, but stick w/ * non-timex fpus for now. */ - ldi 1, ret0 - extru,<> arg0, 10, 5, r1 - ldi 32, r1 /* fpemu zero reg */ - extru,<> arg0, 31, 5, t1 + extru,<> arg0, 10, 5, t1 + ldi 32, t1 /* fpemu zero reg */ + extru,<> arg0, 31, 5, t2 b,n $fpemu_nzt - comib,=,n 2, arg3, $fpemu_exit + nop + comib,=,n 2, t3, $fpemu_exit + nop $fpemu_nzt - copy arg0, t4 - sh3add r1, arg2, arg0 - extru arg1, 20, 2, r1 - sh3add t1, arg2, arg1 - /* * arg0 -- source register (address) * arg1 -- target register (address) * arg2 -- fpregs context - * arg3 -- class + * t3 -- class * r31 -- subop * r1 -- format specifier - * (t4 -- copy or arg0, ie iir) + * (t4 -- copy of arg0, ie iir) */ - comib,=,n 0, arg3, $fpemu0c_0 - comib,=,n 1, arg3, $fpemu0c_1 - comib,=,n 2, arg3, $fpemu0c_2 - comib,=,n 3, arg3, $fpemu0c_3 + sh3add t1, arg2, arg0 + sh3add t2, arg2, arg1 + stw r0, 32*8+0(arg2) /* make sure zero reg is zero */ + stw r0, 32*8+4(arg2) + + comib,=,n 0, t3, $fpemu0c_0 + comib,=,n 1, t3, $fpemu0c_1 + comib,=,n 2, t3, $fpemu0c_2 + comib,=,n 3, t3, $fpemu0c_3 $fpemu0c_0 + comib,=,n 2, r1, $fpemu_exit + comib,=,n 0, r31, $fpemu0c_0_0 comib,=,n 1, r31, $fpemu_exit comib,=,n 2, r31, $fpemu0c_0_2 @@ -134,40 +137,36 @@ $fpemu0c_0_0 copy r0, ret0 $fpemu0c_0_2 /* fcpy */ - comib,=,n 2, r1, $fpemu_exit subi 3, r1, r1 ldw 0*4(arg0), t1 ldw 1*4(arg0), t2 ldw 2*4(arg0), t3 - ldw 3*4(arg0), t4 blr,n r1, r0 - nop + ldw 3*4(arg0), t4 stw t3, 2*4(arg1) stw t4, 3*4(arg1) - stw t2, 1*4(arg1) nop nop nop + stw t2, 1*4(arg1) stw t1, 0*4(arg1) bv 0(rp) copy r0, ret0 $fpemu0c_0_3 /* fabs */ - comib,=,n 2, r1, $fpemu_exit subi 3, r1, r1 ldw 0*4(arg0), t1 ldw 1*4(arg0), t2 ldw 2*4(arg0), t3 ldw 3*4(arg0), t4 - depi 0, 0, 1, t1 blr,n r1, r0 - nop + depi 0, 0, 1, t1 stw t3, 2*4(arg1) stw t4, 3*4(arg1) - stw t2, 1*4(arg1) nop nop nop + stw t2, 1*4(arg1) stw t1, 0*4(arg1) bv 0(rp) copy r0, ret0 @@ -181,8 +180,7 @@ $fpemu0c_0_5 /* frnd */ FP_TABLE2(frnd,sgl,dbl,invalid,quad) $fpemu0c_1 - extru t4, 18, 2, t2 - sh2add r1, t2, r1 + extru t4, 16, 4, r1 comib,=,n 0, r31, $fpemu0c_1_0 comib,=,n 1, r31, $fpemu0c_1_1 comib,=,n 2, r31, $fpemu0c_1_2 @@ -193,7 +191,7 @@ $fpemu0c_1_0 /* fcnvff */ #define dbl_to_quad_fcnvff invalid_fcnvff #define quad_to_sgl_fcnvff invalid_fcnvff #define quad_to_dbl_fcnvff invalid_fcnvff - FP_TABLE3(fcnvff, invalid, sgl_to_dbl, invalid, sgl_to_quad, dbl_to_sgl, invalid, invalid, dbl_to_quad, invalid, invalid, invalid, invalid, quad_to_sgl, quad_to_dbl, invalid, invalid) + FP_TABLE3(fcnvff, invalid, dbl_to_sgl, invalid, quad_to_sgl, sgl_to_dbl, invalid, invalid, quad_to_dbl, invalid, invalid, invalid, invalid, sgl_to_quad, dbl_to_quad, invalid, invalid) $fpemu0c_1_1 /* fcnvxf */ #define sgl_to_quad_fcnvxf invalid_fcnvxf @@ -201,7 +199,7 @@ $fpemu0c_1_1 /* fcnvxf */ #define quad_to_sgl_fcnvxf invalid_fcnvxf #define quad_to_dbl_fcnvxf invalid_fcnvxf #define quad_to_quad_fcnvxf invalid_fcnvxf - FP_TABLE3(fcnvxf, sgl_to_sgl, sgl_to_dbl, invalid, sgl_to_quad, dbl_to_sgl, dbl_to_dbl, invalid, dbl_to_quad, invalid, invalid, invalid, invalid, quad_to_sgl, quad_to_dbl, invalid, quad_to_quad) + FP_TABLE3(fcnvxf, sgl_to_sgl, dbl_to_sgl, invalid, quad_to_sgl, sgl_to_dbl, dbl_to_dbl, invalid, quad_to_dbl, invalid, invalid, invalid, invalid, sgl_to_quad, dbl_to_quad, invalid, quad_to_quad) $fpemu0c_1_2 /* fcnvfx */ #define sgl_to_quad_fcnvfx invalid_fcnvfx @@ -209,7 +207,7 @@ $fpemu0c_1_2 /* fcnvfx */ #define quad_to_sgl_fcnvfx invalid_fcnvfx #define quad_to_dbl_fcnvfx invalid_fcnvfx #define quad_to_quad_fcnvfx invalid_fcnvfx - FP_TABLE3(fcnvfx, sgl_to_sgl, sgl_to_dbl, invalid, sgl_to_quad, dbl_to_sgl, dbl_to_dbl, invalid, dbl_to_quad, invalid, invalid, invalid, invalid, quad_to_sgl, quad_to_dbl, invalid, quad_to_quad) + FP_TABLE3(fcnvfx, sgl_to_sgl, dbl_to_sgl, invalid, quad_to_sgl, sgl_to_dbl, dbl_to_dbl, invalid, quad_to_dbl, invalid, invalid, invalid, invalid, sgl_to_quad, dbl_to_quad, invalid, quad_to_quad) $fpemu0c_1_3 /* fcnvfxt */ #define sgl_to_quad_fcnvfxt invalid_fcnvfxt @@ -217,31 +215,22 @@ $fpemu0c_1_3 /* fcnvfxt */ #define quad_to_sgl_fcnvfxt invalid_fcnvfxt #define quad_to_dbl_fcnvfxt invalid_fcnvfxt #define quad_to_quad_fcnvfxt invalid_fcnvfxt - FP_TABLE3(fcnvfxt, sgl_to_sgl, sgl_to_dbl, invalid, sgl_to_quad, dbl_to_sgl, dbl_to_dbl, invalid, dbl_to_quad, invalid, invalid, invalid, invalid, quad_to_sgl, quad_to_dbl, invalid, quad_to_quad) - + FP_TABLE3(fcnvfxt, sgl_to_sgl, dbl_to_sgl, invalid, quad_to_sgl, sgl_to_dbl, dbl_to_dbl, invalid, quad_to_dbl, invalid, invalid, invalid, invalid, sgl_to_quad, dbl_to_quad, invalid, quad_to_quad) $fpemu0c_2 - comib,=,n 0, r31, $fpemu0c_2_0 comib,=,n 1, r31, $fpemu0c_2_1 - comib,=,n 2, r31, $fpemu_exit - comib,=,n 3, r31, $fpemu_exit - comib,=,n 4, r31, $fpemu_exit - comib,=,n 5, r31, $fpemu_exit - comib,=,n 6, r31, $fpemu_exit - comib,=,n 7, r31, $fpemu_exit + comib,<>,n 0, r31, $fpemu_exit $fpemu0c_2_0 copy arg2, arg3 extru,<> t4, 15, 5, t1 ldi 32, t1 - sh3add t1, arg3, arg1 - extru t4, 31, 5, arg2 + sh3add t1, arg3, arg2 FP_TABLE2(fcmp,sgl,dbl,invalid,invalid) $fpemu0c_2_1 comib,<>,n 0, r1, $fpemu_exit - /* extru t4, 31, 5, arg1 */ /* XXX timex is much more compilicated */ ldw 0(arg2), t1 ldi 0, ret0 @@ -261,19 +250,27 @@ $fpemu0c_2_1 mtctl t2, pcoq $fpemu0c_3 - copy arg2, arg3 - extru,<> t4, 31, 5, t1 + extru,<> t4, 15, 5, t1 ldi 32, t1 - sh3add t1, arg3, arg2 + blr r31, r0 + copy arg2, arg3 - comib,=,n 0, r31, $fpemu0c_3_0 - comib,=,n 1, r31, $fpemu0c_3_1 - comib,=,n 2, r31, $fpemu0c_3_2 - comib,=,n 3, r31, $fpemu0c_3_3 - comib,=,n 4, r31, $fpemu0c_3_4 - comib,=,n 5, r31, $fpemu_exit - comib,=,n 6, r31, $fpemu_exit - comib,=,n 7, r31, $fpemu_exit + b $fpemu0c_3_0 + sh3add t1, arg3, arg2 + b $fpemu0c_3_1 + sh3add t1, arg3, arg2 + b $fpemu0c_3_2 + sh3add t1, arg3, arg2 + b $fpemu0c_3_3 + sh3add t1, arg3, arg2 + b $fpemu0c_3_4 + sh3add t1, arg3, arg2 + b $fpemu_exit + sh3add t1, arg3, arg2 + b $fpemu_exit + sh3add t1, arg3, arg2 + b $fpemu_exit + sh3add t1, arg3, arg2 $fpemu0c_3_0 /* fadd */ FP_TABLE2(fadd,sgl,dbl,invalid,invalid) @@ -306,7 +303,8 @@ invalid_fsub invalid_fmpy invalid_fdiv invalid_frem - bv,n 0(rp) + bv 0(rp) + ldi 1, ret0 EXIT(fpu_emulate) .end diff --git a/sys/arch/hppa/hppa/locore.S b/sys/arch/hppa/hppa/locore.S index 6517e829065..f0996721e0b 100644 --- a/sys/arch/hppa/hppa/locore.S +++ b/sys/arch/hppa/hppa/locore.S @@ -1,4 +1,4 @@ -/* $OpenBSD: locore.S,v 1.89 2002/09/15 09:39:36 mickey Exp $ */ +/* $OpenBSD: locore.S,v 1.90 2002/10/07 14:38:34 mickey Exp $ */ /* * Copyright (c) 1998-2002 Michael Shalayeff @@ -955,7 +955,7 @@ hpmc_v ATRAP(privr,T_PRIV_REG) /* 11. privileged register trap */ ATRAP(ovrfl,T_OVERFLOW) /* 12. overflow trap */ ATRAP(cond,T_CONDITION) /* 13. conditional trap */ - ATRAP(excpt,T_EXCEPTION) /* 14. assist exception trap */ + CTRAP(excpt,T_EXCEPTION,) /* 14. assist exception trap */ STRAP(dtlb,T_DTLBMISS,DTLBPRE) /* 15. data TLB miss fault */ STRAP(itlbna,T_ITLBMISSNA,DTLBPRE)/* 16. ITLB non-access miss fault */ STRAP(dtlbna,T_DTLBMISSNA,DTLBPRE)/* 17. DTLB non-access miss fault */ @@ -1008,8 +1008,48 @@ hpmc_v ATRAP(unk63,63) /* 64 */ + .export TLABEL(excpt), entry +ENTRY(TLABEL(excpt),0) + /* assume we never get this one w/o fpu [enabled] */ + copy rp, r1 + mtctl arg0, tr5 + .import fpu_save, code + .call + bl fpu_save, rp + mfctl cr30, arg0 + copy r1, rp + mtctl r0, ccr /* cause a reload after exception */ + ldil L%fpu_curpcb, r1 + mfctl cr30, arg0 + stw r0, R%fpu_curpcb(r1) + + /* now, check for trap */ + ldw 0(arg0), r1 + bb,>=,n r1, HPPA_FPU_T_POS, excpt_notrap + ldw 8(arg0), r1 + extru r1, 5, 6, r1 + comib,<>,n HPPA_FPU_UNMPL, r1, excpt_notrap + + ldw 0(arg0), r1 + depi 0, HPPA_FPU_T_POS, 1, r1 + stw r1, 0(arg0) + ldw 8(arg0), r1 + stw r0, 8(arg0) + fdc r0(arg0) + .import $fpu_emulate, code + b $fpu_emulate + mfctl tr5, arg0 + +excpt_notrap + fdc r0(arg0) + mfctl tr5, arg0 + sync + b TLABEL(all) + ldi T_EXCEPTION, r1 +EXIT(TLABEL(excpt)) + .export TLABEL(emu), entry -LEAF_ENTRY(TLABEL(emu)) +ENTRY(TLABEL(emu),0) /* * Switch FPU/SFU context @@ -1023,21 +1063,53 @@ LEAF_ENTRY(TLABEL(emu)) * */ + mfctl iir, r1 + extru r1, 5, 6, r1 /* no sfu implementation right now */ + comib,= 4, r1, TLABEL(all) + ldi T_ILLEGAL, r1 + + mfctl iir, r1 + extru r1, 25, 3, r1 /* only fpu coprocessor emulation now */ + comib,<< 4, r1, TLABEL(all) + ldi T_ILLEGAL, r1 + + /* if we are already enabled and hit again, emulate */ mfctl ccr, r1 + extru,<> r1, 25, 2, r0 + b,n $fpusw_set + nop + +#if 0 + /* here we emulate the fld/fst */ + mfctl iir, r1 + extru r1, 5, 6, r1 + comib,= 0xb, r9, TLABEL(all) + ldi T_ILLEGAL, r1 + + mfctl iir, r1 + extru r1, 5, 6, r1 + comib,= 0x9, r9, TLABEL(all) + ldi T_ILLEGAL, r1 +#endif + .import $fpu_emulate, code + b $fpu_emulate + nop + +$fpusw_set /* enable coprocessor */ depi 3, 25, 2, r1 mtctl r1, ccr - mtctl arg0, tr5 + copy arg0, arg1 ldil L%fpu_curpcb, arg0 - mfctl cr30, r1 + mfctl cr30, r9 ldw R%fpu_curpcb(arg0), arg0 - comb,=,n arg0, r1, $fpusw_done - comb,=,n r0, arg0, $fpusw_nosave + comb,=,n arg0, r9, $fpusw_done + comb,=,n arg0, r0, $fpusw_nosave copy rp, r1 - .import fpu_save, entry + .import fpu_save, code .call bl fpu_save, rp ldo PCB_FPREGS+U_PCB(arg0), arg0 @@ -1051,8 +1123,7 @@ $fpusw_nosave ldo 1(arg0), arg0 stw arg0, R%fpu_csw(r1) - mfctl cr30, r1 - ldo 31*8+PCB_FPREGS+U_PCB(r1), arg0 + ldo 31*8+PCB_FPREGS+U_PCB(r9), arg0 fldds,ma -8(arg0), fr31 fldds,ma -8(arg0), fr30 @@ -1091,9 +1162,8 @@ $fpusw_nosave stw arg0, R%fpu_curpcb(r1) $fpusw_done - mfctl tr7, r1 - mfctl tr5, arg0 - rfi + copy arg1, arg0 + rfir nop EXIT(TLABEL(emu)) @@ -1521,8 +1591,9 @@ $trapnowvirt */ mfctl rctr, t1 + mfctl ccr, t2 stw t1, TF_CR0(t3) - /* XXX save ccr here w/ rctr */ + stw t2, TF_CR10(t3) #ifdef DDB /* @@ -1915,20 +1986,36 @@ EXIT(fpu_save) #ifdef FPEMUL /* - * Emulate FPU/SFU if none/disabled + * Emulate FPU * * iisq:iioq - exception triggered instruction */ -ENTRY($fpu_emulate,0) +ENTRY($fpu_emulate,320) mtctl sp, tr3 mtctl r31, tr2 ldil L%fpemu_stack, r31 ldw R%fpemu_stack(r31), r31 - ldo R%TRAPFRAME_SIZEOF+HPPA_FRAME_SIZE(r31), sp stw r2 , TF_R2 (r31) - stw r3 , TF_R2 (r31) + stw r3 , TF_R3 (r31) +#ifdef DDB + stw r4 , TF_R4 (r31) + stw r5 , TF_R5 (r31) + stw r6 , TF_R6 (r31) + stw r7 , TF_R7 (r31) + stw r8 , TF_R8 (r31) + stw r9 , TF_R9 (r31) + stw r10, TF_R10(r31) + stw r11, TF_R11(r31) + stw r12, TF_R12(r31) + stw r13, TF_R13(r31) + stw r14, TF_R14(r31) + stw r15, TF_R15(r31) + stw r16, TF_R16(r31) + stw r17, TF_R17(r31) + stw r18, TF_R18(r31) +#endif stw r19, TF_R19(r31) stw r20, TF_R20(r31) stw r21, TF_R21(r31) @@ -1940,63 +2027,94 @@ ENTRY($fpu_emulate,0) stw r27, TF_R27(r31) stw r28, TF_R28(r31) stw r29, TF_R29(r31) + mfctl tr2, t2 + mfctl tr3, t1 + stw t1, TF_R30(r31) + stw t2, TF_R31(r31) + copy r1, arg0 mfctl sar, r1 - mfctl iir, arg0 stw r1, TF_CR11(r31) stw arg0, TF_CR19(r31) - extru,<> arg0, 10, 1, r0 - extru,= arg0, 11, 1, r0 - or,tr r0, r0, r0 - .call - bl,n $sfu_emu, rp + ldo TRAPFRAME_SIZEOF(r31), r3 + ldo TRAPFRAME_SIZEOF+HPPA_FRAME_SIZE(r31), sp + + ldil L%$global$, dp + ldo R%$global$(dp), dp .import fpu_emulate, code ldil L%fpu_emulate,t1 ldo R%fpu_emulate(t1),t1 - mfctl iir, arg0 - /* arg3 -- regs */ + mfctl cr30, arg2 .call blr r0,rp bv,n 0(t1) nop + mfctl cr30, arg0 + fdc r0(arg0) + ldo 32(arg0), arg0 + fdc r0(arg0) + ldo 32(arg0), arg0 + fdc r0(arg0) + ldo 32(arg0), arg0 + fdc r0(arg0) + ldo 32(arg0), arg0 + fdc r0(arg0) + ldo 32(arg0), arg0 + fdc r0(arg0) + ldo 32(arg0), arg0 + fdc r0(arg0) + ldo 32(arg0), arg0 + fdc r0(arg0) + ldil L%fpemu_stack, r31 ldw R%fpemu_stack(r31), r31 ldw TF_CR11(r31), r1 mtsar r1 - ldw TF_R29(r31), r29 - ldw TF_R28(r31), r27 - mtctl r27, tr5 - ldw TF_R27(r31), r27 - ldw TF_R26(r31), r26 - ldw TF_R25(r31), r25 - ldw TF_R24(r31), r24 - ldw TF_R23(r31), r23 - ldw TF_R22(r31), r22 - ldw TF_R21(r31), r21 - ldw TF_R20(r31), r20 - ldw TF_R19(r31), r19 - ldw TF_R3 (r31), r3 ldw TF_R2 (r31), r2 - mfctl tr3, sp - mfctl tr2, r31 + ldw TF_R3 (r31), r3 + copy ret0, r1 +#ifdef DDB + ldw TF_R4 (r31), r4 + ldw TF_R5 (r31), r5 + ldw TF_R6 (r31), r6 + ldw TF_R7 (r31), r7 + ldw TF_R8 (r31), r8 + ldw TF_R9 (r31), r9 + ldw TF_R10(r31), r10 + ldw TF_R11(r31), r11 + ldw TF_R12(r31), r12 + ldw TF_R13(r31), r13 + ldw TF_R14(r31), r14 + ldw TF_R15(r31), r15 + ldw TF_R16(r31), r16 + ldw TF_R17(r31), r17 + ldw TF_R18(r31), r18 +#endif + ldw TF_R19(r31), r19 + ldw TF_R20(r31), r20 + ldw TF_R21(r31), r21 + ldw TF_R22(r31), r22 + ldw TF_R23(r31), r23 + ldw TF_R24(r31), r24 + ldw TF_R25(r31), r25 + ldw TF_R26(r31), r26 + ldw TF_R27(r31), r27 + ldw TF_R28(r31), r28 + ldw TF_R29(r31), r29 + ldw TF_R30(r31), r30 + ldw TF_R31(r31), r31 - comb,<> r0, ret0, TLABEL(all) - mfctl tr5, ret0 + comb,<> r0, r1, TLABEL(all) + ldi T_EXCEPTION, r1 mfctl tr7, r1 - rfi + rfir nop EXIT($fpu_emulate) - .export $sfu_emu, entry -ENTRY($sfu_emu,0) - bv r0(rp) - ldo 1(r0), ret0 /* none supported by now */ -EXIT($sfu_emu) - #endif /* FPEMUL */ .import dcache_stride, data diff --git a/sys/arch/hppa/hppa/machdep.c b/sys/arch/hppa/hppa/machdep.c index bc8ca2288a5..01827a3b744 100644 --- a/sys/arch/hppa/hppa/machdep.c +++ b/sys/arch/hppa/hppa/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.81 2002/09/23 17:43:20 mickey Exp $ */ +/* $OpenBSD: machdep.c,v 1.82 2002/10/07 14:38:34 mickey Exp $ */ /* * Copyright (c) 1999-2002 Michael Shalayeff @@ -1158,6 +1158,7 @@ setregs(p, pack, stack, retval) u_long stack; register_t *retval; { + extern paddr_t fpu_curpcb; /* from locore.S */ register struct trapframe *tf = p->p_md.md_regs; register struct pcb *pcb = &p->p_addr->u_pcb; #ifdef DEBUG @@ -1176,10 +1177,16 @@ setregs(p, pack, stack, retval) tf->tf_arg1 = tf->tf_arg2 = 0; /* XXX dynload stuff */ /* reset any of the pending FPU exceptions */ - pcb->pcb_fpregs[0] = HPPA_FPU_INIT; + pcb->pcb_fpregs[0] = ((u_int64_t)HPPA_FPU_INIT) << 32; pcb->pcb_fpregs[1] = 0; pcb->pcb_fpregs[2] = 0; pcb->pcb_fpregs[3] = 0; + fdcache(HPPA_SID_KERNEL, (vaddr_t)pcb->pcb_fpregs, 8 * 4); + if (tf->tf_cr30 == fpu_curpcb) { + fpu_curpcb = 0; + /* force an fpu ctxsw, we'll not be hugged by the cpu_switch */ + mtctl(0, CR_CCR); + } /* setup terminal stack frame */ stack = hppa_round_page(stack); diff --git a/sys/arch/hppa/hppa/trap.c b/sys/arch/hppa/hppa/trap.c index 8c9b3f8c1d0..d19bad1b5b2 100644 --- a/sys/arch/hppa/hppa/trap.c +++ b/sys/arch/hppa/hppa/trap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: trap.c,v 1.51 2002/09/23 06:11:46 mickey Exp $ */ +/* $OpenBSD: trap.c,v 1.52 2002/10/07 14:38:34 mickey Exp $ */ /* * Copyright (c) 1998-2001 Michael Shalayeff @@ -144,7 +144,8 @@ trap(type, frame) trapnum = type & ~T_USER; opcode = frame->tf_iir; - if (trapnum == T_ITLBMISS) { + if (trapnum == T_ITLBMISS || + trapnum == T_EXCEPTION || trapnum == T_EMULATION) { va = frame->tf_iioq_head; space = frame->tf_iisq_head; vftype = VM_PROT_EXECUTE; @@ -210,7 +211,6 @@ trap(type, frame) case T_PRIV_REG: /* these just can't make it to the trap() ever */ case T_HPMC: case T_HPMC | T_USER: - case T_EMULATION: #endif case T_IBREAK: case T_DATALIGN: @@ -239,49 +239,47 @@ trap(type, frame) break; case T_EXCEPTION | T_USER: { - extern u_int32_t fpu_enable; /* from machdep */ - extern paddr_t fpu_curpcb; - u_int32_t stat, *pex; + u_int64_t *fpp = (u_int64_t *)frame->tf_cr30; + u_int32_t *pex; int i, flt; -#ifdef DIAGNOSTIC - if (fpu_curpcb != frame->tf_cr30) - panic("trap: FPU is not owned"); -#endif - mfctl(CR_CCR, stat); - if (stat & fpu_enable) /* net quite there yet */ - fpu_save((vaddr_t)p->p_addr->u_pcb.pcb_fpregs); - /* nobody owns it anymore */ - fpu_curpcb = 0; - mtctl(stat & ~fpu_enable, CR_CCR); - - /* get the exceptions and mask by the enabled mask */ - pex = (u_int32_t *)&p->p_addr->u_pcb.pcb_fpregs[0]; + pex = (u_int32_t *)&fpp[0]; for (i = 0, pex++; i < 7 && !*pex; i++, pex++); - stat = HPPA_FPU_OP(*pex); - if (stat & HPPA_FPU_V) - flt = FPE_FLTINV; - else if (stat & HPPA_FPU_Z) - flt = FPE_FLTDIV; - else if (stat & HPPA_FPU_O) - flt = FPE_FLTOVF; - else if (stat & HPPA_FPU_U) - flt = FPE_FLTUND; - else if (stat & HPPA_FPU_I) - flt = FPE_FLTRES; - else - flt = 0; - /* still left: under/over-flow and inexact */ - *pex = 0; + flt = 0; + if (i < 7) { + u_int32_t stat = HPPA_FPU_OP(*pex); + if (stat == HPPA_FPU_UNMPL) + flt = FPE_FLTINV; + else if (stat & HPPA_FPU_V) + flt = FPE_FLTINV; + else if (stat & HPPA_FPU_Z) + flt = FPE_FLTDIV; + else if (stat & HPPA_FPU_I) + flt = FPE_FLTRES; + else if (stat & HPPA_FPU_O) + flt = FPE_FLTOVF; + else if (stat & HPPA_FPU_U) + flt = FPE_FLTUND; + /* still left: under/over-flow w/ inexact */ + *pex = 0; + } + /* reset the trap flag, as if there was none */ + fpp[0] &= ~(((u_int64_t)HPPA_FPU_T) << 32); + /* flush out, since load is done from phys, only 4 regs */ + fdcache(HPPA_SID_KERNEL, (vaddr_t)fpp, 8 * 4); sv.sival_int = va; trapsignal(p, SIGFPE, type &~ T_USER, flt, sv); } break; - case T_EMULATION | T_USER: /* co-proc assist trap */ + case T_EMULATION: + panic("trap: emulation trap in the kernel"); + break; + + case T_EMULATION | T_USER: sv.sival_int = va; - trapsignal(p, SIGFPE, type &~ T_USER, FPE_FLTINV, sv); + trapsignal(p, SIGILL, type &~ T_USER, ILL_ILLOPC, sv); break; case T_OVERFLOW | T_USER: @@ -458,10 +456,6 @@ return; break; case T_CONDITION: -#if 0 -if (kdb_trap (type, va, frame)) - return; -#endif panic("trap: divide by zero in the kernel"); break; diff --git a/sys/arch/hppa/hppa/vm_machdep.c b/sys/arch/hppa/hppa/vm_machdep.c index dd2f8bdf687..de507e3eb57 100644 --- a/sys/arch/hppa/hppa/vm_machdep.c +++ b/sys/arch/hppa/hppa/vm_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vm_machdep.c,v 1.42 2002/09/11 15:55:58 mickey Exp $ */ +/* $OpenBSD: vm_machdep.c,v 1.43 2002/10/07 14:38:34 mickey Exp $ */ /* * Copyright (c) 1999-2002 Michael Shalayeff @@ -136,7 +136,7 @@ void cpu_swapout(p) struct proc *p; { - extern vaddr_t fpu_curpcb; + extern paddr_t fpu_curpcb; /* from locore.S */ struct trapframe *tf = p->p_md.md_regs; if (tf->tf_cr30 == fpu_curpcb) { @@ -153,6 +153,7 @@ cpu_fork(p1, p2, stack, stacksize, func, arg) void (*func)(void *); void *arg; { + extern paddr_t fpu_curpcb; /* from locore.S */ struct pcb *pcbp; struct trapframe *tf; register_t sp, osp; @@ -161,12 +162,20 @@ cpu_fork(p1, p2, stack, stacksize, func, arg) if (round_page(sizeof(struct user)) > NBPG) panic("USPACE too small for user"); #endif + if (p1->p_md.md_regs->tf_cr30 == fpu_curpcb) + fpu_save(fpu_curpcb); pcbp = &p2->p_addr->u_pcb; bcopy(&p1->p_addr->u_pcb, pcbp, sizeof(*pcbp)); /* space is cached for the copy{in,out}'s pleasure */ pcbp->pcb_space = p2->p_vmspace->vm_map.pmap->pm_space; pcbp->pcb_uva = (vaddr_t)p2->p_addr; + /* reset any of the pending FPU exceptions from parent */ + pcbp->pcb_fpregs[0] = ((u_int64_t)HPPA_FPU_INIT) << 32; + pcbp->pcb_fpregs[1] = 0; + pcbp->pcb_fpregs[2] = 0; + pcbp->pcb_fpregs[3] = 0; + fdcache(HPPA_SID_KERNEL, (vaddr_t)&pcbp->pcb_fpregs[0], 8 * 4); sp = (register_t)p2->p_addr + NBPG; p2->p_md.md_regs = tf = (struct trapframe *)sp; @@ -192,7 +201,6 @@ cpu_fork(p1, p2, stack, stacksize, func, arg) tf->tf_sr7 = HPPA_SID_KERNEL; tf->tf_eiem = ~0; tf->tf_ipsw = PSW_C | PSW_Q | PSW_P | PSW_D | PSW_I /* | PSW_L */; - pcbp->pcb_fpregs[32] = 0; /* * Set up return value registers as libc:fork() expects diff --git a/sys/arch/hppa/include/cpu.h b/sys/arch/hppa/include/cpu.h index 7de30854e37..3d2fcfa67d2 100644 --- a/sys/arch/hppa/include/cpu.h +++ b/sys/arch/hppa/include/cpu.h @@ -1,7 +1,7 @@ -/* $OpenBSD: cpu.h,v 1.32 2002/09/17 03:51:49 mickey Exp $ */ +/* $OpenBSD: cpu.h,v 1.33 2002/10/07 14:38:40 mickey Exp $ */ /* - * Copyright (c) 2000-2001 Michael Shalayeff + * Copyright (c) 2000-2002 Michael Shalayeff * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -82,6 +82,7 @@ extern const char *cpu_typename; #define HPPA_FPUS 0xc0 #define HPPA_FPUVER(w) (((w) & 0x003ff800) >> 11) #define HPPA_FPU_OP(w) ((w) >> 26) +#define HPPA_FPU_UNMPL 0x9 #define HPPA_FPU_I 0x01 #define HPPA_FPU_U 0x02 #define HPPA_FPU_O 0x04 @@ -89,11 +90,12 @@ extern const char *cpu_typename; #define HPPA_FPU_V 0x10 #define HPPA_FPU_D 0x20 #define HPPA_FPU_T 0x40 +#define HPPA_FPU_T_POS 25 #define HPPA_FPU_RM 0x00000600 #define HPPA_FPU_CQ 0x00fff800 #define HPPA_FPU_C 0x04000000 #define HPPA_FPU_FLSH 27 -#define HPPA_FPU_INIT (HPPA_FPU_I | HPPA_FPU_U | HPPA_FPU_O | HPPA_FPU_Z | HPPA_FPU_V) +#define HPPA_FPU_INIT (HPPA_FPU_U | HPPA_FPU_O | HPPA_FPU_Z | HPPA_FPU_V) #define HPPA_PMSFUS 0x20 /* ??? */ /* |