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