Rewrite the inner loop of vcopypage() and vzeropage() to be entirely

in inline asm and include turning the DMMU off and back on. This
prevents the compiler (especially gcc -O0) from inserting accesses to
locations in virtual address space when such accesses would fail.
This commit is contained in:
nathanw 2005-04-11 18:35:38 +00:00
parent c674ab7b1d
commit 1e16e443e6

View File

@ -1,4 +1,4 @@
/* $NetBSD: altivec.c,v 1.8 2005/02/22 02:59:46 matt Exp $ */
/* $NetBSD: altivec.c,v 1.9 2005/04/11 18:35:38 nathanw Exp $ */
/*
* Copyright (C) 1996 Wolfgang Solfrank.
@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: altivec.c,v 1.8 2005/02/22 02:59:46 matt Exp $");
__KERNEL_RCSID(0, "$NetBSD: altivec.c,v 1.9 2005/04/11 18:35:38 nathanw Exp $");
#include "opt_multiprocessor.h"
@ -263,28 +263,29 @@ vzeropage(paddr_t pa)
__asm("stvx %1,0,%0" :: "r"(vp), "n"(ZERO_VEC));
__asm("vxor %0,%0,%0" :: "n"(ZERO_VEC));
/*
* Turn off data relocation (DMMU off).
*/
msr &= ~PSL_DR;
__asm __volatile("sync; mtmsr %0; isync" :: "r"(msr));
/*
* Zero the page using a single cache line.
*/
do {
__asm("stvx %2,%0,%1" :: "b"(pa), "r"( 0), "n"(ZERO_VEC));
__asm("stvxl %2,%0,%1" :: "b"(pa), "r"(16), "n"(ZERO_VEC));
__asm("stvx %2,%0,%1" :: "b"(pa), "r"(32), "n"(ZERO_VEC));
__asm("stvxl %2,%0,%1" :: "b"(pa), "r"(48), "n"(ZERO_VEC));
pa += 64;
} while (pa < ea);
/*
* Restore data relocation (DMMU on);
*/
msr |= PSL_DR;
__asm __volatile("sync; mtmsr %0; isync" :: "r"(msr));
__asm __volatile(
" sync ;"
" mfmsr %[msr];"
" rlwinm %[msr],%[msr],0,28,26;" /* Clear PSL_DR */
" mtmsr %[msr];" /* Turn off DMMU */
" isync;"
"1: stvx %[zv], %[pa], %[off0];"
" stvxl %[zv], %[pa], %[off16];"
" stvx %[zv], %[pa], %[off32];"
" stvxl %[zv], %[pa], %[off48];"
" addi %[pa], %[pa], 64;"
" cmplw %[pa], %[ea];"
" blt+ 1b;"
" ori %[msr], %[msr], 0x10;" /* Set PSL_DR */
" sync;"
" mtmsr %[msr];" /* Turn on DMMU */
" isync;"
:: [msr] "r"(msr), [pa] "b"(pa), [ea] "b"(ea),
[off0] "r"(0), [off16] "r"(16), [off32] "r"(32), [off48] "r"(48),
[zv] "n"(ZERO_VEC));
/*
* Restore VEC register (now that we can access the stack again).
@ -323,29 +324,31 @@ vcopypage(paddr_t dst, paddr_t src)
__asm("stvx %2,%1,%0" :: "b"(vp), "r"(16), "n"(HI_VEC));
/*
* Turn off data relocation (DMMU off).
* Copy the page using a single cache line, with DMMU
* disabled. On most PPCs, two vector registers occupy one
* cache line.
*/
msr &= ~PSL_DR;
__asm __volatile("sync; mtmsr %0; isync" :: "r"(msr));
/*
* Copy the page using a single cache line. On most PPCs, two
* vector registers occupy one cache line.
*/
do {
__asm("lvx %2,%0,%1" :: "b"(src), "r"( 0), "n"(LO_VEC));
__asm("stvx %2,%0,%1" :: "b"(dst), "r"( 0), "n"(LO_VEC));
__asm("lvxl %2,%0,%1" :: "b"(src), "r"(16), "n"(HI_VEC));
__asm("stvxl %2,%0,%1" :: "b"(dst), "r"(16), "n"(HI_VEC));
src += 32;
dst += 32;
} while (dst < edst);
/*
* Restore data relocation (DMMU on);
*/
msr |= PSL_DR;
__asm __volatile("sync; mtmsr %0; isync" :: "r"(msr));
__asm __volatile(
" sync ;"
" mfmsr %[msr];"
" rlwinm %[msr],%[msr],0,28,26;" /* Clear PSL_DR */
" mtmsr %[msr];" /* Turn off DMMU */
" isync;"
"1: lvx %[lv], %[src], %[off0];"
" stvx %[lv], %[dst], %[off0];"
" lvxl %[hv], %[src], %[off16];"
" stvxl %[hv], %[dst], %[off16];"
" addi %[src], %[src], 32;"
" addi %[dst], %[dst], 32;"
" cmplw %[dst], %[edst];"
" blt+ 1b;"
" ori %[msr], %[msr], 0x10;" /* Set PSL_DR */
" sync;"
" mtmsr %[msr];" /* Turn on DMMU */
" isync;"
:: [msr] "r"(msr), [src] "b"(src), [dst] "b"(dst),
[edst] "b"(edst), [off0] "r"(0), [off16] "r"(16),
[lv] "n"(LO_VEC), [hv] "n"(HI_VEC));
/*
* Restore VEC registers (now that we can access the stack again).