1209878Snwhitehorn/*-
2209878Snwhitehorn * Copyright (C) 1995-1997, 1999 Wolfgang Solfrank.
3209878Snwhitehorn * Copyright (C) 1995-1997, 1999 TooLs GmbH.
4209878Snwhitehorn * All rights reserved.
5209878Snwhitehorn *
6209878Snwhitehorn * Redistribution and use in source and binary forms, with or without
7209878Snwhitehorn * modification, are permitted provided that the following conditions
8209878Snwhitehorn * are met:
9209878Snwhitehorn * 1. Redistributions of source code must retain the above copyright
10209878Snwhitehorn *    notice, this list of conditions and the following disclaimer.
11209878Snwhitehorn * 2. Redistributions in binary form must reproduce the above copyright
12209878Snwhitehorn *    notice, this list of conditions and the following disclaimer in the
13209878Snwhitehorn *    documentation and/or other materials provided with the distribution.
14209878Snwhitehorn * 3. All advertising materials mentioning features or use of this software
15209878Snwhitehorn *    must display the following acknowledgement:
16209878Snwhitehorn *	This product includes software developed by TooLs GmbH.
17209878Snwhitehorn * 4. The name of TooLs GmbH may not be used to endorse or promote products
18209878Snwhitehorn *    derived from this software without specific prior written permission.
19209878Snwhitehorn *
20209878Snwhitehorn * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
21209878Snwhitehorn * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22209878Snwhitehorn * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23209878Snwhitehorn * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24209878Snwhitehorn * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25209878Snwhitehorn * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26209878Snwhitehorn * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27209878Snwhitehorn * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28209878Snwhitehorn * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29209878Snwhitehorn * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30209878Snwhitehorn *
31209878Snwhitehorn * $NetBSD: syncicache.c,v 1.2 1999/05/05 12:36:40 tsubai Exp $
32209878Snwhitehorn */
33209878Snwhitehorn
34209878Snwhitehorn#ifndef lint
35209878Snwhitehornstatic const char rcsid[] =
36209878Snwhitehorn  "$FreeBSD: releng/10.3/lib/libc/powerpc64/gen/syncicache.c 253750 2013-07-28 18:44:17Z avg $";
37209878Snwhitehorn#endif /* not lint */
38209878Snwhitehorn
39209878Snwhitehorn#include <sys/param.h>
40209878Snwhitehorn#if	defined(_KERNEL) || defined(_STANDALONE)
41209878Snwhitehorn#include <sys/time.h>
42209878Snwhitehorn#include <sys/proc.h>
43209878Snwhitehorn#include <vm/vm.h>
44209878Snwhitehorn#endif
45209878Snwhitehorn#include <sys/sysctl.h>
46209878Snwhitehorn
47253750Savg#include <machine/cpu.h>
48209878Snwhitehorn#include <machine/md_var.h>
49209878Snwhitehorn
50209878Snwhitehorn#ifdef _STANDALONE
51209878Snwhitehornint cacheline_size = 32;
52209878Snwhitehorn#endif
53209878Snwhitehorn
54209878Snwhitehorn#if	!defined(_KERNEL) && !defined(_STANDALONE)
55209878Snwhitehorn#include <stdlib.h>
56209878Snwhitehorn
57209878Snwhitehornint cacheline_size = 0;
58209878Snwhitehorn
59209878Snwhitehornstatic void getcachelinesize(void);
60209878Snwhitehorn
61209878Snwhitehornstatic void
62209878Snwhitehorngetcachelinesize()
63209878Snwhitehorn{
64209878Snwhitehorn	static int	cachemib[] = { CTL_MACHDEP, CPU_CACHELINE };
65209878Snwhitehorn	long		clen;
66209878Snwhitehorn
67209878Snwhitehorn	clen = sizeof(cacheline_size);
68209878Snwhitehorn
69209878Snwhitehorn	if (sysctl(cachemib, sizeof(cachemib) / sizeof(cachemib[0]),
70209878Snwhitehorn	    &cacheline_size, &clen, NULL, 0) < 0 || !cacheline_size) {
71209878Snwhitehorn		abort();
72209878Snwhitehorn	}
73209878Snwhitehorn}
74209878Snwhitehorn#endif
75209878Snwhitehorn
76209878Snwhitehornvoid
77209878Snwhitehorn__syncicache(void *from, int len)
78209878Snwhitehorn{
79209878Snwhitehorn	off_t	l, off;
80209878Snwhitehorn	char	*p;
81209878Snwhitehorn
82209878Snwhitehorn#if	!defined(_KERNEL) && !defined(_STANDALONE)
83209878Snwhitehorn	if (!cacheline_size)
84209878Snwhitehorn		getcachelinesize();
85209878Snwhitehorn#endif
86209878Snwhitehorn
87209878Snwhitehorn	off = (uintptr_t)from & (cacheline_size - 1);
88209878Snwhitehorn	l = len += off;
89209878Snwhitehorn	p = (char *)from - off;
90209878Snwhitehorn
91209878Snwhitehorn	do {
92209878Snwhitehorn		__asm __volatile ("dcbst 0,%0" :: "r"(p));
93209878Snwhitehorn		p += cacheline_size;
94209878Snwhitehorn	} while ((l -= cacheline_size) > 0);
95209878Snwhitehorn	__asm __volatile ("sync");
96209878Snwhitehorn	p = (char *)from - off;
97209878Snwhitehorn	do {
98209878Snwhitehorn		__asm __volatile ("icbi 0,%0" :: "r"(p));
99209878Snwhitehorn		p += cacheline_size;
100209878Snwhitehorn	} while ((len -= cacheline_size) > 0);
101209878Snwhitehorn	__asm __volatile ("sync; isync");
102209878Snwhitehorn}
103209878Snwhitehorn
104