syncicache.c revision 107571
1251964Sjfv/*
2251964Sjfv * Copyright (C) 1995-1997, 1999 Wolfgang Solfrank.
3283620Serj * Copyright (C) 1995-1997, 1999 TooLs GmbH.
4251964Sjfv * All rights reserved.
5251964Sjfv *
6251964Sjfv * Redistribution and use in source and binary forms, with or without
7251964Sjfv * modification, are permitted provided that the following conditions
8251964Sjfv * are met:
9251964Sjfv * 1. Redistributions of source code must retain the above copyright
10251964Sjfv *    notice, this list of conditions and the following disclaimer.
11251964Sjfv * 2. Redistributions in binary form must reproduce the above copyright
12251964Sjfv *    notice, this list of conditions and the following disclaimer in the
13251964Sjfv *    documentation and/or other materials provided with the distribution.
14251964Sjfv * 3. All advertising materials mentioning features or use of this software
15251964Sjfv *    must display the following acknowledgement:
16251964Sjfv *	This product includes software developed by TooLs GmbH.
17251964Sjfv * 4. The name of TooLs GmbH may not be used to endorse or promote products
18251964Sjfv *    derived from this software without specific prior written permission.
19251964Sjfv *
20251964Sjfv * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
21251964Sjfv * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22251964Sjfv * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23251964Sjfv * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24251964Sjfv * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25251964Sjfv * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26251964Sjfv * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27251964Sjfv * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28251964Sjfv * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29251964Sjfv * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30251964Sjfv *
31251964Sjfv * $NetBSD: syncicache.c,v 1.2 1999/05/05 12:36:40 tsubai Exp $
32251964Sjfv */
33251964Sjfv
34251964Sjfv#ifndef lint
35251964Sjfvstatic const char rcsid[] =
36251964Sjfv  "$FreeBSD: head/lib/libc/powerpc/gen/syncicache.c 107571 2002-12-04 07:25:14Z grehan $";
37251964Sjfv#endif /* not lint */
38251964Sjfv
39251964Sjfv#include <sys/param.h>
40251964Sjfv#if	defined(_KERNEL) || defined(_STANDALONE)
41251964Sjfv#include <sys/time.h>
42251964Sjfv#include <sys/proc.h>
43251964Sjfv#include <vm/vm.h>
44251964Sjfv#endif
45251964Sjfv#include <sys/sysctl.h>
46251964Sjfv
47251964Sjfv#include <machine/cpu.h>
48251964Sjfv
49251964Sjfv#if	defined(_KERNEL) || defined(_STANDALONE)
50251964Sjfv#ifndef	CACHELINESIZE
51251964Sjfv#error "Must know the size of a cache line"
52251964Sjfv#endif
53251964Sjfv#else
54251964Sjfvstatic void getcachelinesize(void);
55251964Sjfv
56251964Sjfvstatic int _cachelinesize;
57251964Sjfv#define	CACHELINESIZE	_cachelinesize
58251964Sjfv
59251964Sjfvstatic void
60251964Sjfvgetcachelinesize()
61251964Sjfv{
62251964Sjfv	static int	cachemib[] = { CTL_MACHDEP, CPU_CACHELINE };
63251964Sjfv	int		clen;
64251964Sjfv
65251964Sjfv	clen = sizeof(_cachelinesize);
66251964Sjfv
67251964Sjfv	if (sysctl(cachemib, sizeof(cachemib) / sizeof(cachemib[0]),
68251964Sjfv	    &_cachelinesize, &clen, NULL, 0) < 0 || !_cachelinesize) {
69251964Sjfv		abort();
70251964Sjfv	}
71251964Sjfv}
72251964Sjfv#endif
73251964Sjfv
74251964Sjfvvoid
75251964Sjfv__syncicache(void *from, int len)
76251964Sjfv{
77251964Sjfv	int	l, off;
78251964Sjfv	char	*p;
79251964Sjfv
80251964Sjfv#if	!defined(_KERNEL) && !defined(_STANDALONE)
81251964Sjfv	if (!_cachelinesize)
82251964Sjfv		getcachelinesize();
83251964Sjfv#endif
84251964Sjfv	off = (u_int)from & (CACHELINESIZE - 1);
85251964Sjfv	l = len += off;
86251964Sjfv	p = (char *)from - off;
87251964Sjfv	do {
88251964Sjfv		__asm __volatile ("dcbst 0,%0" :: "r"(p));
89251964Sjfv		p += CACHELINESIZE;
90251964Sjfv	} while ((l -= CACHELINESIZE) > 0);
91251964Sjfv	__asm __volatile ("sync");
92251964Sjfv	p = (char *)from - off;
93251964Sjfv	do {
94251964Sjfv		__asm __volatile ("icbi 0,%0" :: "r"(p));
95251964Sjfv		p += CACHELINESIZE;
96251964Sjfv	} while ((len -= CACHELINESIZE) > 0);
97251964Sjfv	__asm __volatile ("sync; isync");
98251964Sjfv}
99251964Sjfv