Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/powerpc/mpc6xx Add AltiVec routines for save_vec/en...
details: https://anonhg.NetBSD.org/src/rev/f301ca4a43db
branches: trunk
changeset: 533502:f301ca4a43db
user: matt <matt%NetBSD.org@localhost>
date: Tue Jul 02 15:22:47 2002 +0000
description:
Add AltiVec routines for save_vec/enable_vec/init_vec.
diffstat:
sys/arch/powerpc/mpc6xx/altivec.c | 170 ++++++++++++++++++++++++++++++++++++++
1 files changed, 170 insertions(+), 0 deletions(-)
diffs (174 lines):
diff -r a58c79e9dd0c -r f301ca4a43db sys/arch/powerpc/mpc6xx/altivec.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/powerpc/mpc6xx/altivec.c Tue Jul 02 15:22:47 2002 +0000
@@ -0,0 +1,170 @@
+/* $NetBSD: altivec.c,v 1.1 2002/07/02 15:22:47 matt Exp $ */
+
+/*
+ * Copyright (C) 1996 Wolfgang Solfrank.
+ * Copyright (C) 1996 TooLs GmbH.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/param.h>
+#include <sys/proc.h>
+#include <sys/systm.h>
+#include <sys/user.h>
+#include <sys/malloc.h>
+#include <sys/pool.h>
+
+#include <powerpc/altivec.h>
+#include <powerpc/spr.h>
+#include <powerpc/psl.h>
+
+struct pool vecpool;
+
+void
+enable_vec(struct proc *p)
+{
+ struct pcb *pcb = &p->p_addr->u_pcb;
+ struct trapframe *tf = trapframe(p);
+ struct vreg *vr = pcb->pcb_vr;
+ int msr, scratch;
+
+ /*
+ * Enable AltiVec when we return to user-mode.
+ */
+ tf->srr1 |= PSL_VEC;
+
+ /*
+ * Allocate a vreg structure if we haven't done so.
+ */
+ if (!(pcb->pcb_flags & PCB_ALTIVEC)) {
+ vr = pcb->pcb_vr = pool_get(&vecpool, PR_WAITOK);
+ memset(vr, 0, sizeof (*vr));
+ pcb->pcb_flags |= PCB_ALTIVEC;
+ }
+
+ /*
+ * Enable AltiVec temporarily
+ */
+ __asm __volatile ("mfmsr %0; oris %1,%0,%2@h; mtmsr %1; isync"
+ : "=r"(msr), "=r"(scratch)
+ : "J"(PSL_VEC));
+
+ /*
+ * Restore VSCR by first loading it into a vector and then into VSCR.
+ * (this needs to done before loading the user's vector registers
+ * since we need to a scratch vector register)
+ */
+ __asm __volatile("lvx %2,%0,%1; mtvscr %2" \
+ :: "r"(vr), "r"(offsetof(struct vreg, vreg[32])), "n"(0));
+
+ /*
+ * VRSAVE will be restored when trap frame returns
+ */
+ tf->vrsave = vr->vrsave;
+
+#define LVX(n,vr) __asm /*__volatile*/("lvx %2,%0,%1" \
+ :: "r"(vr), "r"(offsetof(struct vreg, vreg[n])), "n"(n));
+
+ /*
+ * Load all 32 vector registers
+ */
+ LVX( 0,vr); LVX( 1,vr); LVX( 2,vr); LVX( 3,vr);
+ LVX( 4,vr); LVX( 5,vr); LVX( 6,vr); LVX( 7,vr);
+ LVX( 8,vr); LVX( 9,vr); LVX(10,vr); LVX(11,vr);
+ LVX(12,vr); LVX(13,vr); LVX(14,vr); LVX(15,vr);
+
+ LVX(16,vr); LVX(17,vr); LVX(18,vr); LVX(19,vr);
+ LVX(20,vr); LVX(21,vr); LVX(22,vr); LVX(23,vr);
+ LVX(24,vr); LVX(25,vr); LVX(26,vr); LVX(27,vr);
+ LVX(28,vr); LVX(29,vr); LVX(30,vr); LVX(31,vr);
+
+ /*
+ * Restore MSR (turn off AltiVec)
+ */
+ __asm __volatile ("mtmsr %0; isync" :: "r"(msr));
+}
+
+void
+save_vec(struct proc *p)
+{
+ struct pcb *pcb = &p->p_addr->u_pcb;
+ struct trapframe *tf = trapframe(p);
+ struct vreg *vr = pcb->pcb_vr;
+ int msr, scratch;
+
+ /*
+ * Turn on AltiVEC
+ */
+ __asm __volatile ("mfmsr %0; oris %1,%0,%2@h; mtmsr %1; isync"
+ : "=r"(msr), "=r"(scratch)
+ : "J"(PSL_VEC));
+
+#define STVX(n,vr) __asm /*__volatile*/("stvx %2,%0,%1" \
+ :: "r"(vr), "r"(offsetof(struct vreg, vreg[n])), "n"(n));
+
+ /*
+ * Save the vector registers.
+ */
+ STVX( 0,vr); STVX( 1,vr); STVX( 2,vr); STVX( 3,vr);
+ STVX( 4,vr); STVX( 5,vr); STVX( 6,vr); STVX( 7,vr);
+ STVX( 8,vr); STVX( 9,vr); STVX(10,vr); STVX(11,vr);
+ STVX(12,vr); STVX(13,vr); STVX(14,vr); STVX(15,vr);
+
+ STVX(16,vr); STVX(17,vr); STVX(18,vr); STVX(19,vr);
+ STVX(20,vr); STVX(21,vr); STVX(22,vr); STVX(23,vr);
+ STVX(24,vr); STVX(25,vr); STVX(26,vr); STVX(27,vr);
+ STVX(28,vr); STVX(29,vr); STVX(30,vr); STVX(31,vr);
+
+ /*
+ * Save VSCR (this needs to be done after save the vector registers
+ * since we need to use one as scratch).
+ */
+ __asm __volatile("mfvscr %2; stvx %2,%0,%1" \
+ :: "r"(vr), "r"(offsetof(struct vreg, vreg[32])), "n"(0));
+
+ /*
+ * Save VRSAVE
+ */
+ vr->vrsave = tf->vrsave;
+
+ /*
+ * Restore MSR (turn off AltiVec).
+ */
+ __asm __volatile ("mtmsr %0; isync" :: "r"(msr));
+
+ /*
+ * Note that we aren't using any CPU resources
+ */
+ pcb->pcb_veccpu = NULL;
+ curcpu()->ci_vecproc = NULL;
+ tf->srr1 &= ~PSL_VEC;
+}
+
+void
+init_vec(void)
+{
+ pool_init(&vecpool, sizeof(struct vreg), 16, 0, 0, "vecpl", NULL);
+}
Home |
Main Index |
Thread Index |
Old Index