summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornwhitehorn <nwhitehorn@FreeBSD.org>2010-10-05 18:08:07 +0000
committernwhitehorn <nwhitehorn@FreeBSD.org>2010-10-05 18:08:07 +0000
commit306dfd834d94e6a3ebf9ea15c35486b2b5939284 (patch)
tree38f5b53bf739baeb37b7ea83a7d9e9a2f35176c4
parentbc318f82cfe1aeb52138931a69460858259cc811 (diff)
downloadFreeBSD-src-306dfd834d94e6a3ebf9ea15c35486b2b5939284.zip
FreeBSD-src-306dfd834d94e6a3ebf9ea15c35486b2b5939284.tar.gz
Handle vector assist traps without a kernel panic, by setting denormalized
values to zero. A correct solution would involve emulating vector operations on denormalized values, but this has little effect on accuracy and is much less complicated for now. MFC after: 2 weeks
-rw-r--r--sys/powerpc/aim/machdep.c4
-rw-r--r--sys/powerpc/aim/trap.c16
-rw-r--r--sys/powerpc/include/altivec.h3
-rw-r--r--sys/powerpc/include/pcb.h2
-rw-r--r--sys/powerpc/include/trap_aim.h5
5 files changed, 23 insertions, 7 deletions
diff --git a/sys/powerpc/aim/machdep.c b/sys/powerpc/aim/machdep.c
index a197681..9dec1f7 100644
--- a/sys/powerpc/aim/machdep.c
+++ b/sys/powerpc/aim/machdep.c
@@ -489,8 +489,8 @@ powerpc_init(vm_offset_t startkernel, vm_offset_t endkernel,
bcopy(generictrap, (void *)EXC_SC, (size_t)&trapsize);
bcopy(generictrap, (void *)EXC_FPA, (size_t)&trapsize);
bcopy(generictrap, (void *)EXC_VEC, (size_t)&trapsize);
- bcopy(generictrap, (void *)EXC_VECAST, (size_t)&trapsize);
- bcopy(generictrap, (void *)EXC_THRM, (size_t)&trapsize);
+ bcopy(generictrap, (void *)EXC_VECAST_G4, (size_t)&trapsize);
+ bcopy(generictrap, (void *)EXC_VECAST_G5, (size_t)&trapsize);
__syncicache(EXC_RSVD, EXC_LAST - EXC_RSVD);
/*
diff --git a/sys/powerpc/aim/trap.c b/sys/powerpc/aim/trap.c
index 6130eab..db48e7b 100644
--- a/sys/powerpc/aim/trap.c
+++ b/sys/powerpc/aim/trap.c
@@ -203,9 +203,19 @@ trap(struct trapframe *frame)
enable_vec(td);
break;
- case EXC_VECAST:
- printf("Vector assist exception!\n");
- sig = SIGILL;
+ case EXC_VECAST_G4:
+ case EXC_VECAST_G5:
+ /*
+ * We get a VPU assist exception for IEEE mode
+ * vector operations on denormalized floats.
+ * Emulating this is a giant pain, so for now,
+ * just switch off IEEE mode and treat them as
+ * zero.
+ */
+
+ save_vec(td);
+ td->td_pcb->pcb_vec.vscr |= ALTIVEC_VSCR_NJ;
+ enable_vec(td);
break;
case EXC_ALI:
diff --git a/sys/powerpc/include/altivec.h b/sys/powerpc/include/altivec.h
index ba16a0b..9a6c5d3 100644
--- a/sys/powerpc/include/altivec.h
+++ b/sys/powerpc/include/altivec.h
@@ -29,6 +29,9 @@
#ifndef _MACHINE_ALTIVEC_H_
#define _MACHINE_ALTIVEC_H_
+#define ALTIVEC_VSCR_NJ 0x00010000 /* Enable non-Java mode */
+#define ALTIVEC_VSCR_SAT 0x00000001 /* Saturation status bit */
+
void enable_vec(struct thread *);
void save_vec(struct thread *);
diff --git a/sys/powerpc/include/pcb.h b/sys/powerpc/include/pcb.h
index 65e3c17..a037276 100644
--- a/sys/powerpc/include/pcb.h
+++ b/sys/powerpc/include/pcb.h
@@ -59,7 +59,7 @@ struct pcb {
uint32_t vr[32][4];
register_t vrsave;
register_t spare[2];
- register_t vscr;
+ register_t vscr; /* aligned at vector element 3 */
} pcb_vec __aligned(16); /* Vector processor */
unsigned int pcb_veccpu; /* which CPU had our vector
stuff. */
diff --git a/sys/powerpc/include/trap_aim.h b/sys/powerpc/include/trap_aim.h
index 8370f56..afb77db 100644
--- a/sys/powerpc/include/trap_aim.h
+++ b/sys/powerpc/include/trap_aim.h
@@ -54,9 +54,12 @@
/* The following is only available on the 601: */
#define EXC_RUNMODETRC 0x2000 /* Run Mode/Trace Exception */
+/* The following are only available on 970(G5): */
+#define EXC_VECAST_G5 0x1700 /* AltiVec Assist */
+
/* The following are only available on 7400(G4): */
#define EXC_VEC 0x0f20 /* AltiVec Unavailable */
-#define EXC_VECAST 0x1600 /* AltiVec Assist */
+#define EXC_VECAST_G4 0x1600 /* AltiVec Assist */
/* The following are only available on 604/750/7400: */
#define EXC_PERF 0x0f00 /* Performance Monitoring */
OpenPOWER on IntegriCloud