1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 1998 Doug Rabson 5 * 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 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 * 28 * $FreeBSD$ 29 */ 30 31 #ifndef _MACHINE_CPUFUNC_H_ 32 #define _MACHINE_CPUFUNC_H_ 33 34 #ifdef _KERNEL 35 36 #include <sys/types.h> 37 38 #include <machine/psl.h> 39 #include <machine/spr.h> 40 41 struct thread; 42 43 #ifdef KDB 44 void breakpoint(void); 45 #else 46 static __inline void 47 breakpoint(void) 48 { 49 50 return; 51 } 52 #endif 53 54 /* CPU register mangling inlines */ 55 56 static __inline void 57 mtmsr(register_t value) 58 { 59 60 __asm __volatile ("mtmsr %0; isync" :: "r"(value)); 61 } 62 63 #ifdef __powerpc64__ 64 static __inline void 65 mtmsrd(register_t value) 66 { 67 68 __asm __volatile ("mtmsrd %0; isync" :: "r"(value)); 69 } 70 #endif 71 72 static __inline register_t 73 mfmsr(void) 74 { 75 register_t value; 76 77 __asm __volatile ("mfmsr %0" : "=r"(value)); 78 79 return (value); 80 } 81 82 #ifndef __powerpc64__ 83 static __inline void 84 mtsrin(vm_offset_t va, register_t value) 85 { 86 87 __asm __volatile ("mtsrin %0,%1; isync" :: "r"(value), "r"(va)); 88 } 89 90 static __inline register_t 91 mfsrin(vm_offset_t va) 92 { 93 register_t value; 94 95 __asm __volatile ("mfsrin %0,%1" : "=r"(value) : "r"(va)); 96 97 return (value); 98 } 99 #endif 100 101 static __inline register_t 102 mfctrl(void) 103 { 104 register_t value; 105 106 __asm __volatile ("mfspr %0,136" : "=r"(value)); 107 108 return (value); 109 } 110 111 static __inline void 112 mtdec(register_t value) 113 { 114 115 __asm __volatile ("mtdec %0" :: "r"(value)); 116 } 117 118 static __inline register_t 119 mfdec(void) 120 { 121 register_t value; 122 123 __asm __volatile ("mfdec %0" : "=r"(value)); 124 125 return (value); 126 } 127 128 static __inline register_t 129 mfpvr(void) 130 { 131 register_t value; 132 133 __asm __volatile ("mfpvr %0" : "=r"(value)); 134 135 return (value); 136 } 137 138 static __inline u_quad_t 139 mftb(void) 140 { 141 u_quad_t tb; 142 #ifdef __powerpc64__ 143 __asm __volatile ("mftb %0" : "=r"(tb)); 144 #else 145 uint32_t *tbup = (uint32_t *)&tb; 146 uint32_t *tblp = tbup + 1; 147 148 do { 149 *tbup = mfspr(TBR_TBU); 150 *tblp = mfspr(TBR_TBL); 151 } while (*tbup != mfspr(TBR_TBU)); 152 #endif 153 154 return (tb); 155 } 156 157 static __inline void 158 mttb(u_quad_t time) 159 { 160 161 mtspr(TBR_TBWL, 0); 162 mtspr(TBR_TBWU, (uint32_t)(time >> 32)); 163 mtspr(TBR_TBWL, (uint32_t)(time & 0xffffffff)); 164 } 165 166 static __inline void 167 eieio(void) 168 { 169 170 __asm __volatile ("eieio" : : : "memory"); 171 } 172 173 static __inline void 174 isync(void) 175 { 176 177 __asm __volatile ("isync" : : : "memory"); 178 } 179 180 static __inline void 181 powerpc_sync(void) 182 { 183 184 __asm __volatile ("sync" : : : "memory"); 185 } 186 187 static __inline int 188 cntlzd(uint64_t word) 189 { 190 uint64_t result; 191 /* cntlzd %0, %1 */ 192 __asm __volatile(".long 0x7c000074 | (%1 << 21) | (%0 << 16)" : 193 "=r"(result) : "r"(word)); 194 195 return (int)result; 196 } 197 198 static __inline int 199 cnttzd(uint64_t word) 200 { 201 uint64_t result; 202 /* cnttzd %0, %1 */ 203 __asm __volatile(".long 0x7c000474 | (%1 << 21) | (%0 << 16)" : 204 "=r"(result) : "r"(word)); 205 206 return (int)result; 207 } 208 209 static __inline void 210 ptesync(void) 211 { 212 __asm __volatile("ptesync"); 213 } 214 215 static __inline register_t 216 intr_disable(void) 217 { 218 register_t msr; 219 220 msr = mfmsr(); 221 mtmsr(msr & ~PSL_EE); 222 return (msr); 223 } 224 225 static __inline void 226 intr_restore(register_t msr) 227 { 228 229 mtmsr(msr); 230 } 231 232 static __inline struct pcpu * 233 get_pcpu(void) 234 { 235 struct pcpu *ret; 236 237 __asm __volatile("mfsprg %0, 0" : "=r"(ret)); 238 239 return (ret); 240 } 241 242 #define HAVE_INLINE_FLS 243 static __inline __pure2 int 244 fls(int mask) 245 { 246 return (mask ? 32 - __builtin_clz(mask) : 0); 247 } 248 249 #define HAVE_INLINE_FLSL 250 static __inline __pure2 int 251 flsl(long mask) 252 { 253 return (mask ? (8 * sizeof(long) - __builtin_clzl(mask)) : 0); 254 } 255 256 /* "NOP" operations to signify priorities to the kernel. */ 257 static __inline void 258 nop_prio_vlow(void) 259 { 260 __asm __volatile("or 31,31,31"); 261 } 262 263 static __inline void 264 nop_prio_low(void) 265 { 266 __asm __volatile("or 1,1,1"); 267 } 268 269 static __inline void 270 nop_prio_mlow(void) 271 { 272 __asm __volatile("or 6,6,6"); 273 } 274 275 static __inline void 276 nop_prio_medium(void) 277 { 278 __asm __volatile("or 2,2,2"); 279 } 280 281 static __inline void 282 nop_prio_mhigh(void) 283 { 284 __asm __volatile("or 5,5,5"); 285 } 286 287 static __inline void 288 nop_prio_high(void) 289 { 290 __asm __volatile("or 3,3,3"); 291 } 292 293 #endif /* _KERNEL */ 294 295 #endif /* !_MACHINE_CPUFUNC_H_ */ 296