123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- /*-
- * SPDX-License-Identifier: BSD-4-Clause
- *
- * 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.
- *
- * $NetBSD: fpu.c,v 1.5 2001/07/22 11:29:46 wiz Exp $
- */
- #include <sys/cdefs.h>
- __FBSDID("$FreeBSD$");
- #include <sys/param.h>
- #include <sys/proc.h>
- #include <sys/systm.h>
- #include <sys/limits.h>
- #include <machine/altivec.h>
- #include <machine/pcb.h>
- #include <machine/psl.h>
- static void
- save_vec_int(struct thread *td)
- {
- int msr;
- struct pcb *pcb;
- pcb = td->td_pcb;
- /*
- * Temporarily re-enable the vector unit during the save
- */
- msr = mfmsr();
- mtmsr(msr | PSL_VEC);
- /*
- * Save the vector registers and VSCR to the PCB
- */
- #define STVX(n) __asm ("stvx %1,0,%0" \
- :: "b"(pcb->pcb_vec.vr[n]), "n"(n));
- STVX(0); STVX(1); STVX(2); STVX(3);
- STVX(4); STVX(5); STVX(6); STVX(7);
- STVX(8); STVX(9); STVX(10); STVX(11);
- STVX(12); STVX(13); STVX(14); STVX(15);
- STVX(16); STVX(17); STVX(18); STVX(19);
- STVX(20); STVX(21); STVX(22); STVX(23);
- STVX(24); STVX(25); STVX(26); STVX(27);
- STVX(28); STVX(29); STVX(30); STVX(31);
- #undef STVX
- __asm __volatile("mfvscr 0; stvewx 0,0,%0" :: "b"(&pcb->pcb_vec.vscr));
- /*
- * Disable vector unit again
- */
- isync();
- mtmsr(msr);
- }
- void
- enable_vec(struct thread *td)
- {
- int msr;
- struct pcb *pcb;
- struct trapframe *tf;
- pcb = td->td_pcb;
- tf = trapframe(td);
- /*
- * Save the thread's Altivec CPU number, and set the CPU's current
- * vector thread
- */
- td->td_pcb->pcb_veccpu = PCPU_GET(cpuid);
- PCPU_SET(vecthread, td);
- /*
- * Enable the vector unit for when the thread returns from the
- * exception. If this is the first time the unit has been used by
- * the thread, initialise the vector registers and VSCR to 0, and
- * set the flag to indicate that the vector unit is in use.
- */
- tf->srr1 |= PSL_VEC;
- if (!(pcb->pcb_flags & PCB_VEC)) {
- memset(&pcb->pcb_vec, 0, sizeof pcb->pcb_vec);
- pcb->pcb_flags |= PCB_VEC;
- }
- /*
- * Temporarily enable the vector unit so the registers
- * can be restored.
- */
- msr = mfmsr();
- mtmsr(msr | 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 use a scratch vector register)
- */
- __asm __volatile("vxor 0,0,0; lvewx 0,0,%0; mtvscr 0" \
- :: "b"(&pcb->pcb_vec.vscr));
- #define LVX(n) __asm ("lvx " #n ",0,%0" \
- :: "b"(&pcb->pcb_vec.vr[n]));
- LVX(0); LVX(1); LVX(2); LVX(3);
- LVX(4); LVX(5); LVX(6); LVX(7);
- LVX(8); LVX(9); LVX(10); LVX(11);
- LVX(12); LVX(13); LVX(14); LVX(15);
- LVX(16); LVX(17); LVX(18); LVX(19);
- LVX(20); LVX(21); LVX(22); LVX(23);
- LVX(24); LVX(25); LVX(26); LVX(27);
- LVX(28); LVX(29); LVX(30); LVX(31);
- #undef LVX
- isync();
- mtmsr(msr);
- }
- void
- save_vec(struct thread *td)
- {
- struct pcb *pcb;
- pcb = td->td_pcb;
- save_vec_int(td);
- /*
- * Clear the current vec thread and pcb's CPU id
- * XXX should this be left clear to allow lazy save/restore ?
- */
- pcb->pcb_veccpu = INT_MAX;
- PCPU_SET(vecthread, NULL);
- }
- /*
- * Save altivec state without dropping ownership. This will only save state if
- * the current vector-thread is `td'.
- */
- void
- save_vec_nodrop(struct thread *td)
- {
- if (td == PCPU_GET(vecthread))
- save_vec_int(td);
- }
|