Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch restructure the FPU and AltiVEC code so that it wor...
details: https://anonhg.NetBSD.org/src/rev/e6237ef21663
branches: trunk
changeset: 534495:e6237ef21663
user: chs <chs%NetBSD.org@localhost>
date: Sun Jul 28 07:07:44 2002 +0000
description:
restructure the FPU and AltiVEC code so that it works for MP.
diffstat:
sys/arch/macppc/include/intr.h | 11 +-
sys/arch/macppc/macppc/machdep.c | 90 ++++++++++++++-----
sys/arch/powerpc/include/altivec.h | 10 +-
sys/arch/powerpc/include/fpu.h | 9 +-
sys/arch/powerpc/mpc6xx/altivec.c | 133 +++++++++++++++++++++-------
sys/arch/powerpc/powerpc/fpu.c | 103 ++++++++++++++++++---
sys/arch/powerpc/powerpc/process_machdep.c | 8 +-
sys/arch/powerpc/powerpc/trap.c | 67 +++++---------
sys/arch/powerpc/powerpc/vm_machdep.c | 19 +--
9 files changed, 307 insertions(+), 143 deletions(-)
diffs (truncated from 811 to 300 lines):
diff -r 3aa08507a652 -r e6237ef21663 sys/arch/macppc/include/intr.h
--- a/sys/arch/macppc/include/intr.h Sun Jul 28 07:07:00 2002 +0000
+++ b/sys/arch/macppc/include/intr.h Sun Jul 28 07:07:44 2002 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: intr.h,v 1.14 2002/07/05 18:45:17 matt Exp $ */
+/* $NetBSD: intr.h,v 1.15 2002/07/28 07:07:46 chs Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -139,12 +139,13 @@
#define CNT_SOFTNET 66
#define CNT_SOFTSERIAL 67
-#define MACPPC_IPI_HALT 0x01
-#define MACPPC_IPI_FLUSH_FPU 0x02
+#ifdef MULTIPROCESSOR
+#define MACPPC_IPI_HALT 0x0001
+#define MACPPC_IPI_FLUSH_FPU 0x0002
+#define MACPPC_IPI_FLUSH_VEC 0x0004
-#ifdef MULTIPROCESSOR
struct cpu_info;
-void macppc_send_ipi(volatile struct cpu_info *, int);
+void macppc_send_ipi(volatile struct cpu_info *, u_long);
#endif
#endif /* _LOCORE */
diff -r 3aa08507a652 -r e6237ef21663 sys/arch/macppc/macppc/machdep.c
--- a/sys/arch/macppc/macppc/machdep.c Sun Jul 28 07:07:00 2002 +0000
+++ b/sys/arch/macppc/macppc/machdep.c Sun Jul 28 07:07:44 2002 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: machdep.c,v 1.116 2002/07/09 19:21:03 matt Exp $ */
+/* $NetBSD: machdep.c,v 1.117 2002/07/28 07:07:46 chs Exp $ */
/*
* Copyright (C) 1995, 1996 Wolfgang Solfrank.
@@ -35,6 +35,7 @@
#include "opt_ddb.h"
#include "opt_kgdb.h"
#include "opt_ipkdb.h"
+#include "opt_altivec.h"
#include "opt_multiprocessor.h"
#include "adb.h"
#include "zsc.h"
@@ -79,6 +80,9 @@
#include <machine/trap.h>
#include <machine/bus.h>
#include <machine/fpu.h>
+#ifdef ALTIVEC
+#include <powerpc/altivec.h>
+#endif
#include <dev/cons.h>
#include <dev/ofw/openfirm.h>
@@ -673,43 +677,81 @@
}
#ifdef MULTIPROCESSOR
+/*
+ * Save a process's FPU state to its PCB. The state is in another CPU
+ * (though by the time our IPI is processed, it may have been flushed already).
+ */
void
-save_fpu_proc(p)
+mp_save_fpu_proc(p)
struct proc *p;
{
- volatile struct cpu_info *fpcpu;
+ struct pcb *pcb = &p->p_addr->u_pcb;
+ struct cpu_info *fpcpu;
int i;
- extern volatile int IPI[]; /* XXX */
- fpcpu = p->p_addr->u_pcb.pcb_fpcpu;
- if (fpcpu == curcpu()) {
- save_fpu(p);
- return;
- }
+ /*
+ * Send an IPI to the other CPU with the data and wait for that CPU
+ * to flush the data. Note that the other CPU might have switched
+ * to a different proc's FPU state by the time it receives the IPI,
+ * but that will only result in an unnecessary reload.
+ */
-#if 0
- printf("save_fpu_proc{%d} pid = %d, fpcpu->ci_cpuid = %d\n",
- cpu_number(), p->p_pid, fpcpu->ci_cpuid);
-#endif
-
+ fpcpu = pcb->pcb_fpcpu;
macppc_send_ipi(fpcpu, MACPPC_IPI_FLUSH_FPU);
/* Wait for flush. */
#if 0
- while (fpcpu->ci_fpuproc);
+ while (pcb->pcb_fpcpu)
+ ;
#else
for (i = 0; i < 0x3fffffff; i++) {
- if (fpcpu->ci_fpuproc == NULL)
- goto done;
+ if (pcb->pcb_fpcpu == NULL)
+ return;
}
- printf("save_fpu_proc{%d} pid = %d, fpcpu->ci_cpuid = %d\n",
+ printf("mp_save_fpu_proc{%d} pid = %d, fpcpu->ci_cpuid = %d\n",
cpu_number(), p->p_pid, fpcpu->ci_cpuid);
- printf("IPI[0] = 0x%x, IPI[1] = 0x%x\n", IPI[0], IPI[1]);
- printf("cpl 0x%x 0x%x\n", cpu_info[0].ci_cpl, cpu_info[1].ci_cpl);
- printf("ipending 0x%x 0x%x\n", cpu_info[0].ci_ipending, cpu_info[1].ci_ipending);
- panic("save_fpu_proc");
-done:;
-
+ panic("mp_save_fpu_proc");
#endif
}
+
+#ifdef ALTIVEC
+/*
+ * Save a process's AltiVEC state to its PCB. The state may be in any CPU.
+ * The process must either be curproc or traced by curproc (and stopped).
+ * (The point being that the process must not run on another CPU during
+ * this function).
+ */
+void
+mp_save_vec_proc(p)
+ struct proc *p;
+{
+ struct pcb *pcb = &p->p_addr->u_pcb;
+ struct cpu_info *veccpu;
+ int i;
+
+ /*
+ * Send an IPI to the other CPU with the data and wait for that CPU
+ * to flush the data. Note that the other CPU might have switched
+ * to a different proc's AltiVEC state by the time it receives the IPI,
+ * but that will only result in an unnecessary reload.
+ */
+
+ veccpu = pcb->pcb_veccpu;
+ macppc_send_ipi(veccpu, MACPPC_IPI_FLUSH_VEC);
+
+ /* Wait for flush. */
+#if 0
+ while (pcb->pcb_veccpu)
+ ;
+#else
+ for (i = 0; i < 0x3fffffff; i++) {
+ if (pcb->pcb_veccpu == NULL)
+ return;
+ }
+ printf("mp_save_vec_proc{%d} pid = %d, veccpu->ci_cpuid = %d\n",
+ cpu_number(), p->p_pid, veccpu->ci_cpuid);
+ panic("mp_save_vec_proc");
+#endif
+}
+#endif /* ALTIVEC */
#endif /* MULTIPROCESSOR */
diff -r 3aa08507a652 -r e6237ef21663 sys/arch/powerpc/include/altivec.h
--- a/sys/arch/powerpc/include/altivec.h Sun Jul 28 07:07:00 2002 +0000
+++ b/sys/arch/powerpc/include/altivec.h Sun Jul 28 07:07:44 2002 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: altivec.h,v 1.3 2002/07/18 22:51:57 matt Exp $ */
+/* $NetBSD: altivec.h,v 1.4 2002/07/28 07:07:44 chs Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -43,8 +43,12 @@
#define VSCR_NJ 0x00010000 /* Non Java-IEEE-C9X FP mode */
#ifdef _KERNEL
-void save_vec(struct proc *p);
-void enable_vec(struct proc *p);
+void enable_vec(void);
+void save_vec_cpu(void);
+void save_vec_proc(struct proc *);
+#ifdef MULTIPROCESSOR
+void mp_save_vec_proc(struct proc *);
+#endif
void init_vec(void);
void vzeropage(paddr_t);
void vcopypage(paddr_t, paddr_t); /* dst, src */
diff -r 3aa08507a652 -r e6237ef21663 sys/arch/powerpc/include/fpu.h
--- a/sys/arch/powerpc/include/fpu.h Sun Jul 28 07:07:00 2002 +0000
+++ b/sys/arch/powerpc/include/fpu.h Sun Jul 28 07:07:44 2002 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: fpu.h,v 1.6 2002/05/19 16:55:43 jdolecek Exp $ */
+/* $NetBSD: fpu.h,v 1.7 2002/07/28 07:07:44 chs Exp $ */
/*-
* Copyright (C) 1996 Wolfgang Solfrank.
@@ -76,9 +76,12 @@
#if defined(PPC_MPC6XX)
#define PPC_HAVE_FPU
-void enable_fpu(struct proc *);
-void save_fpu(struct proc *);
+void enable_fpu(void);
+void save_fpu_cpu(void);
void save_fpu_proc(struct proc *);
+#ifdef MULTIPROCESSOR
+void mp_save_fpu_proc(struct proc *);
+#endif
#endif /* PPC_HAVE_FPU */
#endif /* _KERNEL */
diff -r 3aa08507a652 -r e6237ef21663 sys/arch/powerpc/mpc6xx/altivec.c
--- a/sys/arch/powerpc/mpc6xx/altivec.c Sun Jul 28 07:07:00 2002 +0000
+++ b/sys/arch/powerpc/mpc6xx/altivec.c Sun Jul 28 07:07:44 2002 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: altivec.c,v 1.5 2002/07/25 23:46:47 matt Exp $ */
+/* $NetBSD: altivec.c,v 1.6 2002/07/28 07:07:45 chs Exp $ */
/*
* Copyright (C) 1996 Wolfgang Solfrank.
@@ -44,17 +44,16 @@
struct pool vecpool;
void
-enable_vec(struct proc *p)
+enable_vec()
{
+ struct cpu_info *ci = curcpu();
+ struct proc *p = curproc;
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;
+ KASSERT(pcb->pcb_veccpu == NULL);
/*
* Allocate a vreg structure if we haven't done so.
@@ -62,9 +61,11 @@
if (!(pcb->pcb_flags & PCB_ALTIVEC)) {
vr = pcb->pcb_vr = pool_get(&vecpool, PR_WAITOK);
pcb->pcb_flags |= PCB_ALTIVEC;
+
/*
* Initialize the vectors with NaNs
*/
+
for (scratch = 0; scratch < 32; scratch++) {
vr->vreg[scratch][0] = 0x7FFFDEAD;
vr->vreg[scratch][1] = 0x7FFFDEAD;
@@ -76,16 +77,20 @@
}
/*
- * Enable AltiVec temporarily
+ * Enable AltiVec temporarily (and disable interrupts).
*/
- __asm __volatile ("mfmsr %0; oris %1,%0,%2@h; mtmsr %1; isync"
- : "=r"(msr), "=r"(scratch)
- : "J"(PSL_VEC));
+ msr = mfmsr();
+ mtmsr((msr & ~PSL_EE) | PSL_VEC);
+ __asm __volatile ("isync");
+ if (ci->ci_vecproc) {
+ save_vec_cpu();
+ }
+ KASSERT(curcpu()->ci_vecproc == NULL);
/*
* 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)
+ * since we need to use a scratch vector register)
*/
__asm __volatile("vxor %2,%2,%2; lvewx %2,%0,%1; mtvscr %2" \
:: "r"(vr), "r"(offsetof(struct vreg, vscr)), "n"(0));
@@ -110,27 +115,46 @@
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);
+ __asm __volatile ("isync");
+
+ /*
+ * Enable AltiVec when we return to user-mode.
+ * Record the new ownership of the AltiVec unit.
+ */
+ tf->srr1 |= PSL_VEC;
+ curcpu()->ci_vecproc = p;
+ pcb->pcb_veccpu = curcpu();
+ __asm __volatile ("sync");
/*
* Restore MSR (turn off AltiVec)
*/
- __asm __volatile ("mtmsr %0; isync" :: "r"(msr));
+ mtmsr(msr);
}
void
-save_vec(struct proc *p)
Home |
Main Index |
Thread Index |
Old Index