1 1.66 macallan /* $NetBSD: psl.h,v 1.66 2025/05/20 06:12:00 macallan Exp $ */ 2 1.1 eeh 3 1.1 eeh /* 4 1.1 eeh * Copyright (c) 1992, 1993 5 1.1 eeh * The Regents of the University of California. All rights reserved. 6 1.1 eeh * 7 1.1 eeh * This software was developed by the Computer Systems Engineering group 8 1.1 eeh * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 9 1.1 eeh * contributed to Berkeley. 10 1.1 eeh * 11 1.1 eeh * All advertising materials mentioning features or use of this software 12 1.1 eeh * must display the following acknowledgement: 13 1.1 eeh * This product includes software developed by the University of 14 1.1 eeh * California, Lawrence Berkeley Laboratory. 15 1.1 eeh * 16 1.1 eeh * Redistribution and use in source and binary forms, with or without 17 1.1 eeh * modification, are permitted provided that the following conditions 18 1.1 eeh * are met: 19 1.1 eeh * 1. Redistributions of source code must retain the above copyright 20 1.1 eeh * notice, this list of conditions and the following disclaimer. 21 1.1 eeh * 2. Redistributions in binary form must reproduce the above copyright 22 1.1 eeh * notice, this list of conditions and the following disclaimer in the 23 1.1 eeh * documentation and/or other materials provided with the distribution. 24 1.23 agc * 3. Neither the name of the University nor the names of its contributors 25 1.1 eeh * may be used to endorse or promote products derived from this software 26 1.1 eeh * without specific prior written permission. 27 1.1 eeh * 28 1.1 eeh * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 29 1.1 eeh * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 30 1.1 eeh * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 31 1.1 eeh * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 32 1.1 eeh * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 33 1.1 eeh * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 34 1.1 eeh * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 35 1.1 eeh * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 36 1.1 eeh * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 37 1.1 eeh * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 38 1.1 eeh * SUCH DAMAGE. 39 1.1 eeh * 40 1.1 eeh * @(#)psl.h 8.1 (Berkeley) 6/11/93 41 1.1 eeh */ 42 1.1 eeh 43 1.1 eeh #ifndef PSR_IMPL 44 1.1 eeh 45 1.1 eeh /* 46 1.19 mrg * SPARC Process Status Register (in psl.h for hysterical raisins). This 47 1.19 mrg * doesn't exist on the V9. 48 1.1 eeh * 49 1.1 eeh * The picture in the Sun manuals looks like this: 50 1.1 eeh * 1 1 51 1.1 eeh * 31 28 27 24 23 20 19 14 3 2 11 8 7 6 5 4 0 52 1.1 eeh * +-------+-------+-------+-----------+-+-+-------+-+-+-+---------+ 53 1.1 eeh * | impl | ver | icc | reserved |E|E| pil |S|P|E| CWP | 54 1.1 eeh * | | |n z v c| |C|F| | |S|T| | 55 1.1 eeh * +-------+-------+-------+-----------+-+-+-------+-+-+-+---------+ 56 1.1 eeh */ 57 1.1 eeh 58 1.19 mrg #define PSR_IMPL 0xf0000000 /* implementation */ 59 1.19 mrg #define PSR_VER 0x0f000000 /* version */ 60 1.19 mrg #define PSR_ICC 0x00f00000 /* integer condition codes */ 61 1.19 mrg #define PSR_N 0x00800000 /* negative */ 62 1.19 mrg #define PSR_Z 0x00400000 /* zero */ 63 1.19 mrg #define PSR_O 0x00200000 /* overflow */ 64 1.19 mrg #define PSR_C 0x00100000 /* carry */ 65 1.19 mrg #define PSR_EC 0x00002000 /* coprocessor enable */ 66 1.19 mrg #define PSR_EF 0x00001000 /* FP enable */ 67 1.19 mrg #define PSR_PIL 0x00000f00 /* interrupt level */ 68 1.19 mrg #define PSR_S 0x00000080 /* supervisor (kernel) mode */ 69 1.19 mrg #define PSR_PS 0x00000040 /* previous supervisor mode (traps) */ 70 1.19 mrg #define PSR_ET 0x00000020 /* trap enable */ 71 1.19 mrg #define PSR_CWP 0x0000001f /* current window pointer */ 72 1.1 eeh 73 1.19 mrg #define PSR_BITS "\20\16EC\15EF\10S\7PS\6ET" 74 1.1 eeh 75 1.1 eeh /* Interesting spl()s */ 76 1.1 eeh #define PIL_BIO 5 77 1.1 eeh #define PIL_VIDEO 5 78 1.19 mrg #define PIL_TTY 6 79 1.19 mrg #define PIL_LPT 6 80 1.19 mrg #define PIL_NET 6 81 1.33 yamt #define PIL_VM 7 82 1.24 petrov #define PIL_AUD 8 83 1.19 mrg #define PIL_CLOCK 10 84 1.1 eeh #define PIL_FD 11 85 1.1 eeh #define PIL_SER 12 86 1.33 yamt #define PIL_STATCLOCK 14 87 1.19 mrg #define PIL_HIGH 15 88 1.19 mrg #define PIL_SCHED PIL_CLOCK 89 1.19 mrg #define PIL_LOCK PIL_HIGH 90 1.1 eeh 91 1.1 eeh /* 92 1.1 eeh * SPARC V9 CCR register 93 1.1 eeh */ 94 1.1 eeh 95 1.5 eeh #define ICC_C 0x01L 96 1.5 eeh #define ICC_V 0x02L 97 1.5 eeh #define ICC_Z 0x04L 98 1.5 eeh #define ICC_N 0x08L 99 1.1 eeh #define XCC_SHIFT 4 100 1.1 eeh #define XCC_C (ICC_C<<XCC_SHIFT) 101 1.1 eeh #define XCC_V (ICC_V<<XCC_SHIFT) 102 1.1 eeh #define XCC_Z (ICC_Z<<XCC_SHIFT) 103 1.1 eeh #define XCC_N (ICC_N<<XCC_SHIFT) 104 1.1 eeh 105 1.1 eeh 106 1.1 eeh /* 107 1.1 eeh * SPARC V9 PSTATE register (what replaces the PSR in V9) 108 1.1 eeh * 109 1.1 eeh * Here's the layout: 110 1.1 eeh * 111 1.1 eeh * 11 10 9 8 7 6 5 4 3 2 1 0 112 1.1 eeh * +------------------------------------------------------------+ 113 1.1 eeh * | IG | MG | CLE | TLE | MM | RED | PEF | AM | PRIV | IE | AG | 114 1.1 eeh * +------------------------------------------------------------+ 115 1.1 eeh */ 116 1.1 eeh 117 1.1 eeh #define PSTATE_IG 0x800 /* enable spitfire interrupt globals */ 118 1.1 eeh #define PSTATE_MG 0x400 /* enable spitfire MMU globals */ 119 1.1 eeh #define PSTATE_CLE 0x200 /* current little endian */ 120 1.1 eeh #define PSTATE_TLE 0x100 /* traps little endian */ 121 1.1 eeh #define PSTATE_MM 0x0c0 /* memory model */ 122 1.1 eeh #define PSTATE_MM_TSO 0x000 /* total store order */ 123 1.1 eeh #define PSTATE_MM_PSO 0x040 /* partial store order */ 124 1.1 eeh #define PSTATE_MM_RMO 0x080 /* Relaxed memory order */ 125 1.1 eeh #define PSTATE_RED 0x020 /* RED state */ 126 1.1 eeh #define PSTATE_PEF 0x010 /* enable floating point */ 127 1.1 eeh #define PSTATE_AM 0x008 /* 32-bit address masking */ 128 1.1 eeh #define PSTATE_PRIV 0x004 /* privileged mode */ 129 1.1 eeh #define PSTATE_IE 0x002 /* interrupt enable */ 130 1.1 eeh #define PSTATE_AG 0x001 /* enable alternate globals */ 131 1.1 eeh 132 1.65 rillig #define PSTATE_BITS "\177\020" \ 133 1.65 rillig "b\013IG\0" "b\012MG\0" "b\011CLE\0" "b\010TLE\0" \ 134 1.65 rillig "F\006\002\0" ":\000MM_TSO\0" ":\001MM_PSO\0" \ 135 1.65 rillig ":\002MM_RMO\0" "*?\0" "b\005RED\0" "b\004PEF\0" \ 136 1.65 rillig "b\003AM\0" "b\002PRIV\0" "b\001IE\0" "b\000AG\0" 137 1.1 eeh 138 1.12 eeh 139 1.12 eeh /* 140 1.12 eeh * 32-bit code requires TSO or at best PSO since that's what's supported on 141 1.12 eeh * SPARC V8 and earlier machines. 142 1.12 eeh * 143 1.12 eeh * 64-bit code sets the memory model in the ELF header. 144 1.12 eeh * 145 1.12 eeh * We're running kernel code in TSO for the moment so we don't need to worry 146 1.12 eeh * about possible memory barrier bugs. 147 1.12 eeh */ 148 1.12 eeh 149 1.6 mrg #ifdef __arch64__ 150 1.4 eeh #define PSTATE_PROM (PSTATE_MM_TSO|PSTATE_PRIV) 151 1.4 eeh #define PSTATE_NUCLEUS (PSTATE_MM_TSO|PSTATE_PRIV|PSTATE_AG) 152 1.4 eeh #define PSTATE_KERN (PSTATE_MM_TSO|PSTATE_PRIV) 153 1.4 eeh #define PSTATE_INTR (PSTATE_KERN|PSTATE_IE) 154 1.12 eeh #define PSTATE_USER32 (PSTATE_MM_TSO|PSTATE_AM|PSTATE_IE) 155 1.13 eeh #define PSTATE_USER (PSTATE_MM_RMO|PSTATE_IE) 156 1.4 eeh #else 157 1.1 eeh #define PSTATE_PROM (PSTATE_MM_TSO|PSTATE_PRIV) 158 1.1 eeh #define PSTATE_NUCLEUS (PSTATE_MM_TSO|PSTATE_AM|PSTATE_PRIV|PSTATE_AG) 159 1.1 eeh #define PSTATE_KERN (PSTATE_MM_TSO|PSTATE_AM|PSTATE_PRIV) 160 1.1 eeh #define PSTATE_INTR (PSTATE_KERN|PSTATE_IE) 161 1.12 eeh #define PSTATE_USER32 (PSTATE_MM_TSO|PSTATE_AM|PSTATE_IE) 162 1.12 eeh #define PSTATE_USER (PSTATE_MM_TSO|PSTATE_AM|PSTATE_IE) 163 1.1 eeh #endif 164 1.1 eeh 165 1.19 mrg 166 1.1 eeh /* 167 1.1 eeh * SPARC V9 TSTATE register 168 1.1 eeh * 169 1.57 nakayama * 39 32 31 24 23 20 19 8 7 5 4 0 170 1.1 eeh * +-----+-----+-----+--------+---+-----+ 171 1.1 eeh * | CCR | ASI | - | PSTATE | - | CWP | 172 1.1 eeh * +-----+-----+-----+--------+---+-----+ 173 1.19 mrg */ 174 1.1 eeh 175 1.1 eeh #define TSTATE_CWP 0x01f 176 1.57 nakayama #define TSTATE_PSTATE 0xfff00 177 1.1 eeh #define TSTATE_PSTATE_SHIFT 8 178 1.1 eeh #define TSTATE_ASI 0xff000000LL 179 1.1 eeh #define TSTATE_ASI_SHIFT 24 180 1.1 eeh #define TSTATE_CCR 0xff00000000LL 181 1.1 eeh #define TSTATE_CCR_SHIFT 32 182 1.1 eeh 183 1.39 nakayama #define PSRCC_TO_TSTATE(x) (((int64_t)(x)&PSR_ICC)<<(TSTATE_CCR_SHIFT-20)) 184 1.39 nakayama #define TSTATECCR_TO_PSR(x) (((x)&TSTATE_CCR)>>(TSTATE_CCR_SHIFT-20)) 185 1.1 eeh 186 1.1 eeh /* 187 1.1 eeh * These are here to simplify life. 188 1.1 eeh */ 189 1.1 eeh #define TSTATE_IG (PSTATE_IG<<TSTATE_PSTATE_SHIFT) 190 1.1 eeh #define TSTATE_MG (PSTATE_MG<<TSTATE_PSTATE_SHIFT) 191 1.1 eeh #define TSTATE_CLE (PSTATE_CLE<<TSTATE_PSTATE_SHIFT) 192 1.1 eeh #define TSTATE_TLE (PSTATE_TLE<<TSTATE_PSTATE_SHIFT) 193 1.1 eeh #define TSTATE_MM (PSTATE_MM<<TSTATE_PSTATE_SHIFT) 194 1.1 eeh #define TSTATE_MM_TSO (PSTATE_MM_TSO<<TSTATE_PSTATE_SHIFT) 195 1.1 eeh #define TSTATE_MM_PSO (PSTATE_MM_PSO<<TSTATE_PSTATE_SHIFT) 196 1.1 eeh #define TSTATE_MM_RMO (PSTATE_MM_RMO<<TSTATE_PSTATE_SHIFT) 197 1.1 eeh #define TSTATE_RED (PSTATE_RED<<TSTATE_PSTATE_SHIFT) 198 1.1 eeh #define TSTATE_PEF (PSTATE_PEF<<TSTATE_PSTATE_SHIFT) 199 1.1 eeh #define TSTATE_AM (PSTATE_AM<<TSTATE_PSTATE_SHIFT) 200 1.1 eeh #define TSTATE_PRIV (PSTATE_PRIV<<TSTATE_PSTATE_SHIFT) 201 1.1 eeh #define TSTATE_IE (PSTATE_IE<<TSTATE_PSTATE_SHIFT) 202 1.1 eeh #define TSTATE_AG (PSTATE_AG<<TSTATE_PSTATE_SHIFT) 203 1.1 eeh 204 1.19 mrg #define TSTATE_BITS "\20\14IG\13MG\12CLE\11TLE\10\7MM\6RED\5PEF\4AM\3PRIV\2IE\1AG" 205 1.1 eeh 206 1.40 nakayama #define TSTATE_KERN ((PSTATE_KERN)<<TSTATE_PSTATE_SHIFT) 207 1.40 nakayama #define TSTATE_USER ((PSTATE_USER)<<TSTATE_PSTATE_SHIFT) 208 1.1 eeh /* 209 1.1 eeh * SPARC V9 VER version register. 210 1.1 eeh * 211 1.1 eeh * 63 48 47 32 31 24 23 16 15 8 7 5 4 0 212 1.1 eeh * +-------+------+------+-----+-------+---+--------+ 213 1.1 eeh * | manuf | impl | mask | - | maxtl | - | maxwin | 214 1.1 eeh * +-------+------+------+-----+-------+---+--------+ 215 1.1 eeh * 216 1.1 eeh */ 217 1.1 eeh 218 1.1 eeh #define VER_MANUF 0xffff000000000000LL 219 1.1 eeh #define VER_MANUF_SHIFT 48 220 1.1 eeh #define VER_IMPL 0x0000ffff00000000LL 221 1.1 eeh #define VER_IMPL_SHIFT 32 222 1.1 eeh #define VER_MASK 0x00000000ff000000LL 223 1.1 eeh #define VER_MASK_SHIFT 24 224 1.1 eeh #define VER_MAXTL 0x000000000000ff00LL 225 1.1 eeh #define VER_MAXTL_SHIFT 8 226 1.1 eeh #define VER_MAXWIN 0x000000000000001fLL 227 1.1 eeh 228 1.48 mrg #define MANUF_FUJITSU 0x04 /* Fujitsu SPARC64 */ 229 1.48 mrg #define MANUF_SUN 0x17 /* Sun UltraSPARC */ 230 1.48 mrg 231 1.47 mrg #define IMPL_SPARC64 0x01 /* SPARC64 */ 232 1.47 mrg #define IMPL_SPARC64_II 0x02 /* SPARC64-II */ 233 1.47 mrg #define IMPL_SPARC64_III 0x03 /* SPARC64-III */ 234 1.47 mrg #define IMPL_SPARC64_IV 0x04 /* SPARC64-IV */ 235 1.47 mrg #define IMPL_ZEUS 0x05 /* SPARC64-V */ 236 1.47 mrg #define IMPL_OLYMPUS_C 0x06 /* SPARC64-VI */ 237 1.47 mrg #define IMPL_JUPITER 0x07 /* SPARC64-VII */ 238 1.47 mrg 239 1.45 nakayama #define IMPL_SPITFIRE 0x10 /* UltraSPARC-I */ 240 1.45 nakayama #define IMPL_BLACKBIRD 0x11 /* UltraSPARC-II */ 241 1.45 nakayama #define IMPL_SABRE 0x12 /* UltraSPARC-IIi */ 242 1.45 nakayama #define IMPL_HUMMINGBIRD 0x13 /* UltraSPARC-IIe */ 243 1.45 nakayama #define IMPL_CHEETAH 0x14 /* UltraSPARC-III */ 244 1.45 nakayama #define IMPL_CHEETAH_PLUS 0x15 /* UltraSPARC-III+ */ 245 1.45 nakayama #define IMPL_JALAPENO 0x16 /* UltraSPARC-IIIi */ 246 1.45 nakayama #define IMPL_JAGUAR 0x18 /* UltraSPARC-IV */ 247 1.45 nakayama #define IMPL_PANTHER 0x19 /* UltraSPARC-IV+ */ 248 1.45 nakayama #define IMPL_SERRANO 0x22 /* UltraSPARC-IIIi+ */ 249 1.45 nakayama 250 1.1 eeh /* 251 1.1 eeh * Here are a few things to help us transition between user and kernel mode: 252 1.1 eeh */ 253 1.1 eeh 254 1.1 eeh /* Memory models */ 255 1.1 eeh #define KERN_MM PSTATE_MM_TSO 256 1.1 eeh #define USER_MM PSTATE_MM_RMO 257 1.1 eeh 258 1.4 eeh /* 259 1.4 eeh * Register window handlers. These point to generic routines that check the 260 1.4 eeh * stack pointer and then vector to the real handler. We could optimize this 261 1.4 eeh * if we could guarantee only 32-bit or 64-bit stacks. 262 1.4 eeh */ 263 1.1 eeh #define WSTATE_KERN 026 264 1.1 eeh #define WSTATE_USER 022 265 1.1 eeh 266 1.1 eeh #define CWP 0x01f 267 1.1 eeh 268 1.51 nakayama /* 269 1.51 nakayama * UltraSPARC Ancillary State Registers 270 1.51 nakayama */ 271 1.51 nakayama #define SET_SOFTINT %asr20 /* Set Software Interrupt register bits */ 272 1.51 nakayama #define CLEAR_SOFTINT %asr21 /* Clear Software Interrupt register bits */ 273 1.51 nakayama #define SOFTINT %asr22 /* Software Interrupt register */ 274 1.51 nakayama #define TICK_CMPR %asr23 /* TICK Compare register */ 275 1.51 nakayama #define STICK %asr24 /* STICK register */ 276 1.51 nakayama #define STICK_CMPR %asr25 /* STICK Compare register */ 277 1.51 nakayama 278 1.51 nakayama /* SOFTINT bit descriptions */ 279 1.51 nakayama #define TICK_INT 0x01 /* CPU clock timer interrupt */ 280 1.51 nakayama #define STICK_INT (0x1<<16) /* system clock timer interrupt */ 281 1.51 nakayama 282 1.1 eeh /* 64-byte alignment -- this seems the best place to put this. */ 283 1.49 mrg #define SPARC64_BLOCK_SIZE 64 284 1.49 mrg #define SPARC64_BLOCK_ALIGN 0x3f 285 1.1 eeh 286 1.63 martin 287 1.63 martin #if (defined(_KERNEL) || defined(_KMEMUSER)) && !defined(_LOCORE) 288 1.63 martin typedef uint8_t ipl_t; 289 1.63 martin typedef struct { 290 1.63 martin ipl_t _ipl; 291 1.63 martin } ipl_cookie_t; 292 1.63 martin #endif /* _KERNEL|_KMEMUSER&!_LOCORE */ 293 1.63 martin 294 1.1 eeh #if defined(_KERNEL) && !defined(_LOCORE) 295 1.1 eeh 296 1.56 nakayama #if defined(_KERNEL_OPT) 297 1.56 nakayama #include "opt_sparc_arch.h" 298 1.56 nakayama #endif 299 1.56 nakayama 300 1.56 nakayama /* 301 1.56 nakayama * Put "memory" to asm inline on sun4v to avoid issuing rdpr %ver 302 1.56 nakayama * before checking cputyp as a result of code moving by compiler 303 1.56 nakayama * optimization. 304 1.56 nakayama */ 305 1.60 nakayama #ifdef SUN4V 306 1.56 nakayama #define constasm_clobbers "memory" 307 1.56 nakayama #else 308 1.56 nakayama #define constasm_clobbers 309 1.56 nakayama #endif 310 1.56 nakayama 311 1.1 eeh /* 312 1.52 nakayama * Inlines for manipulating privileged and ancillary state registers 313 1.1 eeh */ 314 1.54 nakayama #define SPARC64_RDCONST_DEF(rd, name, reg, type) \ 315 1.54 nakayama static __inline __constfunc type get##name(void) \ 316 1.54 nakayama { \ 317 1.54 nakayama type _val; \ 318 1.56 nakayama __asm(#rd " %" #reg ",%0" : "=r" (_val) : : constasm_clobbers); \ 319 1.54 nakayama return _val; \ 320 1.54 nakayama } 321 1.52 nakayama #define SPARC64_RD_DEF(rd, name, reg, type) \ 322 1.52 nakayama static __inline type get##name(void) \ 323 1.43 nakayama { \ 324 1.52 nakayama type _val; \ 325 1.52 nakayama __asm volatile(#rd " %" #reg ",%0" : "=r" (_val)); \ 326 1.52 nakayama return _val; \ 327 1.43 nakayama } 328 1.52 nakayama #define SPARC64_WR_DEF(wr, name, reg, type) \ 329 1.52 nakayama static __inline void set##name(type _val) \ 330 1.43 nakayama { \ 331 1.52 nakayama __asm volatile(#wr " %0,0,%" #reg : : "r" (_val) : "memory"); \ 332 1.41 nakayama } 333 1.41 nakayama 334 1.61 nakayama #ifdef __arch64__ 335 1.54 nakayama #define SPARC64_RDCONST64_DEF(rd, name, reg) \ 336 1.54 nakayama SPARC64_RDCONST_DEF(rd, name, reg, uint64_t) 337 1.61 nakayama #define SPARC64_RD64_DEF(rd, name, reg) SPARC64_RD_DEF(rd, name, reg, uint64_t) 338 1.61 nakayama #define SPARC64_WR64_DEF(wr, name, reg) SPARC64_WR_DEF(wr, name, reg, uint64_t) 339 1.41 nakayama #else 340 1.54 nakayama #define SPARC64_RDCONST64_DEF(rd, name, reg) \ 341 1.54 nakayama static __inline __constfunc uint64_t get##name(void) \ 342 1.54 nakayama { \ 343 1.54 nakayama uint32_t _hi, _lo; \ 344 1.54 nakayama __asm(#rd " %" #reg ",%0; srl %0,0,%1; srlx %0,32,%0" \ 345 1.56 nakayama : "=r" (_hi), "=r" (_lo) : : constasm_clobbers); \ 346 1.54 nakayama return ((uint64_t)_hi << 32) | _lo; \ 347 1.54 nakayama } 348 1.52 nakayama #define SPARC64_RD64_DEF(rd, name, reg) \ 349 1.52 nakayama static __inline uint64_t get##name(void) \ 350 1.43 nakayama { \ 351 1.43 nakayama uint32_t _hi, _lo; \ 352 1.52 nakayama __asm volatile(#rd " %" #reg ",%0; srl %0,0,%1; srlx %0,32,%0" \ 353 1.43 nakayama : "=r" (_hi), "=r" (_lo)); \ 354 1.43 nakayama return ((uint64_t)_hi << 32) | _lo; \ 355 1.43 nakayama } 356 1.52 nakayama #define SPARC64_WR64_DEF(wr, name, reg) \ 357 1.52 nakayama static __inline void set##name(uint64_t _val) \ 358 1.43 nakayama { \ 359 1.52 nakayama uint32_t _hi = _val >> 32, _lo = _val; \ 360 1.52 nakayama __asm volatile("sllx %1,32,%0; or %0,%2,%0; " #wr " %0,0,%" #reg\ 361 1.43 nakayama : "=&r" (_hi) /* scratch register */ \ 362 1.43 nakayama : "r" (_hi), "r" (_lo) : "memory"); \ 363 1.43 nakayama } 364 1.41 nakayama #endif 365 1.41 nakayama 366 1.52 nakayama #define SPARC64_RDPR_DEF(name, reg, type) SPARC64_RD_DEF(rdpr, name, reg, type) 367 1.52 nakayama #define SPARC64_WRPR_DEF(name, reg, type) SPARC64_WR_DEF(wrpr, name, reg, type) 368 1.52 nakayama #define SPARC64_RDPR64_DEF(name, reg) SPARC64_RD64_DEF(rdpr, name, reg) 369 1.52 nakayama #define SPARC64_WRPR64_DEF(name, reg) SPARC64_WR64_DEF(wrpr, name, reg) 370 1.52 nakayama #define SPARC64_RDASR64_DEF(name, reg) SPARC64_RD64_DEF(rd, name, reg) 371 1.52 nakayama #define SPARC64_WRASR64_DEF(name, reg) SPARC64_WR64_DEF(wr, name, reg) 372 1.52 nakayama 373 1.43 nakayama /* Tick Register (PR 4) */ 374 1.52 nakayama SPARC64_RDPR64_DEF(tick, %tick) /* gettick() */ 375 1.52 nakayama SPARC64_WRPR64_DEF(tick, %tick) /* settick() */ 376 1.43 nakayama 377 1.43 nakayama /* Processor State Register (PR 6) */ 378 1.52 nakayama SPARC64_RDPR_DEF(pstate, %pstate, int) /* getpstate() */ 379 1.52 nakayama SPARC64_WRPR_DEF(pstate, %pstate, int) /* setpstate() */ 380 1.43 nakayama 381 1.43 nakayama /* Trap Level Register (PR 7) */ 382 1.52 nakayama SPARC64_RDPR_DEF(tl, %tl, int) /* gettl() */ 383 1.43 nakayama 384 1.43 nakayama /* Current Window Pointer Register (PR 9) */ 385 1.52 nakayama SPARC64_RDPR_DEF(cwp, %cwp, int) /* getcwp() */ 386 1.52 nakayama SPARC64_WRPR_DEF(cwp, %cwp, int) /* setcwp() */ 387 1.1 eeh 388 1.43 nakayama /* Version Register (PR 31) */ 389 1.54 nakayama SPARC64_RDCONST64_DEF(rdpr, ver, %ver) /* getver() */ 390 1.52 nakayama 391 1.52 nakayama /* System Tick Register (ASR 24) */ 392 1.52 nakayama SPARC64_RDASR64_DEF(stick, STICK) /* getstick() */ 393 1.52 nakayama SPARC64_WRASR64_DEF(stick, STICK) /* setstick() */ 394 1.1 eeh 395 1.58 palle /* System Tick Compare Register (ASR 25) */ 396 1.58 palle SPARC64_RDASR64_DEF(stickcmpr, STICK_CMPR) /* getstickcmpr() */ 397 1.58 palle 398 1.46 mrg /* Some simple macros to check the cpu type. */ 399 1.55 nakayama #define GETVER_CPU_MASK() ((getver() & VER_MASK) >> VER_MASK_SHIFT) 400 1.46 mrg #define GETVER_CPU_IMPL() ((getver() & VER_IMPL) >> VER_IMPL_SHIFT) 401 1.47 mrg #define GETVER_CPU_MANUF() ((getver() & VER_MANUF) >> VER_MANUF_SHIFT) 402 1.47 mrg #define CPU_IS_SPITFIRE() (GETVER_CPU_IMPL() == IMPL_SPITFIRE) 403 1.50 macallan #define CPU_IS_HUMMINGBIRD() (GETVER_CPU_IMPL() == IMPL_HUMMINGBIRD) 404 1.47 mrg #define CPU_IS_USIIIi() ((GETVER_CPU_IMPL() == IMPL_JALAPENO) || \ 405 1.47 mrg (GETVER_CPU_IMPL() == IMPL_SERRANO)) 406 1.46 mrg #define CPU_IS_USIII_UP() (GETVER_CPU_IMPL() >= IMPL_CHEETAH) 407 1.47 mrg #define CPU_IS_SPARC64_V_UP() (GETVER_CPU_MANUF() == MANUF_FUJITSU && \ 408 1.47 mrg GETVER_CPU_IMPL() >= IMPL_ZEUS) 409 1.46 mrg 410 1.31 perry static __inline int 411 1.26 chs intr_disable(void) 412 1.26 chs { 413 1.26 chs int pstate = getpstate(); 414 1.26 chs 415 1.26 chs setpstate(pstate & ~PSTATE_IE); 416 1.41 nakayama return pstate; 417 1.26 chs } 418 1.26 chs 419 1.31 perry static __inline void 420 1.26 chs intr_restore(int pstate) 421 1.26 chs { 422 1.26 chs setpstate(pstate); 423 1.26 chs } 424 1.26 chs 425 1.1 eeh /* 426 1.1 eeh * GCC pseudo-functions for manipulating PIL 427 1.1 eeh */ 428 1.1 eeh 429 1.1 eeh #ifdef SPLDEBUG 430 1.32 cdi void prom_printf(const char *fmt, ...); 431 1.1 eeh extern int printspl; 432 1.21 chs #define SPLPRINT(x) \ 433 1.21 chs { \ 434 1.21 chs if (printspl) { \ 435 1.21 chs int i = 10000000; \ 436 1.21 chs prom_printf x ; \ 437 1.21 chs while (i--) \ 438 1.21 chs ; \ 439 1.21 chs } \ 440 1.21 chs } 441 1.1 eeh #define SPL(name, newpil) \ 442 1.31 perry static __inline int name##X(const char* file, int line) \ 443 1.1 eeh { \ 444 1.1 eeh int oldpil; \ 445 1.30 perry __asm volatile("rdpr %%pil,%0" : "=r" (oldpil)); \ 446 1.1 eeh SPLPRINT(("{%s:%d %d=>%d}", file, line, oldpil, newpil)); \ 447 1.38 martin __asm volatile("wrpr %%g0,%0,%%pil" : : "n" (newpil) : "memory"); \ 448 1.1 eeh return (oldpil); \ 449 1.1 eeh } 450 1.1 eeh /* A non-priority-decreasing version of SPL */ 451 1.1 eeh #define SPLHOLD(name, newpil) \ 452 1.31 perry static __inline int name##X(const char* file, int line) \ 453 1.1 eeh { \ 454 1.1 eeh int oldpil; \ 455 1.30 perry __asm volatile("rdpr %%pil,%0" : "=r" (oldpil)); \ 456 1.1 eeh if (newpil <= oldpil) \ 457 1.1 eeh return oldpil; \ 458 1.1 eeh SPLPRINT(("{%s:%d %d->!d}", file, line, oldpil, newpil)); \ 459 1.38 martin __asm volatile("wrpr %%g0,%0,%%pil" : : "n" (newpil) : "memory"); \ 460 1.1 eeh return (oldpil); \ 461 1.1 eeh } 462 1.1 eeh 463 1.1 eeh #else 464 1.1 eeh #define SPLPRINT(x) 465 1.1 eeh #define SPL(name, newpil) \ 466 1.62 ryo static __inline __always_inline int name(void) \ 467 1.1 eeh { \ 468 1.1 eeh int oldpil; \ 469 1.30 perry __asm volatile("rdpr %%pil,%0" : "=r" (oldpil)); \ 470 1.38 martin __asm volatile("wrpr %%g0,%0,%%pil" : : "n" (newpil) : "memory"); \ 471 1.1 eeh return (oldpil); \ 472 1.1 eeh } 473 1.1 eeh /* A non-priority-decreasing version of SPL */ 474 1.1 eeh #define SPLHOLD(name, newpil) \ 475 1.62 ryo static __inline __always_inline int name(void) \ 476 1.1 eeh { \ 477 1.1 eeh int oldpil; \ 478 1.30 perry __asm volatile("rdpr %%pil,%0" : "=r" (oldpil)); \ 479 1.1 eeh if (newpil <= oldpil) \ 480 1.1 eeh return oldpil; \ 481 1.38 martin __asm volatile("wrpr %%g0,%0,%%pil" : : "n" (newpil) : "memory"); \ 482 1.1 eeh return (oldpil); \ 483 1.1 eeh } 484 1.1 eeh #endif 485 1.1 eeh 486 1.43 nakayama static __inline ipl_cookie_t 487 1.34 yamt makeiplcookie(ipl_t ipl) 488 1.34 yamt { 489 1.34 yamt 490 1.34 yamt return (ipl_cookie_t){._ipl = ipl}; 491 1.34 yamt } 492 1.34 yamt 493 1.33 yamt static __inline int __attribute__((__unused__)) 494 1.34 yamt splraiseipl(ipl_cookie_t icookie) 495 1.33 yamt { 496 1.34 yamt int newpil = icookie._ipl; 497 1.33 yamt int oldpil; 498 1.33 yamt 499 1.33 yamt /* 500 1.33 yamt * NetBSD/sparc64's IPL_* constants equate directly to the 501 1.33 yamt * corresponding PIL_* names; no need to map them here. 502 1.33 yamt */ 503 1.41 nakayama __asm volatile("rdpr %%pil,%0" : "=r" (oldpil)); 504 1.33 yamt if (newpil <= oldpil) 505 1.33 yamt return (oldpil); 506 1.41 nakayama __asm volatile("wrpr %0,0,%%pil" : : "r" (newpil) : "memory"); 507 1.33 yamt return (oldpil); 508 1.33 yamt } 509 1.33 yamt 510 1.1 eeh SPL(spl0, 0) 511 1.1 eeh 512 1.11 thorpej SPLHOLD(splsoftint, 1) 513 1.11 thorpej #define splsoftclock splsoftint 514 1.1 eeh #define splsoftnet splsoftint 515 1.66 macallan #define splsoftbio splsoftint 516 1.1 eeh 517 1.22 nakayama SPLHOLD(splsoftserial, 4) 518 1.22 nakayama 519 1.1 eeh /* 520 1.1 eeh * Memory allocation (must be as high as highest network, tty, or disk device) 521 1.1 eeh */ 522 1.33 yamt SPLHOLD(splvm, PIL_VM) 523 1.1 eeh 524 1.16 eeh SPLHOLD(splsched, PIL_SCHED) 525 1.14 thorpej 526 1.16 eeh SPLHOLD(splhigh, PIL_HIGH) 527 1.1 eeh 528 1.1 eeh /* splx does not have a return value */ 529 1.1 eeh #ifdef SPLDEBUG 530 1.1 eeh #define spl0() spl0X(__FILE__, __LINE__) 531 1.1 eeh #define splsoftint() splsoftintX(__FILE__, __LINE__) 532 1.22 nakayama #define splsoftserial() splsoftserialX(__FILE__, __LINE__) 533 1.1 eeh #define splausoft() splausoftX(__FILE__, __LINE__) 534 1.1 eeh #define splfdsoft() splfdsoftX(__FILE__, __LINE__) 535 1.18 thorpej #define splvm() splvmX(__FILE__, __LINE__) 536 1.1 eeh #define splclock() splclockX(__FILE__, __LINE__) 537 1.1 eeh #define splfd() splfdX(__FILE__, __LINE__) 538 1.1 eeh #define splzs() splzsX(__FILE__, __LINE__) 539 1.7 eeh #define splserial() splzerialX(__FILE__, __LINE__) 540 1.1 eeh #define splaudio() splaudioX(__FILE__, __LINE__) 541 1.1 eeh #define splstatclock() splstatclockX(__FILE__, __LINE__) 542 1.16 eeh #define splsched() splschedX(__FILE__, __LINE__) 543 1.16 eeh #define spllock() spllockX(__FILE__, __LINE__) 544 1.1 eeh #define splhigh() splhighX(__FILE__, __LINE__) 545 1.1 eeh #define splx(x) splxX((x),__FILE__, __LINE__) 546 1.1 eeh 547 1.31 perry static __inline void splxX(int newpil, const char *file, int line) 548 1.1 eeh #else 549 1.62 ryo static __inline __always_inline void splx(int newpil) 550 1.1 eeh #endif 551 1.1 eeh { 552 1.21 chs #ifdef SPLDEBUG 553 1.1 eeh int pil; 554 1.1 eeh 555 1.30 perry __asm volatile("rdpr %%pil,%0" : "=r" (pil)); 556 1.21 chs SPLPRINT(("{%d->%d}", pil, newpil)); 557 1.21 chs #endif 558 1.38 martin __asm volatile("wrpr %%g0,%0,%%pil" : : "rn" (newpil) : "memory"); 559 1.1 eeh } 560 1.1 eeh #endif /* KERNEL && !_LOCORE */ 561 1.1 eeh 562 1.1 eeh #endif /* PSR_IMPL */ 563