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