summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
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 /* ??? */
/*