1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22/* 23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27#pragma ident "%Z%%M% %I% %E% SMI" 28 29#include <sys/asm_linkage.h> 30#include <sys/machparam.h> /* To get SYSBASE and PAGESIZE */ 31#include <sys/privregs.h> 32 33#if !defined(lint) 34 35 .seg ".text" 36 .align 4 37 38#define PSR_PIL_BIT 0x8 39 40/* 41 * Macro to raise processor priority level. 42 * Avoid dropping processor priority if already at high level. 43 * Also avoid going below CPU->cpu_base_spl, which could've just been set by 44 * a higher-level interrupt thread that just blocked. 45 * XXX4U: bring splr inline 46 */ 47#define RAISE(level) \ 48 b splr; \ 49 mov ((level) << PSR_PIL_BIT), %o0 50/* 51 * Macro to set the priority to a specified level. 52 * Avoid dropping the priority below CPU->cpu_base_spl. 53 * XXX4U: bring splx inline 54 */ 55#define SETPRI(level) \ 56 b splx; \ 57 mov ((level) << PSR_PIL_BIT), %o0 58 59#endif /* lint */ 60 61 /* 62 * Berkley 4.3 introduced symbolically named interrupt levels 63 * as a way deal with priority in a machine independent fashion. 64 * Numbered priorities are machine specific, and should be 65 * discouraged where possible. 66 * 67 * Note, for the machine specific priorities there are 68 * examples listed for devices that use a particular priority. 69 * It should not be construed that all devices of that 70 * type should be at that priority. It is currently were 71 * the current devices fit into the priority scheme based 72 * upon time criticalness. 73 * 74 * The underlying assumption of these assignments is that 75 * SPARC9 IPL 10 is the highest level from which a device 76 * routine can call wakeup. Devices that interrupt from higher 77 * levels are restricted in what they can do. If they need 78 * kernels services they should schedule a routine at a lower 79 * level (via software interrupt) to do the required 80 * processing. 81 * 82 * Examples of this higher usage: 83 * Level Usage 84 * 15 Asynchronous memory exceptions 85 * 14 Profiling clock (and PROM uart polling clock) 86 * 13 Audio device 87 * 12 Serial ports 88 * 11 Floppy controller 89 * 90 * The serial ports request lower level processing on level 6. 91 * Audio and floppy request lower level processing on level 4. 92 * 93 * Also, almost all splN routines (where N is a number or a 94 * mnemonic) will do a RAISE(), on the assumption that they are 95 * never used to lower our priority. 96 * The exceptions are: 97 * spl8() Because you can't be above 15 to begin with! 98 * splzs() Because this is used at boot time to lower our 99 * priority, to allow the PROM to poll the uart. 100 * spl0() Used to lower priority to 0. 101 * splsoftclock() Used by hardclock to lower priority. 102 */ 103 104#if defined(lint) 105 106int splimp(void) { return (0); } 107int splnet(void) { return (0); } 108 109#ifdef notdef 110int spl6(void) { return (0); } 111int spl5(void) { return (0); } 112#endif notdef 113 114#else /* lint */ 115 116 /* locks out all interrupts, including memory errors */ 117 ENTRY(spl8) 118 SETPRI(15) 119 SET_SIZE(spl8) 120 121 /* just below the level that profiling runs */ 122 ALTENTRY(splaudio) 123 ENTRY(spl7) 124 RAISE(13) 125 SET_SIZE(spl7) 126 SET_SIZE(splaudio) 127 128 /* sun specific - highest priority onboard serial i/o zs ports */ 129 ALTENTRY(splzs) 130 SETPRI(12) /* Can't be a RAISE, as it's used to lower us */ 131 SET_SIZE(splzs) 132 133 /* 134 * should lock out clocks and all interrupts, 135 * as you can see, there are exceptions 136 */ 137 ALTENTRY(splhigh) 138 ALTENTRY(splhi) 139 140 /* the standard clock interrupt priority */ 141 ALTENTRY(splclock) 142 143 /* highest priority for any tty handling */ 144 ALTENTRY(spltty) 145 146 /* highest priority required for protection of buffered io system */ 147 ALTENTRY(splbio) 148 149 /* machine specific */ 150 ENTRY2(spl6,spl5) 151 RAISE(10) 152 SET_SIZE(splhigh) 153 SET_SIZE(splhi) 154 SET_SIZE(splclock) 155 SET_SIZE(spltty) 156 SET_SIZE(splbio) 157 SET_SIZE(spl5) 158 SET_SIZE(spl6) 159 160 /* 161 * machine specific 162 * for sun, some frame buffers must be at this priority 163 */ 164 ENTRY(spl4) 165 RAISE(8) 166 SET_SIZE(spl4) 167 168 /* highest level that any network device will use */ 169 ALTENTRY(splimp) 170 171 /* 172 * machine specific 173 * for sun, devices with limited buffering: tapes, ethernet 174 */ 175 ENTRY(spl3) 176 RAISE(6) 177 SET_SIZE(splimp) 178 SET_SIZE(spl3) 179 180 /* 181 * machine specific - not as time critical as above 182 * for sun, disks 183 */ 184 ENTRY(spl2) 185 RAISE(4) 186 SET_SIZE(spl2) 187 188 ENTRY(spl1) 189 RAISE(2) 190 SET_SIZE(spl1) 191 192 /* highest level that any protocol handler will run */ 193 ENTRY(splnet) 194 RAISE(1) 195 SET_SIZE(splnet) 196 197 /* softcall priority */ 198 /* used by hardclock to LOWER priority */ 199 ENTRY(splsoftclock) 200 SETPRI(1) 201 SET_SIZE(splsoftclock) 202 203 /* allow all interrupts */ 204 ENTRY(spl0) 205 SETPRI(0) 206 SET_SIZE(spl0) 207 208#endif /* lint */ 209 210/* 211 * splx - set PIL back to that indicated by the old %PSR passed as an argument, 212 * or to the CPU's base priority, whichever is higher. 213 * sys_rtt (in locore.s) relies on this not to use %g1 or %g2. 214 */ 215 216#if defined(lint) 217 218/* ARGSUSED */ 219void 220splx(int level) 221{ 222} 223 224#else /* lint */ 225 226 ENTRY(splx) 227 rdpr %pil, %o1 ! get current pil 228 wrpr %o0, %pil 229 retl 230 mov %o1, %o0 231 SET_SIZE(splx) 232 233#endif /* level */ 234 235/* 236 * splr() 237 * 238 * splr is like splx but will only raise the priority and never drop it 239 * Be careful not to set priority lower than CPU->cpu_base_pri, 240 * even though it seems we're raising the priority, it could be set higher 241 * at any time by an interrupt routine, so we must block interrupts and 242 * look at CPU->cpu_base_pri. 243 * 244 */ 245 246#if defined(lint) 247#ifdef notdef 248 249/* ARGSUSED */ 250int 251splr(int level) 252{ return (0); } 253 254#endif notdef 255#else /* lint */ 256 257/* 258 * splr(psr_pri_field) 259 * splr is like splx but will only raise the priority and never drop it 260 */ 261 262 ENTRY(splr) 263 rdpr %pil, %o1 ! get current pil 264 cmp %o0, %o1 265 ble 1f 266 nop 267 wrpr %o0, %pil 2681: retl 269 mov %o1, %o0 ! return the old pil 270 SET_SIZE(splr) 271 272#endif /* lint */ 273 274/* 275 * get_ticks() 276 */ 277#if defined(lint) 278 279/* ARGSUSED */ 280uint64_t 281get_ticks(void) 282{ return (0); } 283 284#else /* lint */ 285 286 ENTRY(get_ticks) 287 rdpr %tick, %o0 288 sllx %o0, 1, %o0 289 retl 290 srlx %o0, 1, %o0 ! shake off npt bit 291 SET_SIZE(get_ticks) 292 293#endif /* lint */ 294