flush the dcache after accessing pcb_fpregs.
we access it with the DTLB both on and off, so we need to avoid bad cache aliases.
This commit is contained in:
parent
508451c5cd
commit
b7bd18170e
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: fpu.c,v 1.5 2004/03/26 14:11:01 drochner Exp $ */
|
||||
/* $NetBSD: fpu.c,v 1.6 2004/06/15 16:29:01 chs Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2002 The NetBSD Foundation, Inc.
|
||||
|
@ -41,7 +41,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.5 2004/03/26 14:11:01 drochner Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.6 2004/06/15 16:29:01 chs Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -87,7 +87,7 @@ u_int fpu_csw;
|
|||
paddr_t fpu_cur_uspace;
|
||||
|
||||
/* In locore.S, this swaps states in and out of the FPU. */
|
||||
void hppa_fpu_swap(struct user *, struct user *);
|
||||
void hppa_fpu_swap(struct pcb *, struct pcb *);
|
||||
|
||||
/* XXX see trap.c */
|
||||
void hppa_trapsignal_hack(struct lwp *, int, u_long);
|
||||
|
@ -231,10 +231,13 @@ hppa_fpu_flush(struct lwp *l)
|
|||
* state is currently in it, swap it out.
|
||||
*/
|
||||
|
||||
if (fpu_present &&
|
||||
fpu_cur_uspace != 0 &&
|
||||
fpu_cur_uspace == tf->tf_cr30)
|
||||
hppa_fpu_swap(l->l_addr, NULL);
|
||||
if (!fpu_present || fpu_cur_uspace == 0 ||
|
||||
fpu_cur_uspace != tf->tf_cr30) {
|
||||
return;
|
||||
}
|
||||
|
||||
hppa_fpu_swap(&l->l_addr->u_pcb, NULL);
|
||||
fpu_cur_uspace = 0;
|
||||
}
|
||||
|
||||
#ifdef FPEMUL
|
||||
|
@ -252,7 +255,8 @@ hppa_fpu_ls(struct trapframe *frame, struct lwp *l)
|
|||
u_int offset, index, im5;
|
||||
void *fpreg;
|
||||
u_int r0 = 0;
|
||||
|
||||
int error;
|
||||
|
||||
/*
|
||||
* Get the instruction that we're emulating,
|
||||
* and break it down. Using HP bit notation,
|
||||
|
@ -339,9 +343,12 @@ hppa_fpu_ls(struct trapframe *frame, struct lwp *l)
|
|||
KASSERT(offset == frame->tf_ior);
|
||||
|
||||
/* Perform the load or store. */
|
||||
return (inst & OPCODE_STORE) ?
|
||||
error = (inst & OPCODE_STORE) ?
|
||||
copyout(fpreg, (void *) offset, 1 << log2size) :
|
||||
copyin((const void *) offset, fpreg, 1 << log2size);
|
||||
fdcache(HPPA_SID_KERNEL, (vaddr_t)fpreg,
|
||||
sizeof(l->l_addr->u_pcb.pcb_fpregs));
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -406,6 +413,8 @@ hppa_fpu_emulate(struct trapframe *frame, struct lwp *l)
|
|||
break;
|
||||
}
|
||||
|
||||
fdcache(HPPA_SID_KERNEL, (vaddr_t)fpregs,
|
||||
sizeof(l->l_addr->u_pcb.pcb_fpregs));
|
||||
if (exception)
|
||||
hppa_trapsignal_hack(l, (exception & UNIMPLEMENTEDEXCEPTION) ?
|
||||
SIGILL : SIGFPE, frame->tf_iioq_head);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: process_machdep.c,v 1.3 2003/08/31 01:26:35 chs Exp $ */
|
||||
/* $NetBSD: process_machdep.c,v 1.4 2004/06/15 16:29:01 chs Exp $ */
|
||||
|
||||
/* $OpenBSD: process_machdep.c,v 1.3 1999/06/18 05:19:52 mickey Exp $ */
|
||||
|
||||
|
@ -33,7 +33,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: process_machdep.c,v 1.3 2003/08/31 01:26:35 chs Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: process_machdep.c,v 1.4 2004/06/15 16:29:01 chs Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -41,6 +41,8 @@ __KERNEL_RCSID(0, "$NetBSD: process_machdep.c,v 1.3 2003/08/31 01:26:35 chs Exp
|
|||
#include <sys/ptrace.h>
|
||||
#include <sys/user.h>
|
||||
|
||||
#include <machine/cpufunc.h>
|
||||
|
||||
int
|
||||
process_read_regs(struct lwp *l, struct reg *regs)
|
||||
{
|
||||
|
@ -61,6 +63,8 @@ int
|
|||
process_read_fpregs(struct lwp *l, struct fpreg *fpregs)
|
||||
{
|
||||
bcopy(l->l_addr->u_pcb.pcb_fpregs, fpregs, sizeof(*fpregs));
|
||||
fdcache(HPPA_SID_KERNEL, (vaddr_t)&l->l_addr->u_pcb.pcb_fpregs,
|
||||
sizeof(*fpregs));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -68,6 +72,8 @@ int
|
|||
process_write_fpregs(struct lwp *l, struct fpreg *fpregs)
|
||||
{
|
||||
bcopy(fpregs, l->l_addr->u_pcb.pcb_fpregs, sizeof(*fpregs));
|
||||
fdcache(HPPA_SID_KERNEL, (vaddr_t)&l->l_addr->u_pcb.pcb_fpregs,
|
||||
sizeof(*fpregs));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: trap.S,v 1.8 2003/10/10 15:07:43 chs Exp $ */
|
||||
/* $NetBSD: trap.S,v 1.9 2004/06/15 16:29:01 chs Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2002 The NetBSD Foundation, Inc.
|
||||
|
@ -1013,7 +1013,9 @@ $emulate_fpu:
|
|||
EXIT(TLABEL(emu))
|
||||
|
||||
/*
|
||||
* void hppa_fpu_swap(struct user *user_out, struct user *user_in);
|
||||
* void hppa_fpu_swap(paddr_t out, paddr_t in);
|
||||
* or
|
||||
* void hppa_fpu_swap(struct pcb *out, NULL);
|
||||
*/
|
||||
LEAF_ENTRY(hppa_fpu_swap)
|
||||
|
||||
|
@ -1027,18 +1029,17 @@ LEAF_ENTRY(hppa_fpu_swap)
|
|||
*/
|
||||
|
||||
/*
|
||||
* Assuming that user_out and user_in aren't
|
||||
* both NULL, we will have to run coprocessor
|
||||
* instructions, so we'd better enable it.
|
||||
* Assuming that out and in aren't both NULL,
|
||||
* we will have to run coprocessor instructions,
|
||||
* so we'd better enable it.
|
||||
*
|
||||
* Also, branch if there's no FPU state
|
||||
* to swap out.
|
||||
* Also, branch if there's no FPU state to swap out.
|
||||
*/
|
||||
mfctl %ccr, %r1
|
||||
depi 3, 25, 2, %r1
|
||||
comb,= %r0, %arg0, $fpu_swap_in
|
||||
mtctl %r1, %ccr
|
||||
|
||||
|
||||
/*
|
||||
* Swap out the current FPU state.
|
||||
*/
|
||||
|
@ -1076,6 +1077,19 @@ LEAF_ENTRY(hppa_fpu_swap)
|
|||
fstds,ma %fr30, 8(%arg0)
|
||||
fstds %fr31, 0(%arg0)
|
||||
|
||||
ldo -248(%arg0), %arg0
|
||||
ldil L%dcache_stride, %r1
|
||||
ldw R%dcache_stride(%r1), %r1
|
||||
fdc,m %r1(%arg0)
|
||||
fdc,m %r1(%arg0)
|
||||
fdc,m %r1(%arg0)
|
||||
fdc,m %r1(%arg0)
|
||||
fdc,m %r1(%arg0)
|
||||
fdc,m %r1(%arg0)
|
||||
fdc,m %r1(%arg0)
|
||||
fdc,m %r1(%arg0)
|
||||
sync
|
||||
|
||||
$fpu_swap_in:
|
||||
|
||||
/*
|
||||
|
@ -1132,6 +1146,19 @@ $fpu_swap_in:
|
|||
fldds,ma -8(%arg1), %fr1
|
||||
fldds 0(%arg1), %fr0 /* fr0 must be restored last */
|
||||
|
||||
ldo -248(%arg1), %arg1
|
||||
ldil L%dcache_stride, %r1
|
||||
ldw R%dcache_stride(%r1), %r1
|
||||
fdc,m %r1(%arg1)
|
||||
fdc,m %r1(%arg1)
|
||||
fdc,m %r1(%arg1)
|
||||
fdc,m %r1(%arg1)
|
||||
fdc,m %r1(%arg1)
|
||||
fdc,m %r1(%arg1)
|
||||
fdc,m %r1(%arg1)
|
||||
fdc,m %r1(%arg1)
|
||||
sync
|
||||
|
||||
$fpu_swap_done:
|
||||
|
||||
/* Increment the switch count and return. */
|
||||
|
|
Loading…
Reference in New Issue