diff options
author | nwhitehorn <nwhitehorn@FreeBSD.org> | 2015-02-22 21:40:27 +0000 |
---|---|---|
committer | nwhitehorn <nwhitehorn@FreeBSD.org> | 2015-02-22 21:40:27 +0000 |
commit | 99449144eaa7a166d2b773f5b69a60baf1d9e31c (patch) | |
tree | b937ece7929c309e55f30ba338c3a6e3491c2593 /sys/powerpc/aim | |
parent | d2889adcc557fdb9d7b6db385ac12ceeafedd6c9 (diff) | |
download | FreeBSD-src-99449144eaa7a166d2b773f5b69a60baf1d9e31c.zip FreeBSD-src-99449144eaa7a166d2b773f5b69a60baf1d9e31c.tar.gz |
Kernel support for the Vector-Scalar eXtension (VSX) found on the POWER7
and POWER8. This instruction set unifies the 32 64-bit scalar floating
point registers with the 32 128-bit vector registers into a single bank
of 64 128-bit registers. Kernel support mostly amounts to saving and
restoring the wider version of the floating point registers and making
sure that both scalar FP and vector registers are enabled once a VSX
instruction is executed. get_mcontext() and friends currently cannot
see the high bits, which will require a little more work.
As the system compiler (GCC 4.2) does not support VSX, making use of this
from userland requires either newer GCC or clang.
Relnotes: yes
Sponsored by: FreeBSD Foundation
Diffstat (limited to 'sys/powerpc/aim')
-rw-r--r-- | sys/powerpc/aim/trap.c | 14 | ||||
-rw-r--r-- | sys/powerpc/aim/trap_subr64.S | 2 |
2 files changed, 14 insertions, 2 deletions
diff --git a/sys/powerpc/aim/trap.c b/sys/powerpc/aim/trap.c index 2f30d6d..b0afffc 100644 --- a/sys/powerpc/aim/trap.c +++ b/sys/powerpc/aim/trap.c @@ -116,6 +116,7 @@ static struct powerpc_exception powerpc_exceptions[] = { { 0x0e00, "floating-point assist" }, { 0x0f00, "performance monitoring" }, { 0x0f20, "altivec unavailable" }, + { 0x0f40, "vsx unavailable" }, { 0x1000, "instruction tlb miss" }, { 0x1100, "data load tlb miss" }, { 0x1200, "data store tlb miss" }, @@ -230,6 +231,17 @@ trap(struct trapframe *frame) enable_vec(td); break; + case EXC_VSX: + KASSERT((td->td_pcb->pcb_flags & PCB_VSX) != PCB_VSX, + ("VSX already enabled for thread")); + if (!(td->td_pcb->pcb_flags & PCB_VEC)) + enable_vec(td); + if (!(td->td_pcb->pcb_flags & PCB_FPU)) + save_fpu(td); + td->td_pcb->pcb_flags |= PCB_VSX; + enable_fpu(td); + break; + case EXC_VECAST_G4: case EXC_VECAST_G5: /* @@ -709,7 +721,7 @@ fix_unaligned(struct thread *td, struct trapframe *frame) case EXC_ALI_LFD: case EXC_ALI_STFD: reg = EXC_ALI_RST(frame->cpu.aim.dsisr); - fpr = &td->td_pcb->pcb_fpu.fpr[reg]; + fpr = &td->td_pcb->pcb_fpu.fpr[reg].fpr; fputhread = PCPU_GET(fputhread); /* Juggle the FPU to ensure that we've initialized diff --git a/sys/powerpc/aim/trap_subr64.S b/sys/powerpc/aim/trap_subr64.S index de79845..76c2bae 100644 --- a/sys/powerpc/aim/trap_subr64.S +++ b/sys/powerpc/aim/trap_subr64.S @@ -359,7 +359,7 @@ CNAME(trapcode): li %r1,TRAP_GENTRAP ld %r1,0(%r1) mtlr %r1 - li %r1, 0xA0 /* How to get the vector from LR */ + li %r1, 0xe0 /* How to get the vector from LR */ blrl /* Branch to generictrap */ CNAME(trapcodeend): |