sys_machdep.c revision 1.3
11.3Sthorpej/* $NetBSD: sys_machdep.c,v 1.3 2003/04/02 00:00:46 thorpej Exp $ */ 21.1Schs 31.1Schs/* 41.1Schs * Copyright (c) 1982, 1986, 1993 51.1Schs * The Regents of the University of California. All rights reserved. 61.1Schs * 71.1Schs * Redistribution and use in source and binary forms, with or without 81.1Schs * modification, are permitted provided that the following conditions 91.1Schs * are met: 101.1Schs * 1. Redistributions of source code must retain the above copyright 111.1Schs * notice, this list of conditions and the following disclaimer. 121.1Schs * 2. Redistributions in binary form must reproduce the above copyright 131.1Schs * notice, this list of conditions and the following disclaimer in the 141.1Schs * documentation and/or other materials provided with the distribution. 151.1Schs * 3. All advertising materials mentioning features or use of this software 161.1Schs * must display the following acknowledgement: 171.1Schs * This product includes software developed by the University of 181.1Schs * California, Berkeley and its contributors. 191.1Schs * 4. Neither the name of the University nor the names of its contributors 201.1Schs * may be used to endorse or promote products derived from this software 211.1Schs * without specific prior written permission. 221.1Schs * 231.1Schs * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 241.1Schs * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 251.1Schs * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 261.1Schs * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 271.1Schs * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 281.1Schs * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 291.1Schs * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 301.1Schs * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 311.1Schs * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 321.1Schs * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 331.1Schs * SUCH DAMAGE. 341.1Schs * 351.1Schs * @(#)sys_machdep.c 8.2 (Berkeley) 1/13/94 361.1Schs */ 371.1Schs 381.1Schs#include <sys/cdefs.h> 391.1Schs__KERNEL_RCSID(0, "$NetBSD"); 401.1Schs 411.1Schs#include "opt_compat_hpux.h" 421.1Schs 431.1Schs#include <sys/param.h> 441.1Schs#include <sys/proc.h> 451.1Schs#include <sys/mount.h> 461.1Schs 471.1Schs#include <uvm/uvm_extern.h> 481.1Schs 491.2Sthorpej#include <sys/sa.h> 501.1Schs#include <sys/syscallargs.h> 511.1Schs 521.1Schs#include <machine/cpu.h> 531.1Schs#include <m68k/cacheops.h> 541.1Schs 551.1Schs/* XXX should be in an include file somewhere */ 561.1Schs#define CC_PURGE 1 571.1Schs#define CC_FLUSH 2 581.1Schs#define CC_IPURGE 4 591.1Schs#define CC_EXTPURGE 0x80000000 601.1Schs/* XXX end should be */ 611.1Schs 621.1Schs/* 631.1Schs * Note that what we do here on 040/060 for BSD is different than for HP-UX. 641.1Schs * 651.3Sthorpej * In 'pux they either act on a line (len == 16), a page (len == PAGE_SIZE) 661.1Schs * or the whole cache (len == anything else). 671.1Schs * 681.1Schs * In BSD we attempt to be more optimal when acting on "odd" sizes. 691.3Sthorpej * For lengths up to 1024 we do all affected lines, up to 2*PAGE_SIZE we 701.1Schs * do pages, above that we do the entire cache. 711.1Schs */ 721.1Schs/*ARGSUSED1*/ 731.1Schsint 741.1Schscachectl1(req, addr, len, p) 751.1Schs unsigned long req; 761.1Schs vaddr_t addr; 771.1Schs size_t len; 781.1Schs struct proc *p; 791.1Schs{ 801.1Schs int error = 0; 811.1Schs 821.1Schs#if defined(M68040) || defined(M68060) 831.1Schs if (mmutype == MMU_68040) { 841.1Schs int inc = 0; 851.1Schs boolean_t doall = FALSE; 861.1Schs paddr_t pa = 0; 871.1Schs vaddr_t end = 0; 881.1Schs#ifdef COMPAT_HPUX 891.1Schs extern struct emul emul_hpux; 901.1Schs 911.1Schs if ((p->p_emul == &emul_hpux) && 921.3Sthorpej len != 16 && len != PAGE_SIZE) 931.1Schs doall = 1; 941.1Schs#endif 951.1Schs 961.1Schs if (addr == 0 || 971.1Schs#if defined(M68060) 981.1Schs (cputype == CPU_68040 && req & CC_IPURGE) || 991.1Schs#else 1001.1Schs (req & CC_IPURGE) || 1011.1Schs#endif 1021.3Sthorpej ((req & ~CC_EXTPURGE) != CC_PURGE && len > 2 * PAGE_SIZE)) 1031.1Schs doall = 1; 1041.1Schs 1051.1Schs if (!doall) { 1061.1Schs end = addr + len; 1071.1Schs if (len <= 1024) { 1081.1Schs addr = addr & ~0xf; 1091.1Schs inc = 16; 1101.1Schs } else { 1111.1Schs addr = addr & ~PGOFSET; 1121.3Sthorpej inc = PAGE_SIZE; 1131.1Schs } 1141.1Schs } 1151.1Schs do { 1161.1Schs /* 1171.1Schs * Convert to physical address if needed. 1181.1Schs * If translation fails, we perform operation on 1191.1Schs * entire cache. 1201.1Schs */ 1211.1Schs if (!doall && 1221.1Schs (pa == 0 || m68k_page_offset(addr) == 0)) { 1231.1Schs if (pmap_extract(p->p_vmspace->vm_map.pmap, 1241.1Schs addr, &pa) == FALSE) 1251.1Schs doall = 1; 1261.1Schs } 1271.1Schs switch (req) { 1281.1Schs case CC_EXTPURGE|CC_IPURGE: 1291.1Schs case CC_IPURGE: 1301.1Schs if (doall) { 1311.1Schs DCFA(); 1321.1Schs ICPA(); 1331.1Schs } else if (inc == 16) { 1341.1Schs DCFL(pa); 1351.1Schs ICPL(pa); 1361.3Sthorpej } else if (inc == PAGE_SIZE) { 1371.1Schs DCFP(pa); 1381.1Schs ICPP(pa); 1391.1Schs } 1401.1Schs break; 1411.1Schs 1421.1Schs case CC_EXTPURGE|CC_PURGE: 1431.1Schs case CC_PURGE: 1441.1Schs if (doall) 1451.1Schs DCFA(); /* note: flush not purge */ 1461.1Schs else if (inc == 16) 1471.1Schs DCPL(pa); 1481.3Sthorpej else if (inc == PAGE_SIZE) 1491.1Schs DCPP(pa); 1501.1Schs break; 1511.1Schs 1521.1Schs case CC_EXTPURGE|CC_FLUSH: 1531.1Schs case CC_FLUSH: 1541.1Schs if (doall) 1551.1Schs DCFA(); 1561.1Schs else if (inc == 16) 1571.1Schs DCFL(pa); 1581.3Sthorpej else if (inc == PAGE_SIZE) 1591.1Schs DCFP(pa); 1601.1Schs break; 1611.1Schs 1621.1Schs default: 1631.1Schs error = EINVAL; 1641.1Schs break; 1651.1Schs } 1661.1Schs if (doall) 1671.1Schs break; 1681.1Schs pa += inc; 1691.1Schs addr += inc; 1701.1Schs } while (addr < end); 1711.1Schs return (error); 1721.1Schs } 1731.1Schs#endif 1741.1Schs switch (req) { 1751.1Schs case CC_EXTPURGE|CC_PURGE: 1761.1Schs case CC_EXTPURGE|CC_FLUSH: 1771.1Schs#if defined(CACHE_HAVE_PAC) 1781.1Schs if (ectype == EC_PHYS) 1791.1Schs PCIA(); 1801.1Schs /* fall into... */ 1811.1Schs#endif 1821.1Schs case CC_PURGE: 1831.1Schs case CC_FLUSH: 1841.1Schs DCIU(); 1851.1Schs break; 1861.1Schs case CC_EXTPURGE|CC_IPURGE: 1871.1Schs#if defined(CACHE_HAVE_PAC) 1881.1Schs if (ectype == EC_PHYS) 1891.1Schs PCIA(); 1901.1Schs else 1911.1Schs#endif 1921.1Schs DCIU(); 1931.1Schs /* fall into... */ 1941.1Schs case CC_IPURGE: 1951.1Schs ICIA(); 1961.1Schs break; 1971.1Schs default: 1981.1Schs error = EINVAL; 1991.1Schs break; 2001.1Schs } 2011.1Schs return (error); 2021.1Schs} 2031.1Schs 2041.1Schsint 2051.2Sthorpejsys_sysarch(l, v, retval) 2061.2Sthorpej struct lwp *l; 2071.1Schs void *v; 2081.1Schs register_t *retval; 2091.1Schs{ 2101.1Schs 2111.1Schs return (ENOSYS); 2121.1Schs} 2131.1Schs 2141.1Schs#if defined(amiga) || defined(x68k) 2151.1Schs 2161.1Schs/* 2171.1Schs * DMA cache control 2181.1Schs */ 2191.1Schs 2201.1Schs/*ARGSUSED1*/ 2211.1Schsint 2221.1Schsdma_cachectl(addr, len) 2231.1Schs caddr_t addr; 2241.1Schs int len; 2251.1Schs{ 2261.1Schs#if defined(M68040) || defined(M68060) 2271.1Schs int inc = 0; 2281.1Schs int pa = 0; 2291.1Schs caddr_t end; 2301.1Schs 2311.1Schs if (mmutype != MMU_68040) { 2321.1Schs return (0); 2331.1Schs } 2341.1Schs 2351.1Schs end = addr + len; 2361.1Schs if (len <= 1024) { 2371.1Schs addr = (caddr_t)((vaddr_t)addr & ~0xf); 2381.1Schs inc = 16; 2391.1Schs } else { 2401.1Schs addr = (caddr_t)((vaddr_t)addr & ~PGOFSET); 2411.3Sthorpej inc = PAGE_SIZE; 2421.1Schs } 2431.1Schs do { 2441.1Schs /* 2451.1Schs * Convert to physical address. 2461.1Schs */ 2471.1Schs if (pa == 0 || ((vaddr_t)addr & PGOFSET) == 0) { 2481.1Schs pa = kvtop(addr); 2491.1Schs } 2501.1Schs if (inc == 16) { 2511.1Schs DCFL(pa); 2521.1Schs ICPL(pa); 2531.1Schs } else { 2541.1Schs DCFP(pa); 2551.1Schs ICPP(pa); 2561.1Schs } 2571.1Schs pa += inc; 2581.1Schs addr += inc; 2591.1Schs } while (addr < end); 2601.1Schs#endif /* defined(M68040) || defined(M68060) */ 2611.1Schs return (0); 2621.1Schs} 2631.1Schs#endif /* defined(amiga) || defined(x68k) */ 264