xref: /freebsd-src/sys/powerpc/include/cpufunc.h (revision 95ee2897e98f5d444f26ed2334cc7c439f9c16c6)
1d27f1d4cSBenno Rice /*-
2*4d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
371e3c308SPedro F. Giffuni  *
4d27f1d4cSBenno Rice  * Copyright (c) 1998 Doug Rabson
5d27f1d4cSBenno Rice  * All rights reserved.
6d27f1d4cSBenno Rice  *
7d27f1d4cSBenno Rice  * Redistribution and use in source and binary forms, with or without
8d27f1d4cSBenno Rice  * modification, are permitted provided that the following conditions
9d27f1d4cSBenno Rice  * are met:
10d27f1d4cSBenno Rice  * 1. Redistributions of source code must retain the above copyright
11d27f1d4cSBenno Rice  *    notice, this list of conditions and the following disclaimer.
12d27f1d4cSBenno Rice  * 2. Redistributions in binary form must reproduce the above copyright
13d27f1d4cSBenno Rice  *    notice, this list of conditions and the following disclaimer in the
14d27f1d4cSBenno Rice  *    documentation and/or other materials provided with the distribution.
15d27f1d4cSBenno Rice  *
16d27f1d4cSBenno Rice  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17d27f1d4cSBenno Rice  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18d27f1d4cSBenno Rice  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19d27f1d4cSBenno Rice  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20d27f1d4cSBenno Rice  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21d27f1d4cSBenno Rice  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22d27f1d4cSBenno Rice  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23d27f1d4cSBenno Rice  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24d27f1d4cSBenno Rice  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25d27f1d4cSBenno Rice  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26d27f1d4cSBenno Rice  * SUCH DAMAGE.
27d27f1d4cSBenno Rice  */
28d27f1d4cSBenno Rice 
29d27f1d4cSBenno Rice #ifndef _MACHINE_CPUFUNC_H_
30d27f1d4cSBenno Rice #define	_MACHINE_CPUFUNC_H_
31d27f1d4cSBenno Rice 
32d27f1d4cSBenno Rice #ifdef _KERNEL
33d27f1d4cSBenno Rice 
34d27f1d4cSBenno Rice #include <sys/types.h>
35d27f1d4cSBenno Rice 
36abc5579eSBenno Rice #include <machine/psl.h>
378464af79SRafal Jaworowski #include <machine/spr.h>
38abc5579eSBenno Rice 
39d74ac681SMatthew Dillon struct thread;
407e1f6dfeSJohn Baldwin 
419917bd81SPeter Grehan #ifdef KDB
4212640815SMarcel Moolenaar void breakpoint(void);
43b5f9b5b8SMaxim Sobolev #else
44b5f9b5b8SMaxim Sobolev static __inline void
breakpoint(void)45b5f9b5b8SMaxim Sobolev breakpoint(void)
46b5f9b5b8SMaxim Sobolev {
47b5f9b5b8SMaxim Sobolev 
48b5f9b5b8SMaxim Sobolev 	return;
49b5f9b5b8SMaxim Sobolev }
5067e945baSAndrew Gallatin #endif
51d27f1d4cSBenno Rice 
52abc5579eSBenno Rice /* CPU register mangling inlines */
53abc5579eSBenno Rice 
54abc5579eSBenno Rice static __inline void
mtmsr(register_t value)556da4e60aSBenno Rice mtmsr(register_t value)
56abc5579eSBenno Rice {
57a6b989ffSDavid E. O'Brien 
581a6f777eSPeter Grehan 	__asm __volatile ("mtmsr %0; isync" :: "r"(value));
59abc5579eSBenno Rice }
60abc5579eSBenno Rice 
61c3e289e1SNathan Whitehorn #ifdef __powerpc64__
62c3e289e1SNathan Whitehorn static __inline void
mtmsrd(register_t value)63c3e289e1SNathan Whitehorn mtmsrd(register_t value)
64c3e289e1SNathan Whitehorn {
65c3e289e1SNathan Whitehorn 
66c3e289e1SNathan Whitehorn 	__asm __volatile ("mtmsrd %0; isync" :: "r"(value));
67c3e289e1SNathan Whitehorn }
68c3e289e1SNathan Whitehorn #endif
69c3e289e1SNathan Whitehorn 
706da4e60aSBenno Rice static __inline register_t
mfmsr(void)71abc5579eSBenno Rice mfmsr(void)
72abc5579eSBenno Rice {
736da4e60aSBenno Rice 	register_t value;
74abc5579eSBenno Rice 
75abc5579eSBenno Rice 	__asm __volatile ("mfmsr %0" : "=r"(value));
76abc5579eSBenno Rice 
77abc5579eSBenno Rice 	return (value);
78abc5579eSBenno Rice }
79abc5579eSBenno Rice 
80c3e289e1SNathan Whitehorn #ifndef __powerpc64__
81abc5579eSBenno Rice static __inline void
mtsrin(vm_offset_t va,register_t value)82b2df36e7SBenno Rice mtsrin(vm_offset_t va, register_t value)
83b2df36e7SBenno Rice {
84b2df36e7SBenno Rice 
855ccc0779SJustin Hibbits 	__asm __volatile ("mtsrin %0,%1; isync" :: "r"(value), "r"(va));
86b2df36e7SBenno Rice }
87b2df36e7SBenno Rice 
88b2df36e7SBenno Rice static __inline register_t
mfsrin(vm_offset_t va)89b2df36e7SBenno Rice mfsrin(vm_offset_t va)
90b2df36e7SBenno Rice {
91b2df36e7SBenno Rice 	register_t value;
92b2df36e7SBenno Rice 
93b2df36e7SBenno Rice 	__asm __volatile ("mfsrin %0,%1" : "=r"(value) : "r"(va));
94b2df36e7SBenno Rice 
95b2df36e7SBenno Rice 	return (value);
96b2df36e7SBenno Rice }
97c3e289e1SNathan Whitehorn #endif
98b2df36e7SBenno Rice 
992971d3bbSNathan Whitehorn static __inline register_t
mfctrl(void)1002971d3bbSNathan Whitehorn mfctrl(void)
1012971d3bbSNathan Whitehorn {
1022971d3bbSNathan Whitehorn 	register_t value;
1032971d3bbSNathan Whitehorn 
1042971d3bbSNathan Whitehorn 	__asm __volatile ("mfspr %0,136" : "=r"(value));
1052971d3bbSNathan Whitehorn 
1062971d3bbSNathan Whitehorn 	return (value);
1072971d3bbSNathan Whitehorn }
1082971d3bbSNathan Whitehorn 
109b2df36e7SBenno Rice static __inline void
mtdec(register_t value)1106da4e60aSBenno Rice mtdec(register_t value)
111abc5579eSBenno Rice {
112a6b989ffSDavid E. O'Brien 
113abc5579eSBenno Rice 	__asm __volatile ("mtdec %0" :: "r"(value));
114abc5579eSBenno Rice }
115abc5579eSBenno Rice 
1166da4e60aSBenno Rice static __inline register_t
mfdec(void)117abc5579eSBenno Rice mfdec(void)
118abc5579eSBenno Rice {
1196da4e60aSBenno Rice 	register_t value;
120abc5579eSBenno Rice 
121abc5579eSBenno Rice 	__asm __volatile ("mfdec %0" : "=r"(value));
122abc5579eSBenno Rice 
123abc5579eSBenno Rice 	return (value);
124abc5579eSBenno Rice }
125abc5579eSBenno Rice 
1267844e5a4SLeandro Lupori static __inline uint32_t
mfpvr(void)12743e87179SBenno Rice mfpvr(void)
12843e87179SBenno Rice {
1297844e5a4SLeandro Lupori 	uint32_t value;
13043e87179SBenno Rice 
13143e87179SBenno Rice 	__asm __volatile ("mfpvr %0" : "=r"(value));
13243e87179SBenno Rice 
13343e87179SBenno Rice 	return (value);
1347ad9c533SRafal Jaworowski }
1357ad9c533SRafal Jaworowski 
1367ad9c533SRafal Jaworowski static __inline u_quad_t
mftb(void)1377ad9c533SRafal Jaworowski mftb(void)
1387ad9c533SRafal Jaworowski {
1397ad9c533SRafal Jaworowski 	u_quad_t tb;
140c3e289e1SNathan Whitehorn       #ifdef __powerpc64__
141c3e289e1SNathan Whitehorn 	__asm __volatile ("mftb %0" : "=r"(tb));
142c3e289e1SNathan Whitehorn       #else
1437ad9c533SRafal Jaworowski 	uint32_t *tbup = (uint32_t *)&tb;
1447ad9c533SRafal Jaworowski 	uint32_t *tblp = tbup + 1;
1457ad9c533SRafal Jaworowski 
1467ad9c533SRafal Jaworowski 	do {
1477ad9c533SRafal Jaworowski 		*tbup = mfspr(TBR_TBU);
1487ad9c533SRafal Jaworowski 		*tblp = mfspr(TBR_TBL);
1497ad9c533SRafal Jaworowski 	} while (*tbup != mfspr(TBR_TBU));
150c3e289e1SNathan Whitehorn       #endif
1517ad9c533SRafal Jaworowski 
1527ad9c533SRafal Jaworowski 	return (tb);
1537ad9c533SRafal Jaworowski }
1547ad9c533SRafal Jaworowski 
1557ad9c533SRafal Jaworowski static __inline void
mttb(u_quad_t time)1567ad9c533SRafal Jaworowski mttb(u_quad_t time)
1577ad9c533SRafal Jaworowski {
1587ad9c533SRafal Jaworowski 
1597ad9c533SRafal Jaworowski 	mtspr(TBR_TBWL, 0);
1607ad9c533SRafal Jaworowski 	mtspr(TBR_TBWU, (uint32_t)(time >> 32));
1617ad9c533SRafal Jaworowski 	mtspr(TBR_TBWL, (uint32_t)(time & 0xffffffff));
16243e87179SBenno Rice }
16343e87179SBenno Rice 
1645d0e8619SAlfredo Dal'Ava Junior static __inline register_t
mffs(void)1655d0e8619SAlfredo Dal'Ava Junior mffs(void)
1665d0e8619SAlfredo Dal'Ava Junior {
167ab571179SBrandon Bergren 	uint64_t value;
1685d0e8619SAlfredo Dal'Ava Junior 
1695d0e8619SAlfredo Dal'Ava Junior 	__asm __volatile ("mffs 0; stfd 0,0(%0)"
1705d0e8619SAlfredo Dal'Ava Junior 			:: "b"(&value));
1715d0e8619SAlfredo Dal'Ava Junior 
172ab571179SBrandon Bergren 	return ((register_t)value);
1735d0e8619SAlfredo Dal'Ava Junior }
1745d0e8619SAlfredo Dal'Ava Junior 
1755d0e8619SAlfredo Dal'Ava Junior static __inline void
mtfsf(uint64_t value)176ab571179SBrandon Bergren mtfsf(uint64_t value)
1775d0e8619SAlfredo Dal'Ava Junior {
178ab571179SBrandon Bergren 
1795d0e8619SAlfredo Dal'Ava Junior 	__asm __volatile ("lfd 0,0(%0); mtfsf 0xff,0"
1805d0e8619SAlfredo Dal'Ava Junior 			:: "b"(&value));
1815d0e8619SAlfredo Dal'Ava Junior }
1825d0e8619SAlfredo Dal'Ava Junior 
1836da4e60aSBenno Rice static __inline void
eieio(void)18471cf3a35SBenno Rice eieio(void)
18571cf3a35SBenno Rice {
18671cf3a35SBenno Rice 
18714758466SNathan Whitehorn 	__asm __volatile ("eieio" : : : "memory");
18871cf3a35SBenno Rice }
18971cf3a35SBenno Rice 
19071cf3a35SBenno Rice static __inline void
isync(void)1916da4e60aSBenno Rice isync(void)
1926da4e60aSBenno Rice {
1936da4e60aSBenno Rice 
19414758466SNathan Whitehorn 	__asm __volatile ("isync" : : : "memory");
1956da4e60aSBenno Rice }
1966da4e60aSBenno Rice 
197d3f6fb3bSMarcel Moolenaar static __inline void
powerpc_sync(void)198d3f6fb3bSMarcel Moolenaar powerpc_sync(void)
199d3f6fb3bSMarcel Moolenaar {
200d3f6fb3bSMarcel Moolenaar 
20114758466SNathan Whitehorn 	__asm __volatile ("sync" : : : "memory");
202d3f6fb3bSMarcel Moolenaar }
203d3f6fb3bSMarcel Moolenaar 
20465bbba25SJustin Hibbits static __inline int
cntlzd(uint64_t word)20565bbba25SJustin Hibbits cntlzd(uint64_t word)
20665bbba25SJustin Hibbits {
20765bbba25SJustin Hibbits 	uint64_t result;
20865bbba25SJustin Hibbits 	/* cntlzd %0, %1 */
20965bbba25SJustin Hibbits 	__asm __volatile(".long 0x7c000074 |  (%1 << 21) | (%0 << 16)" :
21065bbba25SJustin Hibbits 	    "=r"(result) : "r"(word));
21165bbba25SJustin Hibbits 
21265bbba25SJustin Hibbits 	return (int)result;
21365bbba25SJustin Hibbits }
21465bbba25SJustin Hibbits 
21565bbba25SJustin Hibbits static __inline int
cnttzd(uint64_t word)21665bbba25SJustin Hibbits cnttzd(uint64_t word)
21765bbba25SJustin Hibbits {
21865bbba25SJustin Hibbits 	uint64_t result;
21965bbba25SJustin Hibbits 	/* cnttzd %0, %1 */
22065bbba25SJustin Hibbits 	__asm __volatile(".long 0x7c000474 |  (%1 << 21) | (%0 << 16)" :
22165bbba25SJustin Hibbits 	    "=r"(result) : "r"(word));
22265bbba25SJustin Hibbits 
22365bbba25SJustin Hibbits 	return (int)result;
22465bbba25SJustin Hibbits }
22565bbba25SJustin Hibbits 
22665bbba25SJustin Hibbits static __inline void
ptesync(void)22765bbba25SJustin Hibbits ptesync(void)
22865bbba25SJustin Hibbits {
22965bbba25SJustin Hibbits 	__asm __volatile("ptesync");
23065bbba25SJustin Hibbits }
23165bbba25SJustin Hibbits 
23254551c77SBenno Rice static __inline register_t
intr_disable(void)23354551c77SBenno Rice intr_disable(void)
234d27f1d4cSBenno Rice {
23554551c77SBenno Rice 	register_t msr;
236d27f1d4cSBenno Rice 
237abc5579eSBenno Rice 	msr = mfmsr();
23850122aa9SPeter Grehan 	mtmsr(msr & ~PSL_EE);
23954551c77SBenno Rice 	return (msr);
240d27f1d4cSBenno Rice }
241d27f1d4cSBenno Rice 
242d27f1d4cSBenno Rice static __inline void
intr_restore(register_t msr)24354551c77SBenno Rice intr_restore(register_t msr)
244d27f1d4cSBenno Rice {
245d27f1d4cSBenno Rice 
24654551c77SBenno Rice 	mtmsr(msr);
247d27f1d4cSBenno Rice }
248d27f1d4cSBenno Rice 
2490bbc8826SJohn Baldwin static __inline struct pcpu *
get_pcpu(void)250e2a8d178SJason A. Harmening get_pcpu(void)
251d27f1d4cSBenno Rice {
2520bbc8826SJohn Baldwin 	struct pcpu *ret;
253d27f1d4cSBenno Rice 
2545da7ea0aSMarcel Moolenaar 	__asm __volatile("mfsprg %0, 0" : "=r"(ret));
255d27f1d4cSBenno Rice 
256d27f1d4cSBenno Rice 	return (ret);
257d27f1d4cSBenno Rice }
258d27f1d4cSBenno Rice 
259e92d228bSJustin Hibbits /* "NOP" operations to signify priorities to the kernel. */
260e92d228bSJustin Hibbits static __inline void
nop_prio_vlow(void)261e92d228bSJustin Hibbits nop_prio_vlow(void)
262e92d228bSJustin Hibbits {
263e92d228bSJustin Hibbits 	__asm __volatile("or 31,31,31");
264e92d228bSJustin Hibbits }
265e92d228bSJustin Hibbits 
266e92d228bSJustin Hibbits static __inline void
nop_prio_low(void)267e92d228bSJustin Hibbits nop_prio_low(void)
268e92d228bSJustin Hibbits {
269e92d228bSJustin Hibbits 	__asm __volatile("or 1,1,1");
270e92d228bSJustin Hibbits }
271e92d228bSJustin Hibbits 
272e92d228bSJustin Hibbits static __inline void
nop_prio_mlow(void)273e92d228bSJustin Hibbits nop_prio_mlow(void)
274e92d228bSJustin Hibbits {
275e92d228bSJustin Hibbits 	__asm __volatile("or 6,6,6");
276e92d228bSJustin Hibbits }
277e92d228bSJustin Hibbits 
278e92d228bSJustin Hibbits static __inline void
nop_prio_medium(void)279e92d228bSJustin Hibbits nop_prio_medium(void)
280e92d228bSJustin Hibbits {
281e92d228bSJustin Hibbits 	__asm __volatile("or 2,2,2");
282e92d228bSJustin Hibbits }
283e92d228bSJustin Hibbits 
284e92d228bSJustin Hibbits static __inline void
nop_prio_mhigh(void)285e92d228bSJustin Hibbits nop_prio_mhigh(void)
286e92d228bSJustin Hibbits {
287e92d228bSJustin Hibbits 	__asm __volatile("or 5,5,5");
288e92d228bSJustin Hibbits }
289e92d228bSJustin Hibbits 
290e92d228bSJustin Hibbits static __inline void
nop_prio_high(void)291e92d228bSJustin Hibbits nop_prio_high(void)
292e92d228bSJustin Hibbits {
293e92d228bSJustin Hibbits 	__asm __volatile("or 3,3,3");
294e92d228bSJustin Hibbits }
295e92d228bSJustin Hibbits 
296d27f1d4cSBenno Rice #endif /* _KERNEL */
297d27f1d4cSBenno Rice 
298d27f1d4cSBenno Rice #endif /* !_MACHINE_CPUFUNC_H_ */
299