/* $OpenBSD: cachectl.c,v 1.1 2005/08/01 11:54:24 miod Exp $ */ /* $NetBSD: sys_machdep.c,v 1.17 1997/05/19 10:15:00 veego Exp $ */ /* * Copyright (c) 1982, 1986, 1993 * The Regents of the University of California. 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 THE REGENTS OR CONTRIBUTORS 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. * * @(#)sys_machdep.c 8.2 (Berkeley) 1/13/94 */ #include #include #include #include #include #include /* * Note that what we do here for a 68040 is different than HP-UX. * * In HP-UX they either act on a line (len == 16), a page (len == NBPG) * or the whole cache (len == anything else). * * In BSD we attempt to be more optimal when acting on "odd" sizes. * For lengths up to 1024 we do all affected lines, up to 2 * NBPG we * do pages, above that we do the entire cache. */ /*ARGSUSED1*/ int cachectl(struct proc *p, int req, vaddr_t addr, int len) { int error = 0; #if defined(M68040) || defined(M68060) if (mmutype <= MMU_68040) { int inc = 0; int doall = 0; paddr_t pa = 0; vaddr_t end = 0; #ifdef COMPAT_HPUX extern struct emul emul_hpux; if ((p->p_emul == &emul_hpux) && len != 16 && len != NBPG) doall = 1; #endif if (addr == 0 || ((req & ~CC_EXTPURGE) != CC_PURGE && len > 2*NBPG)) doall = 1; if (!doall) { end = addr + len; if (len <= 1024) { addr = addr & ~0xF; inc = 16; } else { addr = addr & ~PGOFSET; inc = NBPG; } } do { /* * Convert to physical address if needed. * If translation fails, we perform operation on * entire cache (XXX is this a rational thing to do?) */ if (!doall && (pa == 0 || ((int)addr & PGOFSET) == 0)) { if (pmap_extract( p->p_vmspace->vm_map.pmap, addr, &pa) == FALSE) doall = 1; } switch (req) { case CC_EXTPURGE|CC_IPURGE: case CC_IPURGE: if (doall) { DCFA(); ICPA(); } else if (inc == 16) { DCFL(pa); ICPL(pa); } else if (inc == NBPG) { DCFP(pa); ICPP(pa); } break; case CC_EXTPURGE|CC_PURGE: case CC_PURGE: if (doall) DCFA(); /* note: flush not purge */ else if (inc == 16) DCPL(pa); else if (inc == NBPG) DCPP(pa); break; case CC_EXTPURGE|CC_FLUSH: case CC_FLUSH: if (doall) DCFA(); else if (inc == 16) DCFL(pa); else if (inc == NBPG) DCFP(pa); break; default: error = EINVAL; break; } if (doall) break; pa += inc; addr += inc; } while (addr < end); return (error); } #endif switch (req) { case CC_EXTPURGE|CC_PURGE: case CC_EXTPURGE|CC_FLUSH: #if defined(CACHE_HAVE_PAC) if (ectype == EC_PHYS) PCIA(); /* FALLTHROUGH */ #endif case CC_PURGE: case CC_FLUSH: DCIU(); break; case CC_EXTPURGE|CC_IPURGE: #if defined(CACHE_HAVE_PAC) if (ectype == EC_PHYS) PCIA(); else #endif DCIU(); /* FALLTHROUGH */ case CC_IPURGE: ICIA(); break; default: error = EINVAL; break; } return (error); }