1 /*- 2 * Copyright (c) 1998 Doug Rabson 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD$ 27 */ 28 29 #ifndef _MACHINE_CPUFUNC_H_ 30 #define _MACHINE_CPUFUNC_H_ 31 32 #ifdef _KERNEL 33 34 #include <sys/types.h> 35 36 #include <machine/psl.h> 37 #include <machine/spr.h> 38 39 struct thread; 40 41 #ifdef KDB 42 void breakpoint(void); 43 #else 44 static __inline void 45 breakpoint(void) 46 { 47 48 return; 49 } 50 #endif 51 52 /* CPU register mangling inlines */ 53 54 static __inline void 55 mtmsr(register_t value) 56 { 57 58 __asm __volatile ("mtmsr %0; isync" :: "r"(value)); 59 } 60 61 #ifdef __powerpc64__ 62 static __inline void 63 mtmsrd(register_t value) 64 { 65 66 __asm __volatile ("mtmsrd %0; isync" :: "r"(value)); 67 } 68 #endif 69 70 static __inline register_t 71 mfmsr(void) 72 { 73 register_t value; 74 75 __asm __volatile ("mfmsr %0" : "=r"(value)); 76 77 return (value); 78 } 79 80 #ifndef __powerpc64__ 81 static __inline void 82 mtsrin(vm_offset_t va, register_t value) 83 { 84 85 __asm __volatile ("mtsrin %0,%1; isync" :: "r"(value), "r"(va)); 86 } 87 88 static __inline register_t 89 mfsrin(vm_offset_t va) 90 { 91 register_t value; 92 93 __asm __volatile ("mfsrin %0,%1" : "=r"(value) : "r"(va)); 94 95 return (value); 96 } 97 #endif 98 99 static __inline register_t 100 mfctrl(void) 101 { 102 register_t value; 103 104 __asm __volatile ("mfspr %0,136" : "=r"(value)); 105 106 return (value); 107 } 108 109 110 static __inline void 111 mtdec(register_t value) 112 { 113 114 __asm __volatile ("mtdec %0" :: "r"(value)); 115 } 116 117 static __inline register_t 118 mfdec(void) 119 { 120 register_t value; 121 122 __asm __volatile ("mfdec %0" : "=r"(value)); 123 124 return (value); 125 } 126 127 static __inline register_t 128 mfpvr(void) 129 { 130 register_t value; 131 132 __asm __volatile ("mfpvr %0" : "=r"(value)); 133 134 return (value); 135 } 136 137 static __inline u_quad_t 138 mftb(void) 139 { 140 u_quad_t tb; 141 #ifdef __powerpc64__ 142 __asm __volatile ("mftb %0" : "=r"(tb)); 143 #else 144 uint32_t *tbup = (uint32_t *)&tb; 145 uint32_t *tblp = tbup + 1; 146 147 do { 148 *tbup = mfspr(TBR_TBU); 149 *tblp = mfspr(TBR_TBL); 150 } while (*tbup != mfspr(TBR_TBU)); 151 #endif 152 153 return (tb); 154 } 155 156 static __inline void 157 mttb(u_quad_t time) 158 { 159 160 mtspr(TBR_TBWL, 0); 161 mtspr(TBR_TBWU, (uint32_t)(time >> 32)); 162 mtspr(TBR_TBWL, (uint32_t)(time & 0xffffffff)); 163 } 164 165 static __inline void 166 eieio(void) 167 { 168 169 __asm __volatile ("eieio" : : : "memory"); 170 } 171 172 static __inline void 173 isync(void) 174 { 175 176 __asm __volatile ("isync" : : : "memory"); 177 } 178 179 static __inline void 180 powerpc_sync(void) 181 { 182 183 __asm __volatile ("sync" : : : "memory"); 184 } 185 186 static __inline register_t 187 intr_disable(void) 188 { 189 register_t msr; 190 191 msr = mfmsr(); 192 mtmsr(msr & ~PSL_EE); 193 return (msr); 194 } 195 196 static __inline void 197 intr_restore(register_t msr) 198 { 199 200 mtmsr(msr); 201 } 202 203 static __inline struct pcpu * 204 powerpc_get_pcpup(void) 205 { 206 struct pcpu *ret; 207 208 __asm __volatile("mfsprg %0, 0" : "=r"(ret)); 209 210 return (ret); 211 } 212 213 #endif /* _KERNEL */ 214 215 #endif /* !_MACHINE_CPUFUNC_H_ */ 216