diff options
author | nwhitehorn <nwhitehorn@FreeBSD.org> | 2010-10-05 18:08:07 +0000 |
---|---|---|
committer | nwhitehorn <nwhitehorn@FreeBSD.org> | 2010-10-05 18:08:07 +0000 |
commit | 306dfd834d94e6a3ebf9ea15c35486b2b5939284 (patch) | |
tree | 38f5b53bf739baeb37b7ea83a7d9e9a2f35176c4 | |
parent | bc318f82cfe1aeb52138931a69460858259cc811 (diff) | |
download | FreeBSD-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.c | 4 | ||||
-rw-r--r-- | sys/powerpc/aim/trap.c | 16 | ||||
-rw-r--r-- | sys/powerpc/include/altivec.h | 3 | ||||
-rw-r--r-- | sys/powerpc/include/pcb.h | 2 | ||||
-rw-r--r-- | sys/powerpc/include/trap_aim.h | 5 |
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 */ |