summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorMichael Shalayeff <mickey@cvs.openbsd.org>2002-10-07 14:38:41 +0000
committerMichael Shalayeff <mickey@cvs.openbsd.org>2002-10-07 14:38:41 +0000
commit276264b6d6880707af7f40f523f8ce860f20cefa (patch)
treee2e2321ddb859dbd8c32c2f32086c896a7ad36e7 /sys/arch
parentd9c8c53f017f2cc45df40cda9e68668a47da4746 (diff)
on implementations w/ fpu included unimplemented instructions
are signaled through the exception trap w/ invalid opcode marked instruction in the exception registers, not through the emulation trap (as long as the fpu is enabled, of course). parse emulation from the exception trap as well as the emulation trap and fix the dispatcher into usable condition. parse invalid op exception on trap and signal the user appropriately. reset the exception on exec and for child on fork. the later is appropriate since exceptions are delayed until next fpu instruction, which was in the parent indeed, let him get it. save parent's fpu context on fork before cipying it, if the parent owned the fpu.
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/hppa/hppa/fpemu.S122
-rw-r--r--sys/arch/hppa/hppa/locore.S218
-rw-r--r--sys/arch/hppa/hppa/machdep.c11
-rw-r--r--sys/arch/hppa/hppa/trap.c74
-rw-r--r--sys/arch/hppa/hppa/vm_machdep.c14
-rw-r--r--sys/arch/hppa/include/cpu.h8
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 /* ??? */
/*