sys_machdep.c revision 1.1
1/*	$NetBSD: sys_machdep.c,v 1.1 2002/11/03 02:29:40 chs Exp $	*/
2
3/*
4 * Copyright (c) 1982, 1986, 1993
5 *	The Regents of the University of California.  All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 *    must display the following acknowledgement:
17 *	This product includes software developed by the University of
18 *	California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors
20 *    may be used to endorse or promote products derived from this software
21 *    without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 *
35 *	@(#)sys_machdep.c	8.2 (Berkeley) 1/13/94
36 */
37
38#include <sys/cdefs.h>
39__KERNEL_RCSID(0, "$NetBSD");
40
41#include "opt_compat_hpux.h"
42
43#include <sys/param.h>
44#include <sys/proc.h>
45#include <sys/mount.h>
46
47#include <uvm/uvm_extern.h>
48
49#include <sys/syscallargs.h>
50
51#include <machine/cpu.h>
52#include <m68k/cacheops.h>
53
54/* XXX should be in an include file somewhere */
55#define CC_PURGE	1
56#define CC_FLUSH	2
57#define CC_IPURGE	4
58#define CC_EXTPURGE	0x80000000
59/* XXX end should be */
60
61/*
62 * Note that what we do here on 040/060 for BSD is different than for HP-UX.
63 *
64 * In 'pux they either act on a line (len == 16), a page (len == NBPG)
65 * or the whole cache (len == anything else).
66 *
67 * In BSD we attempt to be more optimal when acting on "odd" sizes.
68 * For lengths up to 1024 we do all affected lines, up to 2*NBPG we
69 * do pages, above that we do the entire cache.
70 */
71/*ARGSUSED1*/
72int
73cachectl1(req, addr, len, p)
74	unsigned long req;
75	vaddr_t	addr;
76	size_t len;
77	struct proc *p;
78{
79	int error = 0;
80
81#if defined(M68040) || defined(M68060)
82	if (mmutype == MMU_68040) {
83		int inc = 0;
84		boolean_t doall = FALSE;
85		paddr_t pa = 0;
86		vaddr_t end = 0;
87#ifdef COMPAT_HPUX
88		extern struct emul emul_hpux;
89
90		if ((p->p_emul == &emul_hpux) &&
91		    len != 16 && len != NBPG)
92			doall = 1;
93#endif
94
95		if (addr == 0 ||
96#if defined(M68060)
97		    (cputype == CPU_68040 && req & CC_IPURGE) ||
98#else
99		    (req & CC_IPURGE) ||
100#endif
101		    ((req & ~CC_EXTPURGE) != CC_PURGE && len > 2 * NBPG))
102			doall = 1;
103
104		if (!doall) {
105			end = addr + len;
106			if (len <= 1024) {
107				addr = addr & ~0xf;
108				inc = 16;
109			} else {
110				addr = addr & ~PGOFSET;
111				inc = NBPG;
112			}
113		}
114		do {
115			/*
116			 * Convert to physical address if needed.
117			 * If translation fails, we perform operation on
118			 * entire cache.
119			 */
120			if (!doall &&
121			    (pa == 0 || m68k_page_offset(addr) == 0)) {
122				if (pmap_extract(p->p_vmspace->vm_map.pmap,
123				    addr, &pa) == FALSE)
124					doall = 1;
125			}
126			switch (req) {
127			case CC_EXTPURGE|CC_IPURGE:
128			case CC_IPURGE:
129				if (doall) {
130					DCFA();
131					ICPA();
132				} else if (inc == 16) {
133					DCFL(pa);
134					ICPL(pa);
135				} else if (inc == NBPG) {
136					DCFP(pa);
137					ICPP(pa);
138				}
139				break;
140
141			case CC_EXTPURGE|CC_PURGE:
142			case CC_PURGE:
143				if (doall)
144					DCFA();	/* note: flush not purge */
145				else if (inc == 16)
146					DCPL(pa);
147				else if (inc == NBPG)
148					DCPP(pa);
149				break;
150
151			case CC_EXTPURGE|CC_FLUSH:
152			case CC_FLUSH:
153				if (doall)
154					DCFA();
155				else if (inc == 16)
156					DCFL(pa);
157				else if (inc == NBPG)
158					DCFP(pa);
159				break;
160
161			default:
162				error = EINVAL;
163				break;
164			}
165			if (doall)
166				break;
167			pa += inc;
168			addr += inc;
169		} while (addr < end);
170		return (error);
171	}
172#endif
173	switch (req) {
174	case CC_EXTPURGE|CC_PURGE:
175	case CC_EXTPURGE|CC_FLUSH:
176#if defined(CACHE_HAVE_PAC)
177		if (ectype == EC_PHYS)
178			PCIA();
179		/* fall into... */
180#endif
181	case CC_PURGE:
182	case CC_FLUSH:
183		DCIU();
184		break;
185	case CC_EXTPURGE|CC_IPURGE:
186#if defined(CACHE_HAVE_PAC)
187		if (ectype == EC_PHYS)
188			PCIA();
189		else
190#endif
191		DCIU();
192		/* fall into... */
193	case CC_IPURGE:
194		ICIA();
195		break;
196	default:
197		error = EINVAL;
198		break;
199	}
200	return (error);
201}
202
203int
204sys_sysarch(p, v, retval)
205	struct proc *p;
206	void *v;
207	register_t *retval;
208{
209
210	return (ENOSYS);
211}
212
213#if defined(amiga) || defined(x68k)
214
215/*
216 * DMA cache control
217 */
218
219/*ARGSUSED1*/
220int
221dma_cachectl(addr, len)
222	caddr_t	addr;
223	int len;
224{
225#if defined(M68040) || defined(M68060)
226	int inc = 0;
227	int pa = 0;
228	caddr_t end;
229
230	if (mmutype != MMU_68040) {
231		return (0);
232	}
233
234	end = addr + len;
235	if (len <= 1024) {
236		addr = (caddr_t)((vaddr_t)addr & ~0xf);
237		inc = 16;
238	} else {
239		addr = (caddr_t)((vaddr_t)addr & ~PGOFSET);
240		inc = NBPG;
241	}
242	do {
243		/*
244		 * Convert to physical address.
245		 */
246		if (pa == 0 || ((vaddr_t)addr & PGOFSET) == 0) {
247			pa = kvtop(addr);
248		}
249		if (inc == 16) {
250			DCFL(pa);
251			ICPL(pa);
252		} else {
253			DCFP(pa);
254			ICPP(pa);
255		}
256		pa += inc;
257		addr += inc;
258	} while (addr < end);
259#endif	/* defined(M68040) || defined(M68060) */
260	return (0);
261}
262#endif	/* defined(amiga) || defined(x68k) */
263